rexis_rag/storage/
database.rs1#[cfg(feature = "database")]
37use super::memory::{Memory, MemoryQuery, MemoryStats, MemoryValue};
38#[cfg(feature = "database")]
39use crate::RragResult;
40#[cfg(feature = "database")]
41use async_trait::async_trait;
42
43#[cfg(feature = "database")]
44#[derive(Debug, Clone)]
46pub struct DatabaseConfig {
47 pub connection_string: String,
49
50 pub max_connections: u32,
52
53 pub connection_timeout_secs: u64,
55
56 pub enable_query_logging: bool,
58}
59
60#[cfg(feature = "database")]
61impl Default for DatabaseConfig {
62 fn default() -> Self {
63 Self {
64 connection_string: "sqlite::memory:".to_string(),
65 max_connections: 10,
66 connection_timeout_secs: 30,
67 enable_query_logging: false,
68 }
69 }
70}
71
72#[cfg(feature = "database")]
73pub struct DatabaseStorage {
78 config: DatabaseConfig,
80
81 fallback: super::in_memory::InMemoryStorage,
83}
84
85#[cfg(feature = "database")]
86impl DatabaseStorage {
87 pub async fn new() -> RragResult<Self> {
89 Self::with_config(DatabaseConfig::default()).await
90 }
91
92 pub async fn with_config(config: DatabaseConfig) -> RragResult<Self> {
96 tracing::warn!(
99 "DatabaseStorage is using in-memory fallback. Full Toasty integration pending."
100 );
101
102 Ok(Self {
103 config,
104 fallback: super::in_memory::InMemoryStorage::new(),
105 })
106 }
107}
108
109#[cfg(feature = "database")]
110#[async_trait]
111impl Memory for DatabaseStorage {
112 fn backend_name(&self) -> &str {
113 "database_fallback"
114 }
115
116 async fn set(&self, key: &str, value: MemoryValue) -> RragResult<()> {
117 self.fallback.set(key, value).await
118 }
119
120 async fn get(&self, key: &str) -> RragResult<Option<MemoryValue>> {
121 self.fallback.get(key).await
122 }
123
124 async fn delete(&self, key: &str) -> RragResult<bool> {
125 self.fallback.delete(key).await
126 }
127
128 async fn exists(&self, key: &str) -> RragResult<bool> {
129 self.fallback.exists(key).await
130 }
131
132 async fn keys(&self, query: &MemoryQuery) -> RragResult<Vec<String>> {
133 self.fallback.keys(query).await
134 }
135
136 async fn mget(&self, keys: &[String]) -> RragResult<Vec<Option<MemoryValue>>> {
137 self.fallback.mget(keys).await
138 }
139
140 async fn mset(&self, pairs: &[(String, MemoryValue)]) -> RragResult<()> {
141 self.fallback.mset(pairs).await
142 }
143
144 async fn mdelete(&self, keys: &[String]) -> RragResult<usize> {
145 self.fallback.mdelete(keys).await
146 }
147
148 async fn clear(&self, namespace: Option<&str>) -> RragResult<()> {
149 self.fallback.clear(namespace).await
150 }
151
152 async fn count(&self, namespace: Option<&str>) -> RragResult<usize> {
153 self.fallback.count(namespace).await
154 }
155
156 async fn health_check(&self) -> RragResult<bool> {
157 self.fallback.health_check().await
158 }
159
160 async fn stats(&self) -> RragResult<MemoryStats> {
161 let mut stats = self.fallback.stats().await?;
162 stats.backend_type = format!("database_fallback ({})", self.config.connection_string);
163 stats.extra.insert(
164 "note".to_string(),
165 serde_json::json!("Using in-memory fallback until Toasty is fully integrated"),
166 );
167 Ok(stats)
168 }
169}
170
171#[cfg(not(feature = "database"))]
173pub struct DatabaseStorage;
174
175#[cfg(not(feature = "database"))]
176impl DatabaseStorage {
177 pub async fn new() -> Result<Self, String> {
178 Err("Database feature not enabled. Enable with --features database".to_string())
179 }
180}