123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package gorm
- import (
- "fmt"
- "reflect"
- "strings"
- )
- func BeginTransaction(scope *Scope) {
- scope.Begin()
- }
- func CommitOrRollbackTransaction(scope *Scope) {
- scope.CommitOrRollback()
- }
- func SaveBeforeAssociations(scope *Scope) {
- for _, field := range scope.Fields() {
- if !field.IsBlank && !field.IsIgnored {
- relationship := field.Relationship
- if relationship != nil && relationship.Kind == "belongs_to" {
- value := field.Field
- newDB := scope.NewDB()
- if !value.CanAddr() {
- // If can't take address, then clone the value and set it back
- value = reflect.New(value.Type()).Elem()
- for _, f := range newDB.NewScope(field.Field.Addr().Interface()).Fields() {
- value.FieldByName(f.Name).Set(reflect.ValueOf(f.Field.Interface()))
- }
- scope.SetColumn(field.Name, value.Interface())
- }
- scope.Err(newDB.Save(value.Addr().Interface()).Error)
- if relationship.ForeignKey != "" {
- scope.SetColumn(relationship.ForeignKey, newDB.NewScope(value.Addr().Interface()).PrimaryKeyValue())
- }
- if relationship.ForeignType != "" {
- scope.Err(fmt.Errorf("gorm does not support polymorphic belongs_to associations"))
- return
- }
- }
- }
- }
- }
- func SaveAfterAssociations(scope *Scope) {
- for _, field := range scope.Fields() {
- if !field.IsBlank && !field.IsIgnored {
- relationship := field.Relationship
- if relationship != nil &&
- (relationship.Kind == "has_one" || relationship.Kind == "has_many" || relationship.Kind == "many_to_many") {
- value := field.Field
- switch value.Kind() {
- case reflect.Slice:
- for i := 0; i < value.Len(); i++ {
- newDB := scope.NewDB()
- elem := value.Index(i).Addr().Interface()
- if relationship.JoinTable == "" && relationship.ForeignKey != "" {
- newDB.NewScope(elem).SetColumn(relationship.ForeignKey, scope.PrimaryKeyValue())
- }
- if relationship.ForeignType != "" {
- newDB.NewScope(elem).SetColumn(relationship.ForeignType, scope.TableName())
- }
- scope.Err(newDB.Save(elem).Error)
- if relationship.JoinTable != "" {
- if relationship.ForeignType != "" {
- scope.Err(fmt.Errorf("gorm does not support polymorphic many-to-many associations"))
- }
- newScope := scope.New(elem)
- joinTable := relationship.JoinTable
- foreignKey := ToSnake(relationship.ForeignKey)
- foreignValue := fmt.Sprintf("%v", scope.PrimaryKeyValue())
- associationForeignKey := ToSnake(relationship.AssociationForeignKey)
- associationForeignValue := fmt.Sprintf("%v", newScope.PrimaryKeyValue())
- newScope.Raw(fmt.Sprintf(
- "INSERT INTO %v (%v) SELECT %v %v WHERE NOT EXISTS (SELECT * FROM %v WHERE %v = %v AND %v = %v);",
- joinTable,
- strings.Join([]string{scope.Quote(foreignKey), scope.Quote(associationForeignKey)}, ","),
- strings.Join([]string{newScope.AddToVars(foreignValue), newScope.AddToVars(associationForeignValue)}, ","),
- scope.Dialect().SelectFromDummyTable(),
- joinTable,
- scope.Quote(foreignKey),
- newScope.AddToVars(foreignValue),
- scope.Quote(associationForeignKey),
- newScope.AddToVars(associationForeignValue),
- ))
- scope.Err(scope.NewDB().Exec(newScope.Sql, newScope.SqlVars...).Error)
- }
- }
- default:
- newDB := scope.NewDB()
- if value.CanAddr() {
- if relationship.ForeignKey != "" {
- newDB.NewScope(value.Addr().Interface()).SetColumn(relationship.ForeignKey, scope.PrimaryKeyValue())
- }
- if relationship.ForeignType != "" {
- newDB.NewScope(value.Addr().Interface()).SetColumn(relationship.ForeignType, scope.TableName())
- }
- scope.Err(newDB.Save(value.Addr().Interface()).Error)
- } else {
- destValue := reflect.New(field.Field.Type()).Elem()
- for _, f := range newDB.NewScope(field.Field.Addr().Interface()).Fields() {
- destValue.FieldByName(f.Name).Set(f.Field)
- }
- elem := destValue.Addr().Interface()
- if relationship.ForeignKey != "" {
- newDB.NewScope(elem).SetColumn(relationship.ForeignKey, scope.PrimaryKeyValue())
- }
- if relationship.ForeignType != "" {
- newDB.NewScope(value.Addr().Interface()).SetColumn(relationship.ForeignType, scope.TableName())
- }
- scope.Err(newDB.Save(elem).Error)
- scope.SetColumn(field.Name, destValue.Interface())
- }
- }
- }
- }
- }
- }
|