nvm figured it out lol?
This commit is contained in:
parent
4de1c20938
commit
5585634c83
@ -15,6 +15,7 @@ type Document struct {
|
||||
model *Model `bson:"-"`
|
||||
exists bool `bson:"-"`
|
||||
self any `bson:"-"`
|
||||
raw any `bson:"-"`
|
||||
populatedFields map[string]bool `bson:"-"`
|
||||
}
|
||||
|
||||
@ -68,6 +69,8 @@ type IDocument interface {
|
||||
markPopulated(field string)
|
||||
markDepopulated(field string)
|
||||
newPopulationMap()
|
||||
getRaw() any
|
||||
setRaw(raw any)
|
||||
}
|
||||
|
||||
type SaveOptions struct {
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"go.mongodb.org/mongo-driver/v2/mongo"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -79,9 +80,11 @@ func serializeIDs(input interface{}, isJson bool, populated map[string]bool, par
|
||||
}
|
||||
var ip bool
|
||||
for k1, v1 := range populated {
|
||||
if k1 == parent {
|
||||
if k1 == descent || k1 == parent {
|
||||
ip = v1
|
||||
break
|
||||
} else if strings.HasPrefix(k1, descent) {
|
||||
ip = v1
|
||||
}
|
||||
}
|
||||
if terr == nil {
|
||||
@ -93,7 +96,9 @@ func serializeIDs(input interface{}, isJson bool, populated map[string]bool, par
|
||||
rarr = append(rarr, getID(fv.Index(j).Interface()))
|
||||
} else {
|
||||
if ip {
|
||||
ret0[bbson.Name] = serializeIDs(fv.Index(j).Interface(), isJson, populated, descent)
|
||||
rarr = append(rarr, serializeIDs(fv.Index(j).Interface(), isJson, populated, descent))
|
||||
} else {
|
||||
rarr = append(rarr, getID(fv.Index(j).Interface()))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -101,15 +106,15 @@ func serializeIDs(input interface{}, isJson bool, populated map[string]bool, par
|
||||
} else if !ok {
|
||||
panic(fmt.Sprintf("referenced model slice at '%s.%s' does not implement HasID", nameOf(input), ft.Name))
|
||||
} else {
|
||||
if reflect.ValueOf(ifc).IsNil() {
|
||||
if reflect.ValueOf(ifc).IsNil() || reflect.ValueOf(ifc.Id()).IsZero() {
|
||||
ret0[bbson.Name] = nil
|
||||
} else {
|
||||
if !isJson {
|
||||
ret0[bbson.Name] = ifc.Id()
|
||||
} else {
|
||||
if ip {
|
||||
if ip && bbson.Name != "-" {
|
||||
ret0[bbson.Name] = serializeIDs(fv.Interface(), isJson, populated, descent)
|
||||
} else {
|
||||
} else if bbson.Name != "-" {
|
||||
ret0[bbson.Name] = ifc.Id()
|
||||
}
|
||||
}
|
||||
@ -313,3 +318,11 @@ func (d *Document) newPopulationMap() {
|
||||
d.populatedFields = make(map[string]bool)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Document) setRaw(raw any) {
|
||||
d.raw = raw
|
||||
}
|
||||
|
||||
func (d *Document) getRaw() any {
|
||||
return d.raw
|
||||
}
|
||||
|
4
model.go
4
model.go
@ -132,8 +132,9 @@ func (m *Model) Find(query interface{}, opts *options.FindOptionsBuilder) (*Quer
|
||||
qq.reOrganize()
|
||||
err = nil
|
||||
}
|
||||
for _, doc := range idoc {
|
||||
for i, doc := range idoc {
|
||||
doc.setModel(*m)
|
||||
doc.setRaw(rawRes[i])
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,6 +172,7 @@ func (m *Model) FindOne(query interface{}, options *options.FindOneOptionsBuilde
|
||||
}
|
||||
qqn := ModelRegistry.new_(m.typeName)
|
||||
idoc, ok := qqn.(IDocument)
|
||||
idoc.setRaw(raw)
|
||||
|
||||
qq := &Query{
|
||||
collection: m.getColl(),
|
||||
|
70
query.go
70
query.go
@ -159,7 +159,9 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter
|
||||
q := bson.M{"_id": rawDoc}
|
||||
reso := DB.Collection(rcoll).FindOne(context.TODO(), q)
|
||||
if !errors.Is(reso.Err(), mongo.ErrNoDocuments) {
|
||||
reso.Decode(t)
|
||||
var anotherMap bson.M
|
||||
reso.Decode(&anotherMap)
|
||||
reflect.ValueOf(t).Elem().Set(reflect.ValueOf(rerere(anotherMap, tto)).Elem())
|
||||
}
|
||||
hatred := rv
|
||||
if hatred.Kind() == reflect.Pointer {
|
||||
@ -227,6 +229,49 @@ func (q *Query) LoadFile(fields ...string) *Query {
|
||||
return q
|
||||
}
|
||||
|
||||
func readFields(field string, m *Model) (Reference, string) {
|
||||
var r Reference
|
||||
var keptKey string
|
||||
if m == nil {
|
||||
return r, keptKey
|
||||
}
|
||||
for k2, v := range m.references {
|
||||
if strings.HasPrefix(k2, field) {
|
||||
r = v
|
||||
keptKey = k2
|
||||
break
|
||||
} else if _, ok := m.references[field]; !ok {
|
||||
splitSegs := strings.Split(field, ".")
|
||||
for ii := 0; ii < len(splitSegs)-1; ii++ {
|
||||
mr, ok2 := m.references[splitSegs[ii]]
|
||||
if ok2 {
|
||||
_, sec, _ := ModelRegistry.HasByName(mr.Model)
|
||||
if sec != nil {
|
||||
refff, ok3 := sec.references[splitSegs[ii+1]]
|
||||
if ok3 {
|
||||
r = refff
|
||||
keptKey = k2
|
||||
break
|
||||
} else {
|
||||
joined := strings.Join(splitSegs[ii+1:], ".")
|
||||
inner1, innerKey := readFields(joined, sec)
|
||||
if inner1.exists {
|
||||
r = inner1
|
||||
keptKey = innerKey
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if keptKey != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
return r, keptKey
|
||||
}
|
||||
|
||||
// Populate populates document references via reflection
|
||||
func (q *Query) Populate(fields ...string) *Query {
|
||||
_, cm, _ := ModelRegistry.HasByName(q.model.typeName)
|
||||
@ -236,14 +281,7 @@ func (q *Query) Populate(fields ...string) *Query {
|
||||
for _, field := range fields {
|
||||
// 0 = fieldname, 1 = typename, 2 = bson name
|
||||
|
||||
var r Reference
|
||||
|
||||
for k2, v := range cm.references {
|
||||
if strings.HasPrefix(k2, field) {
|
||||
r = v
|
||||
break
|
||||
}
|
||||
}
|
||||
r, keptKey := readFields(field, cm)
|
||||
|
||||
if r.exists {
|
||||
// get self
|
||||
@ -275,6 +313,11 @@ func (q *Query) Populate(fields ...string) *Query {
|
||||
}
|
||||
src := ref.Index(i).Interface()
|
||||
inter := populate(r, refColl.collection, val2, field, src)
|
||||
aid, docOk := inter.(IDocument)
|
||||
if docOk {
|
||||
aid.markPopulated(keptKey)
|
||||
aid.markPopulated(field)
|
||||
}
|
||||
if reflect.ValueOf(inter).Kind() == reflect.Pointer {
|
||||
slic.Elem().Set(reflect.Append(slic.Elem(), reflect.ValueOf(inter)))
|
||||
} else {
|
||||
@ -347,7 +390,14 @@ func rerere(input interface{}, resType reflect.Type) interface{} {
|
||||
if resType.Kind() == reflect.Pointer {
|
||||
resType = resType.Elem()
|
||||
}
|
||||
resV := reflect.New(resType)
|
||||
var resV reflect.Value
|
||||
newInstance := ModelRegistry.newForType(resType)
|
||||
if newInstance == nil {
|
||||
resV = reflect.New(resType)
|
||||
} else {
|
||||
resV = reflect.ValueOf(newInstance)
|
||||
}
|
||||
|
||||
var rve = resV
|
||||
if rve.Kind() == reflect.Pointer {
|
||||
rve = resV.Elem()
|
||||
|
@ -167,7 +167,7 @@ func parseTags(t reflect.Type, v reflect.Value, lastParsed string, eqCount int)
|
||||
break
|
||||
}
|
||||
if refTag, ok := tags.Get("ref"); ok == nil {
|
||||
sname := sft.Name + "@" + refTag.Name
|
||||
sname := sft.Name
|
||||
refs[sname] = makeRef(i, refTag.Name, sft.Name, sft.Type)
|
||||
}
|
||||
if gtag, ok := tags.Get("gridfs"); ok == nil {
|
||||
@ -244,6 +244,10 @@ func (r TModelRegistry) new_(n string) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r TModelRegistry) newForType(rt reflect.Type) interface{} {
|
||||
return r.new_(rt.Name())
|
||||
}
|
||||
|
||||
func (r TModelRegistry) Get(name string) *Model {
|
||||
model, ok := r[name]
|
||||
if !ok {
|
||||
|
Loading…
x
Reference in New Issue
Block a user