1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
//! This crate provides an implementation of Mongo GridFS on the top of mongodb's crate.
//! This implementation only use the _async/await_ version of mongodb.
//!
//! From https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst
//! > 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.
//! # Examples
//! Uploading a document:
//!  ```rust
//!  # use mongodb::Client;
//!  # use mongodb::{error::Error, Database};
//!  use mongodb_gridfs::{options::GridFSBucketOptions, GridFSBucket};
//!  # use uuid::Uuid;
//!  
//!  # fn db_name_new() -> String {
//!  #     "test_".to_owned()
//!  #         + Uuid::new_v4()
//!  #             .to_hyphenated()
//!  #             .encode_lower(&mut Uuid::encode_buffer())
//!  # }
//!  #
//!  # #[tokio::main]
//!  # async fn main() -> Result<(), Error> {
//!  #    let client = Client::with_uri_str(&std::env::var("MONGO_URI").unwrap_or("mongodb://localhost:27017/".to_string())).await?;
//!  #    let dbname = db_name_new();
//!  #    let db: Database = client.database(&dbname);
//!  let bucket = GridFSBucket::new(db.clone(), Some(GridFSBucketOptions::default()));
//!  let id = bucket
//!      .upload_from_stream("test.txt", "stream your data here".as_bytes(), None)
//!      .await?;
//!  #     println!("{}", id);
//!  #     db.drop(None).await
//!  # }
//!  ```
//!  Downloading a document:
//!  ```rust
//! use futures::stream::StreamExt;
//! # use mongodb::Client;
//! # use mongodb::Database;
//! use mongodb_gridfs::{options::GridFSBucketOptions, GridFSBucket, GridFSError};
//! # use uuid::Uuid;
//!
//! # fn db_name_new() -> String {
//! #     "test_".to_owned()
//! #         + Uuid::new_v4()
//! #             .to_hyphenated()
//! #             .encode_lower(&mut Uuid::encode_buffer())
//! # }
//! #
//! # #[tokio::main]
//! # async fn main() -> Result<(), GridFSError> {
//! #     let client = Client::with_uri_str(
//! #         &std::env::var("MONGO_URI").unwrap_or("mongodb://localhost:27017/".to_string()),
//! #     )
//! #     .await?;
//! #     let dbname = db_name_new();
//! #     let db: Database = client.database(&dbname);
//! let bucket = GridFSBucket::new(db.clone(), Some(GridFSBucketOptions::default()));
//! #     let id = bucket
//! #         .clone()
//! #         .upload_from_stream("test.txt", "test data".as_bytes(), None)
//! #         .await?;
//! #     println!("{}", id);
//! #
//! let mut cursor = bucket.open_download_stream(id).await?;
//! let buffer = cursor.next().await.unwrap();
//! #     println!("{:?}", buffer);
//! #
//! #     db.drop(None).await?;
//! #     Ok(())
//! # }
//!  ```
//! # Features
//! | Feature                                     | Status  | Notes                                           |
//! | ------------------------------------------- | ------- | ----------------------------------------------- |
//! | GridFSUploadOptions                         | DONE    | `contentType` and `aliases` are not implemented |
//! | GridFSBucketOption                          | DONE    | concerns not used when ensuring indexes         |
//! | GridFSFindOptions                           | DONE    |                                                 |
//! | GridFSDownloadByNameOptions                 | TODO    |                                                 |
//! | GridFSBucket                                | DONE    |                                                 |
//! | GridFSBucket . open_upload_stream           | DONE    |                                                 |
//! | GridFSBucket . open_upload_stream_with_id   |         |                                                 |
//! | GridFSBucket . upload_from_stream           | NO      | No Implementation planned                         |
//! | GridFSBucket . upload_from_stream_with_id   | NO      | No Implementation planned                         |
//! | GridFSBucket . open_download_stream         | DONE    |                                                 |
//! | GridFSBucket . download_to_stream           | NO      | No Implementation planned                         |
//! | GridFSBucket . delete                       | DONE    |                                                 |
//! | GridFSBucket . find                         | DONE    |                                                 |
//! | GridFSBucket . rename                       | DONE    |                                                 |
//! | GridFSBucket . drop                         | DONE    |                                                 |
//! | GridFSBucket . open_download_stream_by_name |         |                                                 |
//! | GridFSBucket . download_to_stream_by_name   |         |                                                 |
//! | indexes                                     | DONE   |                                                 |

pub mod bucket;
pub mod options;
pub use bucket::GridFSBucket;

#[derive(Debug)]
pub enum GridFSError {
    MongoError(mongodb::error::Error),
    FileNotFound(),
}

impl From<mongodb::error::Error> for GridFSError {
    fn from(err: mongodb::error::Error) -> GridFSError {
        GridFSError::MongoError(err)
    }
}