func (d *Driver) isPrimaryKey(fields *driver.Fields, idx int, tag *structs.Tag) bool { if tag.Has("primary_key") { return true } for _, v := range fields.CompositePrimaryKey { if v == idx { return true } } return false }
func (ormStructConfigurator) DecomposeField(s *structs.Struct, typ reflect.Type, tag *structs.Tag) bool { // Don't decompose fields with a codec if tag.Has("codec") { return false } // Avoid decomposing time.Time if typ.Name() == "Time" && typ.PkgPath() == "time" { return false } return true }
func (b *SqlBackend) ScanByteSlice(val []byte, goVal *reflect.Value, t *structs.Tag) error { if goVal.Kind() == reflect.String { goVal.SetString(string(val)) return nil } if len(val) > 0 && !t.Has("raw") { b := make([]byte, len(val)) copy(b, val) val = b } goVal.Set(reflect.ValueOf(val)) return nil }
// returns wheter the kind defaults to nullempty option func defaultsToNullEmpty(typ reflect.Type, t *structs.Tag) bool { if t.Has("references") || t.Has("codec") || (t.Has("notnull") && typ.Kind() != reflect.Bool) { return true } switch typ.Kind() { case reflect.Slice, reflect.Ptr, reflect.Interface, reflect.String: return true case reflect.Struct: return typ == timeType } return false }
func (b *Backend) FieldType(typ reflect.Type, t *structs.Tag) (string, error) { if c := codec.FromTag(t); c != nil { // TODO: Use type JSON on Postgresql >= 9.2 for JSON encoded fields if c.Binary || t.PipeName() != "" { return "BYTEA", nil } return "TEXT", nil } var ft string switch typ.Kind() { case reflect.Bool: ft = "BOOL" case reflect.Int8, reflect.Uint8, reflect.Int16: ft = "INT2" case reflect.Uint16, reflect.Int32: ft = "INT4" case reflect.Int, reflect.Uint, reflect.Uint32, reflect.Int64, reflect.Uint64: ft = "INT8" case reflect.Float32: ft = "FLOAT4" case reflect.Float64: ft = "FLOAT8" case reflect.String: if t.Has("macaddr") { ft = "MACADDR" } else if t.Has("inet") { ft = "INET" } else { if ml, ok := t.MaxLength(); ok { ft = fmt.Sprintf("VARCHAR (%d)", ml) } else if fl, ok := t.Length(); ok { ft = fmt.Sprintf("CHAR (%d)", fl) } else { ft = "TEXT" } } case reflect.Slice: etyp := typ.Elem() if etyp.Kind() == reflect.Uint8 { // []byte ft = "BYTEA" // TODO: database/sql does not support array types. Enable this code // if that changes in the future // } else if typ.Elem().Kind() != reflect.Struct { // et, err := b.FieldType(typ.Elem(), tag) // if err != nil { // return "", err // } // t = et + "[]" } case reflect.Struct: if typ.Name() == "Time" && typ.PkgPath() == "time" { ft = "TIMESTAMP WITHOUT TIME ZONE" } } if t.Has("auto_increment") { if strings.HasPrefix(ft, "INT") { ft = strings.Replace(ft, "INT", "SERIAL", -1) } else { return "", fmt.Errorf("postgres does not support auto incrementing %v", typ) } } if ft != "" { return ft, nil } return "", fmt.Errorf("can't map field type %v to a database type", typ) }
func defaultsToOmitEmpty(typ reflect.Type, t *structs.Tag) bool { return t.Has("auto_increment") || (t.Has("default") && typ.Kind() != reflect.Bool) }