mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
improve ScanList for package gdb; improve Structs for package gconv
This commit is contained in:
@ -207,7 +207,12 @@ func (r Result) ScanList(listPointer interface{}, bindToAttrName string, relatio
|
||||
}
|
||||
|
||||
case reflect.Ptr:
|
||||
e := reflect.New(bindToAttrType.Elem()).Elem()
|
||||
var element reflect.Value
|
||||
if bindToAttrValue.IsNil() {
|
||||
element = reflect.New(bindToAttrType.Elem()).Elem()
|
||||
} else {
|
||||
element = bindToAttrValue.Elem()
|
||||
}
|
||||
if len(relationDataMap) > 0 {
|
||||
relationFromAttrField = relationFromAttrValue.FieldByName(relationBindToSubAttrName)
|
||||
if relationFromAttrField.IsValid() {
|
||||
@ -216,7 +221,7 @@ func (r Result) ScanList(listPointer interface{}, bindToAttrName string, relatio
|
||||
// There's no relational data.
|
||||
continue
|
||||
}
|
||||
if err = gconv.Struct(v, e); err != nil {
|
||||
if err = gconv.Struct(v, element); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
@ -229,14 +234,13 @@ func (r Result) ScanList(listPointer interface{}, bindToAttrName string, relatio
|
||||
// There's no relational data.
|
||||
continue
|
||||
}
|
||||
if err = gconv.Struct(v, e); err != nil {
|
||||
if err = gconv.Struct(v, element); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
bindToAttrValue.Set(e.Addr())
|
||||
bindToAttrValue.Set(element.Addr())
|
||||
|
||||
case reflect.Struct:
|
||||
e := reflect.New(bindToAttrType).Elem()
|
||||
if len(relationDataMap) > 0 {
|
||||
relationFromAttrField = relationFromAttrValue.FieldByName(relationBindToSubAttrName)
|
||||
if relationFromAttrField.IsValid() {
|
||||
@ -245,7 +249,7 @@ func (r Result) ScanList(listPointer interface{}, bindToAttrName string, relatio
|
||||
// There's no relational data.
|
||||
continue
|
||||
}
|
||||
if err = gconv.Struct(relationDataItem, e); err != nil {
|
||||
if err = gconv.Struct(relationDataItem, bindToAttrValue); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
@ -258,11 +262,10 @@ func (r Result) ScanList(listPointer interface{}, bindToAttrName string, relatio
|
||||
// There's no relational data.
|
||||
continue
|
||||
}
|
||||
if err = gconv.Struct(relationDataItem, e); err != nil {
|
||||
if err = gconv.Struct(relationDataItem, bindToAttrValue); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
bindToAttrValue.Set(e)
|
||||
|
||||
default:
|
||||
return gerror.Newf(`unsupported attribute type: %s`, bindToAttrKind.String())
|
||||
|
||||
@ -336,3 +336,323 @@ func TestResult_Structs1(t *testing.T) {
|
||||
t.Assert(array[1].Name, "smith")
|
||||
})
|
||||
}
|
||||
|
||||
// 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")
|
||||
t.Assert(err, nil)
|
||||
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")
|
||||
t.Assert(err, nil)
|
||||
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")
|
||||
t.Assert(err, nil)
|
||||
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")
|
||||
t.Assert(err, nil)
|
||||
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")
|
||||
t.Assert(err, nil)
|
||||
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)
|
||||
t.Assert(err, nil)
|
||||
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)
|
||||
t.Assert(err, nil)
|
||||
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")
|
||||
t.Assert(err, nil)
|
||||
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)
|
||||
t.Assert(err, nil)
|
||||
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)
|
||||
t.Assert(err, nil)
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
@ -467,7 +467,7 @@ CREATE TABLE %s (
|
||||
}
|
||||
|
||||
func Test_SoftDelete(t *testing.T) {
|
||||
table := "time_test_table"
|
||||
table := "time_test_table_" + gtime.TimestampNanoStr()
|
||||
if _, err := db.Exec(fmt.Sprintf(`
|
||||
CREATE TABLE %s (
|
||||
id int(11) NOT NULL,
|
||||
@ -606,7 +606,7 @@ CREATE TABLE %s (
|
||||
}
|
||||
|
||||
func Test_SoftDelete_WhereAndOr(t *testing.T) {
|
||||
table := "time_test_table"
|
||||
table := "time_test_table_" + gtime.TimestampNanoStr()
|
||||
if _, err := db.Exec(fmt.Sprintf(`
|
||||
CREATE TABLE %s (
|
||||
id int(11) NOT NULL,
|
||||
@ -648,7 +648,7 @@ CREATE TABLE %s (
|
||||
}
|
||||
|
||||
func Test_CreateUpdateTime_Struct(t *testing.T) {
|
||||
table := "time_test_table"
|
||||
table := "time_test_table_" + gtime.TimestampNanoStr()
|
||||
if _, err := db.Exec(fmt.Sprintf(`
|
||||
CREATE TABLE %s (
|
||||
id int(11) NOT NULL,
|
||||
|
||||
Reference in New Issue
Block a user