Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support using DeleteId field for soft deletes #18

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,25 @@ SELECT * FROM users WHERE is_del = 0;

// Delete
UPDATE users SET is_del = 1, deleted_at = /* current unix milli second second*/ WHERE ID = 1;
```
```

## Mixed Mode with Delete ID Field
#### Maintaining Unique Key Integrity
This allows you to record the original ID of a deleted record in another field. By doing so, you can maintain the integrity of unique keys by allowing new records with the same unique key to be inserted without conflict.
#### Example
Assume we have a User model where the Email field needs to be unique. By storing the original ID in the DeletedId field and creating a composite unique key with Email and DeletedId, you can insert a new record without violating the unique constraint even after soft deleting an existing record.
```go
type User struct {
ID uint
Name string
Email string
DeletedId uint // Stores the original ID of the deleted record
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedIDField:DeletedId,DeletedIDFromField:ID"` // use `1` `0`
}

// Query
SELECT * FROM users WHERE is_del = 0;

// Delete
UPDATE users SET is_del = 1, deleted_id = /* value from ID */ WHERE ID = 1;
```
24 changes: 20 additions & 4 deletions soft_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ func (DeletedAt) DeleteClauses(f *schema.Field) []clause.Interface {
if v := settings["DELETEDATFIELD"]; v != "" { // DeletedAtField
softDeleteClause.DeleteAtField = f.Schema.LookUpField(v)
}
if v := settings["DELETEDIDFIELD"]; v != "" { // DeleteIdField
softDeleteClause.DeleteIdField = f.Schema.LookUpField(v)
}
if v := settings["DELETEDIDFROMFIELD"]; v != "" { // DeleteIdFromField
softDeleteClause.DeleteIdFromField = f.Schema.LookUpField(v)
}
return []clause.Interface{softDeleteClause}
}

Expand Down Expand Up @@ -101,10 +107,12 @@ func (sd SoftDeleteUpdateClause) ModifyStatement(stmt *gorm.Statement) {
}

type SoftDeleteDeleteClause struct {
Field *schema.Field
Flag bool
TimeType schema.TimeType
DeleteAtField *schema.Field
Field *schema.Field
Flag bool
TimeType schema.TimeType
DeleteAtField *schema.Field
DeleteIdField *schema.Field
DeleteIdFromField *schema.Field
}

func (sd SoftDeleteDeleteClause) Name() string {
Expand Down Expand Up @@ -135,6 +143,14 @@ func (sd SoftDeleteDeleteClause) ModifyStatement(stmt *gorm.Statement) {
stmt.SetColumn(deleteAtField.DBName, value, true)
}

deleteIdField := sd.DeleteIdField
deleteIdFromField := sd.DeleteIdFromField

if deleteIdField != nil && deleteIdFromField != nil {
set = append(set, clause.Assignment{Column: clause.Column{Name: deleteIdField.DBName}, Value: gorm.Expr(deleteIdFromField.DBName)})
stmt.SetColumn(deleteIdField.DBName, gorm.Expr(deleteIdFromField.DBName), true)
}

if sd.Flag {
set = append(clause.Set{{Column: clause.Column{Name: sd.Field.DBName}, Value: FlagDeleted}}, set...)
stmt.SetColumn(sd.Field.DBName, FlagDeleted, true)
Expand Down