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
|
DatabaseTZ *time.Location // The timezone of the database
|
||||||
|
|
||||||
logSessionID bool // create session id
|
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
|
// 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)
|
tagParser := tags.NewParser("xorm", dialect, mapper, mapper, cacherMgr)
|
||||||
|
|
||||||
engine := &Engine{
|
engine := &Engine{
|
||||||
dialect: dialect,
|
dialect: dialect,
|
||||||
driver: dialects.QueryDriver(driverName),
|
driver: dialects.QueryDriver(driverName),
|
||||||
TZLocation: time.Local,
|
TZLocation: time.Local,
|
||||||
defaultContext: context.Background(),
|
defaultContext: context.Background(),
|
||||||
cacherMgr: cacherMgr,
|
cacherMgr: cacherMgr,
|
||||||
tagParser: tagParser,
|
tagParser: tagParser,
|
||||||
driverName: driverName,
|
driverName: driverName,
|
||||||
dataSourceName: dataSourceName,
|
dataSourceName: dataSourceName,
|
||||||
db: db,
|
db: db,
|
||||||
logSessionID: false,
|
logSessionID: false,
|
||||||
|
autoIncrementIncrement: 1,
|
||||||
|
lastInsertIDReversed: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
if dialect.URI().DBType == schemas.SQLITE {
|
if dialect.URI().DBType == schemas.SQLITE {
|
||||||
|
@ -144,6 +149,16 @@ func (engine *Engine) SetQuotePolicy(quotePolicy dialects.QuotePolicy) {
|
||||||
engine.dialect.SetQuotePolicy(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
|
// BufferSize sets buffer size for iterate
|
||||||
func (engine *Engine) BufferSize(size int) *Session {
|
func (engine *Engine) BufferSize(size int) *Session {
|
||||||
session := engine.NewSession()
|
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
|
// SetTableMapper set the table name mapping rule
|
||||||
func (eg *EngineGroup) SetTableMapper(mapper names.Mapper) {
|
func (eg *EngineGroup) SetTableMapper(mapper names.Mapper) {
|
||||||
eg.Engine.SetTableMapper(mapper)
|
eg.Engine.SetTableMapper(mapper)
|
||||||
|
|
|
@ -117,6 +117,8 @@ type EngineInterface interface {
|
||||||
SetTableMapper(names.Mapper)
|
SetTableMapper(names.Mapper)
|
||||||
SetTZDatabase(tz *time.Location)
|
SetTZDatabase(tz *time.Location)
|
||||||
SetTZLocation(tz *time.Location)
|
SetTZLocation(tz *time.Location)
|
||||||
|
SetAutoIncrementIncrement(increment int64)
|
||||||
|
SetLastInsertIDReversed(reversed bool)
|
||||||
AddHook(hook contexts.Hook)
|
AddHook(hook contexts.Hook)
|
||||||
ShowSQL(show ...bool)
|
ShowSQL(show ...bool)
|
||||||
Sync(...interface{}) error
|
Sync(...interface{}) error
|
||||||
|
|
|
@ -210,33 +210,104 @@ func (session *Session) insertMultipleStruct(rowsSlicePtr interface{}) (int64, e
|
||||||
|
|
||||||
_ = session.cacheInsert(tableName)
|
_ = session.cacheInsert(tableName)
|
||||||
|
|
||||||
lenAfterClosures := len(session.afterClosures)
|
var id int64
|
||||||
for i := 0; i < size; i++ {
|
if table.AutoIncrement != "" {
|
||||||
elemValue := reflect.Indirect(sliceValue.Index(i)).Addr().Interface()
|
id, err = res.LastInsertId()
|
||||||
|
if err != nil || id <= 0 {
|
||||||
|
return res.RowsAffected()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// handle AfterInsertProcessor
|
lenAfterClosures := len(session.afterClosures)
|
||||||
if session.isAutoCommit {
|
if session.engine.lastInsertIDReversed {
|
||||||
// !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi??
|
for i := size - 1; i >= 0; i-- {
|
||||||
for _, closure := range session.afterClosures {
|
elemValue := reflect.Indirect(sliceValue.Index(i)).Addr().Interface()
|
||||||
closure(elemValue)
|
|
||||||
}
|
// handle AfterInsertProcessor
|
||||||
if processor, ok := elemValue.(AfterInsertProcessor); ok {
|
if session.isAutoCommit {
|
||||||
processor.AfterInsert()
|
// !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi??
|
||||||
}
|
for _, closure := range session.afterClosures {
|
||||||
} else {
|
closure(elemValue)
|
||||||
if lenAfterClosures > 0 {
|
}
|
||||||
if value, has := session.afterInsertBeans[elemValue]; has && value != nil {
|
if processor, ok := elemValue.(AfterInsertProcessor); ok {
|
||||||
*value = append(*value, session.afterClosures...)
|
processor.AfterInsert()
|
||||||
} else {
|
|
||||||
afterClosures := make([]func(interface{}), lenAfterClosures)
|
|
||||||
copy(afterClosures, session.afterClosures)
|
|
||||||
session.afterInsertBeans[elemValue] = &afterClosures
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if _, ok := elemValue.(AfterInsertProcessor); ok {
|
if lenAfterClosures > 0 {
|
||||||
session.afterInsertBeans[elemValue] = nil
|
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