allow use struct field tag in Exec() and Raw()
				
					
				
			This commit is contained in:
		
							parent
							
								
									02b7e26f6b
								
							
						
					
					
						commit
						15d16fba42
					
				@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"database/sql"
 | 
						"database/sql"
 | 
				
			||||||
	"database/sql/driver"
 | 
						"database/sql/driver"
 | 
				
			||||||
	"go/ast"
 | 
						"go/ast"
 | 
				
			||||||
 | 
						"gorm.io/gorm/utils"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -107,7 +108,11 @@ func (expr NamedExpr) Build(builder Builder) {
 | 
				
			|||||||
					modelType := reflectValue.Type()
 | 
										modelType := reflectValue.Type()
 | 
				
			||||||
					for i := 0; i < modelType.NumField(); i++ {
 | 
										for i := 0; i < modelType.NumField(); i++ {
 | 
				
			||||||
						if fieldStruct := modelType.Field(i); ast.IsExported(fieldStruct.Name) {
 | 
											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 {
 | 
												if fieldStruct.Anonymous {
 | 
				
			||||||
								appendFieldsToMap(reflectValue.Field(i))
 | 
													appendFieldsToMap(reflectValue.Field(i))
 | 
				
			||||||
 | 
				
			|||||||
@ -93,7 +93,7 @@ type Field struct {
 | 
				
			|||||||
func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
 | 
					func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		err        error
 | 
							err        error
 | 
				
			||||||
		tagSetting = ParseTagSetting(fieldStruct.Tag.Get("gorm"), ";")
 | 
							tagSetting = utils.ParseTagSetting(fieldStruct.Tag.Get("gorm"), ";")
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	field := &Field{
 | 
						field := &Field{
 | 
				
			||||||
@ -141,7 +141,7 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				if rv.Kind() == reflect.Struct && !rvType.ConvertibleTo(TimeReflectType) {
 | 
									if rv.Kind() == reflect.Struct && !rvType.ConvertibleTo(TimeReflectType) {
 | 
				
			||||||
					for i := 0; i < rvType.NumField(); i++ {
 | 
										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 {
 | 
												if _, ok := field.TagSettings[key]; !ok {
 | 
				
			||||||
								field.TagSettings[key] = value
 | 
													field.TagSettings[key] = value
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ package schema
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"gorm.io/gorm/utils"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
@ -103,7 +104,7 @@ func parseFieldIndexes(field *Field) (indexes []Index, err error) {
 | 
				
			|||||||
					tag        = strings.Join(v[1:], ":")
 | 
										tag        = strings.Join(v[1:], ":")
 | 
				
			||||||
					idx        = strings.Index(tag, ",")
 | 
										idx        = strings.Index(tag, ",")
 | 
				
			||||||
					tagSetting = strings.Join(strings.Split(tag, ",")[1:], ",")
 | 
										tagSetting = strings.Join(strings.Split(tag, ",")[1:], ",")
 | 
				
			||||||
					settings   = ParseTagSetting(tagSetting, ",")
 | 
										settings   = utils.ParseTagSetting(tagSetting, ",")
 | 
				
			||||||
					length, _  = strconv.Atoi(settings["LENGTH"])
 | 
										length, _  = strconv.Atoi(settings["LENGTH"])
 | 
				
			||||||
				)
 | 
									)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,7 @@ package schema
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"gorm.io/gorm/utils"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
	"strings"
 | 
						"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`
 | 
					// 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 User struct {
 | 
				
			||||||
//     }
 | 
					//	  Toys []Toy `gorm:"polymorphic:Owner;"`
 | 
				
			||||||
//     type Pet struct {
 | 
					//	}
 | 
				
			||||||
//       Toy Toy `gorm:"polymorphic:Owner;"`
 | 
					//	type Pet struct {
 | 
				
			||||||
//     }
 | 
					//	  Toy Toy `gorm:"polymorphic:Owner;"`
 | 
				
			||||||
//     type Toy struct {
 | 
					//	}
 | 
				
			||||||
//       OwnerID   int
 | 
					//	type Toy struct {
 | 
				
			||||||
//       OwnerType string
 | 
					//	  OwnerID   int
 | 
				
			||||||
//     }
 | 
					//	  OwnerType string
 | 
				
			||||||
 | 
					//	}
 | 
				
			||||||
func (schema *Schema) buildPolymorphicRelation(relation *Relationship, field *Field, polymorphic string) {
 | 
					func (schema *Schema) buildPolymorphicRelation(relation *Relationship, field *Field, polymorphic string) {
 | 
				
			||||||
	relation.Polymorphic = &Polymorphic{
 | 
						relation.Polymorphic = &Polymorphic{
 | 
				
			||||||
		Value:           schema.Table,
 | 
							Value:           schema.Table,
 | 
				
			||||||
@ -555,7 +557,7 @@ func (rel *Relationship) ParseConstraint() *Constraint {
 | 
				
			|||||||
	var (
 | 
						var (
 | 
				
			||||||
		name     string
 | 
							name     string
 | 
				
			||||||
		idx      = strings.Index(str, ",")
 | 
							idx      = strings.Index(str, ",")
 | 
				
			||||||
		settings = ParseTagSetting(str, ",")
 | 
							settings = utils.ParseTagSetting(str, ",")
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// optimize match english letters and midline
 | 
						// optimize match english letters and midline
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,7 @@ package schema_test
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"gorm.io/gorm/utils"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
@ -44,7 +45,7 @@ func checkSchemaField(t *testing.T, s *schema.Schema, f *schema.Field, fc func(*
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if f.TagSettings == nil {
 | 
							if f.TagSettings == nil {
 | 
				
			||||||
			if f.Tag != "" {
 | 
								if f.Tag != "" {
 | 
				
			||||||
				f.TagSettings = schema.ParseTagSetting(f.Tag.Get("gorm"), ";")
 | 
									f.TagSettings = utils.ParseTagSetting(f.Tag.Get("gorm"), ";")
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				f.TagSettings = map[string]string{}
 | 
									f.TagSettings = map[string]string{}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
@ -13,37 +13,6 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var embeddedCacheKey = "embedded_cache_store"
 | 
					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) {
 | 
					func toColumns(val string) (results []string) {
 | 
				
			||||||
	if val != "" {
 | 
						if val != "" {
 | 
				
			||||||
		for _, v := range strings.Split(val, ",") {
 | 
							for _, v := range strings.Split(val, ",") {
 | 
				
			||||||
 | 
				
			|||||||
@ -131,3 +131,34 @@ func ToString(value interface{}) string {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return ""
 | 
						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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user