From 68d3d134e65ec03845c051c3dc514f055e29d4e8 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Tue, 29 Oct 2013 10:19:20 +0800 Subject: [PATCH] Yay, Soft Delete works --- do.go | 17 ++++++++++------- gorm_test.go | 11 ++++++++--- model.go | 8 ++++++-- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/do.go b/do.go index 17f29b2c..b9fbdea8 100644 --- a/do.go +++ b/do.go @@ -186,7 +186,7 @@ func (s *Do) delete() { s.err(s.model.callMethod("BeforeDelete")) if !s.hasError() { - if s.model.hasColumn("DeletedAt") { + if !s.unscoped && 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() @@ -217,7 +217,7 @@ func (s *Do) query(where ...interface{}) { ) 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 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) { - var primary_condiation string - var and_conditions, or_conditions []string + var primary_condiations, 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() { - 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 { @@ -384,8 +387,8 @@ func (s *Do) whereSql() (sql string) { combined_conditions = or_sql } - if len(primary_condiation) > 0 { - sql = "WHERE " + primary_condiation + if len(primary_condiations) > 0 { + sql = "WHERE " + strings.Join(primary_condiations, " AND ") if len(combined_conditions) > 0 { sql = sql + " AND ( " + combined_conditions + " )" } diff --git a/gorm_test.go b/gorm_test.go index 334cfa68..da89e734 100644 --- a/gorm_test.go +++ b/gorm_test.go @@ -702,16 +702,21 @@ func TestSoftDelete(t *testing.T) { order := Order{Amount: 1234} 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") } 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") } - 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") } + + db.Unscoped().Delete(&order) + if db.Unscoped().First(&Order{}, "amount = 1234").Error == nil { + t.Errorf("Can't find out permanently deleted order") + } } diff --git a/model.go b/model.go index a844b863..8e786a8c 100644 --- a/model.go +++ b/model.go @@ -109,8 +109,12 @@ func (m *Model) hasColumn(name string) bool { return false } - value := reflect.ValueOf(m.data).Elem().FieldByName(name) - return value.IsValid() + data := reflect.Indirect(reflect.ValueOf(m.data)) + 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) {