Skip to main content

noxu_dbi/
database_config.rs

1//! Database configuration.
2//!
3
4use std::sync::Arc;
5
6use noxu_tree::KeyComparatorFn;
7
8use crate::trigger::Trigger;
9
10/// A persisted-identity + comparison-function pair threaded from the public
11/// `noxu_db::Comparator` down to `DatabaseImpl`.
12///
13/// The `identity` is the stable string persisted in the database record (the
14/// NameLN data) and re-checked at open; the `func` is the actual comparison
15/// closure threaded into the `Tree`.  JE `DatabaseImpl.btreeComparator` plus
16/// the persisted `btreeComparatorBytes` (the serialized class name).
17#[derive(Clone)]
18pub struct ConfigComparator {
19    /// Stable identity persisted in the database record.
20    pub identity: String,
21    /// The comparison closure threaded into the tree.
22    pub func: KeyComparatorFn,
23}
24
25impl std::fmt::Debug for ConfigComparator {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        f.debug_struct("ConfigComparator")
28            .field("identity", &self.identity)
29            .finish()
30    }
31}
32
33/// Configuration for a database.
34///
35///
36#[derive(Clone)]
37pub struct DatabaseConfig {
38    /// Allow database creation if it doesn't exist.
39    pub allow_create: bool,
40    /// Enable sorted duplicates.
41    pub sorted_duplicates: bool,
42    /// Enable key prefixing compression.
43    pub key_prefixing: bool,
44    /// Database is temporary (not persisted).
45    pub temporary: bool,
46    /// Database operations are transactional.
47    pub transactional: bool,
48    /// Database is read-only.
49    pub read_only: bool,
50    /// Maximum entries per node.
51    pub node_max_entries: i32,
52    /// Deferred write: skip WAL logging; flush only at eviction/checkpoint.
53    ///
54    ///
55    pub deferred_write: bool,
56    /// User-supplied B-tree key comparator (DBI-14).
57    ///
58    /// JE `DatabaseImpl.btreeComparator`.  `None` = unsigned-byte order.
59    pub btree_comparator: Option<ConfigComparator>,
60    /// User-supplied duplicate-data comparator (DBI-14).
61    ///
62    /// JE `DatabaseImpl.duplicateComparator`.
63    pub duplicate_comparator: Option<ConfigComparator>,
64    /// JE `DatabaseConfig.overrideBtreeComparator`: replace a persisted
65    /// comparator instead of rejecting a mismatch.
66    pub override_btree_comparator: bool,
67    /// JE `DatabaseConfig.overrideDuplicateComparator`.
68    pub override_duplicate_comparator: bool,
69    /// User-supplied database / transaction triggers, fired in registration
70    /// order (DB-TRIG).
71    ///
72    /// JE `DatabaseConfig.setTriggers` / `getTriggers` (a `List<Trigger>`).
73    /// Runtime-registered only: not persisted, not replicated — see
74    /// [`crate::trigger`].
75    pub triggers: Vec<Arc<dyn Trigger>>,
76}
77
78impl std::fmt::Debug for DatabaseConfig {
79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80        f.debug_struct("DatabaseConfig")
81            .field("allow_create", &self.allow_create)
82            .field("sorted_duplicates", &self.sorted_duplicates)
83            .field("key_prefixing", &self.key_prefixing)
84            .field("temporary", &self.temporary)
85            .field("transactional", &self.transactional)
86            .field("read_only", &self.read_only)
87            .field("node_max_entries", &self.node_max_entries)
88            .field("deferred_write", &self.deferred_write)
89            .field("btree_comparator", &self.btree_comparator)
90            .field("duplicate_comparator", &self.duplicate_comparator)
91            .field("override_btree_comparator", &self.override_btree_comparator)
92            .field(
93                "override_duplicate_comparator",
94                &self.override_duplicate_comparator,
95            )
96            .field("triggers", &self.triggers.len())
97            .finish()
98    }
99}
100
101impl Default for DatabaseConfig {
102    fn default() -> Self {
103        DatabaseConfig {
104            allow_create: false,
105            sorted_duplicates: false,
106            key_prefixing: false,
107            temporary: false,
108            transactional: false,
109            read_only: false,
110            node_max_entries: 128,
111            deferred_write: false,
112            btree_comparator: None,
113            duplicate_comparator: None,
114            override_btree_comparator: false,
115            override_duplicate_comparator: false,
116            triggers: Vec::new(),
117        }
118    }
119}
120
121impl DatabaseConfig {
122    /// Creates a new DatabaseConfig with default values.
123    pub fn new() -> Self {
124        Self::default()
125    }
126
127    /// Sets the allow_create flag.
128    pub fn set_allow_create(&mut self, allow_create: bool) -> &mut Self {
129        self.allow_create = allow_create;
130        self
131    }
132
133    /// Sets the sorted_duplicates flag.
134    pub fn set_sorted_duplicates(
135        &mut self,
136        sorted_duplicates: bool,
137    ) -> &mut Self {
138        self.sorted_duplicates = sorted_duplicates;
139        self
140    }
141
142    /// Sets the key_prefixing flag.
143    pub fn set_key_prefixing(&mut self, key_prefixing: bool) -> &mut Self {
144        self.key_prefixing = key_prefixing;
145        self
146    }
147
148    /// Sets the temporary flag.
149    pub fn set_temporary(&mut self, temporary: bool) -> &mut Self {
150        self.temporary = temporary;
151        self
152    }
153
154    /// Sets the transactional flag.
155    pub fn set_transactional(&mut self, transactional: bool) -> &mut Self {
156        self.transactional = transactional;
157        self
158    }
159
160    /// Sets the read_only flag.
161    pub fn set_read_only(&mut self, read_only: bool) -> &mut Self {
162        self.read_only = read_only;
163        self
164    }
165
166    /// Sets the maximum entries per node.
167    pub fn set_node_max_entries(&mut self, max: i32) -> &mut Self {
168        self.node_max_entries = max;
169        self
170    }
171
172    /// Appends a trigger to the registration list (DB-TRIG).
173    ///
174    /// Triggers fire in the order they are added.  JE
175    /// `DatabaseConfig.setTriggers` (Noxu allows incremental registration).
176    pub fn add_trigger(&mut self, trigger: Arc<dyn Trigger>) -> &mut Self {
177        self.triggers.push(trigger);
178        self
179    }
180}
181
182#[cfg(test)]
183mod tests {
184    use super::*;
185
186    #[test]
187    fn test_default() {
188        let config = DatabaseConfig::default();
189        assert!(!config.allow_create);
190        assert!(!config.sorted_duplicates);
191        assert!(!config.key_prefixing);
192        assert!(!config.temporary);
193        assert!(!config.transactional);
194        assert!(!config.read_only);
195        assert_eq!(config.node_max_entries, 128);
196    }
197
198    #[test]
199    fn test_new() {
200        let config = DatabaseConfig::new();
201        assert!(!config.allow_create);
202    }
203
204    #[test]
205    fn test_setters() {
206        let mut config = DatabaseConfig::new();
207
208        config.set_allow_create(true);
209        assert!(config.allow_create);
210
211        config.set_sorted_duplicates(true);
212        assert!(config.sorted_duplicates);
213
214        config.set_key_prefixing(true);
215        assert!(config.key_prefixing);
216
217        config.set_temporary(true);
218        assert!(config.temporary);
219
220        config.set_transactional(true);
221        assert!(config.transactional);
222
223        config.set_read_only(true);
224        assert!(config.read_only);
225
226        config.set_node_max_entries(256);
227        assert_eq!(config.node_max_entries, 256);
228    }
229
230    #[test]
231    fn test_builder_pattern() {
232        let config = DatabaseConfig::new()
233            .set_allow_create(true)
234            .set_transactional(true)
235            .set_node_max_entries(512)
236            .clone();
237
238        assert!(config.allow_create);
239        assert!(config.transactional);
240        assert_eq!(config.node_max_entries, 512);
241    }
242}