gluesql_composite_storage/
lib.rs1#![deny(clippy::str_to_string)]
2
3mod store;
4mod store_mut;
5mod transaction;
6
7use {
8 gluesql_core::{
9 data::Schema,
10 error::{Error, Result},
11 store::{GStore, GStoreMut, Metadata, Planner, Store},
12 },
13 std::collections::HashMap,
14};
15
16pub trait IStorage: GStore + GStoreMut {}
17
18impl<T: GStore + GStoreMut> IStorage for T {}
19
20#[derive(Default)]
21pub struct CompositeStorage {
22 pub storages: HashMap<String, Box<dyn IStorage>>,
23 pub default_engine: Option<String>,
24}
25
26impl CompositeStorage {
27 pub fn new() -> Self {
28 CompositeStorage::default()
29 }
30
31 pub fn set_default<T: Into<String>>(&mut self, default_engine: T) {
32 self.default_engine = Some(default_engine.into());
33 }
34
35 pub fn remove_default(&mut self) {
36 self.default_engine = None;
37 }
38
39 pub fn push<T: Into<String>, U: IStorage + 'static>(&mut self, engine: T, storage: U) {
40 self.storages.insert(engine.into(), Box::new(storage));
41 }
42
43 pub fn remove<T: AsRef<str>>(&mut self, engine: T) -> Option<Box<dyn IStorage>> {
44 let engine = engine.as_ref();
45
46 if self.default_engine.as_deref() == Some(engine) {
47 self.default_engine = None;
48 }
49
50 self.storages.remove(engine)
51 }
52
53 pub fn clear(&mut self) {
54 self.storages.clear();
55 self.default_engine = None;
56 }
57
58 async fn fetch_engine(&self, table_name: &str) -> Result<String> {
59 self.fetch_schema(table_name)
60 .await?
61 .and_then(|Schema { engine, .. }| engine)
62 .or_else(|| self.default_engine.clone())
63 .ok_or_else(|| Error::StorageMsg(format!("engine not found for table: {table_name}")))
64 }
65
66 async fn fetch_storage(&self, table_name: &str) -> Result<&Box<dyn IStorage>> {
67 self.fetch_engine(table_name)
68 .await
69 .map(|engine| self.storages.get(&engine))?
70 .ok_or_else(|| {
71 Error::StorageMsg(format!(
72 "[fetch_storage] storage not found for table: {table_name}"
73 ))
74 })
75 }
76
77 async fn fetch_storage_mut(&mut self, table_name: &str) -> Result<&mut Box<dyn IStorage>> {
78 self.fetch_engine(table_name)
79 .await
80 .map(|engine| self.storages.get_mut(&engine))?
81 .ok_or_else(|| {
82 Error::StorageMsg(format!(
83 "[fetch_storage_mut] storage not found for table: {table_name}"
84 ))
85 })
86 }
87}
88
89impl gluesql_core::store::AlterTable for CompositeStorage {}
90impl gluesql_core::store::Index for CompositeStorage {}
91impl gluesql_core::store::IndexMut for CompositeStorage {}
92impl Metadata for CompositeStorage {}
93impl gluesql_core::store::CustomFunction for CompositeStorage {}
94impl gluesql_core::store::CustomFunctionMut for CompositeStorage {}
95impl Planner for CompositeStorage {}