Fix naming longer then 64 chars with dots in table

Ensures that foreign key relationships and indexes are given
syntactically valid names when their name length exceeds 64 characters
and they contained dot characters within the name. This is most often
relevant when a Postgres table name is fully qualified by including its schema
as part of its name
This commit is contained in:
mnussbaum 2022-01-31 10:58:51 -08:00
parent f19b84d104
commit 59b92a24a6
3 changed files with 38 additions and 3 deletions

View File

@ -3,7 +3,6 @@ package schema
import (
"crypto/sha1"
"encoding/hex"
"fmt"
"regexp"
"strings"
"unicode/utf8"
@ -95,7 +94,7 @@ func (ns NamingStrategy) formatName(prefix, table, name string) string {
h.Write([]byte(formattedName))
bs := h.Sum(nil)
formattedName = fmt.Sprintf("%v%v%v", prefix, table, name)[0:56] + hex.EncodeToString(bs)[:8]
formattedName = formattedName[0:56] + hex.EncodeToString(bs)[:8]
}
return formattedName
}

View File

@ -193,7 +193,7 @@ func TestFormatNameWithStringLongerThan64Characters(t *testing.T) {
ns := NamingStrategy{}
formattedName := ns.formatName("prefix", "table", "thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString")
if formattedName != "prefixtablethisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryLo180f2c67" {
if formattedName != "prefix_table_thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVery180f2c67" {
t.Errorf("invalid formatted name generated, got %v", formattedName)
}
}

View File

@ -576,3 +576,39 @@ func TestHasManySameForeignKey(t *testing.T) {
References: []Reference{{"ID", "User", "UserRefer", "Profile", "", true}},
})
}
type Author struct {
gorm.Model
}
type Book struct {
gorm.Model
Author Author
AuthorID uint
}
func (Book) TableName() string {
return "my_schema.a_very_very_very_very_very_very_very_very_long_table_name"
}
func TestParseConstraintNameWithSchemaQualifiedLongTableName(t *testing.T) {
s, err := schema.Parse(
&Book{},
&sync.Map{},
schema.NamingStrategy{},
)
if err != nil {
t.Fatalf("Failed to parse schema")
}
expectedConstraintName := "fk_my_schema_a_very_very_very_very_very_very_very_very_l4db13eec"
constraint := s.Relationships.Relations["Author"].ParseConstraint()
if constraint.Name != expectedConstraintName {
t.Fatalf(
"expected constraint name %s, got %s",
expectedConstraintName,
constraint.Name,
)
}
}