implement recursive deletion for gridfs files when Delete() is called on a document

This commit is contained in:
☙◦ The Tablet ❀ GamerGirlandCo ◦❧ 2025-04-01 18:45:36 -04:00
parent ad7c7f38af
commit 322d97dc95
Signed by: tablet
GPG Key ID: 924A5F6AF051E87C
2 changed files with 77 additions and 0 deletions

View File

@ -180,6 +180,7 @@ func doDelete(d *Document, arg interface{}) error {
_, err := c.DeleteOne(context.TODO(), bson.M{"_id": self.Id()}) _, err := c.DeleteOne(context.TODO(), bson.M{"_id": self.Id()})
if err == nil { if err == nil {
d.exists = false d.exists = false
err = gridFsDel(arg, *d.model)
} }
return err return err
} }

View File

@ -105,6 +105,82 @@ func gridFsLoad(val any, g gridFSReference, field string) any {
return doc.Interface() return doc.Interface()
} }
func gridFsDel(val any, imodel Model) error {
var rerr error
v := reflect.ValueOf(val)
el := v
if v.Kind() == reflect.Pointer {
el = el.Elem()
}
switch el.Kind() {
case reflect.Struct:
for i := 0; i < el.NumField(); i++ {
ft := el.Type().Field(i)
fv := el.Field(i)
if !ft.IsExported() {
continue
}
_, err := structtag.Parse(string(ft.Tag))
panik(err)
var gfsRef *gridFSReference
for kk, vv := range imodel.gridFSReferences {
if strings.HasPrefix(kk, ft.Name) {
gfsRef = &vv
break
}
}
var inner = func(b *mongo.GridFSBucket, it reflect.Value) error {
filename := parseFmt(gfsRef.FilenameFmt, it.Interface())
contents := GridFSFile{}
curs, err2 := b.Find(context.TODO(), bson.M{"filename": filename})
if !errors.Is(err2, mongo.ErrNoDocuments) {
_ = curs.Decode(&contents)
if !reflect.ValueOf(contents).IsZero() {
return b.Delete(context.TODO(), contents.ID)
}
}
return nil
}
if gfsRef != nil {
b := bucket(*gfsRef)
if fv.Kind() == reflect.Slice {
for j := 0; j < fv.Len(); j++ {
lerr := inner(b, fv.Index(j))
if lerr != nil {
return lerr
}
}
} else if fv.Kind() == reflect.Struct {
lerr := inner(b, fv)
if lerr != nil {
return lerr
}
} else {
lerr := inner(b, el)
if lerr != nil {
return lerr
}
}
}
err = gridFsDel(fv.Interface(), imodel)
if err != nil {
return err
}
}
case reflect.Slice:
for i := 0; i < el.Len(); i++ {
rerr = gridFsDel(el.Index(i).Interface(), imodel)
if rerr != nil {
return rerr
}
}
default:
break
}
return rerr
}
func gridFsSave(val any, imodel Model) error { func gridFsSave(val any, imodel Model) error {
var rerr error var rerr error
v := reflect.ValueOf(val) v := reflect.ValueOf(val)