diff --git a/clause/expression.go b/clause/expression.go index 92ac7f22..08e5a257 100644 --- a/clause/expression.go +++ b/clause/expression.go @@ -4,6 +4,7 @@ import ( "database/sql" "database/sql/driver" "go/ast" + "gorm.io/gorm/utils" "reflect" ) @@ -107,7 +108,11 @@ func (expr NamedExpr) Build(builder Builder) { modelType := reflectValue.Type() for i := 0; i < modelType.NumField(); i++ { if fieldStruct := modelType.Field(i); ast.IsExported(fieldStruct.Name) { - namedMap[fieldStruct.Name] = reflectValue.Field(i).Interface() + fieldName, exist := utils.ParseTagSetting(fieldStruct.Tag.Get("gorm"), ";")["COLUMN"] + if !exist { + fieldName = fieldStruct.Name + } + namedMap[fieldName] = reflectValue.Field(i).Interface() if fieldStruct.Anonymous { appendFieldsToMap(reflectValue.Field(i)) diff --git a/schema/field.go b/schema/field.go index 1589d984..591311ea 100644 --- a/schema/field.go +++ b/schema/field.go @@ -93,7 +93,7 @@ type Field struct { func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { var ( err error - tagSetting = ParseTagSetting(fieldStruct.Tag.Get("gorm"), ";") + tagSetting = utils.ParseTagSetting(fieldStruct.Tag.Get("gorm"), ";") ) field := &Field{ @@ -141,7 +141,7 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { 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"), ";") { + for key, value := range utils.ParseTagSetting(rvType.Field(i).Tag.Get("gorm"), ";") { if _, ok := field.TagSettings[key]; !ok { field.TagSettings[key] = value } diff --git a/schema/index.go b/schema/index.go index f5ac5dd2..45b3b614 100644 --- a/schema/index.go +++ b/schema/index.go @@ -2,6 +2,7 @@ package schema import ( "fmt" + "gorm.io/gorm/utils" "sort" "strconv" "strings" @@ -103,7 +104,7 @@ func parseFieldIndexes(field *Field) (indexes []Index, err error) { tag = strings.Join(v[1:], ":") idx = strings.Index(tag, ",") tagSetting = strings.Join(strings.Split(tag, ",")[1:], ",") - settings = ParseTagSetting(tagSetting, ",") + settings = utils.ParseTagSetting(tagSetting, ",") length, _ = strconv.Atoi(settings["LENGTH"]) ) diff --git a/schema/relationship.go b/schema/relationship.go index 9436f283..99fd4a04 100644 --- a/schema/relationship.go +++ b/schema/relationship.go @@ -3,6 +3,7 @@ package schema import ( "context" "fmt" + "gorm.io/gorm/utils" "reflect" "strings" @@ -123,16 +124,17 @@ func (schema *Schema) parseRelation(field *Field) *Relationship { } // User has many Toys, its `Polymorphic` is `Owner`, Pet has one Toy, its `Polymorphic` is `Owner` -// type User struct { -// Toys []Toy `gorm:"polymorphic:Owner;"` -// } -// type Pet struct { -// Toy Toy `gorm:"polymorphic:Owner;"` -// } -// type Toy struct { -// OwnerID int -// OwnerType string -// } +// +// type User struct { +// Toys []Toy `gorm:"polymorphic:Owner;"` +// } +// type Pet struct { +// Toy Toy `gorm:"polymorphic:Owner;"` +// } +// type Toy struct { +// OwnerID int +// OwnerType string +// } func (schema *Schema) buildPolymorphicRelation(relation *Relationship, field *Field, polymorphic string) { relation.Polymorphic = &Polymorphic{ Value: schema.Table, @@ -555,7 +557,7 @@ func (rel *Relationship) ParseConstraint() *Constraint { var ( name string idx = strings.Index(str, ",") - settings = ParseTagSetting(str, ",") + settings = utils.ParseTagSetting(str, ",") ) // optimize match english letters and midline diff --git a/schema/schema_helper_test.go b/schema/schema_helper_test.go index 9abaecba..2d06043f 100644 --- a/schema/schema_helper_test.go +++ b/schema/schema_helper_test.go @@ -3,6 +3,7 @@ package schema_test import ( "context" "fmt" + "gorm.io/gorm/utils" "reflect" "strings" "testing" @@ -44,7 +45,7 @@ func checkSchemaField(t *testing.T, s *schema.Schema, f *schema.Field, fc func(* if f.TagSettings == nil { if f.Tag != "" { - f.TagSettings = schema.ParseTagSetting(f.Tag.Get("gorm"), ";") + f.TagSettings = utils.ParseTagSetting(f.Tag.Get("gorm"), ";") } else { f.TagSettings = map[string]string{} } diff --git a/schema/utils.go b/schema/utils.go index acf1a739..d9e2c296 100644 --- a/schema/utils.go +++ b/schema/utils.go @@ -13,37 +13,6 @@ import ( var embeddedCacheKey = "embedded_cache_store" -func ParseTagSetting(str string, sep string) map[string]string { - settings := map[string]string{} - names := strings.Split(str, sep) - - for i := 0; i < len(names); i++ { - j := i - if len(names[j]) > 0 { - for { - if names[j][len(names[j])-1] == '\\' { - i++ - names[j] = names[j][0:len(names[j])-1] + sep + names[i] - names[i] = "" - } else { - break - } - } - } - - values := strings.Split(names[j], ":") - k := strings.TrimSpace(strings.ToUpper(values[0])) - - if len(values) >= 2 { - settings[k] = strings.Join(values[1:], ":") - } else if k != "" { - settings[k] = k - } - } - - return settings -} - func toColumns(val string) (results []string) { if val != "" { for _, v := range strings.Split(val, ",") { diff --git a/utils/utils.go b/utils/utils.go index e08533cd..36bb9fde 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -131,3 +131,34 @@ func ToString(value interface{}) string { } return "" } + +func ParseTagSetting(str string, sep string) map[string]string { + settings := map[string]string{} + names := strings.Split(str, sep) + + for i := 0; i < len(names); i++ { + j := i + if len(names[j]) > 0 { + for { + if names[j][len(names[j])-1] == '\\' { + i++ + names[j] = names[j][0:len(names[j])-1] + sep + names[i] + names[i] = "" + } else { + break + } + } + } + + values := strings.Split(names[j], ":") + k := strings.TrimSpace(strings.ToUpper(values[0])) + + if len(values) >= 2 { + settings[k] = strings.Join(values[1:], ":") + } else if k != "" { + settings[k] = k + } + } + + return settings +}