gorm/callback_create.go

135 lines
4.6 KiB
Go
Raw Normal View History

2014-01-26 08:41:37 +04:00
package gorm
2014-01-26 15:34:06 +04:00
import (
"fmt"
"strings"
)
2016-01-17 11:28:32 +03:00
// Define callbacks for creating
func init() {
defaultCallback.Create().Register("gorm:begin_transaction", beginTransactionCallback)
defaultCallback.Create().Register("gorm:before_create", beforeCreateCallback)
defaultCallback.Create().Register("gorm:save_before_associations", saveBeforeAssociationsCallback)
2016-01-17 13:38:18 +03:00
defaultCallback.Create().Register("gorm:update_time_stamp", updateTimeStampForCreateCallback)
2016-01-17 11:28:32 +03:00
defaultCallback.Create().Register("gorm:create", createCallback)
defaultCallback.Create().Register("gorm:force_reload_after_create", forceReloadAfterCreateCallback)
defaultCallback.Create().Register("gorm:save_after_associations", saveAfterAssociationsCallback)
defaultCallback.Create().Register("gorm:after_create", afterCreateCallback)
defaultCallback.Create().Register("gorm:commit_or_rollback_transaction", commitOrRollbackTransactionCallback)
}
// beforeCreateCallback will invoke `BeforeSave`, `BeforeCreate` method before creating
2016-01-17 10:30:42 +03:00
func beforeCreateCallback(scope *Scope) {
if !scope.HasError() {
scope.CallMethod("BeforeSave")
}
if !scope.HasError() {
scope.CallMethod("BeforeCreate")
}
2014-01-26 08:41:37 +04:00
}
2016-01-17 11:28:32 +03:00
// updateTimeStampForCreateCallback will set `CreatedAt`, `UpdatedAt` when creating
2016-01-17 10:30:42 +03:00
func updateTimeStampForCreateCallback(scope *Scope) {
2014-01-26 08:41:37 +04:00
if !scope.HasError() {
now := NowFunc()
scope.SetColumn("CreatedAt", now)
scope.SetColumn("UpdatedAt", now)
2014-01-27 07:06:13 +04:00
}
}
2014-01-26 17:23:53 +04:00
2016-01-17 11:28:32 +03:00
// createCallback the callback used to insert data into database
2016-01-17 10:30:42 +03:00
func createCallback(scope *Scope) {
2014-01-27 07:06:13 +04:00
if !scope.HasError() {
2016-01-17 11:37:17 +03:00
defer scope.trace(NowFunc())
2016-01-17 12:46:56 +03:00
var (
columns, placeholders []string
blankColumnsWithDefaultValue []string
fields = scope.Fields()
)
2015-03-12 12:47:31 +03:00
for _, field := range fields {
2015-03-12 13:30:59 +03:00
if scope.changeableField(field) {
2015-03-12 12:47:31 +03:00
if field.IsNormal {
2016-01-17 12:46:56 +03:00
if !field.IsPrimaryKey || !field.IsBlank {
if field.IsBlank && field.HasDefaultValue {
blankColumnsWithDefaultValue = append(blankColumnsWithDefaultValue, field.DBName)
scope.InstanceSet("gorm:blank_columns_with_default_value", blankColumnsWithDefaultValue)
} else {
2015-03-12 12:47:31 +03:00
columns = append(columns, scope.Quote(field.DBName))
2016-01-17 12:46:56 +03:00
placeholders = append(placeholders, scope.AddToVars(field.Field.Interface()))
2015-03-12 12:47:31 +03:00
}
}
2016-01-17 12:46:56 +03:00
} else if field.Relationship != nil && field.Relationship.Kind == "belongs_to" {
for _, foreignKey := range field.Relationship.ForeignDBNames {
if foreignField := fields[foreignKey]; !scope.changeableField(foreignField) {
columns = append(columns, scope.Quote(foreignField.DBName))
placeholders = append(placeholders, scope.AddToVars(foreignField.Field.Interface()))
2015-07-30 09:26:48 +03:00
}
2015-03-12 12:47:31 +03:00
}
}
2014-01-26 15:34:06 +04:00
}
}
2016-01-19 06:53:53 +03:00
var (
returningColumn = "*"
quotedTableName = scope.QuotedTableName()
primaryField = scope.PrimaryField()
)
2015-02-17 15:19:47 +03:00
if primaryField != nil {
2016-01-19 06:53:53 +03:00
returningColumn = scope.Quote(primaryField.DBName)
}
2016-01-19 06:53:53 +03:00
lastInsertIdReturningSuffix := scope.Dialect().LastInsertIdReturningSuffix(quotedTableName, returningColumn)
2014-04-29 13:42:10 +04:00
if len(columns) == 0 {
2016-01-19 06:53:53 +03:00
scope.Raw(fmt.Sprintf("INSERT INTO %v DEFAULT VALUES %v", quotedTableName, lastInsertIdReturningSuffix))
2014-04-29 13:42:10 +04:00
} else {
scope.Raw(fmt.Sprintf(
"INSERT INTO %v (%v) VALUES (%v) %v",
2014-06-03 13:15:05 +04:00
scope.QuotedTableName(),
2014-04-29 13:42:10 +04:00
strings.Join(columns, ","),
2016-01-17 12:46:56 +03:00
strings.Join(placeholders, ","),
2016-01-19 06:53:53 +03:00
lastInsertIdReturningSuffix,
2014-04-29 13:42:10 +04:00
))
}
2014-01-26 15:34:06 +04:00
// execute create sql
2016-01-19 06:53:53 +03:00
if lastInsertIdReturningSuffix == "" || primaryField == nil {
2015-02-26 07:35:33 +03:00
if result, err := scope.SqlDB().Exec(scope.Sql, scope.SqlVars...); scope.Err(err) == nil {
2016-01-17 12:46:56 +03:00
// set rows affected count
scope.db.RowsAffected, _ = result.RowsAffected()
// set primary value to primary field
if primaryField != nil && primaryField.IsBlank {
if primaryValue, err := result.LastInsertId(); scope.Err(err) == nil {
scope.Err(primaryField.Set(primaryValue))
2015-02-20 17:06:49 +03:00
}
2014-06-05 13:58:14 +04:00
}
2014-01-26 08:41:37 +04:00
}
} else {
2016-01-17 12:46:56 +03:00
if err := scope.SqlDB().QueryRow(scope.Sql, scope.SqlVars...).Scan(primaryField.Field.Addr().Interface()); scope.Err(err) == nil {
scope.db.RowsAffected = 1
2014-06-09 04:17:20 +04:00
}
2014-01-26 08:41:37 +04:00
}
}
}
2016-01-17 11:28:32 +03:00
// forceReloadAfterCreateCallback will reload columns that having default value, and set it back to current object
2016-01-17 10:30:42 +03:00
func forceReloadAfterCreateCallback(scope *Scope) {
2016-01-17 12:46:56 +03:00
if blankColumnsWithDefaultValue, ok := scope.InstanceGet("gorm:blank_columns_with_default_value"); ok {
scope.DB().New().Select(blankColumnsWithDefaultValue.([]string)).First(scope.Value)
}
}
2016-01-17 13:38:18 +03:00
// afterCreateCallback will invoke `AfterCreate`, `AfterSave` method after creating
2016-01-17 10:30:42 +03:00
func afterCreateCallback(scope *Scope) {
if !scope.HasError() {
scope.CallMethod("AfterCreate")
}
if !scope.HasError() {
scope.CallMethod("AfterSave")
}
2014-01-26 08:41:37 +04:00
}