Refactor find (#2031)
Reviewed-on: https://gitea.com/xorm/xorm/pulls/2031 Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-committed-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
289c27ebec
commit
dbc2de380b
|
@ -325,6 +325,9 @@ func AssignValue(dv reflect.Value, src interface{}) error {
|
||||||
if src == nil {
|
if src == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if v, ok := src.(*interface{}); ok {
|
||||||
|
return AssignValue(dv, *v)
|
||||||
|
}
|
||||||
|
|
||||||
if dv.Type().Implements(scannerType) {
|
if dv.Type().Implements(scannerType) {
|
||||||
return dv.Interface().(sql.Scanner).Scan(src)
|
return dv.Interface().(sql.Scanner).Scan(src)
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2021 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
// New creates a value according type
|
||||||
|
func New(tp reflect.Type, length, cap int) reflect.Value {
|
||||||
|
switch tp.Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
slice := reflect.MakeSlice(tp, length, cap)
|
||||||
|
x := reflect.New(slice.Type())
|
||||||
|
x.Elem().Set(slice)
|
||||||
|
return x
|
||||||
|
case reflect.Map:
|
||||||
|
mp := reflect.MakeMapWithSize(tp, cap)
|
||||||
|
x := reflect.New(mp.Type())
|
||||||
|
x.Elem().Set(mp)
|
||||||
|
return x
|
||||||
|
default:
|
||||||
|
return reflect.New(tp)
|
||||||
|
}
|
||||||
|
}
|
|
@ -161,6 +161,16 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect.Value, sqlStr string, args ...interface{}) error {
|
func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect.Value, sqlStr string, args ...interface{}) error {
|
||||||
|
elemType := containerValue.Type().Elem()
|
||||||
|
var isPointer bool
|
||||||
|
if elemType.Kind() == reflect.Ptr {
|
||||||
|
isPointer = true
|
||||||
|
elemType = elemType.Elem()
|
||||||
|
}
|
||||||
|
if elemType.Kind() == reflect.Ptr {
|
||||||
|
return errors.New("pointer to pointer is not supported")
|
||||||
|
}
|
||||||
|
|
||||||
rows, err := session.queryRows(sqlStr, args...)
|
rows, err := session.queryRows(sqlStr, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -177,31 +187,8 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var newElemFunc func(fields []string) reflect.Value
|
var newElemFunc = func(fields []string) reflect.Value {
|
||||||
elemType := containerValue.Type().Elem()
|
return utils.New(elemType, len(fields), len(fields))
|
||||||
var isPointer bool
|
|
||||||
if elemType.Kind() == reflect.Ptr {
|
|
||||||
isPointer = true
|
|
||||||
elemType = elemType.Elem()
|
|
||||||
}
|
|
||||||
if elemType.Kind() == reflect.Ptr {
|
|
||||||
return errors.New("pointer to pointer is not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
newElemFunc = func(fields []string) reflect.Value {
|
|
||||||
switch elemType.Kind() {
|
|
||||||
case reflect.Slice:
|
|
||||||
slice := reflect.MakeSlice(elemType, len(fields), len(fields))
|
|
||||||
x := reflect.New(slice.Type())
|
|
||||||
x.Elem().Set(slice)
|
|
||||||
return x
|
|
||||||
case reflect.Map:
|
|
||||||
mp := reflect.MakeMap(elemType)
|
|
||||||
x := reflect.New(mp.Type())
|
|
||||||
x.Elem().Set(mp)
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
return reflect.New(elemType)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var containerValueSetFunc func(*reflect.Value, schemas.PK) error
|
var containerValueSetFunc func(*reflect.Value, schemas.PK) error
|
||||||
|
@ -226,10 +213,15 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||||
|
|
||||||
containerValueSetFunc = func(newValue *reflect.Value, pk schemas.PK) error {
|
containerValueSetFunc = func(newValue *reflect.Value, pk schemas.PK) error {
|
||||||
keyValue := reflect.New(keyType)
|
keyValue := reflect.New(keyType)
|
||||||
err := convertPKToValue(table, keyValue.Interface(), pk)
|
cols := table.PKColumns()
|
||||||
if err != nil {
|
if len(cols) == 1 {
|
||||||
|
if err := convert.AssignValue(keyValue, pk[0]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
keyValue.Set(reflect.ValueOf(&pk))
|
||||||
|
}
|
||||||
|
|
||||||
if isPointer {
|
if isPointer {
|
||||||
containerValue.SetMapIndex(keyValue.Elem(), newValue.Elem().Addr())
|
containerValue.SetMapIndex(keyValue.Elem(), newValue.Elem().Addr())
|
||||||
} else {
|
} else {
|
||||||
|
@ -241,8 +233,7 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||||
|
|
||||||
if elemType.Kind() == reflect.Struct {
|
if elemType.Kind() == reflect.Struct {
|
||||||
var newValue = newElemFunc(fields)
|
var newValue = newElemFunc(fields)
|
||||||
dataStruct := utils.ReflectValue(newValue.Interface())
|
tb, err := session.engine.tagParser.ParseWithCache(newValue)
|
||||||
tb, err := session.engine.tagParser.ParseWithCache(dataStruct)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -266,7 +257,6 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||||
default:
|
default:
|
||||||
err = rows.Scan(bean)
|
err = rows.Scan(bean)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -278,16 +268,6 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||||
return rows.Err()
|
return rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertPKToValue(table *schemas.Table, dst interface{}, pk schemas.PK) error {
|
|
||||||
cols := table.PKColumns()
|
|
||||||
if len(cols) == 1 {
|
|
||||||
return convert.Assign(dst, pk[0], nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
dst = pk
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr interface{}, args ...interface{}) (err error) {
|
func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr interface{}, args ...interface{}) (err error) {
|
||||||
if !session.canCache() ||
|
if !session.canCache() ||
|
||||||
utils.IndexNoCase(sqlStr, "having") != -1 ||
|
utils.IndexNoCase(sqlStr, "having") != -1 ||
|
||||||
|
|
Loading…
Reference in New Issue