`Alive' column soft-deletion support.
This commit is contained in:
parent
c2dda88f9a
commit
240f60e864
29
README.md
29
README.md
@ -84,6 +84,7 @@ type User struct{} // struct User's database table name is "users" by default, w
|
|||||||
* Use `CreatedAt` to store record's created time if field exists
|
* Use `CreatedAt` to store record's created time if field exists
|
||||||
* Use `UpdatedAt` to store record's updated time if field exists
|
* Use `UpdatedAt` to store record's updated time if field exists
|
||||||
* Use `DeletedAt` to store record's deleted time if field exists [Soft Delete](#soft-delete)
|
* Use `DeletedAt` to store record's deleted time if field exists [Soft Delete](#soft-delete)
|
||||||
|
* Use nullable `Alive` to store record's aliveness if field exists [Soft Delete](#soft-delete)
|
||||||
* Gorm provide a default model struct, you could embed it in your struct
|
* Gorm provide a default model struct, you could embed it in your struct
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@ -446,10 +447,32 @@ db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})
|
|||||||
//// DELETE from emails where email LIKE "%jinhu%";
|
//// DELETE from emails where email LIKE "%jinhu%";
|
||||||
```
|
```
|
||||||
|
|
||||||
### Soft Delete
|
### Soft-Delete
|
||||||
|
|
||||||
If struct has `DeletedAt` field, it will get soft delete ability automatically!
|
If a struct has a `DeletedAt` field, it will get soft-delete ability automatically!
|
||||||
Then it won't be deleted from database permanently when call `Delete`.
|
Then it won't be deleted from database permanently when `Delete()` is called.
|
||||||
|
|
||||||
|
Or alternatively..
|
||||||
|
|
||||||
|
If a struct has an `Alive` field it will get soft-delete ability automatically!
|
||||||
|
Then it won't be deleted from the database permanently when `Delete()` is called.
|
||||||
|
`Alive` will be set to `null`. This makes it possible to still enforce unique
|
||||||
|
constraints (e.g. "name", "alive"), but not have the unique constraint enforced
|
||||||
|
for "deleted" records.
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Friend struct {
|
||||||
|
ID int64
|
||||||
|
Name string `sql:"type:varchar(255)`
|
||||||
|
Alive int `json:"-" sql:"type:integer;DEFAULT: 1;"`
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Delete(&friend)
|
||||||
|
//// UPDATE friends SET alive=null WHERE id = 42;
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: Choose only one or the other. It won't work right if both `DeletedAt` and
|
||||||
|
`Alive` columns are defined.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
db.Delete(&user)
|
db.Delete(&user)
|
||||||
|
@ -8,13 +8,20 @@ func BeforeDelete(scope *Scope) {
|
|||||||
|
|
||||||
func Delete(scope *Scope) {
|
func Delete(scope *Scope) {
|
||||||
if !scope.HasError() {
|
if !scope.HasError() {
|
||||||
if !scope.Search.Unscoped && scope.HasColumn("DeletedAt") {
|
unscoped := scope.Search.Unscoped
|
||||||
|
if !unscoped && scope.HasColumn("DeletedAt") {
|
||||||
scope.Raw(
|
scope.Raw(
|
||||||
fmt.Sprintf("UPDATE %v SET deleted_at=%v %v",
|
fmt.Sprintf("UPDATE %v SET deleted_at=%v %v",
|
||||||
scope.QuotedTableName(),
|
scope.QuotedTableName(),
|
||||||
scope.AddToVars(NowFunc()),
|
scope.AddToVars(NowFunc()),
|
||||||
scope.CombinedConditionSql(),
|
scope.CombinedConditionSql(),
|
||||||
))
|
))
|
||||||
|
} else if !unscoped && scope.HasColumn("Alive") {
|
||||||
|
scope.Raw(
|
||||||
|
fmt.Sprintf("UPDATE %v SET alive=null %v",
|
||||||
|
scope.QuotedTableName(),
|
||||||
|
scope.CombinedConditionSql(),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
scope.Raw(fmt.Sprintf("DELETE FROM %v %v", scope.QuotedTableName(), scope.CombinedConditionSql()))
|
scope.Raw(fmt.Sprintf("DELETE FROM %v %v", scope.QuotedTableName(), scope.CombinedConditionSql()))
|
||||||
}
|
}
|
||||||
|
@ -158,9 +158,14 @@ func (scope *Scope) buildSelectQuery(clause map[string]interface{}) (str string)
|
|||||||
func (scope *Scope) whereSql() (sql string) {
|
func (scope *Scope) whereSql() (sql string) {
|
||||||
var primaryConditions, andConditions, orConditions []string
|
var primaryConditions, andConditions, orConditions []string
|
||||||
|
|
||||||
if !scope.Search.Unscoped && scope.Fields()["deleted_at"] != nil {
|
if !scope.Search.Unscoped {
|
||||||
sql := fmt.Sprintf("(%v.deleted_at IS NULL OR %v.deleted_at <= '0001-01-02')", scope.QuotedTableName(), scope.QuotedTableName())
|
if scope.Fields()["deleted_at"] != nil {
|
||||||
primaryConditions = append(primaryConditions, sql)
|
sql := fmt.Sprintf("(%v.deleted_at IS NULL OR %v.deleted_at <= '0001-01-02')", scope.QuotedTableName(), scope.QuotedTableName())
|
||||||
|
primaryConditions = append(primaryConditions, sql)
|
||||||
|
} else if scope.Fields()["alive"] != nil {
|
||||||
|
sql := fmt.Sprintf("(%v.alive IS NOT NULL)", scope.QuotedTableName())
|
||||||
|
primaryConditions = append(primaryConditions, sql)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !scope.PrimaryKeyZero() {
|
if !scope.PrimaryKeyZero() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user