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