implement recursive deletion for gridfs files when Delete()
is called on a document
This commit is contained in:
parent
ad7c7f38af
commit
322d97dc95
@ -180,6 +180,7 @@ func doDelete(d *Document, arg interface{}) error {
|
||||
_, err := c.DeleteOne(context.TODO(), bson.M{"_id": self.Id()})
|
||||
if err == nil {
|
||||
d.exists = false
|
||||
err = gridFsDel(arg, *d.model)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
76
gridfs.go
76
gridfs.go
@ -105,6 +105,82 @@ func gridFsLoad(val any, g gridFSReference, field string) any {
|
||||
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 {
|
||||
var rerr error
|
||||
v := reflect.ValueOf(val)
|
||||
|
Loading…
x
Reference in New Issue
Block a user