reth_db_api/
mock.rs

1//! Mock database
2
3use crate::{
4    common::{IterPairResult, PairResult, ValueOnlyResult},
5    cursor::{
6        DbCursorRO, DbCursorRW, DbDupCursorRO, DbDupCursorRW, DupWalker, RangeWalker,
7        ReverseWalker, Walker,
8    },
9    database::Database,
10    database_metrics::DatabaseMetrics,
11    table::{DupSort, Encode, Table, TableImporter},
12    transaction::{DbTx, DbTxMut},
13    DatabaseError,
14};
15use core::ops::Bound;
16use std::{collections::BTreeMap, ops::RangeBounds};
17
18/// Mock database used for testing with inner `BTreeMap` structure
19#[derive(Clone, Debug, Default)]
20pub struct DatabaseMock {
21    /// Main data. TODO (Make it table aware)
22    pub data: BTreeMap<Vec<u8>, Vec<u8>>,
23}
24
25impl Database for DatabaseMock {
26    type TX = TxMock;
27    type TXMut = TxMock;
28    fn tx(&self) -> Result<Self::TX, DatabaseError> {
29        Ok(TxMock::default())
30    }
31
32    fn tx_mut(&self) -> Result<Self::TXMut, DatabaseError> {
33        Ok(TxMock::default())
34    }
35}
36
37impl DatabaseMetrics for DatabaseMock {}
38
39/// Mock read only tx
40#[derive(Debug, Clone, Default)]
41pub struct TxMock {
42    /// Table representation
43    _table: BTreeMap<Vec<u8>, Vec<u8>>,
44}
45
46impl DbTx for TxMock {
47    type Cursor<T: Table> = CursorMock;
48    type DupCursor<T: DupSort> = CursorMock;
49
50    fn get<T: Table>(&self, _key: T::Key) -> Result<Option<T::Value>, DatabaseError> {
51        Ok(None)
52    }
53
54    fn get_by_encoded_key<T: Table>(
55        &self,
56        _key: &<T::Key as Encode>::Encoded,
57    ) -> Result<Option<T::Value>, DatabaseError> {
58        Ok(None)
59    }
60
61    fn commit(self) -> Result<bool, DatabaseError> {
62        Ok(true)
63    }
64
65    fn abort(self) {}
66
67    fn cursor_read<T: Table>(&self) -> Result<Self::Cursor<T>, DatabaseError> {
68        Ok(CursorMock { _cursor: 0 })
69    }
70
71    fn cursor_dup_read<T: DupSort>(&self) -> Result<Self::DupCursor<T>, DatabaseError> {
72        Ok(CursorMock { _cursor: 0 })
73    }
74
75    fn entries<T: Table>(&self) -> Result<usize, DatabaseError> {
76        Ok(self._table.len())
77    }
78
79    fn disable_long_read_transaction_safety(&mut self) {}
80}
81
82impl DbTxMut for TxMock {
83    type CursorMut<T: Table> = CursorMock;
84    type DupCursorMut<T: DupSort> = CursorMock;
85
86    fn put<T: Table>(&self, _key: T::Key, _value: T::Value) -> Result<(), DatabaseError> {
87        Ok(())
88    }
89
90    fn delete<T: Table>(
91        &self,
92        _key: T::Key,
93        _value: Option<T::Value>,
94    ) -> Result<bool, DatabaseError> {
95        Ok(true)
96    }
97
98    fn clear<T: Table>(&self) -> Result<(), DatabaseError> {
99        Ok(())
100    }
101
102    fn cursor_write<T: Table>(&self) -> Result<Self::CursorMut<T>, DatabaseError> {
103        Ok(CursorMock { _cursor: 0 })
104    }
105
106    fn cursor_dup_write<T: DupSort>(&self) -> Result<Self::DupCursorMut<T>, DatabaseError> {
107        Ok(CursorMock { _cursor: 0 })
108    }
109}
110
111impl TableImporter for TxMock {}
112
113/// Cursor that iterates over table
114#[derive(Debug)]
115pub struct CursorMock {
116    _cursor: u32,
117}
118
119impl<T: Table> DbCursorRO<T> for CursorMock {
120    fn first(&mut self) -> PairResult<T> {
121        Ok(None)
122    }
123
124    fn seek_exact(&mut self, _key: T::Key) -> PairResult<T> {
125        Ok(None)
126    }
127
128    fn seek(&mut self, _key: T::Key) -> PairResult<T> {
129        Ok(None)
130    }
131
132    fn next(&mut self) -> PairResult<T> {
133        Ok(None)
134    }
135
136    fn prev(&mut self) -> PairResult<T> {
137        Ok(None)
138    }
139
140    fn last(&mut self) -> PairResult<T> {
141        Ok(None)
142    }
143
144    fn current(&mut self) -> PairResult<T> {
145        Ok(None)
146    }
147
148    fn walk(&mut self, start_key: Option<T::Key>) -> Result<Walker<'_, T, Self>, DatabaseError> {
149        let start: IterPairResult<T> = match start_key {
150            Some(key) => <Self as DbCursorRO<T>>::seek(self, key).transpose(),
151            None => <Self as DbCursorRO<T>>::first(self).transpose(),
152        };
153
154        Ok(Walker::new(self, start))
155    }
156
157    fn walk_range(
158        &mut self,
159        range: impl RangeBounds<T::Key>,
160    ) -> Result<RangeWalker<'_, T, Self>, DatabaseError> {
161        let start_key = match range.start_bound() {
162            Bound::Included(key) | Bound::Excluded(key) => Some((*key).clone()),
163            Bound::Unbounded => None,
164        };
165
166        let end_key = match range.end_bound() {
167            Bound::Included(key) | Bound::Excluded(key) => Bound::Included((*key).clone()),
168            Bound::Unbounded => Bound::Unbounded,
169        };
170
171        let start: IterPairResult<T> = match start_key {
172            Some(key) => <Self as DbCursorRO<T>>::seek(self, key).transpose(),
173            None => <Self as DbCursorRO<T>>::first(self).transpose(),
174        };
175
176        Ok(RangeWalker::new(self, start, end_key))
177    }
178
179    fn walk_back(
180        &mut self,
181        start_key: Option<T::Key>,
182    ) -> Result<ReverseWalker<'_, T, Self>, DatabaseError> {
183        let start: IterPairResult<T> = match start_key {
184            Some(key) => <Self as DbCursorRO<T>>::seek(self, key).transpose(),
185            None => <Self as DbCursorRO<T>>::last(self).transpose(),
186        };
187        Ok(ReverseWalker::new(self, start))
188    }
189}
190
191impl<T: DupSort> DbDupCursorRO<T> for CursorMock {
192    fn next_dup(&mut self) -> PairResult<T> {
193        Ok(None)
194    }
195
196    fn next_no_dup(&mut self) -> PairResult<T> {
197        Ok(None)
198    }
199
200    fn next_dup_val(&mut self) -> ValueOnlyResult<T> {
201        Ok(None)
202    }
203
204    fn seek_by_key_subkey(
205        &mut self,
206        _key: <T as Table>::Key,
207        _subkey: <T as DupSort>::SubKey,
208    ) -> ValueOnlyResult<T> {
209        Ok(None)
210    }
211
212    fn walk_dup(
213        &mut self,
214        _key: Option<<T>::Key>,
215        _subkey: Option<<T as DupSort>::SubKey>,
216    ) -> Result<DupWalker<'_, T, Self>, DatabaseError> {
217        Ok(DupWalker { cursor: self, start: None })
218    }
219}
220
221impl<T: Table> DbCursorRW<T> for CursorMock {
222    fn upsert(
223        &mut self,
224        _key: <T as Table>::Key,
225        _value: &<T as Table>::Value,
226    ) -> Result<(), DatabaseError> {
227        Ok(())
228    }
229
230    fn insert(
231        &mut self,
232        _key: <T as Table>::Key,
233        _value: &<T as Table>::Value,
234    ) -> Result<(), DatabaseError> {
235        Ok(())
236    }
237
238    fn append(
239        &mut self,
240        _key: <T as Table>::Key,
241        _value: &<T as Table>::Value,
242    ) -> Result<(), DatabaseError> {
243        Ok(())
244    }
245
246    fn delete_current(&mut self) -> Result<(), DatabaseError> {
247        Ok(())
248    }
249}
250
251impl<T: DupSort> DbDupCursorRW<T> for CursorMock {
252    fn delete_current_duplicates(&mut self) -> Result<(), DatabaseError> {
253        Ok(())
254    }
255
256    fn append_dup(&mut self, _key: <T>::Key, _value: <T>::Value) -> Result<(), DatabaseError> {
257        Ok(())
258    }
259}