callback_shared.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package gorm
  2. import (
  3. "fmt"
  4. "reflect"
  5. "strings"
  6. )
  7. func BeginTransaction(scope *Scope) {
  8. scope.Begin()
  9. }
  10. func CommitOrRollbackTransaction(scope *Scope) {
  11. scope.CommitOrRollback()
  12. }
  13. func SaveBeforeAssociations(scope *Scope) {
  14. for _, field := range scope.Fields() {
  15. if !field.IsBlank && !field.IsIgnored {
  16. relationship := field.Relationship
  17. if relationship != nil && relationship.Kind == "belongs_to" {
  18. value := field.Field
  19. newDB := scope.NewDB()
  20. if !value.CanAddr() {
  21. // If can't take address, then clone the value and set it back
  22. value = reflect.New(value.Type()).Elem()
  23. for _, f := range newDB.NewScope(field.Field.Addr().Interface()).Fields() {
  24. value.FieldByName(f.Name).Set(reflect.ValueOf(f.Field.Interface()))
  25. }
  26. scope.SetColumn(field.Name, value.Interface())
  27. }
  28. scope.Err(newDB.Save(value.Addr().Interface()).Error)
  29. if relationship.ForeignKey != "" {
  30. scope.SetColumn(relationship.ForeignKey, newDB.NewScope(value.Addr().Interface()).PrimaryKeyValue())
  31. }
  32. if relationship.ForeignType != "" {
  33. scope.Err(fmt.Errorf("gorm does not support polymorphic belongs_to associations"))
  34. return
  35. }
  36. }
  37. }
  38. }
  39. }
  40. func SaveAfterAssociations(scope *Scope) {
  41. for _, field := range scope.Fields() {
  42. if !field.IsBlank && !field.IsIgnored {
  43. relationship := field.Relationship
  44. if relationship != nil &&
  45. (relationship.Kind == "has_one" || relationship.Kind == "has_many" || relationship.Kind == "many_to_many") {
  46. value := field.Field
  47. switch value.Kind() {
  48. case reflect.Slice:
  49. for i := 0; i < value.Len(); i++ {
  50. newDB := scope.NewDB()
  51. elem := value.Index(i).Addr().Interface()
  52. if relationship.JoinTable == "" && relationship.ForeignKey != "" {
  53. newDB.NewScope(elem).SetColumn(relationship.ForeignKey, scope.PrimaryKeyValue())
  54. }
  55. if relationship.ForeignType != "" {
  56. newDB.NewScope(elem).SetColumn(relationship.ForeignType, scope.TableName())
  57. }
  58. scope.Err(newDB.Save(elem).Error)
  59. if relationship.JoinTable != "" {
  60. if relationship.ForeignType != "" {
  61. scope.Err(fmt.Errorf("gorm does not support polymorphic many-to-many associations"))
  62. }
  63. newScope := scope.New(elem)
  64. joinTable := relationship.JoinTable
  65. foreignKey := ToSnake(relationship.ForeignKey)
  66. foreignValue := fmt.Sprintf("%v", scope.PrimaryKeyValue())
  67. associationForeignKey := ToSnake(relationship.AssociationForeignKey)
  68. associationForeignValue := fmt.Sprintf("%v", newScope.PrimaryKeyValue())
  69. newScope.Raw(fmt.Sprintf(
  70. "INSERT INTO %v (%v) SELECT %v %v WHERE NOT EXISTS (SELECT * FROM %v WHERE %v = %v AND %v = %v);",
  71. joinTable,
  72. strings.Join([]string{scope.Quote(foreignKey), scope.Quote(associationForeignKey)}, ","),
  73. strings.Join([]string{newScope.AddToVars(foreignValue), newScope.AddToVars(associationForeignValue)}, ","),
  74. scope.Dialect().SelectFromDummyTable(),
  75. joinTable,
  76. scope.Quote(foreignKey),
  77. newScope.AddToVars(foreignValue),
  78. scope.Quote(associationForeignKey),
  79. newScope.AddToVars(associationForeignValue),
  80. ))
  81. scope.Err(scope.NewDB().Exec(newScope.Sql, newScope.SqlVars...).Error)
  82. }
  83. }
  84. default:
  85. newDB := scope.NewDB()
  86. if value.CanAddr() {
  87. if relationship.ForeignKey != "" {
  88. newDB.NewScope(value.Addr().Interface()).SetColumn(relationship.ForeignKey, scope.PrimaryKeyValue())
  89. }
  90. if relationship.ForeignType != "" {
  91. newDB.NewScope(value.Addr().Interface()).SetColumn(relationship.ForeignType, scope.TableName())
  92. }
  93. scope.Err(newDB.Save(value.Addr().Interface()).Error)
  94. } else {
  95. destValue := reflect.New(field.Field.Type()).Elem()
  96. for _, f := range newDB.NewScope(field.Field.Addr().Interface()).Fields() {
  97. destValue.FieldByName(f.Name).Set(f.Field)
  98. }
  99. elem := destValue.Addr().Interface()
  100. if relationship.ForeignKey != "" {
  101. newDB.NewScope(elem).SetColumn(relationship.ForeignKey, scope.PrimaryKeyValue())
  102. }
  103. if relationship.ForeignType != "" {
  104. newDB.NewScope(value.Addr().Interface()).SetColumn(relationship.ForeignType, scope.TableName())
  105. }
  106. scope.Err(newDB.Save(elem).Error)
  107. scope.SetColumn(field.Name, destValue.Interface())
  108. }
  109. }
  110. }
  111. }
  112. }
  113. }