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{}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
config.Logger = logger.Default
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/jinzhu/inflection"
|
||||
@ -31,31 +30,6 @@ type NamingStrategy struct {
|
||||
SingularTable bool
|
||||
NameReplacer Replacer
|
||||
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
|
||||
@ -128,17 +102,13 @@ func init() {
|
||||
func (ns NamingStrategy) toDBName(name string) string {
|
||||
if name == "" {
|
||||
return ""
|
||||
} else if v, ok := ns.smap.Load(name); ok {
|
||||
return v.(string)
|
||||
}
|
||||
|
||||
origName := name
|
||||
if ns.NameReplacer != nil {
|
||||
name = ns.NameReplacer.Replace(name)
|
||||
}
|
||||
|
||||
if ns.NoLowerCase {
|
||||
ns.smap.Store(origName, name)
|
||||
return name
|
||||
}
|
||||
|
||||
@ -179,6 +149,5 @@ func (ns NamingStrategy) toDBName(name string) string {
|
||||
buf.WriteByte(value[len(value)-1])
|
||||
}
|
||||
ret := buf.String()
|
||||
ns.smap.Store(origName, ret)
|
||||
return ret
|
||||
}
|
||||
|
@ -168,89 +168,3 @@ func TestCustomReplacerWithNoLowerCase(t *testing.T) {
|
||||
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