diff --git a/contrib/drivers/clickhouse/clickhouse_db_test.go b/contrib/drivers/clickhouse/clickhouse_db_test.go new file mode 100644 index 000000000..977cdf7de --- /dev/null +++ b/contrib/drivers/clickhouse/clickhouse_db_test.go @@ -0,0 +1,323 @@ +// 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 clickhouse_test + +import ( + "fmt" + "testing" + + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/test/gtest" +) + +func Test_DB_Ping(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + err1 := db.PingMaster() + err2 := db.PingSlave() + t.Assert(err1, nil) + t.Assert(err2, nil) + }) +} + +func Test_DB_Query(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + _, err := db.Query(ctx, "SELECT ?", 1) + t.AssertNil(err) + + _, err = db.Query(ctx, "SELECT ?+?", 1, 2) + t.AssertNil(err) + + _, err = db.Query(ctx, "SELECT ?+?", g.Slice{1, 2}) + t.AssertNil(err) + + _, err = db.Query(ctx, "ERROR") + t.AssertNE(err, nil) + }) +} + +func Test_DB_Exec(t *testing.T) { + table := createTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + _, err := db.Exec(ctx, fmt.Sprintf("select * from %s ", table)) + t.AssertNil(err) + }) +} + +func Test_DB_Insert(t *testing.T) { + table := createTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + _, err := db.Insert(ctx, table, g.Map{ + "id": uint64(1), + "passport": "t1", + "password": "25d55ad283aa400af464c76d713c07ad", + "nickname": "T1", + "create_time": gtime.Now(), + }) + t.AssertNil(err) + answer, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 1) + t.AssertNil(err) + t.Assert(len(answer), 1) + t.Assert(answer[0]["passport"], "t1") + t.Assert(answer[0]["password"], "25d55ad283aa400af464c76d713c07ad") + t.Assert(answer[0]["nickname"], "T1") + + // normal map + _, err = db.Insert(ctx, table, g.Map{ + "id": uint64(2), + "passport": "t2", + "password": "25d55ad283aa400af464c76d713c07ad", + "nickname": "name_2", + "create_time": gtime.Now(), + }) + t.AssertNil(err) + + answer, err = db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 2) + t.AssertNil(err) + t.Assert(len(answer), 1) + t.Assert(answer[0]["passport"], "t2") + t.Assert(answer[0]["password"], "25d55ad283aa400af464c76d713c07ad") + t.Assert(answer[0]["nickname"], "name_2") + }) +} + +func Test_DB_Save(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + createTable("t_user") + defer dropTable("t_user") + + i := 10 + data := g.Map{ + "id": i, + "passport": fmt.Sprintf(`t%d`, i), + "password": fmt.Sprintf(`p%d`, i), + "nickname": fmt.Sprintf(`T%d`, i), + "create_time": gtime.Now(), + } + _, err := db.Save(ctx, "t_user", data, 10) + gtest.AssertNE(err, nil) + }) +} + +func Test_DB_Replace(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + createTable("t_user") + defer dropTable("t_user") + + i := 10 + data := g.Map{ + "id": i, + "passport": fmt.Sprintf(`t%d`, i), + "password": fmt.Sprintf(`p%d`, i), + "nickname": fmt.Sprintf(`T%d`, i), + "create_time": gtime.Now(), + } + _, err := db.Replace(ctx, "t_user", data, 10) + gtest.AssertNE(err, nil) + }) +} + +func Test_DB_GetAll(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 1) + t.AssertNil(err) + t.Assert(len(result), 1) + t.Assert(result[0]["id"].Int(), 1) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), g.Slice{1}) + t.AssertNil(err) + t.Assert(len(result), 1) + t.Assert(result[0]["id"].Int(), 1) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id in(?)", table), g.Slice{1, 2, 3}) + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"].Int(), 1) + t.Assert(result[1]["id"].Int(), 2) + t.Assert(result[2]["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id in(?,?,?)", table), g.Slice{1, 2, 3}) + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"].Int(), 1) + t.Assert(result[1]["id"].Int(), 2) + t.Assert(result[2]["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id in(?,?,?)", table), g.Slice{1, 2, 3}...) + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"].Int(), 1) + t.Assert(result[1]["id"].Int(), 2) + t.Assert(result[2]["id"].Int(), 3) + }) + gtest.C(t, func(t *gtest.T) { + result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id>=? AND id <=?", table), g.Slice{1, 3}) + t.AssertNil(err) + t.Assert(len(result), 3) + t.Assert(result[0]["id"].Int(), 1) + t.Assert(result[1]["id"].Int(), 2) + t.Assert(result[2]["id"].Int(), 3) + }) +} + +func Test_DB_GetOne(t *testing.T) { + table := createTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + type User struct { + Id uint64 + Passport string + Password string + Nickname string + CreateTime *gtime.Time + } + data := User{ + Id: uint64(1), + Passport: "user_1", + Password: "pass_1", + Nickname: "name_1", + CreateTime: gtime.Now(), + } + _, err := db.Insert(ctx, table, data) + t.AssertNil(err) + + one, err := db.GetOne(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 1) + t.AssertNil(err) + t.Assert(one["passport"], data.Passport) + t.Assert(one["create_time"], data.CreateTime) + t.Assert(one["nickname"], data.Nickname) + }) +} + +func Test_DB_GetValue(t *testing.T) { + table := createInitTable() + defer dropTable(table) + gtest.C(t, func(t *gtest.T) { + value, err := db.GetValue(ctx, fmt.Sprintf("SELECT id FROM %s WHERE passport=?", table), "user_3") + t.AssertNil(err) + t.Assert(value.Int(), 3) + }) +} + +func Test_DB_GetCount(t *testing.T) { + table := createInitTable() + defer dropTable(table) + gtest.C(t, func(t *gtest.T) { + count, err := db.GetCount(ctx, fmt.Sprintf("SELECT * FROM %s", table)) + t.AssertNil(err) + t.Assert(count, TableSize) + }) +} + +func Test_DB_GetArray(t *testing.T) { + table := createInitTable() + defer dropTable(table) + gtest.C(t, func(t *gtest.T) { + array, err := db.GetArray(ctx, fmt.Sprintf("SELECT password FROM %s", table)) + t.AssertNil(err) + arrays := make([]string, 0) + for i := 1; i <= TableSize; i++ { + arrays = append(arrays, fmt.Sprintf(`pass_%d`, i)) + } + t.Assert(array, arrays) + }) +} + +func Test_DB_GetScan(t *testing.T) { + table := createInitTable() + defer dropTable(table) + gtest.C(t, func(t *gtest.T) { + type User struct { + Id int + Passport string + Password string + NickName string + CreateTime gtime.Time + } + user := new(User) + err := db.GetScan(ctx, user, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 3) + t.AssertNil(err) + t.Assert(user.NickName, "name_3") + }) +} + +func Test_DB_Update(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + _, err := db.Update(ctx, table, "password='123456'", "id=3") + t.AssertNE(err, nil) + + one, err := db.Model(table).Where("id", 3).One() + t.AssertNil(err) + t.AssertNE(one["password"].String(), "123456") + + t.Assert(one["id"].Int(), 3) + t.Assert(one["passport"].String(), "user_3") + t.Assert(one["nickname"].String(), "name_3") + }) +} + +func Test_DB_Delete(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + _, err := db.Delete(ctx, table, "id>3") + t.AssertNE(err, nil) + + }) +} + +func Test_DB_Tables(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + tables := []string{"t_user1", "pop", "haha"} + + for _, v := range tables { + createTable(v) + } + + result, err := db.Tables(ctx) + gtest.Assert(err, nil) + + for i := 0; i < len(tables); i++ { + find := false + for j := 0; j < len(result); j++ { + if tables[i] == result[j] { + find = true + break + } + } + gtest.AssertEQ(find, true) + } + }) +} + +func Test_DB_TableFields(t *testing.T) { + table := createInitTable("user") + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + field, err := db.TableFields(ctx, "user") + gtest.AssertNil(err) + gtest.AssertEQ(len(field), 5) + gtest.AssertNQ(field, nil) + }) +} diff --git a/contrib/drivers/clickhouse/clickhouse_init_test.go b/contrib/drivers/clickhouse/clickhouse_init_test.go new file mode 100644 index 000000000..ab775d818 --- /dev/null +++ b/contrib/drivers/clickhouse/clickhouse_init_test.go @@ -0,0 +1,114 @@ +// 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 clickhouse_test + +import ( + "context" + "fmt" + + "github.com/gogf/gf/v2/container/garray" + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/test/gtest" +) + +const ( + TableSize = 10 + TableName = "user" +) + +var ( + db gdb.DB + ctx = context.TODO() +) + +func init() { + node := gdb.ConfigNode{ + Host: "127.0.0.1", + Port: "9000", + User: "default", + Name: "default", + Type: "clickhouse", + Debug: false, + } + var err error + db, err = gdb.New(node) + gtest.AssertNil(err) + gtest.AssertNil(db.PingMaster()) +} + +// create table +func createTable(table ...string) string { + return createTableWithDb(db, table...) +} + +// create table and insert initial data +func createInitTable(table ...string) string { + return createInitTableWithDb(db, table...) +} + +func dropTable(table string) { + dropTableWithDb(db, table) +} + +func createTableWithDb(db gdb.DB, table ...string) (name string) { + if len(table) > 0 { + name = table[0] + } else { + name = fmt.Sprintf(`%s_%d`, TableName, gtime.TimestampNano()) + } + dropTableWithDb(db, name) + + _, err := db.Exec(ctx, fmt.Sprintf(` + CREATE TABLE %s ( + id bigint unsigned NOT NULL, + passport varchar(45), + password char(32) NOT NULL, + nickname varchar(45) NOT NULL, + create_time datetime NOT NULL, + PRIMARY KEY (id) + ) ENGINE = MergeTree() + ORDER BY id ;`, + name, + )) + if err != nil { + gtest.Fatal(err) + } + + return +} + +func createInitTableWithDb(db gdb.DB, table ...string) (name string) { + name = createTableWithDb(db, table...) + array := garray.New(true) + for i := 1; i <= TableSize; i++ { + array.Append(g.Map{ + "id": uint64(i), + "passport": fmt.Sprintf(`user_%d`, i), + "password": fmt.Sprintf(`pass_%d`, i), + "nickname": fmt.Sprintf(`name_%d`, i), + "create_time": gtime.Now(), + }) + } + + result, err := db.Insert(ctx, name, array.Slice()) + gtest.AssertNil(err) + + if result != nil { + n, e := result.RowsAffected() + gtest.Assert(e, nil) + gtest.Assert(n, TableSize) + } + return +} + +func dropTableWithDb(db gdb.DB, table string) { + if _, err := db.Exec(ctx, fmt.Sprintf("DROP TABLE IF EXISTS `%s`", table)); err != nil { + gtest.Error(err) + } +} diff --git a/contrib/drivers/clickhouse/clickhouse_model_test.go b/contrib/drivers/clickhouse/clickhouse_model_test.go new file mode 100644 index 000000000..567a69d13 --- /dev/null +++ b/contrib/drivers/clickhouse/clickhouse_model_test.go @@ -0,0 +1,321 @@ +// 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 clickhouse_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/gogf/gf/v2/database/gdb" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/test/gtest" +) + +func Test_New(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + node := gdb.ConfigNode{ + Host: "127.0.0.1", + Port: "9000", + User: "default", + Name: "default", + Type: "clickhouse", + Debug: false, + } + newDb, err := gdb.New(node) + t.AssertNil(err) + value, err := newDb.GetValue(ctx, `select 1`) + t.AssertNil(err) + t.Assert(value, `1`) + t.AssertNil(newDb.Close(ctx)) + }) +} + +func Test_Model_Raw(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + count, err := db.Model(table).Raw(fmt.Sprintf("select id from %s ", table)).Count() + t.Assert(count, 10) + t.AssertNil(err) + }) + + gtest.C(t, func(t *gtest.T) { + model := db.Model(table) + result, err := model.Data(g.Map{ + "id": gdb.Raw("1+5"), + "passport": "port_1", + "password": "pass_1", + "nickname": "name_1", + }).Insert() + t.Assert(strings.Contains(err.Error(), "converting gdb.Raw to UInt64 is unsupported"), true) + + t.AssertNil(result) + }) +} + +func Test_Model_Insert(t *testing.T) { + table := createTable() + defer dropTable(table) + gtest.C(t, func(t *gtest.T) { + user := db.Model(table) + _, err := user.Data(g.Map{ + "id": uint64(1), + "uid": 1, + "passport": "t1", + "password": "25d55ad283aa400af464c76d713c07ad", + "nickname": "name_1", + "create_time": gtime.Now(), + }).Insert() + t.AssertNil(err) + + _, err = db.Model(table).Data(g.Map{ + "id": uint64(2), + "uid": "2", + "passport": "t2", + "password": "25d55ad283aa400af464c76d713c07ad", + "nickname": "name_2", + "create_time": gtime.Now(), + }).Insert() + t.AssertNil(err) + + type User struct { + Id uint64 `gconv:"id"` + Uid int `gconv:"uid"` + Passport string `json:"passport"` + Password string `gconv:"password"` + Nickname string `gconv:"nickname"` + CreateTime *gtime.Time `json:"create_time"` + } + // Model inserting. + _, err = db.Model(table).Data(User{ + Id: 3, + Uid: 3, + Passport: "t3", + Password: "25d55ad283aa400af464c76d713c07ad", + Nickname: "name_3", + CreateTime: gtime.Now(), + }).Insert() + t.AssertNil(err) + + value, err := db.Model(table).Fields("passport").Where("id=3").Value() //model value + t.AssertNil(err) + t.Assert(value.String(), "t3") + + _, err = db.Model(table).Data(&User{ + Id: 4, + Uid: 4, + Passport: "t4", + Password: "25d55ad283aa400af464c76d713c07ad", + Nickname: "T4", + CreateTime: gtime.Now(), + }).Insert() + t.AssertNil(err) + + value, err = db.Model(table).Fields("passport").Where("id=4").Value() + t.AssertNil(err) + t.Assert(value.String(), "t4") + + _, err = db.Model(table).Where("id>?", 1).Delete() //model delete + t.AssertNil(err) + + }) +} + +func Test_Model_One(t *testing.T) { + table := createTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + type User struct { + Id uint64 + Passport string + Password string + Nickname string + CreateTime *gtime.Time + } + data := User{ + Id: 1, + Passport: "user_1", + Password: "pass_1", + Nickname: "name_1", + CreateTime: gtime.Now(), + } + _, err := db.Model(table).Data(data).Insert() + t.AssertNil(err) + + one, err := db.Model(table).WherePri(1).One() //model one + t.AssertNil(err) + t.Assert(one["passport"], data.Passport) + t.Assert(one["create_time"], data.CreateTime) + t.Assert(one["nickname"], data.Nickname) + }) +} + +func Test_Model_All(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + result, err := db.Model(table).All() + t.AssertNil(err) + t.Assert(len(result), TableSize) + }) +} + +func Test_Model_Delete(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + _, err := db.Model(table).Where("id", "2").Delete() + t.AssertNil(err) + + }) +} + +func Test_Model_Update(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + _, err := db.Model(table).Where("passport='user_3'").Update() + t.AssertEQ(err.Error(), "updating table with empty data") + }) + + // Update + Fields(string) + gtest.C(t, func(t *gtest.T) { + _, err := db.Model(table).Fields("passport").Data(g.Map{ + "passport": "user_44", + "none": "none", + }).Where("passport='user_4'").Update() + t.AssertNil(err) + + _, err = db.Model(table).Where("passport='user_44'").One() + t.AssertNil(err) + }) +} + +func Test_Model_Array(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + all, err := db.Model(table).Where("id", g.Slice{1, 2, 3}).All() + t.AssertNil(err) + t.Assert(all.Array("id"), g.Slice{1, 2, 3}) + t.Assert(all.Array("nickname"), g.Slice{"name_1", "name_2", "name_3"}) + }) + gtest.C(t, func(t *gtest.T) { + array, err := db.Model(table).Fields("nickname").Where("id", g.Slice{1, 2, 3}).Array() + t.AssertNil(err) + t.Assert(array, g.Slice{"name_1", "name_2", "name_3"}) + }) + gtest.C(t, func(t *gtest.T) { + array, err := db.Model(table).Array("nickname", "id", g.Slice{1, 2, 3}) + t.AssertNil(err) + t.Assert(array, g.Slice{"name_1", "name_2", "name_3"}) + }) +} + +func Test_Model_Scan(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + type User struct { + Id uint64 + Passport string + Password string + NickName string + CreateTime gtime.Time + } + gtest.C(t, func(t *gtest.T) { + var users []User + err := db.Model(table).Scan(&users) + t.AssertNil(err) + t.Assert(len(users), TableSize) + }) +} + +func Test_Model_Count(t *testing.T) { + table := createInitTable() + defer dropTable(table) + gtest.C(t, func(t *gtest.T) { + count, err := db.Model(table).Count() + t.AssertNil(err) + t.Assert(count, TableSize) + }) + gtest.C(t, func(t *gtest.T) { + count, err := db.Model(table).FieldsEx("id").Where("id>8").Count() + t.AssertNil(err) + t.Assert(count, 2) + }) +} + +func Test_Model_Where(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + // 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) + }) + + // 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) + }) +} + +func Test_Model_Sav(t *testing.T) { + table := createTable() + defer dropTable(table) + gtest.C(t, func(t *gtest.T) { + _, err := db.Model(table).Data(g.Map{ + "id": uint64(1), + "passport": "t111", + "password": "25d55ad283aa400af464c76d713c07ad", + "nickname": "T111", + "create_time": gtime.Now(), + }).Save() + t.AssertNil(err) + }) +} + +func Test_Model_Replace(t *testing.T) { + table := createTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + _, err := db.Model(table).Data(g.Map{ + "id": uint64(1), + "passport": "t11", + "password": "25d55ad283aa400af464c76d713c07ad", + "nickname": "T11", + "create_time": gtime.Now(), + }).Replace() + t.AssertNil(err) + }) +}