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