forked from mirror/gorm
Don't do real delete when deleted_at column exist
This commit is contained in:
parent
bc785a9173
commit
7e5dc40f6f
7
chain.go
7
chain.go
|
@ -24,6 +24,7 @@ type Chain struct {
|
|||
offsetStr string
|
||||
limitStr string
|
||||
specifiedTableName string
|
||||
unscoped bool
|
||||
}
|
||||
|
||||
func (s *Chain) err(err error) error {
|
||||
|
@ -47,6 +48,7 @@ func (s *Chain) do(value interface{}) *Do {
|
|||
do.offsetStr = s.offsetStr
|
||||
do.limitStr = s.limitStr
|
||||
do.specifiedTableName = s.specifiedTableName
|
||||
do.unscoped = s.unscoped
|
||||
|
||||
s.value = value
|
||||
do.setModel(value)
|
||||
|
@ -177,6 +179,11 @@ func (s *Chain) CreateTable(value interface{}) *Chain {
|
|||
return s
|
||||
}
|
||||
|
||||
func (s *Chain) Unscoped() *Chain {
|
||||
s.unscoped = true
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Chain) Table(name string) *Chain {
|
||||
s.specifiedTableName = name
|
||||
return s
|
||||
|
|
11
do.go
11
do.go
|
@ -7,6 +7,7 @@ import (
|
|||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"strings"
|
||||
)
|
||||
|
@ -31,7 +32,7 @@ type Do struct {
|
|||
orderStrs []string
|
||||
offsetStr string
|
||||
limitStr string
|
||||
|
||||
unscoped bool
|
||||
updateAttrs map[string]interface{}
|
||||
ignoreProtectedAttrs bool
|
||||
}
|
||||
|
@ -184,9 +185,15 @@ func (s *Do) prepareDeleteSql() {
|
|||
func (s *Do) delete() {
|
||||
s.err(s.model.callMethod("BeforeDelete"))
|
||||
|
||||
s.prepareDeleteSql()
|
||||
if !s.hasError() {
|
||||
if s.model.hasColumn("DeletedAt") {
|
||||
delete_sql := "deleted_at=" + s.addToVars(time.Now())
|
||||
s.sql = fmt.Sprintf("UPDATE %v SET %v %v", s.tableName(), delete_sql, s.combinedSql())
|
||||
s.exec()
|
||||
} else {
|
||||
s.prepareDeleteSql()
|
||||
s.exec()
|
||||
}
|
||||
if !s.hasError() {
|
||||
s.err(s.model.callMethod("AfterDelete"))
|
||||
}
|
||||
|
|
26
gorm_test.go
26
gorm_test.go
|
@ -53,7 +53,6 @@ func init() {
|
|||
if err != nil {
|
||||
fmt.Printf("Got error when try to delete table uses, %+v\n", err)
|
||||
}
|
||||
|
||||
db.Exec("drop table products;")
|
||||
|
||||
orm := db.CreateTable(&User{})
|
||||
|
@ -691,3 +690,28 @@ func TestUpdates(t *testing.T) {
|
|||
t.Errorf("We should have Product fgh")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSoftDelete(t *testing.T) {
|
||||
type Order struct {
|
||||
Id int64
|
||||
Amount int64
|
||||
DeletedAt time.Time
|
||||
}
|
||||
db.Exec("drop table orders;")
|
||||
db.CreateTable(&Order{})
|
||||
|
||||
order := Order{Amount: 1234}
|
||||
db.Save(&order)
|
||||
if db.Find(&Order{}, "amount = 1234").Error != nil {
|
||||
t.Errorf("No errors should happen when save an order")
|
||||
}
|
||||
|
||||
db.Delete(&order)
|
||||
if db.Find(&Order{}, "amount = 1234").Error == nil {
|
||||
t.Errorf("Can't find the user because it is soft deleted")
|
||||
}
|
||||
|
||||
if db.Unscoped().Find(&Order{}, "amount = 1234").Error != nil {
|
||||
t.Errorf("Should be able to find out the soft deleted user with unscoped")
|
||||
}
|
||||
}
|
||||
|
|
4
main.go
4
main.go
|
@ -57,6 +57,10 @@ func (s *DB) Delete(value interface{}) *Chain {
|
|||
return s.buildChain().Delete(value)
|
||||
}
|
||||
|
||||
func (s *DB) Unscoped() *Chain {
|
||||
return s.buildChain().Unscoped()
|
||||
}
|
||||
|
||||
func (s *DB) Exec(sql string) *Chain {
|
||||
return s.buildChain().Exec(sql)
|
||||
}
|
||||
|
|
9
model.go
9
model.go
|
@ -104,6 +104,15 @@ func (m *Model) columnsAndValues(operation string) map[string]interface{} {
|
|||
return results
|
||||
}
|
||||
|
||||
func (m *Model) hasColumn(name string) bool {
|
||||
if m.data == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(m.data).Elem().FieldByName(name)
|
||||
return value.IsValid()
|
||||
}
|
||||
|
||||
func (m *Model) tableName() (str string, err error) {
|
||||
if m.data == nil {
|
||||
err = errors.New("Model haven't been set")
|
||||
|
|
Loading…
Reference in New Issue