Yay, Soft Delete works

This commit is contained in:
Jinzhu 2013-10-29 10:19:20 +08:00
parent 7e5dc40f6f
commit 68d3d134e6
3 changed files with 24 additions and 12 deletions

17
do.go
View File

@ -186,7 +186,7 @@ func (s *Do) delete() {
s.err(s.model.callMethod("BeforeDelete")) s.err(s.model.callMethod("BeforeDelete"))
if !s.hasError() { if !s.hasError() {
if s.model.hasColumn("DeletedAt") { if !s.unscoped && s.model.hasColumn("DeletedAt") {
delete_sql := "deleted_at=" + s.addToVars(time.Now()) delete_sql := "deleted_at=" + s.addToVars(time.Now())
s.sql = fmt.Sprintf("UPDATE %v SET %v %v", s.tableName(), delete_sql, s.combinedSql()) s.sql = fmt.Sprintf("UPDATE %v SET %v %v", s.tableName(), delete_sql, s.combinedSql())
s.exec() s.exec()
@ -217,7 +217,7 @@ func (s *Do) query(where ...interface{}) {
) )
dest_out := reflect.Indirect(reflect.ValueOf(s.value)) dest_out := reflect.Indirect(reflect.ValueOf(s.value))
if x := dest_out.Kind(); x == reflect.Slice { if dest_out.Kind() == reflect.Slice {
is_slice = true is_slice = true
dest_type = dest_out.Type().Elem() dest_type = dest_out.Type().Elem()
} }
@ -358,11 +358,14 @@ func (s *Do) buildWhereCondition(clause map[string]interface{}) (str string) {
} }
func (s *Do) whereSql() (sql string) { func (s *Do) whereSql() (sql string) {
var primary_condiation string var primary_condiations, and_conditions, or_conditions []string
var and_conditions, or_conditions []string
if !s.unscoped && s.model.hasColumn("DeletedAt") {
primary_condiations = append(primary_condiations, "(deleted_at is null or deleted_at <= '0001-01-02')")
}
if !s.model.primaryKeyZero() { if !s.model.primaryKeyZero() {
primary_condiation = s.primaryCondiation(s.addToVars(s.model.primaryKeyValue())) primary_condiations = append(primary_condiations, s.primaryCondiation(s.addToVars(s.model.primaryKeyValue())))
} }
for _, clause := range s.whereClause { for _, clause := range s.whereClause {
@ -384,8 +387,8 @@ func (s *Do) whereSql() (sql string) {
combined_conditions = or_sql combined_conditions = or_sql
} }
if len(primary_condiation) > 0 { if len(primary_condiations) > 0 {
sql = "WHERE " + primary_condiation sql = "WHERE " + strings.Join(primary_condiations, " AND ")
if len(combined_conditions) > 0 { if len(combined_conditions) > 0 {
sql = sql + " AND ( " + combined_conditions + " )" sql = sql + " AND ( " + combined_conditions + " )"
} }

View File

@ -702,16 +702,21 @@ func TestSoftDelete(t *testing.T) {
order := Order{Amount: 1234} order := Order{Amount: 1234}
db.Save(&order) db.Save(&order)
if db.Find(&Order{}, "amount = 1234").Error != nil { if db.First(&Order{}, "amount = ?", 1234).Error != nil {
t.Errorf("No errors should happen when save an order") t.Errorf("No errors should happen when save an order")
} }
db.Delete(&order) db.Delete(&order)
if db.Find(&Order{}, "amount = 1234").Error == nil { if db.First(&Order{}, "amount = 1234").Error == nil {
t.Errorf("Can't find the user because it is soft deleted") t.Errorf("Can't find the user because it is soft deleted")
} }
if db.Unscoped().Find(&Order{}, "amount = 1234").Error != nil { if db.Unscoped().First(&Order{}, "amount = 1234").Error != nil {
t.Errorf("Should be able to find out the soft deleted user with unscoped") t.Errorf("Should be able to find out the soft deleted user with unscoped")
} }
db.Unscoped().Delete(&order)
if db.Unscoped().First(&Order{}, "amount = 1234").Error == nil {
t.Errorf("Can't find out permanently deleted order")
}
} }

View File

@ -109,8 +109,12 @@ func (m *Model) hasColumn(name string) bool {
return false return false
} }
value := reflect.ValueOf(m.data).Elem().FieldByName(name) data := reflect.Indirect(reflect.ValueOf(m.data))
return value.IsValid() if data.Kind() == reflect.Slice {
return false //FIXME data.Elem().FieldByName(name).IsValid()
} else {
return data.FieldByName(name).IsValid()
}
} }
func (m *Model) tableName() (str string, err error) { func (m *Model) tableName() (str string, err error) {