mongodb_gridfs/bucket/
delete.rs1use crate::{bucket::GridFSBucket, GridFSError};
2use bson::{doc, oid::ObjectId, Document};
3use mongodb::options::DeleteOptions;
4
5impl GridFSBucket {
6 pub async fn delete(&self, id: ObjectId) -> Result<(), GridFSError> {
50 let dboptions = self.options.clone().unwrap_or_default();
51 let bucket_name = dboptions.bucket_name;
52 let file_collection = bucket_name.clone() + ".files";
53 let files = self.db.collection::<Document>(&file_collection);
54 let chunk_collection = bucket_name + ".chunks";
55 let chunks = self.db.collection::<Document>(&chunk_collection);
56
57 let mut delete_option = DeleteOptions::default();
58 if let Some(write_concern) = dboptions.write_concern.clone() {
59 delete_option.write_concern = Some(write_concern);
60 }
61
62 let delete_result = files
63 .delete_one(doc! {"_id":id}, delete_option.clone())
64 .await?;
65
66 if delete_result.deleted_count == 0 {
69 return Err(GridFSError::FileNotFound());
70 }
71
72 chunks
73 .delete_many(doc! {"files_id":id}, delete_option)
74 .await?;
75 Ok(())
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::GridFSBucket;
82 use crate::{options::GridFSBucketOptions, GridFSError};
83 use bson::doc;
84 use bson::oid::ObjectId;
85 use bson::Document;
86 use mongodb::Client;
87 use mongodb::Database;
88 use uuid::Uuid;
89 fn db_name_new() -> String {
90 "test_".to_owned()
91 + Uuid::new_v4()
92 .hyphenated()
93 .encode_lower(&mut Uuid::encode_buffer())
94 }
95
96 #[tokio::test]
97 async fn delete_a_file() -> Result<(), GridFSError> {
98 let client = Client::with_uri_str(
99 &std::env::var("MONGO_URI").unwrap_or("mongodb://localhost:27017/".to_string()),
100 )
101 .await?;
102 let dbname = db_name_new();
103 let db: Database = client.database(&dbname);
104 let bucket = &GridFSBucket::new(db.clone(), Some(GridFSBucketOptions::default()));
105 let id = bucket
106 .clone()
107 .upload_from_stream("test.txt", "test data".as_bytes(), None)
108 .await?;
109
110 assert_eq!(id.to_hex(), id.to_hex());
111
112 bucket.delete(id).await?;
113
114 let count = db
115 .collection::<Document>("fs.files")
116 .count_documents(doc! { "_id": id }, None)
117 .await?;
118 assert_eq!(count, 0, "File should be deleted");
119
120 let count = db
121 .collection::<Document>("fs.chunks")
122 .count_documents(doc! { "files_id": id }, None)
123 .await?;
124 assert_eq!(count, 0, "Chunks should be deleted");
125
126 db.drop(None).await?;
127 Ok(())
128 }
129
130 #[tokio::test]
131 async fn delete_a_non_existant_file() -> Result<(), GridFSError> {
132 let client = Client::with_uri_str(
133 &std::env::var("MONGO_URI").unwrap_or("mongodb://localhost:27017/".to_string()),
134 )
135 .await?;
136 let dbname = db_name_new();
137 let db: Database = client.database(&dbname);
138 let bucket = &GridFSBucket::new(db.clone(), Some(GridFSBucketOptions::default()));
139 let id = ObjectId::new();
140
141 let result = bucket.delete(id).await;
142 assert!(result.is_err());
143
144 let count = db
145 .collection::<Document>("fs.files")
146 .count_documents(doc! { "_id": id }, None)
147 .await?;
148 assert_eq!(count, 0, "File should be deleted");
149
150 let count = db
151 .collection::<Document>("fs.chunks")
152 .count_documents(doc! { "files_id": id }, None)
153 .await?;
154 assert_eq!(count, 0, "Chunks should be deleted");
155
156 db.drop(None).await?;
157 Ok(())
158 }
159}