Skip to content

Commit 1a526e6

Browse files
committed
Fix NamingStrategy with embedded struct, close #3513
1 parent 6892044 commit 1a526e6

File tree

7 files changed

+107
-3
lines changed

7 files changed

+107
-3
lines changed

schema/field.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
326326

327327
cacheStore := &sync.Map{}
328328
cacheStore.Store(embeddedCacheKey, true)
329-
if field.EmbeddedSchema, err = Parse(fieldValue.Interface(), cacheStore, schema.namer); err != nil {
329+
if field.EmbeddedSchema, err = Parse(fieldValue.Interface(), cacheStore, embeddedNamer{Table: schema.Table, Namer: schema.namer}); err != nil {
330330
schema.err = err
331331
}
332332

schema/naming.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
type Namer interface {
1515
TableName(table string) string
1616
ColumnName(table, column string) string
17-
JoinTableName(table string) string
17+
JoinTableName(joinTable string) string
1818
RelationshipFKName(Relationship) string
1919
CheckerName(table, column string) string
2020
IndexName(table, column string) string

schema/naming_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package schema
22

33
import (
4+
"strings"
45
"testing"
56
)
67

@@ -32,3 +33,28 @@ func TestToDBName(t *testing.T) {
3233
}
3334
}
3435
}
36+
37+
type NewNamingStrategy struct {
38+
NamingStrategy
39+
}
40+
41+
func (ns NewNamingStrategy) ColumnName(table, column string) string {
42+
baseColumnName := ns.NamingStrategy.ColumnName(table, column)
43+
44+
if table == "" {
45+
return baseColumnName
46+
}
47+
48+
s := strings.Split(table, "_")
49+
50+
var prefix string
51+
switch len(s) {
52+
case 1:
53+
prefix = s[0][:3]
54+
case 2:
55+
prefix = s[0][:1] + s[1][:2]
56+
default:
57+
prefix = s[0][:1] + s[1][:1] + s[2][:1]
58+
}
59+
return prefix + "_" + baseColumnName
60+
}

schema/schema.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error)
9797
if tabler, ok := modelValue.Interface().(Tabler); ok {
9898
tableName = tabler.TableName()
9999
}
100+
if en, ok := namer.(embeddedNamer); ok {
101+
tableName = en.Table
102+
}
100103

101104
schema := &Schema{
102105
Name: modelType.Name(),

schema/schema_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package schema_test
22

33
import (
4+
"strings"
45
"sync"
56
"testing"
67

@@ -227,3 +228,72 @@ func TestEmbeddedStruct(t *testing.T) {
227228
})
228229
}
229230
}
231+
232+
type CustomizedNamingStrategy struct {
233+
schema.NamingStrategy
234+
}
235+
236+
func (ns CustomizedNamingStrategy) ColumnName(table, column string) string {
237+
baseColumnName := ns.NamingStrategy.ColumnName(table, column)
238+
239+
if table == "" {
240+
return baseColumnName
241+
}
242+
243+
s := strings.Split(table, "_")
244+
245+
var prefix string
246+
switch len(s) {
247+
case 1:
248+
prefix = s[0][:3]
249+
case 2:
250+
prefix = s[0][:1] + s[1][:2]
251+
default:
252+
prefix = s[0][:1] + s[1][:1] + s[2][:1]
253+
}
254+
return prefix + "_" + baseColumnName
255+
}
256+
257+
func TestEmbeddedStructForCustomizedNamingStrategy(t *testing.T) {
258+
type CorpBase struct {
259+
gorm.Model
260+
OwnerID string
261+
}
262+
263+
type Company struct {
264+
ID int
265+
OwnerID int
266+
Name string
267+
Ignored string `gorm:"-"`
268+
}
269+
270+
type Corp struct {
271+
CorpBase
272+
Base Company `gorm:"embedded;embeddedPrefix:company_"`
273+
}
274+
275+
cropSchema, err := schema.Parse(&Corp{}, &sync.Map{}, CustomizedNamingStrategy{schema.NamingStrategy{}})
276+
277+
if err != nil {
278+
t.Fatalf("failed to parse embedded struct with primary key, got error %v", err)
279+
}
280+
281+
fields := []schema.Field{
282+
{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"}},
283+
{Name: "ID", DBName: "company_cor_id", BindNames: []string{"Base", "ID"}, DataType: schema.Int, Size: 64, TagSettings: map[string]string{"EMBEDDED": "EMBEDDED", "EMBEDDEDPREFIX": "company_"}},
284+
{Name: "Name", DBName: "company_cor_name", BindNames: []string{"Base", "Name"}, DataType: schema.String, TagSettings: map[string]string{"EMBEDDED": "EMBEDDED", "EMBEDDEDPREFIX": "company_"}},
285+
{Name: "Ignored", BindNames: []string{"Base", "Ignored"}, TagSettings: map[string]string{"-": "-", "EMBEDDED": "EMBEDDED", "EMBEDDEDPREFIX": "company_"}},
286+
{Name: "OwnerID", DBName: "company_cor_owner_id", BindNames: []string{"Base", "OwnerID"}, DataType: schema.Int, Size: 64, TagSettings: map[string]string{"EMBEDDED": "EMBEDDED", "EMBEDDEDPREFIX": "company_"}},
287+
{Name: "OwnerID", DBName: "cor_owner_id", BindNames: []string{"CorpBase", "OwnerID"}, DataType: schema.String},
288+
}
289+
290+
for _, f := range fields {
291+
checkSchemaField(t, cropSchema, &f, func(f *schema.Field) {
292+
if f.Name != "Ignored" {
293+
f.Creatable = true
294+
f.Updatable = true
295+
f.Readable = true
296+
}
297+
})
298+
}
299+
}

schema/utils.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,8 @@ func ToQueryValues(table string, foreignKeys []string, foreignValues [][]interfa
190190
return columns, queryValues
191191
}
192192
}
193+
194+
type embeddedNamer struct {
195+
Table string
196+
Namer
197+
}

tests/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/jinzhu/now v1.1.1
88
github.com/lib/pq v1.6.0
99
gorm.io/driver/mysql v1.0.1
10-
gorm.io/driver/postgres v1.0.0
10+
gorm.io/driver/postgres v1.0.1
1111
gorm.io/driver/sqlite v1.1.3
1212
gorm.io/driver/sqlserver v1.0.4
1313
gorm.io/gorm v1.20.1

0 commit comments

Comments
 (0)