Skip to main content

dbx_core/engine/
wos_variant.rs

1//! WOS (Write-Optimized Store) Variant — supports both plain and encrypted implementations
2
3use crate::error::DbxResult;
4use crate::storage::StorageBackend;
5use crate::storage::encryption::wos::EncryptedWosBackend;
6use crate::storage::memory_wos::InMemoryWosBackend;
7use crate::storage::wos::WosBackend;
8use std::sync::Arc;
9
10/// WOS variant — supports both plain and encrypted implementations.
11///
12/// Note: `StorageBackend::scan` has a generic parameter `R: RangeBounds`
13/// which prevents dyn compatibility.
14pub enum WosVariant {
15    Plain(Arc<WosBackend>),
16    Encrypted(Arc<EncryptedWosBackend>),
17    InMemory(Arc<InMemoryWosBackend>),
18}
19
20impl WosVariant {
21    pub fn insert(&self, table: &str, key: &[u8], value: &[u8]) -> DbxResult<()> {
22        match self {
23            Self::Plain(wos) => wos.as_ref().insert(table, key, value),
24            Self::Encrypted(wos) => wos.as_ref().insert(table, key, value),
25            Self::InMemory(wos) => wos.as_ref().insert(table, key, value),
26        }
27    }
28
29    pub fn insert_batch(&self, table: &str, rows: Vec<(Vec<u8>, Vec<u8>)>) -> DbxResult<()> {
30        match self {
31            Self::Plain(wos) => wos.as_ref().insert_batch(table, rows),
32            Self::Encrypted(wos) => wos.as_ref().insert_batch(table, rows),
33            Self::InMemory(wos) => wos.as_ref().insert_batch(table, rows),
34        }
35    }
36
37    pub fn get(&self, table: &str, key: &[u8]) -> DbxResult<Option<Vec<u8>>> {
38        match self {
39            Self::Plain(wos) => wos.as_ref().get(table, key),
40            Self::Encrypted(wos) => wos.as_ref().get(table, key),
41            Self::InMemory(wos) => wos.as_ref().get(table, key),
42        }
43    }
44
45    pub fn delete(&self, table: &str, key: &[u8]) -> DbxResult<bool> {
46        match self {
47            Self::Plain(wos) => wos.as_ref().delete(table, key),
48            Self::Encrypted(wos) => wos.as_ref().delete(table, key),
49            Self::InMemory(wos) => wos.as_ref().delete(table, key),
50        }
51    }
52
53    pub fn scan<R: std::ops::RangeBounds<Vec<u8>> + Clone>(
54        &self,
55        table: &str,
56        range: R,
57    ) -> DbxResult<Vec<(Vec<u8>, Vec<u8>)>> {
58        match self {
59            Self::Plain(wos) => wos.as_ref().scan(table, range),
60            Self::Encrypted(wos) => wos.as_ref().scan(table, range),
61            Self::InMemory(wos) => wos.as_ref().scan(table, range),
62        }
63    }
64
65    pub fn scan_one<R: std::ops::RangeBounds<Vec<u8>> + Clone>(
66        &self,
67        table: &str,
68        range: R,
69    ) -> DbxResult<Option<(Vec<u8>, Vec<u8>)>> {
70        match self {
71            Self::Plain(wos) => wos.as_ref().scan_one(table, range),
72            Self::Encrypted(wos) => wos.as_ref().scan_one(table, range),
73            Self::InMemory(wos) => wos.as_ref().scan_one(table, range),
74        }
75    }
76
77    pub fn flush(&self) -> DbxResult<()> {
78        match self {
79            Self::Plain(wos) => wos.as_ref().flush(),
80            Self::Encrypted(wos) => wos.as_ref().flush(),
81            Self::InMemory(wos) => wos.as_ref().flush(),
82        }
83    }
84
85    pub fn count(&self, table: &str) -> DbxResult<usize> {
86        match self {
87            Self::Plain(wos) => wos.as_ref().count(table),
88            Self::Encrypted(wos) => wos.as_ref().count(table),
89            Self::InMemory(wos) => wos.as_ref().count(table),
90        }
91    }
92
93    pub fn table_names(&self) -> DbxResult<Vec<String>> {
94        match self {
95            Self::Plain(wos) => wos.as_ref().table_names(),
96            Self::Encrypted(wos) => wos.as_ref().table_names(),
97            Self::InMemory(wos) => wos.as_ref().table_names(),
98        }
99    }
100
101    // ════════════════════════════════════════════
102    // Metadata Persistence Helpers
103    // ════════════════════════════════════════════
104
105    /// Save schema metadata (only for Plain WOS, no-op for encrypted/in-memory)
106    pub fn save_schema_metadata(
107        &self,
108        table: &str,
109        schema: &arrow::datatypes::Schema,
110    ) -> DbxResult<()> {
111        match self {
112            Self::Plain(wos) => crate::engine::metadata::save_schema(wos.as_ref(), table, schema),
113            Self::Encrypted(_) | Self::InMemory(_) => {
114                // Encrypted and in-memory WOS don't persist metadata
115                Ok(())
116            }
117        }
118    }
119
120    /// Delete schema metadata (only for Plain WOS)
121    pub fn delete_schema_metadata(&self, table: &str) -> DbxResult<()> {
122        match self {
123            Self::Plain(wos) => crate::engine::metadata::delete_schema(wos.as_ref(), table),
124            Self::Encrypted(_) | Self::InMemory(_) => Ok(()),
125        }
126    }
127
128    /// Save index metadata (only for Plain WOS)
129    pub fn save_index_metadata(
130        &self,
131        index_name: &str,
132        table: &str,
133        column: &str,
134    ) -> DbxResult<()> {
135        match self {
136            Self::Plain(wos) => {
137                crate::engine::metadata::save_index(wos.as_ref(), index_name, table, column)
138            }
139            Self::Encrypted(_) | Self::InMemory(_) => Ok(()),
140        }
141    }
142
143    /// Delete index metadata (only for Plain WOS)
144    pub fn delete_index_metadata(&self, index_name: &str) -> DbxResult<()> {
145        match self {
146            Self::Plain(wos) => crate::engine::metadata::delete_index(wos.as_ref(), index_name),
147            Self::Encrypted(_) | Self::InMemory(_) => Ok(()),
148        }
149    }
150}