Skip to main content

mongodb/coll/action/
drop.rs

1use crate::{
2    action::{action_impl, DropCollection},
3    error::Result,
4    operation::drop_collection as op,
5};
6
7#[action_impl]
8impl<'a> Action for DropCollection<'a> {
9    type Future = DropCollectionFuture;
10
11    async fn execute(mut self) -> Result<()> {
12        #[cfg(feature = "in-use-encryption")]
13        self.cr
14            .drop_aux_collections(self.options.as_ref(), self.session.as_deref_mut())
15            .await?;
16
17        let drop = op::DropCollection::new(self.cr.clone(), self.options);
18        self.cr
19            .client()
20            .execute_operation(drop, self.session.as_deref_mut())
21            .await
22    }
23}
24
25#[cfg(feature = "in-use-encryption")]
26impl<T> crate::Collection<T>
27where
28    T: Send + Sync,
29{
30    #[allow(clippy::needless_option_as_deref)]
31    async fn drop_aux_collections(
32        &self,
33        options: Option<&crate::coll::DropCollectionOptions>,
34        mut session: Option<&mut crate::ClientSession>,
35    ) -> Result<()> {
36        use crate::bson::doc;
37        use futures_util::TryStreamExt;
38
39        // Find associated `encrypted_fields`:
40        // * from options to this call
41        let mut enc_fields = options.and_then(|o| o.encrypted_fields.as_ref());
42        let enc_opts = self.client().auto_encryption_opts().await;
43        // * from client-wide `encrypted_fields_map`:
44        let client_enc_fields = enc_opts
45            .as_ref()
46            .and_then(|eo| eo.encrypted_fields_map.as_ref());
47        if enc_fields.is_none() {
48            enc_fields =
49                client_enc_fields.and_then(|efm| efm.get(&format!("{}", self.namespace())));
50        }
51        // * from a `list_collections` call:
52        let found;
53        if enc_fields.is_none() && enc_opts.is_some() {
54            let filter = doc! { "name": self.name() };
55            let mut specs: Vec<_> = match session.as_deref_mut() {
56                Some(s) => {
57                    let mut cursor = self
58                        .inner
59                        .db
60                        .list_collections()
61                        .filter(filter)
62                        .session(&mut *s)
63                        .await?;
64                    cursor.stream(s).try_collect().await?
65                }
66                None => {
67                    self.inner
68                        .db
69                        .list_collections()
70                        .filter(filter)
71                        .await?
72                        .try_collect()
73                        .await?
74                }
75            };
76            if let Some(spec) = specs.pop() {
77                if let Some(enc) = spec.options.encrypted_fields {
78                    found = enc;
79                    enc_fields = Some(&found);
80                }
81            }
82        }
83
84        // Drop the collections.
85        if let Some(enc_fields) = enc_fields {
86            for ns in crate::client::csfle::aux_collections(&self.namespace(), enc_fields)? {
87                let coll = self.client().database(&ns.db).collection(&ns.coll);
88                let drop = op::DropCollection::new(coll, options.cloned());
89                self.client()
90                    .execute_operation(drop, session.as_deref_mut())
91                    .await?;
92            }
93        }
94        Ok(())
95    }
96}