1pub mod clock;
26pub mod error;
27#[doc(hidden)]
31pub mod sql_builders;
32#[cfg(any(feature = "native-sqlite", feature = "_has-encryption"))]
37pub mod rusqlite_impl;
38#[cfg(feature = "wasm-sqlite")]
39pub mod wasm_backend;
40
41use crate::storage::{
42 CreateTableMetadata, DatabaseInfo, QueryParams, ScanParams, StreamRecord, TableMetadata,
43 TableStats,
44};
45use crate::types::Tag;
46
47pub use clock::{Clock, ManualClock, SystemClock};
48pub use error::BackendError;
49#[cfg(any(feature = "native-sqlite", feature = "_has-encryption"))]
50pub use error::from_rusqlite;
51#[doc(hidden)]
52pub use sql_builders::SqlParam;
53#[cfg(feature = "wasm-sqlite")]
54pub use wasm_backend::WasmBridgeBackend;
55
56#[derive(Debug, Clone)]
63pub struct BaseItemRow {
64 pub pk: String,
66 pub sk: String,
68 pub item_json: String,
70 pub item_size: usize,
72 pub cached_at: Option<f64>,
74 pub hash_prefix: String,
76}
77
78#[derive(Debug, Clone)]
83pub struct GsiItemRow {
84 pub gsi_pk: String,
86 pub gsi_sk: String,
88 pub table_pk: String,
90 pub table_sk: String,
92 pub item_json: String,
94}
95
96#[allow(async_fn_in_trait)]
115pub trait StorageBackend {
116 fn clock(&self) -> &dyn Clock;
125
126 async fn insert_table_metadata(&self, m: &CreateTableMetadata<'_>) -> Result<(), BackendError>;
131
132 async fn get_table_metadata(
133 &self,
134 table_name: &str,
135 ) -> Result<Option<TableMetadata>, BackendError>;
136
137 async fn delete_table_metadata(&self, table_name: &str) -> Result<bool, BackendError>;
138
139 async fn update_table_metadata(
140 &self,
141 table_name: &str,
142 attribute_definitions: &str,
143 gsi_definitions: Option<&str>,
144 ) -> Result<(), BackendError>;
145
146 async fn update_provisioned_throughput(
147 &self,
148 table_name: &str,
149 provisioned_throughput: &str,
150 ) -> Result<(), BackendError>;
151
152 async fn clear_provisioned_throughput(&self, table_name: &str) -> Result<(), BackendError>;
153
154 async fn update_billing_mode(
155 &self,
156 table_name: &str,
157 billing_mode: &str,
158 ) -> Result<(), BackendError>;
159
160 async fn update_table_class(
161 &self,
162 table_name: &str,
163 table_class: &str,
164 ) -> Result<(), BackendError>;
165
166 async fn update_on_demand_throughput(
167 &self,
168 table_name: &str,
169 on_demand_throughput: &str,
170 ) -> Result<(), BackendError>;
171
172 async fn get_tags(&self, table_name: &str) -> Result<Vec<Tag>, BackendError>;
173
174 async fn set_tags(&self, table_name: &str, new_tags: &[Tag]) -> Result<(), BackendError>;
175
176 async fn update_deletion_protection(
177 &self,
178 table_name: &str,
179 enabled: bool,
180 ) -> Result<(), BackendError>;
181
182 async fn remove_tags(&self, table_name: &str, keys: &[String]) -> Result<(), BackendError>;
183
184 async fn list_table_names(&self) -> Result<Vec<String>, BackendError>;
185
186 async fn table_exists(&self, table_name: &str) -> Result<bool, BackendError>;
187
188 async fn create_data_table(&self, table_name: &str) -> Result<(), BackendError>;
193
194 async fn drop_data_table(&self, table_name: &str) -> Result<(), BackendError>;
195
196 async fn create_gsi_table(
197 &self,
198 table_name: &str,
199 index_name: &str,
200 ) -> Result<(), BackendError>;
201
202 async fn drop_gsi_table(&self, table_name: &str, index_name: &str) -> Result<(), BackendError>;
203
204 async fn create_lsi_table(
205 &self,
206 table_name: &str,
207 index_name: &str,
208 ) -> Result<(), BackendError>;
209
210 async fn drop_lsi_table(&self, table_name: &str, index_name: &str) -> Result<(), BackendError>;
211
212 #[allow(clippy::too_many_arguments)]
217 async fn insert_gsi_item(
218 &self,
219 table_name: &str,
220 index_name: &str,
221 gsi_pk: &str,
222 gsi_sk: &str,
223 table_pk: &str,
224 table_sk: &str,
225 item_json: &str,
226 ) -> Result<(), BackendError>;
227
228 async fn insert_gsi_items(
235 &self,
236 table_name: &str,
237 index_name: &str,
238 rows: &[GsiItemRow],
239 ) -> Result<(), BackendError>;
240
241 async fn delete_gsi_item(
242 &self,
243 table_name: &str,
244 index_name: &str,
245 table_pk: &str,
246 table_sk: &str,
247 ) -> Result<(), BackendError>;
248
249 async fn query_gsi_items(
250 &self,
251 table_name: &str,
252 index_name: &str,
253 gsi_pk: &str,
254 params: &QueryParams<'_>,
255 ) -> Result<Vec<(String, String, String)>, BackendError>;
256
257 async fn scan_gsi_items(
258 &self,
259 table_name: &str,
260 index_name: &str,
261 params: &ScanParams<'_>,
262 ) -> Result<Vec<(String, String, String)>, BackendError>;
263
264 #[allow(clippy::too_many_arguments)]
269 async fn insert_lsi_item(
270 &self,
271 table_name: &str,
272 index_name: &str,
273 pk: &str,
274 sk: &str,
275 base_pk: &str,
276 base_sk: &str,
277 item_json: &str,
278 ) -> Result<(), BackendError>;
279
280 async fn delete_lsi_item(
281 &self,
282 table_name: &str,
283 index_name: &str,
284 base_pk: &str,
285 base_sk: &str,
286 ) -> Result<(), BackendError>;
287
288 async fn query_lsi_items(
289 &self,
290 table_name: &str,
291 index_name: &str,
292 pk: &str,
293 params: &QueryParams<'_>,
294 ) -> Result<Vec<(String, String, String)>, BackendError>;
295
296 async fn scan_lsi_items(
297 &self,
298 table_name: &str,
299 index_name: &str,
300 params: &ScanParams<'_>,
301 ) -> Result<Vec<(String, String, String)>, BackendError>;
302
303 async fn begin_transaction(&self) -> Result<(), BackendError>;
308 async fn commit(&self) -> Result<(), BackendError>;
309 async fn rollback(&self) -> Result<(), BackendError>;
310
311 async fn enable_bulk_loading(&self) -> Result<(), BackendError>;
316 async fn disable_bulk_loading(&self) -> Result<(), BackendError>;
317
318 async fn put_item(
323 &self,
324 table_name: &str,
325 pk: &str,
326 sk: &str,
327 item_json: &str,
328 item_size: usize,
329 ) -> Result<Option<String>, BackendError>;
330
331 #[allow(clippy::too_many_arguments)]
332 async fn put_item_with_hash(
333 &self,
334 table_name: &str,
335 pk: &str,
336 sk: &str,
337 item_json: &str,
338 item_size: usize,
339 hash_prefix: &str,
340 ) -> Result<Option<String>, BackendError>;
341
342 async fn put_base_items(
350 &self,
351 table_name: &str,
352 rows: &[BaseItemRow],
353 ) -> Result<(), BackendError>;
354
355 async fn get_item(
356 &self,
357 table_name: &str,
358 pk: &str,
359 sk: &str,
360 ) -> Result<Option<String>, BackendError>;
361
362 async fn get_partition_size(&self, table_name: &str, pk: &str) -> Result<i64, BackendError>;
363
364 async fn get_lsi_partition_size(
365 &self,
366 table_name: &str,
367 index_name: &str,
368 pk: &str,
369 ) -> Result<i64, BackendError>;
370
371 async fn delete_item(
372 &self,
373 table_name: &str,
374 pk: &str,
375 sk: &str,
376 ) -> Result<Option<String>, BackendError>;
377
378 async fn query_items(
379 &self,
380 table_name: &str,
381 pk: &str,
382 params: &QueryParams<'_>,
383 ) -> Result<Vec<(String, String, String)>, BackendError>;
384
385 async fn scan_items(
386 &self,
387 table_name: &str,
388 params: &ScanParams<'_>,
389 ) -> Result<Vec<(String, String, String)>, BackendError>;
390
391 async fn count_items(&self, table_name: &str) -> Result<i64, BackendError>;
392
393 async fn db_size_bytes(&self) -> Result<u64, BackendError>;
398 async fn table_count(&self) -> Result<usize, BackendError>;
399 async fn table_stats(&self) -> Result<Vec<TableStats>, BackendError>;
400 async fn database_info(&self) -> Result<DatabaseInfo, BackendError>;
401 async fn vacuum(&self) -> Result<(), BackendError>;
402
403 async fn enable_stream(
408 &self,
409 table_name: &str,
410 view_type: &str,
411 label: &str,
412 ) -> Result<(), BackendError>;
413
414 async fn disable_stream(&self, table_name: &str) -> Result<(), BackendError>;
415
416 #[allow(clippy::too_many_arguments)]
417 async fn insert_stream_record(
418 &self,
419 table_name: &str,
420 event_name: &str,
421 keys_json: &str,
422 new_image: Option<&str>,
423 old_image: Option<&str>,
424 sequence_number: &str,
425 shard_id: &str,
426 created_at: i64,
427 ) -> Result<(), BackendError>;
428
429 #[allow(clippy::too_many_arguments)]
430 async fn insert_stream_record_with_identity(
431 &self,
432 table_name: &str,
433 event_name: &str,
434 keys_json: &str,
435 new_image: Option<&str>,
436 old_image: Option<&str>,
437 sequence_number: &str,
438 shard_id: &str,
439 created_at: i64,
440 user_identity: Option<&str>,
441 ) -> Result<(), BackendError>;
442
443 async fn next_stream_sequence_number(&self, table_name: &str) -> Result<i64, BackendError>;
444
445 async fn get_stream_records(
446 &self,
447 table_name: &str,
448 shard_id: &str,
449 after_sequence: i64,
450 limit: usize,
451 ) -> Result<Vec<StreamRecord>, BackendError>;
452
453 async fn list_stream_enabled_tables(&self) -> Result<Vec<TableMetadata>, BackendError>;
454
455 async fn update_ttl_config(
460 &self,
461 table_name: &str,
462 attribute_name: Option<&str>,
463 enabled: bool,
464 ) -> Result<(), BackendError>;
465
466 async fn list_ttl_enabled_tables(&self) -> Result<Vec<TableMetadata>, BackendError>;
467
468 async fn get_shard_sequence_range(
469 &self,
470 table_name: &str,
471 shard_id: &str,
472 ) -> Result<(Option<String>, Option<String>), BackendError>;
473
474 async fn touch_cached_at(
479 &self,
480 table_name: &str,
481 pk: &str,
482 sk: &str,
483 timestamp: f64,
484 ) -> Result<(), BackendError>;
485
486 async fn get_lru_items(
487 &self,
488 table_name: &str,
489 limit: usize,
490 ) -> Result<Vec<(String, String, i64)>, BackendError>;
491}