THIS DOESN'T WORK.

but i need to commit
This commit is contained in:
☙◦ The Tablet ❀ GamerGirlandCo ◦❧ 2025-04-06 15:47:21 -04:00
parent 1f9d32193f
commit f3ce7f67ec
Signed by: tablet
GPG Key ID: 924A5F6AF051E87C
6 changed files with 121 additions and 15 deletions

View File

@ -1,6 +1,8 @@
package orm
import (
"encoding/json"
"go.mongodb.org/mongo-driver/v2/bson"
"reflect"
"time"
)
@ -15,6 +17,36 @@ type Document struct {
self any `bson:"-"`
populatedFields map[string]bool `bson:"-"`
}
func (d *Document) UnmarshalJSON(bytes []byte) error {
var fiv interface{}
if err := json.Unmarshal(bytes, &fiv); err != nil {
return err
}
var err error
switch fiv.(type) {
case []interface{}:
tmpV := make(bson.A, 0)
err = json.Unmarshal(bytes, &tmpV)
typ := reflect.SliceOf(d.model.Type)
//d.SetSelf()
rerere(tmpV, typ)
break
case map[string]interface{}:
tmpV := make(bson.M)
err = json.Unmarshal(bytes, &tmpV)
typ := d.model.Type
rerere(tmpV, typ)
break
}
return err
}
func (d *Document) MarshalJSON() ([]byte, error) {
v := serializeIDs((d).self, true, d.populatedFields, "")
return json.Marshal(v)
}
type IDocument interface {
Append(field string, a ...interface{}) error
Pull(field string, a ...any) error
@ -23,7 +55,7 @@ type IDocument interface {
Remove() error
Save() error
SaveWith(opts *SaveOptions) error
setSelf(arg interface{})
SetSelf(arg interface{})
getExists() bool
setExists(n bool)
setModified(Modified time.Time)
@ -35,6 +67,7 @@ type IDocument interface {
setModel(m Model)
markPopulated(field string)
markDepopulated(field string)
newPopulationMap()
}
type SaveOptions struct {
@ -56,7 +89,9 @@ func (d *Document) getModified() time.Time {
func (d *Document) setModified(Modified time.Time) {
d.Modified = Modified
}
func (d *Document) setSelf(arg interface{}) {
// SetSelf - don't call this lol
func (d *Document) SetSelf(arg interface{}) {
d.self = arg
}
@ -125,7 +160,7 @@ func (d *Document) Save() error {
}
func (d *Document) serializeToStore() any {
return serializeIDs((d).self)
return serializeIDs((d).self, false, d.populatedFields, "")
}
// Append appends one or more items to `field`.

View File

@ -12,8 +12,13 @@ import (
"time"
)
func serializeIDs(input interface{}) interface{} {
func serializeIDs(input interface{}, isJson bool, populated map[string]bool, parent string) interface{} {
var key string
if isJson {
key = "json"
} else {
key = "bson"
}
vp := reflect.ValueOf(input)
mt := reflect.TypeOf(input)
var ret interface{}
@ -46,9 +51,15 @@ func serializeIDs(input interface{}) interface{} {
for i := 0; i < vp.Elem().NumField(); i++ {
fv := vp.Elem().Field(i)
ft := mt.Field(i)
var descent string
if parent != "" {
descent = parent + "." + ft.Name
} else {
descent = ft.Name
}
tag, err := structtag.Parse(string(ft.Tag))
panik(err)
bbson, err := tag.Get("bson")
bbson, err := tag.Get(key)
if err != nil || bbson.Name == "-" {
continue
}
@ -66,12 +77,25 @@ func serializeIDs(input interface{}) interface{} {
vp1.Elem().Set(reflect.ValueOf(fv.Interface()))
fv.Set(vp1.Elem())
}
var ip bool
for k1, v1 := range populated {
if k1 == parent {
ip = v1
break
}
}
if terr == nil {
ifc, ok := fv.Interface().(HasID)
if fv.Kind() == reflect.Slice {
rarr := bson.A{}
for j := 0; j < fv.Len(); j++ {
rarr = append(rarr, getID(fv.Index(j).Interface()))
if !isJson {
rarr = append(rarr, getID(fv.Index(j).Interface()))
} else {
if ip {
ret0[bbson.Name] = serializeIDs(fv.Index(j).Interface(), isJson, populated, descent)
}
}
}
ret0[bbson.Name] = rarr
} else if !ok {
@ -80,15 +104,22 @@ func serializeIDs(input interface{}) interface{} {
if reflect.ValueOf(ifc).IsNil() {
ret0[bbson.Name] = nil
} else {
ret0[bbson.Name] = ifc.Id()
if !isJson {
ret0[bbson.Name] = ifc.Id()
} else {
if ip {
ret0[bbson.Name] = serializeIDs(fv.Interface(), isJson, populated, descent)
} else {
ret0[bbson.Name] = ifc.Id()
}
}
}
}
} else {
if fv.Type() == reflect.TypeFor[time.Time]() {
ret0[bbson.Name] = fv.Interface()
} else {
ret0[bbson.Name] = serializeIDs(fv.Interface())
ret0[bbson.Name] = serializeIDs(fv.Interface(), isJson, populated, descent)
}
}
}
@ -99,7 +130,7 @@ func serializeIDs(input interface{}) interface{} {
ret0 := bson.A{}
for i := 0; i < vp.Elem().Len(); i++ {
ret0 = append(ret0, serializeIDs(vp.Elem().Index(i).Addr().Interface()))
ret0 = append(ret0, serializeIDs(vp.Elem().Index(i).Addr().Interface(), isJson, populated, parent))
}
ret = ret0
default:
@ -113,7 +144,7 @@ func doSave(c *mongo.Collection, isNew bool, opts *SaveOptions, arg interface{})
if !ok {
return fmt.Errorf(errFmtNotAModel, nameOf(arg))
}
d.setSelf(d)
d.SetSelf(d)
now := time.Now()
selfo := reflect.ValueOf(d)
vp := selfo
@ -268,9 +299,17 @@ func incrementAll(item interface{}) {
}
func (d *Document) markPopulated(field string) {
d.newPopulationMap()
d.populatedFields[field] = true
}
func (d *Document) markDepopulated(field string) {
d.newPopulationMap()
d.populatedFields[field] = false
}
func (d *Document) newPopulationMap() {
if d.populatedFields == nil {
d.populatedFields = make(map[string]bool)
}
}

View File

@ -189,7 +189,7 @@ func (m *Model) FindOne(query interface{}, options *options.FindOneOptionsBuilde
idoc.setExists(true)
idoc.setModel(*m)
}
idoc.setSelf(idoc)
idoc.SetSelf(idoc)
return qq, err
}
@ -224,6 +224,7 @@ func createBase(d any) (reflect.Value, int, string) {
}
ri.setTypeName(n)
r.Interface().(IDocument).setModel(*ri)
r.Interface().(IDocument).newPopulationMap()
return r, i, n
}
@ -237,7 +238,7 @@ func Create(d any) any {
dm.getModel().setTypeName(n)
what := r.Interface()
dm.setSelf(what)
dm.SetSelf(what)
//df.Set(reflect.ValueOf(dm))
return what
}

View File

@ -3,6 +3,7 @@ package orm
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/fatih/structtag"
"go.mongodb.org/mongo-driver/v2/bson"
@ -157,7 +158,9 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter
t := rawt.(IDocument)
q := bson.M{"_id": rawDoc}
reso := DB.Collection(rcoll).FindOne(context.TODO(), q)
reso.Decode(t)
if !errors.Is(reso.Err(), mongo.ErrNoDocuments) {
reso.Decode(t)
}
hatred := rv
if hatred.Kind() == reflect.Pointer {
hatred = hatred.Elem()
@ -174,12 +177,21 @@ func populate(r Reference, rcoll string, rawDoc interface{}, d string, src inter
src = t
toReturn = src
}
t.SetSelf(t)
t.setExists(true)
}
if toReturn == nil {
sidoc, sok := rv.Interface().(IDocument)
if sok {
sidoc.SetSelf(rv.Interface())
}
return rv.Interface()
}
sidoc, sok := src.(IDocument)
if sok {
sidoc.SetSelf(src)
}
return src
}
@ -271,6 +283,10 @@ func (q *Query) Populate(fields ...string) *Query {
}
tmp1 = slic.Interface()
} else {
asIDocument, docOk := q.doc.(IDocument)
if docOk {
asIDocument.markPopulated(field)
}
tmp1 = populate(r, refColl.collection, rawDoc, field, reflect.ValueOf(q.doc).Interface())
}
q.doc = tmp1

View File

@ -230,9 +230,14 @@ func (r TModelRegistry) new_(n string) interface{} {
df := v.Elem().Field(m.idx)
do := reflect.New(df.Type())
d := do.Interface().(IDocument)
d.newPopulationMap()
//d := df.Interface().(IDocument)
for k := range m.references {
d.markDepopulated(k)
}
d.setModel(*m)
d.getModel().typeName = name
d.SetSelf(do.Interface())
df.Set(reflect.ValueOf(d).Elem())
return v.Interface()
}

10
util.go
View File

@ -218,3 +218,13 @@ func normalizeSliceToDocumentSlice(in any) *DocumentSlice {
}
return &ret
}
func filterMap[k comparable, v any](input map[k]v, pred func(key k, val v) bool) map[k]v {
ret := make(map[k]v)
for k1, v1 := range input {
if pred(k1, v1) {
ret[k1] = v1
}
}
return ret
}