improve json marshaling/unmarshaling
This commit is contained in:
parent
40b754668d
commit
c85efdc49f
18
document.go
18
document.go
@ -2,6 +2,7 @@ package orm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"go.mongodb.org/mongo-driver/v2/bson"
|
"go.mongodb.org/mongo-driver/v2/bson"
|
||||||
"log"
|
"log"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -33,13 +34,24 @@ func (d *Document) UnmarshalJSON(bytes []byte) error {
|
|||||||
err = json.Unmarshal(bytes, &tmpV)
|
err = json.Unmarshal(bytes, &tmpV)
|
||||||
typ := reflect.SliceOf(d.model.Type)
|
typ := reflect.SliceOf(d.model.Type)
|
||||||
//d.SetSelf()
|
//d.SetSelf()
|
||||||
rerere(tmpV, typ)
|
var arr []interface{}
|
||||||
|
reified := rerere(tmpV, typ, true)
|
||||||
|
if ta, ok := reified.(bson.A); ok {
|
||||||
|
arr = []interface{}(ta)
|
||||||
|
} else {
|
||||||
|
arr = reified.([]interface{})
|
||||||
|
}
|
||||||
|
fmt.Println(len(arr))
|
||||||
break
|
break
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
tmpV := make(bson.M)
|
tmpV := make(bson.M)
|
||||||
err = json.Unmarshal(bytes, &tmpV)
|
err = json.Unmarshal(bytes, &tmpV)
|
||||||
typ := d.model.Type
|
typ := reflect.PointerTo(d.model.Type)
|
||||||
rerere(tmpV, typ)
|
self := reflect.ValueOf(d.self)
|
||||||
|
nself := reflect.NewAt(typ.Elem(), self.UnsafePointer())
|
||||||
|
reified := rerere(tmpV, typ, true)
|
||||||
|
nself.Elem().Set(reflect.ValueOf(reified).Elem())
|
||||||
|
d.self = nself.Interface()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
9
model.go
9
model.go
@ -217,14 +217,15 @@ func createBase(d any) (reflect.Value, int, string) {
|
|||||||
v := valueOf(d)
|
v := valueOf(d)
|
||||||
i := ModelRegistry.Index(n)
|
i := ModelRegistry.Index(n)
|
||||||
|
|
||||||
r := reflect.New(t)
|
r := reflect.New(reflect.PointerTo(t)).Elem()
|
||||||
|
r.Addr().Elem().Set(reflect.New(t))
|
||||||
|
|
||||||
r.Elem().Set(v)
|
r.Addr().Elem().Elem().Set(v)
|
||||||
|
|
||||||
if reflect.ValueOf(d).Kind() == reflect.Pointer {
|
if reflect.ValueOf(d).Kind() == reflect.Pointer {
|
||||||
r.Elem().Set(reflect.ValueOf(d).Elem())
|
r.Addr().Elem().Elem().Set(reflect.ValueOf(d).Elem())
|
||||||
} else {
|
} else {
|
||||||
r.Elem().Set(reflect.ValueOf(d))
|
r.Addr().Elem().Elem().Set(reflect.ValueOf(d))
|
||||||
}
|
}
|
||||||
ri.setTypeName(n)
|
ri.setTypeName(n)
|
||||||
r.Interface().(IDocument).setModel(*ri)
|
r.Interface().(IDocument).setModel(*ri)
|
||||||
|
75
query.go
75
query.go
@ -10,6 +10,7 @@ import (
|
|||||||
"go.mongodb.org/mongo-driver/v2/mongo"
|
"go.mongodb.org/mongo-driver/v2/mongo"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Query struct {
|
type Query struct {
|
||||||
@ -176,7 +177,7 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter
|
|||||||
if !errors.Is(reso.Err(), mongo.ErrNoDocuments) {
|
if !errors.Is(reso.Err(), mongo.ErrNoDocuments) {
|
||||||
var anotherMap = make(bson.M)
|
var anotherMap = make(bson.M)
|
||||||
reso.Decode(&anotherMap)
|
reso.Decode(&anotherMap)
|
||||||
reflect.ValueOf(t).Elem().Set(reflect.ValueOf(rerere(anotherMap, tto)).Elem())
|
reflect.ValueOf(t).Elem().Set(reflect.ValueOf(rerere(anotherMap, tto, false)).Elem())
|
||||||
t.setRaw(anotherMap)
|
t.setRaw(anotherMap)
|
||||||
}
|
}
|
||||||
hatred := rv
|
hatred := rv
|
||||||
@ -338,12 +339,12 @@ func (q *Query) reOrganize() {
|
|||||||
}
|
}
|
||||||
slic := reflect.New(reflect.SliceOf(typ))
|
slic := reflect.New(reflect.SliceOf(typ))
|
||||||
for _, v2 := range arr {
|
for _, v2 := range arr {
|
||||||
inter := reflect.ValueOf(rerere(v2, typ))
|
inter := reflect.ValueOf(rerere(v2, typ, false))
|
||||||
slic.Elem().Set(reflect.Append(slic.Elem(), inter))
|
slic.Elem().Set(reflect.Append(slic.Elem(), inter))
|
||||||
}
|
}
|
||||||
trvo = slic.Elem()
|
trvo = slic.Elem()
|
||||||
} else {
|
} else {
|
||||||
trvo = reflect.ValueOf(rerere(q.rawDoc, reflect.TypeOf(q.doc)))
|
trvo = reflect.ValueOf(rerere(q.rawDoc, reflect.TypeOf(q.doc), false))
|
||||||
}
|
}
|
||||||
|
|
||||||
resV := reflect.ValueOf(q.doc)
|
resV := reflect.ValueOf(q.doc)
|
||||||
@ -365,9 +366,15 @@ func (q *Query) reOrganize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func rerere(input interface{}, resType reflect.Type) interface{} {
|
func rerere(input interface{}, resType reflect.Type, isJson bool) interface{} {
|
||||||
t := reflect.TypeOf(input)
|
t := reflect.TypeOf(input)
|
||||||
v := reflect.ValueOf(input)
|
v := reflect.ValueOf(input)
|
||||||
|
var key string
|
||||||
|
if isJson {
|
||||||
|
key = "json"
|
||||||
|
} else {
|
||||||
|
key = "bson"
|
||||||
|
}
|
||||||
if input == nil {
|
if input == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -382,11 +389,24 @@ func rerere(input interface{}, resType reflect.Type) interface{} {
|
|||||||
resType = resType.Elem()
|
resType = resType.Elem()
|
||||||
}
|
}
|
||||||
var resV reflect.Value
|
var resV reflect.Value
|
||||||
newInstance := ModelRegistry.newForType(resType)
|
var newInstance interface{}
|
||||||
if newInstance == nil {
|
if _, _, has := ModelRegistry.Has(reflect.New(resType).Elem().Interface()); has {
|
||||||
resV = reflect.New(resType)
|
newInstance = Create(reflect.New(resType).Elem().Interface())
|
||||||
} else {
|
|
||||||
resV = reflect.ValueOf(newInstance)
|
resV = reflect.ValueOf(newInstance)
|
||||||
|
} else {
|
||||||
|
newInstance = ModelRegistry.newForType(resType)
|
||||||
|
if newInstance == nil && resType.Kind() == reflect.Pointer {
|
||||||
|
newInstance = ModelRegistry.newForType(resType.Elem())
|
||||||
|
if newInstance == nil {
|
||||||
|
resV = reflect.New(resType)
|
||||||
|
} else {
|
||||||
|
resV = reflect.ValueOf(newInstance)
|
||||||
|
}
|
||||||
|
} else if newInstance != nil {
|
||||||
|
resV = reflect.ValueOf(newInstance)
|
||||||
|
} else {
|
||||||
|
resV = reflect.New(resType)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var rve = resV
|
var rve = resV
|
||||||
@ -407,6 +427,12 @@ func rerere(input interface{}, resType reflect.Type) interface{} {
|
|||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
shouldBreak := false
|
shouldBreak := false
|
||||||
mipmap, ok := v.Interface().(bson.M)
|
mipmap, ok := v.Interface().(bson.M)
|
||||||
|
if !ok {
|
||||||
|
var omap map[string]interface{}
|
||||||
|
if omap, ok = v.Interface().(map[string]interface{}); ok {
|
||||||
|
mipmap = bson.M(omap)
|
||||||
|
}
|
||||||
|
}
|
||||||
if ok {
|
if ok {
|
||||||
for i := 0; i < resType.NumField(); i++ {
|
for i := 0; i < resType.NumField(); i++ {
|
||||||
ft := resType.Field(i)
|
ft := resType.Field(i)
|
||||||
@ -417,7 +443,7 @@ func rerere(input interface{}, resType reflect.Type) interface{} {
|
|||||||
}
|
}
|
||||||
tags, err := structtag.Parse(string(ft.Tag))
|
tags, err := structtag.Parse(string(ft.Tag))
|
||||||
panik(err)
|
panik(err)
|
||||||
btag, err := tags.Get("bson")
|
btag, err := tags.Get(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -431,7 +457,7 @@ func rerere(input interface{}, resType reflect.Type) interface{} {
|
|||||||
if ttmp, tok := intermediate.(bson.DateTime); tok {
|
if ttmp, tok := intermediate.(bson.DateTime); tok {
|
||||||
tmp = ttmp.Time()
|
tmp = ttmp.Time()
|
||||||
} else {
|
} else {
|
||||||
tmp = rerere(intermediate, ft.Type)
|
tmp = rerere(intermediate, ft.Type, isJson)
|
||||||
}
|
}
|
||||||
fuck := reflect.ValueOf(tmp)
|
fuck := reflect.ValueOf(tmp)
|
||||||
if tmp != nil {
|
if tmp != nil {
|
||||||
@ -446,7 +472,7 @@ func rerere(input interface{}, resType reflect.Type) interface{} {
|
|||||||
if tt.Kind() == reflect.Pointer {
|
if tt.Kind() == reflect.Pointer {
|
||||||
tt = tt.Elem()
|
tt = tt.Elem()
|
||||||
}
|
}
|
||||||
tmp := rerere(intermediate, ft.Type)
|
tmp := rerere(intermediate, ft.Type, isJson)
|
||||||
if tmp != nil {
|
if tmp != nil {
|
||||||
if reflect.ValueOf(tmp).Kind() == reflect.Pointer && fv.Kind() != reflect.Pointer {
|
if reflect.ValueOf(tmp).Kind() == reflect.Pointer && fv.Kind() != reflect.Pointer {
|
||||||
fv.Set(reflect.ValueOf(tmp).Elem())
|
fv.Set(reflect.ValueOf(tmp).Elem())
|
||||||
@ -463,7 +489,14 @@ func rerere(input interface{}, resType reflect.Type) interface{} {
|
|||||||
nunu := ModelRegistry.new_(resType.Name())
|
nunu := ModelRegistry.new_(resType.Name())
|
||||||
ider, ok := nunu.(HasID)
|
ider, ok := nunu.(HasID)
|
||||||
if ok {
|
if ok {
|
||||||
ider.SetId(v.Interface())
|
toConvert := reflect.ValueOf(ider.Id()).Type()
|
||||||
|
if v.Type() != toConvert {
|
||||||
|
if v.CanConvert(toConvert) {
|
||||||
|
ider.SetId(v.Convert(toConvert).Interface())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ider.SetId(v.Interface())
|
||||||
|
}
|
||||||
if reflect.ValueOf(ider).Kind() == reflect.Pointer {
|
if reflect.ValueOf(ider).Kind() == reflect.Pointer {
|
||||||
nunu = reflect.ValueOf(ider).Elem().Interface()
|
nunu = reflect.ValueOf(ider).Elem().Interface()
|
||||||
}
|
}
|
||||||
@ -471,10 +504,16 @@ func rerere(input interface{}, resType reflect.Type) interface{} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
arr := v.Interface().(bson.A)
|
_, aOk := v.Interface().(bson.A)
|
||||||
|
var arr []interface{}
|
||||||
|
if !aOk {
|
||||||
|
arr = v.Interface().([]interface{})
|
||||||
|
} else {
|
||||||
|
arr = []interface{}(v.Interface().(bson.A))
|
||||||
|
}
|
||||||
for _, it := range arr {
|
for _, it := range arr {
|
||||||
if it != nil {
|
if it != nil {
|
||||||
tmp := reflect.ValueOf(rerere(it, rve.Type().Elem()))
|
tmp := reflect.ValueOf(rerere(it, rve.Type().Elem(), isJson))
|
||||||
if tmp.Kind() == reflect.Pointer {
|
if tmp.Kind() == reflect.Pointer {
|
||||||
tmp = tmp.Elem()
|
tmp = tmp.Elem()
|
||||||
}
|
}
|
||||||
@ -534,7 +573,13 @@ func handleAnon(raw interface{}, rtype reflect.Type, rval reflect.Value) reflect
|
|||||||
if valueField.Kind() == reflect.Pointer {
|
if valueField.Kind() == reflect.Pointer {
|
||||||
valueField.Elem().Set(reflect.ValueOf(fval))
|
valueField.Elem().Set(reflect.ValueOf(fval))
|
||||||
} else {
|
} else {
|
||||||
valueField.Set(reflect.ValueOf(fval))
|
if reflect.TypeOf(fval) == reflect.TypeFor[string]() && typeField.Type == reflect.TypeFor[time.Time]() {
|
||||||
|
tt, _ := time.Parse(time.RFC3339, fval.(string))
|
||||||
|
valueField.Set(reflect.ValueOf(tt))
|
||||||
|
} else {
|
||||||
|
valueField.Set(reflect.ValueOf(fval))
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
registry.go
12
registry.go
@ -227,9 +227,13 @@ func (r TModelRegistry) Index(n string) int {
|
|||||||
func (r TModelRegistry) new_(n string) interface{} {
|
func (r TModelRegistry) new_(n string) interface{} {
|
||||||
if name, m, ok := ModelRegistry.HasByName(n); ok {
|
if name, m, ok := ModelRegistry.HasByName(n); ok {
|
||||||
v := reflect.New(m.Type)
|
v := reflect.New(m.Type)
|
||||||
df := v.Elem().Field(m.idx)
|
av := reflect.New(reflect.PointerTo(m.Type)).Elem()
|
||||||
|
av.Addr().Elem().Set(v)
|
||||||
|
df := av.Addr().Elem().Elem().Field(m.idx)
|
||||||
|
ado := reflect.New(reflect.PointerTo(df.Type())).Elem()
|
||||||
do := reflect.New(df.Type())
|
do := reflect.New(df.Type())
|
||||||
d := do.Interface().(IDocument)
|
ado.Addr().Elem().Set(do)
|
||||||
|
d := ado.Addr().Elem().Interface().(IDocument)
|
||||||
d.newPopulationMap()
|
d.newPopulationMap()
|
||||||
//d := df.Interface().(IDocument)
|
//d := df.Interface().(IDocument)
|
||||||
for k := range m.references {
|
for k := range m.references {
|
||||||
@ -237,9 +241,9 @@ func (r TModelRegistry) new_(n string) interface{} {
|
|||||||
}
|
}
|
||||||
d.setModel(*m)
|
d.setModel(*m)
|
||||||
d.getModel().typeName = name
|
d.getModel().typeName = name
|
||||||
d.SetSelf(do.Interface())
|
d.SetSelf(av.Interface())
|
||||||
df.Set(reflect.ValueOf(d).Elem())
|
df.Set(reflect.ValueOf(d).Elem())
|
||||||
return v.Interface()
|
return av.Interface()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user