1use crate::{
2 cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO, DbDupCursorRW},
3 transaction::{DbTx, DbTxMut},
4 DatabaseError,
5};
6
7use serde::{Deserialize, Serialize};
8use std::fmt::Debug;
9
10pub trait Compress: Send + Sync + Sized + Debug {
12 type Compressed: bytes::BufMut
14 + AsRef<[u8]>
15 + AsMut<[u8]>
16 + Into<Vec<u8>>
17 + Default
18 + Send
19 + Sync
20 + Debug;
21
22 fn uncompressable_ref(&self) -> Option<&[u8]> {
24 None
25 }
26
27 fn compress(self) -> Self::Compressed {
29 let mut buf = Self::Compressed::default();
30 self.compress_to_buf(&mut buf);
31 buf
32 }
33
34 fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(&self, buf: &mut B);
36}
37
38pub trait Decompress: Send + Sync + Sized + Debug {
40 fn decompress(value: &[u8]) -> Result<Self, DatabaseError>;
42
43 fn decompress_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
45 Self::decompress(&value)
46 }
47}
48
49pub trait Encode: Send + Sync + Sized + Debug {
51 type Encoded: AsRef<[u8]> + Into<Vec<u8>> + Send + Sync + Ord + Debug;
53
54 fn encode(self) -> Self::Encoded;
56}
57
58pub trait Decode: Send + Sync + Sized + Debug {
60 fn decode(value: &[u8]) -> Result<Self, DatabaseError>;
62
63 fn decode_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
65 Self::decode(&value)
66 }
67}
68
69pub trait Key: Encode + Decode + Ord + Clone + Serialize + for<'a> Deserialize<'a> {}
71
72impl<T> Key for T where T: Encode + Decode + Ord + Clone + Serialize + for<'a> Deserialize<'a> {}
73
74pub trait Value: Compress + Decompress + Serialize {}
76
77impl<T> Value for T where T: Compress + Decompress + Serialize {}
78
79pub trait Table: Send + Sync + Debug + 'static {
88 const NAME: &'static str;
90
91 const DUPSORT: bool;
93
94 type Key: Key;
98
99 type Value: Value;
101}
102
103pub trait TableInfo: Send + Sync + Debug + 'static {
105 fn name(&self) -> &'static str;
107
108 fn is_dupsort(&self) -> bool;
110}
111
112pub type TableRow<T> = (<T as Table>::Key, <T as Table>::Value);
114
115pub trait DupSort: Table {
119 type SubKey: Key;
125}
126
127pub trait TableImporter: DbTxMut {
129 fn import_table<T: Table, R: DbTx>(&self, source_tx: &R) -> Result<(), DatabaseError> {
131 let mut destination_cursor = self.cursor_write::<T>()?;
132
133 for kv in source_tx.cursor_read::<T>()?.walk(None)? {
134 let (k, v) = kv?;
135 destination_cursor.append(k, &v)?;
136 }
137
138 Ok(())
139 }
140
141 fn import_table_with_range<T: Table, R: DbTx>(
143 &self,
144 source_tx: &R,
145 from: Option<<T as Table>::Key>,
146 to: <T as Table>::Key,
147 ) -> Result<(), DatabaseError>
148 where
149 T::Key: Default,
150 {
151 let mut destination_cursor = self.cursor_write::<T>()?;
152 let mut source_cursor = source_tx.cursor_read::<T>()?;
153
154 let source_range = match from {
155 Some(from) => source_cursor.walk_range(from..=to),
156 None => source_cursor.walk_range(..=to),
157 };
158 for row in source_range? {
159 let (key, value) = row?;
160 destination_cursor.append(key, &value)?;
161 }
162
163 Ok(())
164 }
165
166 fn import_dupsort<T: DupSort, R: DbTx>(&self, source_tx: &R) -> Result<(), DatabaseError> {
168 let mut destination_cursor = self.cursor_dup_write::<T>()?;
169 let mut cursor = source_tx.cursor_dup_read::<T>()?;
170
171 while let Some((k, _)) = cursor.next_no_dup()? {
172 for kv in cursor.walk_dup(Some(k), None)? {
173 let (k, v) = kv?;
174 destination_cursor.append_dup(k, v)?;
175 }
176 }
177
178 Ok(())
179 }
180}