Refactor handleManyToManyPreload

This commit is contained in:
Jinzhu 2016-01-15 10:08:22 +08:00
parent d9229c5a7b
commit 79c4fae34d
1 changed files with 19 additions and 39 deletions

View File

@ -203,6 +203,8 @@ func (scope *Scope) handleManyToManyPreload(field *Field, conditions []interface
destType = field.StructField.Struct.Type.Elem() destType = field.StructField.Struct.Type.Elem()
linkHash = make(map[string][]reflect.Value) linkHash = make(map[string][]reflect.Value)
sourceKeys = []string{} sourceKeys = []string{}
foreignKeyValue interface{}
foreignKeyType = reflect.ValueOf(&foreignKeyValue).Type()
isPtr bool isPtr bool
) )
@ -233,51 +235,29 @@ func (scope *Scope) handleManyToManyPreload(field *Field, conditions []interface
columns, _ := rows.Columns() columns, _ := rows.Columns()
for rows.Next() { for rows.Next() {
elem := reflect.New(destType).Elem() var (
var values = make([]interface{}, len(columns)) elem = reflect.New(destType).Elem()
fields = scope.New(elem.Addr().Interface()).Fields()
)
fields := scope.New(elem.Addr().Interface()).Fields() // register foreign keys in join tables
for _, sourceKey := range sourceKeys {
var foundFields = map[string]bool{} fields[sourceKey] = &Field{Field: reflect.New(foreignKeyType).Elem()}
for index, column := range columns {
if field, ok := fields[column]; ok && !foundFields[column] {
if field.Field.Kind() == reflect.Ptr {
values[index] = field.Field.Addr().Interface()
} else {
values[index] = reflect.New(reflect.PtrTo(field.Field.Type())).Interface()
}
foundFields[column] = true
} else {
var i interface{}
values[index] = &i
}
} }
scope.Err(rows.Scan(values...)) scope.scan(rows, columns, fields)
var sourceKey []interface{} // generate hashed forkey keys in join table
var foreignKeys = make([]interface{}, len(sourceKeys))
for idx, sourceKey := range sourceKeys {
foreignKeys[idx] = fields[sourceKey].Field.Elem().Interface()
}
hashedSourceKeys := toString(foreignKeys)
var scannedFields = map[string]bool{}
for index, column := range columns {
value := values[index]
if field, ok := fields[column]; ok && !scannedFields[column] {
if field.Field.Kind() == reflect.Ptr {
field.Field.Set(reflect.ValueOf(value).Elem())
} else if v := reflect.ValueOf(value).Elem().Elem(); v.IsValid() {
field.Field.Set(v)
}
scannedFields[column] = true
} else if strInSlice(column, sourceKeys) {
sourceKey = append(sourceKey, *(value.(*interface{})))
}
}
if len(sourceKey) != 0 {
if isPtr { if isPtr {
linkHash[toString(sourceKey)] = append(linkHash[toString(sourceKey)], elem.Addr()) linkHash[hashedSourceKeys] = append(linkHash[hashedSourceKeys], elem.Addr())
} else { } else {
linkHash[toString(sourceKey)] = append(linkHash[toString(sourceKey)], elem) linkHash[hashedSourceKeys] = append(linkHash[hashedSourceKeys], elem)
}
} }
} }