优化func (session *Session) slice2Bean方法中的strings.ToLower(对应issue:https://gitea.com/xorm/xorm/issues/2243)
This commit is contained in:
parent
84ff9cba03
commit
b9ee143cc2
4
rows.go
4
rows.go
|
@ -129,7 +129,9 @@ func (rows *Rows) Scan(beans ...interface{}) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := rows.session.scan(rows.rows, rows.session.statement.RefTable, beanKind, beans, types, fields); err != nil {
|
allColumn := ParseQueryRows(fields, types)
|
||||||
|
|
||||||
|
if err := rows.session.scan(rows.rows, rows.session.statement.RefTable, beanKind, beans, allColumn, types, fields); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
session.go
21
session.go
|
@ -16,8 +16,6 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"xorm.io/xorm/contexts"
|
"xorm.io/xorm/contexts"
|
||||||
"xorm.io/xorm/convert"
|
"xorm.io/xorm/convert"
|
||||||
"xorm.io/xorm/core"
|
"xorm.io/xorm/core"
|
||||||
|
@ -418,7 +416,7 @@ func getField(dataStruct *reflect.Value, table *schemas.Table, colName string, i
|
||||||
// Cell cell is a result of one column field
|
// Cell cell is a result of one column field
|
||||||
type Cell *interface{}
|
type Cell *interface{}
|
||||||
|
|
||||||
func (session *Session) rows2Beans(rows *core.Rows, fields []string, types []*sql.ColumnType,
|
func (session *Session) rows2Beans(rows *core.Rows, allColumn *AllColumn, fields []string, types []*sql.ColumnType,
|
||||||
table *schemas.Table, newElemFunc func([]string) reflect.Value,
|
table *schemas.Table, newElemFunc func([]string) reflect.Value,
|
||||||
sliceValueSetFunc func(*reflect.Value, schemas.PK) error,
|
sliceValueSetFunc func(*reflect.Value, schemas.PK) error,
|
||||||
) error {
|
) error {
|
||||||
|
@ -428,11 +426,11 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string, types []*sq
|
||||||
dataStruct := newValue.Elem()
|
dataStruct := newValue.Elem()
|
||||||
|
|
||||||
// handle beforeClosures
|
// handle beforeClosures
|
||||||
scanResults, err := session.row2Slice(rows, fields, types, bean)
|
scanResults, err := session.row2Slice(rows, allColumn, fields, types, bean)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pk, err := session.slice2Bean(scanResults, fields, bean, &dataStruct, table)
|
pk, err := session.slice2Bean(scanResults, allColumn, fields, bean, &dataStruct, table)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -447,7 +445,7 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string, types []*sq
|
||||||
return rows.Err()
|
return rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) row2Slice(rows *core.Rows, fields []string, types []*sql.ColumnType, bean interface{}) ([]interface{}, error) {
|
func (session *Session) row2Slice(rows *core.Rows, allColumn *AllColumn, fields []string, types []*sql.ColumnType, bean interface{}) ([]interface{}, error) {
|
||||||
for _, closure := range session.beforeClosures {
|
for _, closure := range session.beforeClosures {
|
||||||
closure(bean)
|
closure(bean)
|
||||||
}
|
}
|
||||||
|
@ -705,7 +703,7 @@ func (session *Session) convertBeanField(col *schemas.Column, fieldValue *reflec
|
||||||
return convert.AssignValue(fieldValue.Addr(), scanResult)
|
return convert.AssignValue(fieldValue.Addr(), scanResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) slice2Bean(scanResults []interface{}, fields []string, bean interface{}, dataStruct *reflect.Value, table *schemas.Table) (schemas.PK, error) {
|
func (session *Session) slice2Bean(scanResults []interface{}, allColum *AllColumn, fields []string, bean interface{}, dataStruct *reflect.Value, table *schemas.Table) (schemas.PK, error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
executeAfterSet(bean, fields, scanResults)
|
executeAfterSet(bean, fields, scanResults)
|
||||||
}()
|
}()
|
||||||
|
@ -714,19 +712,18 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b
|
||||||
|
|
||||||
tempMap := make(map[string]int)
|
tempMap := make(map[string]int)
|
||||||
var pk schemas.PK
|
var pk schemas.PK
|
||||||
for i, colName := range fields {
|
for i, field := range allColum.Fields {
|
||||||
var idx int
|
var idx int
|
||||||
lKey := strings.ToLower(colName)
|
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
if idx, ok = tempMap[lKey]; !ok {
|
if idx, ok = tempMap[field.LowerFieldName]; !ok {
|
||||||
idx = 0
|
idx = 0
|
||||||
} else {
|
} else {
|
||||||
idx++
|
idx++
|
||||||
}
|
}
|
||||||
tempMap[lKey] = idx
|
tempMap[field.LowerFieldName] = idx
|
||||||
|
|
||||||
col, fieldValue, err := getField(dataStruct, table, colName, idx)
|
col, fieldValue, err := getField(dataStruct, table, field.FieldName, idx)
|
||||||
if _, ok := err.(ErrFieldIsNotExist); ok {
|
if _, ok := err.(ErrFieldIsNotExist); ok {
|
||||||
continue
|
continue
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
package xorm
|
package xorm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
"xorm.io/xorm/caches"
|
"xorm.io/xorm/caches"
|
||||||
|
@ -161,6 +163,36 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
return session.noCacheFind(table, sliceValue, sqlStr, args...)
|
return session.noCacheFind(table, sliceValue, sqlStr, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type QueryedField struct {
|
||||||
|
FieldName string
|
||||||
|
LowerFieldName string
|
||||||
|
ColumnType *sql.ColumnType
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllColumn struct {
|
||||||
|
Fields []*QueryedField
|
||||||
|
FieldNames []string
|
||||||
|
Types []*sql.ColumnType
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseQueryRows(fieldNames []string, types []*sql.ColumnType) *AllColumn {
|
||||||
|
var allColumn AllColumn
|
||||||
|
|
||||||
|
fields := make([]*QueryedField, 0, len(fieldNames))
|
||||||
|
|
||||||
|
for i, fieldName := range fieldNames {
|
||||||
|
field := &QueryedField{
|
||||||
|
FieldName: fieldName,
|
||||||
|
LowerFieldName: strings.ToLower(fieldName),
|
||||||
|
ColumnType: types[i],
|
||||||
|
}
|
||||||
|
fields = append(fields, field)
|
||||||
|
}
|
||||||
|
|
||||||
|
allColumn.Fields = fields
|
||||||
|
return &allColumn
|
||||||
|
}
|
||||||
|
|
||||||
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()
|
elemType := containerValue.Type().Elem()
|
||||||
var isPointer bool
|
var isPointer bool
|
||||||
|
@ -188,6 +220,8 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allColumn := ParseQueryRows(fields, types)
|
||||||
|
|
||||||
newElemFunc := func(fields []string) reflect.Value {
|
newElemFunc := func(fields []string) reflect.Value {
|
||||||
return utils.New(elemType, len(fields), len(fields))
|
return utils.New(elemType, len(fields), len(fields))
|
||||||
}
|
}
|
||||||
|
@ -238,7 +272,7 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = session.rows2Beans(rows, fields, types, tb, newElemFunc, containerValueSetFunc)
|
err = session.rows2Beans(rows, allColumn, fields, types, tb, newElemFunc, containerValueSetFunc)
|
||||||
rows.Close()
|
rows.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -164,7 +164,9 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *schemas.Table,
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := session.scan(rows, table, beanKind, beans, types, fields); err != nil {
|
allColumn := ParseQueryRows(fields, types)
|
||||||
|
|
||||||
|
if err := session.scan(rows, table, beanKind, beans, allColumn, types, fields); err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
rows.Close()
|
rows.Close()
|
||||||
|
@ -172,7 +174,7 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *schemas.Table,
|
||||||
return true, session.executeProcessors()
|
return true, session.executeProcessors()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) scan(rows *core.Rows, table *schemas.Table, firstBeanKind reflect.Kind, beans []interface{}, types []*sql.ColumnType, fields []string) error {
|
func (session *Session) scan(rows *core.Rows, table *schemas.Table, firstBeanKind reflect.Kind, beans []interface{}, allColumn *AllColumn, types []*sql.ColumnType, fields []string) error {
|
||||||
if len(beans) == 1 {
|
if len(beans) == 1 {
|
||||||
bean := beans[0]
|
bean := beans[0]
|
||||||
switch firstBeanKind {
|
switch firstBeanKind {
|
||||||
|
@ -180,13 +182,13 @@ func (session *Session) scan(rows *core.Rows, table *schemas.Table, firstBeanKin
|
||||||
if !isScannableStruct(bean, len(types)) {
|
if !isScannableStruct(bean, len(types)) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
scanResults, err := session.row2Slice(rows, fields, types, bean)
|
scanResults, err := session.row2Slice(rows, allColumn, fields, types, bean)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dataStruct := utils.ReflectValue(bean)
|
dataStruct := utils.ReflectValue(bean)
|
||||||
_, err = session.slice2Bean(scanResults, fields, bean, &dataStruct, table)
|
_, err = session.slice2Bean(scanResults, allColumn, fields, bean, &dataStruct, table)
|
||||||
return err
|
return err
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
return session.getSlice(rows, types, fields, bean)
|
return session.getSlice(rows, types, fields, bean)
|
||||||
|
|
Loading…
Reference in New Issue