issue #6098
This commit is contained in:
parent
cc2d46e5be
commit
f3503275da
15
gorm.go
15
gorm.go
@ -144,7 +144,20 @@ func Open(dialector Dialector, opts ...Option) (db *DB, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.NamingStrategy == nil {
|
if config.NamingStrategy == nil {
|
||||||
config.NamingStrategy = schema.NamingStrategy{}
|
// Set default value of IdentifierMaxLength according to the database type
|
||||||
|
identifierMaxLength := 64
|
||||||
|
switch dialector.Name() {
|
||||||
|
case "mysql":
|
||||||
|
identifierMaxLength = 64
|
||||||
|
case "postgres":
|
||||||
|
identifierMaxLength = 63
|
||||||
|
case "sqlite":
|
||||||
|
identifierMaxLength = 64
|
||||||
|
case "sqlserver":
|
||||||
|
identifierMaxLength = 128
|
||||||
|
}
|
||||||
|
|
||||||
|
config.NamingStrategy = schema.NamingStrategy{NamingStrategyConfig: schema.NamingStrategyConfig{IdentifierMaxLength: identifierMaxLength}}
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Logger == nil {
|
if config.Logger == nil {
|
||||||
|
@ -15,7 +15,7 @@ type UserCheck struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestParseCheck(t *testing.T) {
|
func TestParseCheck(t *testing.T) {
|
||||||
user, err := schema.Parse(&UserCheck{}, &sync.Map{}, schema.NamingStrategy{})
|
user, err := schema.Parse(&UserCheck{}, &sync.Map{}, schema.NamingStrategy{NamingStrategyConfig: schema.NamingStrategyConfig{IdentifierMaxLength: 64}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to parse user check, got error %v", err)
|
t.Fatalf("failed to parse user check, got error %v", err)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ type CompIdxLevel2B struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestParseIndex(t *testing.T) {
|
func TestParseIndex(t *testing.T) {
|
||||||
user, err := schema.Parse(&UserIndex{}, &sync.Map{}, schema.NamingStrategy{})
|
user, err := schema.Parse(&UserIndex{}, &sync.Map{}, schema.NamingStrategy{NamingStrategyConfig: schema.NamingStrategyConfig{IdentifierMaxLength: 64}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to parse user index, got error %v", err)
|
t.Fatalf("failed to parse user index, got error %v", err)
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,17 @@ type NamingStrategy struct {
|
|||||||
SingularTable bool
|
SingularTable bool
|
||||||
NameReplacer Replacer
|
NameReplacer Replacer
|
||||||
NoLowerCase bool
|
NoLowerCase bool
|
||||||
|
NamingStrategyConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// This struct is used to configure the behavior NamingStrategy, according to DB.
|
||||||
|
// For example, in MySQL, the maximum length of an identifier is 64 characters.
|
||||||
|
// In PostgreSQL, the maximum length of an identifier is 63 characters.
|
||||||
|
// In SQL Server, the maximum length of an identifier is 128 characters.
|
||||||
|
// In SQLite, the maximum length of an identifier is unlimited.
|
||||||
|
// In future, we may add more options to NamingStrategyConfig.
|
||||||
|
type NamingStrategyConfig struct {
|
||||||
|
IdentifierMaxLength int
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName convert string to table name
|
// TableName convert string to table name
|
||||||
@ -89,12 +100,12 @@ func (ns NamingStrategy) formatName(prefix, table, name string) string {
|
|||||||
prefix, table, name,
|
prefix, table, name,
|
||||||
}, "_"), ".", "_")
|
}, "_"), ".", "_")
|
||||||
|
|
||||||
if utf8.RuneCountInString(formattedName) > 64 {
|
if utf8.RuneCountInString(formattedName) > ns.IdentifierMaxLength {
|
||||||
h := sha1.New()
|
h := sha1.New()
|
||||||
h.Write([]byte(formattedName))
|
h.Write([]byte(formattedName))
|
||||||
bs := h.Sum(nil)
|
bs := h.Sum(nil)
|
||||||
|
|
||||||
formattedName = formattedName[0:56] + hex.EncodeToString(bs)[:8]
|
formattedName = formattedName[0:ns.IdentifierMaxLength-8] + hex.EncodeToString(bs)[:8]
|
||||||
}
|
}
|
||||||
return formattedName
|
return formattedName
|
||||||
}
|
}
|
||||||
|
@ -57,9 +57,10 @@ func TestToDBName(t *testing.T) {
|
|||||||
|
|
||||||
func TestNamingStrategy(t *testing.T) {
|
func TestNamingStrategy(t *testing.T) {
|
||||||
ns := NamingStrategy{
|
ns := NamingStrategy{
|
||||||
TablePrefix: "public.",
|
TablePrefix: "public.",
|
||||||
SingularTable: true,
|
SingularTable: true,
|
||||||
NameReplacer: strings.NewReplacer("CID", "Cid"),
|
NameReplacer: strings.NewReplacer("CID", "Cid"),
|
||||||
|
NamingStrategyConfig: NamingStrategyConfig{IdentifierMaxLength: 64},
|
||||||
}
|
}
|
||||||
idxName := ns.IndexName("public.table", "name")
|
idxName := ns.IndexName("public.table", "name")
|
||||||
|
|
||||||
@ -111,7 +112,8 @@ func TestCustomReplacer(t *testing.T) {
|
|||||||
return strings.NewReplacer("CID", "_Cid").Replace(replaced)
|
return strings.NewReplacer("CID", "_Cid").Replace(replaced)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NoLowerCase: false,
|
NamingStrategyConfig: NamingStrategyConfig{IdentifierMaxLength: 64},
|
||||||
|
NoLowerCase: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
idxName := ns.IndexName("public.table", "name")
|
idxName := ns.IndexName("public.table", "name")
|
||||||
@ -155,7 +157,8 @@ func TestCustomReplacerWithNoLowerCase(t *testing.T) {
|
|||||||
return strings.NewReplacer("CID", "_Cid").Replace(replaced)
|
return strings.NewReplacer("CID", "_Cid").Replace(replaced)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NoLowerCase: true,
|
NamingStrategyConfig: NamingStrategyConfig{IdentifierMaxLength: 64},
|
||||||
|
NoLowerCase: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
idxName := ns.IndexName("public.table", "name")
|
idxName := ns.IndexName("public.table", "name")
|
||||||
@ -189,13 +192,27 @@ func TestCustomReplacerWithNoLowerCase(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFormatNameWithStringLongerThan64Characters(t *testing.T) {
|
func TestFormatNameWithStringLongerThanMaxIdentifierLength(t *testing.T) {
|
||||||
ns := NamingStrategy{}
|
ns := NamingStrategy{NamingStrategyConfig: NamingStrategyConfig{IdentifierMaxLength: 63}}
|
||||||
|
|
||||||
formattedName := ns.formatName("prefix", "table", "thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString")
|
formattedName := ns.formatName("prefix", "table", "thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString")
|
||||||
|
if formattedName != "prefix_table_thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVer180f2c67" {
|
||||||
|
t.Errorf("invalid formatted name generated, got %v", formattedName)
|
||||||
|
}
|
||||||
|
|
||||||
|
ns = NamingStrategy{NamingStrategyConfig: NamingStrategyConfig{IdentifierMaxLength: 64}}
|
||||||
|
|
||||||
|
formattedName = ns.formatName("prefix", "table", "thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString")
|
||||||
if formattedName != "prefix_table_thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVery180f2c67" {
|
if formattedName != "prefix_table_thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVery180f2c67" {
|
||||||
t.Errorf("invalid formatted name generated, got %v", formattedName)
|
t.Errorf("invalid formatted name generated, got %v", formattedName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ns = NamingStrategy{NamingStrategyConfig: NamingStrategyConfig{IdentifierMaxLength: 128}}
|
||||||
|
|
||||||
|
formattedName = ns.formatName("prefix", "table", "thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString")
|
||||||
|
if formattedName != "prefix_table_thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVery81f06061" {
|
||||||
|
t.Errorf("invalid formatted name generated, got %v", formattedName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReplaceEmptyTableName(t *testing.T) {
|
func TestReplaceEmptyTableName(t *testing.T) {
|
||||||
|
@ -642,7 +642,7 @@ func TestParseConstraintNameWithSchemaQualifiedLongTableName(t *testing.T) {
|
|||||||
s, err := schema.Parse(
|
s, err := schema.Parse(
|
||||||
&Book{},
|
&Book{},
|
||||||
&sync.Map{},
|
&sync.Map{},
|
||||||
schema.NamingStrategy{},
|
schema.NamingStrategy{NamingStrategyConfig: schema.NamingStrategyConfig{IdentifierMaxLength: 64}},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to parse schema")
|
t.Fatalf("Failed to parse schema")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user