Refactor gorm field
This commit is contained in:
parent
3c77eb0bb0
commit
69b851ed95
@ -15,6 +15,13 @@ import (
|
||||
"gorm.io/gorm/utils"
|
||||
)
|
||||
|
||||
// special types' reflect type
|
||||
var (
|
||||
TimeReflectType = reflect.TypeOf(time.Time{})
|
||||
TimePtrReflectType = reflect.TypeOf(&time.Time{})
|
||||
ByteReflectType = reflect.TypeOf(uint8(0))
|
||||
)
|
||||
|
||||
type (
|
||||
// DataType GORM data type
|
||||
DataType string
|
||||
@ -22,9 +29,6 @@ type (
|
||||
TimeType int64
|
||||
)
|
||||
|
||||
// TimeReflectType time's reflect type
|
||||
var TimeReflectType = reflect.TypeOf(time.Time{})
|
||||
|
||||
// GORM time types
|
||||
const (
|
||||
UnixTime TimeType = 1
|
||||
@ -103,6 +107,8 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
|
||||
Updatable: true,
|
||||
Readable: true,
|
||||
PrimaryKey: utils.CheckTruth(tagSetting["PRIMARYKEY"], tagSetting["PRIMARY_KEY"]),
|
||||
AutoIncrement: utils.CheckTruth(tagSetting["AUTOINCREMENT"]),
|
||||
HasDefaultValue: utils.CheckTruth(tagSetting["AUTOINCREMENT"]),
|
||||
NotNull: utils.CheckTruth(tagSetting["NOT NULL"], tagSetting["NOTNULL"]),
|
||||
Unique: utils.CheckTruth(tagSetting["UNIQUE"]),
|
||||
Comment: tagSetting["COMMENT"],
|
||||
@ -114,7 +120,7 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
|
||||
}
|
||||
|
||||
fieldValue := reflect.New(field.IndirectFieldType)
|
||||
// if field is valuer, used its value or first fields as data type
|
||||
// if field is valuer, used its value or first field as data type
|
||||
valuer, isValuer := fieldValue.Interface().(driver.Valuer)
|
||||
if isValuer {
|
||||
if _, ok := fieldValue.Interface().(GormDataTypeInterface); !ok {
|
||||
@ -122,31 +128,37 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
|
||||
fieldValue = reflect.ValueOf(v)
|
||||
}
|
||||
|
||||
// Use the field struct's first field type as data type, e.g: use `string` for sql.NullString
|
||||
var getRealFieldValue func(reflect.Value)
|
||||
getRealFieldValue = func(v reflect.Value) {
|
||||
rv := reflect.Indirect(v)
|
||||
if rv.Kind() == reflect.Struct && !rv.Type().ConvertibleTo(TimeReflectType) {
|
||||
for i := 0; i < rv.Type().NumField(); i++ {
|
||||
newFieldType := rv.Type().Field(i).Type
|
||||
var (
|
||||
rv = reflect.Indirect(v)
|
||||
rvType = rv.Type()
|
||||
)
|
||||
|
||||
if rv.Kind() == reflect.Struct && !rvType.ConvertibleTo(TimeReflectType) {
|
||||
for i := 0; i < rvType.NumField(); i++ {
|
||||
for key, value := range ParseTagSetting(rvType.Field(i).Tag.Get("gorm"), ";") {
|
||||
if _, ok := field.TagSettings[key]; !ok {
|
||||
field.TagSettings[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < rvType.NumField(); i++ {
|
||||
newFieldType := rvType.Field(i).Type
|
||||
for newFieldType.Kind() == reflect.Ptr {
|
||||
newFieldType = newFieldType.Elem()
|
||||
}
|
||||
|
||||
fieldValue = reflect.New(newFieldType)
|
||||
|
||||
if rv.Type() != reflect.Indirect(fieldValue).Type() {
|
||||
if rvType != reflect.Indirect(fieldValue).Type() {
|
||||
getRealFieldValue(fieldValue)
|
||||
}
|
||||
|
||||
if fieldValue.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
for key, value := range ParseTagSetting(field.IndirectFieldType.Field(i).Tag.Get("gorm"), ";") {
|
||||
if _, ok := field.TagSettings[key]; !ok {
|
||||
field.TagSettings[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -155,11 +167,6 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := field.TagSettings["AUTOINCREMENT"]; ok && utils.CheckTruth(val) {
|
||||
field.AutoIncrement = true
|
||||
field.HasDefaultValue = true
|
||||
}
|
||||
|
||||
if num, ok := field.TagSettings["AUTOINCREMENTINCREMENT"]; ok {
|
||||
field.AutoIncrementIncrement, _ = strconv.ParseInt(num, 10, 64)
|
||||
}
|
||||
@ -218,7 +225,6 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
|
||||
}
|
||||
case reflect.String:
|
||||
field.DataType = String
|
||||
|
||||
if field.HasDefaultValue && !skipParseDefaultValue {
|
||||
field.DefaultValue = strings.Trim(field.DefaultValue, "'")
|
||||
field.DefaultValue = strings.Trim(field.DefaultValue, `"`)
|
||||
@ -229,17 +235,15 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
|
||||
field.DataType = Time
|
||||
} else if fieldValue.Type().ConvertibleTo(TimeReflectType) {
|
||||
field.DataType = Time
|
||||
} else if fieldValue.Type().ConvertibleTo(reflect.TypeOf(&time.Time{})) {
|
||||
} else if fieldValue.Type().ConvertibleTo(TimePtrReflectType) {
|
||||
field.DataType = Time
|
||||
}
|
||||
case reflect.Array, reflect.Slice:
|
||||
if reflect.Indirect(fieldValue).Type().Elem() == reflect.TypeOf(uint8(0)) {
|
||||
if reflect.Indirect(fieldValue).Type().Elem() == ByteReflectType {
|
||||
field.DataType = Bytes
|
||||
}
|
||||
}
|
||||
|
||||
field.GORMDataType = field.DataType
|
||||
|
||||
if dataTyper, ok := fieldValue.Interface().(GormDataTypeInterface); ok {
|
||||
field.DataType = DataType(dataTyper.GormDataType())
|
||||
}
|
||||
@ -339,8 +343,9 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := field.TagSettings["EMBEDDED"]; field.GORMDataType != Time && field.GORMDataType != Bytes &&
|
||||
(ok || (fieldStruct.Anonymous && !isValuer && (field.Creatable || field.Updatable || field.Readable))) {
|
||||
// Normal anonymous field or having `EMBEDDED` tag
|
||||
if _, ok := field.TagSettings["EMBEDDED"]; ok || (field.GORMDataType != Time && field.GORMDataType != Bytes && !isValuer &&
|
||||
fieldStruct.Anonymous && (field.Creatable || field.Updatable || field.Readable)) {
|
||||
kind := reflect.Indirect(fieldValue).Kind()
|
||||
switch kind {
|
||||
case reflect.Struct:
|
||||
|
@ -9,7 +9,7 @@ require (
|
||||
github.com/jinzhu/now v1.1.4
|
||||
github.com/lib/pq v1.10.4
|
||||
github.com/mattn/go-sqlite3 v1.14.11 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506 // indirect
|
||||
gorm.io/driver/mysql v1.2.3
|
||||
gorm.io/driver/postgres v1.2.3
|
||||
gorm.io/driver/sqlite v1.2.6
|
||||
@ -18,3 +18,5 @@ require (
|
||||
)
|
||||
|
||||
replace gorm.io/gorm => ../
|
||||
|
||||
replace gorm.io/driver/sqlserver => /Users/jinzhu/Projects/gorm/sqlserver
|
||||
|
Loading…
x
Reference in New Issue
Block a user