1use reifydb_codec::key::encoded::EncodedKey;
5use reifydb_macro::KeyCodec;
6
7use super::KeyTag;
8use crate::{
9 interface::catalog::{
10 id::{ColumnId, ColumnSnapshotId, SeriesId, TableId},
11 object::ObjectId,
12 },
13 key::{
14 any::{Field, KeyFields, Width},
15 bound::{TaggedKeyBoundRange, object_fields},
16 catalog::{KeyDeserializerCatalogExt, KeySerializerCatalogExt},
17 },
18};
19
20#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
21#[key(tag = Column)]
22pub struct ColumnKey {
23 pub object: ObjectId,
24 pub column: ColumnId,
25}
26
27impl ColumnKey {
28 pub fn new(object: impl Into<ObjectId>, column: impl Into<ColumnId>) -> Self {
29 Self {
30 object: object.into(),
31 column: column.into(),
32 }
33 }
34
35 pub fn encoded(object: impl Into<ObjectId>, column: impl Into<ColumnId>) -> EncodedKey {
36 Self::new(object, column).encode()
37 }
38
39 pub fn full_scan(object: impl Into<ObjectId>) -> TaggedKeyBoundRange {
40 TaggedKeyBoundRange::prefix(Self::TAG, object_fields(object.into()))
41 }
42}
43
44#[cfg(test)]
45pub mod column_key_tests {
46 use crate::{
47 interface::catalog::{id::ColumnId, object::ObjectId},
48 key::column::ColumnKey,
49 };
50
51 #[test]
52 fn test_encode_decode() {
53 let key = ColumnKey {
54 object: ObjectId::table(0xABCD),
55 column: ColumnId(0x123456789ABCDEF0),
56 };
57 let encoded = key.encode();
58
59 let expected: Vec<u8> = vec![
60 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32, 0xED, 0xCB, 0xA9, 0x87, 0x65, 0x43,
61 0x21, 0x0F,
62 ];
63
64 assert_eq!(encoded.as_slice(), expected);
65
66 let key = ColumnKey::decode(&encoded).unwrap();
67 assert_eq!(key.object, 0xABCD);
68 assert_eq!(key.column, 0x123456789ABCDEF0);
69 }
70
71 #[test]
72 fn test_order_preserving() {
73 let key1 = ColumnKey {
74 object: ObjectId::table(1),
75 column: ColumnId(100),
76 };
77 let key2 = ColumnKey {
78 object: ObjectId::table(1),
79 column: ColumnId(200),
80 };
81 let key3 = ColumnKey {
82 object: ObjectId::table(2),
83 column: ColumnId(0),
84 };
85
86 let encoded1 = key1.encode();
87 let encoded2 = key2.encode();
88 let encoded3 = key3.encode();
89
90 assert!(encoded3 < encoded2, "ordering not preserved");
91 assert!(encoded2 < encoded1, "ordering not preserved");
92 }
93}
94
95#[derive(Debug, Clone, Copy, PartialEq, Eq, KeyCodec, Hash)]
96#[key(tag = ColumnSequence)]
97pub struct ColumnSequenceKey {
98 pub object: ObjectId,
99 pub column: ColumnId,
100}
101
102impl ColumnSequenceKey {
103 pub fn new(object: impl Into<ObjectId>, column: impl Into<ColumnId>) -> Self {
104 Self {
105 object: object.into(),
106 column: column.into(),
107 }
108 }
109
110 pub fn encoded(object: impl Into<ObjectId>, column: impl Into<ColumnId>) -> EncodedKey {
111 Self::new(object, column).encode()
112 }
113}
114
115#[cfg(test)]
116pub mod column_sequence_key_tests {
117 use reifydb_codec::key::encoded::EncodedKey;
118
119 use super::ColumnSequenceKey;
120 use crate::interface::catalog::{id::ColumnId, object::ObjectId};
121
122 #[test]
123 fn test_encode_decode() {
124 let key = ColumnSequenceKey {
125 object: ObjectId::table(0x1234),
126 column: ColumnId(0x5678),
127 };
128 let encoded = key.encode();
129
130 assert_eq!(encoded[0], 0xF1);
131
132 let decoded = ColumnSequenceKey::decode(&encoded).unwrap();
133 assert_eq!(decoded.object, ObjectId::table(0x1234));
134 assert_eq!(decoded.column, ColumnId(0x5678));
135 }
136
137 #[test]
138 fn test_decode_invalid_version() {
139 let mut encoded = vec![0xFF];
140 encoded.push(0x0E);
141 encoded.extend(&[0; 16]);
142
143 let decoded = ColumnSequenceKey::decode(&EncodedKey::new(encoded));
144 assert!(decoded.is_none());
145 }
146
147 #[test]
148 fn test_decode_invalid_kind() {
149 let mut encoded = vec![0x01];
150 encoded.push(0xFF);
151 encoded.extend(&[0; 16]);
152
153 let decoded = ColumnSequenceKey::decode(&EncodedKey::new(encoded));
154 assert!(decoded.is_none());
155 }
156
157 #[test]
158 fn test_decode_invalid_length() {
159 let encoded = vec![0x01, 0x0E];
160 let decoded = ColumnSequenceKey::decode(&EncodedKey::new(encoded));
161 assert!(decoded.is_none());
162 }
163}
164
165#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
166#[key(tag = ColumnSnapshot)]
167pub struct ColumnSnapshotKey {
168 pub snapshot: ColumnSnapshotId,
169}
170
171impl ColumnSnapshotKey {
172 pub fn new(snapshot: ColumnSnapshotId) -> Self {
173 Self {
174 snapshot,
175 }
176 }
177
178 pub fn encoded(snapshot: impl Into<ColumnSnapshotId>) -> EncodedKey {
179 Self::new(snapshot.into()).encode()
180 }
181
182 pub fn full_scan() -> TaggedKeyBoundRange {
183 TaggedKeyBoundRange::kind(Self::TAG)
184 }
185}
186
187#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
188#[key(tag = SeriesColumnSnapshot)]
189pub struct SeriesColumnSnapshotKey {
190 pub series: SeriesId,
191 pub snapshot: ColumnSnapshotId,
192}
193
194impl SeriesColumnSnapshotKey {
195 pub fn new(series: SeriesId, snapshot: ColumnSnapshotId) -> Self {
196 Self {
197 series,
198 snapshot,
199 }
200 }
201
202 pub fn encoded(series: impl Into<SeriesId>, snapshot: impl Into<ColumnSnapshotId>) -> EncodedKey {
203 Self::new(series.into(), snapshot.into()).encode()
204 }
205
206 pub fn full_scan(series: SeriesId) -> TaggedKeyBoundRange {
207 TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, series.0 as u128)])
208 }
209}
210
211#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
212#[key(tag = TableColumnSnapshot)]
213pub struct TableColumnSnapshotKey {
214 pub table: TableId,
215 pub snapshot: ColumnSnapshotId,
216}
217
218impl TableColumnSnapshotKey {
219 pub fn new(table: TableId, snapshot: ColumnSnapshotId) -> Self {
220 Self {
221 table,
222 snapshot,
223 }
224 }
225
226 pub fn encoded(table: impl Into<TableId>, snapshot: impl Into<ColumnSnapshotId>) -> EncodedKey {
227 Self::new(table.into(), snapshot.into()).encode()
228 }
229
230 pub fn full_scan(table: TableId) -> TaggedKeyBoundRange {
231 TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, table.0 as u128)])
232 }
233}
234
235#[cfg(test)]
236pub mod column_snapshot_key_tests {
237 use std::ops::Bound;
238
239 use super::*;
240
241 #[test]
242 fn a_snapshot_key_reports_its_own_kind_from_its_first_byte() {
243 assert_eq!(KeyTag::of(&ColumnSnapshotKey::encoded(ColumnSnapshotId(1))), Some(KeyTag::ColumnSnapshot));
246 assert_eq!(
247 KeyTag::of(&SeriesColumnSnapshotKey::encoded(SeriesId(1), ColumnSnapshotId(2))),
248 Some(KeyTag::SeriesColumnSnapshot)
249 );
250 assert_eq!(
251 KeyTag::of(&TableColumnSnapshotKey::encoded(TableId(1), ColumnSnapshotId(2))),
252 Some(KeyTag::TableColumnSnapshot)
253 );
254 }
255
256 #[test]
257 fn test_column_snapshot_key_encode_decode() {
258 let key = ColumnSnapshotKey {
259 snapshot: ColumnSnapshotId(0x1234),
260 };
261 let encoded = key.encode();
262 let decoded = ColumnSnapshotKey::decode(&encoded).unwrap();
263 assert_eq!(decoded.snapshot, key.snapshot);
264 }
265
266 #[test]
267 fn test_column_snapshot_key_full_scan() {
268 let range = ColumnSnapshotKey::full_scan();
269 assert!(matches!(range.start, Bound::Included(_) | Bound::Excluded(_)));
270 assert!(matches!(range.end, Bound::Included(_) | Bound::Excluded(_)));
271 }
272
273 #[test]
274 fn test_series_column_snapshot_key_encode_decode() {
275 let key = SeriesColumnSnapshotKey {
276 series: SeriesId(42),
277 snapshot: ColumnSnapshotId(99),
278 };
279 let encoded = key.encode();
280 let decoded = SeriesColumnSnapshotKey::decode(&encoded).unwrap();
281 assert_eq!(decoded.series, key.series);
282 assert_eq!(decoded.snapshot, key.snapshot);
283 }
284
285 #[test]
286 fn test_table_column_snapshot_key_encode_decode() {
287 let key = TableColumnSnapshotKey {
288 table: TableId(42),
289 snapshot: ColumnSnapshotId(99),
290 };
291 let encoded = key.encode();
292 let decoded = TableColumnSnapshotKey::decode(&encoded).unwrap();
293 assert_eq!(decoded.table, key.table);
294 assert_eq!(decoded.snapshot, key.snapshot);
295 }
296}
297
298#[derive(Debug, Clone, PartialEq, KeyCodec, Hash)]
299#[key(tag = Columns)]
300pub struct ColumnsKey {
301 pub column: ColumnId,
302}
303
304impl ColumnsKey {
305 pub fn new(column: impl Into<ColumnId>) -> Self {
306 Self {
307 column: column.into(),
308 }
309 }
310
311 pub fn encoded(column: impl Into<ColumnId>) -> EncodedKey {
312 Self::new(column).encode()
313 }
314
315 pub fn full_scan() -> TaggedKeyBoundRange {
316 TaggedKeyBoundRange::kind(Self::TAG)
317 }
318}
319
320#[cfg(test)]
321pub mod columns_key_tests {
322 use super::ColumnsKey;
323 use crate::interface::catalog::id::ColumnId;
324
325 #[test]
326 fn test_encode_decode() {
327 let key = ColumnsKey {
328 column: ColumnId(0xABCD),
329 };
330 let encoded = key.encode();
331 let expected = vec![0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x54, 0x32];
332 assert_eq!(encoded.as_slice(), expected);
333
334 let key = ColumnsKey::decode(&encoded).unwrap();
335 assert_eq!(key.column, 0xABCD);
336 }
337}