Fix NamingStrategy with embedded struct, close #3513
This commit is contained in:
		
							parent
							
								
									68920449f9
								
							
						
					
					
						commit
						1a526e6802
					
				| @ -326,7 +326,7 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { | ||||
| 
 | ||||
| 			cacheStore := &sync.Map{} | ||||
| 			cacheStore.Store(embeddedCacheKey, true) | ||||
| 			if field.EmbeddedSchema, err = Parse(fieldValue.Interface(), cacheStore, schema.namer); err != nil { | ||||
| 			if field.EmbeddedSchema, err = Parse(fieldValue.Interface(), cacheStore, embeddedNamer{Table: schema.Table, Namer: schema.namer}); err != nil { | ||||
| 				schema.err = err | ||||
| 			} | ||||
| 
 | ||||
|  | ||||
| @ -14,7 +14,7 @@ import ( | ||||
| type Namer interface { | ||||
| 	TableName(table string) string | ||||
| 	ColumnName(table, column string) string | ||||
| 	JoinTableName(table string) string | ||||
| 	JoinTableName(joinTable string) string | ||||
| 	RelationshipFKName(Relationship) string | ||||
| 	CheckerName(table, column string) string | ||||
| 	IndexName(table, column string) string | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| package schema | ||||
| 
 | ||||
| import ( | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| ) | ||||
| 
 | ||||
| @ -32,3 +33,28 @@ func TestToDBName(t *testing.T) { | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type NewNamingStrategy struct { | ||||
| 	NamingStrategy | ||||
| } | ||||
| 
 | ||||
| func (ns NewNamingStrategy) ColumnName(table, column string) string { | ||||
| 	baseColumnName := ns.NamingStrategy.ColumnName(table, column) | ||||
| 
 | ||||
| 	if table == "" { | ||||
| 		return baseColumnName | ||||
| 	} | ||||
| 
 | ||||
| 	s := strings.Split(table, "_") | ||||
| 
 | ||||
| 	var prefix string | ||||
| 	switch len(s) { | ||||
| 	case 1: | ||||
| 		prefix = s[0][:3] | ||||
| 	case 2: | ||||
| 		prefix = s[0][:1] + s[1][:2] | ||||
| 	default: | ||||
| 		prefix = s[0][:1] + s[1][:1] + s[2][:1] | ||||
| 	} | ||||
| 	return prefix + "_" + baseColumnName | ||||
| } | ||||
|  | ||||
| @ -97,6 +97,9 @@ func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) | ||||
| 	if tabler, ok := modelValue.Interface().(Tabler); ok { | ||||
| 		tableName = tabler.TableName() | ||||
| 	} | ||||
| 	if en, ok := namer.(embeddedNamer); ok { | ||||
| 		tableName = en.Table | ||||
| 	} | ||||
| 
 | ||||
| 	schema := &Schema{ | ||||
| 		Name:           modelType.Name(), | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| package schema_test | ||||
| 
 | ||||
| import ( | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"testing" | ||||
| 
 | ||||
| @ -227,3 +228,72 @@ func TestEmbeddedStruct(t *testing.T) { | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type CustomizedNamingStrategy struct { | ||||
| 	schema.NamingStrategy | ||||
| } | ||||
| 
 | ||||
| func (ns CustomizedNamingStrategy) ColumnName(table, column string) string { | ||||
| 	baseColumnName := ns.NamingStrategy.ColumnName(table, column) | ||||
| 
 | ||||
| 	if table == "" { | ||||
| 		return baseColumnName | ||||
| 	} | ||||
| 
 | ||||
| 	s := strings.Split(table, "_") | ||||
| 
 | ||||
| 	var prefix string | ||||
| 	switch len(s) { | ||||
| 	case 1: | ||||
| 		prefix = s[0][:3] | ||||
| 	case 2: | ||||
| 		prefix = s[0][:1] + s[1][:2] | ||||
| 	default: | ||||
| 		prefix = s[0][:1] + s[1][:1] + s[2][:1] | ||||
| 	} | ||||
| 	return prefix + "_" + baseColumnName | ||||
| } | ||||
| 
 | ||||
| func TestEmbeddedStructForCustomizedNamingStrategy(t *testing.T) { | ||||
| 	type CorpBase struct { | ||||
| 		gorm.Model | ||||
| 		OwnerID string | ||||
| 	} | ||||
| 
 | ||||
| 	type Company struct { | ||||
| 		ID      int | ||||
| 		OwnerID int | ||||
| 		Name    string | ||||
| 		Ignored string `gorm:"-"` | ||||
| 	} | ||||
| 
 | ||||
| 	type Corp struct { | ||||
| 		CorpBase | ||||
| 		Base Company `gorm:"embedded;embeddedPrefix:company_"` | ||||
| 	} | ||||
| 
 | ||||
| 	cropSchema, err := schema.Parse(&Corp{}, &sync.Map{}, CustomizedNamingStrategy{schema.NamingStrategy{}}) | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("failed to parse embedded struct with primary key, got error %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	fields := []schema.Field{ | ||||
| 		{Name: "ID", DBName: "cor_id", BindNames: []string{"CorpBase", "Model", "ID"}, DataType: schema.Uint, PrimaryKey: true, Size: 64, HasDefaultValue: true, AutoIncrement: true, TagSettings: map[string]string{"PRIMARYKEY": "PRIMARYKEY"}}, | ||||
| 		{Name: "ID", DBName: "company_cor_id", BindNames: []string{"Base", "ID"}, DataType: schema.Int, Size: 64, TagSettings: map[string]string{"EMBEDDED": "EMBEDDED", "EMBEDDEDPREFIX": "company_"}}, | ||||
| 		{Name: "Name", DBName: "company_cor_name", BindNames: []string{"Base", "Name"}, DataType: schema.String, TagSettings: map[string]string{"EMBEDDED": "EMBEDDED", "EMBEDDEDPREFIX": "company_"}}, | ||||
| 		{Name: "Ignored", BindNames: []string{"Base", "Ignored"}, TagSettings: map[string]string{"-": "-", "EMBEDDED": "EMBEDDED", "EMBEDDEDPREFIX": "company_"}}, | ||||
| 		{Name: "OwnerID", DBName: "company_cor_owner_id", BindNames: []string{"Base", "OwnerID"}, DataType: schema.Int, Size: 64, TagSettings: map[string]string{"EMBEDDED": "EMBEDDED", "EMBEDDEDPREFIX": "company_"}}, | ||||
| 		{Name: "OwnerID", DBName: "cor_owner_id", BindNames: []string{"CorpBase", "OwnerID"}, DataType: schema.String}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, f := range fields { | ||||
| 		checkSchemaField(t, cropSchema, &f, func(f *schema.Field) { | ||||
| 			if f.Name != "Ignored" { | ||||
| 				f.Creatable = true | ||||
| 				f.Updatable = true | ||||
| 				f.Readable = true | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -190,3 +190,8 @@ func ToQueryValues(table string, foreignKeys []string, foreignValues [][]interfa | ||||
| 		return columns, queryValues | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type embeddedNamer struct { | ||||
| 	Table string | ||||
| 	Namer | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,7 @@ require ( | ||||
| 	github.com/jinzhu/now v1.1.1 | ||||
| 	github.com/lib/pq v1.6.0 | ||||
| 	gorm.io/driver/mysql v1.0.1 | ||||
| 	gorm.io/driver/postgres v1.0.0 | ||||
| 	gorm.io/driver/postgres v1.0.1 | ||||
| 	gorm.io/driver/sqlite v1.1.3 | ||||
| 	gorm.io/driver/sqlserver v1.0.4 | ||||
| 	gorm.io/gorm v1.20.1 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinzhu
						Jinzhu