Remove the name cache from NamingStrategy.
This commit is contained in:
parent
403967a34c
commit
8c0c82e887
6
gorm.go
6
gorm.go
@ -92,12 +92,6 @@ func Open(dialector Dialector, config *Config) (db *DB, err error) {
|
|||||||
config.NamingStrategy = schema.NamingStrategy{}
|
config.NamingStrategy = schema.NamingStrategy{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case: initialize the smap if given Namer is a schema.NamingStrategy.
|
|
||||||
if v, ok := config.NamingStrategy.(schema.NamingStrategy); ok {
|
|
||||||
v.Init()
|
|
||||||
config.NamingStrategy = v
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.Logger == nil {
|
if config.Logger == nil {
|
||||||
config.Logger = logger.Default
|
config.Logger = logger.Default
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/jinzhu/inflection"
|
"github.com/jinzhu/inflection"
|
||||||
@ -31,31 +30,6 @@ type NamingStrategy struct {
|
|||||||
SingularTable bool
|
SingularTable bool
|
||||||
NameReplacer Replacer
|
NameReplacer Replacer
|
||||||
NoLowerCase bool
|
NoLowerCase bool
|
||||||
smap *safeSyncMap // Optional: gorm.Open initializes this by calling Init().
|
|
||||||
}
|
|
||||||
|
|
||||||
// safeSyncMap is a sync.Map that allows Load and Store to be called with a nil receiver.
|
|
||||||
type safeSyncMap sync.Map
|
|
||||||
|
|
||||||
// Load implements a nil-safe call to sync.Map's Load.
|
|
||||||
func (smap *safeSyncMap) Load(name string) (interface{}, bool) {
|
|
||||||
if smap == nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
return (*sync.Map)(smap).Load(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store implements a nil-safe call to sync.Map's Store.
|
|
||||||
func (smap *safeSyncMap) Store(name string, value interface{}) {
|
|
||||||
if smap == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
(*sync.Map)(smap).Store(name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init initializes a NamingStrategy instance smap ptr.
|
|
||||||
func (ns *NamingStrategy) Init() {
|
|
||||||
ns.smap = &safeSyncMap{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName convert string to table name
|
// TableName convert string to table name
|
||||||
@ -128,17 +102,13 @@ func init() {
|
|||||||
func (ns NamingStrategy) toDBName(name string) string {
|
func (ns NamingStrategy) toDBName(name string) string {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return ""
|
return ""
|
||||||
} else if v, ok := ns.smap.Load(name); ok {
|
|
||||||
return v.(string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
origName := name
|
|
||||||
if ns.NameReplacer != nil {
|
if ns.NameReplacer != nil {
|
||||||
name = ns.NameReplacer.Replace(name)
|
name = ns.NameReplacer.Replace(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ns.NoLowerCase {
|
if ns.NoLowerCase {
|
||||||
ns.smap.Store(origName, name)
|
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +149,5 @@ func (ns NamingStrategy) toDBName(name string) string {
|
|||||||
buf.WriteByte(value[len(value)-1])
|
buf.WriteByte(value[len(value)-1])
|
||||||
}
|
}
|
||||||
ret := buf.String()
|
ret := buf.String()
|
||||||
ns.smap.Store(origName, ret)
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
@ -168,89 +168,3 @@ func TestCustomReplacerWithNoLowerCase(t *testing.T) {
|
|||||||
t.Errorf("invalid column name generated, got %v", columdName)
|
t.Errorf("invalid column name generated, got %v", columdName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNamingStrategySmapInit(t *testing.T) {
|
|
||||||
ncalls := 0 // Track how many times testReplacer was called
|
|
||||||
args := []string{} // Track the arguments given to each call
|
|
||||||
|
|
||||||
// This CustomReplacer keeps track of how many times it was called.
|
|
||||||
var testReplacer = CustomReplacer{
|
|
||||||
func(name string) string {
|
|
||||||
args = append(args, name)
|
|
||||||
ncalls++
|
|
||||||
return name
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// First NamingStrategy instance using our CustomReplacer.
|
|
||||||
var ns = NamingStrategy{
|
|
||||||
NameReplacer: testReplacer,
|
|
||||||
}
|
|
||||||
|
|
||||||
// A different NamingStrategy instance does not share the same smap.
|
|
||||||
var ns2 = NamingStrategy{
|
|
||||||
NameReplacer: testReplacer,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions to make assertions about the CustomReplacer.
|
|
||||||
var expectCalls = func(expected int) {
|
|
||||||
t.Helper()
|
|
||||||
if ncalls != expected {
|
|
||||||
t.Errorf("testReplacer called unexpected # of times, got %v; expected %v", ncalls, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var expectNthCallArg = func(n int, expected string) {
|
|
||||||
t.Helper()
|
|
||||||
if len(args) <= n {
|
|
||||||
t.Errorf("cannot expect Nth arg: testReplacer was not called %v times", n)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if args[n] != expected {
|
|
||||||
t.Errorf("testReplacer called with unexpected argument, got '%v'; expected '%v'", args[n], expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This will call the Replacer: there is no smap.
|
|
||||||
ns.IndexName("public.table", "name")
|
|
||||||
expectCalls(1)
|
|
||||||
expectNthCallArg(0, "name")
|
|
||||||
|
|
||||||
// This will call the Replacer: there is no smap.
|
|
||||||
ns.IndexName("public.table", "name")
|
|
||||||
expectCalls(2)
|
|
||||||
expectNthCallArg(1, "name")
|
|
||||||
|
|
||||||
// Now call Init() to create the smap. The next call will be cached.
|
|
||||||
ns.Init()
|
|
||||||
|
|
||||||
// This will call the Replacer: smap not populated yet.
|
|
||||||
ns.IndexName("public.table", "name")
|
|
||||||
expectCalls(3)
|
|
||||||
expectNthCallArg(2, "name")
|
|
||||||
|
|
||||||
// This will not call the Replacer: "name" is in the smap.
|
|
||||||
ns.IndexName("public.table", "name")
|
|
||||||
expectCalls(3)
|
|
||||||
|
|
||||||
// This will call the Replacer: it's a different name, not in the smap.
|
|
||||||
ns.IndexName("public.table", "name2")
|
|
||||||
expectCalls(4)
|
|
||||||
expectNthCallArg(3, "name2")
|
|
||||||
|
|
||||||
// This will call the Replacer: ns2 has not been initialized.
|
|
||||||
ns2.IndexName("public.table", "name")
|
|
||||||
expectCalls(5)
|
|
||||||
expectNthCallArg(4, "name")
|
|
||||||
|
|
||||||
ns2.Init()
|
|
||||||
|
|
||||||
// This will call the Replacer: ns2's smap is empty.
|
|
||||||
ns2.IndexName("public.table", "name")
|
|
||||||
expectCalls(6)
|
|
||||||
expectNthCallArg(5, "name")
|
|
||||||
|
|
||||||
// This will not call the Replacer: "name" is now in ns2's smap.
|
|
||||||
ns2.IndexName("public.table", "name")
|
|
||||||
expectCalls(6)
|
|
||||||
expectNthCallArg(5, "name")
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user