Skip to content

Commit

Permalink
Use pkg name in tableMap for unique cache keys (#479)
Browse files Browse the repository at this point in the history
When using two structs from different packages where both structs have the same name as models, the `tableMap` would incorrectly set up as only the struct's name is used as the cache key.

This patch uses the package path and the struct name to generate unique cache keys across go projects.

Closes #477

Signed-off-by: aeneasr <aeneas@ory.sh>
  • Loading branch information
aeneasr authored and stanislas-m committed Nov 29, 2019
1 parent 11bd52a commit d9c4e3c
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 10 deletions.
2 changes: 1 addition & 1 deletion genny/fizz/cempty/mocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ type mockTranslator struct{}

func (mockTranslator) Name() string {
return "test"
}
}
22 changes: 13 additions & 9 deletions model.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,23 @@ func (m *Model) TableName() string {
}

t := reflect.TypeOf(m.Value)
name := m.typeName(t)
name, cacheKey := m.typeName(t)

defer tableMapMu.Unlock()
tableMapMu.Lock()

if tableMap[name] == "" {
if tableMap[cacheKey] == "" {
m.tableName = nflect.Tableize(name)
tableMap[name] = m.tableName
tableMap[cacheKey] = m.tableName
}
return tableMap[name]
return tableMap[cacheKey]
}

func (m *Model) typeName(t reflect.Type) string {
func (m *Model) cacheKey(t reflect.Type) string {
return t.PkgPath() + "." + t.Name()
}

func (m *Model) typeName(t reflect.Type) (name, cacheKey string) {
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
Expand All @@ -117,14 +121,14 @@ func (m *Model) typeName(t reflect.Type) string {
v := reflect.New(el)
out := v.MethodByName("TableName").Call([]reflect.Value{})
name := out[0].String()
if tableMap[el.Name()] == "" {
tableMap[el.Name()] = name
if tableMap[m.cacheKey(el)] == "" {
tableMap[m.cacheKey(el)] = name
}
}

return el.Name()
return el.Name(), m.cacheKey(el)
default:
return t.Name()
return t.Name(), m.cacheKey(t)
}
}

Expand Down
13 changes: 13 additions & 0 deletions model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import (
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/gobuffalo/pop/testdata/models/a"
"github.com/gobuffalo/pop/testdata/models/b"
)

func Test_Model_TableName(t *testing.T) {
Expand Down Expand Up @@ -36,6 +40,15 @@ func (tn) TableName() string {
return "this is my table name"
}

// A failing test case for #477
func Test_TableNameCache(t *testing.T) {
r := assert.New(t)
r.Equal("usera", (&Model{Value: a.User{}}).TableName())
r.Equal("userb", (&Model{Value: b.User{}}).TableName())
r.Equal("usera", (&Model{Value: []a.User{}}).TableName())
r.Equal("userb", (&Model{Value: []b.User{}}).TableName())
}

func Test_TableName(t *testing.T) {
r := require.New(t)

Expand Down
7 changes: 7 additions & 0 deletions testdata/models/a/user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package a

type User struct{}

func (u User) TableName() string {
return "usera"
}
7 changes: 7 additions & 0 deletions testdata/models/b/user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package b

type User struct{}

func (u User) TableName() string {
return "userb"
}

0 comments on commit d9c4e3c

Please sign in to comment.