diff --git a/document_internals.go b/document_internals.go index 7dccc2d..1b3dfa9 100644 --- a/document_internals.go +++ b/document_internals.go @@ -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 } diff --git a/gridfs.go b/gridfs.go index 73c16f4..93f2d65 100644 --- a/gridfs.go +++ b/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)