1use crate::{
2 cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO, DbDupCursorRW},
3 transaction::{DbTx, DbTxMut},
4 DatabaseError, Tables,
5};
6use serde::{Deserialize, Serialize};
7use std::fmt::Debug;
8
9pub use reth_codecs::{Compress, Decompress};
10
11pub trait IntoVec: AsRef<[u8]> {
16 fn into_vec(self) -> Vec<u8>;
18}
19
20impl IntoVec for Vec<u8> {
21 #[inline]
22 fn into_vec(self) -> Vec<u8> {
23 self
24 }
25}
26
27impl<const N: usize> IntoVec for [u8; N] {
28 #[inline]
29 fn into_vec(self) -> Vec<u8> {
30 self.to_vec()
31 }
32}
33
34impl<const N: usize> IntoVec for arrayvec::ArrayVec<u8, N> {
35 #[inline]
36 fn into_vec(self) -> Vec<u8> {
37 self.to_vec()
38 }
39}
40
41pub trait Encode: Send + Sync + Sized + Debug {
43 type Encoded: IntoVec + Send + Sync + Ord + Debug;
45
46 fn encode(self) -> Self::Encoded;
48}
49
50pub trait Decode: Send + Sync + Sized + Debug {
52 fn decode(value: &[u8]) -> Result<Self, DatabaseError>;
54
55 fn decode_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
57 Self::decode(&value)
58 }
59}
60
61pub trait Key: Encode + Decode + Ord + Clone + Serialize + for<'a> Deserialize<'a> {}
63
64impl<T> Key for T where T: Encode + Decode + Ord + Clone + Serialize + for<'a> Deserialize<'a> {}
65
66pub trait Value: Compress + Decompress + Serialize {}
68
69impl<T> Value for T where T: Compress + Decompress + Serialize {}
70
71pub trait Table: Send + Sync + Debug + 'static {
80 const NAME: &'static str;
82
83 const DUPSORT: bool;
85
86 const TABLE: Option<Tables> = None;
92
93 type Key: Key;
97
98 type Value: Value;
100}
101
102pub trait TableInfo: Send + Sync + Debug + 'static {
104 fn name(&self) -> &'static str;
106
107 fn is_dupsort(&self) -> bool;
109}
110
111pub type TableRow<T> = (<T as Table>::Key, <T as Table>::Value);
113
114pub trait DupSort: Table {
118 type SubKey: Key;
124}
125
126pub trait TableImporter: DbTxMut {
128 fn import_table<T: Table, R: DbTx>(&self, source_tx: &R) -> Result<(), DatabaseError> {
130 let mut destination_cursor = self.cursor_write::<T>()?;
131
132 for kv in source_tx.cursor_read::<T>()?.walk(None)? {
133 let (k, v) = kv?;
134 destination_cursor.append(k, &v)?;
135 }
136
137 Ok(())
138 }
139
140 fn import_table_with_range<T: Table, R: DbTx>(
145 &self,
146 source_tx: &R,
147 from: Option<<T as Table>::Key>,
148 to: <T as Table>::Key,
149 ) -> Result<(), DatabaseError>
150 where
151 T::Key: Default,
152 {
153 let mut destination_cursor = self.cursor_write::<T>()?;
154 let mut source_cursor = source_tx.cursor_read::<T>()?;
155
156 let source_range = match from {
157 Some(from) => source_cursor.walk_range(from..=to),
158 None => source_cursor.walk_range(..=to),
159 };
160 for row in source_range? {
161 let (key, value) = row?;
162 destination_cursor.append(key, &value)?;
163 }
164
165 Ok(())
166 }
167
168 fn import_dupsort<T: DupSort, R: DbTx>(&self, source_tx: &R) -> Result<(), DatabaseError> {
170 let mut destination_cursor = self.cursor_dup_write::<T>()?;
171 let mut cursor = source_tx.cursor_dup_read::<T>()?;
172
173 while let Some((k, _)) = cursor.next_no_dup()? {
174 for kv in cursor.walk_dup(Some(k), None)? {
175 let (k, v) = kv?;
176 destination_cursor.append_dup(k, v)?;
177 }
178 }
179
180 Ok(())
181 }
182}