From 8f07aa25b9a2a5591293f8f0b73b73e33babbd46 Mon Sep 17 00:00:00 2001 From: CyJaySong Date: Mon, 26 Feb 2024 09:46:34 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=A5=20NoAutoCondition=20=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E5=BD=B1=E5=93=8Ddeleted=E6=9D=A1=E4=BB=B6=E7=94=9F?= =?UTF-8?q?=E6=88=90=EF=BC=8Cdeleted=E6=9D=A1=E4=BB=B6=E4=BB=85=E7=94=B1Un?= =?UTF-8?q?scoped=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/statements/query.go | 6 ++++- internal/statements/statement.go | 8 +++---- rows.go | 23 ++++++------------- session_delete.go | 14 +++++++----- session_find.go | 39 ++++++++++++++++---------------- session_get.go | 2 +- session_update.go | 26 ++++++--------------- 7 files changed, 50 insertions(+), 68 deletions(-) diff --git a/internal/statements/query.go b/internal/statements/query.go index e817403c..320744d7 100644 --- a/internal/statements/query.go +++ b/internal/statements/query.go @@ -118,7 +118,11 @@ func (statement *Statement) GenGetSQL(bean interface{}) (string, []interface{}, 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() if err := statement.writeSelect(buf, columnStr, false); err != nil { return "", nil, err diff --git a/internal/statements/statement.go b/internal/statements/statement.go index 734cc19a..ab4e04e3 100644 --- a/internal/statements/statement.go +++ b/internal/statements/statement.go @@ -526,7 +526,9 @@ func (statement *Statement) buildConds2(table *schemas.Table, bean interface{}, if !includeAutoIncr && col.IsAutoIncrement { continue } - + if col.IsDeleted { + continue + } if col.IsJSON { continue } @@ -549,10 +551,6 @@ func (statement *Statement) buildConds2(table *schemas.Table, bean interface{}, continue } - if col.IsDeleted && !unscoped { // tag "deleted" is enabled - conds = append(conds, statement.CondDeleted(col)) - } - fieldValue := *fieldValuePtr if fieldValue.Interface() == nil { continue diff --git a/rows.go b/rows.go index c539410e..0457a73d 100644 --- a/rows.go +++ b/rows.go @@ -50,21 +50,14 @@ func newRows(session *Session, bean interface{}) (*Rows, error) { table := rows.session.statement.RefTable if !session.statement.NoAutoCondition { - var err error - autoCond, err = session.statement.BuildConds(table, bean, true, true, false, true, addedTableName) - if err != nil { + if autoCond, err = session.statement.BuildConds(table, bean, true, true, false, true, addedTableName); err != nil { return nil, err } - } else { - // !oinume! Add " 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) - } } - - sqlStr, args, err = rows.session.statement.GenFindSQL(autoCond) - if err != nil { + if col := table.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled + autoCond = builder.And(autoCond, session.statement.CondDeleted(col)) + } + if sqlStr, args, err = rows.session.statement.GenFindSQL(autoCond); err != nil { return nil, err } } else { @@ -72,12 +65,10 @@ func newRows(session *Session, bean interface{}) (*Rows, error) { args = rows.session.statement.RawParams } - rows.rows, err = rows.session.queryRows(sqlStr, args...) - if err != nil { - rows.Close() + if rows.rows, err = rows.session.queryRows(sqlStr, args...); err != nil { + _ = rows.Close() return nil, err } - return rows, nil } diff --git a/session_delete.go b/session_delete.go index 7336040f..fd33530a 100644 --- a/session_delete.go +++ b/session_delete.go @@ -97,7 +97,7 @@ func (session *Session) Truncate(beans ...interface{}) (int64, error) { func (session *Session) delete(beans []interface{}, mustHaveConditions bool) (int64, error) { if session.isAutoClose { - defer session.Close() + defer func(session *Session) { _ = session.Close() }(session) } if session.statement.LastError != nil { @@ -116,7 +116,7 @@ func (session *Session) delete(beans []interface{}, mustHaveConditions bool) (in executeBeforeClosures(session, bean) - if processor, ok := interface{}(bean).(BeforeDeleteProcessor); ok { + if processor, ok := bean.(BeforeDeleteProcessor); ok { processor.BeforeDelete() } @@ -124,6 +124,11 @@ func (session *Session) delete(beans []interface{}, mustHaveConditions bool) (in 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 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 { return 0, err } - - if session.statement.GetUnscoped() || table == nil || table.DeletedColumn() == nil { // tag "deleted" is disabled - } else { + if table != nil && table.DeletedColumn() != nil && !session.statement.GetUnscoped() { deletedColumn := table.DeletedColumn() _, t, err := session.engine.nowTime(deletedColumn) if err != nil { return 0, err } - colName := deletedColumn.Name session.afterClosures = append(session.afterClosures, func(bean interface{}) { col := table.GetColumn(colName) diff --git a/session_find.go b/session_find.go index 1026910c..cbf2be58 100644 --- a/session_find.go +++ b/session_find.go @@ -9,6 +9,7 @@ import ( "errors" "reflect" "strings" + "xorm.io/xorm/core" "xorm.io/builder" "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 func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...interface{}) (int64, error) { if session.isAutoClose { - defer session.Close() + defer func(session *Session) { _ = session.Close() }(session) } session.autoResetStatement = false @@ -70,15 +71,13 @@ func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...inte session.statement.Start = 0 } - // session has stored the conditions so we use `unscoped` to avoid duplicated condition. if sliceElementType.Kind() == reflect.Struct { - return session.Unscoped().Count(reflect.New(sliceElementType).Interface()) + return session.Count(reflect.New(sliceElementType).Interface()) } - - return session.Unscoped().Count() + return session.Count() } -func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error { +func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) (err error) { defer session.resetStatement() if session.statement.LastError != nil { return session.statement.LastError @@ -98,7 +97,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 { @@ -106,7 +105,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 { @@ -120,19 +119,19 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) autoCond builder.Cond ) if tp == tpStruct { - if !session.statement.NoAutoCondition && len(condiBean) > 0 { - condTable, err := session.engine.tagParser.Parse(reflect.ValueOf(condiBean[0])) - if err != nil { + condTable := table + if len(condiBean) > 0 { + if condTable, err = session.engine.tagParser.Parse(reflect.ValueOf(condiBean[0])); err != nil { 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 } - } else { - if col := table.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled - autoCond = session.statement.CondDeleted(col) - } + } + if col := condTable.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled + autoCond = builder.And(autoCond, session.statement.CondDeleted(col)) } } @@ -236,7 +235,7 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect if err != nil { return err } - defer rows.Close() + defer func(rows *core.Rows) { _ = rows.Close() }(rows) fields, err := rows.Columns() if err != nil { @@ -302,7 +301,7 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect columnsSchema := ParseColumnsSchema(fields, types, tb) err = session.rows2Beans(rows, columnsSchema, fields, types, tb, newElemFunc, containerValueSetFunc) - rows.Close() + _ = rows.Close() if err != nil { return err } @@ -361,7 +360,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in if err != nil { return err } - defer rows.Close() + defer func(rows *core.Rows) { _ = rows.Close() }(rows) var i int ids = make([]schemas.PK, 0) diff --git a/session_get.go b/session_get.go index 76ccaf97..86779b23 100644 --- a/session_get.go +++ b/session_get.go @@ -29,7 +29,7 @@ var ( // will be as conditions func (session *Session) Get(beans ...interface{}) (bool, error) { if session.isAutoClose { - defer session.Close() + defer func(session *Session) { _ = session.Close() }(session) } return session.get(beans...) } diff --git a/session_update.go b/session_update.go index b3640ad2..7ac91a39 100644 --- a/session_update.go +++ b/session_update.go @@ -28,12 +28,6 @@ func (session *Session) genAutoCond(condiBean interface{}) (builder.Cond, error) for k, v := range c { 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 } @@ -62,7 +56,7 @@ func (session *Session) genAutoCond(condiBean interface{}) (builder.Cond, error) // 2.float32 & float64 may be not inexact as conditions func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int64, error) { if session.isAutoClose { - defer session.Close() + defer func(session *Session) { _ = session.Close() }(session) } defer session.resetStatement() @@ -79,7 +73,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 closure(bean) } cleanupProcessorsClosures(&session.beforeClosures) // cleanup after used - if processor, ok := interface{}(bean).(BeforeUpdateProcessor); ok { + if processor, ok := bean.(BeforeUpdateProcessor); ok { processor.BeforeUpdate() } // -- @@ -90,7 +84,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 isMap := t.Kind() == reflect.Map isStruct := t.Kind() == reflect.Struct if isStruct { - if err := session.statement.SetRefBean(bean); err != nil { + if err = session.statement.SetRefBean(bean); err != nil { return 0, err } @@ -153,19 +147,13 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6 var autoCond builder.Cond if len(condiBean) > 0 { - autoCond, err = session.genAutoCond(condiBean[0]) - if err != nil { + if autoCond, err = session.genAutoCond(condiBean[0]); err != nil { return 0, err } - } else if table != nil { + } + if table != nil { if col := table.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled - autoCond1 := session.statement.CondDeleted(col) - - if autoCond == nil { - autoCond = autoCond1 - } else { - autoCond = autoCond.And(autoCond1) - } + autoCond = builder.And(autoCond, session.statement.CondDeleted(col)) } }