fix: fix inseart id auto increment(#2167)
This commit is contained in:
parent
18f8e7a86c
commit
4a9fb23c4e
35
engine.go
35
engine.go
|
@ -47,6 +47,9 @@ type Engine struct {
|
|||
DatabaseTZ *time.Location // The timezone of the database
|
||||
|
||||
logSessionID bool // create session id
|
||||
|
||||
autoIncrementIncrement int64 // auto increment increment default 1
|
||||
lastInsertIDReversed bool // create id reversed
|
||||
}
|
||||
|
||||
// NewEngine new a db manager according to the parameter. Currently support four
|
||||
|
@ -71,16 +74,18 @@ func newEngine(driverName, dataSourceName string, dialect dialects.Dialect, db *
|
|||
tagParser := tags.NewParser("xorm", dialect, mapper, mapper, cacherMgr)
|
||||
|
||||
engine := &Engine{
|
||||
dialect: dialect,
|
||||
driver: dialects.QueryDriver(driverName),
|
||||
TZLocation: time.Local,
|
||||
defaultContext: context.Background(),
|
||||
cacherMgr: cacherMgr,
|
||||
tagParser: tagParser,
|
||||
driverName: driverName,
|
||||
dataSourceName: dataSourceName,
|
||||
db: db,
|
||||
logSessionID: false,
|
||||
dialect: dialect,
|
||||
driver: dialects.QueryDriver(driverName),
|
||||
TZLocation: time.Local,
|
||||
defaultContext: context.Background(),
|
||||
cacherMgr: cacherMgr,
|
||||
tagParser: tagParser,
|
||||
driverName: driverName,
|
||||
dataSourceName: dataSourceName,
|
||||
db: db,
|
||||
logSessionID: false,
|
||||
autoIncrementIncrement: 1,
|
||||
lastInsertIDReversed: false,
|
||||
}
|
||||
|
||||
if dialect.URI().DBType == schemas.SQLITE {
|
||||
|
@ -144,6 +149,16 @@ func (engine *Engine) SetQuotePolicy(quotePolicy dialects.QuotePolicy) {
|
|||
engine.dialect.SetQuotePolicy(quotePolicy)
|
||||
}
|
||||
|
||||
// SetAutoIncrementIncrement set insert id auto increment increment
|
||||
func (engine *Engine) SetAutoIncrementIncrement(increment int64) {
|
||||
engine.autoIncrementIncrement = increment
|
||||
}
|
||||
|
||||
// SetLastInsertIDReversed set insert id reversed
|
||||
func (engine *Engine) SetLastInsertIDReversed(reversed bool) {
|
||||
engine.lastInsertIDReversed = reversed
|
||||
}
|
||||
|
||||
// BufferSize sets buffer size for iterate
|
||||
func (engine *Engine) BufferSize(size int) *Session {
|
||||
session := engine.NewSession()
|
||||
|
|
|
@ -206,6 +206,16 @@ func (eg *EngineGroup) SetQuotePolicy(quotePolicy dialects.QuotePolicy) {
|
|||
}
|
||||
}
|
||||
|
||||
// SetAutoIncrementIncrement set insert id auto increment increment
|
||||
func (eg *EngineGroup) SetAutoIncrementIncrement(increment int64) {
|
||||
eg.autoIncrementIncrement = increment
|
||||
}
|
||||
|
||||
// SetLastInsertIDReversed set insert id reversed
|
||||
func (eg *EngineGroup) SetLastInsertIDReversed(reversed bool) {
|
||||
eg.lastInsertIDReversed = reversed
|
||||
}
|
||||
|
||||
// SetTableMapper set the table name mapping rule
|
||||
func (eg *EngineGroup) SetTableMapper(mapper names.Mapper) {
|
||||
eg.Engine.SetTableMapper(mapper)
|
||||
|
|
|
@ -117,6 +117,8 @@ type EngineInterface interface {
|
|||
SetTableMapper(names.Mapper)
|
||||
SetTZDatabase(tz *time.Location)
|
||||
SetTZLocation(tz *time.Location)
|
||||
SetAutoIncrementIncrement(increment int64)
|
||||
SetLastInsertIDReversed(reversed bool)
|
||||
AddHook(hook contexts.Hook)
|
||||
ShowSQL(show ...bool)
|
||||
Sync(...interface{}) error
|
||||
|
|
|
@ -210,33 +210,104 @@ func (session *Session) insertMultipleStruct(rowsSlicePtr interface{}) (int64, e
|
|||
|
||||
_ = session.cacheInsert(tableName)
|
||||
|
||||
lenAfterClosures := len(session.afterClosures)
|
||||
for i := 0; i < size; i++ {
|
||||
elemValue := reflect.Indirect(sliceValue.Index(i)).Addr().Interface()
|
||||
var id int64
|
||||
if table.AutoIncrement != "" {
|
||||
id, err = res.LastInsertId()
|
||||
if err != nil || id <= 0 {
|
||||
return res.RowsAffected()
|
||||
}
|
||||
}
|
||||
|
||||
// handle AfterInsertProcessor
|
||||
if session.isAutoCommit {
|
||||
// !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi??
|
||||
for _, closure := range session.afterClosures {
|
||||
closure(elemValue)
|
||||
}
|
||||
if processor, ok := elemValue.(AfterInsertProcessor); ok {
|
||||
processor.AfterInsert()
|
||||
}
|
||||
} else {
|
||||
if lenAfterClosures > 0 {
|
||||
if value, has := session.afterInsertBeans[elemValue]; has && value != nil {
|
||||
*value = append(*value, session.afterClosures...)
|
||||
} else {
|
||||
afterClosures := make([]func(interface{}), lenAfterClosures)
|
||||
copy(afterClosures, session.afterClosures)
|
||||
session.afterInsertBeans[elemValue] = &afterClosures
|
||||
lenAfterClosures := len(session.afterClosures)
|
||||
if session.engine.lastInsertIDReversed {
|
||||
for i := size - 1; i >= 0; i-- {
|
||||
elemValue := reflect.Indirect(sliceValue.Index(i)).Addr().Interface()
|
||||
|
||||
// handle AfterInsertProcessor
|
||||
if session.isAutoCommit {
|
||||
// !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi??
|
||||
for _, closure := range session.afterClosures {
|
||||
closure(elemValue)
|
||||
}
|
||||
if processor, ok := elemValue.(AfterInsertProcessor); ok {
|
||||
processor.AfterInsert()
|
||||
}
|
||||
} else {
|
||||
if _, ok := elemValue.(AfterInsertProcessor); ok {
|
||||
session.afterInsertBeans[elemValue] = nil
|
||||
if lenAfterClosures > 0 {
|
||||
if value, has := session.afterInsertBeans[elemValue]; has && value != nil {
|
||||
*value = append(*value, session.afterClosures...)
|
||||
} else {
|
||||
afterClosures := make([]func(interface{}), lenAfterClosures)
|
||||
copy(afterClosures, session.afterClosures)
|
||||
session.afterInsertBeans[elemValue] = &afterClosures
|
||||
}
|
||||
} else {
|
||||
if _, ok := elemValue.(AfterInsertProcessor); ok {
|
||||
session.afterInsertBeans[elemValue] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle auto increment
|
||||
aiValue, err := table.AutoIncrColumn().ValueOf(elemValue)
|
||||
if err != nil {
|
||||
session.engine.logger.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := convert.AssignValue(*aiValue, id); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
id -= session.engine.autoIncrementIncrement
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < size; i++ {
|
||||
elemValue := reflect.Indirect(sliceValue.Index(i)).Addr().Interface()
|
||||
|
||||
// handle AfterInsertProcessor
|
||||
if session.isAutoCommit {
|
||||
// !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi??
|
||||
for _, closure := range session.afterClosures {
|
||||
closure(elemValue)
|
||||
}
|
||||
if processor, ok := elemValue.(AfterInsertProcessor); ok {
|
||||
processor.AfterInsert()
|
||||
}
|
||||
} else {
|
||||
if lenAfterClosures > 0 {
|
||||
if value, has := session.afterInsertBeans[elemValue]; has && value != nil {
|
||||
*value = append(*value, session.afterClosures...)
|
||||
} else {
|
||||
afterClosures := make([]func(interface{}), lenAfterClosures)
|
||||
copy(afterClosures, session.afterClosures)
|
||||
session.afterInsertBeans[elemValue] = &afterClosures
|
||||
}
|
||||
} else {
|
||||
if _, ok := elemValue.(AfterInsertProcessor); ok {
|
||||
session.afterInsertBeans[elemValue] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle auto increment
|
||||
aiValue, err := table.AutoIncrColumn().ValueOf(elemValue)
|
||||
if err != nil {
|
||||
session.engine.logger.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := convert.AssignValue(*aiValue, id); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
id += session.engine.autoIncrementIncrement
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue