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 ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"go.mongodb.org/mongo-driver/v2/bson" | ||||
| 	"log" | ||||
| 	"reflect" | ||||
| @ -33,13 +34,24 @@ func (d *Document) UnmarshalJSON(bytes []byte) error { | ||||
| 		err = json.Unmarshal(bytes, &tmpV) | ||||
| 		typ := reflect.SliceOf(d.model.Type) | ||||
| 		//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 | ||||
| 	case map[string]interface{}: | ||||
| 		tmpV := make(bson.M) | ||||
| 		err = json.Unmarshal(bytes, &tmpV) | ||||
| 		typ := d.model.Type | ||||
| 		rerere(tmpV, typ) | ||||
| 		typ := reflect.PointerTo(d.model.Type) | ||||
| 		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 | ||||
| 	} | ||||
| 	return err | ||||
|  | ||||
							
								
								
									
										9
									
								
								model.go
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								model.go
									
									
									
									
									
								
							| @ -217,14 +217,15 @@ func createBase(d any) (reflect.Value, int, string) { | ||||
| 	v := valueOf(d) | ||||
| 	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 { | ||||
| 		r.Elem().Set(reflect.ValueOf(d).Elem()) | ||||
| 		r.Addr().Elem().Elem().Set(reflect.ValueOf(d).Elem()) | ||||
| 	} else { | ||||
| 		r.Elem().Set(reflect.ValueOf(d)) | ||||
| 		r.Addr().Elem().Elem().Set(reflect.ValueOf(d)) | ||||
| 	} | ||||
| 	ri.setTypeName(n) | ||||
| 	r.Interface().(IDocument).setModel(*ri) | ||||
|  | ||||
							
								
								
									
										75
									
								
								query.go
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								query.go
									
									
									
									
									
								
							| @ -10,6 +10,7 @@ import ( | ||||
| 	"go.mongodb.org/mongo-driver/v2/mongo" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| 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) { | ||||
| 			var anotherMap = make(bson.M) | ||||
| 			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) | ||||
| 		} | ||||
| 		hatred := rv | ||||
| @ -338,12 +339,12 @@ func (q *Query) reOrganize() { | ||||
| 		} | ||||
| 		slic := reflect.New(reflect.SliceOf(typ)) | ||||
| 		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)) | ||||
| 		} | ||||
| 		trvo = slic.Elem() | ||||
| 	} 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) | ||||
| @ -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) | ||||
| 	v := reflect.ValueOf(input) | ||||
| 	var key string | ||||
| 	if isJson { | ||||
| 		key = "json" | ||||
| 	} else { | ||||
| 		key = "bson" | ||||
| 	} | ||||
| 	if input == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| @ -382,11 +389,24 @@ func rerere(input interface{}, resType reflect.Type) interface{} { | ||||
| 		resType = resType.Elem() | ||||
| 	} | ||||
| 	var resV reflect.Value | ||||
| 	newInstance := ModelRegistry.newForType(resType) | ||||
| 	if newInstance == nil { | ||||
| 		resV = reflect.New(resType) | ||||
| 	} else { | ||||
| 	var newInstance interface{} | ||||
| 	if _, _, has := ModelRegistry.Has(reflect.New(resType).Elem().Interface()); has { | ||||
| 		newInstance = Create(reflect.New(resType).Elem().Interface()) | ||||
| 		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 | ||||
| @ -407,6 +427,12 @@ func rerere(input interface{}, resType reflect.Type) interface{} { | ||||
| 	case reflect.Struct: | ||||
| 		shouldBreak := false | ||||
| 		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 { | ||||
| 			for i := 0; i < resType.NumField(); i++ { | ||||
| 				ft := resType.Field(i) | ||||
| @ -417,7 +443,7 @@ func rerere(input interface{}, resType reflect.Type) interface{} { | ||||
| 				} | ||||
| 				tags, err := structtag.Parse(string(ft.Tag)) | ||||
| 				panik(err) | ||||
| 				btag, err := tags.Get("bson") | ||||
| 				btag, err := tags.Get(key) | ||||
| 				if err != nil { | ||||
| 					continue | ||||
| 				} | ||||
| @ -431,7 +457,7 @@ func rerere(input interface{}, resType reflect.Type) interface{} { | ||||
| 					if ttmp, tok := intermediate.(bson.DateTime); tok { | ||||
| 						tmp = ttmp.Time() | ||||
| 					} else { | ||||
| 						tmp = rerere(intermediate, ft.Type) | ||||
| 						tmp = rerere(intermediate, ft.Type, isJson) | ||||
| 					} | ||||
| 					fuck := reflect.ValueOf(tmp) | ||||
| 					if tmp != nil { | ||||
| @ -446,7 +472,7 @@ func rerere(input interface{}, resType reflect.Type) interface{} { | ||||
| 					if tt.Kind() == reflect.Pointer { | ||||
| 						tt = tt.Elem() | ||||
| 					} | ||||
| 					tmp := rerere(intermediate, ft.Type) | ||||
| 					tmp := rerere(intermediate, ft.Type, isJson) | ||||
| 					if tmp != nil { | ||||
| 						if reflect.ValueOf(tmp).Kind() == reflect.Pointer && fv.Kind() != reflect.Pointer { | ||||
| 							fv.Set(reflect.ValueOf(tmp).Elem()) | ||||
| @ -463,7 +489,14 @@ func rerere(input interface{}, resType reflect.Type) interface{} { | ||||
| 			nunu := ModelRegistry.new_(resType.Name()) | ||||
| 			ider, ok := nunu.(HasID) | ||||
| 			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 { | ||||
| 					nunu = reflect.ValueOf(ider).Elem().Interface() | ||||
| 				} | ||||
| @ -471,10 +504,16 @@ func rerere(input interface{}, resType reflect.Type) interface{} { | ||||
| 			} | ||||
| 		} | ||||
| 	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 { | ||||
| 			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 { | ||||
| 					tmp = tmp.Elem() | ||||
| 				} | ||||
| @ -534,7 +573,13 @@ func handleAnon(raw interface{}, rtype reflect.Type, rval reflect.Value) reflect | ||||
| 				if valueField.Kind() == reflect.Pointer { | ||||
| 					valueField.Elem().Set(reflect.ValueOf(fval)) | ||||
| 				} 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{} { | ||||
| 	if name, m, ok := ModelRegistry.HasByName(n); ok { | ||||
| 		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()) | ||||
| 		d := do.Interface().(IDocument) | ||||
| 		ado.Addr().Elem().Set(do) | ||||
| 		d := ado.Addr().Elem().Interface().(IDocument) | ||||
| 		d.newPopulationMap() | ||||
| 		//d := df.Interface().(IDocument)
 | ||||
| 		for k := range m.references { | ||||
| @ -237,9 +241,9 @@ func (r TModelRegistry) new_(n string) interface{} { | ||||
| 		} | ||||
| 		d.setModel(*m) | ||||
| 		d.getModel().typeName = name | ||||
| 		d.SetSelf(do.Interface()) | ||||
| 		d.SetSelf(av.Interface()) | ||||
| 		df.Set(reflect.ValueOf(d).Elem()) | ||||
| 		return v.Interface() | ||||
| 		return av.Interface() | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user