コード例 #1
0
ファイル: driver.go プロジェクト: rainycape/gondola
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
}
コード例 #2
0
ファイル: registry.go プロジェクト: rainycape/gondola
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
}
コード例 #3
0
ファイル: backend.go プロジェクト: rainycape/gondola
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
}
コード例 #4
0
ファイル: registry.go プロジェクト: rainycape/gondola
// 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
}
コード例 #5
0
ファイル: backend.go プロジェクト: rainycape/gondola
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)
}
コード例 #6
0
ファイル: registry.go プロジェクト: rainycape/gondola
func defaultsToOmitEmpty(typ reflect.Type, t *structs.Tag) bool {
	return t.Has("auto_increment") || (t.Has("default") && typ.Kind() != reflect.Bool)
}