delete.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package callbacks
  2. import (
  3. "reflect"
  4. "strings"
  5. "gorm.io/gorm"
  6. "gorm.io/gorm/clause"
  7. "gorm.io/gorm/schema"
  8. )
  9. func BeforeDelete(db *gorm.DB) {
  10. if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && db.Statement.Schema.BeforeDelete {
  11. callMethod(db, func(value interface{}, tx *gorm.DB) bool {
  12. if i, ok := value.(BeforeDeleteInterface); ok {
  13. db.AddError(i.BeforeDelete(tx))
  14. return true
  15. }
  16. return false
  17. })
  18. }
  19. }
  20. func DeleteBeforeAssociations(db *gorm.DB) {
  21. if db.Error == nil && db.Statement.Schema != nil {
  22. selectColumns, restricted := db.Statement.SelectAndOmitColumns(true, false)
  23. if restricted {
  24. for column, v := range selectColumns {
  25. if v {
  26. if rel, ok := db.Statement.Schema.Relationships.Relations[column]; ok {
  27. switch rel.Type {
  28. case schema.HasOne, schema.HasMany:
  29. queryConds := rel.ToQueryConditions(db.Statement.ReflectValue)
  30. modelValue := reflect.New(rel.FieldSchema.ModelType).Interface()
  31. tx := db.Session(&gorm.Session{NewDB: true}).Model(modelValue)
  32. withoutConditions := false
  33. if db.Statement.Unscoped {
  34. tx = tx.Unscoped()
  35. }
  36. if len(db.Statement.Selects) > 0 {
  37. selects := make([]string, 0, len(db.Statement.Selects))
  38. for _, s := range db.Statement.Selects {
  39. if s == clause.Associations {
  40. selects = append(selects, s)
  41. } else if strings.HasPrefix(s, column+".") {
  42. selects = append(selects, strings.TrimPrefix(s, column+"."))
  43. }
  44. }
  45. if len(selects) > 0 {
  46. tx = tx.Select(selects)
  47. }
  48. }
  49. for _, cond := range queryConds {
  50. if c, ok := cond.(clause.IN); ok && len(c.Values) == 0 {
  51. withoutConditions = true
  52. break
  53. }
  54. }
  55. if !withoutConditions {
  56. if db.AddError(tx.Clauses(clause.Where{Exprs: queryConds}).Delete(modelValue).Error) != nil {
  57. return
  58. }
  59. }
  60. case schema.Many2Many:
  61. var (
  62. queryConds = make([]clause.Expression, 0, len(rel.References))
  63. foreignFields = make([]*schema.Field, 0, len(rel.References))
  64. relForeignKeys = make([]string, 0, len(rel.References))
  65. modelValue = reflect.New(rel.JoinTable.ModelType).Interface()
  66. table = rel.JoinTable.Table
  67. tx = db.Session(&gorm.Session{NewDB: true}).Model(modelValue).Table(table)
  68. )
  69. for _, ref := range rel.References {
  70. if ref.OwnPrimaryKey {
  71. foreignFields = append(foreignFields, ref.PrimaryKey)
  72. relForeignKeys = append(relForeignKeys, ref.ForeignKey.DBName)
  73. } else if ref.PrimaryValue != "" {
  74. queryConds = append(queryConds, clause.Eq{
  75. Column: clause.Column{Table: rel.JoinTable.Table, Name: ref.ForeignKey.DBName},
  76. Value: ref.PrimaryValue,
  77. })
  78. }
  79. }
  80. _, foreignValues := schema.GetIdentityFieldValuesMap(db.Statement.ReflectValue, foreignFields)
  81. column, values := schema.ToQueryValues(table, relForeignKeys, foreignValues)
  82. queryConds = append(queryConds, clause.IN{Column: column, Values: values})
  83. if db.AddError(tx.Clauses(clause.Where{Exprs: queryConds}).Delete(modelValue).Error) != nil {
  84. return
  85. }
  86. }
  87. }
  88. }
  89. }
  90. }
  91. }
  92. }
  93. func Delete(db *gorm.DB) {
  94. if db.Error == nil {
  95. if db.Statement.Schema != nil && !db.Statement.Unscoped {
  96. for _, c := range db.Statement.Schema.DeleteClauses {
  97. db.Statement.AddClause(c)
  98. }
  99. }
  100. if db.Statement.SQL.String() == "" {
  101. db.Statement.SQL.Grow(100)
  102. db.Statement.AddClauseIfNotExists(clause.Delete{})
  103. if db.Statement.Schema != nil {
  104. _, queryValues := schema.GetIdentityFieldValuesMap(db.Statement.ReflectValue, db.Statement.Schema.PrimaryFields)
  105. column, values := schema.ToQueryValues(db.Statement.Table, db.Statement.Schema.PrimaryFieldDBNames, queryValues)
  106. if len(values) > 0 {
  107. db.Statement.AddClause(clause.Where{Exprs: []clause.Expression{clause.IN{Column: column, Values: values}}})
  108. }
  109. if db.Statement.ReflectValue.CanAddr() && db.Statement.Dest != db.Statement.Model && db.Statement.Model != nil {
  110. _, queryValues = schema.GetIdentityFieldValuesMap(reflect.ValueOf(db.Statement.Model), db.Statement.Schema.PrimaryFields)
  111. column, values = schema.ToQueryValues(db.Statement.Table, db.Statement.Schema.PrimaryFieldDBNames, queryValues)
  112. if len(values) > 0 {
  113. db.Statement.AddClause(clause.Where{Exprs: []clause.Expression{clause.IN{Column: column, Values: values}}})
  114. }
  115. }
  116. }
  117. db.Statement.AddClauseIfNotExists(clause.From{})
  118. db.Statement.Build(db.Statement.BuildClauses...)
  119. }
  120. if _, ok := db.Statement.Clauses["WHERE"]; !db.AllowGlobalUpdate && !ok && db.Error == nil {
  121. db.AddError(gorm.ErrMissingWhereClause)
  122. return
  123. }
  124. if !db.DryRun && db.Error == nil {
  125. result, err := db.Statement.ConnPool.ExecContext(db.Statement.Context, db.Statement.SQL.String(), db.Statement.Vars...)
  126. if err == nil {
  127. db.RowsAffected, _ = result.RowsAffected()
  128. } else {
  129. db.AddError(err)
  130. }
  131. }
  132. }
  133. }
  134. func AfterDelete(db *gorm.DB) {
  135. if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && db.Statement.Schema.AfterDelete {
  136. callMethod(db, func(value interface{}, tx *gorm.DB) bool {
  137. if i, ok := value.(AfterDeleteInterface); ok {
  138. db.AddError(i.AfterDelete(tx))
  139. return true
  140. }
  141. return false
  142. })
  143. }
  144. }