mongodb_gridfs/lib.rs
1//! This crate provides an implementation of Mongo GridFS on the top of mongodb's crate.
2//! This implementation only use the _async/await_ version of mongodb.
3//!
4//! From <https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst>
5//! > GridFS is a convention drivers use to store and retrieve BSON binary data (type “\x05”) that exceeds MongoDB’s BSON-document size limit of 16 MiB. When this data, called a user file, is written to the system, GridFS divides the file into chunks that are stored as distinct documents in a chunks collection. To retrieve a stored file, GridFS locates and returns all of its component chunks. Internally, GridFS creates a files collection document for each stored file. Files collection documents hold information about stored files, and they are stored in a files collection.
6//! # Examples
7//! Uploading a document:
8//! ```rust
9//! # use mongodb::Client;
10//! # use mongodb::{error::Error, Database};
11//! use mongodb_gridfs::{options::GridFSBucketOptions, GridFSBucket};
12//! # use uuid::Uuid;
13//!
14//! # fn db_name_new() -> String {
15//! # "test_".to_owned()
16//! # + Uuid::new_v4()
17//! # .hyphenated()
18//! # .encode_lower(&mut Uuid::encode_buffer())
19//! # }
20//! #
21//! # #[tokio::main]
22//! # async fn main() -> Result<(), Error> {
23//! # let client = Client::with_uri_str(&std::env::var("MONGO_URI").unwrap_or("mongodb://localhost:27017/".to_string())).await?;
24//! # let dbname = db_name_new();
25//! # let db: Database = client.database(&dbname);
26//! let mut bucket = GridFSBucket::new(db.clone(), Some(GridFSBucketOptions::default()));
27//! let id = bucket
28//! .upload_from_stream("test.txt", "stream your data here".as_bytes(), None)
29//! .await?;
30//! # println!("{}", id);
31//! # db.drop(None).await
32//! # }
33//! ```
34//! Downloading a document:
35//! ```rust
36//! # #[cfg(feature = "async-std-runtime")]
37//! # use futures::stream::StreamExt;
38//! # #[cfg(any(feature = "default", feature = "tokio-runtime"))]
39//! use tokio_stream::StreamExt;
40//! # use mongodb::Client;
41//! # use mongodb::Database;
42//! use mongodb_gridfs::{options::GridFSBucketOptions, GridFSBucket, GridFSError};
43//! # use uuid::Uuid;
44//!
45//! # fn db_name_new() -> String {
46//! # "test_".to_owned()
47//! # + Uuid::new_v4()
48//! # .hyphenated()
49//! # .encode_lower(&mut Uuid::encode_buffer())
50//! # }
51//! #
52//! # #[tokio::main]
53//! # async fn main() -> Result<(), GridFSError> {
54//! # let client = Client::with_uri_str(
55//! # &std::env::var("MONGO_URI").unwrap_or("mongodb://localhost:27017/".to_string()),
56//! # )
57//! # .await?;
58//! # let dbname = db_name_new();
59//! # let db: Database = client.database(&dbname);
60//! let bucket = GridFSBucket::new(db.clone(), Some(GridFSBucketOptions::default()));
61//! # let id = bucket
62//! # .clone()
63//! # .upload_from_stream("test.txt", "test data".as_bytes(), None)
64//! # .await?;
65//! # println!("{}", id);
66//! #
67//! let mut cursor = bucket.open_download_stream(id).await?;
68//! let buffer = cursor.next().await.unwrap();
69//! # println!("{:?}", buffer);
70//! #
71//! # db.drop(None).await?;
72//! # Ok(())
73//! # }
74//! ```
75//! # Features
76//! The following features are propagated to mongodb:
77//! - default
78//! - async-std-runtime
79//! - tokio-runtime
80//! # Code Status
81//! | Feature | Status | Notes |
82//! | ------------------------------------------- | ------- | ----------------------------------------------- |
83//! | GridFSUploadOptions | DONE | `contentType` and `aliases` are not implemented |
84//! | GridFSBucketOption | DONE | concerns not used when ensuring indexes |
85//! | GridFSFindOptions | DONE | |
86//! | GridFSDownloadByNameOptions | TODO | |
87//! | GridFSBucket | DONE | |
88//! | GridFSBucket . open_upload_stream | DONE | |
89//! | GridFSBucket . open_upload_stream_with_id | | |
90//! | GridFSBucket . upload_from_stream | NO | No Implementation planned |
91//! | GridFSBucket . upload_from_stream_with_id | NO | No Implementation planned |
92//! | GridFSBucket . open_download_stream | DONE | |
93//! | GridFSBucket . download_to_stream | NO | No Implementation planned |
94//! | GridFSBucket . delete | DONE | |
95//! | GridFSBucket . find | DONE | |
96//! | GridFSBucket . rename | DONE | |
97//! | GridFSBucket . drop | DONE | |
98//! | GridFSBucket . open_download_stream_by_name | | |
99//! | GridFSBucket . download_to_stream_by_name | | |
100//! | indexes | DONE | |
101
102pub mod bucket;
103pub mod options;
104use std::{
105 error::Error,
106 fmt::{Display, Formatter, Result},
107};
108
109pub use bucket::GridFSBucket;
110
111#[derive(Debug)]
112pub enum GridFSError {
113 MongoError(mongodb::error::Error),
114 FileNotFound(),
115}
116
117impl From<mongodb::error::Error> for GridFSError {
118 fn from(err: mongodb::error::Error) -> GridFSError {
119 GridFSError::MongoError(err)
120 }
121}
122
123impl Error for GridFSError {
124 fn source(&self) -> Option<&(dyn Error + 'static)> {
125 match self {
126 GridFSError::MongoError(e) => Some(e),
127 GridFSError::FileNotFound() => None,
128 }
129 }
130
131 // fn backtrace(&self) -> Option<&std::backtrace::Backtrace> {
132 // None
133 // }
134
135 fn description(&self) -> &str {
136 "description() is deprecated; use Display"
137 }
138
139 fn cause(&self) -> Option<&dyn Error> {
140 self.source()
141 }
142}
143
144impl Display for GridFSError {
145 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
146 match self {
147 GridFSError::MongoError(me) => write!(f, "{}", me),
148 GridFSError::FileNotFound() => write!(f, "File not found"),
149 }
150 }
151}