Skip to main content

reth_db_api/
mock.rs

1//! Mock database implementation for testing and development.
2//!
3//! Provides lightweight mock implementations of database traits. All operations
4//! are no-ops that return default values without persisting data.
5
6use crate::{
7    common::{IterPairResult, PairResult, ValueOnlyResult},
8    cursor::{
9        DbCursorRO, DbCursorRW, DbDupCursorRO, DbDupCursorRW, DupWalker, RangeWalker,
10        ReverseWalker, Walker,
11    },
12    database::Database,
13    database_metrics::DatabaseMetrics,
14    table::{DupSort, Encode, Table, TableImporter},
15    transaction::{DbTx, DbTxMut},
16    DatabaseError,
17};
18use core::ops::Bound;
19use std::{collections::BTreeMap, ops::RangeBounds, path::PathBuf};
20
21/// Mock database implementation for testing and development.
22///
23/// Provides a lightweight implementation of the [`Database`] trait suitable
24/// for testing scenarios where actual database operations are not required.
25#[derive(Clone, Debug, Default)]
26pub struct DatabaseMock {
27    /// Internal data storage using a `BTreeMap`.
28    ///
29    /// TODO: Make the mock database table-aware by properly utilizing
30    /// this data structure to simulate realistic database behavior during testing.
31    pub data: BTreeMap<Vec<u8>, Vec<u8>>,
32}
33
34impl Database for DatabaseMock {
35    type TX = TxMock;
36    type TXMut = TxMock;
37
38    /// Creates a new read-only transaction.
39    ///
40    /// This always succeeds and returns a default [`TxMock`] instance.
41    /// The mock transaction doesn't actually perform any database operations.
42    fn tx(&self) -> Result<Self::TX, DatabaseError> {
43        Ok(TxMock::default())
44    }
45
46    /// Creates a new read-write transaction.
47    ///
48    /// This always succeeds and returns a default [`TxMock`] instance.
49    /// The mock transaction doesn't actually perform any database operations.
50    fn tx_mut(&self) -> Result<Self::TXMut, DatabaseError> {
51        Ok(TxMock::default())
52    }
53
54    fn path(&self) -> PathBuf {
55        PathBuf::default()
56    }
57}
58
59impl DatabaseMetrics for DatabaseMock {}
60
61/// Mock transaction implementation for testing and development.
62///
63/// Implements both [`DbTx`] and [`DbTxMut`] traits. All operations are no-ops
64/// that return success or default values, suitable for testing database operations
65/// without side effects.
66#[derive(Debug, Clone, Default)]
67pub struct TxMock {
68    /// Internal table representation (currently unused).
69    _table: BTreeMap<Vec<u8>, Vec<u8>>,
70}
71
72impl DbTx for TxMock {
73    type Cursor<T: Table> = CursorMock;
74    type DupCursor<T: DupSort> = CursorMock;
75
76    /// Retrieves a value by key from the specified table.
77    ///
78    /// **Mock behavior**: Always returns `None` regardless of the key.
79    /// This simulates a table with no data, which is typical for testing
80    /// scenarios where you want to verify that read operations are called
81    /// correctly without actually storing data.
82    fn get<T: Table>(&self, _key: T::Key) -> Result<Option<T::Value>, DatabaseError> {
83        Ok(None)
84    }
85
86    /// Retrieves a value by encoded key from the specified table.
87    ///
88    /// **Mock behavior**: Always returns `None` regardless of the encoded key.
89    /// This is equivalent to [`Self::get`] but works with pre-encoded keys.
90    fn get_by_encoded_key<T: Table>(
91        &self,
92        _key: &<T::Key as Encode>::Encoded,
93    ) -> Result<Option<T::Value>, DatabaseError> {
94        Ok(None)
95    }
96
97    /// Commits the transaction.
98    ///
99    /// **Mock behavior**: Always returns `Ok(())`, indicating successful commit.
100    /// No actual data is persisted since this is a mock implementation.
101    fn commit(self) -> Result<(), DatabaseError> {
102        Ok(())
103    }
104
105    /// Aborts the transaction.
106    ///
107    /// **Mock behavior**: No-op. Since no data is actually stored in the mock,
108    /// there's nothing to rollback.
109    fn abort(self) {}
110
111    /// Creates a read-only cursor for the specified table.
112    ///
113    /// **Mock behavior**: Returns a default [`CursorMock`] that will not
114    /// iterate over any data (all cursor operations return `None`).
115    fn cursor_read<T: Table>(&self) -> Result<Self::Cursor<T>, DatabaseError> {
116        Ok(CursorMock { _cursor: 0 })
117    }
118
119    /// Creates a read-only duplicate cursor for the specified duplicate sort table.
120    ///
121    /// **Mock behavior**: Returns a default [`CursorMock`] that will not
122    /// iterate over any data (all cursor operations return `None`).
123    fn cursor_dup_read<T: DupSort>(&self) -> Result<Self::DupCursor<T>, DatabaseError> {
124        Ok(CursorMock { _cursor: 0 })
125    }
126
127    /// Returns the number of entries in the specified table.
128    ///
129    /// **Mock behavior**: Returns the length of the internal `_table` `BTreeMap`,
130    /// which is typically 0 since no data is actually stored.
131    fn entries<T: Table>(&self) -> Result<usize, DatabaseError> {
132        Ok(self._table.len())
133    }
134
135    /// Disables long read transaction safety checks.
136    ///
137    /// **Mock behavior**: No-op. This is a performance optimization that
138    /// doesn't apply to the mock implementation.
139    fn disable_long_read_transaction_safety(&mut self) {}
140}
141
142impl DbTxMut for TxMock {
143    type CursorMut<T: Table> = CursorMock;
144    type DupCursorMut<T: DupSort> = CursorMock;
145
146    /// Inserts or updates a key-value pair in the specified table.
147    ///
148    /// **Mock behavior**: Always returns `Ok(())` without actually storing
149    /// the data. This allows tests to verify that write operations are called
150    /// correctly without side effects.
151    fn put<T: Table>(&self, _key: T::Key, _value: T::Value) -> Result<(), DatabaseError> {
152        Ok(())
153    }
154
155    /// Deletes a key-value pair from the specified table.
156    ///
157    /// **Mock behavior**: Always returns `Ok(true)`, indicating successful
158    /// deletion, without actually removing any data.
159    fn delete<T: Table>(
160        &self,
161        _key: T::Key,
162        _value: Option<T::Value>,
163    ) -> Result<bool, DatabaseError> {
164        Ok(true)
165    }
166
167    /// Clears all entries from the specified table.
168    ///
169    /// **Mock behavior**: Always returns `Ok(())` without actually clearing
170    /// any data. This simulates successful table clearing for testing purposes.
171    fn clear<T: Table>(&self) -> Result<(), DatabaseError> {
172        Ok(())
173    }
174
175    /// Creates a write cursor for the specified table.
176    ///
177    /// **Mock behavior**: Returns a default [`CursorMock`] that will not
178    /// iterate over any data and all write operations will be no-ops.
179    fn cursor_write<T: Table>(&self) -> Result<Self::CursorMut<T>, DatabaseError> {
180        Ok(CursorMock { _cursor: 0 })
181    }
182
183    /// Creates a write duplicate cursor for the specified duplicate sort table.
184    ///
185    /// **Mock behavior**: Returns a default [`CursorMock`] that will not
186    /// iterate over any data and all write operations will be no-ops.
187    fn cursor_dup_write<T: DupSort>(&self) -> Result<Self::DupCursorMut<T>, DatabaseError> {
188        Ok(CursorMock { _cursor: 0 })
189    }
190}
191
192impl TableImporter for TxMock {}
193
194/// Mock cursor implementation for testing and development.
195///
196/// Implements all cursor traits. All operations are no-ops that return empty
197/// results, suitable for testing cursor operations without side effects.
198#[derive(Debug)]
199pub struct CursorMock {
200    /// Internal cursor position (currently unused).
201    _cursor: u32,
202}
203
204impl<T: Table> DbCursorRO<T> for CursorMock {
205    /// Moves to the first entry in the table.
206    /// **Mock behavior**: Always returns `None`.
207    fn first(&mut self) -> PairResult<T> {
208        Ok(None)
209    }
210
211    /// Seeks to an exact key match.
212    /// **Mock behavior**: Always returns `None`.
213    fn seek_exact(&mut self, _key: T::Key) -> PairResult<T> {
214        Ok(None)
215    }
216
217    /// Seeks to the first key greater than or equal to the given key.
218    /// **Mock behavior**: Always returns `None`.
219    fn seek(&mut self, _key: T::Key) -> PairResult<T> {
220        Ok(None)
221    }
222
223    /// Moves to the next entry.
224    /// **Mock behavior**: Always returns `None`.
225    fn next(&mut self) -> PairResult<T> {
226        Ok(None)
227    }
228
229    /// Moves to the previous entry.
230    /// **Mock behavior**: Always returns `None`.
231    fn prev(&mut self) -> PairResult<T> {
232        Ok(None)
233    }
234
235    /// Moves to the last entry in the table.
236    /// **Mock behavior**: Always returns `None`.
237    fn last(&mut self) -> PairResult<T> {
238        Ok(None)
239    }
240
241    /// Returns the current entry without moving the cursor.
242    /// **Mock behavior**: Always returns `None`.
243    fn current(&mut self) -> PairResult<T> {
244        Ok(None)
245    }
246
247    /// Creates a forward walker starting from the given key.
248    /// **Mock behavior**: Returns an empty walker that won't iterate over any data.
249    fn walk(&mut self, start_key: Option<T::Key>) -> Result<Walker<'_, T, Self>, DatabaseError> {
250        let start: IterPairResult<T> = match start_key {
251            Some(key) => <Self as DbCursorRO<T>>::seek(self, key).transpose(),
252            None => <Self as DbCursorRO<T>>::first(self).transpose(),
253        };
254
255        Ok(Walker::new(self, start))
256    }
257
258    /// Creates a range walker for the specified key range.
259    /// **Mock behavior**: Returns an empty walker that won't iterate over any data.
260    fn walk_range(
261        &mut self,
262        range: impl RangeBounds<T::Key>,
263    ) -> Result<RangeWalker<'_, T, Self>, DatabaseError> {
264        let start_key = match range.start_bound() {
265            Bound::Included(key) | Bound::Excluded(key) => Some((*key).clone()),
266            Bound::Unbounded => None,
267        };
268
269        let end_key = match range.end_bound() {
270            Bound::Included(key) | Bound::Excluded(key) => Bound::Included((*key).clone()),
271            Bound::Unbounded => Bound::Unbounded,
272        };
273
274        let start: IterPairResult<T> = match start_key {
275            Some(key) => <Self as DbCursorRO<T>>::seek(self, key).transpose(),
276            None => <Self as DbCursorRO<T>>::first(self).transpose(),
277        };
278
279        Ok(RangeWalker::new(self, start, end_key))
280    }
281
282    /// Creates a backward walker starting from the given key.
283    /// **Mock behavior**: Returns an empty walker that won't iterate over any data.
284    fn walk_back(
285        &mut self,
286        start_key: Option<T::Key>,
287    ) -> Result<ReverseWalker<'_, T, Self>, DatabaseError> {
288        let start: IterPairResult<T> = match start_key {
289            Some(key) => <Self as DbCursorRO<T>>::seek(self, key).transpose(),
290            None => <Self as DbCursorRO<T>>::last(self).transpose(),
291        };
292        Ok(ReverseWalker::new(self, start))
293    }
294}
295
296impl<T: DupSort> DbDupCursorRO<T> for CursorMock {
297    /// Moves to the next duplicate entry.
298    /// **Mock behavior**: Always returns `None`.
299    fn next_dup(&mut self) -> PairResult<T> {
300        Ok(None)
301    }
302
303    /// Moves to the previous duplicate entry.
304    /// **Mock behavior**: Always returns `None`.
305    fn prev_dup(&mut self) -> PairResult<T> {
306        Ok(None)
307    }
308
309    /// Moves to the last duplicate entry.
310    /// **Mock behavior**: Always returns `None`.
311    fn last_dup(&mut self) -> ValueOnlyResult<T> {
312        Ok(None)
313    }
314
315    /// Moves to the next entry with a different key.
316    /// **Mock behavior**: Always returns `None`.
317    fn next_no_dup(&mut self) -> PairResult<T> {
318        Ok(None)
319    }
320
321    /// Moves to the next duplicate value.
322    /// **Mock behavior**: Always returns `None`.
323    fn next_dup_val(&mut self) -> ValueOnlyResult<T> {
324        Ok(None)
325    }
326
327    /// Seeks to a specific key-subkey combination.
328    /// **Mock behavior**: Always returns `None`.
329    fn seek_by_key_subkey(
330        &mut self,
331        _key: <T as Table>::Key,
332        _subkey: <T as DupSort>::SubKey,
333    ) -> ValueOnlyResult<T> {
334        Ok(None)
335    }
336
337    /// Creates a duplicate walker for the specified key and subkey.
338    /// **Mock behavior**: Returns an empty walker that won't iterate over any data.
339    fn walk_dup(
340        &mut self,
341        _key: Option<<T>::Key>,
342        _subkey: Option<<T as DupSort>::SubKey>,
343    ) -> Result<DupWalker<'_, T, Self>, DatabaseError> {
344        Ok(DupWalker { cursor: self, start: None })
345    }
346}
347
348impl<T: Table> DbCursorRW<T> for CursorMock {
349    /// Inserts or updates a key-value pair at the current cursor position.
350    /// **Mock behavior**: Always succeeds without modifying any data.
351    fn upsert(
352        &mut self,
353        _key: <T as Table>::Key,
354        _value: &<T as Table>::Value,
355    ) -> Result<(), DatabaseError> {
356        Ok(())
357    }
358
359    /// Inserts a key-value pair at the current cursor position.
360    /// **Mock behavior**: Always succeeds without modifying any data.
361    fn insert(
362        &mut self,
363        _key: <T as Table>::Key,
364        _value: &<T as Table>::Value,
365    ) -> Result<(), DatabaseError> {
366        Ok(())
367    }
368
369    /// Appends a key-value pair at the end of the table.
370    /// **Mock behavior**: Always succeeds without modifying any data.
371    fn append(
372        &mut self,
373        _key: <T as Table>::Key,
374        _value: &<T as Table>::Value,
375    ) -> Result<(), DatabaseError> {
376        Ok(())
377    }
378
379    /// Deletes the entry at the current cursor position.
380    /// **Mock behavior**: Always succeeds without modifying any data.
381    fn delete_current(&mut self) -> Result<(), DatabaseError> {
382        Ok(())
383    }
384}
385
386impl<T: DupSort> DbDupCursorRW<T> for CursorMock {
387    /// Deletes all duplicate entries at the current cursor position.
388    /// **Mock behavior**: Always succeeds without modifying any data.
389    fn delete_current_duplicates(&mut self) -> Result<(), DatabaseError> {
390        Ok(())
391    }
392
393    /// Appends a duplicate key-value pair.
394    /// **Mock behavior**: Always succeeds without modifying any data.
395    fn append_dup(&mut self, _key: <T>::Key, _value: <T>::Value) -> Result<(), DatabaseError> {
396        Ok(())
397    }
398}