1
0

Update xorm to v1 (#323)

Fix limit for databases other than sqlite

go mod tidy && go mod vendor

Remove unneeded break statements

Make everything work with the new xorm version

Fix xorm logging

Fix lint

Fix redis init

Fix using id field

Fix database init for testing

Change default database log level

Add xorm logger

Use const for postgres

go mod tidy

Merge branch 'master' into update/xorm

# Conflicts:
#	go.mod
#	go.sum
#	vendor/modules.txt

go mod vendor

Fix loading fixtures for postgres

Go mod vendor1

Update xorm to version 1

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/323
This commit is contained in:
konrad
2020-04-12 17:29:24 +00:00
parent 713560702b
commit d28f005552
430 changed files with 48291 additions and 99915 deletions

203
vendor/xorm.io/xorm/session_find.go generated vendored
View File

@ -8,10 +8,12 @@ import (
"errors"
"fmt"
"reflect"
"strings"
"xorm.io/builder"
"xorm.io/core"
"xorm.io/xorm/caches"
"xorm.io/xorm/internal/statements"
"xorm.io/xorm/internal/utils"
"xorm.io/xorm/schemas"
)
const (
@ -52,25 +54,27 @@ func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...inte
}
session.autoResetStatement = true
if session.statement.selectStr != "" {
session.statement.selectStr = ""
if session.statement.SelectStr != "" {
session.statement.SelectStr = ""
}
if session.statement.OrderStr != "" {
session.statement.OrderStr = ""
}
return session.Count(reflect.New(sliceElementType).Interface())
// session has stored the conditions so we use `unscoped` to avoid duplicated condition.
return session.Unscoped().Count(reflect.New(sliceElementType).Interface())
}
func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error {
defer session.resetStatement()
if session.statement.lastError != nil {
return session.statement.lastError
if session.statement.LastError != nil {
return session.statement.LastError
}
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map {
var isSlice = sliceValue.Kind() == reflect.Slice
var isMap = sliceValue.Kind() == reflect.Map
if !isSlice && !isMap {
return errors.New("needs a pointer to a slice or a map")
}
@ -81,7 +85,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
if sliceElementType.Kind() == reflect.Ptr {
if sliceElementType.Elem().Kind() == reflect.Struct {
pv := reflect.New(sliceElementType.Elem())
if err := session.statement.setRefValue(pv); err != nil {
if err := session.statement.SetRefValue(pv); err != nil {
return err
}
} else {
@ -89,7 +93,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
}
} else if sliceElementType.Kind() == reflect.Struct {
pv := reflect.New(sliceElementType)
if err := session.statement.setRefValue(pv); err != nil {
if err := session.statement.SetRefValue(pv); err != nil {
return err
}
} else {
@ -97,107 +101,54 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
}
}
var table = session.statement.RefTable
var addedTableName = (len(session.statement.JoinStr) > 0)
var autoCond builder.Cond
var (
table = session.statement.RefTable
addedTableName = (len(session.statement.JoinStr) > 0)
autoCond builder.Cond
)
if tp == tpStruct {
if !session.statement.noAutoCondition && len(condiBean) > 0 {
if !session.statement.NoAutoCondition && len(condiBean) > 0 {
var err error
autoCond, err = session.statement.buildConds(table, condiBean[0], true, true, false, true, addedTableName)
autoCond, err = session.statement.BuildConds(table, condiBean[0], true, true, false, true, addedTableName)
if err != nil {
return err
}
} else {
// !oinume! Add "<col> IS NULL" to WHERE whatever condiBean is given.
// See https://gitea.com/xorm/xorm/issues/179
if col := table.DeletedColumn(); col != nil && !session.statement.unscoped { // tag "deleted" is enabled
var colName = session.engine.Quote(col.Name)
if addedTableName {
var nm = session.statement.TableName()
if len(session.statement.TableAlias) > 0 {
nm = session.statement.TableAlias
}
colName = session.engine.Quote(nm) + "." + colName
}
autoCond = session.engine.CondDeleted(colName)
if col := table.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled
autoCond = session.statement.CondDeleted(col)
}
}
}
var sqlStr string
var args []interface{}
var err error
if session.statement.RawSQL == "" {
if len(session.statement.TableName()) <= 0 {
return ErrTableNotFound
// if it's a map with Cols but primary key not in column list, we still need the primary key
if isMap && !session.statement.ColumnMap.IsEmpty() {
for _, k := range session.statement.RefTable.PrimaryKeys {
session.statement.ColumnMap.Add(k)
}
var columnStr = session.statement.ColumnStr
if len(session.statement.selectStr) > 0 {
columnStr = session.statement.selectStr
} else {
if session.statement.JoinStr == "" {
if columnStr == "" {
if session.statement.GroupByStr != "" {
columnStr = session.engine.quoteColumns(session.statement.GroupByStr)
} else {
columnStr = session.statement.genColumnStr()
}
}
} else {
if columnStr == "" {
if session.statement.GroupByStr != "" {
columnStr = session.engine.quoteColumns(session.statement.GroupByStr)
} else {
columnStr = "*"
}
}
}
if columnStr == "" {
columnStr = "*"
}
}
session.statement.cond = session.statement.cond.And(autoCond)
condSQL, condArgs, err := builder.ToSQL(session.statement.cond)
if err != nil {
return err
}
args = append(session.statement.joinArgs, condArgs...)
sqlStr, err = session.statement.genSelectSQL(columnStr, condSQL, true, true)
if err != nil {
return err
}
// for mssql and use limit
qs := strings.Count(sqlStr, "?")
if len(args)*2 == qs {
args = append(args, args...)
}
} else {
sqlStr = session.statement.RawSQL
args = session.statement.RawParams
}
if session.canCache() {
if cacher := session.engine.getCacher(session.statement.TableName()); cacher != nil &&
sqlStr, args, err := session.statement.GenFindSQL(autoCond)
if err != nil {
return err
}
if session.statement.ColumnMap.IsEmpty() && session.canCache() {
if cacher := session.engine.GetCacher(session.statement.TableName()); cacher != nil &&
!session.statement.IsDistinct &&
!session.statement.unscoped {
!session.statement.GetUnscoped() {
err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...)
if err != ErrCacheFailed {
return err
}
err = nil // !nashtsai! reset err to nil for ErrCacheFailed
session.engine.logger.Warn("Cache Find Failed")
session.engine.logger.Warnf("Cache Find Failed")
}
}
return session.noCacheFind(table, sliceValue, sqlStr, args...)
}
func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Value, sqlStr string, args ...interface{}) error {
func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect.Value, sqlStr string, args ...interface{}) error {
rows, err := session.queryRows(sqlStr, args...)
if err != nil {
return err
@ -236,10 +187,10 @@ func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Va
return reflect.New(elemType)
}
var containerValueSetFunc func(*reflect.Value, core.PK) error
var containerValueSetFunc func(*reflect.Value, schemas.PK) error
if containerValue.Kind() == reflect.Slice {
containerValueSetFunc = func(newValue *reflect.Value, pk core.PK) error {
containerValueSetFunc = func(newValue *reflect.Value, pk schemas.PK) error {
if isPointer {
containerValue.Set(reflect.Append(containerValue, newValue.Elem().Addr()))
} else {
@ -256,7 +207,7 @@ func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Va
return errors.New("don't support multiple primary key's map has non-slice key type")
}
containerValueSetFunc = func(newValue *reflect.Value, pk core.PK) error {
containerValueSetFunc = func(newValue *reflect.Value, pk schemas.PK) error {
keyValue := reflect.New(keyType)
err := convertPKToValue(table, keyValue.Interface(), pk)
if err != nil {
@ -273,8 +224,8 @@ func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Va
if elemType.Kind() == reflect.Struct {
var newValue = newElemFunc(fields)
dataStruct := rValue(newValue.Interface())
tb, err := session.engine.autoMapType(dataStruct)
dataStruct := utils.ReflectValue(newValue.Interface())
tb, err := session.engine.tagParser.ParseWithCache(dataStruct)
if err != nil {
return err
}
@ -310,7 +261,7 @@ func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Va
return nil
}
func convertPKToValue(table *core.Table, dst interface{}, pk core.PK) error {
func convertPKToValue(table *schemas.Table, dst interface{}, pk schemas.PK) error {
cols := table.PKColumns()
if len(cols) == 1 {
return convertAssign(dst, pk[0])
@ -322,28 +273,28 @@ func convertPKToValue(table *core.Table, dst interface{}, pk core.PK) error {
func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr interface{}, args ...interface{}) (err error) {
if !session.canCache() ||
indexNoCase(sqlStr, "having") != -1 ||
indexNoCase(sqlStr, "group by") != -1 {
utils.IndexNoCase(sqlStr, "having") != -1 ||
utils.IndexNoCase(sqlStr, "group by") != -1 {
return ErrCacheFailed
}
tableName := session.statement.TableName()
cacher := session.engine.getCacher(tableName)
cacher := session.engine.cacherMgr.GetCacher(tableName)
if cacher == nil {
return nil
}
for _, filter := range session.engine.dialect.Filters() {
sqlStr = filter.Do(sqlStr, session.engine.dialect, session.statement.RefTable)
sqlStr = filter.Do(sqlStr)
}
newsql := session.statement.convertIDSQL(sqlStr)
newsql := session.statement.ConvertIDSQL(sqlStr)
if newsql == "" {
return ErrCacheFailed
}
table := session.statement.RefTable
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
ids, err := caches.GetCacheSql(cacher, tableName, newsql, args)
if err != nil {
rows, err := session.queryRows(newsql, args...)
if err != nil {
@ -352,11 +303,11 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
defer rows.Close()
var i int
ids = make([]core.PK, 0)
ids = make([]schemas.PK, 0)
for rows.Next() {
i++
if i > 500 {
session.engine.logger.Debug("[cacheFind] ids length > 500, no cache")
session.engine.logger.Debugf("[cacheFind] ids length > 500, no cache")
return ErrCacheFailed
}
var res = make([]string, len(table.PrimaryKeys))
@ -364,7 +315,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
if err != nil {
return err
}
var pk core.PK = make([]interface{}, len(table.PrimaryKeys))
var pk schemas.PK = make([]interface{}, len(table.PrimaryKeys))
for i, col := range table.PKColumns() {
pk[i], err = session.engine.idTypeAssertion(col, res[i])
if err != nil {
@ -375,19 +326,19 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
ids = append(ids, pk)
}
session.engine.logger.Debug("[cacheFind] cache sql:", ids, tableName, sqlStr, newsql, args)
err = core.PutCacheSql(cacher, ids, tableName, newsql, args)
session.engine.logger.Debugf("[cache] cache sql: %v, %v, %v, %v, %v", ids, tableName, sqlStr, newsql, args)
err = caches.PutCacheSql(cacher, ids, tableName, newsql, args)
if err != nil {
return err
}
} else {
session.engine.logger.Debug("[cacheFind] cache hit sql:", tableName, sqlStr, newsql, args)
session.engine.logger.Debugf("[cache] cache hit sql: %v, %v, %v, %v", tableName, sqlStr, newsql, args)
}
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
ididxes := make(map[string]int)
var ides []core.PK
var ides []schemas.PK
var temps = make([]interface{}, len(ids))
for idx, id := range ids {
@ -396,20 +347,38 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
return err
}
bean := cacher.GetBean(tableName, sid)
if bean == nil || reflect.ValueOf(bean).Elem().Type() != t {
// fix issue #894
isHit := func() (ht bool) {
if bean == nil {
ht = false
return
}
ckb := reflect.ValueOf(bean).Elem().Type()
ht = ckb == t
if !ht && t.Kind() == reflect.Ptr {
ht = t.Elem() == ckb
}
return
}
if !isHit() {
ides = append(ides, id)
ididxes[sid] = idx
} else {
session.engine.logger.Debug("[cacheFind] cache hit bean:", tableName, id, bean)
session.engine.logger.Debugf("[cache] cache hit bean: %v, %v, %v", tableName, id, bean)
pk, err := session.engine.IDOf(bean)
if err != nil {
return err
}
pk := session.engine.IdOf(bean)
xid, err := pk.ToString()
if err != nil {
return err
}
if sid != xid {
session.engine.logger.Error("[cacheFind] error cache", xid, sid, bean)
session.engine.logger.Errorf("[cache] error cache: %v, %v, %v", xid, sid, bean)
return ErrCacheFailed
}
temps[idx] = bean
@ -420,6 +389,12 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
slices := reflect.New(reflect.SliceOf(t))
beans := slices.Interface()
statement := session.statement
session.statement = statements.NewStatement(
session.engine.dialect,
session.engine.tagParser,
session.engine.DatabaseTZ,
)
if len(table.PrimaryKeys) == 1 {
ff := make([]interface{}, 0, len(ides))
for _, ie := range ides {
@ -442,6 +417,8 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
return err
}
session.statement = statement
vs := reflect.Indirect(reflect.ValueOf(beans))
for i := 0; i < vs.Len(); i++ {
rv := vs.Index(i)
@ -459,7 +436,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
bean := rv.Interface()
temps[ididxes[sid]] = bean
session.engine.logger.Debug("[cacheFind] cache bean:", tableName, id, bean, temps)
session.engine.logger.Debugf("[cache] cache bean: %v, %v, %v, %v", tableName, id, bean, temps)
cacher.PutBean(tableName, sid, bean)
}
}
@ -467,7 +444,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
for j := 0; j < len(temps); j++ {
bean := temps[j]
if bean == nil {
session.engine.logger.Warn("[cacheFind] cache no hit:", tableName, ids[j], temps)
session.engine.logger.Warnf("[cache] cache no hit: %v, %v, %v", tableName, ids[j], temps)
// return errors.New("cache error") // !nashtsai! no need to return error, but continue instead
continue
}
@ -488,7 +465,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
}
} else {
if keyType.Kind() != reflect.Slice {
return errors.New("table have multiple primary keys, key is not core.PK or slice")
return errors.New("table have multiple primary keys, key is not schemas.PK or slice")
}
ikey = key
}