Fix error log when loading issues caused by a xorm bug (#7271)
* fix error log when loading issues caused by a xorm bug * upgrade packages * fix fmt * fix Consistency * fix tests
This commit is contained in:
parent
baefea311f
commit
aa7c34cf86
156 changed files with 1854 additions and 1833 deletions
338
vendor/xorm.io/core/rows.go
generated
vendored
Normal file
338
vendor/xorm.io/core/rows.go
generated
vendored
Normal file
|
@ -0,0 +1,338 @@
|
|||
// Copyright 2019 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 core
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"reflect"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Rows struct {
|
||||
*sql.Rows
|
||||
db *DB
|
||||
}
|
||||
|
||||
func (rs *Rows) ToMapString() ([]map[string]string, error) {
|
||||
cols, err := rs.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var results = make([]map[string]string, 0, 10)
|
||||
for rs.Next() {
|
||||
var record = make(map[string]string, len(cols))
|
||||
err = rs.ScanMap(&record)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results = append(results, record)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// scan data to a struct's pointer according field index
|
||||
func (rs *Rows) ScanStructByIndex(dest ...interface{}) error {
|
||||
if len(dest) == 0 {
|
||||
return errors.New("at least one struct")
|
||||
}
|
||||
|
||||
vvvs := make([]reflect.Value, len(dest))
|
||||
for i, s := range dest {
|
||||
vv := reflect.ValueOf(s)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
return errors.New("dest should be a struct's pointer")
|
||||
}
|
||||
|
||||
vvvs[i] = vv.Elem()
|
||||
}
|
||||
|
||||
cols, err := rs.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newDest := make([]interface{}, len(cols))
|
||||
|
||||
var i = 0
|
||||
for _, vvv := range vvvs {
|
||||
for j := 0; j < vvv.NumField(); j++ {
|
||||
newDest[i] = vvv.Field(j).Addr().Interface()
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
return rs.Rows.Scan(newDest...)
|
||||
}
|
||||
|
||||
var (
|
||||
fieldCache = make(map[reflect.Type]map[string]int)
|
||||
fieldCacheMutex sync.RWMutex
|
||||
)
|
||||
|
||||
func fieldByName(v reflect.Value, name string) reflect.Value {
|
||||
t := v.Type()
|
||||
fieldCacheMutex.RLock()
|
||||
cache, ok := fieldCache[t]
|
||||
fieldCacheMutex.RUnlock()
|
||||
if !ok {
|
||||
cache = make(map[string]int)
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
cache[t.Field(i).Name] = i
|
||||
}
|
||||
fieldCacheMutex.Lock()
|
||||
fieldCache[t] = cache
|
||||
fieldCacheMutex.Unlock()
|
||||
}
|
||||
|
||||
if i, ok := cache[name]; ok {
|
||||
return v.Field(i)
|
||||
}
|
||||
|
||||
return reflect.Zero(t)
|
||||
}
|
||||
|
||||
// scan data to a struct's pointer according field name
|
||||
func (rs *Rows) ScanStructByName(dest interface{}) error {
|
||||
vv := reflect.ValueOf(dest)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
return errors.New("dest should be a struct's pointer")
|
||||
}
|
||||
|
||||
cols, err := rs.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newDest := make([]interface{}, len(cols))
|
||||
var v EmptyScanner
|
||||
for j, name := range cols {
|
||||
f := fieldByName(vv.Elem(), rs.db.Mapper.Table2Obj(name))
|
||||
if f.IsValid() {
|
||||
newDest[j] = f.Addr().Interface()
|
||||
} else {
|
||||
newDest[j] = &v
|
||||
}
|
||||
}
|
||||
|
||||
return rs.Rows.Scan(newDest...)
|
||||
}
|
||||
|
||||
// scan data to a slice's pointer, slice's length should equal to columns' number
|
||||
func (rs *Rows) ScanSlice(dest interface{}) error {
|
||||
vv := reflect.ValueOf(dest)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Slice {
|
||||
return errors.New("dest should be a slice's pointer")
|
||||
}
|
||||
|
||||
vvv := vv.Elem()
|
||||
cols, err := rs.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newDest := make([]interface{}, len(cols))
|
||||
|
||||
for j := 0; j < len(cols); j++ {
|
||||
if j >= vvv.Len() {
|
||||
newDest[j] = reflect.New(vvv.Type().Elem()).Interface()
|
||||
} else {
|
||||
newDest[j] = vvv.Index(j).Addr().Interface()
|
||||
}
|
||||
}
|
||||
|
||||
err = rs.Rows.Scan(newDest...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
srcLen := vvv.Len()
|
||||
for i := srcLen; i < len(cols); i++ {
|
||||
vvv = reflect.Append(vvv, reflect.ValueOf(newDest[i]).Elem())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// scan data to a map's pointer
|
||||
func (rs *Rows) ScanMap(dest interface{}) error {
|
||||
vv := reflect.ValueOf(dest)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
return errors.New("dest should be a map's pointer")
|
||||
}
|
||||
|
||||
cols, err := rs.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newDest := make([]interface{}, len(cols))
|
||||
vvv := vv.Elem()
|
||||
|
||||
for i, _ := range cols {
|
||||
newDest[i] = rs.db.reflectNew(vvv.Type().Elem()).Interface()
|
||||
}
|
||||
|
||||
err = rs.Rows.Scan(newDest...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, name := range cols {
|
||||
vname := reflect.ValueOf(name)
|
||||
vvv.SetMapIndex(vname, reflect.ValueOf(newDest[i]).Elem())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type Row struct {
|
||||
rows *Rows
|
||||
// One of these two will be non-nil:
|
||||
err error // deferred error for easy chaining
|
||||
}
|
||||
|
||||
// ErrorRow return an error row
|
||||
func ErrorRow(err error) *Row {
|
||||
return &Row{
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
// NewRow from rows
|
||||
func NewRow(rows *Rows, err error) *Row {
|
||||
return &Row{rows, err}
|
||||
}
|
||||
|
||||
func (row *Row) Columns() ([]string, error) {
|
||||
if row.err != nil {
|
||||
return nil, row.err
|
||||
}
|
||||
return row.rows.Columns()
|
||||
}
|
||||
|
||||
func (row *Row) Scan(dest ...interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
}
|
||||
defer row.rows.Close()
|
||||
|
||||
for _, dp := range dest {
|
||||
if _, ok := dp.(*sql.RawBytes); ok {
|
||||
return errors.New("sql: RawBytes isn't allowed on Row.Scan")
|
||||
}
|
||||
}
|
||||
|
||||
if !row.rows.Next() {
|
||||
if err := row.rows.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
err := row.rows.Scan(dest...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Make sure the query can be processed to completion with no errors.
|
||||
return row.rows.Close()
|
||||
}
|
||||
|
||||
func (row *Row) ScanStructByName(dest interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
}
|
||||
defer row.rows.Close()
|
||||
|
||||
if !row.rows.Next() {
|
||||
if err := row.rows.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
err := row.rows.ScanStructByName(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Make sure the query can be processed to completion with no errors.
|
||||
return row.rows.Close()
|
||||
}
|
||||
|
||||
func (row *Row) ScanStructByIndex(dest interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
}
|
||||
defer row.rows.Close()
|
||||
|
||||
if !row.rows.Next() {
|
||||
if err := row.rows.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
err := row.rows.ScanStructByIndex(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Make sure the query can be processed to completion with no errors.
|
||||
return row.rows.Close()
|
||||
}
|
||||
|
||||
// scan data to a slice's pointer, slice's length should equal to columns' number
|
||||
func (row *Row) ScanSlice(dest interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
}
|
||||
defer row.rows.Close()
|
||||
|
||||
if !row.rows.Next() {
|
||||
if err := row.rows.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
err := row.rows.ScanSlice(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Make sure the query can be processed to completion with no errors.
|
||||
return row.rows.Close()
|
||||
}
|
||||
|
||||
// scan data to a map's pointer
|
||||
func (row *Row) ScanMap(dest interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
}
|
||||
defer row.rows.Close()
|
||||
|
||||
if !row.rows.Next() {
|
||||
if err := row.rows.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
err := row.rows.ScanMap(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Make sure the query can be processed to completion with no errors.
|
||||
return row.rows.Close()
|
||||
}
|
||||
|
||||
func (row *Row) ToMapString() (map[string]string, error) {
|
||||
cols, err := row.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var record = make(map[string]string, len(cols))
|
||||
err = row.ScanMap(&record)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return record, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue