🌺
- 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"
|
||||||
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -80,11 +79,9 @@ func serializeIDs(input interface{}, isJson bool, populated map[string]bool, par
|
|||||||
}
|
}
|
||||||
var ip bool
|
var ip bool
|
||||||
for k1, v1 := range populated {
|
for k1, v1 := range populated {
|
||||||
if k1 == descent || k1 == parent {
|
if k1 == descent {
|
||||||
ip = v1
|
ip = v1
|
||||||
break
|
break
|
||||||
} else if strings.HasPrefix(k1, descent) {
|
|
||||||
ip = v1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if terr == nil {
|
if terr == nil {
|
||||||
|
6
query.go
6
query.go
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"github.com/fatih/structtag"
|
"github.com/fatih/structtag"
|
||||||
"go.mongodb.org/mongo-driver/v2/bson"
|
"go.mongodb.org/mongo-driver/v2/bson"
|
||||||
"go.mongodb.org/mongo-driver/v2/mongo"
|
"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 hatred.CanSet() {
|
||||||
if reflect.ValueOf(t).Kind() == reflect.Pointer {
|
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 {
|
if hatred.Kind() == reflect.Pointer {
|
||||||
hatred.Set(reflect.ValueOf(t))
|
hatred.Set(reflect.ValueOf(t))
|
||||||
} else {
|
} else {
|
||||||
@ -292,6 +289,9 @@ func readFields(field string, m *Model) (Reference, string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if ok {
|
||||||
|
r = m.references[field]
|
||||||
|
break
|
||||||
}
|
}
|
||||||
if keptKey != "" {
|
if keptKey != "" {
|
||||||
break
|
break
|
||||||
|
73
registry.go
73
registry.go
@ -6,6 +6,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/fatih/structtag"
|
"github.com/fatih/structtag"
|
||||||
"go.mongodb.org/mongo-driver/v2/bson"
|
"go.mongodb.org/mongo-driver/v2/bson"
|
||||||
@ -111,48 +112,38 @@ func makeRef(idx int, modelName string, fieldName string, ht reflect.Type) Refer
|
|||||||
panic("model name was empty")
|
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 := ""
|
coll := ""
|
||||||
refs := make(map[string]Reference)
|
refs := make(map[string]Reference)
|
||||||
idcs := make(map[string][]InternalIndex)
|
idcs := make(map[string][]InternalIndex)
|
||||||
gfsRefs := make(map[string]gridFSReference)
|
gfsRefs := make(map[string]gridFSReference)
|
||||||
|
if depth >= 4 {
|
||||||
|
return idcs, refs, gfsRefs, coll
|
||||||
|
}
|
||||||
for i := 0; i < v.NumField(); i++ {
|
for i := 0; i < v.NumField(); i++ {
|
||||||
sft := t.Field(i)
|
sft := t.Field(i)
|
||||||
ft := sft.Type
|
ft := sft.Type
|
||||||
tags, err := structtag.Parse(string(sft.Tag))
|
tags, err := structtag.Parse(string(sft.Tag))
|
||||||
panik(err)
|
panik(err)
|
||||||
shouldContinue := true
|
|
||||||
for {
|
|
||||||
if !shouldContinue {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
switch ft.Kind() {
|
switch ft.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
ft = ft.Elem()
|
ft = ft.Elem()
|
||||||
count := eqCount
|
fallthrough
|
||||||
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:
|
case reflect.Pointer:
|
||||||
|
if ft.Kind() == reflect.Pointer {
|
||||||
ft = ft.Elem()
|
ft = ft.Elem()
|
||||||
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
if ft.ConvertibleTo(reflect.TypeOf(Document{})) {
|
if ft.ConvertibleTo(reflect.TypeOf(Document{})) {
|
||||||
@ -163,8 +154,25 @@ func parseTags(t reflect.Type, v reflect.Value, lastParsed string, eqCount int)
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
idcs[sft.Type.Name()] = scanIndex(idxTag.Value())
|
idcs[sft.Type.Name()] = scanIndex(idxTag.Value())
|
||||||
}
|
}
|
||||||
shouldContinue = false
|
continue
|
||||||
break
|
}
|
||||||
|
|
||||||
|
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 {
|
if refTag, ok := tags.Get("ref"); ok == nil {
|
||||||
sname := sft.Name
|
sname := sft.Name
|
||||||
@ -184,9 +192,6 @@ func parseTags(t reflect.Type, v reflect.Value, lastParsed string, eqCount int)
|
|||||||
sname := sft.Name + "@" + gtag.Name
|
sname := sft.Name + "@" + gtag.Name
|
||||||
gfsRefs[sname] = makeGfsRef(gtag, i)
|
gfsRefs[sname] = makeGfsRef(gtag, i)
|
||||||
}
|
}
|
||||||
shouldContinue = false
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return idcs, refs, gfsRefs, coll
|
return idcs, refs, gfsRefs, coll
|
||||||
@ -304,7 +309,7 @@ func (r TModelRegistry) Model(mdl ...any) {
|
|||||||
if idx < 0 {
|
if idx < 0 {
|
||||||
panic("A model must embed the Document struct!")
|
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 == "" {
|
if coll == "" {
|
||||||
panic(fmt.Sprintf("a Document needs to be given a collection name! (passed type: %s)", n))
|
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