func (b *SqlBackend) ScanInt(val int64, goVal *reflect.Value, t *structs.Tag) error { if types.Kind(goVal.Kind()) == types.Uint { goVal.SetUint(uint64(val)) return nil } goVal.SetInt(val) return nil }
func valRepr(s *gosym.Sym, typ reflect.Type, values []string, _html bool) (r string) { val, _ := strconv.ParseUint(values[0], 0, 64) var val2 uint64 if len(values) > 1 { val2, _ = strconv.ParseUint(values[1], 0, 64) } // If there's a panic prettyfy'ing the value just // assume it's a pointer. It's better than // omitting the error page. defer func() { if recover() != nil { r = pointerRepr(nil, val, false) } }() switch types.Kind(typ.Kind()) { case types.Bool: if val == 0 { return "= false" } return "= true" case types.Int: return "= " + strconv.FormatInt(int64(val), 10) case types.Uint: return "= " + strconv.FormatUint(val, 10) case types.Float: if typ.Kind() == reflect.Float32 { return "= " + strconv.FormatFloat(float64(math.Float32frombits(uint32(val))), 'g', -1, 32) } return "= " + strconv.FormatFloat(math.Float64frombits(uint64(val)), 'g', -1, 64) case types.Slice: return sliceRepr(val, val2, s) case types.String: v := stringRepr(val, val2) if _html { v = html.Escape(v) } return v case types.Interface: if typ.NumMethod() == 0 { return emptyInterfaceRepr(val, val2) } idata := [2]uintptr{uintptr(val), uintptr(val2)} v := reflect.NewAt(typ, unsafe.Pointer(&idata[0])).Elem() return descRepr(val, &v, _html) case types.Func: fn := reflect.NewAt(typ, unsafe.Pointer(&val)).Elem() f := runtime.FuncForPC(fn.Pointer()) if f != nil { return "= " + f.Name() } } return pointerRepr(typ, val, _html) }
func Number(lang i18n.Languager, number interface{}) (string, error) { val := reflect.Indirect(reflect.ValueOf(number)) if val.IsValid() { switch types.Kind(val.Kind()) { case types.Int: return formatNumber(lang, strconv.FormatInt(val.Int(), 10), ""), nil case types.Uint: return formatNumber(lang, strconv.FormatUint(val.Uint(), 10), ""), nil case types.Float: return formatStringNumber(lang, strconv.FormatFloat(val.Float(), 'f', -1, 64)), nil case types.String: return formatStringNumber(lang, val.String()), nil } } return "", fmt.Errorf("can't format type %T as number", number) }
func toHTMLValue(val interface{}) string { v := reflect.ValueOf(val) if v.IsValid() { for v.Kind() == reflect.Ptr { v = v.Elem() } if v.IsValid() { // Avoid enum types with a String() method to be represented // as a string. Use their numeric representation. k := types.Kind(v.Kind()) if k == types.Int { return strconv.FormatInt(v.Int(), 10) } if k == types.Uint { return strconv.FormatUint(v.Uint(), 10) } } } return html.Escape(types.ToString(val)) }
func (b *Backend) ScanByteSlice(val []byte, goVal *reflect.Value, t *structs.Tag) error { // mysql returns u?int types as []byte under // some circumstances (not sure exactly when, but other // times they're returned as an int64). switch types.Kind(goVal.Kind()) { case types.Int: v, err := strconv.ParseInt(string(val), 10, 64) if err != nil { return err } goVal.SetInt(v) return nil case types.Uint: v, err := strconv.ParseUint(string(val), 10, 64) if err != nil { return err } goVal.SetUint(v) return nil } return b.SqlBackend.ScanByteSlice(val, goVal, t) }
func (d *Driver) Insert(m driver.Model, data interface{}) (driver.Result, error) { var id int64 fields := m.Fields() var pkVal *reflect.Value // TODO: If the PK is supplied by the user rather than auto-assigned, it // might conflict with PKs generated by datastore.AllocateIDs(). if fields.PrimaryKey >= 0 { p := d.primaryKey(fields, data) if p.IsValid() && types.Kind(p.Kind()) == types.Int { id = p.Int() if id == 0 { // Must assign PK field value after calling AllocateIDs pkVal = &p } } } name := m.Table() // Make all objects of a given kind ancestors of the same key. While // this hurts scalability, it makes all reads strongly consistent. parent := d.parentKey(m) var err error if id == 0 { id, _, err = datastore.AllocateIDs(d.c, name, parent, 1) if err != nil { return nil, err } } if fields.AutoincrementPk && pkVal != nil { pkVal.SetInt(int64(id)) } key := datastore.NewKey(d.c, name, "", id, parent) log.Debugf("DATASTORE: put %s %v", key, data) _, err = datastore.Put(d.c, key, data) if err != nil { return nil, err } return &result{key: key, count: 1}, nil }
func (o *Orm) fields(table string, s *structs.Struct) (*driver.Fields, map[string]*reference, error) { methods, err := driver.MakeMethods(s.Type) if err != nil { return nil, nil, err } fields := &driver.Fields{ Struct: s, PrimaryKey: -1, Methods: methods, } var references map[string]*reference for ii, v := range s.QNames { // XXX: Check if this quoting is enough fields.QuotedNames = append(fields.QuotedNames, fmt.Sprintf("\"%s\".\"%s\"", table, s.MNames[ii])) t := s.Types[ii] ftag := s.Tags[ii] // Check encoded types if cn := ftag.CodecName(); cn != "" { if codec.Get(cn) == nil { if imp := codec.RequiredImport(cn); imp != "" { return nil, nil, fmt.Errorf("please import %q to use the codec %q", imp, cn) } return nil, nil, fmt.Errorf("can't find codec %q. Perhaps you missed an import?", cn) } } else { switch t.Kind() { case reflect.Array, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map: return nil, nil, fmt.Errorf("field %q in struct %s has invalid type %s", v, s.Type, t) } } if pn := ftag.PipeName(); pn != "" { // Check if the field has a codec and the pipe exists if ftag.CodecName() == "" { return nil, nil, fmt.Errorf("field %q has pipe %s but no codec - only encoded types can use pipes", v, pn) } if pipe.FromTag(ftag) == nil { return nil, nil, fmt.Errorf("can't find ORM pipe %q. Perhaps you missed an import?", pn) } } // Struct has flattened types, but we need to original type // to determine if it should be nullempty or omitempty by default field := s.Type.FieldByIndex(s.Indexes[ii]) fields.OmitEmpty = append(fields.OmitEmpty, ftag.Has("omitempty") || (defaultsToOmitEmpty(field.Type, ftag) && !ftag.Has("notomitempty"))) fields.NullEmpty = append(fields.NullEmpty, ftag.Has("nullempty") || (defaultsToNullEmpty(field.Type, ftag) && !ftag.Has("notnullempty"))) if ftag.Has("primary_key") { if fields.PrimaryKey >= 0 { return nil, nil, fmt.Errorf("duplicate primary_key in struct %v (%s and %s)", s.Type, s.QNames[fields.PrimaryKey], v) } fields.PrimaryKey = ii } if ftag.Has("auto_increment") { if k := types.Kind(t.Kind()); k != types.Int && k != types.Uint { return nil, nil, fmt.Errorf("auto_increment field %q in struct %s must be of integer type (signed or unsigned", v, s.Type) } fields.AutoincrementPk = fields.PrimaryKey == ii } if ref := ftag.Value("references"); ref != "" { m := referencesRe.FindStringSubmatch(ref) if len(m) != 4 { return nil, nil, fmt.Errorf("field %q has invalid references %q. Must be in the form references=Model or references=Model(Field)", v, ref) } if references == nil { references = make(map[string]*reference) } references[v] = &reference{model: m[1], field: m[3]} } } if err := o.setFieldsDefaults(fields); err != nil { return nil, nil, err } return fields, references, nil }