Skip to main content

noxu_db/
cursor_config.rs

1//! Cursor configuration.
2//!
3
4/// Configuration for opening a cursor.
5///
6/// Specifies the configuration parameters used to open a cursor on a database.
7///
8/// # Changes in v1.5.1
9///
10/// Four fields that used to live on this struct (`read_committed`,
11/// `non_sticky`, `evict_ln`, `prefix_constraint`) were removed because
12/// the engine never consulted them.  See
13/// the 2026 review for the full rationale
14/// and migration notes.
15///
16/// * `read_committed` — to use read-committed isolation, set it on the
17///   surrounding [`crate::transaction_config::TransactionConfig`] (it
18///   is honoured by [`crate::cursor::Cursor`] via the txn's locker)
19///   or pass [`crate::lock_mode::LockMode::ReadCommitted`] to a
20///   per-operation [`crate::read_options::ReadOptions`].
21/// * `non_sticky` — Rust cursors are bound to their owning scope and
22///   are not sticky to a transaction in the JE sense; the flag had
23///   no observable effect.
24/// * `evict_ln` — use [`crate::cache_mode::CacheMode::Unchanged`] /
25///   `EvictLn` on the surrounding `DatabaseConfig` instead.
26/// * `prefix_constraint` — application code should compare the
27///   returned key against its own prefix and stop iterating; the
28///   engine's BIN-level prefix is independent of the user's
29///   range-scan termination condition.
30#[derive(Debug, Clone, PartialEq, Eq, Default)]
31#[must_use]
32pub struct CursorConfig {
33    /// Use read-uncommitted isolation (dirty reads).
34    ///
35    /// When `true`, the cursor is opened in read-only mode and skips
36    /// read-lock acquisition.  This mirrors JE's
37    /// `CursorConfig.setReadUncommitted(true)` shape and is the only
38    /// isolation override consulted at cursor-open time.  Per-operation
39    /// `LockMode` overrides (passed via
40    /// [`crate::read_options::ReadOptions`]) take precedence at the
41    /// individual `get` call.
42    pub read_uncommitted: bool,
43}
44
45impl CursorConfig {
46    /// Creates a new CursorConfig with default settings.
47    pub fn new() -> Self {
48        Self::default()
49    }
50
51    /// Sets read-uncommitted isolation.
52    pub fn set_read_uncommitted(
53        &mut self,
54        read_uncommitted: bool,
55    ) -> &mut Self {
56        self.read_uncommitted = read_uncommitted;
57        self
58    }
59
60    /// Builder-style method to set read_uncommitted.
61    pub fn with_read_uncommitted(mut self, read_uncommitted: bool) -> Self {
62        self.read_uncommitted = read_uncommitted;
63        self
64    }
65
66    /// Creates a CursorConfig for read-uncommitted isolation.
67    pub fn read_uncommitted() -> Self {
68        Self::new().with_read_uncommitted(true)
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75
76    #[test]
77    fn test_new_defaults_to_no_read_uncommitted() {
78        let config = CursorConfig::new();
79        assert!(!config.read_uncommitted);
80    }
81
82    #[test]
83    fn test_set_read_uncommitted() {
84        let mut config = CursorConfig::new();
85        config.set_read_uncommitted(true);
86        assert!(config.read_uncommitted);
87    }
88
89    #[test]
90    fn test_with_read_uncommitted() {
91        let config = CursorConfig::new().with_read_uncommitted(true);
92        assert!(config.read_uncommitted);
93    }
94
95    #[test]
96    fn test_read_uncommitted_factory() {
97        let config = CursorConfig::read_uncommitted();
98        assert!(config.read_uncommitted);
99    }
100
101    #[test]
102    fn test_default() {
103        let config = CursorConfig::default();
104        assert!(!config.read_uncommitted);
105    }
106
107    #[test]
108    fn test_clone_eq() {
109        let a = CursorConfig::read_uncommitted();
110        let b = a.clone();
111        assert_eq!(a, b);
112
113        let c = CursorConfig::new();
114        assert_ne!(a, c);
115    }
116
117    #[test]
118    fn test_debug_format_mentions_field() {
119        let config = CursorConfig::read_uncommitted();
120        let debug = format!("{:?}", config);
121        assert!(debug.contains("read_uncommitted"));
122    }
123}