Skip to main content

mongodb/sync/
db.rs

1use std::fmt::Debug;
2
3use super::{gridfs::GridFsBucket, Collection};
4use crate::{
5    options::{
6        CollectionOptions,
7        GridFsBucketOptions,
8        ReadConcern,
9        SelectionCriteria,
10        WriteConcern,
11    },
12    Database as AsyncDatabase,
13};
14
15/// `Database` is the client-side abstraction of a MongoDB database. It can be used to perform
16/// database-level operations or to obtain handles to specific collections within the database. A
17/// `Database` can only be obtained through a [`Client`](struct.Client.html) by calling either
18/// [`Client::database`](struct.Client.html#method.database) or
19/// [`Client::database_with_options`](struct.Client.html#method.database_with_options).
20///
21/// `Database` uses [`std::sync::Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html) internally,
22/// so it can safely be shared across threads. For example:
23///
24/// ```rust
25/// # use mongodb::{bson::Document, sync::Client, error::Result};
26///
27/// # fn start_workers() -> Result<()> {
28/// # let client = Client::with_uri_str("mongodb://example.com")?;
29/// let db = client.database("items");
30///
31/// for i in 0..5 {
32///     let db_ref = db.clone();
33///
34///     std::thread::spawn(move || {
35///         let collection = db_ref.collection::<Document>(&format!("coll{}", i));
36///
37///         // Do something with the collection
38///     });
39/// }
40/// #
41/// # // Technically we should join the threads here, but for the purpose of the example, we'll just
42/// # // sleep for a bit.
43/// # std::thread::sleep(std::time::Duration::from_secs(3));
44/// # Ok(())
45/// # }
46/// ```
47#[derive(Debug, Clone)]
48pub struct Database {
49    pub(crate) async_database: AsyncDatabase,
50}
51
52impl Database {
53    pub(crate) fn new(async_database: AsyncDatabase) -> Self {
54        Self { async_database }
55    }
56
57    /// Gets the name of the `Database`.
58    pub fn name(&self) -> &str {
59        self.async_database.name()
60    }
61
62    /// Gets the read preference of the `Database`.
63    pub fn selection_criteria(&self) -> Option<&SelectionCriteria> {
64        self.async_database.selection_criteria()
65    }
66
67    /// Gets the read concern of the `Database`.
68    pub fn read_concern(&self) -> Option<&ReadConcern> {
69        self.async_database.read_concern()
70    }
71
72    /// Gets the write concern of the `Database`.
73    pub fn write_concern(&self) -> Option<&WriteConcern> {
74        self.async_database.write_concern()
75    }
76
77    /// Gets a handle to a collection with type `T` specified by `name` of the database. The
78    /// `Collection` options (e.g. read preference and write concern) will default to those of the
79    /// `Database`.
80    ///
81    /// This method does not send or receive anything across the wire to the database, so it can be
82    /// used repeatedly without incurring any costs from I/O.
83    pub fn collection<T: Send + Sync>(&self, name: &str) -> Collection<T> {
84        Collection::new(self.async_database.collection(name))
85    }
86
87    /// Gets a handle to a collection with type `T` specified by `name` in the cluster the `Client`
88    /// is connected to. Operations done with this `Collection` will use the options specified by
89    /// `options` by default and will otherwise default to those of the `Database`.
90    ///
91    /// This method does not send or receive anything across the wire to the database, so it can be
92    /// used repeatedly without incurring any costs from I/O.
93    pub fn collection_with_options<T: Send + Sync>(
94        &self,
95        name: &str,
96        options: CollectionOptions,
97    ) -> Collection<T> {
98        Collection::new(self.async_database.collection_with_options(name, options))
99    }
100
101    /// Creates a new [`GridFsBucket`] in the database with the given options.
102    pub fn gridfs_bucket(&self, options: impl Into<Option<GridFsBucketOptions>>) -> GridFsBucket {
103        GridFsBucket::new(self.async_database.gridfs_bucket(options))
104    }
105}