use type instead of value for Reflection in Coll.initFields
This commit is contained in:
parent
29a3f73f15
commit
11dc6d2640
@ -25,7 +25,7 @@ func (c *Coll[TData]) EnsureInitializedReflection(v TData) {
|
||||
|
||||
m := make(map[string]fullTypeRef)
|
||||
|
||||
c.initFields("", rval, m, make([]int, 0))
|
||||
c.initFields("", rval.Type(), m, make([]int, 0))
|
||||
|
||||
c.implDataTypeMap[rval.Type()] = m
|
||||
}
|
||||
@ -50,20 +50,17 @@ func (c *Coll[TData]) init() {
|
||||
c.implDataTypeMap = make(map[reflect.Type]map[string]fullTypeRef)
|
||||
|
||||
v := reflect.ValueOf(example)
|
||||
c.initFields("", v, c.dataTypeMap, make([]int, 0))
|
||||
c.initFields("", v.Type(), c.dataTypeMap, make([]int, 0))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (c *Coll[TData]) initFields(prefix string, rval reflect.Value, m map[string]fullTypeRef, idxarr []int) {
|
||||
|
||||
rtyp := rval.Type()
|
||||
func (c *Coll[TData]) initFields(prefix string, rtyp reflect.Type, m map[string]fullTypeRef, idxarr []int) {
|
||||
|
||||
for i := 0; i < rtyp.NumField(); i++ {
|
||||
|
||||
rsfield := rtyp.Field(i)
|
||||
rvfield := rval.Field(i)
|
||||
|
||||
if !rsfield.IsExported() {
|
||||
continue
|
||||
@ -91,21 +88,21 @@ func (c *Coll[TData]) initFields(prefix string, rval reflect.Value, m map[string
|
||||
newIdxArr := langext.ArrCopy(idxarr)
|
||||
newIdxArr = append(newIdxArr, i)
|
||||
|
||||
if langext.InArray("inline", bsontags) && rvfield.Kind() == reflect.Struct {
|
||||
if langext.InArray("inline", bsontags) && rsfield.Type.Kind() == reflect.Struct {
|
||||
|
||||
// pass-through field
|
||||
c.initFields(prefix, rvfield, m, newIdxArr)
|
||||
c.initFields(prefix, rsfield.Type, m, newIdxArr)
|
||||
|
||||
} else {
|
||||
|
||||
if rvfield.Type().Kind() == reflect.Pointer {
|
||||
if rsfield.Type.Kind() == reflect.Pointer {
|
||||
|
||||
m[fullKey] = fullTypeRef{
|
||||
IsPointer: true,
|
||||
RealType: rvfield.Type(),
|
||||
Kind: rvfield.Type().Elem().Kind(),
|
||||
Type: rvfield.Type().Elem(),
|
||||
UnderlyingType: reflectext.Underlying(rvfield.Type().Elem()),
|
||||
RealType: rsfield.Type,
|
||||
Kind: rsfield.Type.Elem().Kind(),
|
||||
Type: rsfield.Type.Elem(),
|
||||
UnderlyingType: reflectext.Underlying(rsfield.Type.Elem()),
|
||||
Name: rsfield.Name,
|
||||
Index: newIdxArr,
|
||||
}
|
||||
@ -114,20 +111,23 @@ func (c *Coll[TData]) initFields(prefix string, rval reflect.Value, m map[string
|
||||
|
||||
m[fullKey] = fullTypeRef{
|
||||
IsPointer: false,
|
||||
RealType: rvfield.Type(),
|
||||
Kind: rvfield.Type().Kind(),
|
||||
Type: rvfield.Type(),
|
||||
UnderlyingType: reflectext.Underlying(rvfield.Type()),
|
||||
RealType: rsfield.Type,
|
||||
Kind: rsfield.Type.Kind(),
|
||||
Type: rsfield.Type,
|
||||
UnderlyingType: reflectext.Underlying(rsfield.Type),
|
||||
Name: rsfield.Name,
|
||||
Index: newIdxArr,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if rvfield.Kind() == reflect.Struct {
|
||||
c.initFields(fullKey+".", rvfield, m, newIdxArr)
|
||||
if rsfield.Type.Kind() == reflect.Struct {
|
||||
c.initFields(fullKey+".", rsfield.Type, m, newIdxArr)
|
||||
}
|
||||
|
||||
if rsfield.Type.Kind() == reflect.Pointer && rsfield.Type.Elem().Kind() == reflect.Struct {
|
||||
c.initFields(fullKey+".", rsfield.Type.Elem(), m, newIdxArr)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,9 @@ func TestReflectionGetFieldType(t *testing.T) {
|
||||
Sub struct {
|
||||
A string `bson:"a"`
|
||||
} `bson:"sub"`
|
||||
SubPtr *struct {
|
||||
A string `bson:"a"`
|
||||
} `bson:"subPtr"`
|
||||
Str string `bson:"str"`
|
||||
Ptr *int `bson:"ptr"`
|
||||
MDate rfctime.RFC3339NanoTime `bson:"mdate"`
|
||||
@ -43,6 +46,11 @@ func TestReflectionGetFieldType(t *testing.T) {
|
||||
}{
|
||||
A: "2",
|
||||
},
|
||||
SubPtr: &struct {
|
||||
A string `bson:"a"`
|
||||
}{
|
||||
A: "4",
|
||||
},
|
||||
Str: "3",
|
||||
Ptr: langext.Ptr(4),
|
||||
MDate: t1,
|
||||
@ -82,6 +90,12 @@ func TestReflectionGetFieldType(t *testing.T) {
|
||||
tst.AssertEqual(t, gft("sub.a").IsPointer, false)
|
||||
tst.AssertEqual(t, gfv("sub.a").(string), "2")
|
||||
|
||||
tst.AssertEqual(t, gft("subPtr.a").Kind.String(), "string")
|
||||
tst.AssertEqual(t, gft("subPtr.a").Type.String(), "string")
|
||||
tst.AssertEqual(t, gft("subPtr.a").Name, "A")
|
||||
tst.AssertEqual(t, gft("subPtr.a").IsPointer, false)
|
||||
tst.AssertEqual(t, gfv("subPtr.a").(string), "4")
|
||||
|
||||
tst.AssertEqual(t, gft("str").Kind.String(), "string")
|
||||
tst.AssertEqual(t, gft("str").Type.String(), "string")
|
||||
tst.AssertEqual(t, gft("str").Name, "Str")
|
||||
@ -105,6 +119,9 @@ func TestReflectionGetTokenValueAsMongoType(t *testing.T) {
|
||||
Sub struct {
|
||||
A string `bson:"a"`
|
||||
} `bson:"sub"`
|
||||
SubPtr struct {
|
||||
A string `bson:"a"`
|
||||
} `bson:"subPtr"`
|
||||
Str string `bson:"str"`
|
||||
Ptr *int `bson:"ptr"`
|
||||
Num int `bson:"num"`
|
||||
@ -130,6 +147,8 @@ func TestReflectionGetTokenValueAsMongoType(t *testing.T) {
|
||||
}
|
||||
|
||||
tst.AssertEqual(t, gtvasmt("hello", "str").(string), "hello")
|
||||
tst.AssertEqual(t, gtvasmt("hello", "sub.a").(string), "hello")
|
||||
tst.AssertEqual(t, gtvasmt("hello", "subPtr.a").(string), "hello")
|
||||
tst.AssertEqual(t, gtvasmt("4", "num").(int), 4)
|
||||
tst.AssertEqual(t, gtvasmt("asdf", "_id").(IDType), "asdf")
|
||||
tst.AssertEqual(t, gtvasmt("", "ptr").(*int), nil)
|
||||
|
Loading…
Reference in New Issue
Block a user