2021-01-17 21:46:25 +08:00
|
|
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
2020-04-11 09:09:25 +08:00
|
|
|
//
|
|
|
|
// 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 gdb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2020-07-25 10:54:48 +08:00
|
|
|
"github.com/go-sql-driver/mysql"
|
2020-11-19 14:52:19 +08:00
|
|
|
"github.com/gogf/gf/container/gvar"
|
2020-04-11 09:09:25 +08:00
|
|
|
"github.com/gogf/gf/os/gcmd"
|
|
|
|
"github.com/gogf/gf/os/gtime"
|
|
|
|
"github.com/gogf/gf/test/gtest"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2021-02-27 23:58:36 +08:00
|
|
|
SCHEMA = "test_internal"
|
|
|
|
TestDbUser = "root"
|
|
|
|
TestDbPass = "12345678"
|
2020-04-11 09:09:25 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
db DB
|
|
|
|
configNode ConfigNode
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
parser, err := gcmd.Parse(map[string]bool{
|
|
|
|
"name": true,
|
|
|
|
"type": true,
|
|
|
|
}, false)
|
2021-02-07 14:39:32 +08:00
|
|
|
gtest.AssertNil(err)
|
2020-04-11 09:09:25 +08:00
|
|
|
configNode = ConfigNode{
|
|
|
|
Host: "127.0.0.1",
|
|
|
|
Port: "3306",
|
2021-02-27 23:58:36 +08:00
|
|
|
User: TestDbUser,
|
|
|
|
Pass: TestDbPass,
|
2020-04-11 09:09:25 +08:00
|
|
|
Name: parser.GetOpt("name", ""),
|
|
|
|
Type: parser.GetOpt("type", "mysql"),
|
|
|
|
Role: "master",
|
|
|
|
Charset: "utf8",
|
|
|
|
Weight: 1,
|
|
|
|
MaxIdleConnCount: 10,
|
|
|
|
MaxOpenConnCount: 10,
|
|
|
|
MaxConnLifetime: 600,
|
|
|
|
}
|
2020-12-14 19:34:02 +08:00
|
|
|
AddConfigNode(DefaultGroupName, configNode)
|
2020-04-11 09:09:25 +08:00
|
|
|
// Default db.
|
|
|
|
if r, err := New(); err != nil {
|
|
|
|
gtest.Error(err)
|
|
|
|
} else {
|
|
|
|
db = r
|
|
|
|
}
|
|
|
|
schemaTemplate := "CREATE DATABASE IF NOT EXISTS `%s` CHARACTER SET UTF8"
|
|
|
|
if _, err := db.Exec(fmt.Sprintf(schemaTemplate, SCHEMA)); err != nil {
|
|
|
|
gtest.Error(err)
|
|
|
|
}
|
|
|
|
db.SetSchema(SCHEMA)
|
|
|
|
}
|
|
|
|
|
|
|
|
func dropTable(table string) {
|
|
|
|
if _, err := db.Exec(fmt.Sprintf("DROP TABLE IF EXISTS `%s`", table)); err != nil {
|
|
|
|
gtest.Error(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_Func_FormatSqlWithArgs(t *testing.T) {
|
|
|
|
// mysql
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
var s string
|
|
|
|
s = FormatSqlWithArgs("select * from table where id>=? and sex=?", []interface{}{100, 1})
|
|
|
|
t.Assert(s, "select * from table where id>=100 and sex=1")
|
|
|
|
})
|
|
|
|
// mssql
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
var s string
|
2020-07-20 21:55:34 +08:00
|
|
|
s = FormatSqlWithArgs("select * from table where id>=@p1 and sex=@p2", []interface{}{100, 1})
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(s, "select * from table where id>=100 and sex=1")
|
|
|
|
})
|
|
|
|
// pgsql
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
var s string
|
2020-07-20 22:47:12 +08:00
|
|
|
s = FormatSqlWithArgs("select * from table where id>=$1 and sex=$2", []interface{}{100, 1})
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(s, "select * from table where id>=100 and sex=1")
|
|
|
|
})
|
|
|
|
// oracle
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
var s string
|
2020-07-15 20:21:04 +08:00
|
|
|
s = FormatSqlWithArgs("select * from table where id>=:v1 and sex=:v2", []interface{}{100, 1})
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(s, "select * from table where id>=100 and sex=1")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_Func_doQuoteWord(t *testing.T) {
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
array := map[string]string{
|
|
|
|
"user": "`user`",
|
|
|
|
"user u": "user u",
|
|
|
|
"user_detail": "`user_detail`",
|
|
|
|
"user,user_detail": "user,user_detail",
|
|
|
|
"user u, user_detail ut": "user u, user_detail ut",
|
|
|
|
"u.id asc": "u.id asc",
|
|
|
|
"u.id asc, ut.uid desc": "u.id asc, ut.uid desc",
|
|
|
|
}
|
|
|
|
for k, v := range array {
|
|
|
|
t.Assert(doQuoteWord(k, "`", "`"), v)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_Func_doQuoteString(t *testing.T) {
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
array := map[string]string{
|
|
|
|
"user": "`user`",
|
|
|
|
"user u": "`user` u",
|
|
|
|
"user,user_detail": "`user`,`user_detail`",
|
|
|
|
"user u, user_detail ut": "`user` u,`user_detail` ut",
|
|
|
|
"u.id, u.name, u.age": "`u`.`id`,`u`.`name`,`u`.`age`",
|
|
|
|
"u.id asc": "`u`.`id` asc",
|
|
|
|
"u.id asc, ut.uid desc": "`u`.`id` asc,`ut`.`uid` desc",
|
|
|
|
"user.user u, user.user_detail ut": "`user`.`user` u,`user`.`user_detail` ut",
|
|
|
|
// mssql global schema access with double dots.
|
|
|
|
"user..user u, user.user_detail ut": "`user`..`user` u,`user`.`user_detail` ut",
|
|
|
|
}
|
|
|
|
for k, v := range array {
|
|
|
|
t.Assert(doQuoteString(k, "`", "`"), v)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_Func_addTablePrefix(t *testing.T) {
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
prefix := ""
|
|
|
|
array := map[string]string{
|
|
|
|
"user": "`user`",
|
|
|
|
"user u": "`user` u",
|
|
|
|
"user as u": "`user` as u",
|
|
|
|
"user,user_detail": "`user`,`user_detail`",
|
|
|
|
"user u, user_detail ut": "`user` u,`user_detail` ut",
|
|
|
|
"`user`.user_detail": "`user`.`user_detail`",
|
|
|
|
"`user`.`user_detail`": "`user`.`user_detail`",
|
|
|
|
"user as u, user_detail as ut": "`user` as u,`user_detail` as ut",
|
|
|
|
"UserCenter.user as u, UserCenter.user_detail as ut": "`UserCenter`.`user` as u,`UserCenter`.`user_detail` as ut",
|
|
|
|
// mssql global schema access with double dots.
|
|
|
|
"UserCenter..user as u, user_detail as ut": "`UserCenter`..`user` as u,`user_detail` as ut",
|
|
|
|
}
|
|
|
|
for k, v := range array {
|
|
|
|
t.Assert(doHandleTableName(k, prefix, "`", "`"), v)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
prefix := "gf_"
|
|
|
|
array := map[string]string{
|
|
|
|
"user": "`gf_user`",
|
|
|
|
"user u": "`gf_user` u",
|
|
|
|
"user as u": "`gf_user` as u",
|
|
|
|
"user,user_detail": "`gf_user`,`gf_user_detail`",
|
|
|
|
"user u, user_detail ut": "`gf_user` u,`gf_user_detail` ut",
|
|
|
|
"`user`.user_detail": "`user`.`gf_user_detail`",
|
|
|
|
"`user`.`user_detail`": "`user`.`gf_user_detail`",
|
|
|
|
"user as u, user_detail as ut": "`gf_user` as u,`gf_user_detail` as ut",
|
|
|
|
"UserCenter.user as u, UserCenter.user_detail as ut": "`UserCenter`.`gf_user` as u,`UserCenter`.`gf_user_detail` as ut",
|
|
|
|
// mssql global schema access with double dots.
|
|
|
|
"UserCenter..user as u, user_detail as ut": "`UserCenter`..`gf_user` as u,`gf_user_detail` as ut",
|
|
|
|
}
|
|
|
|
for k, v := range array {
|
|
|
|
t.Assert(doHandleTableName(k, prefix, "`", "`"), v)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_Model_getSoftFieldName(t *testing.T) {
|
|
|
|
table1 := "soft_deleting_table_" + gtime.TimestampNanoStr()
|
|
|
|
if _, err := db.Exec(fmt.Sprintf(`
|
|
|
|
CREATE TABLE %s (
|
|
|
|
id int(11) NOT NULL,
|
|
|
|
name varchar(45) DEFAULT NULL,
|
|
|
|
create_at datetime DEFAULT NULL,
|
|
|
|
update_at datetime DEFAULT NULL,
|
|
|
|
delete_at datetime DEFAULT NULL,
|
|
|
|
PRIMARY KEY (id)
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
|
|
`, table1)); err != nil {
|
|
|
|
gtest.Error(err)
|
|
|
|
}
|
|
|
|
defer dropTable(table1)
|
|
|
|
|
|
|
|
table2 := "soft_deleting_table_" + gtime.TimestampNanoStr()
|
|
|
|
if _, err := db.Exec(fmt.Sprintf(`
|
|
|
|
CREATE TABLE %s (
|
|
|
|
id int(11) NOT NULL,
|
|
|
|
name varchar(45) DEFAULT NULL,
|
|
|
|
createat datetime DEFAULT NULL,
|
|
|
|
updateat datetime DEFAULT NULL,
|
|
|
|
deleteat datetime DEFAULT NULL,
|
|
|
|
PRIMARY KEY (id)
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
|
|
`, table2)); err != nil {
|
|
|
|
gtest.Error(err)
|
|
|
|
}
|
|
|
|
defer dropTable(table2)
|
|
|
|
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
2021-02-27 23:58:36 +08:00
|
|
|
model := db.Model(table1)
|
2020-10-20 21:01:39 +08:00
|
|
|
gtest.Assert(model.getSoftFieldNameCreated(table2), "createat")
|
|
|
|
gtest.Assert(model.getSoftFieldNameUpdated(table2), "updateat")
|
|
|
|
gtest.Assert(model.getSoftFieldNameDeleted(table2), "deleteat")
|
2020-04-11 09:09:25 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_Model_getConditionForSoftDeleting(t *testing.T) {
|
|
|
|
table1 := "soft_deleting_table_" + gtime.TimestampNanoStr()
|
|
|
|
if _, err := db.Exec(fmt.Sprintf(`
|
|
|
|
CREATE TABLE %s (
|
|
|
|
id1 int(11) NOT NULL,
|
|
|
|
name1 varchar(45) DEFAULT NULL,
|
|
|
|
create_at datetime DEFAULT NULL,
|
|
|
|
update_at datetime DEFAULT NULL,
|
|
|
|
delete_at datetime DEFAULT NULL,
|
|
|
|
PRIMARY KEY (id1)
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
|
|
`, table1)); err != nil {
|
|
|
|
gtest.Error(err)
|
|
|
|
}
|
|
|
|
defer dropTable(table1)
|
|
|
|
|
|
|
|
table2 := "soft_deleting_table_" + gtime.TimestampNanoStr()
|
|
|
|
if _, err := db.Exec(fmt.Sprintf(`
|
|
|
|
CREATE TABLE %s (
|
|
|
|
id2 int(11) NOT NULL,
|
|
|
|
name2 varchar(45) DEFAULT NULL,
|
|
|
|
createat datetime DEFAULT NULL,
|
|
|
|
updateat datetime DEFAULT NULL,
|
|
|
|
deleteat datetime DEFAULT NULL,
|
|
|
|
PRIMARY KEY (id2)
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
|
|
`, table2)); err != nil {
|
|
|
|
gtest.Error(err)
|
|
|
|
}
|
|
|
|
defer dropTable(table2)
|
|
|
|
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
2021-02-27 23:58:36 +08:00
|
|
|
model := db.Model(table1)
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(model.getConditionForSoftDeleting(), "`delete_at` IS NULL")
|
|
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
2021-02-27 23:58:36 +08:00
|
|
|
model := db.Model(fmt.Sprintf(`%s as t`, table1))
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(model.getConditionForSoftDeleting(), "`delete_at` IS NULL")
|
|
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
2021-02-27 23:58:36 +08:00
|
|
|
model := db.Model(fmt.Sprintf(`%s, %s`, table1, table2))
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(model.getConditionForSoftDeleting(), fmt.Sprintf(
|
|
|
|
"`%s`.`delete_at` IS NULL AND `%s`.`deleteat` IS NULL",
|
|
|
|
table1, table2,
|
|
|
|
))
|
|
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
2021-02-27 23:58:36 +08:00
|
|
|
model := db.Model(fmt.Sprintf(`%s t1, %s as t2`, table1, table2))
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(model.getConditionForSoftDeleting(), "`t1`.`delete_at` IS NULL AND `t2`.`deleteat` IS NULL")
|
|
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
2021-02-27 23:58:36 +08:00
|
|
|
model := db.Model(fmt.Sprintf(`%s as t1, %s as t2`, table1, table2))
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(model.getConditionForSoftDeleting(), "`t1`.`delete_at` IS NULL AND `t2`.`deleteat` IS NULL")
|
|
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
2021-02-27 23:58:36 +08:00
|
|
|
model := db.Model(fmt.Sprintf(`%s as t1`, table1)).LeftJoin(table2+" t2", "t2.id2=t1.id1")
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(model.getConditionForSoftDeleting(), "`t1`.`delete_at` IS NULL AND `t2`.`deleteat` IS NULL")
|
|
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
2021-02-27 23:58:36 +08:00
|
|
|
model := db.Model(fmt.Sprintf(`%s`, table1)).LeftJoin(table2, "t2.id2=t1.id1")
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(model.getConditionForSoftDeleting(), fmt.Sprintf(
|
|
|
|
"`%s`.`delete_at` IS NULL AND `%s`.`deleteat` IS NULL",
|
|
|
|
table1, table2,
|
|
|
|
))
|
|
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
2021-02-27 23:58:36 +08:00
|
|
|
model := db.Model(fmt.Sprintf(`%s`, table1)).LeftJoin(table2, "t2.id2=t1.id1").RightJoin(table2, "t2.id2=t1.id1")
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(model.getConditionForSoftDeleting(), fmt.Sprintf(
|
|
|
|
"`%s`.`delete_at` IS NULL AND `%s`.`deleteat` IS NULL AND `%s`.`deleteat` IS NULL",
|
|
|
|
table1, table2, table2,
|
|
|
|
))
|
|
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
2021-02-27 23:58:36 +08:00
|
|
|
model := db.Model(table1+" as t1").LeftJoin(table2+" as t2", "t2.id2=t1.id1").RightJoin(table2+" as t3 ", "t2.id2=t1.id1")
|
2020-04-11 09:09:25 +08:00
|
|
|
t.Assert(
|
|
|
|
model.getConditionForSoftDeleting(),
|
|
|
|
"`t1`.`delete_at` IS NULL AND `t2`.`deleteat` IS NULL AND `t3`.`deleteat` IS NULL",
|
|
|
|
)
|
|
|
|
})
|
|
|
|
}
|
2020-07-25 10:54:48 +08:00
|
|
|
|
|
|
|
// Fix issue: https://github.com/gogf/gf/issues/819
|
2020-10-10 17:29:38 +08:00
|
|
|
func Test_Func_ConvertDataForTableRecord(t *testing.T) {
|
2020-07-25 10:54:48 +08:00
|
|
|
type Test struct {
|
|
|
|
ResetPasswordTokenAt mysql.NullTime `orm:"reset_password_token_at"`
|
|
|
|
}
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
2020-10-10 17:29:38 +08:00
|
|
|
m := ConvertDataForTableRecord(new(Test))
|
2020-07-25 10:54:48 +08:00
|
|
|
t.Assert(len(m), 1)
|
|
|
|
t.AssertNE(m["reset_password_token_at"], nil)
|
|
|
|
t.Assert(m["reset_password_token_at"], new(mysql.NullTime))
|
|
|
|
})
|
|
|
|
}
|
2020-09-03 21:57:58 +08:00
|
|
|
|
|
|
|
func Test_isSubQuery(t *testing.T) {
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
t.Assert(isSubQuery("user"), false)
|
|
|
|
t.Assert(isSubQuery("user.uid"), false)
|
|
|
|
t.Assert(isSubQuery("u, user.uid"), false)
|
|
|
|
t.Assert(isSubQuery("select 1"), true)
|
|
|
|
})
|
|
|
|
}
|
2020-11-19 14:52:19 +08:00
|
|
|
|
|
|
|
func TestResult_Structs1(t *testing.T) {
|
|
|
|
type A struct {
|
|
|
|
Id int `orm:"id"`
|
|
|
|
}
|
|
|
|
type B struct {
|
|
|
|
*A
|
|
|
|
Name string
|
|
|
|
}
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
r := Result{
|
|
|
|
Record{"id": gvar.New(nil), "name": gvar.New("john")},
|
|
|
|
Record{"id": gvar.New(nil), "name": gvar.New("smith")},
|
|
|
|
}
|
|
|
|
array := make([]*B, 2)
|
|
|
|
err := r.Structs(&array)
|
2021-02-07 14:39:32 +08:00
|
|
|
t.AssertNil(err)
|
2020-11-19 14:52:19 +08:00
|
|
|
t.Assert(array[0].Id, 0)
|
|
|
|
t.Assert(array[1].Id, 0)
|
|
|
|
t.Assert(array[0].Name, "john")
|
|
|
|
t.Assert(array[1].Name, "smith")
|
|
|
|
})
|
|
|
|
}
|
2021-02-05 17:42:05 +08:00
|
|
|
|
|
|
|
// https://github.com/gogf/gf/issues/1159
|
|
|
|
func Test_ScanList_NoRecreate_PtrAttribute(t *testing.T) {
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
type S1 struct {
|
|
|
|
Id int
|
|
|
|
Name string
|
|
|
|
Age int
|
|
|
|
Score int
|
|
|
|
}
|
|
|
|
type S3 struct {
|
|
|
|
One *S1
|
|
|
|
}
|
|
|
|
var (
|
|
|
|
s []*S3
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
r1 := Result{
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(1),
|
|
|
|
"name": gvar.New("john"),
|
|
|
|
"age": gvar.New(16),
|
|
|
|
},
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(2),
|
|
|
|
"name": gvar.New("smith"),
|
|
|
|
"age": gvar.New(18),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err = r1.ScanList(&s, "One")
|
2021-02-07 14:39:32 +08:00
|
|
|
t.AssertNil(err)
|
2021-02-05 17:42:05 +08:00
|
|
|
t.Assert(len(s), 2)
|
|
|
|
t.Assert(s[0].One.Name, "john")
|
|
|
|
t.Assert(s[0].One.Age, 16)
|
|
|
|
t.Assert(s[1].One.Name, "smith")
|
|
|
|
t.Assert(s[1].One.Age, 18)
|
|
|
|
|
|
|
|
r2 := Result{
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(1),
|
|
|
|
"age": gvar.New(20),
|
|
|
|
},
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(2),
|
|
|
|
"age": gvar.New(21),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err = r2.ScanList(&s, "One", "One", "id:Id")
|
2021-02-07 14:39:32 +08:00
|
|
|
t.AssertNil(err)
|
2021-02-05 17:42:05 +08:00
|
|
|
t.Assert(len(s), 2)
|
|
|
|
t.Assert(s[0].One.Name, "john")
|
|
|
|
t.Assert(s[0].One.Age, 20)
|
|
|
|
t.Assert(s[1].One.Name, "smith")
|
|
|
|
t.Assert(s[1].One.Age, 21)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// https://github.com/gogf/gf/issues/1159
|
|
|
|
func Test_ScanList_NoRecreate_StructAttribute(t *testing.T) {
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
type S1 struct {
|
|
|
|
Id int
|
|
|
|
Name string
|
|
|
|
Age int
|
|
|
|
Score int
|
|
|
|
}
|
|
|
|
type S3 struct {
|
|
|
|
One S1
|
|
|
|
}
|
|
|
|
var (
|
|
|
|
s []*S3
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
r1 := Result{
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(1),
|
|
|
|
"name": gvar.New("john"),
|
|
|
|
"age": gvar.New(16),
|
|
|
|
},
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(2),
|
|
|
|
"name": gvar.New("smith"),
|
|
|
|
"age": gvar.New(18),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err = r1.ScanList(&s, "One")
|
2021-02-07 14:39:32 +08:00
|
|
|
t.AssertNil(err)
|
2021-02-05 17:42:05 +08:00
|
|
|
t.Assert(len(s), 2)
|
|
|
|
t.Assert(s[0].One.Name, "john")
|
|
|
|
t.Assert(s[0].One.Age, 16)
|
|
|
|
t.Assert(s[1].One.Name, "smith")
|
|
|
|
t.Assert(s[1].One.Age, 18)
|
|
|
|
|
|
|
|
r2 := Result{
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(1),
|
|
|
|
"age": gvar.New(20),
|
|
|
|
},
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(2),
|
|
|
|
"age": gvar.New(21),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err = r2.ScanList(&s, "One", "One", "id:Id")
|
2021-02-07 14:39:32 +08:00
|
|
|
t.AssertNil(err)
|
2021-02-05 17:42:05 +08:00
|
|
|
t.Assert(len(s), 2)
|
|
|
|
t.Assert(s[0].One.Name, "john")
|
|
|
|
t.Assert(s[0].One.Age, 20)
|
|
|
|
t.Assert(s[1].One.Name, "smith")
|
|
|
|
t.Assert(s[1].One.Age, 21)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// https://github.com/gogf/gf/issues/1159
|
|
|
|
func Test_ScanList_NoRecreate_SliceAttribute_Ptr(t *testing.T) {
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
type S1 struct {
|
|
|
|
Id int
|
|
|
|
Name string
|
|
|
|
Age int
|
|
|
|
Score int
|
|
|
|
}
|
|
|
|
type S2 struct {
|
|
|
|
Id int
|
|
|
|
Pid int
|
|
|
|
Name string
|
|
|
|
Age int
|
|
|
|
Score int
|
|
|
|
}
|
|
|
|
type S3 struct {
|
|
|
|
One *S1
|
|
|
|
Many []*S2
|
|
|
|
}
|
|
|
|
var (
|
|
|
|
s []*S3
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
r1 := Result{
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(1),
|
|
|
|
"name": gvar.New("john"),
|
|
|
|
"age": gvar.New(16),
|
|
|
|
},
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(2),
|
|
|
|
"name": gvar.New("smith"),
|
|
|
|
"age": gvar.New(18),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err = r1.ScanList(&s, "One")
|
2021-02-07 14:39:32 +08:00
|
|
|
t.AssertNil(err)
|
2021-02-05 17:42:05 +08:00
|
|
|
t.Assert(len(s), 2)
|
|
|
|
t.Assert(s[0].One.Name, "john")
|
|
|
|
t.Assert(s[0].One.Age, 16)
|
|
|
|
t.Assert(s[1].One.Name, "smith")
|
|
|
|
t.Assert(s[1].One.Age, 18)
|
|
|
|
|
|
|
|
r2 := Result{
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(100),
|
|
|
|
"pid": gvar.New(1),
|
|
|
|
"age": gvar.New(30),
|
|
|
|
"name": gvar.New("john"),
|
|
|
|
},
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(200),
|
|
|
|
"pid": gvar.New(1),
|
|
|
|
"age": gvar.New(31),
|
|
|
|
"name": gvar.New("smith"),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err = r2.ScanList(&s, "Many", "One", "pid:Id")
|
|
|
|
//fmt.Printf("%+v", err)
|
2021-02-07 14:39:32 +08:00
|
|
|
t.AssertNil(err)
|
2021-02-05 17:42:05 +08:00
|
|
|
t.Assert(len(s), 2)
|
|
|
|
t.Assert(s[0].One.Name, "john")
|
|
|
|
t.Assert(s[0].One.Age, 16)
|
|
|
|
t.Assert(len(s[0].Many), 2)
|
|
|
|
t.Assert(s[0].Many[0].Name, "john")
|
|
|
|
t.Assert(s[0].Many[0].Age, 30)
|
|
|
|
t.Assert(s[0].Many[1].Name, "smith")
|
|
|
|
t.Assert(s[0].Many[1].Age, 31)
|
|
|
|
|
|
|
|
t.Assert(s[1].One.Name, "smith")
|
|
|
|
t.Assert(s[1].One.Age, 18)
|
|
|
|
t.Assert(len(s[1].Many), 0)
|
|
|
|
|
|
|
|
r3 := Result{
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(100),
|
|
|
|
"pid": gvar.New(1),
|
|
|
|
"age": gvar.New(40),
|
|
|
|
},
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(200),
|
|
|
|
"pid": gvar.New(1),
|
|
|
|
"age": gvar.New(41),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err = r3.ScanList(&s, "Many", "One", "pid:Id")
|
|
|
|
//fmt.Printf("%+v", err)
|
2021-02-07 14:39:32 +08:00
|
|
|
t.AssertNil(err)
|
2021-02-05 17:42:05 +08:00
|
|
|
t.Assert(len(s), 2)
|
|
|
|
t.Assert(s[0].One.Name, "john")
|
|
|
|
t.Assert(s[0].One.Age, 16)
|
|
|
|
t.Assert(len(s[0].Many), 2)
|
|
|
|
t.Assert(s[0].Many[0].Name, "john")
|
|
|
|
t.Assert(s[0].Many[0].Age, 40)
|
|
|
|
t.Assert(s[0].Many[1].Name, "smith")
|
|
|
|
t.Assert(s[0].Many[1].Age, 41)
|
|
|
|
|
|
|
|
t.Assert(s[1].One.Name, "smith")
|
|
|
|
t.Assert(s[1].One.Age, 18)
|
|
|
|
t.Assert(len(s[1].Many), 0)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// https://github.com/gogf/gf/issues/1159
|
|
|
|
func Test_ScanList_NoRecreate_SliceAttribute_Struct(t *testing.T) {
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
|
|
type S1 struct {
|
|
|
|
Id int
|
|
|
|
Name string
|
|
|
|
Age int
|
|
|
|
Score int
|
|
|
|
}
|
|
|
|
type S2 struct {
|
|
|
|
Id int
|
|
|
|
Pid int
|
|
|
|
Name string
|
|
|
|
Age int
|
|
|
|
Score int
|
|
|
|
}
|
|
|
|
type S3 struct {
|
|
|
|
One S1
|
|
|
|
Many []S2
|
|
|
|
}
|
|
|
|
var (
|
|
|
|
s []S3
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
r1 := Result{
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(1),
|
|
|
|
"name": gvar.New("john"),
|
|
|
|
"age": gvar.New(16),
|
|
|
|
},
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(2),
|
|
|
|
"name": gvar.New("smith"),
|
|
|
|
"age": gvar.New(18),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err = r1.ScanList(&s, "One")
|
2021-02-07 14:39:32 +08:00
|
|
|
t.AssertNil(err)
|
2021-02-05 17:42:05 +08:00
|
|
|
t.Assert(len(s), 2)
|
|
|
|
t.Assert(s[0].One.Name, "john")
|
|
|
|
t.Assert(s[0].One.Age, 16)
|
|
|
|
t.Assert(s[1].One.Name, "smith")
|
|
|
|
t.Assert(s[1].One.Age, 18)
|
|
|
|
|
|
|
|
r2 := Result{
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(100),
|
|
|
|
"pid": gvar.New(1),
|
|
|
|
"age": gvar.New(30),
|
|
|
|
"name": gvar.New("john"),
|
|
|
|
},
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(200),
|
|
|
|
"pid": gvar.New(1),
|
|
|
|
"age": gvar.New(31),
|
|
|
|
"name": gvar.New("smith"),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err = r2.ScanList(&s, "Many", "One", "pid:Id")
|
|
|
|
//fmt.Printf("%+v", err)
|
2021-02-07 14:39:32 +08:00
|
|
|
t.AssertNil(err)
|
2021-02-05 17:42:05 +08:00
|
|
|
t.Assert(len(s), 2)
|
|
|
|
t.Assert(s[0].One.Name, "john")
|
|
|
|
t.Assert(s[0].One.Age, 16)
|
|
|
|
t.Assert(len(s[0].Many), 2)
|
|
|
|
t.Assert(s[0].Many[0].Name, "john")
|
|
|
|
t.Assert(s[0].Many[0].Age, 30)
|
|
|
|
t.Assert(s[0].Many[1].Name, "smith")
|
|
|
|
t.Assert(s[0].Many[1].Age, 31)
|
|
|
|
|
|
|
|
t.Assert(s[1].One.Name, "smith")
|
|
|
|
t.Assert(s[1].One.Age, 18)
|
|
|
|
t.Assert(len(s[1].Many), 0)
|
|
|
|
|
|
|
|
r3 := Result{
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(100),
|
|
|
|
"pid": gvar.New(1),
|
|
|
|
"age": gvar.New(40),
|
|
|
|
},
|
|
|
|
Record{
|
|
|
|
"id": gvar.New(200),
|
|
|
|
"pid": gvar.New(1),
|
|
|
|
"age": gvar.New(41),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err = r3.ScanList(&s, "Many", "One", "pid:Id")
|
|
|
|
//fmt.Printf("%+v", err)
|
2021-02-07 14:39:32 +08:00
|
|
|
t.AssertNil(err)
|
2021-02-05 17:42:05 +08:00
|
|
|
t.Assert(len(s), 2)
|
|
|
|
t.Assert(s[0].One.Name, "john")
|
|
|
|
t.Assert(s[0].One.Age, 16)
|
|
|
|
t.Assert(len(s[0].Many), 2)
|
|
|
|
t.Assert(s[0].Many[0].Name, "john")
|
|
|
|
t.Assert(s[0].Many[0].Age, 40)
|
|
|
|
t.Assert(s[0].Many[1].Name, "smith")
|
|
|
|
t.Assert(s[0].Many[1].Age, 41)
|
|
|
|
|
|
|
|
t.Assert(s[1].One.Name, "smith")
|
|
|
|
t.Assert(s[1].One.Age, 18)
|
|
|
|
t.Assert(len(s[1].Many), 0)
|
|
|
|
})
|
|
|
|
}
|