💥 NoAutoCondition 不再影响deleted条件生成,deleted条件仅由Unscoped控制

This commit is contained in:
CyJaySong 2024-02-26 09:46:34 +08:00
parent 3e6294dc7e
commit 8f07aa25b9
7 changed files with 50 additions and 68 deletions

View File

@ -118,7 +118,11 @@ func (statement *Statement) GenGetSQL(bean interface{}) (string, []interface{},
return "", nil, err return "", nil, err
} }
} }
if statement.RefTable != nil {
if col := statement.RefTable.DeletedColumn(); col != nil && !statement.GetUnscoped() { // tag "deleted" is enabled
statement.And(statement.CondDeleted(col))
}
}
buf := builder.NewWriter() buf := builder.NewWriter()
if err := statement.writeSelect(buf, columnStr, false); err != nil { if err := statement.writeSelect(buf, columnStr, false); err != nil {
return "", nil, err return "", nil, err

View File

@ -526,7 +526,9 @@ func (statement *Statement) buildConds2(table *schemas.Table, bean interface{},
if !includeAutoIncr && col.IsAutoIncrement { if !includeAutoIncr && col.IsAutoIncrement {
continue continue
} }
if col.IsDeleted {
continue
}
if col.IsJSON { if col.IsJSON {
continue continue
} }
@ -549,10 +551,6 @@ func (statement *Statement) buildConds2(table *schemas.Table, bean interface{},
continue continue
} }
if col.IsDeleted && !unscoped { // tag "deleted" is enabled
conds = append(conds, statement.CondDeleted(col))
}
fieldValue := *fieldValuePtr fieldValue := *fieldValuePtr
if fieldValue.Interface() == nil { if fieldValue.Interface() == nil {
continue continue

23
rows.go
View File

@ -50,21 +50,14 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
table := rows.session.statement.RefTable table := rows.session.statement.RefTable
if !session.statement.NoAutoCondition { if !session.statement.NoAutoCondition {
var err error if autoCond, err = session.statement.BuildConds(table, bean, true, true, false, true, addedTableName); err != nil {
autoCond, err = session.statement.BuildConds(table, bean, true, true, false, true, addedTableName)
if err != nil {
return nil, err return nil, 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.GetUnscoped() { // tag "deleted" is enabled
autoCond = session.statement.CondDeleted(col)
}
} }
if col := table.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled
sqlStr, args, err = rows.session.statement.GenFindSQL(autoCond) autoCond = builder.And(autoCond, session.statement.CondDeleted(col))
if err != nil { }
if sqlStr, args, err = rows.session.statement.GenFindSQL(autoCond); err != nil {
return nil, err return nil, err
} }
} else { } else {
@ -72,12 +65,10 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
args = rows.session.statement.RawParams args = rows.session.statement.RawParams
} }
rows.rows, err = rows.session.queryRows(sqlStr, args...) if rows.rows, err = rows.session.queryRows(sqlStr, args...); err != nil {
if err != nil { _ = rows.Close()
rows.Close()
return nil, err return nil, err
} }
return rows, nil return rows, nil
} }

View File

@ -97,7 +97,7 @@ func (session *Session) Truncate(beans ...interface{}) (int64, error) {
func (session *Session) delete(beans []interface{}, mustHaveConditions bool) (int64, error) { func (session *Session) delete(beans []interface{}, mustHaveConditions bool) (int64, error) {
if session.isAutoClose { if session.isAutoClose {
defer session.Close() defer func(session *Session) { _ = session.Close() }(session)
} }
if session.statement.LastError != nil { if session.statement.LastError != nil {
@ -116,7 +116,7 @@ func (session *Session) delete(beans []interface{}, mustHaveConditions bool) (in
executeBeforeClosures(session, bean) executeBeforeClosures(session, bean)
if processor, ok := interface{}(bean).(BeforeDeleteProcessor); ok { if processor, ok := bean.(BeforeDeleteProcessor); ok {
processor.BeforeDelete() processor.BeforeDelete()
} }
@ -124,6 +124,11 @@ func (session *Session) delete(beans []interface{}, mustHaveConditions bool) (in
return 0, err return 0, err
} }
} }
if session.statement.RefTable != nil {
if col := session.statement.RefTable.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled
session.statement.And(session.statement.CondDeleted(col))
}
}
pLimitN := session.statement.LimitN pLimitN := session.statement.LimitN
if mustHaveConditions && !session.statement.Conds().IsValid() && (pLimitN == nil || *pLimitN == 0) { if mustHaveConditions && !session.statement.Conds().IsValid() && (pLimitN == nil || *pLimitN == 0) {
@ -138,15 +143,12 @@ func (session *Session) delete(beans []interface{}, mustHaveConditions bool) (in
if err := session.statement.WriteDelete(realSQLWriter, deleteSQLWriter, session.engine.nowTime); err != nil { if err := session.statement.WriteDelete(realSQLWriter, deleteSQLWriter, session.engine.nowTime); err != nil {
return 0, err return 0, err
} }
if table != nil && table.DeletedColumn() != nil && !session.statement.GetUnscoped() {
if session.statement.GetUnscoped() || table == nil || table.DeletedColumn() == nil { // tag "deleted" is disabled
} else {
deletedColumn := table.DeletedColumn() deletedColumn := table.DeletedColumn()
_, t, err := session.engine.nowTime(deletedColumn) _, t, err := session.engine.nowTime(deletedColumn)
if err != nil { if err != nil {
return 0, err return 0, err
} }
colName := deletedColumn.Name colName := deletedColumn.Name
session.afterClosures = append(session.afterClosures, func(bean interface{}) { session.afterClosures = append(session.afterClosures, func(bean interface{}) {
col := table.GetColumn(colName) col := table.GetColumn(colName)

View File

@ -9,6 +9,7 @@ import (
"errors" "errors"
"reflect" "reflect"
"strings" "strings"
"xorm.io/xorm/core"
"xorm.io/builder" "xorm.io/builder"
"xorm.io/xorm/caches" "xorm.io/xorm/caches"
@ -36,7 +37,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
// FindAndCount find the results and also return the counts // FindAndCount find the results and also return the counts
func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...interface{}) (int64, error) { func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...interface{}) (int64, error) {
if session.isAutoClose { if session.isAutoClose {
defer session.Close() defer func(session *Session) { _ = session.Close() }(session)
} }
session.autoResetStatement = false session.autoResetStatement = false
@ -70,15 +71,13 @@ func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...inte
session.statement.Start = 0 session.statement.Start = 0
} }
// session has stored the conditions so we use `unscoped` to avoid duplicated condition.
if sliceElementType.Kind() == reflect.Struct { if sliceElementType.Kind() == reflect.Struct {
return session.Unscoped().Count(reflect.New(sliceElementType).Interface()) return session.Count(reflect.New(sliceElementType).Interface())
} }
return session.Count()
return session.Unscoped().Count()
} }
func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error { func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) (err error) {
defer session.resetStatement() defer session.resetStatement()
if session.statement.LastError != nil { if session.statement.LastError != nil {
return session.statement.LastError return session.statement.LastError
@ -98,7 +97,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
if sliceElementType.Kind() == reflect.Ptr { if sliceElementType.Kind() == reflect.Ptr {
if sliceElementType.Elem().Kind() == reflect.Struct { if sliceElementType.Elem().Kind() == reflect.Struct {
pv := reflect.New(sliceElementType.Elem()) pv := reflect.New(sliceElementType.Elem())
if err := session.statement.SetRefValue(pv); err != nil { if err = session.statement.SetRefValue(pv); err != nil {
return err return err
} }
} else { } else {
@ -106,7 +105,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
} }
} else if sliceElementType.Kind() == reflect.Struct { } else if sliceElementType.Kind() == reflect.Struct {
pv := reflect.New(sliceElementType) pv := reflect.New(sliceElementType)
if err := session.statement.SetRefValue(pv); err != nil { if err = session.statement.SetRefValue(pv); err != nil {
return err return err
} }
} else { } else {
@ -120,19 +119,19 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
autoCond builder.Cond autoCond builder.Cond
) )
if tp == tpStruct { if tp == tpStruct {
if !session.statement.NoAutoCondition && len(condiBean) > 0 { condTable := table
condTable, err := session.engine.tagParser.Parse(reflect.ValueOf(condiBean[0])) if len(condiBean) > 0 {
if err != nil { if condTable, err = session.engine.tagParser.Parse(reflect.ValueOf(condiBean[0])); err != nil {
return err return err
} }
autoCond, err = session.statement.BuildConds(condTable, condiBean[0], true, true, false, true, addedTableName) }
if err != nil { if len(condiBean) > 0 && !session.statement.NoAutoCondition {
if autoCond, err = session.statement.BuildConds(condTable, condiBean[0], true, true, false, true, addedTableName); err != nil {
return err return err
} }
} else { }
if col := table.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled if col := condTable.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled
autoCond = session.statement.CondDeleted(col) autoCond = builder.And(autoCond, session.statement.CondDeleted(col))
}
} }
} }
@ -236,7 +235,7 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
if err != nil { if err != nil {
return err return err
} }
defer rows.Close() defer func(rows *core.Rows) { _ = rows.Close() }(rows)
fields, err := rows.Columns() fields, err := rows.Columns()
if err != nil { if err != nil {
@ -302,7 +301,7 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
columnsSchema := ParseColumnsSchema(fields, types, tb) columnsSchema := ParseColumnsSchema(fields, types, tb)
err = session.rows2Beans(rows, columnsSchema, fields, types, tb, newElemFunc, containerValueSetFunc) err = session.rows2Beans(rows, columnsSchema, fields, types, tb, newElemFunc, containerValueSetFunc)
rows.Close() _ = rows.Close()
if err != nil { if err != nil {
return err return err
} }
@ -361,7 +360,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
if err != nil { if err != nil {
return err return err
} }
defer rows.Close() defer func(rows *core.Rows) { _ = rows.Close() }(rows)
var i int var i int
ids = make([]schemas.PK, 0) ids = make([]schemas.PK, 0)

View File

@ -29,7 +29,7 @@ var (
// will be as conditions // will be as conditions
func (session *Session) Get(beans ...interface{}) (bool, error) { func (session *Session) Get(beans ...interface{}) (bool, error) {
if session.isAutoClose { if session.isAutoClose {
defer session.Close() defer func(session *Session) { _ = session.Close() }(session)
} }
return session.get(beans...) return session.get(beans...)
} }

View File

@ -28,12 +28,6 @@ func (session *Session) genAutoCond(condiBean interface{}) (builder.Cond, error)
for k, v := range c { for k, v := range c {
eq[session.engine.Quote(k)] = v eq[session.engine.Quote(k)] = v
} }
if session.statement.RefTable != nil {
if col := session.statement.RefTable.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled
return eq.And(session.statement.CondDeleted(col)), nil
}
}
return eq, nil return eq, nil
} }
@ -62,7 +56,7 @@ func (session *Session) genAutoCond(condiBean interface{}) (builder.Cond, error)
// 2.float32 & float64 may be not inexact as conditions // 2.float32 & float64 may be not inexact as conditions
func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int64, error) { func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int64, error) {
if session.isAutoClose { if session.isAutoClose {
defer session.Close() defer func(session *Session) { _ = session.Close() }(session)
} }
defer session.resetStatement() defer session.resetStatement()
@ -79,7 +73,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
closure(bean) closure(bean)
} }
cleanupProcessorsClosures(&session.beforeClosures) // cleanup after used cleanupProcessorsClosures(&session.beforeClosures) // cleanup after used
if processor, ok := interface{}(bean).(BeforeUpdateProcessor); ok { if processor, ok := bean.(BeforeUpdateProcessor); ok {
processor.BeforeUpdate() processor.BeforeUpdate()
} }
// -- // --
@ -90,7 +84,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
isMap := t.Kind() == reflect.Map isMap := t.Kind() == reflect.Map
isStruct := t.Kind() == reflect.Struct isStruct := t.Kind() == reflect.Struct
if isStruct { if isStruct {
if err := session.statement.SetRefBean(bean); err != nil { if err = session.statement.SetRefBean(bean); err != nil {
return 0, err return 0, err
} }
@ -153,19 +147,13 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
var autoCond builder.Cond var autoCond builder.Cond
if len(condiBean) > 0 { if len(condiBean) > 0 {
autoCond, err = session.genAutoCond(condiBean[0]) if autoCond, err = session.genAutoCond(condiBean[0]); err != nil {
if err != nil {
return 0, err return 0, err
} }
} else if table != nil { }
if table != nil {
if col := table.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled if col := table.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled
autoCond1 := session.statement.CondDeleted(col) autoCond = builder.And(autoCond, session.statement.CondDeleted(col))
if autoCond == nil {
autoCond = autoCond1
} else {
autoCond = autoCond.And(autoCond1)
}
} }
} }