querystring performance
This commit is contained in:
parent
8f8195a86b
commit
eb3fd81154
|
@ -0,0 +1,30 @@
|
||||||
|
// 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 convert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String2Time converts a string to time with original location
|
||||||
|
func String2Time(s string, originalLocation *time.Location, convertedLocation *time.Location) (*time.Time, error) {
|
||||||
|
if len(s) == 19 {
|
||||||
|
dt, err := time.ParseInLocation("2006-01-02 15:04:05", s, originalLocation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dt = dt.In(convertedLocation)
|
||||||
|
return &dt, nil
|
||||||
|
} else if len(s) == 20 && s[10] == 'T' && s[19] == 'Z' {
|
||||||
|
dt, err := time.ParseInLocation("2006-01-02T15:04:05Z", s, originalLocation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dt = dt.In(convertedLocation)
|
||||||
|
return &dt, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unsupported convertion from %s to time", s)
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
// 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 xorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"xorm.io/xorm/convert"
|
||||||
|
"xorm.io/xorm/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (session *Session) scan(rows *core.Rows, types []*sql.ColumnType, v ...interface{}) error {
|
||||||
|
var v2 = make([]interface{}, 0, len(v))
|
||||||
|
var turnBackIdxes = make([]int, 0, 5)
|
||||||
|
for i, vv := range v {
|
||||||
|
switch vv.(type) {
|
||||||
|
case *time.Time:
|
||||||
|
v2 = append(v2, &sql.NullString{})
|
||||||
|
turnBackIdxes = append(turnBackIdxes, i)
|
||||||
|
case *sql.NullTime:
|
||||||
|
v2 = append(v2, &sql.NullString{})
|
||||||
|
turnBackIdxes = append(turnBackIdxes, i)
|
||||||
|
default:
|
||||||
|
v2 = append(v2, v[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := rows.Scan(v2...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, i := range turnBackIdxes {
|
||||||
|
switch t := v[i].(type) {
|
||||||
|
case *time.Time:
|
||||||
|
var s = *(v2[i].(*sql.NullString))
|
||||||
|
if !s.Valid {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
dt, err := convert.String2Time(s.String, session.engine.DatabaseTZ, session.engine.TZLocation)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*t = *dt
|
||||||
|
case *sql.NullTime:
|
||||||
|
var s = *(v2[i].(*sql.NullString))
|
||||||
|
if !s.Valid {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
dt, err := convert.String2Time(s.String, session.engine.DatabaseTZ, session.engine.TZLocation)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.Time = *dt
|
||||||
|
t.Valid = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (engine *Engine) row2mapStr(rows *core.Rows, types []*sql.ColumnType, fields []string) (map[string]string, error) {
|
||||||
|
var scanResults = make([]interface{}, len(fields))
|
||||||
|
for i := 0; i < len(fields); i++ {
|
||||||
|
var s sql.NullString
|
||||||
|
scanResults[i] = &s
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := rows.Scan(scanResults...); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make(map[string]string, len(fields))
|
||||||
|
for ii, key := range fields {
|
||||||
|
s := scanResults[ii].(*sql.NullString)
|
||||||
|
result[key] = s.String
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
|
@ -75,34 +75,6 @@ func value2String(rawValue *reflect.Value) (str string, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) {
|
|
||||||
result := make(map[string]string)
|
|
||||||
scanResultContainers := make([]interface{}, len(fields))
|
|
||||||
for i := 0; i < len(fields); i++ {
|
|
||||||
var scanResultContainer interface{}
|
|
||||||
scanResultContainers[i] = &scanResultContainer
|
|
||||||
}
|
|
||||||
if err := rows.Scan(scanResultContainers...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for ii, key := range fields {
|
|
||||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
|
|
||||||
// if row is null then as empty string
|
|
||||||
if rawValue.Interface() == nil {
|
|
||||||
result[key] = ""
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if data, err := value2String(&rawValue); err == nil {
|
|
||||||
result[key] = data
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func row2sliceStr(rows *core.Rows, fields []string) (results []string, err error) {
|
func row2sliceStr(rows *core.Rows, fields []string) (results []string, err error) {
|
||||||
result := make([]string, 0, len(fields))
|
result := make([]string, 0, len(fields))
|
||||||
scanResultContainers := make([]interface{}, len(fields))
|
scanResultContainers := make([]interface{}, len(fields))
|
||||||
|
@ -131,13 +103,18 @@ func row2sliceStr(rows *core.Rows, fields []string) (results []string, err error
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
|
func (session *Session) rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
|
||||||
fields, err := rows.Columns()
|
fields, err := rows.Columns()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
types, err := rows.ColumnTypes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
result, err := row2mapStr(rows, fields)
|
result, err := session.engine.row2mapStr(rows, types, fields)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -180,7 +157,7 @@ func (session *Session) QueryString(sqlOrArgs ...interface{}) ([]map[string]stri
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
return rows2Strings(rows)
|
return session.rows2Strings(rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuerySliceString runs a raw sql and return records as [][]string
|
// QuerySliceString runs a raw sql and return records as [][]string
|
||||||
|
|
Loading…
Reference in New Issue