callback_save.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package gorm
  2. import (
  3. "reflect"
  4. "strings"
  5. )
  6. func beginTransactionCallback(scope *Scope) {
  7. scope.Begin()
  8. }
  9. func commitOrRollbackTransactionCallback(scope *Scope) {
  10. scope.CommitOrRollback()
  11. }
  12. func saveAssociationCheck(scope *Scope, field *Field) (autoUpdate bool, autoCreate bool, saveReference bool, r *Relationship) {
  13. checkTruth := func(value interface{}) bool {
  14. if v, ok := value.(bool); ok && !v {
  15. return false
  16. }
  17. if v, ok := value.(string); ok {
  18. v = strings.ToLower(v)
  19. return v == "true"
  20. }
  21. return true
  22. }
  23. if scope.changeableField(field) && !field.IsBlank && !field.IsIgnored {
  24. if r = field.Relationship; r != nil {
  25. autoUpdate, autoCreate, saveReference = true, true, true
  26. if value, ok := scope.Get("gorm:save_associations"); ok {
  27. autoUpdate = checkTruth(value)
  28. autoCreate = autoUpdate
  29. saveReference = autoUpdate
  30. } else if value, ok := field.TagSettingsGet("SAVE_ASSOCIATIONS"); ok {
  31. autoUpdate = checkTruth(value)
  32. autoCreate = autoUpdate
  33. saveReference = autoUpdate
  34. }
  35. if value, ok := scope.Get("gorm:association_autoupdate"); ok {
  36. autoUpdate = checkTruth(value)
  37. } else if value, ok := field.TagSettingsGet("ASSOCIATION_AUTOUPDATE"); ok {
  38. autoUpdate = checkTruth(value)
  39. }
  40. if value, ok := scope.Get("gorm:association_autocreate"); ok {
  41. autoCreate = checkTruth(value)
  42. } else if value, ok := field.TagSettingsGet("ASSOCIATION_AUTOCREATE"); ok {
  43. autoCreate = checkTruth(value)
  44. }
  45. if value, ok := scope.Get("gorm:association_save_reference"); ok {
  46. saveReference = checkTruth(value)
  47. } else if value, ok := field.TagSettingsGet("ASSOCIATION_SAVE_REFERENCE"); ok {
  48. saveReference = checkTruth(value)
  49. }
  50. }
  51. }
  52. return
  53. }
  54. func saveBeforeAssociationsCallback(scope *Scope) {
  55. for _, field := range scope.Fields() {
  56. autoUpdate, autoCreate, saveReference, relationship := saveAssociationCheck(scope, field)
  57. if relationship != nil && relationship.Kind == "belongs_to" {
  58. fieldValue := field.Field.Addr().Interface()
  59. newScope := scope.New(fieldValue)
  60. if newScope.PrimaryKeyZero() {
  61. if autoCreate {
  62. scope.Err(scope.NewDB().Save(fieldValue).Error)
  63. }
  64. } else if autoUpdate {
  65. scope.Err(scope.NewDB().Save(fieldValue).Error)
  66. }
  67. if saveReference {
  68. if len(relationship.ForeignFieldNames) != 0 {
  69. // set value's foreign key
  70. for idx, fieldName := range relationship.ForeignFieldNames {
  71. associationForeignName := relationship.AssociationForeignDBNames[idx]
  72. if foreignField, ok := scope.New(fieldValue).FieldByName(associationForeignName); ok {
  73. scope.Err(scope.SetColumn(fieldName, foreignField.Field.Interface()))
  74. }
  75. }
  76. }
  77. }
  78. }
  79. }
  80. }
  81. func saveAfterAssociationsCallback(scope *Scope) {
  82. for _, field := range scope.Fields() {
  83. autoUpdate, autoCreate, saveReference, relationship := saveAssociationCheck(scope, field)
  84. if relationship != nil && (relationship.Kind == "has_one" || relationship.Kind == "has_many" || relationship.Kind == "many_to_many") {
  85. value := field.Field
  86. switch value.Kind() {
  87. case reflect.Slice:
  88. for i := 0; i < value.Len(); i++ {
  89. newDB := scope.NewDB()
  90. elem := value.Index(i).Addr().Interface()
  91. newScope := newDB.NewScope(elem)
  92. if saveReference {
  93. if relationship.JoinTableHandler == nil && len(relationship.ForeignFieldNames) != 0 {
  94. for idx, fieldName := range relationship.ForeignFieldNames {
  95. associationForeignName := relationship.AssociationForeignDBNames[idx]
  96. if f, ok := scope.FieldByName(associationForeignName); ok {
  97. scope.Err(newScope.SetColumn(fieldName, f.Field.Interface()))
  98. }
  99. }
  100. }
  101. if relationship.PolymorphicType != "" {
  102. scope.Err(newScope.SetColumn(relationship.PolymorphicType, relationship.PolymorphicValue))
  103. }
  104. }
  105. if newScope.PrimaryKeyZero() {
  106. if autoCreate {
  107. scope.Err(newDB.Save(elem).Error)
  108. }
  109. } else if autoUpdate {
  110. scope.Err(newDB.Save(elem).Error)
  111. }
  112. if !scope.New(newScope.Value).PrimaryKeyZero() && saveReference {
  113. if joinTableHandler := relationship.JoinTableHandler; joinTableHandler != nil {
  114. scope.Err(joinTableHandler.Add(joinTableHandler, newDB, scope.Value, newScope.Value))
  115. }
  116. }
  117. }
  118. default:
  119. elem := value.Addr().Interface()
  120. newScope := scope.New(elem)
  121. if saveReference {
  122. if len(relationship.ForeignFieldNames) != 0 {
  123. for idx, fieldName := range relationship.ForeignFieldNames {
  124. associationForeignName := relationship.AssociationForeignDBNames[idx]
  125. if f, ok := scope.FieldByName(associationForeignName); ok {
  126. scope.Err(newScope.SetColumn(fieldName, f.Field.Interface()))
  127. }
  128. }
  129. }
  130. if relationship.PolymorphicType != "" {
  131. scope.Err(newScope.SetColumn(relationship.PolymorphicType, relationship.PolymorphicValue))
  132. }
  133. }
  134. if newScope.PrimaryKeyZero() {
  135. if autoCreate {
  136. scope.Err(scope.NewDB().Save(elem).Error)
  137. }
  138. } else if autoUpdate {
  139. scope.Err(scope.NewDB().Save(elem).Error)
  140. }
  141. }
  142. }
  143. }
  144. }