🌺
- fix references in nested structs not being registered properly - rework struct tag parsing - remove debug logs - fix bug where an unrelated field with the same prefix as another population path is erroneously marked as populated
This commit is contained in:
		
							parent
							
								
									c85efdc49f
								
							
						
					
					
						commit
						510a126f4b
					
				| @ -9,7 +9,6 @@ import ( | ||||
| 	"go.mongodb.org/mongo-driver/v2/mongo" | ||||
| 	"go.mongodb.org/mongo-driver/v2/mongo/options" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| @ -80,11 +79,9 @@ func serializeIDs(input interface{}, isJson bool, populated map[string]bool, par | ||||
| 				} | ||||
| 				var ip bool | ||||
| 				for k1, v1 := range populated { | ||||
| 					if k1 == descent || k1 == parent { | ||||
| 					if k1 == descent { | ||||
| 						ip = v1 | ||||
| 						break | ||||
| 					} else if strings.HasPrefix(k1, descent) { | ||||
| 						ip = v1 | ||||
| 					} | ||||
| 				} | ||||
| 				if terr == nil { | ||||
|  | ||||
							
								
								
									
										6
									
								
								query.go
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								query.go
									
									
									
									
									
								
							| @ -4,7 +4,6 @@ import ( | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/fatih/structtag" | ||||
| 	"go.mongodb.org/mongo-driver/v2/bson" | ||||
| 	"go.mongodb.org/mongo-driver/v2/mongo" | ||||
| @ -186,8 +185,6 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter | ||||
| 		} | ||||
| 		if hatred.CanSet() { | ||||
| 			if reflect.ValueOf(t).Kind() == reflect.Pointer { | ||||
| 				fmt.Println(reflect.ValueOf(t).Elem().Type().String()) | ||||
| 				fmt.Println(rv.Type().String()) | ||||
| 				if hatred.Kind() == reflect.Pointer { | ||||
| 					hatred.Set(reflect.ValueOf(t)) | ||||
| 				} else { | ||||
| @ -292,6 +289,9 @@ func readFields(field string, m *Model) (Reference, string) { | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} else if ok { | ||||
| 			r = m.references[field] | ||||
| 			break | ||||
| 		} | ||||
| 		if keptKey != "" { | ||||
| 			break | ||||
|  | ||||
							
								
								
									
										129
									
								
								registry.go
									
									
									
									
									
								
							
							
						
						
									
										129
									
								
								registry.go
									
									
									
									
									
								
							| @ -6,6 +6,7 @@ import ( | ||||
| 	"log" | ||||
| 	"reflect" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/fatih/structtag" | ||||
| 	"go.mongodb.org/mongo-driver/v2/bson" | ||||
| @ -111,82 +112,86 @@ func makeRef(idx int, modelName string, fieldName string, ht reflect.Type) Refer | ||||
| 	panic("model name was empty") | ||||
| } | ||||
| 
 | ||||
| func parseTags(t reflect.Type, v reflect.Value, lastParsed string, eqCount int) (map[string][]InternalIndex, map[string]Reference, map[string]gridFSReference, string) { | ||||
| type parseResult []string | ||||
| 
 | ||||
| func (p parseResult) includes(str string) bool { | ||||
| 	for _, v := range p { | ||||
| 		if v == str { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func parseTags(t reflect.Type, v reflect.Value, lastParsed parseResult, depth int) (map[string][]InternalIndex, map[string]Reference, map[string]gridFSReference, string) { | ||||
| 	coll := "" | ||||
| 	refs := make(map[string]Reference) | ||||
| 	idcs := make(map[string][]InternalIndex) | ||||
| 	gfsRefs := make(map[string]gridFSReference) | ||||
| 
 | ||||
| 	if depth >= 4 { | ||||
| 		return idcs, refs, gfsRefs, coll | ||||
| 	} | ||||
| 	for i := 0; i < v.NumField(); i++ { | ||||
| 		sft := t.Field(i) | ||||
| 		ft := sft.Type | ||||
| 		tags, err := structtag.Parse(string(sft.Tag)) | ||||
| 		panik(err) | ||||
| 		shouldContinue := true | ||||
| 		for { | ||||
| 			if !shouldContinue { | ||||
| 				break | ||||
| 		switch ft.Kind() { | ||||
| 		case reflect.Slice: | ||||
| 			ft = ft.Elem() | ||||
| 			fallthrough | ||||
| 		case reflect.Pointer: | ||||
| 			if ft.Kind() == reflect.Pointer { | ||||
| 				ft = ft.Elem() | ||||
| 			} | ||||
| 			switch ft.Kind() { | ||||
| 			case reflect.Slice: | ||||
| 				ft = ft.Elem() | ||||
| 				count := eqCount | ||||
| 				if lastParsed != ft.String() { | ||||
| 					count = 0 | ||||
| 				} else { | ||||
| 					count = count + 1 | ||||
| 				} | ||||
| 				if /*_, ok := tags.Get("ref"); ok != nil && */ count < 3 { | ||||
| 					if ft.Kind() == reflect.Struct { | ||||
| 						ii2, rr2, gg2, _ := parseTags(ft, reflect.New(ft).Elem(), ft.String(), count) | ||||
| 						for k, vv := range ii2 { | ||||
| 							idcs[sft.Name+"."+k] = vv | ||||
| 						} | ||||
| 						for k, vv := range rr2 { | ||||
| 							refs[sft.Name+"."+k] = vv | ||||
| 						} | ||||
| 						for k, vv := range gg2 { | ||||
| 							gfsRefs[sft.Name+"."+k] = vv | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				continue | ||||
| 			case reflect.Pointer: | ||||
| 				ft = ft.Elem() | ||||
| 				fallthrough | ||||
| 			case reflect.Struct: | ||||
| 				if ft.ConvertibleTo(reflect.TypeOf(Document{})) { | ||||
| 					collTag, err := tags.Get("coll") | ||||
| 					panik(err) | ||||
| 					coll = collTag.Name | ||||
| 					idxTag, err := tags.Get("idx") | ||||
| 					if err == nil { | ||||
| 						idcs[sft.Type.Name()] = scanIndex(idxTag.Value()) | ||||
| 					} | ||||
| 					shouldContinue = false | ||||
| 					break | ||||
| 				} | ||||
| 				if refTag, ok := tags.Get("ref"); ok == nil { | ||||
| 					sname := sft.Name | ||||
| 					refs[sname] = makeRef(i, refTag.Name, sft.Name, sft.Type) | ||||
| 				} | ||||
| 				if gtag, ok := tags.Get("gridfs"); ok == nil { | ||||
| 					sname := sft.Name + "@" + gtag.Name | ||||
| 					gfsRefs[sname] = makeGfsRef(gtag, i) | ||||
| 				} | ||||
| 				fallthrough | ||||
| 			default: | ||||
| 			fallthrough | ||||
| 		case reflect.Struct: | ||||
| 			if ft.ConvertibleTo(reflect.TypeOf(Document{})) { | ||||
| 				collTag, err := tags.Get("coll") | ||||
| 				panik(err) | ||||
| 				coll = collTag.Name | ||||
| 				idxTag, err := tags.Get("idx") | ||||
| 				if err == nil { | ||||
| 					idcs[sft.Name] = scanIndex(idxTag.Value()) | ||||
| 					idcs[sft.Type.Name()] = scanIndex(idxTag.Value()) | ||||
| 				} | ||||
| 				if gtag, ok := tags.Get("gridfs"); ok == nil { | ||||
| 					sname := sft.Name + "@" + gtag.Name | ||||
| 					gfsRefs[sname] = makeGfsRef(gtag, i) | ||||
| 				} | ||||
| 				shouldContinue = false | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			if lastParsed.includes(sft.Name) { | ||||
| 				continue | ||||
| 			} | ||||
| 			blip := lastParsed | ||||
| 			blip = append(blip, sft.Name) | ||||
| 			if ft.Kind() == reflect.Struct && ft != reflect.TypeFor[time.Time]() { | ||||
| 				ii2, rr2, gg2, _ := parseTags(ft, reflect.New(ft).Elem(), blip, depth+1) | ||||
| 				for k, vv := range ii2 { | ||||
| 					idcs[sft.Name+"."+k] = vv | ||||
| 				} | ||||
| 				for k, vv := range rr2 { | ||||
| 					refs[sft.Name+"."+k] = vv | ||||
| 				} | ||||
| 				for k, vv := range gg2 { | ||||
| 					gfsRefs[sft.Name+"."+k] = vv | ||||
| 				} | ||||
| 			} | ||||
| 			if refTag, ok := tags.Get("ref"); ok == nil { | ||||
| 				sname := sft.Name | ||||
| 				refs[sname] = makeRef(i, refTag.Name, sft.Name, sft.Type) | ||||
| 			} | ||||
| 			if gtag, ok := tags.Get("gridfs"); ok == nil { | ||||
| 				sname := sft.Name + "@" + gtag.Name | ||||
| 				gfsRefs[sname] = makeGfsRef(gtag, i) | ||||
| 			} | ||||
| 			fallthrough | ||||
| 		default: | ||||
| 			idxTag, err := tags.Get("idx") | ||||
| 			if err == nil { | ||||
| 				idcs[sft.Name] = scanIndex(idxTag.Value()) | ||||
| 			} | ||||
| 			if gtag, ok := tags.Get("gridfs"); ok == nil { | ||||
| 				sname := sft.Name + "@" + gtag.Name | ||||
| 				gfsRefs[sname] = makeGfsRef(gtag, i) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return idcs, refs, gfsRefs, coll | ||||
| @ -304,7 +309,7 @@ func (r TModelRegistry) Model(mdl ...any) { | ||||
| 		if idx < 0 { | ||||
| 			panic("A model must embed the Document struct!") | ||||
| 		} | ||||
| 		inds, refs, gfs, coll := parseTags(t, v, "", 0) | ||||
| 		inds, refs, gfs, coll := parseTags(t, v, make(parseResult, 0), 0) | ||||
| 		if coll == "" { | ||||
| 			panic(fmt.Sprintf("a Document needs to be given a collection name! (passed type: %s)", n)) | ||||
| 		} | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user