1
use std::collections::HashMap;
2
#[cfg(feature = "encryption")]
3
use std::sync::Arc;
4

            
5
use bonsaidb_core::{
6
    document::KeyId,
7
    schema::{CollectionName, Schematic},
8
};
9
use nebari::{
10
    io::any::AnyFile,
11
    tree::{AnyTreeRoot, Root, Unversioned, Versioned},
12
};
13

            
14
#[cfg(feature = "encryption")]
15
use crate::vault::{TreeVault, Vault};
16
use crate::{
17
    database::document_tree_name,
18
    views::{
19
        view_document_map_tree_name, view_entries_tree_name, view_invalidated_docs_tree_name,
20
        view_omitted_docs_tree_name,
21
    },
22
    Error,
23
};
24

            
25
333712
#[derive(Default)]
26
pub(crate) struct OpenTrees {
27
    pub trees: Vec<Box<dyn AnyTreeRoot<AnyFile>>>,
28
    pub trees_index_by_name: HashMap<String, usize>,
29
}
30

            
31
impl OpenTrees {
32
    #[cfg_attr(not(feature = "encryption"), allow(unused_mut))]
33
    #[cfg_attr(feature = "encryption", allow(clippy::unnecessary_wraps))]
34
1450826
    pub fn open_tree<R: Root>(
35
1450826
        &mut self,
36
1450826
        name: &str,
37
1450826
        encryption_key: Option<&KeyId>,
38
1450826
        #[cfg(feature = "encryption")] vault: &Arc<Vault>,
39
1450826
    ) -> Result<(), Error> {
40
1450826
        if !self.trees_index_by_name.contains_key(name) {
41
1143207
            self.trees_index_by_name
42
1143207
                .insert(name.to_string(), self.trees.len());
43
1143207
            let mut tree = R::tree(name.to_string());
44

            
45
            #[cfg(feature = "encryption")]
46
1143207
            if let Some(encryption_key) = encryption_key {
47
10700
                tree = tree.with_vault(TreeVault {
48
10700
                    key: encryption_key.clone(),
49
10700
                    vault: vault.clone(),
50
10700
                });
51
1132387
            }
52

            
53
            #[cfg(not(feature = "encryption"))]
54
            if encryption_key.is_some() {
55
                return Err(Error::EncryptionDisabled);
56
            }
57

            
58
1143087
            self.trees.push(Box::new(tree));
59
307619
        }
60
1450706
        Ok(())
61
1450706
    }
62

            
63
    pub fn open_trees_for_document_change(
64
        &mut self,
65
        collection: &CollectionName,
66
        schema: &Schematic,
67
        encryption_key: Option<&KeyId>,
68
        #[cfg(feature = "encryption")] vault: &Arc<Vault>,
69
    ) -> Result<(), Error> {
70
475551
        self.open_tree::<Versioned>(
71
475551
            &document_tree_name(collection),
72
475551
            encryption_key,
73
475551
            #[cfg(feature = "encryption")]
74
475551
            vault,
75
475551
        )?;
76

            
77
475551
        if let Some(views) = schema.views_in_collection(collection) {
78
1113753
            for view in views {
79
835243
                let view_name = view.view_name();
80
835243
                if view.unique() {
81
70028
                    self.open_tree::<Unversioned>(
82
70028
                        &view_omitted_docs_tree_name(&view_name),
83
70028
                        encryption_key,
84
70028
                        #[cfg(feature = "encryption")]
85
70028
                        vault,
86
70028
                    )?;
87
70028
                    self.open_tree::<Unversioned>(
88
70028
                        &view_document_map_tree_name(&view_name),
89
70028
                        encryption_key,
90
70028
                        #[cfg(feature = "encryption")]
91
70028
                        vault,
92
70028
                    )?;
93
70028
                    self.open_tree::<Unversioned>(
94
70028
                        &view_entries_tree_name(&view_name),
95
70028
                        encryption_key,
96
70028
                        #[cfg(feature = "encryption")]
97
70028
                        vault,
98
70028
                    )?;
99
                } else {
100
765215
                    self.open_tree::<Unversioned>(
101
765215
                        &view_invalidated_docs_tree_name(&view_name),
102
765215
                        encryption_key,
103
765215
                        #[cfg(feature = "encryption")]
104
765215
                        vault,
105
765215
                    )?;
106
                }
107
            }
108
197041
        }
109

            
110
475551
        Ok(())
111
475551
    }
112
}