From 3a13eade4eadd9e9ef9aef6f2c0bbb9918e2e81d Mon Sep 17 00:00:00 2001 From: Jason Seriff Date: Mon, 25 Jan 2016 14:28:02 -0600 Subject: [PATCH 1/2] Remove regex guess on counting query - replace with explicit set on Count() call to fix order by issues --- scope_private.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/scope_private.go b/scope_private.go index fa5d5f44..6209f8e5 100644 --- a/scope_private.go +++ b/scope_private.go @@ -220,8 +220,6 @@ func (scope *Scope) whereSql() (sql string) { return } -var hasCountRegexp = regexp.MustCompile(`(?i)count\(.+\)`) - func (scope *Scope) selectSql() string { if len(scope.Search.selects) == 0 { if scope.Search.joins != "" { @@ -229,9 +227,7 @@ func (scope *Scope) selectSql() string { } return "*" } - sql := scope.buildSelectQuery(scope.Search.selects) - scope.Search.countingQuery = (len(scope.Search.group) == 0) && hasCountRegexp.MatchString(sql) - return sql + return scope.buildSelectQuery(scope.Search.selects) } func (scope *Scope) orderSql() string { @@ -416,6 +412,7 @@ func (scope *Scope) pluck(column string, value interface{}) *Scope { func (scope *Scope) count(value interface{}) *Scope { scope.Search.Select("count(*)") + scope.Search.countingQuery = true scope.Err(scope.row().Scan(value)) return scope } From b520f4bd1cd151c1c5d769e6237ac9d10297cb7f Mon Sep 17 00:00:00 2001 From: Pavel Hrechyshkin Date: Mon, 22 Feb 2016 01:09:56 +0300 Subject: [PATCH 2/2] Issue-860. Preload performance --- preload.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/preload.go b/preload.go index a855f794..e1ca69ff 100644 --- a/preload.go +++ b/preload.go @@ -150,20 +150,24 @@ func (scope *Scope) handleHasManyPreload(field *Field, conditions []interface{}) resultValues := reflect.Indirect(reflect.ValueOf(results)) if scope.IndirectValue().Kind() == reflect.Slice { + preloadMap := make(map[string][]reflect.Value) for i := 0; i < resultValues.Len(); i++ { result := resultValues.Index(i) value := getRealValue(result, relation.ForeignFieldNames) - objects := scope.IndirectValue() - for j := 0; j < objects.Len(); j++ { - object := reflect.Indirect(objects.Index(j)) - if equalAsString(getRealValue(object, relation.AssociationForeignFieldNames), value) { - if object.Kind() == reflect.Ptr { - object = object.Elem() - } - f := object.FieldByName(field.Name) - f.Set(reflect.Append(f, result)) - break + preloadMap[toString(value)] = append(preloadMap[toString(value)], result) + } + + objects := scope.IndirectValue() + for j := 0; j < objects.Len(); j++ { + object := reflect.Indirect(objects.Index(j)) + objectRealValue := getRealValue(object, relation.AssociationForeignFieldNames) + objectStringValue := toString(objectRealValue) + if results, ok := preloadMap[objectStringValue]; ok { + if object.Kind() == reflect.Ptr { + object = object.Elem() } + f := object.FieldByName(field.Name) + f.Set(reflect.Append(f, results...)) } } } else {