Merge branch 'master' into master

This commit is contained in:
Adem Özay 2018-08-20 14:30:07 +03:00 committed by GitHub
commit 4ab3223f03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 43 additions and 32 deletions

View File

@ -14,8 +14,14 @@ func preloadCallback(scope *Scope) {
return return
} }
if _, ok := scope.Get("gorm:auto_preload"); ok { if ap, ok := scope.Get("gorm:auto_preload"); ok {
// If gorm:auto_preload IS NOT a bool then auto preload.
// Else if it IS a bool, use the value
if apb, ok := ap.(bool); !ok {
autoPreload(scope) autoPreload(scope)
} else if apb {
autoPreload(scope)
}
} }
if scope.Search.preload == nil || scope.HasError() { if scope.Search.preload == nil || scope.HasError() {

View File

@ -6,7 +6,7 @@ import (
) )
var ( var (
// ErrRecordNotFound record not found error, happens when haven't find any matched data when looking up with a struct // ErrRecordNotFound record not found error, happens when only haven't find any matched data when looking up with a struct, finding a slice won't return this error
ErrRecordNotFound = errors.New("record not found") ErrRecordNotFound = errors.New("record not found")
// ErrInvalidSQL invalid SQL error, happens when you passed invalid SQL // ErrInvalidSQL invalid SQL error, happens when you passed invalid SQL
ErrInvalidSQL = errors.New("invalid SQL") ErrInvalidSQL = errors.New("invalid SQL")

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"strings" "strings"
"sync"
"time" "time"
) )
@ -162,7 +163,7 @@ func (s *DB) HasBlockGlobalUpdate() bool {
// SingularTable use singular table by default // SingularTable use singular table by default
func (s *DB) SingularTable(enable bool) { func (s *DB) SingularTable(enable bool) {
modelStructsMap = newModelStructsMap() modelStructsMap = sync.Map{}
s.parent.singularTable = enable s.parent.singularTable = enable
} }

View File

@ -17,28 +17,7 @@ var DefaultTableNameHandler = func(db *DB, defaultTableName string) string {
return defaultTableName return defaultTableName
} }
type safeModelStructsMap struct { var modelStructsMap sync.Map
m map[reflect.Type]*ModelStruct
l *sync.RWMutex
}
func (s *safeModelStructsMap) Set(key reflect.Type, value *ModelStruct) {
s.l.Lock()
defer s.l.Unlock()
s.m[key] = value
}
func (s *safeModelStructsMap) Get(key reflect.Type) *ModelStruct {
s.l.RLock()
defer s.l.RUnlock()
return s.m[key]
}
func newModelStructsMap() *safeModelStructsMap {
return &safeModelStructsMap{l: new(sync.RWMutex), m: make(map[reflect.Type]*ModelStruct)}
}
var modelStructsMap = newModelStructsMap()
// ModelStruct model definition // ModelStruct model definition
type ModelStruct struct { type ModelStruct struct {
@ -48,7 +27,7 @@ type ModelStruct struct {
defaultTableName string defaultTableName string
} }
// TableName get model's table name // TableName returns model's table name
func (s *ModelStruct) TableName(db *DB) string { func (s *ModelStruct) TableName(db *DB) string {
if s.defaultTableName == "" && db != nil && s.ModelType != nil { if s.defaultTableName == "" && db != nil && s.ModelType != nil {
// Set default table name // Set default table name
@ -152,8 +131,8 @@ func (scope *Scope) GetModelStruct() *ModelStruct {
} }
// Get Cached model struct // Get Cached model struct
if value := modelStructsMap.Get(reflectType); value != nil { if value, ok := modelStructsMap.Load(reflectType); ok && value != nil {
return value return value.(*ModelStruct)
} }
modelStruct.ModelType = reflectType modelStruct.ModelType = reflectType
@ -601,7 +580,7 @@ func (scope *Scope) GetModelStruct() *ModelStruct {
} }
} }
modelStructsMap.Set(reflectType, &modelStruct) modelStructsMap.Store(reflectType, &modelStruct)
return &modelStruct return &modelStruct
} }

View File

@ -123,6 +123,31 @@ func TestAutoPreload(t *testing.T) {
} }
} }
func TestAutoPreloadFalseDoesntPreload(t *testing.T) {
user1 := getPreloadUser("auto_user1")
DB.Save(user1)
preloadDB := DB.Set("gorm:auto_preload", false).Where("role = ?", "Preload")
var user User
preloadDB.Find(&user)
if user.BillingAddress.Address1 != "" {
t.Error("AutoPreload was set to fasle, but still fetched data")
}
user2 := getPreloadUser("auto_user2")
DB.Save(user2)
var users []User
preloadDB.Find(&users)
for _, user := range users {
if user.BillingAddress.Address1 != "" {
t.Error("AutoPreload was set to fasle, but still fetched data")
}
}
}
func TestNestedPreload1(t *testing.T) { func TestNestedPreload1(t *testing.T) {
type ( type (
Level1 struct { Level1 struct {

View File

@ -586,10 +586,10 @@ func (scope *Scope) buildCondition(clause map[string]interface{}, include bool)
scope.Err(fmt.Errorf("invalid query condition: %v", value)) scope.Err(fmt.Errorf("invalid query condition: %v", value))
return return
} }
scopeQuotedTableName := newScope.QuotedTableName()
for _, field := range newScope.Fields() { for _, field := range newScope.Fields() {
if !field.IsIgnored && !field.IsBlank { if !field.IsIgnored && !field.IsBlank {
sqls = append(sqls, fmt.Sprintf("(%v.%v %s %v)", quotedTableName, scope.Quote(field.DBName), equalSQL, scope.AddToVars(field.Field.Interface()))) sqls = append(sqls, fmt.Sprintf("(%v.%v %s %v)", scopeQuotedTableName, scope.Quote(field.DBName), equalSQL, scope.AddToVars(field.Field.Interface())))
} }
} }
return strings.Join(sqls, " AND ") return strings.Join(sqls, " AND ")