forked from forgejo/forgejo
Use AfterLoad instead of AfterSet on Structs (#2628)
* use AfterLoad instead of AfterSet on Structs * fix the comments on AfterLoad * fix the comments on action AfterLoad
This commit is contained in:
parent
1ad902d529
commit
a8717e5e3a
35 changed files with 334 additions and 315 deletions
17
vendor/github.com/go-xorm/xorm/engine.go
generated
vendored
17
vendor/github.com/go-xorm/xorm/engine.go
generated
vendored
|
@ -1516,10 +1516,14 @@ func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
|
|||
return results, lastError
|
||||
}
|
||||
|
||||
// NowTime2 return current time
|
||||
func (engine *Engine) NowTime2(sqlTypeName string) (interface{}, time.Time) {
|
||||
// nowTime return current time
|
||||
func (engine *Engine) nowTime(col *core.Column) (interface{}, time.Time) {
|
||||
t := time.Now()
|
||||
return engine.formatTime(sqlTypeName, t.In(engine.DatabaseTZ)), t.In(engine.TZLocation)
|
||||
var tz = engine.DatabaseTZ
|
||||
if !col.DisableTimeZone && col.TimeZone != nil {
|
||||
tz = col.TimeZone
|
||||
}
|
||||
return engine.formatTime(col.SQLType.Name, t.In(tz)), t.In(engine.TZLocation)
|
||||
}
|
||||
|
||||
func (engine *Engine) formatColTime(col *core.Column, t time.Time) (v interface{}) {
|
||||
|
@ -1574,3 +1578,10 @@ func (engine *Engine) CondDeleted(colName string) builder.Cond {
|
|||
}
|
||||
return builder.IsNull{colName}.Or(builder.Eq{colName: zeroTime1})
|
||||
}
|
||||
|
||||
// BufferSize sets buffer size for iterate
|
||||
func (engine *Engine) BufferSize(size int) *Session {
|
||||
session := engine.NewSession()
|
||||
session.isAutoClose = true
|
||||
return session.BufferSize(size)
|
||||
}
|
||||
|
|
2
vendor/github.com/go-xorm/xorm/helpers.go
generated
vendored
2
vendor/github.com/go-xorm/xorm/helpers.go
generated
vendored
|
@ -422,7 +422,7 @@ func genCols(table *core.Table, session *Session, bean interface{}, useCol bool,
|
|||
|
||||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
|
||||
// if time is non-empty, then set to auto time
|
||||
val, t := session.engine.NowTime2(col.SQLType.Name)
|
||||
val, t := session.engine.nowTime(col)
|
||||
args = append(args, val)
|
||||
|
||||
var colName = col.Name
|
||||
|
|
40
vendor/github.com/go-xorm/xorm/processors.go
generated
vendored
40
vendor/github.com/go-xorm/xorm/processors.go
generated
vendored
|
@ -29,13 +29,6 @@ type AfterSetProcessor interface {
|
|||
AfterSet(string, Cell)
|
||||
}
|
||||
|
||||
// !nashtsai! TODO enable BeforeValidateProcessor when xorm start to support validations
|
||||
//// Executed before an object is validated
|
||||
//type BeforeValidateProcessor interface {
|
||||
// BeforeValidate()
|
||||
//}
|
||||
// --
|
||||
|
||||
// AfterInsertProcessor executed after an object is persisted to the database
|
||||
type AfterInsertProcessor interface {
|
||||
AfterInsert()
|
||||
|
@ -50,3 +43,36 @@ type AfterUpdateProcessor interface {
|
|||
type AfterDeleteProcessor interface {
|
||||
AfterDelete()
|
||||
}
|
||||
|
||||
// AfterLoadProcessor executed after an ojbect has been loaded from database
|
||||
type AfterLoadProcessor interface {
|
||||
AfterLoad()
|
||||
}
|
||||
|
||||
// AfterLoadSessionProcessor executed after an ojbect has been loaded from database with session parameter
|
||||
type AfterLoadSessionProcessor interface {
|
||||
AfterLoad(*Session)
|
||||
}
|
||||
|
||||
type executedProcessorFunc func(*Session, interface{}) error
|
||||
|
||||
type executedProcessor struct {
|
||||
fun executedProcessorFunc
|
||||
session *Session
|
||||
bean interface{}
|
||||
}
|
||||
|
||||
func (executor *executedProcessor) execute() error {
|
||||
return executor.fun(executor.session, executor.bean)
|
||||
}
|
||||
|
||||
func (session *Session) executeProcessors() error {
|
||||
processors := session.afterProcessors
|
||||
session.afterProcessors = make([]executedProcessor, 0)
|
||||
for _, processor := range processors {
|
||||
if err := processor.execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
10
vendor/github.com/go-xorm/xorm/rows.go
generated
vendored
10
vendor/github.com/go-xorm/xorm/rows.go
generated
vendored
|
@ -99,13 +99,17 @@ func (rows *Rows) Scan(bean interface{}) error {
|
|||
return err
|
||||
}
|
||||
|
||||
scanResults, err := rows.session.row2Slice(rows.rows, rows.fields, len(rows.fields), bean)
|
||||
scanResults, err := rows.session.row2Slice(rows.rows, rows.fields, bean)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = rows.session.slice2Bean(scanResults, rows.fields, len(rows.fields), bean, &dataStruct, rows.session.statement.RefTable)
|
||||
return err
|
||||
_, err = rows.session.slice2Bean(scanResults, rows.fields, bean, &dataStruct, rows.session.statement.RefTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return rows.session.executeProcessors()
|
||||
}
|
||||
|
||||
// Close session if session.IsAutoClose is true, and claimed any opened resources
|
||||
|
|
68
vendor/github.com/go-xorm/xorm/session.go
generated
vendored
68
vendor/github.com/go-xorm/xorm/session.go
generated
vendored
|
@ -41,6 +41,8 @@ type Session struct {
|
|||
beforeClosures []func(interface{})
|
||||
afterClosures []func(interface{})
|
||||
|
||||
afterProcessors []executedProcessor
|
||||
|
||||
prepareStmt bool
|
||||
stmtCache map[uint32]*core.Stmt //key: hash.Hash32 of (queryStr, len(queryStr))
|
||||
|
||||
|
@ -75,6 +77,8 @@ func (session *Session) Init() {
|
|||
session.beforeClosures = make([]func(interface{}), 0)
|
||||
session.afterClosures = make([]func(interface{}), 0)
|
||||
|
||||
session.afterProcessors = make([]executedProcessor, 0)
|
||||
|
||||
session.lastSQL = ""
|
||||
session.lastSQLArgs = []interface{}{}
|
||||
}
|
||||
|
@ -296,37 +300,40 @@ func (session *Session) getField(dataStruct *reflect.Value, key string, table *c
|
|||
// Cell cell is a result of one column field
|
||||
type Cell *interface{}
|
||||
|
||||
func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount int,
|
||||
func (session *Session) rows2Beans(rows *core.Rows, fields []string,
|
||||
table *core.Table, newElemFunc func([]string) reflect.Value,
|
||||
sliceValueSetFunc func(*reflect.Value, core.PK) error) error {
|
||||
for rows.Next() {
|
||||
var newValue = newElemFunc(fields)
|
||||
bean := newValue.Interface()
|
||||
dataStruct := rValue(bean)
|
||||
dataStruct := newValue.Elem()
|
||||
|
||||
// handle beforeClosures
|
||||
scanResults, err := session.row2Slice(rows, fields, fieldsCount, bean)
|
||||
scanResults, err := session.row2Slice(rows, fields, bean)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pk, err := session.slice2Bean(scanResults, fields, fieldsCount, bean, &dataStruct, table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = sliceValueSetFunc(&newValue, pk)
|
||||
pk, err := session.slice2Bean(scanResults, fields, bean, &dataStruct, table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
session.afterProcessors = append(session.afterProcessors, executedProcessor{
|
||||
fun: func(*Session, interface{}) error {
|
||||
return sliceValueSetFunc(&newValue, pk)
|
||||
},
|
||||
session: session,
|
||||
bean: bean,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (session *Session) row2Slice(rows *core.Rows, fields []string, fieldsCount int, bean interface{}) ([]interface{}, error) {
|
||||
func (session *Session) row2Slice(rows *core.Rows, fields []string, bean interface{}) ([]interface{}, error) {
|
||||
for _, closure := range session.beforeClosures {
|
||||
closure(bean)
|
||||
}
|
||||
|
||||
scanResults := make([]interface{}, fieldsCount)
|
||||
scanResults := make([]interface{}, len(fields))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
var cell interface{}
|
||||
scanResults[i] = &cell
|
||||
|
@ -343,20 +350,49 @@ func (session *Session) row2Slice(rows *core.Rows, fields []string, fieldsCount
|
|||
return scanResults, nil
|
||||
}
|
||||
|
||||
func (session *Session) slice2Bean(scanResults []interface{}, fields []string, fieldsCount int, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) {
|
||||
func (session *Session) slice2Bean(scanResults []interface{}, fields []string, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) {
|
||||
defer func() {
|
||||
if b, hasAfterSet := bean.(AfterSetProcessor); hasAfterSet {
|
||||
for ii, key := range fields {
|
||||
b.AfterSet(key, Cell(scanResults[ii].(*interface{})))
|
||||
}
|
||||
}
|
||||
|
||||
// handle afterClosures
|
||||
for _, closure := range session.afterClosures {
|
||||
closure(bean)
|
||||
}
|
||||
}()
|
||||
|
||||
// handle afterClosures
|
||||
for _, closure := range session.afterClosures {
|
||||
session.afterProcessors = append(session.afterProcessors, executedProcessor{
|
||||
fun: func(sess *Session, bean interface{}) error {
|
||||
closure(bean)
|
||||
return nil
|
||||
},
|
||||
session: session,
|
||||
bean: bean,
|
||||
})
|
||||
}
|
||||
|
||||
if a, has := bean.(AfterLoadProcessor); has {
|
||||
session.afterProcessors = append(session.afterProcessors, executedProcessor{
|
||||
fun: func(sess *Session, bean interface{}) error {
|
||||
a.AfterLoad()
|
||||
return nil
|
||||
},
|
||||
session: session,
|
||||
bean: bean,
|
||||
})
|
||||
}
|
||||
|
||||
if a, has := bean.(AfterLoadSessionProcessor); has {
|
||||
session.afterProcessors = append(session.afterProcessors, executedProcessor{
|
||||
fun: func(sess *Session, bean interface{}) error {
|
||||
a.AfterLoad(sess)
|
||||
return nil
|
||||
},
|
||||
session: session,
|
||||
bean: bean,
|
||||
})
|
||||
}
|
||||
|
||||
var tempMap = make(map[string]int)
|
||||
var pk core.PK
|
||||
for ii, key := range fields {
|
||||
|
|
4
vendor/github.com/go-xorm/xorm/session_delete.go
generated
vendored
4
vendor/github.com/go-xorm/xorm/session_delete.go
generated
vendored
|
@ -184,12 +184,12 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// !oinume! Insert NowTime to the head of session.statement.Params
|
||||
// !oinume! Insert nowTime to the head of session.statement.Params
|
||||
condArgs = append(condArgs, "")
|
||||
paramsLen := len(condArgs)
|
||||
copy(condArgs[1:paramsLen], condArgs[0:paramsLen-1])
|
||||
|
||||
val, t := session.engine.NowTime2(deletedColumn.SQLType.Name)
|
||||
val, t := session.engine.nowTime(deletedColumn)
|
||||
condArgs[0] = val
|
||||
|
||||
var colName = deletedColumn.Name
|
||||
|
|
7
vendor/github.com/go-xorm/xorm/session_find.go
generated
vendored
7
vendor/github.com/go-xorm/xorm/session_find.go
generated
vendored
|
@ -239,7 +239,12 @@ func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Va
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return session.rows2Beans(rows, fields, len(fields), tb, newElemFunc, containerValueSetFunc)
|
||||
err = session.rows2Beans(rows, fields, tb, newElemFunc, containerValueSetFunc)
|
||||
rows.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return session.executeProcessors()
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
|
|
9
vendor/github.com/go-xorm/xorm/session_get.go
generated
vendored
9
vendor/github.com/go-xorm/xorm/session_get.go
generated
vendored
|
@ -87,7 +87,7 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
|
|||
return true, err
|
||||
}
|
||||
|
||||
scanResults, err := session.row2Slice(rows, fields, len(fields), bean)
|
||||
scanResults, err := session.row2Slice(rows, fields, bean)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -95,7 +95,12 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
|
|||
rows.Close()
|
||||
|
||||
dataStruct := rValue(bean)
|
||||
_, err = session.slice2Bean(scanResults, fields, len(fields), bean, &dataStruct, table)
|
||||
_, err = session.slice2Bean(scanResults, fields, bean, &dataStruct, table)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
return true, session.executeProcessors()
|
||||
case reflect.Slice:
|
||||
err = rows.ScanSlice(bean)
|
||||
case reflect.Map:
|
||||
|
|
4
vendor/github.com/go-xorm/xorm/session_insert.go
generated
vendored
4
vendor/github.com/go-xorm/xorm/session_insert.go
generated
vendored
|
@ -126,7 +126,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
|||
}
|
||||
}
|
||||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
|
||||
val, t := session.engine.NowTime2(col.SQLType.Name)
|
||||
val, t := session.engine.nowTime(col)
|
||||
args = append(args, val)
|
||||
|
||||
var colName = col.Name
|
||||
|
@ -181,7 +181,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
|||
}
|
||||
}
|
||||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
|
||||
val, t := session.engine.NowTime2(col.SQLType.Name)
|
||||
val, t := session.engine.nowTime(col)
|
||||
args = append(args, val)
|
||||
|
||||
var colName = col.Name
|
||||
|
|
50
vendor/github.com/go-xorm/xorm/session_iterate.go
generated
vendored
50
vendor/github.com/go-xorm/xorm/session_iterate.go
generated
vendored
|
@ -23,6 +23,10 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
|
|||
defer session.Close()
|
||||
}
|
||||
|
||||
if session.statement.bufferSize > 0 {
|
||||
return session.bufferIterate(bean, fun)
|
||||
}
|
||||
|
||||
rows, err := session.Rows(bean)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -44,3 +48,49 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
|
|||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// BufferSize sets the buffersize for iterate
|
||||
func (session *Session) BufferSize(size int) *Session {
|
||||
session.statement.bufferSize = size
|
||||
return session
|
||||
}
|
||||
|
||||
func (session *Session) bufferIterate(bean interface{}, fun IterFunc) error {
|
||||
if session.isAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
var bufferSize = session.statement.bufferSize
|
||||
var limit = session.statement.LimitN
|
||||
if limit > 0 && bufferSize > limit {
|
||||
bufferSize = limit
|
||||
}
|
||||
var start = session.statement.Start
|
||||
v := rValue(bean)
|
||||
sliceType := reflect.SliceOf(v.Type())
|
||||
var idx = 0
|
||||
for {
|
||||
slice := reflect.New(sliceType)
|
||||
if err := session.Limit(bufferSize, start).find(slice.Interface(), bean); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := 0; i < slice.Elem().Len(); i++ {
|
||||
if err := fun(idx, slice.Elem().Index(i).Addr().Interface()); err != nil {
|
||||
return err
|
||||
}
|
||||
idx++
|
||||
}
|
||||
|
||||
start = start + slice.Elem().Len()
|
||||
if limit > 0 && idx+bufferSize > limit {
|
||||
bufferSize = limit - idx
|
||||
}
|
||||
|
||||
if bufferSize <= 0 || slice.Elem().Len() < bufferSize || idx == limit {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
2
vendor/github.com/go-xorm/xorm/session_update.go
generated
vendored
2
vendor/github.com/go-xorm/xorm/session_update.go
generated
vendored
|
@ -205,7 +205,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
|||
if _, ok := session.statement.columnMap[strings.ToLower(table.Updated)]; !ok {
|
||||
colNames = append(colNames, session.engine.Quote(table.Updated)+" = ?")
|
||||
col := table.UpdatedColumn()
|
||||
val, t := session.engine.NowTime2(col.SQLType.Name)
|
||||
val, t := session.engine.nowTime(col)
|
||||
args = append(args, val)
|
||||
|
||||
var colName = col.Name
|
||||
|
|
2
vendor/github.com/go-xorm/xorm/statement.go
generated
vendored
2
vendor/github.com/go-xorm/xorm/statement.go
generated
vendored
|
@ -73,6 +73,7 @@ type Statement struct {
|
|||
decrColumns map[string]decrParam
|
||||
exprColumns map[string]exprParam
|
||||
cond builder.Cond
|
||||
bufferSize int
|
||||
}
|
||||
|
||||
// Init reset all the statement's fields
|
||||
|
@ -111,6 +112,7 @@ func (statement *Statement) Init() {
|
|||
statement.decrColumns = make(map[string]decrParam)
|
||||
statement.exprColumns = make(map[string]exprParam)
|
||||
statement.cond = builder.NewCond()
|
||||
statement.bufferSize = 0
|
||||
}
|
||||
|
||||
// NoAutoCondition if you do not want convert bean's field as query condition, then use this function
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue