Merge branch 'oinume-feature/softdelete'
This commit is contained in:
commit
60dfca5ea4
|
@ -776,6 +776,8 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
|
||||||
col.Default = "1"
|
col.Default = "1"
|
||||||
case k == "UPDATED":
|
case k == "UPDATED":
|
||||||
col.IsUpdated = true
|
col.IsUpdated = true
|
||||||
|
case k == "DELETED":
|
||||||
|
col.IsDeleted = true
|
||||||
case strings.HasPrefix(k, "INDEX(") && strings.HasSuffix(k, ")"):
|
case strings.HasPrefix(k, "INDEX(") && strings.HasSuffix(k, ")"):
|
||||||
indexName := k[len("INDEX")+1 : len(k)-1]
|
indexName := k[len("INDEX")+1 : len(k)-1]
|
||||||
indexNames[indexName] = core.IndexType
|
indexNames[indexName] = core.IndexType
|
||||||
|
@ -1414,3 +1416,10 @@ func (engine *Engine) FormatTime(sqlTypeName string, t time.Time) (v interface{}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always disable struct tag "deleted"
|
||||||
|
func (engine *Engine) Unscoped() *Session {
|
||||||
|
session := engine.NewSession()
|
||||||
|
session.IsAutoClose = true
|
||||||
|
return session.Unscoped()
|
||||||
|
}
|
||||||
|
|
46
session.go
46
session.go
|
@ -1079,7 +1079,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
if len(condiBean) > 0 {
|
if len(condiBean) > 0 {
|
||||||
colNames, args := buildConditions(session.Engine, table, condiBean[0], true, true,
|
colNames, args := buildConditions(session.Engine, table, condiBean[0], true, true,
|
||||||
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
||||||
session.Statement.mustColumnMap)
|
session.Statement.unscoped, session.Statement.mustColumnMap)
|
||||||
session.Statement.ConditionStr = strings.Join(colNames, " AND ")
|
session.Statement.ConditionStr = strings.Join(colNames, " AND ")
|
||||||
session.Statement.BeanArgs = args
|
session.Statement.BeanArgs = args
|
||||||
}
|
}
|
||||||
|
@ -3172,7 +3172,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
if len(condiBean) > 0 {
|
if len(condiBean) > 0 {
|
||||||
condiColNames, condiArgs = buildConditions(session.Engine, session.Statement.RefTable, condiBean[0], true, true,
|
condiColNames, condiArgs = buildConditions(session.Engine, session.Statement.RefTable, condiBean[0], true, true,
|
||||||
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
||||||
session.Statement.mustColumnMap)
|
session.Statement.unscoped, session.Statement.mustColumnMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
var condition = ""
|
var condition = ""
|
||||||
|
@ -3376,7 +3376,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||||
session.Statement.RefTable = table
|
session.Statement.RefTable = table
|
||||||
colNames, args := buildConditions(session.Engine, table, bean, true, true,
|
colNames, args := buildConditions(session.Engine, table, bean, true, true,
|
||||||
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
||||||
session.Statement.mustColumnMap)
|
session.Statement.unscoped, session.Statement.mustColumnMap)
|
||||||
|
|
||||||
var condition = ""
|
var condition = ""
|
||||||
var andStr = session.Engine.dialect.AndStr()
|
var andStr = session.Engine.dialect.AndStr()
|
||||||
|
@ -3402,13 +3402,39 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||||
return 0, ErrNeedDeletedCond
|
return 0, ErrNeedDeletedCond
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlStr := fmt.Sprintf("DELETE FROM %v WHERE %v",
|
sqlStr, sqlStrForCache := "", ""
|
||||||
|
argsForCache := make([]interface{}, 0, len(args) * 2)
|
||||||
|
if session.Statement.unscoped || table.DeletedColumn() == nil { // tag "deleted" is disabled
|
||||||
|
sqlStr = fmt.Sprintf("DELETE FROM %v WHERE %v",
|
||||||
session.Engine.Quote(session.Statement.TableName()), condition)
|
session.Engine.Quote(session.Statement.TableName()), condition)
|
||||||
|
|
||||||
|
sqlStrForCache = sqlStr
|
||||||
|
copy(argsForCache, args)
|
||||||
|
argsForCache = append(session.Statement.Params, argsForCache...)
|
||||||
|
} else {
|
||||||
|
// !oinume! sqlStrForCache and argsForCache is needed to behave as executing "DELETE FROM ..." for cache.
|
||||||
|
sqlStrForCache = fmt.Sprintf("DELETE FROM %v WHERE %v",
|
||||||
|
session.Engine.Quote(session.Statement.TableName()), condition)
|
||||||
|
copy(argsForCache, args)
|
||||||
|
argsForCache = append(session.Statement.Params, argsForCache...)
|
||||||
|
|
||||||
|
deletedColumn := table.DeletedColumn()
|
||||||
|
sqlStr = fmt.Sprintf("UPDATE %v SET %v = ? WHERE %v",
|
||||||
|
session.Engine.Quote(session.Statement.TableName()),
|
||||||
|
session.Engine.Quote(deletedColumn.Name),
|
||||||
|
condition)
|
||||||
|
|
||||||
|
// !oinume! Insert NowTime to the head of session.Statement.Params
|
||||||
|
session.Statement.Params = append(session.Statement.Params, "")
|
||||||
|
paramsLen := len(session.Statement.Params)
|
||||||
|
copy(session.Statement.Params[1:paramsLen], session.Statement.Params[0:paramsLen-1])
|
||||||
|
session.Statement.Params[0] = session.Engine.NowTime(deletedColumn.SQLType.Name)
|
||||||
|
}
|
||||||
|
|
||||||
args = append(session.Statement.Params, args...)
|
args = append(session.Statement.Params, args...)
|
||||||
|
|
||||||
if cacher := session.Engine.getCacher2(session.Statement.RefTable); cacher != nil && session.Statement.UseCache {
|
if cacher := session.Engine.getCacher2(session.Statement.RefTable); cacher != nil && session.Statement.UseCache {
|
||||||
session.cacheDelete(sqlStr, args...)
|
session.cacheDelete(sqlStrForCache, argsForCache...)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := session.exec(sqlStr, args...)
|
res, err := session.exec(sqlStr, args...)
|
||||||
|
@ -3612,6 +3638,12 @@ func (s *Session) Sync2(beans ...interface{}) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always disable struct tag "deleted"
|
||||||
|
func (session *Session) Unscoped() *Session {
|
||||||
|
session.Statement.Unscoped()
|
||||||
|
return session
|
||||||
|
}
|
||||||
|
|
||||||
func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, includeQuote bool) ([]string, []interface{}, error) {
|
func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, includeQuote bool) ([]string, []interface{}, error) {
|
||||||
colNames := make([]string, 0)
|
colNames := make([]string, 0)
|
||||||
args := make([]interface{}, 0)
|
args := make([]interface{}, 0)
|
||||||
|
@ -3651,6 +3683,10 @@ func genCols(table *core.Table, session *Session, bean interface{}, useCol bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if col.IsDeleted {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if session.Statement.ColumnStr != "" {
|
if session.Statement.ColumnStr != "" {
|
||||||
if _, ok := session.Statement.columnMap[lColName]; !ok {
|
if _, ok := session.Statement.columnMap[lColName]; !ok {
|
||||||
continue
|
continue
|
||||||
|
|
22
statement.go
22
statement.go
|
@ -57,6 +57,7 @@ type Statement struct {
|
||||||
IsDistinct bool
|
IsDistinct bool
|
||||||
allUseBool bool
|
allUseBool bool
|
||||||
checkVersion bool
|
checkVersion bool
|
||||||
|
unscoped bool
|
||||||
mustColumnMap map[string]bool
|
mustColumnMap map[string]bool
|
||||||
inColumns map[string]*inParam
|
inColumns map[string]*inParam
|
||||||
incrColumns map[string]incrParam
|
incrColumns map[string]incrParam
|
||||||
|
@ -91,6 +92,7 @@ func (statement *Statement) Init() {
|
||||||
statement.useAllCols = false
|
statement.useAllCols = false
|
||||||
statement.mustColumnMap = make(map[string]bool)
|
statement.mustColumnMap = make(map[string]bool)
|
||||||
statement.checkVersion = true
|
statement.checkVersion = true
|
||||||
|
statement.unscoped = false
|
||||||
statement.inColumns = make(map[string]*inParam)
|
statement.inColumns = make(map[string]*inParam)
|
||||||
statement.incrColumns = make(map[string]incrParam)
|
statement.incrColumns = make(map[string]incrParam)
|
||||||
statement.decrColumns = make(map[string]decrParam)
|
statement.decrColumns = make(map[string]decrParam)
|
||||||
|
@ -286,6 +288,9 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||||
if !includeAutoIncr && col.IsAutoIncrement {
|
if !includeAutoIncr && col.IsAutoIncrement {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if col.IsDeleted {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text {
|
if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text {
|
||||||
continue
|
continue
|
||||||
|
@ -465,7 +470,7 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||||
// Auto generating conditions according a struct
|
// Auto generating conditions according a struct
|
||||||
func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
||||||
includeVersion bool, includeUpdated bool, includeNil bool,
|
includeVersion bool, includeUpdated bool, includeNil bool,
|
||||||
includeAutoIncr bool, allUseBool bool, useAllCols bool,
|
includeAutoIncr bool, allUseBool bool, useAllCols bool, unscoped bool,
|
||||||
mustColumnMap map[string]bool) ([]string, []interface{}) {
|
mustColumnMap map[string]bool) ([]string, []interface{}) {
|
||||||
|
|
||||||
colNames := make([]string, 0)
|
colNames := make([]string, 0)
|
||||||
|
@ -490,6 +495,10 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if col.IsDeleted && !unscoped { // tag "deleted" is enabled
|
||||||
|
colNames = append(colNames, fmt.Sprintf("%v IS NULL", engine.Quote(col.Name)))
|
||||||
|
}
|
||||||
|
|
||||||
fieldValue := *fieldValuePtr
|
fieldValue := *fieldValuePtr
|
||||||
if fieldValue.Interface() == nil {
|
if fieldValue.Interface() == nil {
|
||||||
continue
|
continue
|
||||||
|
@ -926,6 +935,12 @@ func (statement *Statement) Having(conditions string) *Statement {
|
||||||
return statement
|
return statement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always disable struct tag "deleted"
|
||||||
|
func (statement *Statement) Unscoped() *Statement {
|
||||||
|
statement.unscoped = true
|
||||||
|
return statement
|
||||||
|
}
|
||||||
|
|
||||||
func (statement *Statement) genColumnStr() string {
|
func (statement *Statement) genColumnStr() string {
|
||||||
table := statement.RefTable
|
table := statement.RefTable
|
||||||
colNames := make([]string, 0)
|
colNames := make([]string, 0)
|
||||||
|
@ -1030,7 +1045,7 @@ func (statement *Statement) genGetSql(bean interface{}) (string, []interface{})
|
||||||
|
|
||||||
colNames, args := buildConditions(statement.Engine, table, bean, true, true,
|
colNames, args := buildConditions(statement.Engine, table, bean, true, true,
|
||||||
false, true, statement.allUseBool, statement.useAllCols,
|
false, true, statement.allUseBool, statement.useAllCols,
|
||||||
statement.mustColumnMap)
|
statement.unscoped, statement.mustColumnMap)
|
||||||
|
|
||||||
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.dialect.AndStr()+" ")
|
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.dialect.AndStr()+" ")
|
||||||
statement.BeanArgs = args
|
statement.BeanArgs = args
|
||||||
|
@ -1076,7 +1091,8 @@ func (statement *Statement) genCountSql(bean interface{}) (string, []interface{}
|
||||||
statement.RefTable = table
|
statement.RefTable = table
|
||||||
|
|
||||||
colNames, args := buildConditions(statement.Engine, table, bean, true, true, false,
|
colNames, args := buildConditions(statement.Engine, table, bean, true, true, false,
|
||||||
true, statement.allUseBool, statement.useAllCols, statement.mustColumnMap)
|
true, statement.allUseBool, statement.useAllCols,
|
||||||
|
statement.unscoped, statement.mustColumnMap)
|
||||||
|
|
||||||
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.Dialect().AndStr()+" ")
|
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.Dialect().AndStr()+" ")
|
||||||
statement.BeanArgs = args
|
statement.BeanArgs = args
|
||||||
|
|
Loading…
Reference in New Issue