Spanner: support for lastInsertId (#101770)
* Support for returning inserted ID in Spanner. * Convert bytes to string when storing them into text column.
This commit is contained in:
@@ -438,9 +438,11 @@ func (session *Session) innerInsert(bean any) (int64, error) {
|
||||
}
|
||||
|
||||
if len(table.AutoIncrement) > 0 && session.engine.dialect.DBType() == core.POSTGRES {
|
||||
if _, err := buf.WriteString(" RETURNING " + session.engine.Quote(table.AutoIncrement)); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
buf.WriteString(" RETURNING " + session.engine.Quote(table.AutoIncrement))
|
||||
}
|
||||
|
||||
if len(table.AutoIncrement) > 0 && session.engine.dialect.DBType() == "spanner" {
|
||||
buf.WriteString(" THEN RETURN " + session.engine.Quote(table.AutoIncrement))
|
||||
}
|
||||
|
||||
sqlStr := buf.String()
|
||||
@@ -476,6 +478,7 @@ func (session *Session) innerInsert(bean any) (int64, error) {
|
||||
|
||||
// for postgres, many of them didn't implement lastInsertId, so we should
|
||||
// implemented it ourself.
|
||||
var insertID, rowsAffected int64
|
||||
if session.engine.dialect.DBType() == core.ORACLE && len(table.AutoIncrement) > 0 {
|
||||
res, err := session.queryBytes("select seq_atable.currval from dual", args...)
|
||||
if err != nil {
|
||||
@@ -498,23 +501,11 @@ func (session *Session) innerInsert(bean any) (int64, error) {
|
||||
}
|
||||
|
||||
idByte := res[0][table.AutoIncrement]
|
||||
id, err := strconv.ParseInt(string(idByte), 10, 64)
|
||||
if err != nil || id <= 0 {
|
||||
insertID, err = strconv.ParseInt(string(idByte), 10, 64)
|
||||
if err != nil || insertID <= 0 {
|
||||
return 1, err
|
||||
}
|
||||
|
||||
aiValue, err := table.AutoIncrColumn().ValueOf(bean)
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
}
|
||||
|
||||
if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() {
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
aiValue.Set(int64ToIntValue(id, aiValue.Type()))
|
||||
|
||||
return 1, nil
|
||||
rowsAffected = 1
|
||||
} else if len(table.AutoIncrement) > 0 && (session.engine.dialect.DBType() == core.POSTGRES) {
|
||||
res, err := session.queryBytes(sqlStr, args...)
|
||||
|
||||
@@ -537,23 +528,11 @@ func (session *Session) innerInsert(bean any) (int64, error) {
|
||||
}
|
||||
|
||||
idByte := res[0][table.AutoIncrement]
|
||||
id, err := strconv.ParseInt(string(idByte), 10, 64)
|
||||
if err != nil || id <= 0 {
|
||||
insertID, err = strconv.ParseInt(string(idByte), 10, 64)
|
||||
if err != nil || insertID <= 0 {
|
||||
return 1, err
|
||||
}
|
||||
|
||||
aiValue, err := table.AutoIncrColumn().ValueOf(bean)
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
}
|
||||
|
||||
if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() {
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
aiValue.Set(int64ToIntValue(id, aiValue.Type()))
|
||||
|
||||
return 1, nil
|
||||
rowsAffected = 1
|
||||
} else {
|
||||
res, err := session.exec(sqlStr, args...)
|
||||
if err != nil {
|
||||
@@ -575,25 +554,29 @@ func (session *Session) innerInsert(bean any) (int64, error) {
|
||||
return res.RowsAffected()
|
||||
}
|
||||
|
||||
var id int64
|
||||
id, err = res.LastInsertId()
|
||||
if err != nil || id <= 0 {
|
||||
insertID, err = res.LastInsertId()
|
||||
if err != nil || insertID <= 0 {
|
||||
return res.RowsAffected()
|
||||
}
|
||||
|
||||
aiValue, err := table.AutoIncrColumn().ValueOf(bean)
|
||||
rowsAffected, err = res.RowsAffected()
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() {
|
||||
return res.RowsAffected()
|
||||
}
|
||||
|
||||
aiValue.Set(int64ToIntValue(id, aiValue.Type()))
|
||||
|
||||
return res.RowsAffected()
|
||||
}
|
||||
|
||||
// Set insertID back to the bean.
|
||||
aiValue, err := table.AutoIncrColumn().ValueOf(bean)
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
}
|
||||
|
||||
if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() {
|
||||
return rowsAffected, nil
|
||||
}
|
||||
|
||||
aiValue.Set(int64ToIntValue(insertID, aiValue.Type()))
|
||||
return rowsAffected, nil
|
||||
}
|
||||
|
||||
// InsertOne insert only one struct into database as a record.
|
||||
|
||||
Reference in New Issue
Block a user