forked from mirror/gorm
increase performance m2m preload
This commit is contained in:
parent
e2689d335b
commit
07571d1adf
48
preload.go
48
preload.go
|
@ -202,20 +202,13 @@ func (scope *Scope) handleHasManyToManyPreload(field *Field, conditions []interf
|
|||
destType = destType.Elem()
|
||||
}
|
||||
|
||||
var destKeys []string
|
||||
var sourceKeys []string
|
||||
var linkHash = make(map[string][]string)
|
||||
|
||||
for _, key := range joinTableHandler.DestinationForeignKeys() {
|
||||
destKeys = append(destKeys, key.DBName)
|
||||
}
|
||||
var linkHash = make(map[string][]interface{})
|
||||
|
||||
for _, key := range joinTableHandler.SourceForeignKeys() {
|
||||
sourceKeys = append(sourceKeys, key.DBName)
|
||||
}
|
||||
|
||||
results := reflect.New(field.Struct.Type).Elem()
|
||||
|
||||
db := scope.NewDB().Table(scope.New(reflect.New(destType).Interface()).TableName())
|
||||
preloadJoinDB := joinTableHandler.PreloadWithJoin(joinTableHandler, db, scope.Value)
|
||||
if len(conditions) > 0 {
|
||||
|
@ -250,7 +243,6 @@ func (scope *Scope) handleHasManyToManyPreload(field *Field, conditions []interf
|
|||
|
||||
scope.Err(rows.Scan(values...))
|
||||
|
||||
var destKey []interface{}
|
||||
var sourceKey []interface{}
|
||||
|
||||
for index, column := range columns {
|
||||
|
@ -261,61 +253,47 @@ func (scope *Scope) handleHasManyToManyPreload(field *Field, conditions []interf
|
|||
} else if v := reflect.ValueOf(value).Elem().Elem(); v.IsValid() {
|
||||
field.Field.Set(v)
|
||||
}
|
||||
} else if strInSlice(column, destKeys) {
|
||||
destKey = append(destKey, *(value.(*interface{})))
|
||||
} else if strInSlice(column, sourceKeys) {
|
||||
sourceKey = append(sourceKey, *(value.(*interface{})))
|
||||
}
|
||||
}
|
||||
|
||||
if len(destKey) != 0 && len(sourceKey) != 0 {
|
||||
linkHash[toString(sourceKey)] = append(linkHash[toString(sourceKey)], toString(destKey))
|
||||
}
|
||||
|
||||
if len(sourceKey) != 0 {
|
||||
if isPtr {
|
||||
results = reflect.Append(results, elem.Addr())
|
||||
linkHash[toString(sourceKey)] = append(linkHash[toString(sourceKey)], elem.Addr())
|
||||
} else {
|
||||
results = reflect.Append(results, elem)
|
||||
linkHash[toString(sourceKey)] = append(linkHash[toString(sourceKey)], elem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if scope.IndirectValue().Kind() == reflect.Slice {
|
||||
objects := scope.IndirectValue()
|
||||
for j := 0; j < objects.Len(); j++ {
|
||||
var checked []string
|
||||
|
||||
object := reflect.Indirect(objects.Index(j))
|
||||
source := getRealValue(object, relation.AssociationForeignStructFieldNames)
|
||||
links := linkHash[toString(source)]
|
||||
|
||||
for i := 0; i < results.Len(); i++ {
|
||||
result := results.Index(i)
|
||||
value := getRealValue(result, relation.ForeignStructFieldNames)
|
||||
|
||||
if strInSlice(toString(value), linkHash[toString(source)]) && !strInSlice(toString(value), checked) {
|
||||
for i := 0; i < len(links); i++ {
|
||||
f := object.FieldByName(field.Name)
|
||||
f.Set(reflect.Append(f, result))
|
||||
checked = append(checked, toString(value))
|
||||
a := links[i].(reflect.Value)
|
||||
f.Set(reflect.Append(f, a))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
object := scope.IndirectValue()
|
||||
var checked []string
|
||||
source := getRealValue(object, relation.AssociationForeignStructFieldNames)
|
||||
|
||||
for i := 0; i < results.Len(); i++ {
|
||||
result := results.Index(i)
|
||||
value := getRealValue(result, relation.ForeignStructFieldNames)
|
||||
links := linkHash[toString(source)]
|
||||
|
||||
if strInSlice(toString(value), linkHash[toString(source)]) && !strInSlice(toString(value), checked) {
|
||||
for i := 0; i < len(links); i++ {
|
||||
f := object.FieldByName(field.Name)
|
||||
f.Set(reflect.Append(f, result))
|
||||
checked = append(checked, toString(value))
|
||||
a := links[i].(reflect.Value)
|
||||
f.Set(reflect.Append(f, a))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (scope *Scope) getColumnAsArray(columns []string) (results [][]interface{}) {
|
||||
|
|
Loading…
Reference in New Issue