mongodb_gridfs/bucket/
find.rs1use crate::{bucket::GridFSBucket, options::GridFSFindOptions};
2use bson::Document;
3use mongodb::error::Result;
4use mongodb::options::FindOptions;
5use mongodb::Cursor;
6
7impl GridFSBucket {
8 pub async fn find(
46 &self,
47 filter: Document,
48 options: GridFSFindOptions,
49 ) -> Result<Cursor<Document>> {
50 let dboptions = self.options.clone().unwrap_or_default();
51 let bucket_name = dboptions.bucket_name;
52 let file_collection = bucket_name + ".files";
53 let files = self.db.collection::<Document>(&file_collection);
54
55 let find_options = FindOptions::builder()
56 .allow_disk_use(options.allow_disk_use)
57 .limit(options.limit)
58 .max_time(options.max_time)
59 .no_cursor_timeout(options.no_cursor_timeout)
60 .skip(options.skip)
61 .sort(options.sort)
62 .read_concern(dboptions.read_concern)
63 .build();
64
65 files.find(filter, find_options).await
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::GridFSBucket;
72 use crate::{
73 options::{GridFSBucketOptions, GridFSFindOptions},
74 GridFSError,
75 };
76 use bson::doc;
77 #[cfg(feature = "async-std-runtime")]
78 use futures::stream::StreamExt;
79 use mongodb::{Client, Database};
80 #[cfg(any(feature = "default", feature = "tokio-runtime"))]
81 use tokio_stream::StreamExt;
82 use uuid::Uuid;
83
84 fn db_name_new() -> String {
85 "test_".to_owned()
86 + Uuid::new_v4()
87 .hyphenated()
88 .encode_lower(&mut Uuid::encode_buffer())
89 }
90
91 #[tokio::test]
92 async fn find_a_file() -> Result<(), GridFSError> {
93 let client = Client::with_uri_str(
94 &std::env::var("MONGO_URI").unwrap_or("mongodb://localhost:27017/".to_string()),
95 )
96 .await?;
97 let dbname = db_name_new();
98 let db: Database = client.database(&dbname);
99 let bucket = &GridFSBucket::new(db.clone(), Some(GridFSBucketOptions::default()));
100 let id = bucket
101 .clone()
102 .upload_from_stream("test.txt", "test data".as_bytes(), None)
103 .await?;
104
105 assert_eq!(id.to_hex(), id.to_hex());
106
107 let mut cursor = bucket
108 .find(doc! {"filename":"test.txt"}, GridFSFindOptions::default())
109 .await?;
110
111 while let Some(doc) = cursor.next().await {
112 let doc = doc.unwrap();
113 assert_eq!(doc.get_str("filename").unwrap(), "test.txt");
114 assert_eq!(doc.get_i32("chunkSize").unwrap(), 261120);
115 assert_eq!(doc.get_i64("length").unwrap(), 9);
116 assert_eq!(
117 doc.get_str("md5").unwrap(),
118 "eb733a00c0c9d336e65691a37ab54293"
119 );
120 }
121 db.drop(None).await?;
122 Ok(())
123 }
124
125 #[tokio::test]
126 async fn find_a_non_existing_file() -> Result<(), GridFSError> {
127 let client = Client::with_uri_str(
128 &std::env::var("MONGO_URI").unwrap_or("mongodb://localhost:27017/".to_string()),
129 )
130 .await?;
131 let dbname = db_name_new();
132 let db: Database = client.database(&dbname);
133 let bucket = &GridFSBucket::new(db.clone(), Some(GridFSBucketOptions::default()));
134 let id = bucket
135 .clone()
136 .upload_from_stream("test.txt", "test data".as_bytes(), None)
137 .await?;
138
139 assert_eq!(id.to_hex(), id.to_hex());
140
141 let mut cursor = bucket
142 .find(doc! {"filename":"null.txt"}, GridFSFindOptions::default())
143 .await?;
144
145 match cursor.next().await {
146 None => assert!(true),
147 Some(_) => assert!(false),
148 }
149
150 db.drop(None).await?;
151 Ok(())
152 }
153}