mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
This pull request introduces significant improvements to the handling of the `Replace` and `Save` operations for multiple database drivers, especially for MSSQL and PostgreSQL. The changes ensure that these operations now auto-detect primary keys when conflict columns are not explicitly provided, improving usability and aligning behavior across drivers. Additionally, the pull request updates related tests to reflect these enhancements and includes some minor documentation and code cleanup. **Key changes:** ### Enhanced Replace/Save Logic for Database Drivers * **MSSQL Driver:** - `Replace` and `Save` operations now auto-detect primary keys if `OnConflict` is not specified, using the `MERGE` statement for upsert functionality. If no primary key is found in the data, a detailed error is returned. [[1]](diffhunk://#diff-87815aa559a927e2de09bd05148f9841dfc06a1b5f3ecc5e3d5fcb80323a87f8L23-R61) [[2]](diffhunk://#diff-87815aa559a927e2de09bd05148f9841dfc06a1b5f3ecc5e3d5fcb80323a87f8L43-L59) - Updated tests to verify that `Replace` correctly updates or inserts records, and that missing conflict columns are properly handled. [[1]](diffhunk://#diff-bdbde9d7d6ee14c795343767b414740c4396f4dd3e97788b1f9d4e615405a42dL141-R151) [[2]](diffhunk://#diff-26338e93e473300b1313936eb0f6826546473793442f24715fa294b595f7a805L2661-R2707) * **PostgreSQL Driver:** - Similar to MSSQL, `Replace` and `Save` now auto-detect primary keys for conflict resolution if `OnConflict` is not set, and treat `Replace` as a `Save` operation. - Adjusted tests to ensure `Save` and `Replace` work as expected, including verifying data replacement and insertion. [[1]](diffhunk://#diff-c22703c37ebb6836c332f7cd2ada570577ba4564fe39886db02f7c2d0e7a2048L93-R93) [[2]](diffhunk://#diff-c22703c37ebb6836c332f7cd2ada570577ba4564fe39886db02f7c2d0e7a2048R102) [[3]](diffhunk://#diff-c22703c37ebb6836c332f7cd2ada570577ba4564fe39886db02f7c2d0e7a2048L110-R130) * **DM Driver:** - Improved conflict detection: now checks that at least one primary key exists in the provided data when `OnConflict` is not specified, and provides clearer error messages. - Refactored to use the core method for primary key detection and removed redundant code. ### Minor Improvements and Documentation * Added clarifying comments to `DoInsert` methods for ClickHouse, DM, MSSQL, Oracle, and PostgreSQL drivers, specifying that the input list must have at least one validated record. [[1]](diffhunk://#diff-f2e003895041ed3c52b91bb8c270696adc3528d77c39d2f7137af3396267444cR19) [[2]](diffhunk://#diff-f51b30e3f0b0f1284b905385a89992efd0de2fe9ff8c5a4062344dfab17d428eR23) [[3]](diffhunk://#diff-87815aa559a927e2de09bd05148f9841dfc06a1b5f3ecc5e3d5fcb80323a87f8L23-R61) [[4]](diffhunk://#diff-f61dac3fcfd5df4a3936cd8743499c8c0fc45f4f5d0f5398ed84a0cb1603202cR24) [[5]](diffhunk://#diff-c1dfed79aaa3a432057d2bd74d270e4b4094ebcf72984f1161d4972bea009410R16-R72) * Minor code and comment cleanups, including improved formatting and error handling. [[1]](diffhunk://#diff-f61dac3fcfd5df4a3936cd8743499c8c0fc45f4f5d0f5398ed84a0cb1603202cR37) [[2]](diffhunk://#diff-f61dac3fcfd5df4a3936cd8743499c8c0fc45f4f5d0f5398ed84a0cb1603202cL96-R98) [[3]](diffhunk://#diff-f61dac3fcfd5df4a3936cd8743499c8c0fc45f4f5d0f5398ed84a0cb1603202cL106-L116) [[4]](diffhunk://#diff-a17b44c76aaac53d1f164a2bb9440a5531659f4355e7ccfabdadff8dc8633c09L170-R171) [[5]](diffhunk://#diff-56189fa9ae1df51716b50d34d7fe56bfe67a330e8ac2c6b0de7b958db6817ed5R83-R98) ### Workflow and Documentation Updates * Updated example Docker commands in the CI workflow for consistency and clarity. [[1]](diffhunk://#diff-a1a3cb9bdeb5541d148091d973cf266aa3b317e6415a86630e816cbe27cf8b9cL57-R57) [[2]](diffhunk://#diff-a1a3cb9bdeb5541d148091d973cf266aa3b317e6415a86630e816cbe27cf8b9cL78-R78) [[3]](diffhunk://#diff-a1a3cb9bdeb5541d148091d973cf266aa3b317e6415a86630e816cbe27cf8b9cL92-R92) [[4]](diffhunk://#diff-a1a3cb9bdeb5541d148091d973cf266aa3b317e6415a86630e816cbe27cf8b9cL106-R106) [[5]](diffhunk://#diff-a1a3cb9bdeb5541d148091d973cf266aa3b317e6415a86630e816cbe27cf8b9cL153-R153) [[6]](diffhunk://#diff-a1a3cb9bdeb5541d148091d973cf266aa3b317e6415a86630e816cbe27cf8b9cL164-R164) * Removed outdated note about `Replace` support from the SQLite driver documentation. These changes improve the consistency, reliability, and developer experience when performing upsert operations across different database backends. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Lance Add <1196661499@qq.com>
1289 lines
32 KiB
Go
1289 lines
32 KiB
Go
// Copyright 2019 gf Author(https://github.com/gogf/gf). 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 mssql_test
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gogf/gf/v2/database/gdb"
|
|
"github.com/gogf/gf/v2/encoding/gjson"
|
|
"github.com/gogf/gf/v2/encoding/gxml"
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
"github.com/gogf/gf/v2/os/gctx"
|
|
"github.com/gogf/gf/v2/os/gtime"
|
|
"github.com/gogf/gf/v2/test/gtest"
|
|
|
|
"github.com/gogf/gf/contrib/drivers/mssql/v2"
|
|
)
|
|
|
|
func TestTables(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(context.Background())
|
|
gtest.AssertNil(err)
|
|
|
|
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)
|
|
}
|
|
|
|
result, err = db.Tables(context.Background(), TestSchema)
|
|
gtest.AssertNil(err)
|
|
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)
|
|
}
|
|
|
|
for _, v := range tables {
|
|
dropTable(v)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestTableFields(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
createTable("t_user")
|
|
defer dropTable("t_user")
|
|
var expect = map[string][]any{
|
|
"ID": {"numeric(10,0)", false, "PRI", "", "", ""},
|
|
"PASSPORT": {"varchar(45)", true, "", "", "", ""},
|
|
"PASSWORD": {"varchar(32)", true, "", "", "", ""},
|
|
"NICKNAME": {"varchar(45)", true, "", "", "", ""},
|
|
"CREATE_TIME": {"datetime", true, "", "", "", ""},
|
|
}
|
|
|
|
res, err := db.TableFields(context.Background(), "t_user")
|
|
gtest.AssertNil(err)
|
|
|
|
for k, v := range expect {
|
|
_, ok := res[k]
|
|
gtest.AssertEQ(ok, true)
|
|
gtest.AssertEQ(res[k].Name, k)
|
|
gtest.AssertEQ(res[k].Type, v[0])
|
|
gtest.AssertEQ(res[k].Null, v[1])
|
|
gtest.AssertEQ(res[k].Key, v[2])
|
|
gtest.AssertEQ(res[k].Default, v[3])
|
|
gtest.AssertEQ(res[k].Extra, v[4])
|
|
gtest.AssertEQ(res[k].Comment, v[5])
|
|
}
|
|
|
|
res, err = db.TableFields(context.Background(), "t_user", TestSchema)
|
|
gtest.AssertNil(err)
|
|
|
|
for k, v := range expect {
|
|
_, ok := res[k]
|
|
gtest.AssertEQ(ok, true)
|
|
gtest.AssertEQ(res[k].Name, k)
|
|
gtest.AssertEQ(res[k].Type, v[0])
|
|
gtest.AssertEQ(res[k].Null, v[1])
|
|
gtest.AssertEQ(res[k].Key, v[2])
|
|
gtest.AssertEQ(res[k].Default, v[3])
|
|
gtest.AssertEQ(res[k].Extra, v[4])
|
|
gtest.AssertEQ(res[k].Comment, v[5])
|
|
}
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
_, err := db.TableFields(context.Background(), "t_user t_user2")
|
|
gtest.AssertNE(err, nil)
|
|
})
|
|
}
|
|
|
|
func TestDoInsert(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.Insert(context.Background(), "t_user", data)
|
|
gtest.AssertNil(err)
|
|
|
|
})
|
|
|
|
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(),
|
|
}
|
|
// Save without OnConflict should fail (missing conflict columns)
|
|
_, err := db.Save(context.Background(), "t_user", data, 10)
|
|
gtest.AssertNE(err, nil)
|
|
|
|
// Replace should fail because primary key 'id' is not in the data
|
|
_, err = db.Replace(context.Background(), "t_user", data, 10)
|
|
gtest.AssertNE(err, nil)
|
|
})
|
|
}
|
|
|
|
func TestDoInsertGetId(t *testing.T) {
|
|
// create test table
|
|
createInsertAndGetIdTableForTest()
|
|
gtest.C(t, func(t *gtest.T) {
|
|
table := "ip_to_id"
|
|
data := map[string]interface{}{
|
|
"ip": "192.168.179.1",
|
|
}
|
|
id, err := db.InsertAndGetId(gctx.New(), table, data)
|
|
t.AssertNil(err)
|
|
t.AssertGT(id, 0)
|
|
// fmt.Println("id:", id)
|
|
|
|
// multiple insert test
|
|
dataAry := []map[string]interface{}{{"ip": "192.168.5.9"}, {"ip": "192.168.5.10"}}
|
|
id1, err1 := db.InsertAndGetId(gctx.New(), table, dataAry)
|
|
t.AssertNil(err1)
|
|
t.AssertGT(id1, 0)
|
|
})
|
|
}
|
|
|
|
func TestGetTableFromSql(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
okTable := "ip_to_id"
|
|
sqlStr := "INSERT INTO \"ip_to_id\"(\"ip\") VALUES(?)"
|
|
dbWrapper, ok := db.GetCore().GetDB().(*gdb.DriverWrapperDB)
|
|
t.Assert(ok, true)
|
|
dbMssql, ok := dbWrapper.DB.(*mssql.Driver)
|
|
t.Assert(ok, true)
|
|
table := dbMssql.GetTableNameFromSql(sqlStr)
|
|
// fmt.Println("default table:", table)
|
|
t.Assert(table, okTable)
|
|
|
|
sqlStr = "INSERT INTO \"MyLogDb\".\"dbo\".\"ip_to_id\"(\"ip\") VALUES(?)"
|
|
table = dbMssql.GetTableNameFromSql(sqlStr)
|
|
// fmt.Println("MyLogDb.dbo.ip_to_id table:", table)
|
|
t.Assert(table, okTable)
|
|
|
|
sqlStr = "INSERT INTO \"ip_to_id\" as \"tt\" (\"ip\") VALUES(?)"
|
|
table = dbMssql.GetTableNameFromSql(sqlStr)
|
|
// fmt.Println("ip_to_id as tt table:", table)
|
|
t.Assert(table, okTable)
|
|
|
|
sqlStr = "INSERT INTO \"ip_to_id\" \"tt\" (\"ip\") VALUES(?)"
|
|
table = dbMssql.GetTableNameFromSql(sqlStr)
|
|
// fmt.Println("ip_to_id tt table:", table)
|
|
t.Assert(table, okTable)
|
|
})
|
|
}
|
|
|
|
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) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
_, err := db.Exec(ctx, "SELECT ?", 1)
|
|
t.AssertNil(err)
|
|
|
|
_, err = db.Exec(ctx, "ERROR")
|
|
t.AssertNE(err, nil)
|
|
})
|
|
}
|
|
|
|
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": 1,
|
|
"passport": "t1",
|
|
"password": "25d55ad283aa400af464c76d713c07ad",
|
|
"nickname": "T1",
|
|
"create_time": gtime.Now(),
|
|
})
|
|
t.AssertNil(err)
|
|
|
|
// normal map
|
|
result, err := db.Insert(ctx, table, g.Map{
|
|
"id": "2",
|
|
"passport": "t2",
|
|
"password": "25d55ad283aa400af464c76d713c07ad",
|
|
"nickname": "name_2",
|
|
"create_time": gtime.Now(),
|
|
})
|
|
t.AssertNil(err)
|
|
n, _ := result.RowsAffected()
|
|
t.Assert(n, 1)
|
|
|
|
// struct
|
|
type User struct {
|
|
Id int `gconv:"id"`
|
|
Passport string `json:"passport"`
|
|
Password string `gconv:"password"`
|
|
Nickname string `gconv:"nickname"`
|
|
CreateTime *gtime.Time `json:"create_time"`
|
|
}
|
|
timeNow := gtime.New("2024-10-01 12:01:01")
|
|
result, err = db.Insert(ctx, table, User{
|
|
Id: 3,
|
|
Passport: "user_3",
|
|
Password: "25d55ad283aa400af464c76d713c07ad",
|
|
Nickname: "name_3",
|
|
CreateTime: timeNow,
|
|
})
|
|
t.AssertNil(err)
|
|
n, _ = result.RowsAffected()
|
|
t.Assert(n, 1)
|
|
|
|
one, err := db.Model(table).Where("id", 3).One()
|
|
t.AssertNil(err)
|
|
t.Assert(one["ID"].Int(), 3)
|
|
t.Assert(one["PASSPORT"].String(), "user_3")
|
|
t.Assert(one["PASSWORD"].String(), "25d55ad283aa400af464c76d713c07ad")
|
|
t.Assert(one["NICKNAME"].String(), "name_3")
|
|
t.AssertNE(one["CREATE_TIME"].GTime(), nil)
|
|
t.AssertLT(timeNow.Sub(one["CREATE_TIME"].GTime()), 3)
|
|
|
|
// *struct
|
|
timeNow = gtime.Now()
|
|
result, err = db.Insert(ctx, table, &User{
|
|
Id: 4,
|
|
Passport: "t4",
|
|
Password: "25d55ad283aa400af464c76d713c07ad",
|
|
Nickname: "name_4",
|
|
CreateTime: timeNow,
|
|
})
|
|
t.AssertNil(err)
|
|
n, _ = result.RowsAffected()
|
|
t.Assert(n, 1)
|
|
|
|
one, err = db.Model(table).Where("id", 4).One()
|
|
t.AssertNil(err)
|
|
t.Assert(one["ID"].Int(), 4)
|
|
t.Assert(one["PASSPORT"].String(), "t4")
|
|
t.Assert(one["PASSWORD"].String(), "25d55ad283aa400af464c76d713c07ad")
|
|
t.Assert(one["NICKNAME"].String(), "name_4")
|
|
|
|
// batch with Insert
|
|
timeNow = gtime.Now()
|
|
r, err := db.Insert(ctx, table, g.Slice{
|
|
g.Map{
|
|
"id": 200,
|
|
"passport": "t200",
|
|
"password": "25d55ad283aa400af464c76d71qw07ad",
|
|
"nickname": "T200",
|
|
"create_time": timeNow,
|
|
},
|
|
g.Map{
|
|
"id": 300,
|
|
"passport": "t300",
|
|
"password": "25d55ad283aa400af464c76d713c07ad",
|
|
"nickname": "T300",
|
|
"create_time": timeNow,
|
|
},
|
|
})
|
|
t.AssertNil(err)
|
|
n, _ = r.RowsAffected()
|
|
t.Assert(n, 2)
|
|
|
|
one, err = db.Model(table).Where("id", 200).One()
|
|
t.AssertNil(err)
|
|
t.Assert(one["ID"].Int(), 200)
|
|
t.Assert(one["PASSPORT"].String(), "t200")
|
|
t.Assert(one["PASSWORD"].String(), "25d55ad283aa400af464c76d71qw07ad")
|
|
t.Assert(one["NICKNAME"].String(), "T200")
|
|
})
|
|
}
|
|
|
|
func Test_DB_Insert_KeyFieldNameMapping(t *testing.T) {
|
|
table := createTable()
|
|
defer dropTable(table)
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
type User struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
Nickname string
|
|
CreateTime string
|
|
}
|
|
data := User{
|
|
Id: 1,
|
|
Passport: "user_1",
|
|
Password: "pass_1",
|
|
Nickname: "name_1",
|
|
CreateTime: "2020-10-10 12:00:01",
|
|
}
|
|
_, 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_Update_KeyFieldNameMapping(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 string
|
|
}
|
|
data := User{
|
|
Id: 1,
|
|
Passport: "user_10",
|
|
Password: "pass_10",
|
|
Nickname: "name_10",
|
|
CreateTime: "2020-10-10 12:00:01",
|
|
}
|
|
_, err := db.Update(ctx, table, data, "id=1")
|
|
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_BatchInsert(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
table := createTable()
|
|
defer dropTable(table)
|
|
r, err := db.Insert(ctx, table, g.List{
|
|
{
|
|
"id": 2,
|
|
"passport": "t2",
|
|
"password": "25d55ad283aa400af464c76d713c07ad",
|
|
"nickname": "name_2",
|
|
"create_time": gtime.Now(),
|
|
},
|
|
{
|
|
"id": 3,
|
|
"passport": "user_3",
|
|
"password": "25d55ad283aa400af464c76d713c07ad",
|
|
"nickname": "name_3",
|
|
"create_time": gtime.Now(),
|
|
},
|
|
}, 1)
|
|
t.AssertNil(err)
|
|
n, _ := r.RowsAffected()
|
|
t.Assert(n, 2)
|
|
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
table := createTable()
|
|
defer dropTable(table)
|
|
// []any
|
|
r, err := db.Insert(ctx, table, g.Slice{
|
|
g.Map{
|
|
"id": 2,
|
|
"passport": "t2",
|
|
"password": "25d55ad283aa400af464c76d713c07ad",
|
|
"nickname": "name_2",
|
|
"create_time": gtime.Now(),
|
|
},
|
|
g.Map{
|
|
"id": 3,
|
|
"passport": "user_3",
|
|
"password": "25d55ad283aa400af464c76d713c07ad",
|
|
"nickname": "name_3",
|
|
"create_time": gtime.Now(),
|
|
},
|
|
}, 1)
|
|
t.AssertNil(err)
|
|
n, _ := r.RowsAffected()
|
|
t.Assert(n, 2)
|
|
})
|
|
|
|
// batch insert map
|
|
gtest.C(t, func(t *gtest.T) {
|
|
table := createTable()
|
|
defer dropTable(table)
|
|
result, err := db.Insert(ctx, table, g.Map{
|
|
"id": 1,
|
|
"passport": "t1",
|
|
"password": "p1",
|
|
"nickname": "T1",
|
|
"create_time": gtime.Now(),
|
|
})
|
|
t.AssertNil(err)
|
|
n, _ := result.RowsAffected()
|
|
t.Assert(n, 1)
|
|
})
|
|
}
|
|
|
|
func Test_DB_BatchInsert_Struct(t *testing.T) {
|
|
// batch insert struct
|
|
gtest.C(t, func(t *gtest.T) {
|
|
table := createTable()
|
|
defer dropTable(table)
|
|
|
|
type User struct {
|
|
Id int `c:"id"`
|
|
Passport string `c:"passport"`
|
|
Password string `c:"password"`
|
|
NickName string `c:"nickname"`
|
|
CreateTime *gtime.Time `c:"create_time"`
|
|
}
|
|
user := &User{
|
|
Id: 1,
|
|
Passport: "t1",
|
|
Password: "p1",
|
|
NickName: "T1",
|
|
CreateTime: gtime.Now(),
|
|
}
|
|
result, err := db.Insert(ctx, table, user)
|
|
t.AssertNil(err)
|
|
n, _ := result.RowsAffected()
|
|
t.Assert(n, 1)
|
|
})
|
|
}
|
|
|
|
func Test_DB_Update(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
result, err := db.Update(ctx, table, "password='987654321'", "id=3")
|
|
t.AssertNil(err)
|
|
n, _ := result.RowsAffected()
|
|
t.Assert(n, 1)
|
|
|
|
one, err := db.Model(table).Where("id", 3).One()
|
|
t.AssertNil(err)
|
|
t.Assert(one["ID"].Int(), 3)
|
|
t.Assert(one["PASSPORT"].String(), "user_3")
|
|
t.Assert(one["PASSWORD"].String(), "987654321")
|
|
t.Assert(one["NICKNAME"].String(), "name_3")
|
|
})
|
|
}
|
|
|
|
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 := createInitTable()
|
|
defer dropTable(table)
|
|
gtest.C(t, func(t *gtest.T) {
|
|
record, err := db.GetOne(ctx, fmt.Sprintf("SELECT * FROM %s WHERE passport=?", table), "user_1")
|
|
t.AssertNil(err)
|
|
t.Assert(record["NICKNAME"].String(), "name_1")
|
|
})
|
|
}
|
|
|
|
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_GetStruct(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")
|
|
})
|
|
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_GetStructs(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
|
|
}
|
|
var users []User
|
|
err := db.GetScan(ctx, &users, fmt.Sprintf("SELECT * FROM %s WHERE id>?", table), 1)
|
|
t.AssertNil(err)
|
|
t.Assert(len(users), TableSize-1)
|
|
t.Assert(users[0].Id, 2)
|
|
t.Assert(users[1].Id, 3)
|
|
t.Assert(users[2].Id, 4)
|
|
t.Assert(users[0].NickName, "name_2")
|
|
t.Assert(users[1].NickName, "name_3")
|
|
t.Assert(users[2].NickName, "name_4")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
type User struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime *gtime.Time
|
|
}
|
|
var users []User
|
|
err := db.GetScan(ctx, &users, fmt.Sprintf("SELECT * FROM %s WHERE id>?", table), 1)
|
|
t.AssertNil(err)
|
|
t.Assert(len(users), TableSize-1)
|
|
t.Assert(users[0].Id, 2)
|
|
t.Assert(users[1].Id, 3)
|
|
t.Assert(users[2].Id, 4)
|
|
t.Assert(users[0].NickName, "name_2")
|
|
t.Assert(users[1].NickName, "name_3")
|
|
t.Assert(users[2].NickName, "name_4")
|
|
})
|
|
}
|
|
|
|
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")
|
|
})
|
|
gtest.C(t, func(t *gtest.T) {
|
|
type User struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime gtime.Time
|
|
}
|
|
var user *User
|
|
err := db.GetScan(ctx, &user, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 3)
|
|
t.AssertNil(err)
|
|
t.Assert(user.NickName, "name_3")
|
|
})
|
|
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")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
type User struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime gtime.Time
|
|
}
|
|
var users []User
|
|
err := db.GetScan(ctx, &users, fmt.Sprintf("SELECT * FROM %s WHERE id>?", table), 1)
|
|
t.AssertNil(err)
|
|
t.Assert(len(users), TableSize-1)
|
|
t.Assert(users[0].Id, 2)
|
|
t.Assert(users[1].Id, 3)
|
|
t.Assert(users[2].Id, 4)
|
|
t.Assert(users[0].NickName, "name_2")
|
|
t.Assert(users[1].NickName, "name_3")
|
|
t.Assert(users[2].NickName, "name_4")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
type User struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime *gtime.Time
|
|
}
|
|
var users []User
|
|
err := db.GetScan(ctx, &users, fmt.Sprintf("SELECT * FROM %s WHERE id>?", table), 1)
|
|
t.AssertNil(err)
|
|
t.Assert(len(users), TableSize-1)
|
|
t.Assert(users[0].Id, 2)
|
|
t.Assert(users[1].Id, 3)
|
|
t.Assert(users[2].Id, 4)
|
|
t.Assert(users[0].NickName, "name_2")
|
|
t.Assert(users[1].NickName, "name_3")
|
|
t.Assert(users[2].NickName, "name_4")
|
|
})
|
|
}
|
|
|
|
func Test_DB_Delete(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
gtest.C(t, func(t *gtest.T) {
|
|
result, err := db.Delete(ctx, table, "1=1")
|
|
t.AssertNil(err)
|
|
n, _ := result.RowsAffected()
|
|
t.Assert(n, TableSize)
|
|
})
|
|
}
|
|
|
|
func Test_DB_Time(t *testing.T) {
|
|
table := createTable()
|
|
defer dropTable(table)
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
result, err := db.Insert(ctx, table, g.Map{
|
|
"id": 200,
|
|
"passport": "t200",
|
|
"password": "123456",
|
|
"nickname": "T200",
|
|
"create_time": time.Now(),
|
|
})
|
|
if err != nil {
|
|
gtest.Error(err)
|
|
}
|
|
n, _ := result.RowsAffected()
|
|
t.Assert(n, 1)
|
|
value, err := db.GetValue(ctx, fmt.Sprintf("select passport from %s where id=?", table), 200)
|
|
t.AssertNil(err)
|
|
t.Assert(value.String(), "t200")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
t1 := time.Now()
|
|
result, err := db.Insert(ctx, table, g.Map{
|
|
"id": 300,
|
|
"passport": "t300",
|
|
"password": "123456",
|
|
"nickname": "T300",
|
|
"create_time": &t1,
|
|
})
|
|
if err != nil {
|
|
gtest.Error(err)
|
|
}
|
|
n, _ := result.RowsAffected()
|
|
t.Assert(n, 1)
|
|
value, err := db.GetValue(ctx, fmt.Sprintf("select passport from %s where id=?", table), 300)
|
|
t.AssertNil(err)
|
|
t.Assert(value.String(), "t300")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
result, err := db.Delete(ctx, table, "1=1")
|
|
t.AssertNil(err)
|
|
n, _ := result.RowsAffected()
|
|
t.Assert(n, 2)
|
|
})
|
|
}
|
|
|
|
func Test_DB_ToJson(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
_, err := db.Update(ctx, table, "create_time='2010-10-10 00:00:01'", "id=?", 1)
|
|
gtest.AssertNil(err)
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
result, err := db.Model(table).Fields("*").Where("id =? ", 1).All()
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
type User struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime string
|
|
}
|
|
|
|
users := make([]User, 0)
|
|
|
|
err = result.Structs(users)
|
|
t.AssertNE(err, nil)
|
|
|
|
err = result.Structs(&users)
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
// ToJson
|
|
resultJson, err := gjson.LoadContent([]byte(result.Json()))
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
t.Assert(users[0].Id, resultJson.Get("0.ID").Int())
|
|
t.Assert(users[0].Passport, resultJson.Get("0.PASSPORT").String())
|
|
t.Assert(users[0].Password, resultJson.Get("0.PASSWORD").String())
|
|
t.Assert(users[0].NickName, resultJson.Get("0.NICKNAME").String())
|
|
t.Assert(users[0].CreateTime, resultJson.Get("0.CREATE_TIME").String())
|
|
|
|
result = nil
|
|
t.Assert(result.Structs(&users), sql.ErrNoRows)
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
result, err := db.Model(table).Fields("*").Where("id =? ", 1).One()
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
type User struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime string
|
|
}
|
|
|
|
users := User{}
|
|
|
|
err = result.Struct(&users)
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
result = nil
|
|
err = result.Struct(&users)
|
|
t.AssertNE(err, nil)
|
|
})
|
|
}
|
|
|
|
func Test_DB_ToXml(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
_, err := db.Update(ctx, table, "create_time='2010-10-10 00:00:01'", "id=?", 1)
|
|
gtest.AssertNil(err)
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
record, err := db.Model(table).Fields("*").Where("id = ?", 1).One()
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
type User struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime string
|
|
}
|
|
|
|
user := User{}
|
|
err = record.Struct(&user)
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
result, err := gxml.Decode([]byte(record.Xml("doc")))
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
resultXml := result["doc"].(map[string]any)
|
|
if v, ok := resultXml["ID"]; ok {
|
|
t.Assert(user.Id, v)
|
|
} else {
|
|
gtest.Fatal("FAIL")
|
|
}
|
|
|
|
if v, ok := resultXml["PASSPORT"]; ok {
|
|
t.Assert(user.Passport, v)
|
|
} else {
|
|
gtest.Fatal("FAIL")
|
|
}
|
|
|
|
if v, ok := resultXml["PASSWORD"]; ok {
|
|
t.Assert(user.Password, v)
|
|
} else {
|
|
gtest.Fatal("FAIL")
|
|
}
|
|
|
|
if v, ok := resultXml["NICKNAME"]; ok {
|
|
t.Assert(user.NickName, v)
|
|
} else {
|
|
gtest.Fatal("FAIL")
|
|
}
|
|
|
|
if v, ok := resultXml["CREATE_TIME"]; ok {
|
|
t.Assert(user.CreateTime, v)
|
|
} else {
|
|
gtest.Fatal("FAIL")
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test_DB_ToStringMap(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
_, err := db.Update(ctx, table, "create_time='2010-10-10 00:00:01'", "id=?", 1)
|
|
gtest.AssertNil(err)
|
|
gtest.C(t, func(t *gtest.T) {
|
|
id := "1"
|
|
result, err := db.Model(table).Fields("*").Where("id = ?", 1).All()
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
type t_user struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime string
|
|
}
|
|
|
|
t_users := make([]t_user, 0)
|
|
err = result.Structs(&t_users)
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
resultStringMap := result.MapKeyStr("ID")
|
|
t.Assert(t_users[0].Id, resultStringMap[id]["ID"])
|
|
t.Assert(t_users[0].Passport, resultStringMap[id]["PASSPORT"])
|
|
t.Assert(t_users[0].Password, resultStringMap[id]["PASSWORD"])
|
|
t.Assert(t_users[0].NickName, resultStringMap[id]["NICKNAME"])
|
|
t.Assert(t_users[0].CreateTime, resultStringMap[id]["CREATE_TIME"])
|
|
})
|
|
}
|
|
|
|
func Test_DB_ToIntMap(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
_, err := db.Update(ctx, table, "create_time='2010-10-10 00:00:01'", "id=?", 1)
|
|
gtest.AssertNil(err)
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
id := 1
|
|
result, err := db.Model(table).Fields("*").Where("id = ?", id).All()
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
type t_user struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime string
|
|
}
|
|
|
|
t_users := make([]t_user, 0)
|
|
err = result.Structs(&t_users)
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
resultIntMap := result.MapKeyInt("ID")
|
|
t.Assert(t_users[0].Id, resultIntMap[id]["ID"])
|
|
t.Assert(t_users[0].Passport, resultIntMap[id]["PASSPORT"])
|
|
t.Assert(t_users[0].Password, resultIntMap[id]["PASSWORD"])
|
|
t.Assert(t_users[0].NickName, resultIntMap[id]["NICKNAME"])
|
|
t.Assert(t_users[0].CreateTime, resultIntMap[id]["CREATE_TIME"])
|
|
})
|
|
}
|
|
|
|
func Test_DB_ToUintMap(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
_, err := db.Update(ctx, table, "create_time='2010-10-10 00:00:01'", "id=?", 1)
|
|
gtest.AssertNil(err)
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
id := 1
|
|
result, err := db.Model(table).Fields("*").Where("id = ?", id).All()
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
type t_user struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime string
|
|
}
|
|
|
|
t_users := make([]t_user, 0)
|
|
err = result.Structs(&t_users)
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
resultUintMap := result.MapKeyUint("ID")
|
|
t.Assert(t_users[0].Id, resultUintMap[uint(id)]["ID"])
|
|
t.Assert(t_users[0].Passport, resultUintMap[uint(id)]["PASSPORT"])
|
|
t.Assert(t_users[0].Password, resultUintMap[uint(id)]["PASSWORD"])
|
|
t.Assert(t_users[0].NickName, resultUintMap[uint(id)]["NICKNAME"])
|
|
t.Assert(t_users[0].CreateTime, resultUintMap[uint(id)]["CREATE_TIME"])
|
|
})
|
|
}
|
|
|
|
func Test_DB_ToStringRecord(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
_, err := db.Update(ctx, table, "create_time='2010-10-10 00:00:01'", "id=?", 1)
|
|
gtest.AssertNil(err)
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
id := 1
|
|
ids := "1"
|
|
result, err := db.Model(table).Fields("*").Where("id = ?", id).All()
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
type t_user struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime string
|
|
}
|
|
|
|
t_users := make([]t_user, 0)
|
|
err = result.Structs(&t_users)
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
resultStringRecord := result.RecordKeyStr("ID")
|
|
t.Assert(t_users[0].Id, resultStringRecord[ids]["ID"].Int())
|
|
t.Assert(t_users[0].Passport, resultStringRecord[ids]["PASSPORT"].String())
|
|
t.Assert(t_users[0].Password, resultStringRecord[ids]["PASSWORD"].String())
|
|
t.Assert(t_users[0].NickName, resultStringRecord[ids]["NICKNAME"].String())
|
|
t.Assert(t_users[0].CreateTime, resultStringRecord[ids]["CREATE_TIME"].String())
|
|
})
|
|
}
|
|
|
|
func Test_DB_ToIntRecord(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
_, err := db.Update(ctx, table, "create_time='2010-10-10 00:00:01'", "id=?", 1)
|
|
gtest.AssertNil(err)
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
id := 1
|
|
result, err := db.Model(table).Fields("*").Where("id = ?", id).All()
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
type t_user struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime string
|
|
}
|
|
|
|
t_users := make([]t_user, 0)
|
|
err = result.Structs(&t_users)
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
resultIntRecord := result.RecordKeyInt("ID")
|
|
t.Assert(t_users[0].Id, resultIntRecord[id]["ID"].Int())
|
|
t.Assert(t_users[0].Passport, resultIntRecord[id]["PASSPORT"].String())
|
|
t.Assert(t_users[0].Password, resultIntRecord[id]["PASSWORD"].String())
|
|
t.Assert(t_users[0].NickName, resultIntRecord[id]["NICKNAME"].String())
|
|
t.Assert(t_users[0].CreateTime, resultIntRecord[id]["CREATE_TIME"].String())
|
|
})
|
|
}
|
|
|
|
func Test_DB_ToUintRecord(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
_, err := db.Update(ctx, table, "create_time='2010-10-10 00:00:01'", "id=?", 1)
|
|
gtest.AssertNil(err)
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
id := 1
|
|
result, err := db.Model(table).Fields("*").Where("id = ?", id).All()
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
type t_user struct {
|
|
Id int
|
|
Passport string
|
|
Password string
|
|
NickName string
|
|
CreateTime string
|
|
}
|
|
|
|
t_users := make([]t_user, 0)
|
|
err = result.Structs(&t_users)
|
|
if err != nil {
|
|
gtest.Fatal(err)
|
|
}
|
|
|
|
resultUintRecord := result.RecordKeyUint("ID")
|
|
t.Assert(t_users[0].Id, resultUintRecord[uint(id)]["ID"].Int())
|
|
t.Assert(t_users[0].Passport, resultUintRecord[uint(id)]["PASSPORT"].String())
|
|
t.Assert(t_users[0].Password, resultUintRecord[uint(id)]["PASSWORD"].String())
|
|
t.Assert(t_users[0].NickName, resultUintRecord[uint(id)]["NICKNAME"].String())
|
|
t.Assert(t_users[0].CreateTime, resultUintRecord[uint(id)]["CREATE_TIME"].String())
|
|
})
|
|
}
|
|
|
|
func Test_Model_InnerJoin(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
table1 := createInitTable("user1")
|
|
table2 := createInitTable("user2")
|
|
|
|
defer dropTable(table1)
|
|
defer dropTable(table2)
|
|
|
|
res, err := db.Model(table1).Where("id > ?", 5).Delete()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
n, err := res.RowsAffected()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
t.Assert(n, 5)
|
|
|
|
result, err := db.Model(table1+" u1").InnerJoin(table2+" u2", "u1.id = u2.id").Order("u1.id").All()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
t.Assert(len(result), 5)
|
|
|
|
result, err = db.Model(table1+" u1").InnerJoin(table2+" u2", "u1.id = u2.id").Where("u1.id > ?", 1).Order("u1.id").All()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
t.Assert(len(result), 4)
|
|
})
|
|
}
|
|
|
|
func Test_Model_LeftJoin(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
table1 := createInitTable("user1")
|
|
table2 := createInitTable("user2")
|
|
|
|
defer dropTable(table1)
|
|
defer dropTable(table2)
|
|
|
|
res, err := db.Model(table2).Where("id > ?", 3).Delete()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
n, err := res.RowsAffected()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else {
|
|
t.Assert(n, 7)
|
|
}
|
|
|
|
result, err := db.Model(table1+" u1").LeftJoin(table2+" u2", "u1.id = u2.id").All()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
t.Assert(len(result), 10)
|
|
|
|
result, err = db.Model(table1+" u1").LeftJoin(table2+" u2", "u1.id = u2.id").Where("u1.id > ? ", 2).All()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
t.Assert(len(result), 8)
|
|
})
|
|
}
|
|
|
|
func Test_Model_RightJoin(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
table1 := createInitTable("user1")
|
|
table2 := createInitTable("user2")
|
|
|
|
defer dropTable(table1)
|
|
defer dropTable(table2)
|
|
|
|
res, err := db.Model(table1).Where("id > ?", 3).Delete()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
n, err := res.RowsAffected()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
t.Assert(n, 7)
|
|
|
|
result, err := db.Model(table1+" u1").RightJoin(table2+" u2", "u1.id = u2.id").All()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Assert(len(result), 10)
|
|
|
|
result, err = db.Model(table1+" u1").RightJoin(table2+" u2", "u1.id = u2.id").Where("u1.id > 2").All()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Assert(len(result), 1)
|
|
})
|
|
}
|
|
|
|
func Test_Empty_Slice_Argument(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 in(?)`, table), g.Slice{})
|
|
t.AssertNil(err)
|
|
t.Assert(len(result), 0)
|
|
})
|
|
}
|