1use std::fmt::Debug;
2use std::hash::Hash;
3
4use serde::de::DeserializeOwned;
5use serde::Serialize;
6
7use crate::clients::{BaseClient, ClientConfig};
8use crate::db::config::DatabaseConfiguration;
9use crate::db::runtime::{RunTime, RuntTimeType};
10use crate::db::Database;
11
12#[derive(Debug)]
13pub struct QuickMemoryClient<T>
14where
15 T: Serialize + DeserializeOwned + Debug + Eq + PartialEq + Hash + Send + Sync + Clone + 'static,
16{
17 db: Database<T>,
18}
19
20impl<T> BaseClient<T> for QuickMemoryClient<T>
21where
22 T: Serialize + DeserializeOwned + Debug + Eq + PartialEq + Hash + Send + Sync + Clone + 'static,
23{
24 fn new(config: ClientConfig) -> Self
25 {
26 let _config = DatabaseConfiguration::new(
27 config.path,
28 RunTime::new(RuntTimeType::Memory).into(),
29 config.log,
30 config.log_level,
31 config.default_ttl,
32 )
33 .unwrap();
34
35 let db = Database::new(_config).unwrap();
36
37 Self { db }
38 }
39
40 fn get(&mut self, key: &str) -> anyhow::Result<Option<T>>
41 {
42 match self.db.get(key.to_string()) {
43 Ok(value) => Ok(value),
44 Err(e) => Err(e),
45 }
46 }
47
48 fn set(&mut self, key: &str, value: T) -> anyhow::Result<()>
49 {
50 match self.db.set(key, value, None) {
51 Ok(_) => Ok(()),
52 Err(e) => Err(e),
53 }
54 }
55
56 fn update(&mut self, key: &str, value: T, upsert: Option<bool>) -> anyhow::Result<()>
57 {
58 match self.db.update(key, value, None, upsert) {
59 Ok(_) => Ok(()),
60 Err(e) => Err(e),
61 }
62 }
63
64 fn delete(&mut self, key: &str) -> anyhow::Result<()>
65 {
66 match self.db.delete(key) {
67 Ok(_) => Ok(()),
68 Err(e) => Err(e),
69 }
70 }
71
72 fn exists(&mut self, key: &str) -> anyhow::Result<bool>
73 {
74 match self.db.state.lock().unwrap().entries.contains_key(key) {
75 true => Ok(true),
76 false => Ok(false),
77 }
78 }
79
80 fn keys(&mut self) -> anyhow::Result<Option<Vec<String>>>
81 {
82 let keys = self.db.state.lock().unwrap().entries.keys().cloned().collect::<Vec<String>>();
83 if !keys.is_empty() {
84 Ok(Some(keys))
85 } else {
86 Ok(None)
87 }
88 }
89
90 fn values(&mut self) -> anyhow::Result<Option<Vec<T>>>
91 {
92 let values = self.db.state.lock().unwrap().entries.values().cloned().collect::<Vec<_>>();
93
94 if !values.is_empty() {
95 let v = values.into_iter().map(|entry| entry.data).collect::<Vec<T>>();
96 Ok(Some(v))
97 } else {
98 Ok(None)
99 }
100 }
101
102 fn len(&mut self) -> anyhow::Result<usize>
103 {
104 match self.db.state.lock().unwrap().entries.len() {
105 len if len > 0 => Ok(len),
106 _ => Ok(0),
107 }
108 }
109
110 fn purge(&mut self) -> anyhow::Result<()>
111 {
112 match self.db.purge() {
113 Ok(_) => Ok(()),
114 Err(e) => Err(e),
115 }
116 }
117
118 fn get_many(&mut self, keys: &[&str]) -> anyhow::Result<Option<Vec<T>>>
119 {
120 let mut values = Vec::new();
121
122 for key in keys {
123 if let Ok(Some(v)) = self.db.get(key.to_string()) {
124 values.push(v);
125 }
126 }
127
128 if !values.is_empty() {
129 Ok(Some(values))
130 } else {
131 Ok(None)
132 }
133 }
134
135 fn set_many(&mut self, keys: &[&str], values: &[T]) -> anyhow::Result<()>
136 {
137 for (key, value) in keys.iter().zip(values.iter()) {
138 self.db.set(key, value.clone(), None)?;
139 }
140
141 Ok(())
142 }
143
144 fn delete_many(&mut self, keys: &[&str]) -> anyhow::Result<()>
145 {
146 for key in keys {
147 self.db.delete(key)?;
148 }
149
150 Ok(())
151 }
152
153 fn update_many(&mut self, keys: &[&str], values: &[T], upsert: Option<bool>) -> anyhow::Result<()>
154 {
155 for (key, value) in keys.iter().zip(values.iter()) {
156 self.db.update(key, value.clone(), None, upsert)?;
157 }
158
159 Ok(())
160 }
161}
162
163#[cfg(test)]
164mod tests
165{
166 use tempfile::tempdir;
167
168 use super::*;
169 use crate::types::HashSet;
170
171 #[test]
172 fn test_quick_client_set_get()
173 {
174 let config = ClientConfig {
175 path: Some("test_db".to_string()),
176 log: None,
177 log_level: None,
178 default_ttl: None,
179 };
180 let mut client: QuickMemoryClient<String> = QuickMemoryClient::<String>::new(config);
181
182 let key = "test_key";
183 let value = "test_value".to_string();
184
185 client.set(key, value.clone()).unwrap();
186 let retrieved_value = client.get(key).unwrap().unwrap();
187
188 assert_eq!(retrieved_value, value);
189 }
190
191 #[test]
192 fn test_quick_client_delete()
193 {
194 let tmp_dir = tempdir().expect("Failed to create tempdir");
195 let tmp_file = tmp_dir.path().join("test.qkv").to_str().unwrap().to_string();
196
197 let config = ClientConfig {
198 path: Some(tmp_file),
199 log: None,
200 log_level: None,
201 default_ttl: None,
202 };
203 let mut client = QuickMemoryClient::<String>::new(config);
204
205 let key = "test_key";
206 let value = "test_value".to_string();
207
208 client.set(key, value.clone()).unwrap();
209 client.delete(key).unwrap();
210 let retrieved_value = client.get(key).unwrap();
211
212 assert!(retrieved_value.is_none());
213 }
214
215 #[test]
216 fn test_quick_client_set_many_get_many()
217 {
218 let tmp_dir = tempdir().expect("Failed to create tempdir");
219 let tmp_file = tmp_dir.path().join("test.qkv").to_str().unwrap().to_string();
220
221 let config = ClientConfig {
222 path: Some(tmp_file),
223 log: None,
224 log_level: None,
225 default_ttl: None,
226 };
227 let mut client = QuickMemoryClient::<String>::new(config);
228
229 let keys = vec!["key1", "key2", "key3"];
230 let values = vec!["value1", "value2", "value3"]
231 .iter()
232 .map(|&s| s.to_string())
233 .collect::<Vec<String>>();
234
235 client.set_many(&keys, &values).unwrap();
236 let retrieved_values = client.get_many(&keys).unwrap().unwrap();
237
238 assert_eq!(retrieved_values, values);
239 }
240
241 #[test]
242 fn test_quick_client_exists()
243 {
244 let tmp_dir = tempdir().expect("Failed to create tempdir");
245 let tmp_file = tmp_dir.path().join("test.qkv").to_str().unwrap().to_string();
246
247 let config = ClientConfig {
248 path: Some(tmp_file),
249 log: None,
250 log_level: None,
251 default_ttl: None,
252 };
253 let mut client = QuickMemoryClient::<String>::new(config);
254
255 let key = "test_key";
256 let value = "test_value".to_string();
257
258 assert_eq!(client.exists(key).unwrap(), false);
260
261 client.set(key, value.clone()).unwrap();
263
264 assert_eq!(client.exists(key).unwrap(), true);
266 }
267
268 #[test]
269 fn test_quick_client_keys()
270 {
271 let tmp_dir = tempdir().expect("Failed to create tempdir");
272 let tmp_file = tmp_dir.path().join("test.qkv").to_str().unwrap().to_string();
273
274 let config = ClientConfig {
275 path: Some(tmp_file),
276 log: None,
277 log_level: None,
278 default_ttl: None,
279 };
280 let mut client = QuickMemoryClient::<String>::new(config);
281
282 let keys = vec!["key1", "key2", "key3"];
283 let values = vec!["value1", "value2", "value3"]
284 .iter()
285 .map(|&s| s.to_string())
286 .collect::<Vec<String>>();
287
288 client.set_many(&keys, &values).unwrap();
289
290 let retrieved_keys = client.keys().unwrap().unwrap().into_iter().collect::<HashSet<_>>();
291 let expected_keys: HashSet<_> = keys.iter().map(|&s| s.to_string()).collect();
292
293 assert_eq!(retrieved_keys, expected_keys);
294 }
295
296 #[test]
297 fn test_quick_client_values()
298 {
299 let tmp_dir = tempdir().expect("Failed to create tempdir");
300 let tmp_file = tmp_dir.path().join("test.qkv").to_str().unwrap().to_string();
301
302 let config = ClientConfig {
303 path: Some(tmp_file),
304 log: None,
305 log_level: None,
306 default_ttl: None,
307 };
308 let mut client = QuickMemoryClient::<String>::new(config);
309
310 let keys = vec!["key1", "key2", "key3"];
311 let values = vec!["value1", "value2", "value3"]
312 .iter()
313 .map(|&s| s.to_string())
314 .collect::<Vec<String>>();
315
316 client.set_many(&keys, &values).unwrap();
317
318 let retrieved_values = client.values().unwrap().unwrap().into_iter().collect::<HashSet<_>>();
319 let expected_values: HashSet<_> = values.iter().map(|s| s.to_string()).collect();
320
321 assert_eq!(retrieved_values, expected_values);
322 }
323
324 #[test]
325 fn test_quick_client_len()
326 {
327 let tmp_dir = tempdir().expect("Failed to create tempdir");
328 let tmp_file = tmp_dir.path().join("test.qkv").to_str().unwrap().to_string();
329
330 let config = ClientConfig {
331 path: Some(tmp_file),
332 log: None,
333 log_level: None,
334 default_ttl: None,
335 };
336 let mut client = QuickMemoryClient::<String>::new(config);
337
338 let keys = vec!["key1", "key2", "key3"];
339 let values = vec!["value1", "value2", "value3"]
340 .iter()
341 .map(|&s| s.to_string())
342 .collect::<Vec<String>>();
343
344 client.set_many(&keys, &values).unwrap();
345
346 let length = client.len().unwrap();
347 assert_eq!(length, 3);
348 }
349
350 #[test]
351 fn test_quick_client_purge()
352 {
353 let tmp_dir = tempdir().expect("Failed to create tempdir");
354 let tmp_file = tmp_dir.path().join("test.qkv").to_str().unwrap().to_string();
355
356 let config = ClientConfig {
357 path: Some(tmp_file),
358 log: None,
359 log_level: None,
360 default_ttl: None,
361 };
362 let mut client = QuickMemoryClient::<String>::new(config);
363
364 let key = "test_key";
365 let value = "test_value".to_string();
366
367 client.set(key, value.clone()).unwrap();
368 client.purge().unwrap();
369
370 assert_eq!(client.len().unwrap(), 0);
371 }
372
373 #[test]
374 fn test_quick_client_update_many()
375 {
376 let tmp_dir = tempdir().expect("Failed to create tempdir");
377 let tmp_file = tmp_dir.path().join("test.qkv").to_str().unwrap().to_string();
378
379 let config = ClientConfig {
380 path: Some(tmp_file),
381 log: None,
382 log_level: None,
383 default_ttl: None,
384 };
385 let mut client = QuickMemoryClient::<String>::new(config);
386
387 let keys = vec!["key1", "key2", "key3"];
388 let values = vec!["value1", "value2", "value3"]
389 .iter()
390 .map(|&s| s.to_string())
391 .collect::<Vec<String>>();
392
393 client.set_many(&keys, &values).unwrap();
394
395 let new_values = vec!["new_value1", "new_value2", "new_value3"]
396 .iter()
397 .map(|&s| s.to_string())
398 .collect::<Vec<String>>();
399
400 client.update_many(&keys, &new_values, None).unwrap();
401
402 let retrieved_values = client.values().unwrap().unwrap();
403
404 let mut sorted_retrieved_values = retrieved_values.clone();
406 let mut sorted_new_values = new_values.clone();
407 sorted_retrieved_values.sort();
408 sorted_new_values.sort();
409
410 assert_eq!(sorted_retrieved_values, sorted_new_values);
411 }
412
413 #[test]
414 fn test_quick_client_delete_many()
415 {
416 let tmp_dir = tempdir().expect("Failed to create tempdir");
417 let tmp_file = tmp_dir.path().join("test.qkv").to_str().unwrap().to_string();
418
419 let config = ClientConfig {
420 path: Some(tmp_file),
421 log: None,
422 log_level: None,
423 default_ttl: None,
424 };
425 let mut client = QuickMemoryClient::<String>::new(config);
426
427 let keys = vec!["key1", "key2", "key3"];
428 let values = vec!["value1", "value2", "value3"]
429 .iter()
430 .map(|&s| s.to_string())
431 .collect::<Vec<String>>();
432
433 client.set_many(&keys, &values).unwrap();
434
435 let keys_to_delete = vec!["key1", "key2"];
436
437 client.delete_many(&keys_to_delete).unwrap();
438
439 let remaining_keys = client.keys().unwrap().unwrap();
440 assert_eq!(remaining_keys, vec!["key3"]);
441 }
442}