diff --git a/README.md b/README.md index 8f61f20d..b0adb8a4 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,18 @@ db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).First(&user) //// user -> select * from users name = "jinzhu" and age = 20 limit 1; db.Where("birthday < ?", time.Now()).Find(&users) +// Not +db.Not([]int64{1,2,3}).First(&user) +//// user -> select * from users where id NOT IN (1,2,3) +db.Not([]int64{}).First(&user) +//// user -> select * from users; +db.Not("name", "jinzhu").First(&user) +//// user -> select * from users where name <> "jinzhu" +db.Not("name", []string{"jinzhu", "jinzhu 2"}).First(&user) +//// user -> select * from users where name NOT IN ("jinzhu", "jinzhu 2") +db.Not(User{Name: "jinzhu"}).First(&user) +//// user -> select * from users where name <> "jinzhu"; + // Inline search condition db.First(&user, 23) //// user -> select * from users where id = 23 limit 1; diff --git a/do.go b/do.go index b9a292a6..1850d7f3 100644 --- a/do.go +++ b/do.go @@ -435,8 +435,8 @@ func (s *Do) buildNotCondition(clause map[string]interface{}) (str string) { id, _ := strconv.Atoi(value) return fmt.Sprintf("(%v <> %v)", s.model.primaryKeyDb(), id) } else { - str = "( \"" + value + "\" NOT INT (?))" - not_equal_sql = " (%v <> ?) " + str = fmt.Sprintf(" (%v NOT IN (?)) ", value) + not_equal_sql = fmt.Sprintf(" (%v <> ?) ", value) } case int, int64, int32: return fmt.Sprintf("(%v <> %v)", s.model.primaryKeyDb(), query) @@ -445,8 +445,7 @@ func (s *Do) buildNotCondition(clause map[string]interface{}) (str string) { str = fmt.Sprintf("(%v not in (?))", s.model.primaryKeyDb()) clause["args"] = []interface{}{query} } else { - s.err(errors.New(fmt.Sprintf("%+v not supported", query))) - return + return "" } case map[string]interface{}: var sqls []string diff --git a/gorm_test.go b/gorm_test.go index e54a5ec5..a5cc30d7 100644 --- a/gorm_test.go +++ b/gorm_test.go @@ -935,3 +935,48 @@ func TestFindOrCreate(t *testing.T) { t.Errorf("user should be found and updated with assigned attrs") } } + +func TestNot(t *testing.T) { + var users1, users2, users3, users4, users5, users6, users7, users8 []User + db.Find(&users1) + + db.Not(users1[0].Id).Find(&users2) + + if len(users1)-len(users2) != 1 { + t.Errorf("Should ignore the first users with Not") + } + + db.Not([]int{}).Find(&users3) + if len(users1)-len(users3) != 0 { + t.Errorf("Should find all users with a blank condition") + } + + var name_3_count int64 + db.Table("users").Where("name = ?", "3").Count(&name_3_count) + db.Not("name", "3").Find(&users4) + if len(users1)-len(users4) != int(name_3_count) { + t.Errorf("Should find all users's name not equal 3") + } + + db.Not(User{Name: "3"}).Find(&users5) + if len(users1)-len(users5) != int(name_3_count) { + t.Errorf("Should find all users's name not equal 3") + } + + db.Not(map[string]interface{}{"name": "3"}).Find(&users6) + if len(users1)-len(users6) != int(name_3_count) { + t.Errorf("Should find all users's name not equal 3") + } + + db.Not("name", []string{"3"}).Find(&users7) + if len(users1)-len(users7) != int(name_3_count) { + t.Errorf("Should find all users's name not equal 3") + } + + var name_2_count int64 + db.Table("users").Where("name = ?", "2").Count(&name_2_count) + db.Not("name", []string{"3", "2"}).Find(&users8) + if len(users1)-len(users8) != (int(name_3_count) + int(name_2_count)) { + t.Errorf("Should find all users's name not equal 3") + } +}