Merge branch 'fix/4086' of github.com:gogf/gf into fix/4086

This commit is contained in:
John Guo
2025-01-09 14:01:21 +08:00
5 changed files with 5351 additions and 5351 deletions

View File

@ -7,129 +7,129 @@
package mysql_test
import (
"context"
"database/sql"
"fmt"
"testing"
"context"
"database/sql"
"fmt"
"testing"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/test/gtest"
)
func Test_Model_Hook_Select(t *testing.T) {
table := createInitTable()
defer dropTable(table)
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
m := db.Model(table).Hook(gdb.HookHandler{
Select: func(ctx context.Context, in *gdb.HookSelectInput) (result gdb.Result, err error) {
result, err = in.Next(ctx)
if err != nil {
return
}
for i, record := range result {
record["test"] = gdb.NewValue(100 + record["id"].Int())
result[i] = record
}
return
},
})
all, err := m.Where(`id > 6`).OrderAsc(`id`).All()
t.AssertNil(err)
t.Assert(len(all), 4)
t.Assert(all[0]["id"].Int(), 7)
t.Assert(all[0]["test"].Int(), 107)
t.Assert(all[1]["test"].Int(), 108)
t.Assert(all[2]["test"].Int(), 109)
t.Assert(all[3]["test"].Int(), 110)
})
gtest.C(t, func(t *gtest.T) {
m := db.Model(table).Hook(gdb.HookHandler{
Select: func(ctx context.Context, in *gdb.HookSelectInput) (result gdb.Result, err error) {
result, err = in.Next(ctx)
if err != nil {
return
}
for i, record := range result {
record["test"] = gdb.NewValue(100 + record["id"].Int())
result[i] = record
}
return
},
})
all, err := m.Where(`id > 6`).OrderAsc(`id`).All()
t.AssertNil(err)
t.Assert(len(all), 4)
t.Assert(all[0]["id"].Int(), 7)
t.Assert(all[0]["test"].Int(), 107)
t.Assert(all[1]["test"].Int(), 108)
t.Assert(all[2]["test"].Int(), 109)
t.Assert(all[3]["test"].Int(), 110)
})
}
func Test_Model_Hook_Insert(t *testing.T) {
table := createTable()
defer dropTable(table)
table := createTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
m := db.Model(table).Hook(gdb.HookHandler{
Insert: func(ctx context.Context, in *gdb.HookInsertInput) (result sql.Result, err error) {
for i, item := range in.Data {
item["passport"] = fmt.Sprintf(`test_port_%d`, item["id"])
item["nickname"] = fmt.Sprintf(`test_name_%d`, item["id"])
in.Data[i] = item
}
return in.Next(ctx)
},
})
_, err := m.Insert(g.Map{
"id": 1,
"nickname": "name_1",
})
t.AssertNil(err)
one, err := m.One()
t.AssertNil(err)
t.Assert(one["id"].Int(), 1)
t.Assert(one["passport"], `test_port_1`)
t.Assert(one["nickname"], `test_name_1`)
})
gtest.C(t, func(t *gtest.T) {
m := db.Model(table).Hook(gdb.HookHandler{
Insert: func(ctx context.Context, in *gdb.HookInsertInput) (result sql.Result, err error) {
for i, item := range in.Data {
item["passport"] = fmt.Sprintf(`test_port_%d`, item["id"])
item["nickname"] = fmt.Sprintf(`test_name_%d`, item["id"])
in.Data[i] = item
}
return in.Next(ctx)
},
})
_, err := m.Insert(g.Map{
"id": 1,
"nickname": "name_1",
})
t.AssertNil(err)
one, err := m.One()
t.AssertNil(err)
t.Assert(one["id"].Int(), 1)
t.Assert(one["passport"], `test_port_1`)
t.Assert(one["nickname"], `test_name_1`)
})
}
func Test_Model_Hook_Update(t *testing.T) {
table := createInitTable()
defer dropTable(table)
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
m := db.Model(table).Hook(gdb.HookHandler{
Update: func(ctx context.Context, in *gdb.HookUpdateInput) (result sql.Result, err error) {
switch value := in.Data.(type) {
case gdb.List:
for i, data := range value {
data["passport"] = `port`
data["nickname"] = `name`
value[i] = data
}
in.Data = value
gtest.C(t, func(t *gtest.T) {
m := db.Model(table).Hook(gdb.HookHandler{
Update: func(ctx context.Context, in *gdb.HookUpdateInput) (result sql.Result, err error) {
switch value := in.Data.(type) {
case gdb.List:
for i, data := range value {
data["passport"] = `port`
data["nickname"] = `name`
value[i] = data
}
in.Data = value
case gdb.Map:
value["passport"] = `port`
value["nickname"] = `name`
in.Data = value
}
return in.Next(ctx)
},
})
_, err := m.Data(g.Map{
"nickname": "name_1",
}).WherePri(1).Update()
t.AssertNil(err)
case gdb.Map:
value["passport"] = `port`
value["nickname"] = `name`
in.Data = value
}
return in.Next(ctx)
},
})
_, err := m.Data(g.Map{
"nickname": "name_1",
}).WherePri(1).Update()
t.AssertNil(err)
one, err := m.One()
t.AssertNil(err)
t.Assert(one["id"].Int(), 1)
t.Assert(one["passport"], `port`)
t.Assert(one["nickname"], `name`)
})
one, err := m.One()
t.AssertNil(err)
t.Assert(one["id"].Int(), 1)
t.Assert(one["passport"], `port`)
t.Assert(one["nickname"], `name`)
})
}
func Test_Model_Hook_Delete(t *testing.T) {
table := createInitTable()
defer dropTable(table)
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
m := db.Model(table).Hook(gdb.HookHandler{
Delete: func(ctx context.Context, in *gdb.HookDeleteInput) (result sql.Result, err error) {
return db.Model(table).Data(g.Map{
"nickname": `deleted`,
}).Where(in.Condition).Update()
},
})
_, err := m.Where(1).Delete()
t.AssertNil(err)
gtest.C(t, func(t *gtest.T) {
m := db.Model(table).Hook(gdb.HookHandler{
Delete: func(ctx context.Context, in *gdb.HookDeleteInput) (result sql.Result, err error) {
return db.Model(table).Data(g.Map{
"nickname": `deleted`,
}).Where(in.Condition).Update()
},
})
_, err := m.Where(1).Delete()
t.AssertNil(err)
all, err := m.All()
t.AssertNil(err)
for _, item := range all {
t.Assert(item["nickname"].String(), `deleted`)
}
})
all, err := m.All()
t.AssertNil(err)
for _, item := range all {
t.Assert(item["nickname"].String(), `deleted`)
}
})
}

View File

@ -7,476 +7,476 @@
package mysql_test
import (
"database/sql"
"reflect"
"testing"
"database/sql"
"reflect"
"testing"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/util/gconv"
)
func Test_Model_Embedded_Insert(t *testing.T) {
table := createTable()
defer dropTable(table)
table := createTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
type Base struct {
Id int `json:"id"`
Uid int `json:"uid"`
CreateTime string `json:"create_time"`
}
type User struct {
Base
Passport string `json:"passport"`
Password string `json:"password"`
Nickname string `json:"nickname"`
}
result, err := db.Model(table).Data(User{
Passport: "john-test",
Password: "123456",
Nickname: "John",
Base: Base{
Id: 100,
Uid: 100,
CreateTime: gtime.Now().String(),
},
}).Insert()
t.AssertNil(err)
n, _ := result.RowsAffected()
t.Assert(n, 1)
value, err := db.Model(table).Fields("passport").Where("id=100").Value()
t.AssertNil(err)
t.Assert(value.String(), "john-test")
})
gtest.C(t, func(t *gtest.T) {
type Base struct {
Id int `json:"id"`
Uid int `json:"uid"`
CreateTime string `json:"create_time"`
}
type User struct {
Base
Passport string `json:"passport"`
Password string `json:"password"`
Nickname string `json:"nickname"`
}
result, err := db.Model(table).Data(User{
Passport: "john-test",
Password: "123456",
Nickname: "John",
Base: Base{
Id: 100,
Uid: 100,
CreateTime: gtime.Now().String(),
},
}).Insert()
t.AssertNil(err)
n, _ := result.RowsAffected()
t.Assert(n, 1)
value, err := db.Model(table).Fields("passport").Where("id=100").Value()
t.AssertNil(err)
t.Assert(value.String(), "john-test")
})
}
func Test_Model_Embedded_MapToStruct(t *testing.T) {
table := createTable()
defer dropTable(table)
table := createTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
type Ids struct {
Id int `json:"id"`
Uid int `json:"uid"`
}
type Base struct {
Ids
CreateTime string `json:"create_time"`
}
type User struct {
Base
Passport string `json:"passport"`
Password string `json:"password"`
Nickname string `json:"nickname"`
}
data := g.Map{
"id": 100,
"uid": 101,
"passport": "t1",
"password": "123456",
"nickname": "T1",
"create_time": gtime.Now().String(),
}
result, err := db.Model(table).Data(data).Insert()
t.AssertNil(err)
n, _ := result.RowsAffected()
t.Assert(n, 1)
gtest.C(t, func(t *gtest.T) {
type Ids struct {
Id int `json:"id"`
Uid int `json:"uid"`
}
type Base struct {
Ids
CreateTime string `json:"create_time"`
}
type User struct {
Base
Passport string `json:"passport"`
Password string `json:"password"`
Nickname string `json:"nickname"`
}
data := g.Map{
"id": 100,
"uid": 101,
"passport": "t1",
"password": "123456",
"nickname": "T1",
"create_time": gtime.Now().String(),
}
result, err := db.Model(table).Data(data).Insert()
t.AssertNil(err)
n, _ := result.RowsAffected()
t.Assert(n, 1)
one, err := db.Model(table).Where("id=100").One()
t.AssertNil(err)
one, err := db.Model(table).Where("id=100").One()
t.AssertNil(err)
user := new(User)
user := new(User)
t.Assert(one.Struct(user), nil)
t.Assert(user.Id, data["id"])
t.Assert(user.Passport, data["passport"])
t.Assert(user.Password, data["password"])
t.Assert(user.Nickname, data["nickname"])
t.Assert(user.CreateTime, data["create_time"])
})
t.Assert(one.Struct(user), nil)
t.Assert(user.Id, data["id"])
t.Assert(user.Passport, data["passport"])
t.Assert(user.Password, data["password"])
t.Assert(user.Nickname, data["nickname"])
t.Assert(user.CreateTime, data["create_time"])
})
}
func Test_Struct_Pointer_Attribute(t *testing.T) {
table := createInitTable()
defer dropTable(table)
table := createInitTable()
defer dropTable(table)
type User struct {
Id *int
Passport *string
Password *string
Nickname string
}
type User struct {
Id *int
Passport *string
Password *string
Nickname string
}
gtest.C(t, func(t *gtest.T) {
one, err := db.Model(table).WherePri(1).One()
t.AssertNil(err)
user := new(User)
err = one.Struct(user)
t.AssertNil(err)
t.Assert(*user.Id, 1)
t.Assert(*user.Passport, "user_1")
t.Assert(*user.Password, "pass_1")
t.Assert(user.Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
user := new(User)
err := db.Model(table).Scan(user, "id=1")
t.AssertNil(err)
t.Assert(*user.Id, 1)
t.Assert(*user.Passport, "user_1")
t.Assert(*user.Password, "pass_1")
t.Assert(user.Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
var user *User
err := db.Model(table).Scan(&user, "id=1")
t.AssertNil(err)
t.Assert(*user.Id, 1)
t.Assert(*user.Passport, "user_1")
t.Assert(*user.Password, "pass_1")
t.Assert(user.Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
one, err := db.Model(table).WherePri(1).One()
t.AssertNil(err)
user := new(User)
err = one.Struct(user)
t.AssertNil(err)
t.Assert(*user.Id, 1)
t.Assert(*user.Passport, "user_1")
t.Assert(*user.Password, "pass_1")
t.Assert(user.Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
user := new(User)
err := db.Model(table).Scan(user, "id=1")
t.AssertNil(err)
t.Assert(*user.Id, 1)
t.Assert(*user.Passport, "user_1")
t.Assert(*user.Password, "pass_1")
t.Assert(user.Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
var user *User
err := db.Model(table).Scan(&user, "id=1")
t.AssertNil(err)
t.Assert(*user.Id, 1)
t.Assert(*user.Passport, "user_1")
t.Assert(*user.Password, "pass_1")
t.Assert(user.Nickname, "name_1")
})
}
func Test_Structs_Pointer_Attribute(t *testing.T) {
table := createInitTable()
defer dropTable(table)
table := createInitTable()
defer dropTable(table)
type User struct {
Id *int
Passport *string
Password *string
Nickname string
}
// All
gtest.C(t, func(t *gtest.T) {
one, err := db.Model(table).All("id < 3")
t.AssertNil(err)
users := make([]User, 0)
err = one.Structs(&users)
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
one, err := db.Model(table).All("id < 3")
t.AssertNil(err)
users := make([]*User, 0)
err = one.Structs(&users)
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
var users []User
one, err := db.Model(table).All("id < 3")
t.AssertNil(err)
err = one.Structs(&users)
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
var users []*User
one, err := db.Model(table).All("id < 3")
t.AssertNil(err)
err = one.Structs(&users)
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
// Structs
gtest.C(t, func(t *gtest.T) {
users := make([]User, 0)
err := db.Model(table).Scan(&users, "id < 3")
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
users := make([]*User, 0)
err := db.Model(table).Scan(&users, "id < 3")
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
var users []User
err := db.Model(table).Scan(&users, "id < 3")
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
var users []*User
err := db.Model(table).Scan(&users, "id < 3")
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
type User struct {
Id *int
Passport *string
Password *string
Nickname string
}
// All
gtest.C(t, func(t *gtest.T) {
one, err := db.Model(table).All("id < 3")
t.AssertNil(err)
users := make([]User, 0)
err = one.Structs(&users)
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
one, err := db.Model(table).All("id < 3")
t.AssertNil(err)
users := make([]*User, 0)
err = one.Structs(&users)
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
var users []User
one, err := db.Model(table).All("id < 3")
t.AssertNil(err)
err = one.Structs(&users)
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
var users []*User
one, err := db.Model(table).All("id < 3")
t.AssertNil(err)
err = one.Structs(&users)
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
// Structs
gtest.C(t, func(t *gtest.T) {
users := make([]User, 0)
err := db.Model(table).Scan(&users, "id < 3")
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
users := make([]*User, 0)
err := db.Model(table).Scan(&users, "id < 3")
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
var users []User
err := db.Model(table).Scan(&users, "id < 3")
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
gtest.C(t, func(t *gtest.T) {
var users []*User
err := db.Model(table).Scan(&users, "id < 3")
t.AssertNil(err)
t.Assert(len(users), 2)
t.Assert(*users[0].Id, 1)
t.Assert(*users[0].Passport, "user_1")
t.Assert(*users[0].Password, "pass_1")
t.Assert(users[0].Nickname, "name_1")
})
}
func Test_Struct_Empty(t *testing.T) {
table := createTable()
defer dropTable(table)
table := createTable()
defer dropTable(table)
type User struct {
Id int
Passport string
Password string
Nickname string
}
type User struct {
Id int
Passport string
Password string
Nickname string
}
gtest.C(t, func(t *gtest.T) {
user := new(User)
err := db.Model(table).Where("id=100").Scan(user)
t.Assert(err, sql.ErrNoRows)
t.AssertNE(user, nil)
})
gtest.C(t, func(t *gtest.T) {
user := new(User)
err := db.Model(table).Where("id=100").Scan(user)
t.Assert(err, sql.ErrNoRows)
t.AssertNE(user, nil)
})
gtest.C(t, func(t *gtest.T) {
one, err := db.Model(table).Where("id=100").One()
t.AssertNil(err)
var user *User
t.Assert(one.Struct(&user), nil)
t.Assert(user, nil)
})
gtest.C(t, func(t *gtest.T) {
one, err := db.Model(table).Where("id=100").One()
t.AssertNil(err)
var user *User
t.Assert(one.Struct(&user), nil)
t.Assert(user, nil)
})
gtest.C(t, func(t *gtest.T) {
var user *User
err := db.Model(table).Where("id=100").Scan(&user)
t.AssertNil(err)
t.Assert(user, nil)
})
gtest.C(t, func(t *gtest.T) {
var user *User
err := db.Model(table).Where("id=100").Scan(&user)
t.AssertNil(err)
t.Assert(user, nil)
})
}
func Test_Structs_Empty(t *testing.T) {
table := createTable()
defer dropTable(table)
table := createTable()
defer dropTable(table)
type User struct {
Id int
Passport string
Password string
Nickname string
}
type User struct {
Id int
Passport string
Password string
Nickname string
}
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
users := make([]User, 0)
t.Assert(all.Structs(&users), nil)
})
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
users := make([]User, 10)
t.Assert(all.Structs(&users), sql.ErrNoRows)
})
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
var users []User
t.Assert(all.Structs(&users), nil)
})
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
users := make([]User, 0)
t.Assert(all.Structs(&users), nil)
})
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
users := make([]User, 10)
t.Assert(all.Structs(&users), sql.ErrNoRows)
})
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
var users []User
t.Assert(all.Structs(&users), nil)
})
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
users := make([]*User, 0)
t.Assert(all.Structs(&users), nil)
})
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
users := make([]*User, 10)
t.Assert(all.Structs(&users), sql.ErrNoRows)
})
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
var users []*User
t.Assert(all.Structs(&users), nil)
})
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
users := make([]*User, 0)
t.Assert(all.Structs(&users), nil)
})
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
users := make([]*User, 10)
t.Assert(all.Structs(&users), sql.ErrNoRows)
})
gtest.C(t, func(t *gtest.T) {
all, err := db.Model(table).Where("id>100").All()
t.AssertNil(err)
var users []*User
t.Assert(all.Structs(&users), nil)
})
}
type MyTime struct {
gtime.Time
gtime.Time
}
type MyTimeSt struct {
CreateTime MyTime
CreateTime MyTime
}
func (st *MyTimeSt) UnmarshalValue(v interface{}) error {
m := gconv.Map(v)
t, err := gtime.StrToTime(gconv.String(m["create_time"]))
if err != nil {
return err
}
st.CreateTime = MyTime{*t}
return nil
m := gconv.Map(v)
t, err := gtime.StrToTime(gconv.String(m["create_time"]))
if err != nil {
return err
}
st.CreateTime = MyTime{*t}
return nil
}
func Test_Model_Scan_CustomType_Time(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
st := new(MyTimeSt)
err := db.Model(table).Fields("create_time").Scan(st)
t.AssertNil(err)
t.Assert(st.CreateTime.String(), "2018-10-24 10:00:00")
})
gtest.C(t, func(t *gtest.T) {
var stSlice []*MyTimeSt
err := db.Model(table).Fields("create_time").Scan(&stSlice)
t.AssertNil(err)
t.Assert(len(stSlice), TableSize)
t.Assert(stSlice[0].CreateTime.String(), "2018-10-24 10:00:00")
t.Assert(stSlice[9].CreateTime.String(), "2018-10-24 10:00:00")
})
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
st := new(MyTimeSt)
err := db.Model(table).Fields("create_time").Scan(st)
t.AssertNil(err)
t.Assert(st.CreateTime.String(), "2018-10-24 10:00:00")
})
gtest.C(t, func(t *gtest.T) {
var stSlice []*MyTimeSt
err := db.Model(table).Fields("create_time").Scan(&stSlice)
t.AssertNil(err)
t.Assert(len(stSlice), TableSize)
t.Assert(stSlice[0].CreateTime.String(), "2018-10-24 10:00:00")
t.Assert(stSlice[9].CreateTime.String(), "2018-10-24 10:00:00")
})
}
func Test_Model_Scan_CustomType_String(t *testing.T) {
type MyString string
type MyString string
type MyStringSt struct {
Passport MyString
}
type MyStringSt struct {
Passport MyString
}
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
st := new(MyStringSt)
err := db.Model(table).Fields("Passport").WherePri(1).Scan(st)
t.AssertNil(err)
t.Assert(st.Passport, "user_1")
})
gtest.C(t, func(t *gtest.T) {
var sts []MyStringSt
err := db.Model(table).Fields("Passport").Order("id asc").Scan(&sts)
t.AssertNil(err)
t.Assert(len(sts), TableSize)
t.Assert(sts[0].Passport, "user_1")
})
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
st := new(MyStringSt)
err := db.Model(table).Fields("Passport").WherePri(1).Scan(st)
t.AssertNil(err)
t.Assert(st.Passport, "user_1")
})
gtest.C(t, func(t *gtest.T) {
var sts []MyStringSt
err := db.Model(table).Fields("Passport").Order("id asc").Scan(&sts)
t.AssertNil(err)
t.Assert(len(sts), TableSize)
t.Assert(sts[0].Passport, "user_1")
})
}
type User struct {
Id int
Passport string
Password string
Nickname string
CreateTime *gtime.Time
Id int
Passport string
Password string
Nickname string
CreateTime *gtime.Time
}
func (user *User) UnmarshalValue(value interface{}) error {
if record, ok := value.(gdb.Record); ok {
*user = User{
Id: record["id"].Int(),
Passport: record["passport"].String(),
Password: "",
Nickname: record["nickname"].String(),
CreateTime: record["create_time"].GTime(),
}
return nil
}
return gerror.NewCodef(gcode.CodeInvalidParameter, `unsupported value type for UnmarshalValue: %v`, reflect.TypeOf(value))
if record, ok := value.(gdb.Record); ok {
*user = User{
Id: record["id"].Int(),
Passport: record["passport"].String(),
Password: "",
Nickname: record["nickname"].String(),
CreateTime: record["create_time"].GTime(),
}
return nil
}
return gerror.NewCodef(gcode.CodeInvalidParameter, `unsupported value type for UnmarshalValue: %v`, reflect.TypeOf(value))
}
func Test_Model_Scan_UnmarshalValue(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
var users []*User
err := db.Model(table).Order("id asc").Scan(&users)
t.AssertNil(err)
t.Assert(len(users), TableSize)
t.Assert(users[0].Id, 1)
t.Assert(users[0].Passport, "user_1")
t.Assert(users[0].Password, "")
t.Assert(users[0].Nickname, "name_1")
t.Assert(users[0].CreateTime.String(), CreateTime)
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
var users []*User
err := db.Model(table).Order("id asc").Scan(&users)
t.AssertNil(err)
t.Assert(len(users), TableSize)
t.Assert(users[0].Id, 1)
t.Assert(users[0].Passport, "user_1")
t.Assert(users[0].Password, "")
t.Assert(users[0].Nickname, "name_1")
t.Assert(users[0].CreateTime.String(), CreateTime)
t.Assert(users[9].Id, 10)
t.Assert(users[9].Passport, "user_10")
t.Assert(users[9].Password, "")
t.Assert(users[9].Nickname, "name_10")
t.Assert(users[9].CreateTime.String(), CreateTime)
})
t.Assert(users[9].Id, 10)
t.Assert(users[9].Passport, "user_10")
t.Assert(users[9].Password, "")
t.Assert(users[9].Nickname, "name_10")
t.Assert(users[9].CreateTime.String(), CreateTime)
})
}
func Test_Model_Scan_Map(t *testing.T) {
table := createInitTable()
defer dropTable(table)
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
var users []*User
err := db.Model(table).Order("id asc").Scan(&users)
t.AssertNil(err)
t.Assert(len(users), TableSize)
t.Assert(users[0].Id, 1)
t.Assert(users[0].Passport, "user_1")
t.Assert(users[0].Password, "")
t.Assert(users[0].Nickname, "name_1")
t.Assert(users[0].CreateTime.String(), CreateTime)
gtest.C(t, func(t *gtest.T) {
var users []*User
err := db.Model(table).Order("id asc").Scan(&users)
t.AssertNil(err)
t.Assert(len(users), TableSize)
t.Assert(users[0].Id, 1)
t.Assert(users[0].Passport, "user_1")
t.Assert(users[0].Password, "")
t.Assert(users[0].Nickname, "name_1")
t.Assert(users[0].CreateTime.String(), CreateTime)
t.Assert(users[9].Id, 10)
t.Assert(users[9].Passport, "user_10")
t.Assert(users[9].Password, "")
t.Assert(users[9].Nickname, "name_10")
t.Assert(users[9].CreateTime.String(), CreateTime)
})
t.Assert(users[9].Id, 10)
t.Assert(users[9].Passport, "user_10")
t.Assert(users[9].Password, "")
t.Assert(users[9].Nickname, "name_10")
t.Assert(users[9].CreateTime.String(), CreateTime)
})
}
func Test_Scan_AutoFilteringByStructAttributes(t *testing.T) {
table := createInitTable()
defer dropTable(table)
table := createInitTable()
defer dropTable(table)
type User struct {
Id int
Passport string
}
// db.SetDebug(true)
gtest.C(t, func(t *gtest.T) {
var user *User
err := db.Model(table).OrderAsc("id").Scan(&user)
t.AssertNil(err)
t.Assert(user.Id, 1)
})
gtest.C(t, func(t *gtest.T) {
var users []User
err := db.Model(table).OrderAsc("id").Scan(&users)
t.AssertNil(err)
t.Assert(len(users), TableSize)
t.Assert(users[0].Id, 1)
})
type User struct {
Id int
Passport string
}
// db.SetDebug(true)
gtest.C(t, func(t *gtest.T) {
var user *User
err := db.Model(table).OrderAsc("id").Scan(&user)
t.AssertNil(err)
t.Assert(user.Id, 1)
})
gtest.C(t, func(t *gtest.T) {
var users []User
err := db.Model(table).OrderAsc("id").Scan(&users)
t.AssertNil(err)
t.Assert(len(users), TableSize)
t.Assert(users[0].Id, 1)
})
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,130 +7,130 @@
package pgsql
import (
"context"
"reflect"
"strings"
"context"
"reflect"
"strings"
"github.com/lib/pq"
"github.com/lib/pq"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gregex"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
)
// ConvertValueForField converts value to database acceptable value.
func (d *Driver) ConvertValueForField(ctx context.Context, fieldType string, fieldValue interface{}) (interface{}, error) {
if g.IsNil(fieldValue) {
return d.Core.ConvertValueForField(ctx, fieldType, fieldValue)
}
if g.IsNil(fieldValue) {
return d.Core.ConvertValueForField(ctx, fieldType, fieldValue)
}
var fieldValueKind = reflect.TypeOf(fieldValue).Kind()
var fieldValueKind = reflect.TypeOf(fieldValue).Kind()
if fieldValueKind == reflect.Slice {
// For pgsql, json or jsonb require '[]'
if !gstr.Contains(fieldType, "json") {
fieldValue = gstr.ReplaceByMap(gconv.String(fieldValue),
map[string]string{
"[": "{",
"]": "}",
},
)
}
}
return d.Core.ConvertValueForField(ctx, fieldType, fieldValue)
if fieldValueKind == reflect.Slice {
// For pgsql, json or jsonb require '[]'
if !gstr.Contains(fieldType, "json") {
fieldValue = gstr.ReplaceByMap(gconv.String(fieldValue),
map[string]string{
"[": "{",
"]": "}",
},
)
}
}
return d.Core.ConvertValueForField(ctx, fieldType, fieldValue)
}
// CheckLocalTypeForField checks and returns corresponding local golang type for given db type.
func (d *Driver) CheckLocalTypeForField(ctx context.Context, fieldType string, fieldValue interface{}) (gdb.LocalType, error) {
var typeName string
match, _ := gregex.MatchString(`(.+?)\((.+)\)`, fieldType)
if len(match) == 3 {
typeName = gstr.Trim(match[1])
} else {
typeName = fieldType
}
typeName = strings.ToLower(typeName)
switch typeName {
case
// For pgsql, int2 = smallint.
"int2",
// For pgsql, int4 = integer
"int4":
return gdb.LocalTypeInt, nil
var typeName string
match, _ := gregex.MatchString(`(.+?)\((.+)\)`, fieldType)
if len(match) == 3 {
typeName = gstr.Trim(match[1])
} else {
typeName = fieldType
}
typeName = strings.ToLower(typeName)
switch typeName {
case
// For pgsql, int2 = smallint.
"int2",
// For pgsql, int4 = integer
"int4":
return gdb.LocalTypeInt, nil
case
// For pgsql, int8 = bigint
"int8":
return gdb.LocalTypeInt64, nil
case
// For pgsql, int8 = bigint
"int8":
return gdb.LocalTypeInt64, nil
case
"_int2",
"_int4":
return gdb.LocalTypeIntSlice, nil
case
"_int2",
"_int4":
return gdb.LocalTypeIntSlice, nil
case
"_int8":
return gdb.LocalTypeInt64Slice, nil
case
"_int8":
return gdb.LocalTypeInt64Slice, nil
case
"_varchar", "_text":
return gdb.LocalTypeStringSlice, nil
case
"_varchar", "_text":
return gdb.LocalTypeStringSlice, nil
default:
return d.Core.CheckLocalTypeForField(ctx, fieldType, fieldValue)
}
default:
return d.Core.CheckLocalTypeForField(ctx, fieldType, fieldValue)
}
}
// ConvertValueForLocal converts value to local Golang type of value according field type name from database.
// The parameter `fieldType` is in lower case, like:
// `float(5,2)`, `unsigned double(5,2)`, `decimal(10,2)`, `char(45)`, `varchar(100)`, etc.
func (d *Driver) ConvertValueForLocal(ctx context.Context, fieldType string, fieldValue interface{}) (interface{}, error) {
typeName, _ := gregex.ReplaceString(`\(.+\)`, "", fieldType)
typeName = strings.ToLower(typeName)
switch typeName {
// For pgsql, int2 = smallint and int4 = integer.
case "int2", "int4":
return gconv.Int(gconv.String(fieldValue)), nil
typeName, _ := gregex.ReplaceString(`\(.+\)`, "", fieldType)
typeName = strings.ToLower(typeName)
switch typeName {
// For pgsql, int2 = smallint and int4 = integer.
case "int2", "int4":
return gconv.Int(gconv.String(fieldValue)), nil
// For pgsql, int8 = bigint.
case "int8":
return gconv.Int64(gconv.String(fieldValue)), nil
// For pgsql, int8 = bigint.
case "int8":
return gconv.Int64(gconv.String(fieldValue)), nil
// Int32 slice.
case
"_int2", "_int4":
return gconv.Ints(
gstr.ReplaceByMap(gconv.String(fieldValue),
map[string]string{
"{": "[",
"}": "]",
},
),
), nil
// Int32 slice.
case
"_int2", "_int4":
return gconv.Ints(
gstr.ReplaceByMap(gconv.String(fieldValue),
map[string]string{
"{": "[",
"}": "]",
},
),
), nil
// Int64 slice.
case
"_int8":
return gconv.Int64s(
gstr.ReplaceByMap(gconv.String(fieldValue),
map[string]string{
"{": "[",
"}": "]",
},
),
), nil
// Int64 slice.
case
"_int8":
return gconv.Int64s(
gstr.ReplaceByMap(gconv.String(fieldValue),
map[string]string{
"{": "[",
"}": "]",
},
),
), nil
// String slice.
case "_varchar", "_text":
var result = make(pq.StringArray, 0)
if err := result.Scan(fieldValue); err != nil {
return nil, err
}
return []string(result), nil
// String slice.
case "_varchar", "_text":
var result = make(pq.StringArray, 0)
if err := result.Scan(fieldValue); err != nil {
return nil, err
}
return []string(result), nil
default:
return d.Core.ConvertValueForLocal(ctx, fieldType, fieldValue)
}
default:
return d.Core.ConvertValueForLocal(ctx, fieldType, fieldValue)
}
}