mirror of
https://gitee.com/johng/gf.git
synced 2024-11-30 19:27:46 +08:00
add more unit test cases for gdb
This commit is contained in:
parent
6ab0a77364
commit
0af55794f6
2
TODO.MD
2
TODO.MD
@ -57,7 +57,7 @@
|
||||
1. 更新跨域请求CORS相关功能文档;
|
||||
1. ghttp的热重启的本地进程端口监听,在不使用该特性时默认关闭掉;
|
||||
1. gcfg包目前允许添加重复的目录路径,需要在SetPath/AddPath时判断重复性,不能添加重复的路径;
|
||||
|
||||
1. gdb执行数据写入时,如果参数为struct/[]struct,自动映射与表字段对应关系,不再使用gconv标签标识;
|
||||
|
||||
|
||||
|
||||
|
@ -39,8 +39,8 @@ type DB interface {
|
||||
doPrepare(link dbLink, query string) (*sql.Stmt, error)
|
||||
doInsert(link dbLink, table string, data interface{}, option int, batch...int) (result sql.Result, err error)
|
||||
doBatchInsert(link dbLink, table string, list interface{}, option int, batch...int) (result sql.Result, err error)
|
||||
doUpdate(link dbLink, table string, data interface{}, condition interface{}, args ...interface{}) (result sql.Result, err error)
|
||||
doDelete(link dbLink, table string, condition interface{}, args ...interface{}) (result sql.Result, err error)
|
||||
doUpdate(link dbLink, table string, data interface{}, condition string, args ...interface{}) (result sql.Result, err error)
|
||||
doDelete(link dbLink, table string, condition string, args ...interface{}) (result sql.Result, err error)
|
||||
|
||||
// 数据库查询
|
||||
GetAll(query string, args ...interface{}) (Result, error)
|
||||
|
@ -312,7 +312,7 @@ func (bs *dbBase) doInsert(link dbLink, table string, data interface{}, option i
|
||||
return bs.db.doBatchInsert(link, table, data, option, batch...)
|
||||
case reflect.Map: fallthrough
|
||||
case reflect.Struct:
|
||||
dataMap = Map(gconv.Map(data))
|
||||
dataMap = gconv.Map(data)
|
||||
default:
|
||||
return result, errors.New(fmt.Sprint("unsupported data type:", kind))
|
||||
}
|
||||
@ -320,7 +320,7 @@ func (bs *dbBase) doInsert(link dbLink, table string, data interface{}, option i
|
||||
for k, v := range dataMap {
|
||||
fields = append(fields, charL + k + charR)
|
||||
values = append(values, "?")
|
||||
params = append(params, v)
|
||||
params = append(params, convertParam(v))
|
||||
}
|
||||
operation := getInsertOperationByOption(option)
|
||||
updateStr := ""
|
||||
@ -369,6 +369,10 @@ func (bs *dbBase) doBatchInsert(link dbLink, table string, list interface{}, opt
|
||||
var params []interface{}
|
||||
listMap := (List)(nil)
|
||||
switch v := list.(type) {
|
||||
case Result:
|
||||
listMap = v.ToList()
|
||||
case Record:
|
||||
listMap = List{v.ToMap()}
|
||||
case List:
|
||||
listMap = v
|
||||
case Map:
|
||||
@ -436,7 +440,7 @@ func (bs *dbBase) doBatchInsert(link dbLink, table string, list interface{}, opt
|
||||
}
|
||||
for i := 0; i < len(listMap); i++ {
|
||||
for _, k := range keys {
|
||||
params = append(params, listMap[i][k])
|
||||
params = append(params, convertParam(listMap[i][k]))
|
||||
}
|
||||
values = append(values, valueHolderStr)
|
||||
if len(values) == batchNum {
|
||||
@ -479,17 +483,13 @@ func (bs *dbBase) doBatchInsert(link dbLink, table string, list interface{}, opt
|
||||
// CURD操作:数据更新,统一采用sql预处理。
|
||||
// data参数支持string/map/struct/*struct类型。
|
||||
func (bs *dbBase) Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error) {
|
||||
link, err := bs.db.Master()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bs.db.doUpdate(link, table, data, condition, args ...)
|
||||
newWhere, newArgs := formatCondition(condition, args)
|
||||
return bs.db.doUpdate(nil, table, data, newWhere, newArgs ...)
|
||||
}
|
||||
|
||||
// CURD操作:数据更新,统一采用sql预处理。
|
||||
// data参数支持string/map/struct/*struct类型类型。
|
||||
func (bs *dbBase) doUpdate(link dbLink, table string, data interface{}, condition interface{}, args ...interface{}) (result sql.Result, err error) {
|
||||
params := ([]interface{})(nil)
|
||||
func (bs *dbBase) doUpdate(link dbLink, table string, data interface{}, condition string, args ...interface{}) (result sql.Result, err error) {
|
||||
updates := ""
|
||||
charL, charR := bs.db.getChars()
|
||||
// 使用反射进行类型判断
|
||||
@ -499,43 +499,51 @@ func (bs *dbBase) doUpdate(link dbLink, table string, data interface{}, conditio
|
||||
rv = rv.Elem()
|
||||
kind = rv.Kind()
|
||||
}
|
||||
params := []interface{}(nil)
|
||||
switch kind {
|
||||
case reflect.Map: fallthrough
|
||||
case reflect.Struct:
|
||||
var fields []string
|
||||
for k, v := range gconv.Map(data) {
|
||||
fields = append(fields, fmt.Sprintf("%s%s%s=?", charL, k, charR))
|
||||
params = append(params, gconv.String(v))
|
||||
params = append(params, convertParam(v))
|
||||
}
|
||||
updates = strings.Join(fields, ",")
|
||||
default:
|
||||
updates = gconv.String(data)
|
||||
}
|
||||
for _, v := range args {
|
||||
params = append(params, gconv.String(v))
|
||||
if len(params) > 0 {
|
||||
args = append(params, args...)
|
||||
}
|
||||
// 如果没有传递link,那么使用默认的写库对象
|
||||
if link == nil {
|
||||
if link, err = bs.db.Master(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
newWhere, newArgs := formatCondition(condition, params)
|
||||
return bs.db.doExec(link, fmt.Sprintf("UPDATE %s SET %s WHERE %s", table, updates, newWhere), newArgs...)
|
||||
if len(condition) == 0 {
|
||||
return bs.db.doExec(link, fmt.Sprintf("UPDATE %s SET %s", table, updates), args...)
|
||||
}
|
||||
return bs.db.doExec(link, fmt.Sprintf("UPDATE %s SET %s WHERE %s", table, updates, condition), args...)
|
||||
}
|
||||
|
||||
// CURD操作:删除数据
|
||||
func (bs *dbBase) Delete(table string, condition interface{}, args ...interface{}) (result sql.Result, err error) {
|
||||
link, err := bs.db.Master()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bs.db.doDelete(link, table, condition, args ...)
|
||||
newWhere, newArgs := formatCondition(condition, args)
|
||||
return bs.db.doDelete(nil, table, newWhere, newArgs ...)
|
||||
}
|
||||
|
||||
// CURD操作:删除数据
|
||||
func (bs *dbBase) doDelete(link dbLink, table string, condition interface{}, args ...interface{}) (result sql.Result, err error) {
|
||||
newWhere, newArgs := formatCondition(condition, args)
|
||||
return bs.db.doExec(link, fmt.Sprintf("DELETE FROM %s WHERE %s", table, newWhere), newArgs...)
|
||||
func (bs *dbBase) doDelete(link dbLink, table string, condition string, args ...interface{}) (result sql.Result, err error) {
|
||||
if link == nil {
|
||||
if link, err = bs.db.Master(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(condition) == 0 {
|
||||
return bs.db.doExec(link, fmt.Sprintf("DELETE FROM %s", table), args...)
|
||||
}
|
||||
return bs.db.doExec(link, fmt.Sprintf("DELETE FROM %s WHERE %s", table, condition), args...)
|
||||
}
|
||||
|
||||
// 获得缓存对象
|
||||
|
@ -78,8 +78,9 @@ func formatCondition(where interface{}, args []interface{}) (newWhere string, ne
|
||||
default:
|
||||
buffer.WriteString(gconv.String(where))
|
||||
}
|
||||
// 没有任何条件查询参数,直接返回
|
||||
if buffer.Len() == 0 {
|
||||
buffer.WriteString("1=1")
|
||||
return "", args
|
||||
}
|
||||
newWhere = buffer.String()
|
||||
tmpArgs = append(tmpArgs, args...)
|
||||
@ -125,6 +126,22 @@ func formatCondition(where interface{}, args []interface{}) (newWhere string, ne
|
||||
return
|
||||
}
|
||||
|
||||
// 将预处理参数转换为底层数据库引擎支持的格式。
|
||||
// 主要是判断参数是否为复杂数据类型,如果是,那么转换为基础类型。
|
||||
func convertParam(value interface{}) interface{} {
|
||||
rv := reflect.ValueOf(value)
|
||||
kind := rv.Kind()
|
||||
if kind == reflect.Ptr {
|
||||
rv = rv.Elem()
|
||||
kind = rv.Kind()
|
||||
}
|
||||
switch kind {
|
||||
case reflect.Struct:
|
||||
return gconv.String(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// 打印SQL对象(仅在debug=true时有效)
|
||||
func printSql(v *Sql) {
|
||||
s := fmt.Sprintf("%s, %v, %s, %s, %d ms, %s", v.Sql, v.Args,
|
||||
|
@ -247,13 +247,17 @@ func (md *Model) Data(data ...interface{}) *Model {
|
||||
}
|
||||
model.data = m
|
||||
} else {
|
||||
switch data[0].(type) {
|
||||
switch params := data[0].(type) {
|
||||
case Result:
|
||||
model.data = params.ToList()
|
||||
case Record:
|
||||
model.data = params.ToMap()
|
||||
case List:
|
||||
model.data = data[0]
|
||||
model.data = params
|
||||
case Map:
|
||||
model.data = data[0]
|
||||
model.data = params
|
||||
default:
|
||||
rv := reflect.ValueOf(data[0])
|
||||
rv := reflect.ValueOf(params)
|
||||
kind := rv.Kind()
|
||||
if kind == reflect.Ptr {
|
||||
rv = rv.Elem()
|
||||
@ -420,9 +424,9 @@ func (md *Model) Update() (result sql.Result, err error) {
|
||||
}
|
||||
}
|
||||
if md.tx == nil {
|
||||
return md.db.Update(md.tables, md.data, md.where, md.whereArgs ...)
|
||||
return md.db.doUpdate(nil, md.tables, md.data, md.where, md.whereArgs ...)
|
||||
} else {
|
||||
return md.tx.Update(md.tables, md.data, md.where, md.whereArgs ...)
|
||||
return md.tx.doUpdate(md.tables, md.data, md.where, md.whereArgs ...)
|
||||
}
|
||||
}
|
||||
|
||||
@ -434,9 +438,9 @@ func (md *Model) Delete() (result sql.Result, err error) {
|
||||
}
|
||||
}()
|
||||
if md.tx == nil {
|
||||
return md.db.Delete(md.tables, md.where, md.whereArgs...)
|
||||
return md.db.doDelete(nil, md.tables, md.where, md.whereArgs...)
|
||||
} else {
|
||||
return md.tx.Delete(md.tables, md.where, md.whereArgs...)
|
||||
return md.tx.doDelete(md.tables, md.where, md.whereArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,14 +162,28 @@ func (tx *TX) BatchSave(table string, list interface{}, batch...int) (sql.Result
|
||||
return tx.db.doBatchInsert(tx.tx, table, list, OPTION_SAVE, batch...)
|
||||
}
|
||||
|
||||
// CURD操作:数据更新,统一采用sql预处理
|
||||
// data参数支持字符串或者关联数组类型,内部会自行做判断处理
|
||||
// CURD操作:数据更新,统一采用sql预处理,
|
||||
// data参数支持字符串或者关联数组类型,内部会自行做判断处理.
|
||||
func (tx *TX) Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error) {
|
||||
newWhere, newArgs := formatCondition(condition, args)
|
||||
return tx.doUpdate(table, data, newWhere, newArgs ...)
|
||||
}
|
||||
|
||||
// 与Update方法的区别是不处理条件参数
|
||||
func (tx *TX) doUpdate(table string, data interface{}, condition string, args ...interface{}) (sql.Result, error) {
|
||||
return tx.db.doUpdate(tx.tx, table, data, condition, args ...)
|
||||
}
|
||||
|
||||
// CURD操作:删除数据
|
||||
func (tx *TX) Delete(table string, condition interface{}, args ...interface{}) (sql.Result, error) {
|
||||
newWhere, newArgs := formatCondition(condition, args)
|
||||
return tx.doDelete(table, newWhere, newArgs ...)
|
||||
}
|
||||
|
||||
// 与Delete方法的区别是不处理条件参数
|
||||
func (tx *TX) doDelete(table string, condition string, args ...interface{}) (sql.Result, error) {
|
||||
return tx.db.doDelete(tx.tx, table, condition, args ...)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,11 +1,20 @@
|
||||
package gdb_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g"
|
||||
"github.com/gogf/gf/g/container/garray"
|
||||
"github.com/gogf/gf/g/database/gdb"
|
||||
"github.com/gogf/gf/g/os/gtime"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
// 初始化表数据量
|
||||
INIT_DATA_SIZE = 10
|
||||
)
|
||||
|
||||
var (
|
||||
// 数据库对象/接口
|
||||
db gdb.DB
|
||||
@ -26,10 +35,12 @@ func init() {
|
||||
Priority: 1,
|
||||
}
|
||||
hostname, _ := os.Hostname()
|
||||
// 本地测试hack
|
||||
if hostname == "ijohn" {
|
||||
node.Pass = "12345678"
|
||||
}
|
||||
gdb.AddDefaultConfigNode(node)
|
||||
gdb.AddConfigNode("test", node)
|
||||
gdb.AddConfigNode(gdb.DEFAULT_GROUP_NAME, node)
|
||||
if r, err := gdb.New(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
@ -39,12 +50,25 @@ func init() {
|
||||
if _, err := db.Exec("CREATE DATABASE IF NOT EXISTS `test` CHARACTER SET UTF8"); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
// 选择操作数据库
|
||||
db.SetSchema("test")
|
||||
if _, err := db.Exec("DROP TABLE IF EXISTS `user`"); err != nil {
|
||||
gtest.Fatal(err)
|
||||
// 创建默认用户表
|
||||
createTable("user")
|
||||
}
|
||||
|
||||
// 创建指定名称的user测试表,当table为空时,创建随机的表名。
|
||||
// 创建的测试表默认没有任何数据。
|
||||
// 执行完成后返回该表名。
|
||||
// TODO 支持更多数据库
|
||||
func createTable(table...string) (name string) {
|
||||
if len(table) > 0 {
|
||||
name = table[0]
|
||||
} else {
|
||||
name = fmt.Sprintf(`user_%d`, gtime.Nanosecond())
|
||||
}
|
||||
if _, err := db.Exec(`
|
||||
CREATE TABLE user (
|
||||
dropTable(name)
|
||||
if _, err := db.Exec(fmt.Sprintf(`
|
||||
CREATE TABLE %s (
|
||||
id int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
|
||||
passport varchar(45) NOT NULL COMMENT '账号',
|
||||
password char(32) NOT NULL COMMENT '密码',
|
||||
@ -52,7 +76,38 @@ func init() {
|
||||
create_time timestamp NOT NULL COMMENT '创建时间/注册时间',
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
`); err != nil {
|
||||
`, name)); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 删除指定表.
|
||||
func dropTable(table string) {
|
||||
if _, err := db.Exec(fmt.Sprintf("DROP TABLE IF EXISTS `%s`", table)); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// See createTable.
|
||||
// 创建测试表,并初始化默认数据。
|
||||
func createInitTable(table...string) (name string) {
|
||||
name = createTable(table...)
|
||||
array := garray.New(true)
|
||||
for i := 1; i <= INIT_DATA_SIZE; i++ {
|
||||
array.Append(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().String(),
|
||||
})
|
||||
}
|
||||
result, err := db.Table(name).Data(array.Slice()).Insert()
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
n, e := result.RowsAffected()
|
||||
gtest.Assert(e, nil)
|
||||
gtest.Assert(n, INIT_DATA_SIZE)
|
||||
return
|
||||
}
|
||||
|
@ -9,6 +9,15 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDbBase_Ping(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
err1 := db.PingMaster()
|
||||
err2 := db.PingSlave()
|
||||
gtest.Assert(err1, nil)
|
||||
gtest.Assert(err2, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDbBase_Query(t *testing.T) {
|
||||
if _, err := db.Query("SELECT ?", 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
@ -144,57 +153,102 @@ func TestDbBase_Insert(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDbBase_BatchInsert(t *testing.T) {
|
||||
if r, err := db.BatchInsert("user", g.List {
|
||||
{
|
||||
"id" : 2,
|
||||
"passport" : "t2",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T2",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
{
|
||||
"id" : 3,
|
||||
"passport" : "t3",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T3",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
}, 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
n, _ := r.RowsAffected()
|
||||
gtest.Assert(n, 2)
|
||||
}
|
||||
gtest.Case(t, func() {
|
||||
if r, err := db.BatchInsert("user", g.List {
|
||||
{
|
||||
"id" : 2,
|
||||
"passport" : "t2",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T2",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
{
|
||||
"id" : 3,
|
||||
"passport" : "t3",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T3",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
}, 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
n, _ := r.RowsAffected()
|
||||
gtest.Assert(n, 2)
|
||||
}
|
||||
|
||||
result, err := db.Delete("user", "id>?", 1)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 2)
|
||||
|
||||
// []interface{}
|
||||
if r, err := db.BatchInsert("user", []interface{} {
|
||||
map[interface{}]interface{} {
|
||||
"id" : 2,
|
||||
"passport" : "t2",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T2",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
map[interface{}]interface{} {
|
||||
"id" : 3,
|
||||
"passport" : "t3",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T3",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
}, 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
n, _ := r.RowsAffected()
|
||||
result, err := db.Delete("user", "id>?", 1)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 2)
|
||||
}
|
||||
|
||||
// []interface{}
|
||||
if r, err := db.BatchInsert("user", []interface{} {
|
||||
map[interface{}]interface{} {
|
||||
"id" : 2,
|
||||
"passport" : "t2",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T2",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
map[interface{}]interface{} {
|
||||
"id" : 3,
|
||||
"passport" : "t3",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T3",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
}, 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
n, _ := r.RowsAffected()
|
||||
gtest.Assert(n, 2)
|
||||
}
|
||||
})
|
||||
// batch insert map
|
||||
gtest.Case(t, func() {
|
||||
table := createTable()
|
||||
defer dropTable(table)
|
||||
result, err := db.BatchInsert(table, g.Map{
|
||||
"id" : 1,
|
||||
"passport" : "t1",
|
||||
"password" : "p1",
|
||||
"nickname" : "T1",
|
||||
"create_time" : gtime.Now().String(),
|
||||
})
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 1)
|
||||
})
|
||||
// batch insert struct
|
||||
gtest.Case(t, func() {
|
||||
table := createTable()
|
||||
defer dropTable(table)
|
||||
|
||||
type User struct {
|
||||
Id int `gconv:"id"`
|
||||
Passport string `gconv:"passport"`
|
||||
Password string `gconv:"password"`
|
||||
NickName string `gconv:"nickname"`
|
||||
CreateTime *gtime.Time `gconv:"create_time"`
|
||||
}
|
||||
user := &User{
|
||||
Id : 1,
|
||||
Passport : "t1",
|
||||
Password : "p1",
|
||||
NickName : "T1",
|
||||
CreateTime : gtime.Now(),
|
||||
}
|
||||
result, err := db.BatchInsert(table, user)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDbBase_Save(t *testing.T) {
|
||||
|
@ -90,29 +90,66 @@ func TestModel_Insert(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestModel_Batch(t *testing.T) {
|
||||
result, err := db.Table("user").Filter().Data(g.List{
|
||||
{
|
||||
"id" : 2,
|
||||
"uid" : 2,
|
||||
"passport" : "t2",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T2",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
{
|
||||
"id" : 3,
|
||||
"uid" : 3,
|
||||
"passport" : "t3",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T3",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
}).Batch(1).Insert()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 2)
|
||||
// batch insert
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table("user").Filter().Data(g.List{
|
||||
{
|
||||
"id" : 2,
|
||||
"uid" : 2,
|
||||
"passport" : "t2",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T2",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
{
|
||||
"id" : 3,
|
||||
"uid" : 3,
|
||||
"passport" : "t3",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T3",
|
||||
"create_time" : gtime.Now().String(),
|
||||
},
|
||||
}).Batch(1).Insert()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 2)
|
||||
})
|
||||
|
||||
// batch save
|
||||
gtest.Case(t, func() {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
result, err := db.Table(table).All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), INIT_DATA_SIZE)
|
||||
for _, v := range result {
|
||||
v["nickname"].Set(v["nickname"].String() + v["id"].String())
|
||||
}
|
||||
r, e := db.Table(table).Data(result).Save()
|
||||
gtest.Assert(e, nil)
|
||||
n, e := r.RowsAffected()
|
||||
gtest.Assert(e, nil)
|
||||
gtest.Assert(n, INIT_DATA_SIZE*2)
|
||||
})
|
||||
|
||||
// batch replace
|
||||
gtest.Case(t, func() {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
result, err := db.Table(table).All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), INIT_DATA_SIZE)
|
||||
for _, v := range result {
|
||||
v["nickname"].Set(v["nickname"].String() + v["id"].String())
|
||||
}
|
||||
r, e := db.Table(table).Data(result).Replace()
|
||||
gtest.Assert(e, nil)
|
||||
n, e := r.RowsAffected()
|
||||
gtest.Assert(e, nil)
|
||||
gtest.Assert(n, INIT_DATA_SIZE*2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestModel_Replace(t *testing.T) {
|
||||
@ -146,12 +183,23 @@ func TestModel_Save(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestModel_Update(t *testing.T) {
|
||||
result, err := db.Table("user").Data("passport", "t22").Where("passport=?", "t2").Update()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 1)
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table("user").Data("passport", "t22").Where("passport=?", "t2").Update()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 1)
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Table("user").Data("passport", "t2").Where("passport='t22'").Update()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestModel_Clone(t *testing.T) {
|
||||
|
@ -320,4 +320,24 @@ func Interfaces(i interface{}) []interface{} {
|
||||
}
|
||||
return array
|
||||
}
|
||||
}
|
||||
|
||||
// 将类型转换为[]map[string]interface{}类型.
|
||||
func Maps(i interface{}) []map[string]interface{} {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
if r, ok := i.([]map[string]interface{}); ok {
|
||||
return r
|
||||
} else {
|
||||
array := Interfaces(i)
|
||||
if len(array) == 0 {
|
||||
return nil
|
||||
}
|
||||
list := make([]map[string]interface{}, len(array))
|
||||
for k, v := range array {
|
||||
list[k] = Map(v)
|
||||
}
|
||||
return list
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user