From 5e475901658b80fe9cc5a8e757832841293c3c48 Mon Sep 17 00:00:00 2001 From: John Guo Date: Mon, 9 Dec 2024 09:24:48 +0800 Subject: [PATCH] feat(database/gdb): add `WhereExists/WhereNotExists` (#4015) --- .../drivers/mysql/mysql_z_unit_model_test.go | 1061 +------------- .../mysql/mysql_z_unit_model_where_test.go | 1244 +++++++++++++++++ database/gdb/gdb_model_builder_where.go | 10 + database/gdb/gdb_model_where.go | 10 + 4 files changed, 1280 insertions(+), 1045 deletions(-) create mode 100644 contrib/drivers/mysql/mysql_z_unit_model_where_test.go diff --git a/contrib/drivers/mysql/mysql_z_unit_model_test.go b/contrib/drivers/mysql/mysql_z_unit_model_test.go index 5f3033b36d0..9be10ff1313 100644 --- a/contrib/drivers/mysql/mysql_z_unit_model_test.go +++ b/contrib/drivers/mysql/mysql_z_unit_model_test.go @@ -17,7 +17,6 @@ import ( "time" "github.com/gogf/gf/v2/container/garray" - "github.com/gogf/gf/v2/container/gmap" "github.com/gogf/gf/v2/container/gvar" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/encoding/gjson" @@ -28,7 +27,6 @@ import ( "github.com/gogf/gf/v2/test/gtest" "github.com/gogf/gf/v2/text/gstr" "github.com/gogf/gf/v2/util/guid" - "github.com/gogf/gf/v2/util/gutil" ) func Test_Model_Insert(t *testing.T) { @@ -1366,591 +1364,6 @@ func Test_Model_Data(t *testing.T) { }) } -func Test_Model_Where(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - // string - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id=? and nickname=?", 3, "name_3").One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - - // slice - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(g.Slice{"id", 3}).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(g.Slice{"id", 3, "nickname", "name_3"}).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - - // slice parameter - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id=? and nickname=?", g.Slice{3, "name_3"}).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - // map like - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(g.Map{ - "passport like": "user_1%", - }).Order("id asc").All() - t.AssertNil(err) - t.Assert(len(result), 2) - t.Assert(result[0].GMap().Get("id"), 1) - t.Assert(result[1].GMap().Get("id"), 10) - }) - // map + slice parameter - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(g.Map{ - "id": g.Slice{1, 2, 3}, - "passport": g.Slice{"user_2", "user_3"}, - }).Where("id=? and nickname=?", g.Slice{3, "name_3"}).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id=3", g.Slice{}).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id=?", g.Slice{3}).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id", 3).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id", 3).Where("nickname", "name_3").One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id", 3).Where("nickname", "name_3").One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id", 30).WhereOr("nickname", "name_3").One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id", 30).WhereOr("nickname", "name_3").Where("id>?", 1).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id", 30).WhereOr("nickname", "name_3").Where("id>", 1).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // slice - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id=? AND nickname=?", g.Slice{3, "name_3"}...).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id=? AND nickname=?", g.Slice{3, "name_3"}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("passport like ? and nickname like ?", g.Slice{"user_3", "name_3"}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // map - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(g.Map{"id": 3, "nickname": "name_3"}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // map key operator - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(g.Map{"id>": 1, "id<": 3}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 2) - }) - - // gmap.Map - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(gmap.NewFrom(g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // gmap.Map key operator - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(gmap.NewFrom(g.MapAnyAny{"id>": 1, "id<": 3})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 2) - }) - - // list map - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(gmap.NewListMapFrom(g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // list map key operator - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(gmap.NewListMapFrom(g.MapAnyAny{"id>": 1, "id<": 3})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 2) - }) - - // tree map - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(gmap.NewTreeMapFrom(gutil.ComparatorString, g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // tree map key operator - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(gmap.NewTreeMapFrom(gutil.ComparatorString, g.MapAnyAny{"id>": 1, "id<": 3})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 2) - }) - - // complicated where 1 - gtest.C(t, func(t *gtest.T) { - // db.SetDebug(true) - conditions := g.Map{ - "nickname like ?": "%name%", - "id between ? and ?": g.Slice{1, 3}, - "id > 0": nil, - "create_time > 0": nil, - "id": g.Slice{1, 2, 3}, - } - result, err := db.Model(table).Where(conditions).Order("id asc").All() - t.AssertNil(err) - t.Assert(len(result), 3) - t.Assert(result[0]["id"].Int(), 1) - }) - // complicated where 2 - gtest.C(t, func(t *gtest.T) { - // db.SetDebug(true) - conditions := g.Map{ - "nickname like ?": "%name%", - "id between ? and ?": g.Slice{1, 3}, - "id >= ?": 1, - "create_time > ?": 0, - "id in(?)": g.Slice{1, 2, 3}, - } - result, err := db.Model(table).Where(conditions).Order("id asc").All() - t.AssertNil(err) - t.Assert(len(result), 3) - t.Assert(result[0]["id"].Int(), 1) - }) - // struct, automatic mapping and filtering. - gtest.C(t, func(t *gtest.T) { - type User struct { - Id int - Nickname string - } - result, err := db.Model(table).Where(User{3, "name_3"}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - - result, err = db.Model(table).Where(&User{3, "name_3"}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // slice single - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("id IN(?)", g.Slice{1, 3}).Order("id ASC").All() - t.AssertNil(err) - t.Assert(len(result), 2) - t.Assert(result[0]["id"].Int(), 1) - t.Assert(result[1]["id"].Int(), 3) - }) - // slice + string - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("nickname=? AND id IN(?)", "name_3", g.Slice{1, 3}).Order("id ASC").All() - t.AssertNil(err) - t.Assert(len(result), 1) - t.Assert(result[0]["id"].Int(), 3) - }) - // slice + map - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(g.Map{ - "id": g.Slice{1, 3}, - "nickname": "name_3", - }).Order("id ASC").All() - t.AssertNil(err) - t.Assert(len(result), 1) - t.Assert(result[0]["id"].Int(), 3) - }) - // slice + struct - gtest.C(t, func(t *gtest.T) { - type User struct { - Ids []int `json:"id"` - Nickname string `gconv:"nickname"` - } - result, err := db.Model(table).Where(User{ - Ids: []int{1, 3}, - Nickname: "name_3", - }).Order("id ASC").All() - t.AssertNil(err) - t.Assert(len(result), 1) - t.Assert(result[0]["id"].Int(), 3) - }) -} - -func Test_Model_Where_ISNULL_1(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - // db.SetDebug(true) - result, err := db.Model(table).Data("nickname", nil).Where("id", 2).Update() - t.AssertNil(err) - n, _ := result.RowsAffected() - t.Assert(n, 1) - - one, err := db.Model(table).Where("nickname", nil).One() - t.AssertNil(err) - t.Assert(one.IsEmpty(), false) - t.Assert(one["id"], 2) - }) -} - -func Test_Model_Where_ISNULL_2(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - // complicated one. - gtest.C(t, func(t *gtest.T) { - // db.SetDebug(true) - conditions := g.Map{ - "nickname like ?": "%name%", - "id between ? and ?": g.Slice{1, 3}, - "id > 0": nil, - "create_time > 0": nil, - "id": g.Slice{1, 2, 3}, - } - result, err := db.Model(table).Where(conditions).Order("id asc").All() - t.AssertNil(err) - t.Assert(len(result), 3) - t.Assert(result[0]["id"].Int(), 1) - }) -} - -func Test_Model_Where_OmitEmpty(t *testing.T) { - table := createInitTable() - defer dropTable(table) - gtest.C(t, func(t *gtest.T) { - conditions := g.Map{ - "id < 4": "", - } - result, err := db.Model(table).Where(conditions).Order("id desc").All() - t.AssertNil(err) - t.Assert(len(result), 3) - t.Assert(result[0]["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - conditions := g.Map{ - "id < 4": "", - } - result, err := db.Model(table).Where(conditions).OmitEmpty().Order("id desc").All() - t.AssertNil(err) - t.Assert(len(result), 10) - t.Assert(result[0]["id"].Int(), 10) - }) -} - -func Test_Model_Where_GTime(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("create_time>?", gtime.NewFromStr("2010-09-01")).All() - t.AssertNil(err) - t.Assert(len(result), 10) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where("create_time>?", *gtime.NewFromStr("2010-09-01")).All() - t.AssertNil(err) - t.Assert(len(result), 10) - }) -} - -func Test_Model_WherePri(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - // primary key - gtest.C(t, func(t *gtest.T) { - one, err := db.Model(table).WherePri(3).One() - t.AssertNil(err) - t.AssertNE(one, nil) - t.Assert(one["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - all, err := db.Model(table).WherePri(g.Slice{3, 9}).Order("id asc").All() - t.AssertNil(err) - t.Assert(len(all), 2) - t.Assert(all[0]["id"].Int(), 3) - t.Assert(all[1]["id"].Int(), 9) - }) - - // string - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id=? and nickname=?", 3, "name_3").One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - // slice parameter - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id=? and nickname=?", g.Slice{3, "name_3"}).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - // map like - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(g.Map{ - "passport like": "user_1%", - }).Order("id asc").All() - t.AssertNil(err) - t.Assert(len(result), 2) - t.Assert(result[0].GMap().Get("id"), 1) - t.Assert(result[1].GMap().Get("id"), 10) - }) - // map + slice parameter - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(g.Map{ - "id": g.Slice{1, 2, 3}, - "passport": g.Slice{"user_2", "user_3"}, - }).Where("id=? and nickname=?", g.Slice{3, "name_3"}).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(g.Map{ - "id": g.Slice{1, 2, 3}, - "passport": g.Slice{"user_2", "user_3"}, - }).WhereOr("nickname=?", g.Slice{"name_4"}).Where("id", 3).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 2) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id=3", g.Slice{}).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id=?", g.Slice{3}).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id", 3).One() - t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id", 3).WherePri("nickname", "name_3").One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id", 3).Where("nickname", "name_3").One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id", 30).WhereOr("nickname", "name_3").One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id", 30).WhereOr("nickname", "name_3").Where("id>?", 1).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id", 30).WhereOr("nickname", "name_3").Where("id>", 1).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // slice - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id=? AND nickname=?", g.Slice{3, "name_3"}...).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id=? AND nickname=?", g.Slice{3, "name_3"}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("passport like ? and nickname like ?", g.Slice{"user_3", "name_3"}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // map - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(g.Map{"id": 3, "nickname": "name_3"}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // map key operator - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(g.Map{"id>": 1, "id<": 3}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 2) - }) - - // gmap.Map - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(gmap.NewFrom(g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // gmap.Map key operator - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(gmap.NewFrom(g.MapAnyAny{"id>": 1, "id<": 3})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 2) - }) - - // list map - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(gmap.NewListMapFrom(g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // list map key operator - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(gmap.NewListMapFrom(g.MapAnyAny{"id>": 1, "id<": 3})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 2) - }) - - // tree map - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(gmap.NewTreeMapFrom(gutil.ComparatorString, g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // tree map key operator - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(gmap.NewTreeMapFrom(gutil.ComparatorString, g.MapAnyAny{"id>": 1, "id<": 3})).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 2) - }) - - // complicated where 1 - gtest.C(t, func(t *gtest.T) { - // db.SetDebug(true) - conditions := g.Map{ - "nickname like ?": "%name%", - "id between ? and ?": g.Slice{1, 3}, - "id > 0": nil, - "create_time > 0": nil, - "id": g.Slice{1, 2, 3}, - } - result, err := db.Model(table).WherePri(conditions).Order("id asc").All() - t.AssertNil(err) - t.Assert(len(result), 3) - t.Assert(result[0]["id"].Int(), 1) - }) - // complicated where 2 - gtest.C(t, func(t *gtest.T) { - // db.SetDebug(true) - conditions := g.Map{ - "nickname like ?": "%name%", - "id between ? and ?": g.Slice{1, 3}, - "id >= ?": 1, - "create_time > ?": 0, - "id in(?)": g.Slice{1, 2, 3}, - } - result, err := db.Model(table).WherePri(conditions).Order("id asc").All() - t.AssertNil(err) - t.Assert(len(result), 3) - t.Assert(result[0]["id"].Int(), 1) - }) - // struct - gtest.C(t, func(t *gtest.T) { - type User struct { - Id int `json:"id"` - Nickname string `gconv:"nickname"` - } - result, err := db.Model(table).WherePri(User{3, "name_3"}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - - result, err = db.Model(table).WherePri(&User{3, "name_3"}).One() - t.AssertNil(err) - t.Assert(result["id"].Int(), 3) - }) - // slice single - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("id IN(?)", g.Slice{1, 3}).Order("id ASC").All() - t.AssertNil(err) - t.Assert(len(result), 2) - t.Assert(result[0]["id"].Int(), 1) - t.Assert(result[1]["id"].Int(), 3) - }) - // slice + string - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri("nickname=? AND id IN(?)", "name_3", g.Slice{1, 3}).Order("id ASC").All() - t.AssertNil(err) - t.Assert(len(result), 1) - t.Assert(result[0]["id"].Int(), 3) - }) - // slice + map - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WherePri(g.Map{ - "id": g.Slice{1, 3}, - "nickname": "name_3", - }).Order("id ASC").All() - t.AssertNil(err) - t.Assert(len(result), 1) - t.Assert(result[0]["id"].Int(), 3) - }) - // slice + struct - gtest.C(t, func(t *gtest.T) { - type User struct { - Ids []int `json:"id"` - Nickname string `gconv:"nickname"` - } - result, err := db.Model(table).WherePri(User{ - Ids: []int{1, 3}, - Nickname: "name_3", - }).Order("id ASC").All() - t.AssertNil(err) - t.Assert(len(result), 1) - t.Assert(result[0]["id"].Int(), 3) - }) -} - func Test_Model_Delete(t *testing.T) { table := createInitTable() defer dropTable(table) @@ -2265,79 +1678,29 @@ func Test_Model_OmitNil(t *testing.T) { ) ENGINE=InnoDB DEFAULT CHARSET=utf8; `, table)); err != nil { gtest.Error(err) - } - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - _, err := db.Model(table).OmitNil().Data(g.Map{ - "id": 1, - "name": nil, - }).Save() - t.AssertNE(err, nil) - }) - gtest.C(t, func(t *gtest.T) { - _, err := db.Model(table).OmitNil().Data(g.Map{ - "id": 1, - "name": "", - }).Save() - t.AssertNil(err) - }) - gtest.C(t, func(t *gtest.T) { - _, err := db.Model(table).OmitNilWhere().Data(g.Map{ - "id": 1, - "name": "", - }).Save() - t.AssertNil(err) - }) -} - -func Test_Model_Option_Where(t *testing.T) { - gtest.C(t, func(t *gtest.T) { - table := createInitTable() - defer dropTable(table) - r, err := db.Model(table).OmitEmpty().Data("nickname", 1).Where(g.Map{"id": 0, "passport": ""}).Where(1).Update() - t.AssertNil(err) - n, _ := r.RowsAffected() - t.Assert(n, TableSize) - }) - - gtest.C(t, func(t *gtest.T) { - table := createInitTable() - defer dropTable(table) - r, err := db.Model(table).OmitEmpty().Data("nickname", 1).Where(g.Map{"id": 1, "passport": ""}).Update() - t.AssertNil(err) - n, _ := r.RowsAffected() - t.Assert(n, 1) + } + defer dropTable(table) - v, err := db.Model(table).Where("id", 1).Fields("nickname").Value() - t.AssertNil(err) - t.Assert(v.String(), "1") + gtest.C(t, func(t *gtest.T) { + _, err := db.Model(table).OmitNil().Data(g.Map{ + "id": 1, + "name": nil, + }).Save() + t.AssertNE(err, nil) }) -} - -func Test_Model_Where_MultiSliceArguments(t *testing.T) { - table := createInitTable() - defer dropTable(table) gtest.C(t, func(t *gtest.T) { - r, err := db.Model(table).Where(g.Map{ - "id": g.Slice{1, 2, 3, 4}, - "passport": g.Slice{"user_2", "user_3", "user_4"}, - "nickname": g.Slice{"name_2", "name_4"}, - "id >= 4": nil, - }).All() + _, err := db.Model(table).OmitNil().Data(g.Map{ + "id": 1, + "name": "", + }).Save() t.AssertNil(err) - t.Assert(len(r), 1) - t.Assert(r[0]["id"], 4) }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Where(g.Map{ - "id": g.Slice{1, 2, 3}, - "passport": g.Slice{"user_2", "user_3"}, - }).WhereOr("nickname=?", g.Slice{"name_4"}).Where("id", 3).One() + _, err := db.Model(table).OmitNilWhere().Data(g.Map{ + "id": 1, + "name": "", + }).Save() t.AssertNil(err) - t.AssertGT(len(result), 0) - t.Assert(result["id"].Int(), 2) }) } @@ -3260,315 +2623,6 @@ func Test_Model_Fields_Map_Struct(t *testing.T) { }) } -func Test_Model_WhereIn(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereIn("id", g.Slice{1, 2, 3, 4}).WhereIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 2) - t.Assert(result[0]["id"], 3) - t.Assert(result[1]["id"], 4) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereIn("id", g.Slice{}).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 0) - }) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).OmitEmptyWhere().WhereIn("id", g.Slice{}).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), TableSize) - }) -} - -func Test_Model_WhereNotIn(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereNotIn("id", g.Slice{1, 2, 3, 4}).WhereNotIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 5) - t.Assert(result[0]["id"], 6) - t.Assert(result[1]["id"], 7) - }) -} - -func Test_Model_WhereOrIn(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereOrIn("id", g.Slice{1, 2, 3, 4}).WhereOrIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 5) - t.Assert(result[0]["id"], 1) - t.Assert(result[4]["id"], 5) - }) -} - -func Test_Model_WhereOrNotIn(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereOrNotIn("id", g.Slice{1, 2, 3, 4}).WhereOrNotIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 8) - t.Assert(result[0]["id"], 1) - t.Assert(result[4]["id"], 7) - }) -} - -func Test_Model_WhereBetween(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereBetween("id", 1, 4).WhereBetween("id", 3, 5).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 2) - t.Assert(result[0]["id"], 3) - t.Assert(result[1]["id"], 4) - }) -} - -func Test_Model_WhereNotBetween(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereNotBetween("id", 2, 8).WhereNotBetween("id", 3, 100).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 1) - t.Assert(result[0]["id"], 1) - }) -} - -func Test_Model_WhereOrBetween(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereOrBetween("id", 1, 4).WhereOrBetween("id", 3, 5).OrderDesc("id").All() - t.AssertNil(err) - t.Assert(len(result), 5) - t.Assert(result[0]["id"], 5) - t.Assert(result[4]["id"], 1) - }) -} - -func Test_Model_WhereOrNotBetween(t *testing.T) { - table := createInitTable() - defer dropTable(table) - // db.SetDebug(true) - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereOrNotBetween("id", 1, 4).WhereOrNotBetween("id", 3, 5).OrderDesc("id").All() - t.AssertNil(err) - t.Assert(len(result), 8) - t.Assert(result[0]["id"], 10) - t.Assert(result[4]["id"], 6) - }) -} - -func Test_Model_WhereLike(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereLike("nickname", "name%").OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), TableSize) - t.Assert(result[0]["id"], 1) - t.Assert(result[TableSize-1]["id"], TableSize) - }) -} - -func Test_Model_WhereNotLike(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereNotLike("nickname", "name%").OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 0) - }) -} - -func Test_Model_WhereOrLike(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereOrLike("nickname", "namexxx%").WhereOrLike("nickname", "name%").OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), TableSize) - t.Assert(result[0]["id"], 1) - t.Assert(result[TableSize-1]["id"], TableSize) - }) -} - -func Test_Model_WhereOrNotLike(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereOrNotLike("nickname", "namexxx%").WhereOrNotLike("nickname", "name%").OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), TableSize) - t.Assert(result[0]["id"], 1) - t.Assert(result[TableSize-1]["id"], TableSize) - }) -} - -func Test_Model_WhereNull(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereNull("nickname").WhereNull("passport").OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 0) - }) -} - -func Test_Model_WhereNotNull(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereNotNull("nickname").WhereNotNull("passport").OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), TableSize) - t.Assert(result[0]["id"], 1) - t.Assert(result[TableSize-1]["id"], TableSize) - }) -} - -func Test_Model_WhereOrNull(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereOrNull("nickname").WhereOrNull("passport").OrderAsc("id").OrderRandom().All() - t.AssertNil(err) - t.Assert(len(result), 0) - }) -} - -func Test_Model_WhereOrNotNull(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereOrNotNull("nickname").WhereOrNotNull("passport").OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), TableSize) - t.Assert(result[0]["id"], 1) - t.Assert(result[TableSize-1]["id"], TableSize) - }) -} - -func Test_Model_WhereLT(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereLT("id", 3).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 2) - t.Assert(result[0]["id"], 1) - }) -} - -func Test_Model_WhereLTE(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereLTE("id", 3).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 3) - t.Assert(result[0]["id"], 1) - }) -} - -func Test_Model_WhereGT(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereGT("id", 8).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 2) - t.Assert(result[0]["id"], 9) - }) -} - -func Test_Model_WhereGTE(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereGTE("id", 8).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 3) - t.Assert(result[0]["id"], 8) - }) -} - -func Test_Model_WhereOrLT(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereLT("id", 3).WhereOrLT("id", 4).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 3) - t.Assert(result[0]["id"], 1) - t.Assert(result[2]["id"], 3) - }) -} - -func Test_Model_WhereOrLTE(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereLTE("id", 3).WhereOrLTE("id", 4).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 4) - t.Assert(result[0]["id"], 1) - t.Assert(result[3]["id"], 4) - }) -} - -func Test_Model_WhereOrGT(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereGT("id", 8).WhereOrGT("id", 7).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 3) - t.Assert(result[0]["id"], 8) - }) -} - -func Test_Model_WhereOrGTE(t *testing.T) { - table := createInitTable() - defer dropTable(table) - - gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).WhereGTE("id", 8).WhereOrGTE("id", 7).OrderAsc("id").All() - t.AssertNil(err) - t.Assert(len(result), 4) - t.Assert(result[0]["id"], 7) - }) -} - func Test_Model_Min_Max_Avg_Sum(t *testing.T) { table := createInitTable() defer dropTable(table) @@ -4270,89 +3324,6 @@ func Test_Model_Fields_AutoFilterInJoinStatement(t *testing.T) { }) } -func Test_Model_WherePrefix(t *testing.T) { - var ( - table1 = gtime.TimestampNanoStr() + "_table1" - table2 = gtime.TimestampNanoStr() + "_table2" - ) - createInitTable(table1) - defer dropTable(table1) - createInitTable(table2) - defer dropTable(table2) - - gtest.C(t, func(t *gtest.T) { - r, err := db.Model(table1). - FieldsPrefix(table1, "*"). - LeftJoinOnField(table2, "id"). - WherePrefix(table2, g.Map{ - "id": g.Slice{1, 2}, - }). - Order("id asc").All() - t.AssertNil(err) - t.Assert(len(r), 2) - t.Assert(r[0]["id"], "1") - t.Assert(r[1]["id"], "2") - }) -} - -func Test_Model_WhereOrPrefix(t *testing.T) { - var ( - table1 = gtime.TimestampNanoStr() + "_table1" - table2 = gtime.TimestampNanoStr() + "_table2" - ) - createInitTable(table1) - defer dropTable(table1) - createInitTable(table2) - defer dropTable(table2) - - gtest.C(t, func(t *gtest.T) { - r, err := db.Model(table1). - FieldsPrefix(table1, "*"). - LeftJoinOnField(table2, "id"). - WhereOrPrefix(table1, g.Map{ - "id": g.Slice{1, 2}, - }). - WhereOrPrefix(table2, g.Map{ - "id": g.Slice{8, 9}, - }). - Order("id asc").All() - t.AssertNil(err) - t.Assert(len(r), 4) - t.Assert(r[0]["id"], "1") - t.Assert(r[1]["id"], "2") - t.Assert(r[2]["id"], "8") - t.Assert(r[3]["id"], "9") - }) -} - -func Test_Model_WherePrefixLike(t *testing.T) { - var ( - table1 = gtime.TimestampNanoStr() + "_table1" - table2 = gtime.TimestampNanoStr() + "_table2" - ) - createInitTable(table1) - defer dropTable(table1) - createInitTable(table2) - defer dropTable(table2) - - gtest.C(t, func(t *gtest.T) { - r, err := db.Model(table1). - FieldsPrefix(table1, "*"). - LeftJoinOnField(table2, "id"). - WherePrefix(table1, g.Map{ - "id": g.Slice{1, 2, 3}, - }). - WherePrefix(table2, g.Map{ - "id": g.Slice{3, 4, 5}, - }). - WherePrefixLike(table2, "nickname", "name%"). - Order("id asc").All() - t.AssertNil(err) - t.Assert(len(r), 1) - t.Assert(r[0]["id"], "3") - }) -} - // https://github.com/gogf/gf/issues/1159 func Test_ScanList_NoRecreate_PtrAttribute(t *testing.T) { gtest.C(t, func(t *gtest.T) { diff --git a/contrib/drivers/mysql/mysql_z_unit_model_where_test.go b/contrib/drivers/mysql/mysql_z_unit_model_where_test.go new file mode 100644 index 00000000000..c0007c6885a --- /dev/null +++ b/contrib/drivers/mysql/mysql_z_unit_model_where_test.go @@ -0,0 +1,1244 @@ +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package mysql_test + +import ( + "fmt" + "testing" + + "github.com/gogf/gf/v2/container/gmap" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/test/gtest" + "github.com/gogf/gf/v2/util/gutil" +) + +func Test_Model_Where(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + // string + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id=? and nickname=?", 3, "name_3").One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + + // slice + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(g.Slice{"id", 3}).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(g.Slice{"id", 3, "nickname", "name_3"}).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + + // slice parameter + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id=? and nickname=?", g.Slice{3, "name_3"}).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + // map like + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(g.Map{ + "passport like": "user_1%", + }).Order("id asc").All() + t.AssertNil(err) + t.Assert(len(result), 2) + t.Assert(result[0].GMap().Get("id"), 1) + t.Assert(result[1].GMap().Get("id"), 10) + }) + // map + slice parameter + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(g.Map{ + "id": g.Slice{1, 2, 3}, + "passport": g.Slice{"user_2", "user_3"}, + }).Where("id=? and nickname=?", g.Slice{3, "name_3"}).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(g.Map{ + "id": g.Slice{1, 2, 3}, + "passport": g.Slice{"user_2", "user_3"}, + }).WhereOr("nickname=?", g.Slice{"name_4"}).Where("id", 3).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 2) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id=3", g.Slice{}).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id=?", g.Slice{3}).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id", 3).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id", 3).Where("nickname", "name_3").One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id", 3).Where("nickname", "name_3").One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id", 30).WhereOr("nickname", "name_3").One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id", 30).WhereOr("nickname", "name_3").Where("id>?", 1).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id", 30).WhereOr("nickname", "name_3").Where("id>", 1).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // slice + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id=? AND nickname=?", g.Slice{3, "name_3"}...).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id=? AND nickname=?", g.Slice{3, "name_3"}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("passport like ? and nickname like ?", g.Slice{"user_3", "name_3"}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // map + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(g.Map{"id": 3, "nickname": "name_3"}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // map key operator + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(g.Map{"id>": 1, "id<": 3}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 2) + }) + + // gmap.Map + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(gmap.NewFrom(g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // gmap.Map key operator + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(gmap.NewFrom(g.MapAnyAny{"id>": 1, "id<": 3})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 2) + }) + + // list map + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(gmap.NewListMapFrom(g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // list map key operator + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(gmap.NewListMapFrom(g.MapAnyAny{"id>": 1, "id<": 3})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 2) + }) + + // tree map + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(gmap.NewTreeMapFrom(gutil.ComparatorString, g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // tree map key operator + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(gmap.NewTreeMapFrom(gutil.ComparatorString, g.MapAnyAny{"id>": 1, "id<": 3})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 2) + }) + + // complicated where 1 + gtest.C(t, func(t *gtest.T) { + // db.SetDebug(true) + conditions := g.Map{ + "nickname like ?": "%name%", + "id between ? and ?": g.Slice{1, 3}, + "id > 0": nil, + "create_time > 0": nil, + "id": g.Slice{1, 2, 3}, + } + result, err := db.Model(table).Where(conditions).Order("id asc").All() + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"].Int(), 1) + }) + // complicated where 2 + gtest.C(t, func(t *gtest.T) { + // db.SetDebug(true) + conditions := g.Map{ + "nickname like ?": "%name%", + "id between ? and ?": g.Slice{1, 3}, + "id >= ?": 1, + "create_time > ?": 0, + "id in(?)": g.Slice{1, 2, 3}, + } + result, err := db.Model(table).Where(conditions).Order("id asc").All() + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"].Int(), 1) + }) + // struct, automatic mapping and filtering. + gtest.C(t, func(t *gtest.T) { + type User struct { + Id int + Nickname string + } + result, err := db.Model(table).Where(User{3, "name_3"}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + + result, err = db.Model(table).Where(&User{3, "name_3"}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // slice single + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("id IN(?)", g.Slice{1, 3}).Order("id ASC").All() + t.AssertNil(err) + t.Assert(len(result), 2) + t.Assert(result[0]["id"].Int(), 1) + t.Assert(result[1]["id"].Int(), 3) + }) + // slice + string + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("nickname=? AND id IN(?)", "name_3", g.Slice{1, 3}).Order("id ASC").All() + t.AssertNil(err) + t.Assert(len(result), 1) + t.Assert(result[0]["id"].Int(), 3) + }) + // slice + map + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(g.Map{ + "id": g.Slice{1, 3}, + "nickname": "name_3", + }).Order("id ASC").All() + t.AssertNil(err) + t.Assert(len(result), 1) + t.Assert(result[0]["id"].Int(), 3) + }) + // slice + struct + gtest.C(t, func(t *gtest.T) { + type User struct { + Ids []int `json:"id"` + Nickname string `gconv:"nickname"` + } + result, err := db.Model(table).Where(User{ + Ids: []int{1, 3}, + Nickname: "name_3", + }).Order("id ASC").All() + t.AssertNil(err) + t.Assert(len(result), 1) + t.Assert(result[0]["id"].Int(), 3) + }) +} + +func Test_Model_Option_Where(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + table := createInitTable() + defer dropTable(table) + r, err := db.Model(table).OmitEmpty().Data("nickname", 1).Where(g.Map{"id": 0, "passport": ""}).Where(1).Update() + t.AssertNil(err) + n, _ := r.RowsAffected() + t.Assert(n, TableSize) + }) + + gtest.C(t, func(t *gtest.T) { + table := createInitTable() + defer dropTable(table) + r, err := db.Model(table).OmitEmpty().Data("nickname", 1).Where(g.Map{"id": 1, "passport": ""}).Update() + t.AssertNil(err) + n, _ := r.RowsAffected() + t.Assert(n, 1) + + v, err := db.Model(table).Where("id", 1).Fields("nickname").Value() + t.AssertNil(err) + t.Assert(v.String(), "1") + }) +} + +func Test_Model_Where_MultiSliceArguments(t *testing.T) { + table := createInitTable() + defer dropTable(table) + gtest.C(t, func(t *gtest.T) { + r, err := db.Model(table).Where(g.Map{ + "id": g.Slice{1, 2, 3, 4}, + "passport": g.Slice{"user_2", "user_3", "user_4"}, + "nickname": g.Slice{"name_2", "name_4"}, + "id >= 4": nil, + }).All() + t.AssertNil(err) + t.Assert(len(r), 1) + t.Assert(r[0]["id"], 4) + }) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where(g.Map{ + "id": g.Slice{1, 2, 3}, + "passport": g.Slice{"user_2", "user_3"}, + }).WhereOr("nickname=?", g.Slice{"name_4"}).Where("id", 3).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 2) + }) +} + +func Test_Model_Where_ISNULL_1(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + // db.SetDebug(true) + result, err := db.Model(table).Data("nickname", nil).Where("id", 2).Update() + t.AssertNil(err) + n, _ := result.RowsAffected() + t.Assert(n, 1) + + one, err := db.Model(table).Where("nickname", nil).One() + t.AssertNil(err) + t.Assert(one.IsEmpty(), false) + t.Assert(one["id"], 2) + }) +} + +func Test_Model_Where_ISNULL_2(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + // complicated one. + gtest.C(t, func(t *gtest.T) { + // db.SetDebug(true) + conditions := g.Map{ + "nickname like ?": "%name%", + "id between ? and ?": g.Slice{1, 3}, + "id > 0": nil, + "create_time > 0": nil, + "id": g.Slice{1, 2, 3}, + } + result, err := db.Model(table).Where(conditions).Order("id asc").All() + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"].Int(), 1) + }) +} + +func Test_Model_Where_OmitEmpty(t *testing.T) { + table := createInitTable() + defer dropTable(table) + gtest.C(t, func(t *gtest.T) { + conditions := g.Map{ + "id < 4": "", + } + result, err := db.Model(table).Where(conditions).Order("id desc").All() + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + conditions := g.Map{ + "id < 4": "", + } + result, err := db.Model(table).Where(conditions).OmitEmpty().Order("id desc").All() + t.AssertNil(err) + t.Assert(len(result), 10) + t.Assert(result[0]["id"].Int(), 10) + }) +} + +func Test_Model_Where_GTime(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("create_time>?", gtime.NewFromStr("2010-09-01")).All() + t.AssertNil(err) + t.Assert(len(result), 10) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).Where("create_time>?", *gtime.NewFromStr("2010-09-01")).All() + t.AssertNil(err) + t.Assert(len(result), 10) + }) +} + +func Test_Model_WherePri(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + // primary key + gtest.C(t, func(t *gtest.T) { + one, err := db.Model(table).WherePri(3).One() + t.AssertNil(err) + t.AssertNE(one, nil) + t.Assert(one["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + all, err := db.Model(table).WherePri(g.Slice{3, 9}).Order("id asc").All() + t.AssertNil(err) + t.Assert(len(all), 2) + t.Assert(all[0]["id"].Int(), 3) + t.Assert(all[1]["id"].Int(), 9) + }) + + // string + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id=? and nickname=?", 3, "name_3").One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + // slice parameter + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id=? and nickname=?", g.Slice{3, "name_3"}).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + // map like + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(g.Map{ + "passport like": "user_1%", + }).Order("id asc").All() + t.AssertNil(err) + t.Assert(len(result), 2) + t.Assert(result[0].GMap().Get("id"), 1) + t.Assert(result[1].GMap().Get("id"), 10) + }) + // map + slice parameter + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(g.Map{ + "id": g.Slice{1, 2, 3}, + "passport": g.Slice{"user_2", "user_3"}, + }).Where("id=? and nickname=?", g.Slice{3, "name_3"}).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(g.Map{ + "id": g.Slice{1, 2, 3}, + "passport": g.Slice{"user_2", "user_3"}, + }).WhereOr("nickname=?", g.Slice{"name_4"}).Where("id", 3).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 2) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id=3", g.Slice{}).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id=?", g.Slice{3}).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id", 3).One() + t.AssertNil(err) + t.AssertGT(len(result), 0) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id", 3).WherePri("nickname", "name_3").One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id", 3).Where("nickname", "name_3").One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id", 30).WhereOr("nickname", "name_3").One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id", 30).WhereOr("nickname", "name_3").Where("id>?", 1).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id", 30).WhereOr("nickname", "name_3").Where("id>", 1).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // slice + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id=? AND nickname=?", g.Slice{3, "name_3"}...).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id=? AND nickname=?", g.Slice{3, "name_3"}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("passport like ? and nickname like ?", g.Slice{"user_3", "name_3"}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // map + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(g.Map{"id": 3, "nickname": "name_3"}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // map key operator + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(g.Map{"id>": 1, "id<": 3}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 2) + }) + + // gmap.Map + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(gmap.NewFrom(g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // gmap.Map key operator + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(gmap.NewFrom(g.MapAnyAny{"id>": 1, "id<": 3})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 2) + }) + + // list map + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(gmap.NewListMapFrom(g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // list map key operator + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(gmap.NewListMapFrom(g.MapAnyAny{"id>": 1, "id<": 3})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 2) + }) + + // tree map + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(gmap.NewTreeMapFrom(gutil.ComparatorString, g.MapAnyAny{"id": 3, "nickname": "name_3"})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // tree map key operator + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(gmap.NewTreeMapFrom(gutil.ComparatorString, g.MapAnyAny{"id>": 1, "id<": 3})).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 2) + }) + + // complicated where 1 + gtest.C(t, func(t *gtest.T) { + // db.SetDebug(true) + conditions := g.Map{ + "nickname like ?": "%name%", + "id between ? and ?": g.Slice{1, 3}, + "id > 0": nil, + "create_time > 0": nil, + "id": g.Slice{1, 2, 3}, + } + result, err := db.Model(table).WherePri(conditions).Order("id asc").All() + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"].Int(), 1) + }) + // complicated where 2 + gtest.C(t, func(t *gtest.T) { + // db.SetDebug(true) + conditions := g.Map{ + "nickname like ?": "%name%", + "id between ? and ?": g.Slice{1, 3}, + "id >= ?": 1, + "create_time > ?": 0, + "id in(?)": g.Slice{1, 2, 3}, + } + result, err := db.Model(table).WherePri(conditions).Order("id asc").All() + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"].Int(), 1) + }) + // struct + gtest.C(t, func(t *gtest.T) { + type User struct { + Id int `json:"id"` + Nickname string `gconv:"nickname"` + } + result, err := db.Model(table).WherePri(User{3, "name_3"}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + + result, err = db.Model(table).WherePri(&User{3, "name_3"}).One() + t.AssertNil(err) + t.Assert(result["id"].Int(), 3) + }) + // slice single + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("id IN(?)", g.Slice{1, 3}).Order("id ASC").All() + t.AssertNil(err) + t.Assert(len(result), 2) + t.Assert(result[0]["id"].Int(), 1) + t.Assert(result[1]["id"].Int(), 3) + }) + // slice + string + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri("nickname=? AND id IN(?)", "name_3", g.Slice{1, 3}).Order("id ASC").All() + t.AssertNil(err) + t.Assert(len(result), 1) + t.Assert(result[0]["id"].Int(), 3) + }) + // slice + map + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WherePri(g.Map{ + "id": g.Slice{1, 3}, + "nickname": "name_3", + }).Order("id ASC").All() + t.AssertNil(err) + t.Assert(len(result), 1) + t.Assert(result[0]["id"].Int(), 3) + }) + // slice + struct + gtest.C(t, func(t *gtest.T) { + type User struct { + Ids []int `json:"id"` + Nickname string `gconv:"nickname"` + } + result, err := db.Model(table).WherePri(User{ + Ids: []int{1, 3}, + Nickname: "name_3", + }).Order("id ASC").All() + t.AssertNil(err) + t.Assert(len(result), 1) + t.Assert(result[0]["id"].Int(), 3) + }) +} + +func Test_Model_WhereIn(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereIn("id", g.Slice{1, 2, 3, 4}).WhereIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 2) + t.Assert(result[0]["id"], 3) + t.Assert(result[1]["id"], 4) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereIn("id", g.Slice{}).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 0) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).OmitEmptyWhere().WhereIn("id", g.Slice{}).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), TableSize) + }) +} + +func Test_Model_WhereNotIn(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereNotIn("id", g.Slice{1, 2, 3, 4}).WhereNotIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 5) + t.Assert(result[0]["id"], 6) + t.Assert(result[1]["id"], 7) + }) +} + +func Test_Model_WhereOrIn(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereOrIn("id", g.Slice{1, 2, 3, 4}).WhereOrIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 5) + t.Assert(result[0]["id"], 1) + t.Assert(result[4]["id"], 5) + }) +} + +func Test_Model_WhereOrNotIn(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereOrNotIn("id", g.Slice{1, 2, 3, 4}).WhereOrNotIn("id", g.Slice{3, 4, 5}).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 8) + t.Assert(result[0]["id"], 1) + t.Assert(result[4]["id"], 7) + }) +} + +func Test_Model_WhereBetween(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereBetween("id", 1, 4).WhereBetween("id", 3, 5).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 2) + t.Assert(result[0]["id"], 3) + t.Assert(result[1]["id"], 4) + }) +} + +func Test_Model_WhereNotBetween(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereNotBetween("id", 2, 8).WhereNotBetween("id", 3, 100).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 1) + t.Assert(result[0]["id"], 1) + }) +} + +func Test_Model_WhereOrBetween(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereOrBetween("id", 1, 4).WhereOrBetween("id", 3, 5).OrderDesc("id").All() + t.AssertNil(err) + t.Assert(len(result), 5) + t.Assert(result[0]["id"], 5) + t.Assert(result[4]["id"], 1) + }) +} + +func Test_Model_WhereOrNotBetween(t *testing.T) { + table := createInitTable() + defer dropTable(table) + // db.SetDebug(true) + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereOrNotBetween("id", 1, 4).WhereOrNotBetween("id", 3, 5).OrderDesc("id").All() + t.AssertNil(err) + t.Assert(len(result), 8) + t.Assert(result[0]["id"], 10) + t.Assert(result[4]["id"], 6) + }) +} + +func Test_Model_WhereLike(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereLike("nickname", "name%").OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), TableSize) + t.Assert(result[0]["id"], 1) + t.Assert(result[TableSize-1]["id"], TableSize) + }) +} + +func Test_Model_WhereNotLike(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereNotLike("nickname", "name%").OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 0) + }) +} + +func Test_Model_WhereOrLike(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereOrLike("nickname", "namexxx%").WhereOrLike("nickname", "name%").OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), TableSize) + t.Assert(result[0]["id"], 1) + t.Assert(result[TableSize-1]["id"], TableSize) + }) +} + +func Test_Model_WhereOrNotLike(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereOrNotLike("nickname", "namexxx%").WhereOrNotLike("nickname", "name%").OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), TableSize) + t.Assert(result[0]["id"], 1) + t.Assert(result[TableSize-1]["id"], TableSize) + }) +} + +func Test_Model_WhereNull(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereNull("nickname").WhereNull("passport").OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 0) + }) +} + +func Test_Model_WhereNotNull(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereNotNull("nickname").WhereNotNull("passport").OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), TableSize) + t.Assert(result[0]["id"], 1) + t.Assert(result[TableSize-1]["id"], TableSize) + }) +} + +func Test_Model_WhereOrNull(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereOrNull("nickname").WhereOrNull("passport").OrderAsc("id").OrderRandom().All() + t.AssertNil(err) + t.Assert(len(result), 0) + }) +} + +func Test_Model_WhereOrNotNull(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereOrNotNull("nickname").WhereOrNotNull("passport").OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), TableSize) + t.Assert(result[0]["id"], 1) + t.Assert(result[TableSize-1]["id"], TableSize) + }) +} + +func Test_Model_WhereLT(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereLT("id", 3).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 2) + t.Assert(result[0]["id"], 1) + }) +} + +func Test_Model_WhereLTE(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereLTE("id", 3).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"], 1) + }) +} + +func Test_Model_WhereGT(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereGT("id", 8).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 2) + t.Assert(result[0]["id"], 9) + }) +} + +func Test_Model_WhereGTE(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereGTE("id", 8).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"], 8) + }) +} + +func Test_Model_WhereOrLT(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereLT("id", 3).WhereOrLT("id", 4).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"], 1) + t.Assert(result[2]["id"], 3) + }) +} + +func Test_Model_WhereOrLTE(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereLTE("id", 3).WhereOrLTE("id", 4).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 4) + t.Assert(result[0]["id"], 1) + t.Assert(result[3]["id"], 4) + }) +} + +func Test_Model_WhereOrGT(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereGT("id", 8).WhereOrGT("id", 7).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"], 8) + }) +} + +func Test_Model_WhereOrGTE(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).WhereGTE("id", 8).WhereOrGTE("id", 7).OrderAsc("id").All() + t.AssertNil(err) + t.Assert(len(result), 4) + t.Assert(result[0]["id"], 7) + }) +} + +func Test_Model_WherePrefix(t *testing.T) { + var ( + table1 = gtime.TimestampNanoStr() + "_table1" + table2 = gtime.TimestampNanoStr() + "_table2" + ) + createInitTable(table1) + defer dropTable(table1) + createInitTable(table2) + defer dropTable(table2) + + gtest.C(t, func(t *gtest.T) { + r, err := db.Model(table1). + FieldsPrefix(table1, "*"). + LeftJoinOnField(table2, "id"). + WherePrefix(table2, g.Map{ + "id": g.Slice{1, 2}, + }). + Order("id asc").All() + t.AssertNil(err) + t.Assert(len(r), 2) + t.Assert(r[0]["id"], "1") + t.Assert(r[1]["id"], "2") + }) +} + +func Test_Model_WhereOrPrefix(t *testing.T) { + var ( + table1 = gtime.TimestampNanoStr() + "_table1" + table2 = gtime.TimestampNanoStr() + "_table2" + ) + createInitTable(table1) + defer dropTable(table1) + createInitTable(table2) + defer dropTable(table2) + + gtest.C(t, func(t *gtest.T) { + r, err := db.Model(table1). + FieldsPrefix(table1, "*"). + LeftJoinOnField(table2, "id"). + WhereOrPrefix(table1, g.Map{ + "id": g.Slice{1, 2}, + }). + WhereOrPrefix(table2, g.Map{ + "id": g.Slice{8, 9}, + }). + Order("id asc").All() + t.AssertNil(err) + t.Assert(len(r), 4) + t.Assert(r[0]["id"], "1") + t.Assert(r[1]["id"], "2") + t.Assert(r[2]["id"], "8") + t.Assert(r[3]["id"], "9") + }) +} + +func Test_Model_WherePrefixLike(t *testing.T) { + var ( + table1 = gtime.TimestampNanoStr() + "_table1" + table2 = gtime.TimestampNanoStr() + "_table2" + ) + createInitTable(table1) + defer dropTable(table1) + createInitTable(table2) + defer dropTable(table2) + + gtest.C(t, func(t *gtest.T) { + r, err := db.Model(table1). + FieldsPrefix(table1, "*"). + LeftJoinOnField(table2, "id"). + WherePrefix(table1, g.Map{ + "id": g.Slice{1, 2, 3}, + }). + WherePrefix(table2, g.Map{ + "id": g.Slice{3, 4, 5}, + }). + WherePrefixLike(table2, "nickname", "name%"). + Order("id asc").All() + t.AssertNil(err) + t.Assert(len(r), 1) + t.Assert(r[0]["id"], "3") + }) +} + +func Test_Model_WhereExists(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + // Create another table for exists subquery + table2 := "table2_" + gtime.TimestampNanoStr() + sqlCreate := fmt.Sprintf(` +CREATE TABLE %s ( + id int(10) unsigned NOT NULL AUTO_INCREMENT, + uid int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + `, table2) + if _, err := db.Exec(ctx, sqlCreate); err != nil { + t.AssertNil(err) + } + defer dropTable(table2) + + // Insert test data + _, err := db.Model(table2).Insert(g.List{ + {"uid": 1}, + {"uid": 2}, + }) + t.AssertNil(err) + + // Test WhereExists with subquery + subQuery1 := db.Model(table2). + Fields("id"). + Where("uid = ?", db.Raw("user.id")) + + r, err := db.Model(table + " as user"). + WhereExists(subQuery1). + Order("id asc"). + All() + t.AssertNil(err) + t.Assert(len(r), 2) + t.Assert(r[0]["id"].Int(), 1) + t.Assert(r[1]["id"].Int(), 2) + + // Test WhereNotExists + r, err = db.Model(table + " as user"). + WhereNotExists(subQuery1). + Order("id asc"). + All() + t.AssertNil(err) + t.Assert(len(r), 8) + t.Assert(r[0]["id"].Int(), 3) + + // Test WhereExists with empty result + subQuery2 := db.Model(table2). + Fields("id"). + Where("uid = -1") + r, err = db.Model(table). + WhereExists(subQuery2). + All() + t.AssertNil(err) + t.Assert(len(r), 0) + + // Test WhereNotExists with all results + r, err = db.Model(table). + WhereNotExists(subQuery2). + All() + t.AssertNil(err) + t.Assert(len(r), 10) + + // Test combination of Where and WhereExists + r, err = db.Model(table+" as user"). + Where("id>?", 3). + WhereExists(subQuery1). + Order("id asc"). + All() + t.AssertNil(err) + t.Assert(len(r), 0) + + // Test WhereExists with complex subquery + subQuery3 := db.Model(table2). + Fields("id"). + Where("uid = ?", db.Raw("user.id")). + Where("id > ?", 0) + r, err = db.Model(table + " as user"). + WhereExists(subQuery3). + Order("id asc"). + All() + t.AssertNil(err) + t.Assert(len(r), 2) + t.Assert(r[0]["id"].Int(), 1) + t.Assert(r[1]["id"].Int(), 2) + + // Test WhereExists with Fields + r, err = db.Model(table + " as user"). + Fields("id,passport"). + WhereExists(subQuery1). + Order("id asc"). + All() + t.AssertNil(err) + t.Assert(len(r), 2) + t.Assert(r[0]["id"].Int(), 1) + t.Assert(r[0]["passport"].String(), "user_1") + + // Test WhereExists with Group + r, err = db.Model(table + " as user"). + WhereExists(subQuery1). + Group("id"). + Order("id asc"). + All() + t.AssertNil(err) + t.Assert(len(r), 2) + t.Assert(r[0]["id"].Int(), 1) + t.Assert(r[1]["id"].Int(), 2) + + // Test WhereExists with Having + r, err = db.Model(table+" as user"). + WhereExists(subQuery1). + Group("id"). + Having("id > ?", 1). + Order("id asc"). + All() + t.AssertNil(err) + t.Assert(len(r), 1) + t.Assert(r[0]["id"].Int(), 2) + }) +} + +func Test_Model_WhereNotExists(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + // Create another table for exists subquery + table2 := "table2_" + gtime.TimestampNanoStr() + sqlCreate := fmt.Sprintf(` +CREATE TABLE %s ( + id int(10) unsigned NOT NULL AUTO_INCREMENT, + uid int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + `, table2) + if _, err := db.Exec(ctx, sqlCreate); err != nil { + t.AssertNil(err) + } + defer dropTable(table2) + + // Insert test data + _, err := db.Model(table2).Insert(g.List{ + {"uid": 1}, + {"uid": 2}, + }) + t.AssertNil(err) + + // Test WhereNotExists with subquery + subQuery1 := db.Model(table2). + Fields("id"). + Where("uid = ?", db.Raw("user.id")) + + r, err := db.Model(table + " as user"). + WhereNotExists(subQuery1). + Order("id asc"). + All() + t.AssertNil(err) + t.Assert(len(r), 8) // Should be 8 because records with id 1 and 2 exist in table2 + t.Assert(r[0]["id"].Int(), 3) // First record should be id 3 + t.Assert(r[1]["id"].Int(), 4) // Second record should be id 4 + + // Test WhereNotExists with empty subquery + subQuery2 := db.Model(table2). + Fields("id"). + Where("uid = -1") // This condition will return no results + r, err = db.Model(table + " as user"). + WhereNotExists(subQuery2). + Order("id asc"). + All() + t.AssertNil(err) + t.Assert(len(r), 10) // Should return all records when subquery is empty + + // Test WhereNotExists with complex condition + subQuery3 := db.Model(table2). + Fields("id"). + Where("uid = ?", db.Raw("user.id")). + Where("id > ?", 1) + r, err = db.Model(table + " as user"). + WhereNotExists(subQuery3). + Order("id asc"). + All() + t.AssertNil(err) + t.Assert(len(r), 9) // Should only exclude the record with id 2 + t.Assert(r[0]["id"].Int(), 1) // Should include id 1 + }) +} diff --git a/database/gdb/gdb_model_builder_where.go b/database/gdb/gdb_model_builder_where.go index 4ae43f856a8..7b695b96b64 100644 --- a/database/gdb/gdb_model_builder_where.go +++ b/database/gdb/gdb_model_builder_where.go @@ -159,3 +159,13 @@ func (b *WhereBuilder) WhereNotNull(columns ...string) *WhereBuilder { } return builder } + +// WhereExists builds `EXISTS (subQuery)` statement. +func (b *WhereBuilder) WhereExists(subQuery *Model) *WhereBuilder { + return b.Wheref(`EXISTS (?)`, subQuery) +} + +// WhereNotExists builds `NOT EXISTS (subQuery)` statement. +func (b *WhereBuilder) WhereNotExists(subQuery *Model) *WhereBuilder { + return b.Wheref(`NOT EXISTS (?)`, subQuery) +} diff --git a/database/gdb/gdb_model_where.go b/database/gdb/gdb_model_where.go index 96ea722b6b3..067a9bcadb9 100644 --- a/database/gdb/gdb_model_where.go +++ b/database/gdb/gdb_model_where.go @@ -117,3 +117,13 @@ func (m *Model) WhereNotIn(column string, in interface{}) *Model { func (m *Model) WhereNotNull(columns ...string) *Model { return m.callWhereBuilder(m.whereBuilder.WhereNotNull(columns...)) } + +// WhereExists builds `EXISTS (subQuery)` statement. +func (m *Model) WhereExists(subQuery *Model) *Model { + return m.callWhereBuilder(m.whereBuilder.WhereExists(subQuery)) +} + +// WhereNotExists builds `NOT EXISTS (subQuery)` statement. +func (m *Model) WhereNotExists(subQuery *Model) *Model { + return m.callWhereBuilder(m.whereBuilder.WhereNotExists(subQuery)) +}