1pub mod memory;
6pub mod disk;
7pub mod aof;
8
9pub use memory::MemoryStorage;
10pub use disk::DiskStorage;
11pub use aof::AOFStorage;
12
13use async_trait::async_trait;
14use crate::{KVResult, Key, Entry, DatabaseId, PersistenceMode};
15
16#[async_trait]
18pub trait Storage: Send + Sync {
19 async fn get(&self, database_id: DatabaseId, key: &Key) -> KVResult<Option<Entry>>;
21
22 async fn set(&self, database_id: DatabaseId, key: Key, entry: Entry) -> KVResult<()>;
24
25 async fn delete(&self, database_id: DatabaseId, key: &Key) -> KVResult<bool>;
27
28 async fn exists(&self, database_id: DatabaseId, key: &Key) -> KVResult<bool>;
30
31 async fn keys(&self, database_id: DatabaseId) -> KVResult<Vec<Key>>;
33
34 async fn keys_pattern(&self, database_id: DatabaseId, pattern: &str) -> KVResult<Vec<Key>>;
36
37 async fn clear_database(&self, database_id: DatabaseId) -> KVResult<()>;
39
40 async fn get_stats(&self, database_id: DatabaseId) -> KVResult<StorageStats>;
42
43 async fn flush(&self) -> KVResult<()>;
45
46 async fn close(&self) -> KVResult<()>;
48}
49
50#[derive(Debug, Clone)]
52pub struct StorageStats {
53 pub total_keys: u64,
54 pub memory_usage: u64,
55 pub disk_usage: Option<u64>,
56 pub last_flush: Option<chrono::DateTime<chrono::Utc>>,
57}
58
59pub struct StorageFactory;
61
62impl StorageFactory {
63 pub async fn create(
68 mode: PersistenceMode,
69 data_dir: &str,
70 database_id: DatabaseId,
71 ) -> KVResult<Box<dyn Storage>> {
72 match mode {
73 PersistenceMode::Memory => {
74 Ok(Box::new(MemoryStorage::new()))
75 }
76 PersistenceMode::AOF => {
77 let aof_path = format!("{data_dir}/db_{database_id}.aof");
78 Ok(Box::new(AOFStorage::new(&aof_path).await?))
79 }
80 PersistenceMode::Full => {
81 let db_path = format!("{data_dir}/db_{database_id}");
82 Ok(Box::new(DiskStorage::new(&db_path)?))
83 }
84 PersistenceMode::Hybrid => {
85 let aof_path = format!("{data_dir}/db_{database_id}.aof");
87 Ok(Box::new(AOFStorage::new(&aof_path).await?))
88 }
89 }
90 }
91}