use crate::bson::{doc, Bson};
#[cfg(docsrs)]
use crate::gridfs::FilesCollectionDocument;
use crate::{
action::action_impl,
error::{ErrorKind, GridFsErrorKind, GridFsFileIdentifier, Result},
gridfs::GridFsBucket,
};
impl GridFsBucket {
pub fn delete(&self, id: Bson) -> Delete {
Delete { bucket: self, id }
}
pub fn delete_by_name(&self, filename: impl Into<String>) -> DeleteByName {
DeleteByName {
bucket: self,
filename: filename.into(),
}
}
}
#[cfg(feature = "sync")]
impl crate::sync::gridfs::GridFsBucket {
pub fn delete(&self, id: Bson) -> Delete {
self.async_bucket.delete(id)
}
pub fn delete_by_name(&self, filename: impl Into<String>) -> DeleteByName {
self.async_bucket.delete_by_name(filename)
}
}
#[must_use]
pub struct Delete<'a> {
bucket: &'a GridFsBucket,
id: Bson,
}
#[action_impl]
impl<'a> Action for Delete<'a> {
type Future = DeleteFuture;
async fn execute(self) -> Result<()> {
let delete_result = self
.bucket
.files()
.delete_one(doc! { "_id": self.id.clone() })
.await?;
self.bucket
.chunks()
.delete_many(doc! { "files_id": self.id.clone() })
.await?;
if delete_result.deleted_count == 0 {
return Err(ErrorKind::GridFs(GridFsErrorKind::FileNotFound {
identifier: GridFsFileIdentifier::Id(self.id),
})
.into());
}
Ok(())
}
}
#[must_use]
pub struct DeleteByName<'a> {
bucket: &'a GridFsBucket,
filename: String,
}
#[action_impl]
impl<'a> Action for DeleteByName<'a> {
type Future = DeleteByNameFuture;
async fn execute(self) -> Result<()> {
use futures_util::stream::{StreamExt, TryStreamExt};
let ids: Vec<_> = self
.bucket
.files()
.find(doc! { "filename": self.filename.clone() })
.projection(doc! { "_id": 1 })
.await?
.with_type::<crate::bson::Document>()
.map(|r| match r {
Ok(mut d) => d
.remove("_id")
.ok_or_else(|| crate::error::Error::internal("_id field expected")),
Err(e) => Err(e),
})
.try_collect()
.await?;
let count = self
.bucket
.files()
.delete_many(doc! { "_id": { "$in": ids.clone() } })
.await?
.deleted_count;
self.bucket
.chunks()
.delete_many(doc! { "files_id": { "$in": ids } })
.await?;
if count == 0 {
return Err(ErrorKind::GridFs(GridFsErrorKind::FileNotFound {
identifier: GridFsFileIdentifier::Filename(self.filename),
})
.into());
}
Ok(())
}
}