mirror of
https://gitee.com/johng/gf.git
synced 2024-12-03 12:47:50 +08:00
Merge branch 'master' into develop
This commit is contained in:
commit
22a7ef43ce
@ -14,7 +14,11 @@
|
||||
[![Code Helper](https://www.codetriage.com/gogf/gf/badges/users.svg)](https://www.codetriage.com/gogf/gf)
|
||||
-->
|
||||
|
||||
`GF(GoFrame)` is a modular, loose-coupled and production-ready application development framework written in Go. Providing a series of core components and dozens of practical modules, such as: cache, logging, array/queue/set/map, timer/timing tasks, file/memory lock, object pool, validator, database ORM, etc. Supporting web server with graceful server, hot updates, multi-domain, multi-port, multi-service, HTTP/HTTPS, dynamic/hook routing, rewrite rules and many more features.
|
||||
<!--
|
||||
GoFrame is a modular, loose-coupled, production-ready and most-powerful application development framework of golang. Providing a series of core components and dozens of practical modules, such as: cache, logging, containers, timer, validator, database orm, etc. Supporting web server integrated with router, cookie, session, logger, configure, template, https, hooks, rewrites and many more features.
|
||||
-->
|
||||
|
||||
`GF(GoFrame)` is a modular, loose-coupled, production-ready and most-powerful application development framework of golang. Providing a series of core components and dozens of practical modules, such as: memcache, configure, validator, logging, array/queue/set/map containers, timer/timing tasks, file/memory lock, object pool, database ORM, etc. Supporting web server integrated with router, cookie, session, logger, template, https, hooks, rewrites and many more features.
|
||||
|
||||
# Installation
|
||||
```
|
||||
|
@ -47,7 +47,9 @@ type DB interface {
|
||||
GetOne(query string, args ...interface{}) (Record, error)
|
||||
GetValue(query string, args ...interface{}) (Value, error)
|
||||
GetCount(query string, args ...interface{}) (int, error)
|
||||
GetStruct(obj interface{}, query string, args ...interface{}) error
|
||||
GetStruct(objPointer interface{}, query string, args ...interface{}) error
|
||||
GetStructs(objPointerSlice interface{}, query string, args ...interface{}) error
|
||||
GetScan(objPointer interface{}, query string, args ...interface{}) error
|
||||
|
||||
// 创建底层数据库master/slave链接对象
|
||||
Master() (*sql.DB, error)
|
||||
|
@ -165,13 +165,44 @@ func (bs *dbBase) GetOne(query string, args ...interface{}) (Record, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// 数据库查询,获取查询结果记录,自动映射数据到给定的struct对象中
|
||||
func (bs *dbBase) GetStruct(obj interface{}, query string, args ...interface{}) error {
|
||||
// 数据库查询,查询单条记录,自动映射数据到给定的struct对象中
|
||||
func (bs *dbBase) GetStruct(objPointer interface{}, query string, args ...interface{}) error {
|
||||
one, err := bs.GetOne(query, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return one.ToStruct(obj)
|
||||
return one.ToStruct(objPointer)
|
||||
}
|
||||
|
||||
// 数据库查询,查询多条记录,并自动转换为指定的slice对象, 如: []struct/[]*struct。
|
||||
func (bs *dbBase) GetStructs(objPointerSlice interface{}, query string, args ...interface{}) error {
|
||||
all, err := bs.GetAll(query, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return all.ToStructs(objPointerSlice)
|
||||
}
|
||||
|
||||
// 将结果转换为指定的struct/*struct/[]struct/[]*struct,
|
||||
// 参数应该为指针类型,否则返回失败。
|
||||
// 该方法自动识别参数类型,调用Struct/Structs方法。
|
||||
func (bs *dbBase) GetScan(objPointer interface{}, query string, args ...interface{}) error {
|
||||
t := reflect.TypeOf(objPointer)
|
||||
k := t.Kind()
|
||||
if k != reflect.Ptr {
|
||||
return fmt.Errorf("params should be type of pointer, but got: %v", k)
|
||||
}
|
||||
k = t.Elem().Kind()
|
||||
switch k {
|
||||
case reflect.Array:
|
||||
case reflect.Slice:
|
||||
return bs.db.GetStructs(objPointer, query, args ...)
|
||||
case reflect.Struct:
|
||||
return bs.db.GetStruct(objPointer, query, args ...)
|
||||
default:
|
||||
return fmt.Errorf("element type should be type of struct/slice, unsupported: %v", k)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 数据库查询,获取查询字段值
|
||||
|
@ -35,6 +35,7 @@ type Model struct {
|
||||
cacheEnabled bool // 当前SQL操作是否开启查询缓存功能
|
||||
cacheTime int // 查询缓存时间
|
||||
cacheName string // 查询缓存名称
|
||||
alterable bool // 当前模型是否运行可修改模式(默认情况下链式操作不会修改当前模型,而是创建新的模型返回)
|
||||
}
|
||||
|
||||
// 链式操作,数据表字段,可支持多个表,以半角逗号连接
|
||||
@ -79,44 +80,65 @@ func (md *Model) Clone() *Model {
|
||||
return newModel
|
||||
}
|
||||
|
||||
// 标识当前对象可被修改。
|
||||
// 1. 默认情况下,模型对象的对象属性无法被修改,
|
||||
// 每一次链式操作都是克隆一个新的模型对象,这样所有的操作都不会污染模型对象。
|
||||
// 但是链式操作如果需要分开执行,那么需要将新的克隆对象赋值给旧的模型对象继续操作。
|
||||
// 2. 当标识模型对象为可修改,那么在当前模型对象的所有链式操作均会影响下一次的链式操作,
|
||||
// 即使是链式操作分开执行。
|
||||
// 3. 大部分ORM框架默认模型对象是可修改的,但是GF框架的ORM提供给开发者更灵活,更安全的链式操作选项。
|
||||
func (md *Model) Alterable() *Model {
|
||||
md.alterable = true
|
||||
return md
|
||||
}
|
||||
|
||||
// 返回操作的模型对象,可能是当前对象,也可能是新的克隆对象,根据alterable决定。
|
||||
func (md *Model) getModel() *Model {
|
||||
if md.alterable {
|
||||
return md
|
||||
} else {
|
||||
return md.Clone()
|
||||
}
|
||||
}
|
||||
|
||||
// 链式操作,左联表
|
||||
func (md *Model) LeftJoin(joinTable string, on string) (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
model.tables += fmt.Sprintf(" LEFT JOIN %s ON (%s)", joinTable, on)
|
||||
return model
|
||||
}
|
||||
|
||||
// 链式操作,右联表
|
||||
func (md *Model) RightJoin(joinTable string, on string) (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
model.tables += fmt.Sprintf(" RIGHT JOIN %s ON (%s)", joinTable, on)
|
||||
return model
|
||||
}
|
||||
|
||||
// 链式操作,内联表
|
||||
func (md *Model) InnerJoin(joinTable string, on string) (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
model.tables += fmt.Sprintf(" INNER JOIN %s ON (%s)", joinTable, on)
|
||||
return model
|
||||
}
|
||||
|
||||
// 链式操作,查询字段
|
||||
func (md *Model) Fields(fields string) (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
model.fields = fields
|
||||
return model
|
||||
}
|
||||
|
||||
// 链式操作,过滤字段
|
||||
func (md *Model) Filter() (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
model.filter = true
|
||||
return model
|
||||
}
|
||||
|
||||
// 链式操作,condition,支持string & gdb.Map
|
||||
func (md *Model) Where(where interface{}, args ...interface{}) (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
newWhere, newArgs := formatCondition(where, args)
|
||||
model.where = newWhere
|
||||
model.whereArgs = append(model.whereArgs, newArgs...)
|
||||
@ -129,7 +151,7 @@ func (md *Model) Where(where interface{}, args ...interface{}) (*Model) {
|
||||
|
||||
// 链式操作,添加AND条件到Where中
|
||||
func (md *Model) And(where interface{}, args ...interface{}) (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
newWhere, newArgs := formatCondition(where, args)
|
||||
model.where += " AND " + newWhere
|
||||
model.whereArgs = append(model.whereArgs, newArgs...)
|
||||
@ -138,7 +160,7 @@ func (md *Model) And(where interface{}, args ...interface{}) (*Model) {
|
||||
|
||||
// 链式操作,添加OR条件到Where中
|
||||
func (md *Model) Or(where interface{}, args ...interface{}) (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
newWhere, newArgs := formatCondition(where, args)
|
||||
model.where += " OR " + newWhere
|
||||
model.whereArgs = append(model.whereArgs, newArgs...)
|
||||
@ -147,21 +169,21 @@ func (md *Model) Or(where interface{}, args ...interface{}) (*Model) {
|
||||
|
||||
// 链式操作,group by
|
||||
func (md *Model) GroupBy(groupBy string) (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
model.groupBy = groupBy
|
||||
return model
|
||||
}
|
||||
|
||||
// 链式操作,order by
|
||||
func (md *Model) OrderBy(orderBy string) (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
model.orderBy = orderBy
|
||||
return model
|
||||
}
|
||||
|
||||
// 链式操作,limit
|
||||
func (md *Model) Limit(start int, limit int) (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
model.start = start
|
||||
model.limit = limit
|
||||
return model
|
||||
@ -170,7 +192,7 @@ func (md *Model) Limit(start int, limit int) (*Model) {
|
||||
// 链式操作,翻页
|
||||
// @author ymrjqyy
|
||||
func (md *Model) ForPage(page, limit int) (*Model) {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
model.start = (page - 1) * limit
|
||||
model.limit = limit
|
||||
return model
|
||||
@ -178,7 +200,7 @@ func (md *Model) ForPage(page, limit int) (*Model) {
|
||||
|
||||
// 设置批处理的大小
|
||||
func (md *Model) Batch(batch int) *Model {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
model.batch = batch
|
||||
return model
|
||||
}
|
||||
@ -188,7 +210,7 @@ func (md *Model) Batch(batch int) *Model {
|
||||
// name表示自定义的缓存名称,便于业务层精准定位缓存项(如果业务层需要手动清理时,必须指定缓存名称),
|
||||
// 例如:查询缓存时设置名称,清理缓存时可以给定清理的缓存名称进行精准清理。
|
||||
func (md *Model) Cache(time int, name ... string) *Model {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
model.cacheTime = time
|
||||
if len(name) > 0 {
|
||||
model.cacheName = name[0]
|
||||
@ -203,7 +225,7 @@ func (md *Model) Cache(time int, name ... string) *Model {
|
||||
// 链式操作,操作数据项,参数data类型支持 string/map/slice/struct/*struct ,
|
||||
// 也可以是:key,value,key,value,...。
|
||||
func (md *Model) Data(data ...interface{}) *Model {
|
||||
model := md.Clone()
|
||||
model := md.getModel()
|
||||
if len(data) > 1 {
|
||||
m := make(map[string]interface{})
|
||||
for i := 0; i < len(data); i += 2 {
|
||||
@ -438,13 +460,44 @@ func (md *Model) Value() (Value, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// 链式操作,查询单条记录,并自动转换为struct对象
|
||||
func (md *Model) Struct(obj interface{}) error {
|
||||
// 链式操作,查询单条记录,并自动转换为struct对象, 参数必须为对象的指针,不能为空指针。
|
||||
func (md *Model) Struct(objPointer interface{}) error {
|
||||
one, err := md.One()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return one.ToStruct(obj)
|
||||
return one.ToStruct(objPointer)
|
||||
}
|
||||
|
||||
// 链式操作,查询多条记录,并自动转换为指定的slice对象, 如: []struct/[]*struct。
|
||||
func (md *Model) Structs(objPointerSlice interface{}) error {
|
||||
r, err := md.All()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.ToStructs(objPointerSlice)
|
||||
}
|
||||
|
||||
// 链式操作,将结果转换为指定的struct/*struct/[]struct/[]*struct,
|
||||
// 参数应该为指针类型,否则返回失败。
|
||||
// 该方法自动识别参数类型,调用Struct/Structs方法。
|
||||
func (md *Model) Scan(objPointer interface{}) error {
|
||||
t := reflect.TypeOf(objPointer)
|
||||
k := t.Kind()
|
||||
if k != reflect.Ptr {
|
||||
return fmt.Errorf("params should be type of pointer, but got: %v", k)
|
||||
}
|
||||
k = t.Elem().Kind()
|
||||
switch k {
|
||||
case reflect.Array:
|
||||
case reflect.Slice:
|
||||
return md.Structs(objPointer)
|
||||
case reflect.Struct:
|
||||
return md.Struct(objPointer)
|
||||
default:
|
||||
return fmt.Errorf("element type should be type of struct/slice, unsupported: %v", k)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 链式操作,查询数量,fields可以为空,也可以自定义查询字段,
|
||||
|
@ -8,8 +8,10 @@ package gdb
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g/text/gregex"
|
||||
_ "github.com/gogf/gf/third/github.com/go-sql-driver/mysql"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// 数据库事务对象
|
||||
@ -75,6 +77,37 @@ func (tx *TX) GetStruct(obj interface{}, query string, args ...interface{}) erro
|
||||
return one.ToStruct(obj)
|
||||
}
|
||||
|
||||
// 数据库查询,查询多条记录,并自动转换为指定的slice对象, 如: []struct/[]*struct。
|
||||
func (tx *TX) GetStructs(objPointerSlice interface{}, query string, args ...interface{}) error {
|
||||
all, err := tx.GetAll(query, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return all.ToStructs(objPointerSlice)
|
||||
}
|
||||
|
||||
// 将结果转换为指定的struct/*struct/[]struct/[]*struct,
|
||||
// 参数应该为指针类型,否则返回失败。
|
||||
// 该方法自动识别参数类型,调用Struct/Structs方法。
|
||||
func (tx *TX) GetScan(objPointer interface{}, query string, args ...interface{}) error {
|
||||
t := reflect.TypeOf(objPointer)
|
||||
k := t.Kind()
|
||||
if k != reflect.Ptr {
|
||||
return fmt.Errorf("params should be type of pointer, but got: %v", k)
|
||||
}
|
||||
k = t.Elem().Kind()
|
||||
switch k {
|
||||
case reflect.Array:
|
||||
case reflect.Slice:
|
||||
return tx.db.GetStructs(objPointer, query, args ...)
|
||||
case reflect.Struct:
|
||||
return tx.db.GetStruct(objPointer, query, args ...)
|
||||
default:
|
||||
return fmt.Errorf("element type should be type of struct/slice, unsupported: %v", k)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 数据库查询,获取查询字段值
|
||||
func (tx *TX) GetValue(query string, args ...interface{}) (Value, error) {
|
||||
one, err := tx.GetOne(query, args ...)
|
||||
|
@ -33,10 +33,6 @@ func (r Record) ToMap() Map {
|
||||
}
|
||||
|
||||
// 将Map变量映射到指定的struct对象中,注意参数应当是一个对象的指针
|
||||
func (r Record) ToStruct(obj interface{}) error {
|
||||
m := make(map[string]interface{})
|
||||
for k, v := range r {
|
||||
m[k] = v.Val()
|
||||
}
|
||||
return gconv.Struct(m, obj)
|
||||
func (r Record) ToStruct(objPointer interface{}) error {
|
||||
return gconv.Struct(r.ToMap(), objPointer)
|
||||
}
|
||||
|
@ -7,7 +7,9 @@
|
||||
package gdb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g/encoding/gparser"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// 将结果集转换为JSON字符串
|
||||
@ -96,3 +98,30 @@ func (r Result) ToUintRecord(key string) map[uint]Record {
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// 将结果列表转换为指定对象的slice。
|
||||
func (r Result) ToStructs(objPointerSlice interface{}) error {
|
||||
l := len(r)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
t := reflect.TypeOf(objPointerSlice)
|
||||
if t.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("params should be type of pointer, but got: %v", t.Kind())
|
||||
}
|
||||
a := reflect.MakeSlice(t.Elem(), l, l)
|
||||
itemType := a.Index(0).Type()
|
||||
for i := 0; i < l; i++ {
|
||||
if itemType.Kind() == reflect.Ptr {
|
||||
e := reflect.New(itemType.Elem()).Elem()
|
||||
r[i].ToStruct(e)
|
||||
a.Index(i).Set(e.Addr())
|
||||
} else {
|
||||
e := reflect.New(itemType).Elem()
|
||||
r[i].ToStruct(e)
|
||||
a.Index(i).Set(e)
|
||||
}
|
||||
}
|
||||
reflect.ValueOf(objPointerSlice).Elem().Set(a)
|
||||
return nil
|
||||
}
|
||||
|
@ -266,19 +266,159 @@ func TestDbBase_GetCount(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDbBase_GetStruct(t *testing.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
if err := db.GetStruct(user, "SELECT * FROM user WHERE id=?", 3); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
gtest.Assert(user.CreateTime.String(), "2010-10-10 00:00:01")
|
||||
}
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
if err := db.GetStruct(user, "SELECT * FROM user WHERE id=?", 3); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
gtest.Assert(user.CreateTime.String(), "2010-10-10 00:00:01")
|
||||
}
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
if err := db.GetStruct(user, "SELECT * FROM user WHERE id=?", 3); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
gtest.Assert(user.CreateTime.String(), "2010-10-10 00:00:01")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDbBase_GetStructs(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
var users []User
|
||||
if err := db.GetStructs(&users, "SELECT * FROM user WHERE id>=?", 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 3)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T111")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[2].CreateTime.String(), "2010-10-10 00:00:01")
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var users []User
|
||||
if err := db.GetStructs(&users, "SELECT * FROM user WHERE id>=?", 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 3)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T111")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[2].CreateTime.String(), "2010-10-10 00:00:01")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDbBase_GetScan(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
if err := db.GetScan(user, "SELECT * FROM user WHERE id=?", 3); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
gtest.Assert(user.CreateTime.String(), "2010-10-10 00:00:01")
|
||||
}
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
if err := db.GetScan(user, "SELECT * FROM user WHERE id=?", 3); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
gtest.Assert(user.CreateTime.String(), "2010-10-10 00:00:01")
|
||||
}
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
var users []User
|
||||
if err := db.GetScan(&users, "SELECT * FROM user WHERE id>=?", 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 3)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T111")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[2].CreateTime.String(), "2010-10-10 00:00:01")
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var users []User
|
||||
if err := db.GetScan(&users, "SELECT * FROM user WHERE id>=?", 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 3)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T111")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[2].CreateTime.String(), "2010-10-10 00:00:01")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDbBase_Delete(t *testing.T) {
|
||||
|
@ -121,7 +121,7 @@ func TestModel_Replace(t *testing.T) {
|
||||
"passport" : "t11",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T11",
|
||||
"create_time" : gtime.Now().String(),
|
||||
"create_time" : "2018-10-10 00:01:10",
|
||||
}).Replace()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
@ -136,7 +136,7 @@ func TestModel_Save(t *testing.T) {
|
||||
"passport" : "t111",
|
||||
"password" : "25d55ad283aa400af464c76d713c07ad",
|
||||
"nickname" : "T111",
|
||||
"create_time" : gtime.Now().String(),
|
||||
"create_time" : "2018-10-10 00:01:10",
|
||||
}).Save()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
@ -168,13 +168,30 @@ func TestModel_Clone(t *testing.T) {
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(count, 2)
|
||||
gtest.Assert(record["id"].Int(), 3)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(count, 2)
|
||||
gtest.Assert(record["id"].Int(), 3)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["id"].Int(), 1)
|
||||
gtest.Assert(result[1]["id"].Int(), 3)
|
||||
}
|
||||
|
||||
func TestModel_Alterable(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
md := db.Table("user").Alterable().Where("id IN(?)", g.Slice{1,3})
|
||||
count, err := md.Count()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(count, 2)
|
||||
md.And("id = ?", 1)
|
||||
count, err = md.Count()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(count, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestModel_All(t *testing.T) {
|
||||
result, err := db.Table("user").All()
|
||||
if err != nil {
|
||||
@ -222,19 +239,164 @@ func TestModel_Select(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestModel_Struct(t *testing.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
err := db.Table("user").Where("id=1").Struct(user)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(user.NickName, "T111")
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
err := db.Table("user").Where("id=1").Struct(user)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(user.NickName, "T111")
|
||||
gtest.Assert(user.CreateTime.String(), "2018-10-10 00:01:10")
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
err := db.Table("user").Where("id=1").Struct(user)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(user.NickName, "T111")
|
||||
gtest.Assert(user.CreateTime.String(), "2018-10-10 00:01:10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestModel_Structs(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
var users []User
|
||||
err := db.Table("user").OrderBy("id asc").Structs(&users)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 3)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T111")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[0].CreateTime.String(), "2018-10-10 00:01:10")
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var users []*User
|
||||
err := db.Table("user").OrderBy("id asc").Structs(&users)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 3)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T111")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[0].CreateTime.String(), "2018-10-10 00:01:10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestModel_Scan(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
err := db.Table("user").Where("id=1").Scan(user)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(user.NickName, "T111")
|
||||
gtest.Assert(user.CreateTime.String(), "2018-10-10 00:01:10")
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
err := db.Table("user").Where("id=1").Scan(user)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(user.NickName, "T111")
|
||||
gtest.Assert(user.CreateTime.String(), "2018-10-10 00:01:10")
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
var users []User
|
||||
err := db.Table("user").OrderBy("id asc").Scan(&users)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 3)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T111")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[0].CreateTime.String(), "2018-10-10 00:01:10")
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var users []*User
|
||||
err := db.Table("user").OrderBy("id asc").Scan(&users)
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 3)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T111")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[0].CreateTime.String(), "2018-10-10 00:01:10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestModel_OrderBy(t *testing.T) {
|
||||
|
@ -267,6 +267,29 @@ func TestTX_Save(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTX_Update(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
if result, err := db.Update("user", "create_time='2010-10-10 00:00:01'", "id=3"); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 1)
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
if value, err := db.Table("user").Fields("create_time").Where("id", 3).Value(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
gtest.Assert(value.String(), "2010-10-10 00:00:01")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestTX_GetAll(t *testing.T) {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
@ -331,26 +354,215 @@ func TestTX_GetCount(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTX_GetStruct(t *testing.T) {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
if err := tx.GetStruct(user, "SELECT * FROM user WHERE id=?", 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
gtest.Assert(user.NickName, "T11")
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Case(t, func() {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
if err := tx.GetStruct(user, "SELECT * FROM user WHERE id=?", 3); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(user.NickName, "T3")
|
||||
gtest.Assert(user.CreateTime.String(), "2010-10-10 00:00:01")
|
||||
if err := tx.Commit(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
if err := tx.GetStruct(user, "SELECT * FROM user WHERE id=?", 3); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(user.NickName, "T3")
|
||||
gtest.Assert(user.CreateTime.String(), "2010-10-10 00:00:01")
|
||||
if err := tx.Commit(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestTX_GetStructs(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
var users []User
|
||||
if err := tx.GetStructs(&users, "SELECT * FROM user WHERE id>=?", 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 4)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T11")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[2].CreateTime.String(), "2010-10-10 00:00:01")
|
||||
if err := tx.Commit(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var users []User
|
||||
if err := tx.GetStructs(&users, "SELECT * FROM user WHERE id>=?", 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 4)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T11")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[2].CreateTime.String(), "2010-10-10 00:00:01")
|
||||
if err := tx.Commit(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestTX_GetScan(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
if err := tx.GetScan(user, "SELECT * FROM user WHERE id=?", 3); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(user.NickName, "T3")
|
||||
gtest.Assert(user.CreateTime.String(), "2010-10-10 00:00:01")
|
||||
if err := tx.Commit(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
})
|
||||
gtest.Case(t, func() {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
if err := tx.GetScan(user, "SELECT * FROM user WHERE id=?", 3); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(user.NickName, "T3")
|
||||
gtest.Assert(user.CreateTime.String(), "2010-10-10 00:00:01")
|
||||
if err := tx.Commit(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
var users []User
|
||||
if err := tx.GetScan(&users, "SELECT * FROM user WHERE id>=?", 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 4)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T11")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[2].CreateTime.String(), "2010-10-10 00:00:01")
|
||||
if err := tx.Commit(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var users []User
|
||||
if err := tx.GetScan(&users, "SELECT * FROM user WHERE id>=?", 1); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
gtest.Assert(len(users), 4)
|
||||
gtest.Assert(users[0].Id, 1)
|
||||
gtest.Assert(users[1].Id, 2)
|
||||
gtest.Assert(users[2].Id, 3)
|
||||
gtest.Assert(users[0].NickName, "T11")
|
||||
gtest.Assert(users[1].NickName, "T2")
|
||||
gtest.Assert(users[2].NickName, "T3")
|
||||
gtest.Assert(users[2].CreateTime.String(), "2010-10-10 00:00:01")
|
||||
if err := tx.Commit(); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestTX_Delete(t *testing.T) {
|
||||
|
@ -47,7 +47,16 @@ func Convert(i interface{}, t string, extraParams...interface{}) interface{} {
|
||||
return Time(i, String(extraParams[0]))
|
||||
}
|
||||
return Time(i)
|
||||
|
||||
case "gtime.Time":
|
||||
if len(extraParams) > 0 {
|
||||
return GTime(i, String(extraParams[0]))
|
||||
}
|
||||
return *GTime(i)
|
||||
case "*gtime.Time":
|
||||
if len(extraParams) > 0 {
|
||||
return GTime(i, String(extraParams[0]))
|
||||
}
|
||||
return GTime(i)
|
||||
case "time.Duration": return TimeDuration(i)
|
||||
default:
|
||||
return i
|
||||
|
@ -15,68 +15,60 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 将params键值对参数映射到对应的struct对象属性上,第三个参数mapping为非必需,表示自定义名称与属性名称的映射关系。
|
||||
// 将params键值对参数映射到对应的struct对象属性上,
|
||||
// 第三个参数mapping为非必需,表示自定义名称与属性名称的映射关系。
|
||||
// 需要注意:
|
||||
// 1、第二个参数应当为struct对象指针;
|
||||
// 2、struct对象的**公开属性(首字母大写)**才能被映射赋值;
|
||||
// 3、map中的键名可以为小写,映射转换时会自动将键名首字母转为大写做匹配映射,如果无法匹配则忽略;
|
||||
func Struct(params interface{}, objPointer interface{}, attrMapping...map[string]string) error {
|
||||
if params == nil {
|
||||
return nil
|
||||
return errors.New("params cannot be nil")
|
||||
}
|
||||
isParamMap := true
|
||||
paramsMap := (map[string]interface{})(nil)
|
||||
// 先将参数转为 map[string]interface{} 类型
|
||||
if m, ok := params.(map[string]interface{}); ok {
|
||||
paramsMap = m
|
||||
} else {
|
||||
paramsMap = make(map[string]interface{})
|
||||
if reflect.ValueOf(params).Kind() == reflect.Map {
|
||||
ks := reflect.ValueOf(params).MapKeys()
|
||||
vs := reflect.ValueOf(params)
|
||||
for _, k := range ks {
|
||||
paramsMap[String(k.Interface())] = vs.MapIndex(k).Interface()
|
||||
}
|
||||
} else {
|
||||
isParamMap = false
|
||||
}
|
||||
if objPointer == nil {
|
||||
return errors.New("object pointer cannot be nil")
|
||||
}
|
||||
paramsMap := Map(params)
|
||||
if paramsMap == nil {
|
||||
return fmt.Errorf("invalid params: %v", params)
|
||||
}
|
||||
// struct的反射对象
|
||||
elem := reflect.Value{}
|
||||
if v, ok := objPointer.(reflect.Value); ok {
|
||||
elem = v
|
||||
} else {
|
||||
elem = reflect.ValueOf(objPointer).Elem()
|
||||
}
|
||||
// 如果给定的参数不是map类型,那么直接将参数值映射到第一个属性上
|
||||
if !isParamMap {
|
||||
if err := bindVarToStructByIndex(elem, 0, params); err != nil {
|
||||
return err
|
||||
rv := reflect.ValueOf(objPointer)
|
||||
if kind := rv.Kind(); kind != reflect.Ptr {
|
||||
return fmt.Errorf("object pointer should be type of: %v", kind)
|
||||
}
|
||||
return nil
|
||||
if !rv.IsValid() || rv.IsNil() {
|
||||
return errors.New("object pointer cannot be nil")
|
||||
}
|
||||
elem = rv.Elem()
|
||||
}
|
||||
// 已执行过转换的属性,只执行一次转换
|
||||
dmap := make(map[string]bool)
|
||||
// 已执行过转换的属性,只执行一次转换。
|
||||
// 或者是已经执行过转换检查的属性(即使不进行转换), 以便重复判断。
|
||||
doneMap := make(map[string]bool)
|
||||
// 首先按照传递的映射关系进行匹配
|
||||
if len(attrMapping) > 0 && len(attrMapping[0]) > 0 {
|
||||
for mappingk, mappingv := range attrMapping[0] {
|
||||
if v, ok := paramsMap[mappingk]; ok {
|
||||
dmap[mappingv] = true
|
||||
if err := bindVarToStructAttr(elem, mappingv, v); err != nil {
|
||||
for mapK, mapV := range attrMapping[0] {
|
||||
if v, ok := paramsMap[mapK]; ok {
|
||||
doneMap[mapV] = true
|
||||
if err := bindVarToStructAttr(elem, mapV, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 其次匹配对象定义时绑定的属性名称
|
||||
// 其次匹配对象定义时绑定的属性名称,
|
||||
// 标签映射关系map,如果有的话
|
||||
tagmap := getTagMapOfStruct(objPointer)
|
||||
for tagk, tagv := range tagmap {
|
||||
if _, ok := dmap[tagv]; ok {
|
||||
tagMap := getTagMapOfStruct(objPointer)
|
||||
for tagk, tagv := range tagMap {
|
||||
if _, ok := doneMap[tagv]; ok {
|
||||
continue
|
||||
}
|
||||
if v, ok := paramsMap[tagk]; ok {
|
||||
dmap[tagv] = true
|
||||
doneMap[tagv] = true
|
||||
if err := bindVarToStructAttr(elem, tagv, v); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -88,19 +80,19 @@ func Struct(params interface{}, objPointer interface{}, attrMapping...map[string
|
||||
for i := 0; i < elem.NumField(); i++ {
|
||||
attrMap[elemType.Field(i).Name] = struct{}{}
|
||||
}
|
||||
for mapk, mapv := range paramsMap {
|
||||
for mapK, mapV := range paramsMap {
|
||||
name := ""
|
||||
for _, checkName := range []string {
|
||||
gstr.UcFirst(mapk),
|
||||
gstr.ReplaceByMap(mapk, map[string]string{
|
||||
gstr.UcFirst(mapK),
|
||||
gstr.ReplaceByMap(mapK, map[string]string{
|
||||
"_" : "",
|
||||
"-" : "",
|
||||
" " : "",
|
||||
})} {
|
||||
if _, ok := dmap[checkName]; ok {
|
||||
})} {
|
||||
if _, ok := doneMap[checkName]; ok {
|
||||
continue
|
||||
}
|
||||
if _, ok := tagmap[checkName]; ok {
|
||||
if _, ok := tagMap[checkName]; ok {
|
||||
continue
|
||||
}
|
||||
// 循环查找属性名称进行匹配
|
||||
@ -114,6 +106,7 @@ func Struct(params interface{}, objPointer interface{}, attrMapping...map[string
|
||||
break
|
||||
}
|
||||
}
|
||||
doneMap[checkName] = true
|
||||
if name != "" {
|
||||
break
|
||||
}
|
||||
@ -122,7 +115,7 @@ func Struct(params interface{}, objPointer interface{}, attrMapping...map[string
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
if err := bindVarToStructAttr(elem, name, mapv); err != nil {
|
||||
if err := bindVarToStructAttr(elem, name, mapV); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ func TimeDuration(i interface{}) time.Duration {
|
||||
return time.Duration(Int64(i))
|
||||
}
|
||||
|
||||
// 将变量i转换为time.Time类型
|
||||
// 将变量i转换为time.Time类型, 自动识别i为时间戳或者标准化的时间字符串。
|
||||
func GTime(i interface{}, format...string) *gtime.Time {
|
||||
s := String(i)
|
||||
if len(s) == 0 {
|
||||
|
@ -5,19 +5,7 @@ import (
|
||||
"github.com/gogf/gf/g/util/gconv"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id int
|
||||
}
|
||||
|
||||
type RPCResponse struct {
|
||||
ID interface{} `json:"id,omitempty"`
|
||||
JsonRPC string `json:"jsonrpc"`
|
||||
Error *User `json:"error,omitempty"`
|
||||
Result interface{} `json:"result,omitempty"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
var rpc RPCResponse
|
||||
fmt.Println(rpc.Error)
|
||||
fmt.Println(gconv.Map(rpc))
|
||||
t := gconv.GTime("2010-10-10 00:00:01")
|
||||
fmt.Println(t.String())
|
||||
}
|
Loading…
Reference in New Issue
Block a user