diff --git a/schema/naming.go b/schema/naming.go index f6d15f5a..a52f2fe7 100644 --- a/schema/naming.go +++ b/schema/naming.go @@ -20,11 +20,16 @@ type Namer interface { IndexName(table, column string) string } +// Replacer replacer interface like strings.Replacer +type Replacer interface { + Replace(name string) string +} + // NamingStrategy tables, columns naming strategy type NamingStrategy struct { TablePrefix string SingularTable bool - NameReplacer *strings.Replacer + NameReplacer Replacer } // TableName convert string to table name @@ -95,6 +100,11 @@ func init() { commonInitialismsReplacer = strings.NewReplacer(commonInitialismsForReplacer...) } +// reset should be called before each unit test. It clears out the cached names from smap. TODO: make smap part of NamingStrategy instead of a global singleton. +func reset() { + smap = sync.Map{} +} + func (ns NamingStrategy) toDBName(name string) string { if name == "" { return "" diff --git a/schema/naming_test.go b/schema/naming_test.go index b7a32160..32e96d1e 100644 --- a/schema/naming_test.go +++ b/schema/naming_test.go @@ -6,6 +6,8 @@ import ( ) func TestToDBName(t *testing.T) { + reset() + var maps = map[string]string{ "": "", "x": "x", @@ -36,6 +38,8 @@ func TestToDBName(t *testing.T) { } func TestNamingStrategy(t *testing.T) { + reset() + var ns = NamingStrategy{ TablePrefix: "public.", SingularTable: true, @@ -72,3 +76,56 @@ func TestNamingStrategy(t *testing.T) { t.Errorf("invalid column name generated, got %v", columdName) } } + +type CustomReplacer struct { + f func(string) string +} + +func (r CustomReplacer) Replace(name string) string { + return r.f(name) +} + +func TestCustomReplacer(t *testing.T) { + reset() + + var ns = NamingStrategy{ + TablePrefix: "public.", + SingularTable: true, + NameReplacer: CustomReplacer{ + func(name string) string { + replaced := "REPLACED_" + strings.ToUpper(name) + return strings.NewReplacer("CID", "_Cid").Replace(replaced) + }, + }, + } + + idxName := ns.IndexName("public.table", "name") + if idxName != "idx_public_table_replaced_name" { + t.Errorf("invalid index name generated, got %v", idxName) + } + + chkName := ns.CheckerName("public.table", "name") + if chkName != "chk_public_table_name" { + t.Errorf("invalid checker name generated, got %v", chkName) + } + + joinTable := ns.JoinTableName("user_languages") + if joinTable != "public.user_languages" { // Seems like a bug in NamingStrategy to skip the Replacer when the name is lowercase here. + t.Errorf("invalid join table generated, got %v", joinTable) + } + + joinTable2 := ns.JoinTableName("UserLanguage") + if joinTable2 != "public.replaced_userlanguage" { + t.Errorf("invalid join table generated, got %v", joinTable2) + } + + tableName := ns.TableName("Company") + if tableName != "public.replaced_company" { + t.Errorf("invalid table name generated, got %v", tableName) + } + + columdName := ns.ColumnName("", "NameCID") + if columdName != "replaced_name_cid" { + t.Errorf("invalid column name generated, got %v", columdName) + } +}