alex_db_lib/
db.rs

1use crate::{
2    config::Config,
3    error::Error,
4    index::Index,
5    stat_record::StatRecord,
6    value_record::{
7        Value, ValueAppend, ValueDecrement, ValueIncrement, ValuePopBack, ValuePopFront, ValuePost,
8        ValuePrepend, ValuePut, ValueRecord, ValueResponse,
9    },
10    Result,
11};
12use chrono::{Duration, Utc};
13use lz4_flex::{compress_prepend_size, decompress_size_prepended};
14use serde::{Deserialize, Serialize};
15use std::{collections::HashMap, fs, path::Path, sync::RwLock};
16use uuid::Uuid;
17
18pub const API_KEYS_FILE: &str = "api_keys.sec";
19pub const CREATED_AT_INDEX_FILE: &str = "created_at.idx";
20pub const DELETE_AT_INDEX_FILE: &str = "delete_at.idx";
21pub const DATABASE_FILE: &str = "values.db";
22pub const KEY_INDEX_FILE: &str = "key.idx";
23pub const UPDATED_AT_INDEX_FILE: &str = "updated_at.idx";
24
25#[derive(Debug, Deserialize, Serialize)]
26pub struct Db {
27    api_keys: RwLock<Vec<Uuid>>,
28    pub config: Config,
29    pub indexes: Index,
30    pub stats: RwLock<StatRecord>,
31    pub values: RwLock<HashMap<Uuid, ValueRecord>>,
32}
33
34impl Db {
35    /// Creates new DB.
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// use alex_db_lib::{config::Config, db::Db};
41    ///
42    /// let config = Config::default();
43    /// let db = Db::new(config);
44    ///
45    /// assert_eq!(0, db.values.read().unwrap().len());
46    /// ```
47    pub fn new(config: Config) -> Self {
48        Self {
49            api_keys: RwLock::new(vec![]),
50            config,
51            indexes: Index::default(),
52            stats: RwLock::new(StatRecord::default()),
53            values: RwLock::new(HashMap::new()),
54        }
55    }
56
57    pub fn api_key_exists(&self, api_key: Uuid) -> Result<bool> {
58        let api_keys = self.api_keys.read().unwrap();
59
60        let result = api_keys.contains(&api_key);
61
62        Ok(result)
63    }
64
65    pub fn api_key_init(&self) -> Result<Option<Uuid>> {
66        let mut api_keys = self.api_keys.write().unwrap();
67
68        if api_keys.is_empty() {
69            let api_key = Uuid::new_v4();
70            api_keys.append(&mut vec![api_key]);
71
72            return Ok(Some(api_key));
73        }
74
75        Ok(None)
76    }
77
78    pub fn gc(&self) -> Result<()> {
79        let delete_at_index = self.indexes.delete_at.read().unwrap();
80        let now = Utc::now();
81        let mut ids = vec![];
82
83        for (key, value) in delete_at_index.iter() {
84            if now.timestamp_nanos() > *key {
85                ids.append(&mut vec![*value]);
86            }
87        }
88
89        drop(delete_at_index);
90
91        for id in ids {
92            self.try_delete_by_id(id)?;
93        }
94
95        Ok(())
96    }
97
98    pub fn get_stats(&self) -> Result<StatRecord> {
99        let stats = self.stats.read().unwrap().to_owned();
100
101        Ok(stats)
102    }
103
104    pub fn restore(&mut self) -> Result<()> {
105        if let Some(data_dir) = &self.config.data_dir {
106            let api_keys_file_path = format!("{data_dir}/{API_KEYS_FILE}");
107            if Path::new(&api_keys_file_path).exists() {
108                let compressed = fs::read(api_keys_file_path)?;
109                let uncompressed = decompress_size_prepended(&compressed)?;
110                let serialized = String::from_utf8(uncompressed)?;
111                self.api_keys = serde_json::from_str(&serialized)?;
112            }
113
114            let created_at_index_file_path = format!("{data_dir}/{CREATED_AT_INDEX_FILE}");
115            if Path::new(&created_at_index_file_path).exists() {
116                let compressed = fs::read(created_at_index_file_path)?;
117                let uncompressed = decompress_size_prepended(&compressed)?;
118                let serialized = String::from_utf8(uncompressed)?;
119                self.indexes.created_at = serde_json::from_str(&serialized)?;
120            }
121
122            let delete_at_index_file_path = format!("{data_dir}/{DELETE_AT_INDEX_FILE}");
123            if Path::new(&delete_at_index_file_path).exists() {
124                let compressed = fs::read(delete_at_index_file_path)?;
125                let uncompressed = decompress_size_prepended(&compressed)?;
126                let serialized = String::from_utf8(uncompressed)?;
127                self.indexes.delete_at = serde_json::from_str(&serialized)?;
128            }
129
130            let key_index_file_path = format!("{data_dir}/{KEY_INDEX_FILE}");
131            if Path::new(&key_index_file_path).exists() {
132                let compressed = fs::read(key_index_file_path)?;
133                let uncompressed = decompress_size_prepended(&compressed)?;
134                let serialized = String::from_utf8(uncompressed)?;
135                self.indexes.key = serde_json::from_str(&serialized)?;
136            }
137
138            let updated_at_index_file_path = format!("{data_dir}/{UPDATED_AT_INDEX_FILE}");
139            if Path::new(&updated_at_index_file_path).exists() {
140                let compressed = fs::read(updated_at_index_file_path)?;
141                let uncompressed = decompress_size_prepended(&compressed)?;
142                let serialized = String::from_utf8(uncompressed)?;
143                self.indexes.updated_at = serde_json::from_str(&serialized)?;
144            }
145
146            let values_file_path = format!("{data_dir}/{DATABASE_FILE}");
147            if Path::new(&values_file_path).exists() {
148                let compressed = fs::read(values_file_path)?;
149                let uncompressed = decompress_size_prepended(&compressed)?;
150                let serialized = String::from_utf8(uncompressed)?;
151                self.values = serde_json::from_str(&serialized)?;
152            }
153        }
154
155        Ok(())
156    }
157
158    pub fn save(&self) -> Result<()> {
159        if let Some(data_dir) = &self.config.data_dir {
160            let mut stats = self.stats.write().unwrap();
161
162            if stats.can_save(
163                self.config.save_triggered_after_ms,
164                self.config.save_triggered_by_threshold,
165            ) {
166                let api_keys = self.api_keys.read().unwrap().to_owned();
167                let api_keys_file_path = format!("{data_dir}/{API_KEYS_FILE}");
168                let serialized = serde_json::to_vec(&*api_keys)?;
169                let compressed = compress_prepend_size(&serialized);
170                fs::write(api_keys_file_path, compressed)?;
171
172                let created_at_index = self.indexes.created_at.read().unwrap();
173                let created_at_index_file_path = format!("{data_dir}/{CREATED_AT_INDEX_FILE}");
174                let serialized = serde_json::to_vec(&*created_at_index)?;
175                let compressed = compress_prepend_size(&serialized);
176                fs::write(created_at_index_file_path, compressed)?;
177
178                let delete_at_index = self.indexes.delete_at.read().unwrap();
179                let delete_at_index_file_path = format!("{data_dir}/{DELETE_AT_INDEX_FILE}");
180                let serialized = serde_json::to_vec(&*delete_at_index)?;
181                let compressed = compress_prepend_size(&serialized);
182                fs::write(delete_at_index_file_path, compressed)?;
183
184                let key_index = self.indexes.key.read().unwrap();
185                let key_index_file_path = format!("{data_dir}/{KEY_INDEX_FILE}");
186                let serialized = serde_json::to_vec(&*key_index)?;
187                let compressed = compress_prepend_size(&serialized);
188                fs::write(key_index_file_path, compressed)?;
189
190                let updated_at_index = self.indexes.updated_at.read().unwrap();
191                let updated_at_index_file_path = format!("{data_dir}/{UPDATED_AT_INDEX_FILE}");
192                let serialized = serde_json::to_vec(&*updated_at_index)?;
193                let compressed = compress_prepend_size(&serialized);
194                fs::write(updated_at_index_file_path, compressed)?;
195
196                let values = self.values.read().unwrap();
197                let values_file_path = format!("{data_dir}/{DATABASE_FILE}");
198                let serialized = serde_json::to_vec(&*values)?;
199                let compressed = compress_prepend_size(&serialized);
200                fs::write(values_file_path, compressed)?;
201
202                stats.update_saved_writes();
203            }
204        }
205
206        Ok(())
207    }
208
209    /// Returns a list of records from the database.
210    ///
211    /// # Examples
212    ///
213    /// ```
214    /// use alex_db_lib::{config::Config, db::{Db, Direction, Sort}, value_record::{Value, ValuePost}};
215    ///
216    /// let config = Config::default();
217    /// let mut db = Db::new(config);
218    ///
219    /// assert_eq!(0, db.stats.read().unwrap().reads);
220    ///
221    /// let value_responses = db.list(Direction::Asc, None, None, Sort::CreatedAt).unwrap();
222    ///
223    /// assert_eq!(0, value_responses.len());
224    /// assert_eq!(0, db.stats.read().unwrap().reads);
225    ///
226    /// let key = "test_key".to_string();
227    /// let value = Value::Boolean(true);
228    /// let value_post = ValuePost { key: key.clone(), ttl: None, value: value.clone()};
229    /// db.try_create(value_post);
230    /// let value_responses = db.list(Direction::Asc, None, None, Sort::CreatedAt).unwrap();
231    ///
232    /// assert_eq!(1, value_responses.len());
233    /// assert_eq!(1, db.stats.read().unwrap().reads);
234    /// ```
235    pub fn list(
236        &self,
237        direction: Direction,
238        limit: Option<usize>,
239        page: Option<usize>,
240        sort: Sort,
241    ) -> Result<Vec<ValueResponse>> {
242        let mut stats = self.stats.write().unwrap();
243        stats.inc_requests();
244
245        let values = self.values.read().unwrap();
246        let mut result = vec![];
247        let mut ids = vec![];
248
249        match sort {
250            Sort::CreatedAt => {
251                let created_at_index = self.indexes.created_at.read().unwrap();
252
253                match direction {
254                    Direction::Asc => {
255                        for (_key, value) in created_at_index.iter() {
256                            ids.append(&mut vec![*value]);
257                        }
258                    }
259                    Direction::Desc => {
260                        for (_key, value) in created_at_index.iter().rev() {
261                            ids.append(&mut vec![*value]);
262                        }
263                    }
264                }
265            }
266            Sort::DeleteAt => {
267                let delete_at_index = self.indexes.delete_at.read().unwrap();
268
269                match direction {
270                    Direction::Asc => {
271                        for (_key, value) in delete_at_index.iter() {
272                            ids.append(&mut vec![*value]);
273                        }
274                    }
275                    Direction::Desc => {
276                        for (_key, value) in delete_at_index.iter().rev() {
277                            ids.append(&mut vec![*value]);
278                        }
279                    }
280                }
281            }
282            Sort::Key => {
283                let key_index = self.indexes.key.read().unwrap();
284
285                match direction {
286                    Direction::Asc => {
287                        for (_key, value) in key_index.iter() {
288                            ids.append(&mut vec![*value]);
289                        }
290                    }
291                    Direction::Desc => {
292                        for (_key, value) in key_index.iter().rev() {
293                            ids.append(&mut vec![*value]);
294                        }
295                    }
296                }
297            }
298            Sort::UpdatedAt => {
299                let updated_at_index = self.indexes.updated_at.read().unwrap();
300
301                match direction {
302                    Direction::Asc => {
303                        for (_key, value) in updated_at_index.iter() {
304                            ids.append(&mut vec![*value]);
305                        }
306                    }
307                    Direction::Desc => {
308                        for (_key, value) in updated_at_index.iter().rev() {
309                            ids.append(&mut vec![*value]);
310                        }
311                    }
312                }
313            }
314        }
315
316        let limit = limit.unwrap_or(100);
317        let page = page.unwrap_or(1);
318
319        let skip = (page - 1) * limit;
320
321        ids = ids
322            .into_iter()
323            .skip(skip)
324            .take(limit)
325            .collect::<Vec<Uuid>>();
326
327        for id in ids {
328            let value = values.get(&id).cloned().unwrap();
329            result.append(&mut vec![value.into()]);
330            stats.inc_reads();
331        }
332
333        Ok(result)
334    }
335
336    /// Tries to append a value to an existing record in the database using the specified key.
337    ///
338    /// # Examples
339    ///
340    /// ```
341    /// use alex_db_lib::{config::Config, db::Db, value_record::{Value, ValueAppend, ValuePost}};
342    /// use std::collections::VecDeque;
343    ///
344    /// let config = Config::default();
345    /// let mut db = Db::new(config);
346    ///
347    /// assert_eq!(0, db.stats.read().unwrap().writes);
348    ///
349    /// let key = "test_key".to_string();
350    /// let value1 = Value::String("test_value".to_string());
351    /// let value1_array = Value::Array(VecDeque::from([value1.clone()]));
352    /// let value_post = ValuePost { key: key.clone(), ttl: None, value: value1_array.clone()};
353    /// let value_response = db.try_create(value_post).unwrap().unwrap();
354    ///
355    /// assert_eq!(value_response.key, key);
356    /// assert_eq!(value_response.value, value1_array);
357    /// assert_eq!(1, db.stats.read().unwrap().writes);
358    ///
359    /// let value2 = Value::Integer(100);
360    /// let value2_array = Value::Array(VecDeque::from([value2.clone()]));
361    /// let value_append = ValueAppend { append: value2_array.clone()};
362    /// let value_response = db.try_append(&key, value_append).unwrap().unwrap();
363    ///
364    /// assert_eq!(value_response.key, key);
365    /// assert_eq!(value_response.value, Value::Array(VecDeque::from([value1, value2])));
366    /// assert_eq!(2, db.stats.read().unwrap().writes);
367    /// ```
368    pub fn try_append(
369        &self,
370        key: &str,
371        value_append: ValueAppend,
372    ) -> Result<Option<ValueResponse>> {
373        let mut stats = self.stats.write().unwrap();
374        stats.inc_requests();
375
376        let key_index = self.indexes.key.write().unwrap();
377        let id = *key_index.get(key).unwrap();
378
379        let mut values = self.values.write().unwrap();
380        let original_value = values.get(&id).ok_or(Error::NotFound)?.clone();
381
382        let value = match (original_value.value, value_append.append) {
383            (Value::Array(original_value_vec), Value::Array(mut value_append_vec)) => {
384                let mut new_value = original_value_vec;
385                new_value.append(&mut value_append_vec);
386
387                Value::Array(new_value)
388            }
389            _ => return Ok(None),
390        };
391
392        let now = Utc::now();
393        let value_record = ValueRecord::new(
394            id,
395            &original_value.key,
396            &value,
397            original_value.created_at,
398            original_value.delete_at,
399            now,
400        );
401        values.insert(id, value_record);
402        let result = values.get(&id).cloned();
403
404        match result {
405            None => Ok(None),
406            Some(result) => {
407                stats.inc_writes();
408
409                let mut updated_at_index = self.indexes.updated_at.write().unwrap();
410                updated_at_index.remove(&original_value.updated_at.timestamp_nanos());
411                updated_at_index.insert(result.updated_at.timestamp_nanos(), id);
412
413                Ok(Some(result.into()))
414            }
415        }
416    }
417
418    /// Tries to create a new record containing a value in the database.
419    ///
420    /// # Examples
421    ///
422    /// ```
423    /// use alex_db_lib::{config::Config, db::Db, value_record::{Value, ValuePost}};
424    ///
425    /// let config = Config::default();
426    /// let mut db = Db::new(config);
427    ///
428    /// assert_eq!(0, db.indexes.created_at.read().unwrap().len());
429    /// assert_eq!(0, db.indexes.delete_at.read().unwrap().len());
430    /// assert_eq!(0, db.indexes.key.read().unwrap().len());
431    /// assert_eq!(0, db.indexes.updated_at.read().unwrap().len());
432    /// assert_eq!(0, db.stats.read().unwrap().writes);
433    /// assert_eq!(0, db.values.read().unwrap().len());
434    ///
435    /// let key = "test_key1".to_string();
436    /// let value = Value::String("test_value".to_string());
437    /// let value_post = ValuePost { key: key.clone(), ttl: None, value: value.clone()};
438    /// let value_response = db.try_create(value_post).unwrap().unwrap();
439    ///
440    /// assert_eq!(value_response.key, key);
441    /// assert_eq!(value_response.value, value);
442    /// assert_eq!(1, db.indexes.created_at.read().unwrap().len());
443    /// assert_eq!(0, db.indexes.delete_at.read().unwrap().len());
444    /// assert_eq!(1, db.indexes.key.read().unwrap().len());
445    /// assert_eq!(1, db.indexes.updated_at.read().unwrap().len());
446    /// assert_eq!(1, db.stats.read().unwrap().writes);
447    /// assert_eq!(1, db.values.read().unwrap().len());
448    ///
449    /// let key = "test_key2".to_string();
450    /// let value = Value::Integer(10);
451    /// let value_post = ValuePost { key: key.clone(), ttl: Some(100), value: value.clone()};
452    /// let value_response = db.try_create(value_post).unwrap().unwrap();
453    ///
454    /// assert_eq!(value_response.key, key);
455    /// assert_eq!(value_response.value, value);
456    /// assert_eq!(2, db.indexes.created_at.read().unwrap().len());
457    /// assert_eq!(1, db.indexes.delete_at.read().unwrap().len());
458    /// assert_eq!(2, db.indexes.key.read().unwrap().len());
459    /// assert_eq!(2, db.indexes.updated_at.read().unwrap().len());
460    /// assert_eq!(2, db.stats.read().unwrap().writes);
461    /// assert_eq!(2, db.values.read().unwrap().len());
462    /// ```
463    pub fn try_create(&self, value_post: ValuePost) -> Result<Option<ValueResponse>> {
464        let mut stats = self.stats.write().unwrap();
465        stats.inc_requests();
466
467        let mut values = self.values.write().unwrap();
468        let id = Uuid::new_v4();
469        let now = Utc::now();
470        let delete_at = value_post.ttl.map(|ttl| now + Duration::seconds(ttl));
471        let value_record =
472            ValueRecord::new(id, &value_post.key, &value_post.value, now, delete_at, now);
473        values.insert(id, value_record);
474        let result = values.get(&id).cloned();
475
476        match result {
477            None => Ok(None),
478            Some(result) => {
479                stats.inc_writes();
480
481                let mut created_at_index = self.indexes.created_at.write().unwrap();
482                created_at_index.insert(result.created_at.timestamp_nanos(), id);
483
484                if let Some(delete_at) = delete_at {
485                    let mut delete_at_index = self.indexes.delete_at.write().unwrap();
486                    delete_at_index.insert(delete_at.timestamp_nanos(), id);
487                }
488
489                let mut key_index = self.indexes.key.write().unwrap();
490                key_index.insert(value_post.key, id);
491
492                let mut updated_at_index = self.indexes.updated_at.write().unwrap();
493                updated_at_index.insert(result.updated_at.timestamp_nanos(), id);
494
495                Ok(Some(result.into()))
496            }
497        }
498    }
499
500    /// Tries to decrement a value of an existing record in the database using the specified key.
501    ///
502    /// # Examples
503    ///
504    /// ```
505    /// use alex_db_lib::{config::Config, db::Db, value_record::{Value, ValueDecrement, ValuePost}};
506    /// use std::collections::VecDeque;
507    ///
508    /// let config = Config::default();
509    /// let mut db = Db::new(config);
510    ///
511    /// assert_eq!(0, db.stats.read().unwrap().writes);
512    ///
513    /// let key = "test_key".to_string();
514    /// let value = Value::Integer(5000);
515    /// let value_post = ValuePost { key: key.clone(), ttl: None, value: value.clone()};
516    /// let value_response = db.try_create(value_post).unwrap().unwrap();
517    ///
518    /// assert_eq!(value_response.key, key);
519    /// assert_eq!(value_response.value, value);
520    /// assert_eq!(1, db.stats.read().unwrap().writes);
521    ///
522    /// let value_decrement = ValueDecrement { decrement: None };
523    /// let value_response = db.try_decrement(&key, value_decrement).unwrap().unwrap();
524    ///
525    /// assert_eq!(value_response.key, key);
526    /// assert_eq!(value_response.value, Value::Integer(4999));
527    /// assert_eq!(2, db.stats.read().unwrap().writes);
528    ///
529    /// let value_decrement = ValueDecrement { decrement: Some(10) };
530    /// let value_response = db.try_decrement(&key, value_decrement).unwrap().unwrap();
531    ///
532    /// assert_eq!(value_response.key, key);
533    /// assert_eq!(value_response.value, Value::Integer(4989));
534    /// assert_eq!(3, db.stats.read().unwrap().writes);
535    /// ```
536    pub fn try_decrement(
537        &self,
538        key: &str,
539        value_decrement: ValueDecrement,
540    ) -> Result<Option<ValueResponse>> {
541        let mut stats = self.stats.write().unwrap();
542        stats.inc_requests();
543
544        let key_index = self.indexes.key.write().unwrap();
545        let id = *key_index.get(key).unwrap();
546
547        let mut values = self.values.write().unwrap();
548        let original_value = values.get(&id).ok_or(Error::NotFound)?.clone();
549
550        let value = match original_value.value {
551            Value::Integer(original_value_integer) => match value_decrement.decrement {
552                None => Value::Integer(original_value_integer.saturating_sub(1)),
553                Some(decrement) => {
554                    if let Some(abs) = decrement.checked_abs() {
555                        Value::Integer(original_value_integer.saturating_sub(abs))
556                    } else {
557                        Value::Integer(original_value_integer)
558                    }
559                }
560            },
561            _ => return Ok(None),
562        };
563
564        let now = Utc::now();
565        let value_record = ValueRecord::new(
566            id,
567            &original_value.key,
568            &value,
569            original_value.created_at,
570            original_value.delete_at,
571            now,
572        );
573        values.insert(id, value_record);
574        let result = values.get(&id).cloned();
575
576        match result {
577            None => Ok(None),
578            Some(result) => {
579                stats.inc_writes();
580
581                let mut updated_at_index = self.indexes.updated_at.write().unwrap();
582                updated_at_index.remove(&original_value.updated_at.timestamp_nanos());
583                updated_at_index.insert(result.updated_at.timestamp_nanos(), id);
584
585                Ok(Some(result.into()))
586            }
587        }
588    }
589
590    /// Tries to delete an existing record from the database using the specified key.
591    ///
592    /// # Examples
593    ///
594    /// ```
595    /// use alex_db_lib::{config::Config, db::Db, value_record::{Value, ValuePost}};
596    /// use std::collections::VecDeque;
597    ///
598    /// let config = Config::default();
599    /// let mut db = Db::new(config);
600    ///
601    /// assert_eq!(0, db.stats.read().unwrap().writes);
602    ///
603    /// let key = "test_key".to_string();
604    /// let value = Value::Boolean(false);
605    /// let value_post = ValuePost { key: key.clone(), ttl: None, value: value.clone()};
606    /// let value_response = db.try_create(value_post).unwrap().unwrap();
607    ///
608    /// assert_eq!(value_response.key, key);
609    /// assert_eq!(value_response.value, value);
610    /// assert_eq!(1, db.stats.read().unwrap().writes);
611    ///
612    /// let value_response = db.try_delete(&key).unwrap().unwrap();
613    ///
614    /// assert_eq!(value_response.key, key);
615    /// assert_eq!(value_response.value, value);
616    /// assert_eq!(2, db.stats.read().unwrap().writes);
617    ///
618    /// let value_response = db.try_read(&key).unwrap();
619    ///
620    /// assert!(value_response.is_none());
621    /// ```
622    pub fn try_delete(&self, key: &str) -> Result<Option<ValueResponse>> {
623        let key_index = self.indexes.key.read().unwrap();
624        let id = *key_index.get(key).unwrap();
625        drop(key_index);
626
627        self.try_delete_by_id(id)
628    }
629
630    fn try_delete_by_id(&self, id: Uuid) -> Result<Option<ValueResponse>> {
631        let mut stats = self.stats.write().unwrap();
632        stats.inc_requests();
633
634        let mut values = self.values.write().unwrap();
635        let result = values.remove(&id);
636
637        match result {
638            None => Ok(None),
639            Some(result) => {
640                stats.inc_writes();
641
642                let mut created_at_index = self.indexes.created_at.write().unwrap();
643                created_at_index.remove(&result.created_at.timestamp_nanos());
644
645                if let Some(delete_at) = result.delete_at {
646                    let mut delete_at_index = self.indexes.delete_at.write().unwrap();
647                    delete_at_index.remove(&delete_at.timestamp_nanos());
648                }
649
650                let mut key_index = self.indexes.key.write().unwrap();
651                key_index.remove(&result.key);
652
653                let mut updated_at_index = self.indexes.updated_at.write().unwrap();
654                updated_at_index.remove(&result.updated_at.timestamp_nanos());
655
656                Ok(Some(result.into()))
657            }
658        }
659    }
660
661    /// Tries to increment a value of an existing record in the database using the specified key.
662    ///
663    /// # Examples
664    ///
665    /// ```
666    /// use alex_db_lib::{config::Config, db::Db, value_record::{Value, ValuePost, ValueIncrement}};
667    /// use std::collections::VecDeque;
668    ///
669    /// let config = Config::default();
670    /// let mut db = Db::new(config);
671    ///
672    /// assert_eq!(0, db.stats.read().unwrap().writes);
673    ///
674    /// let key = "test_key".to_string();
675    /// let value = Value::Integer(1000);
676    /// let value_post = ValuePost { key: key.clone(), ttl: None, value: value.clone()};
677    /// let value_response = db.try_create(value_post).unwrap().unwrap();
678    ///
679    /// assert_eq!(value_response.key, key);
680    /// assert_eq!(value_response.value, value);
681    /// assert_eq!(1, db.stats.read().unwrap().writes);
682    ///
683    /// let value_increment = ValueIncrement { increment: None };
684    /// let value_response = db.try_increment(&key, value_increment).unwrap().unwrap();
685    ///
686    /// assert_eq!(value_response.key, key);
687    /// assert_eq!(value_response.value, Value::Integer(1001));
688    /// assert_eq!(2, db.stats.read().unwrap().writes);
689    ///
690    /// let value_increment = ValueIncrement { increment: Some(10) };
691    /// let value_response = db.try_increment(&key, value_increment).unwrap().unwrap();
692    ///
693    /// assert_eq!(value_response.key, key);
694    /// assert_eq!(value_response.value, Value::Integer(1011));
695    /// assert_eq!(3, db.stats.read().unwrap().writes);
696    /// ```
697    pub fn try_increment(
698        &self,
699        key: &str,
700        value_increment: ValueIncrement,
701    ) -> Result<Option<ValueResponse>> {
702        let mut stats = self.stats.write().unwrap();
703        stats.inc_requests();
704
705        let key_index = self.indexes.key.write().unwrap();
706        let id = *key_index.get(key).unwrap();
707
708        let mut values = self.values.write().unwrap();
709        let original_value = values.get(&id).ok_or(Error::NotFound)?.clone();
710
711        let value = match original_value.value {
712            Value::Integer(original_value_integer) => match value_increment.increment {
713                None => Value::Integer(original_value_integer.saturating_add(1)),
714                Some(increment) => {
715                    if let Some(abs) = increment.checked_abs() {
716                        Value::Integer(original_value_integer.saturating_add(abs))
717                    } else {
718                        Value::Integer(original_value_integer)
719                    }
720                }
721            },
722            _ => return Ok(None),
723        };
724
725        let now = Utc::now();
726        let value_record = ValueRecord::new(
727            id,
728            &original_value.key,
729            &value,
730            original_value.created_at,
731            original_value.delete_at,
732            now,
733        );
734        values.insert(id, value_record);
735        let result = values.get(&id).cloned();
736
737        match result {
738            None => Ok(None),
739            Some(result) => {
740                stats.inc_writes();
741
742                let mut updated_at_index = self.indexes.updated_at.write().unwrap();
743                updated_at_index.remove(&original_value.updated_at.timestamp_nanos());
744                updated_at_index.insert(result.updated_at.timestamp_nanos(), id);
745
746                Ok(Some(result.into()))
747            }
748        }
749    }
750
751    /// Tries to pop a value from the back of an existing record in the database using the specified key.
752    ///
753    /// # Examples
754    ///
755    /// ```
756    /// use alex_db_lib::{config::Config, db::Db, value_record::{Value, ValuePopBack, ValuePost}};
757    /// use std::collections::VecDeque;
758    ///
759    /// let config = Config::default();
760    /// let mut db = Db::new(config);
761    ///
762    /// assert_eq!(0, db.stats.read().unwrap().writes);
763    ///
764    /// let key = "test_key".to_string();
765    /// let value1 = Value::String("test_value1".to_string());
766    /// let value2 = Value::String("test_value2".to_string());
767    /// let value3 = Value::Integer(100);
768    /// let value4 = Value::Integer(1000);
769    /// let value_array = Value::Array(VecDeque::from([value1.clone(), value2.clone(), value3.clone(), value4.clone()]));
770    /// let value_post = ValuePost { key: key.clone(), ttl: None, value: value_array.clone() };
771    /// let value_response = db.try_create(value_post).unwrap().unwrap();
772    ///
773    /// assert_eq!(value_response.key, key);
774    /// assert_eq!(value_response.value, value_array);
775    /// assert_eq!(1, db.stats.read().unwrap().writes);
776    ///
777    /// let value_pop_back = ValuePopBack { pop_back: None };
778    /// let value_response = db.try_pop_back(&key, value_pop_back).unwrap().unwrap();
779    ///
780    /// assert_eq!(value_response, vec![value4]);
781    /// assert_eq!(2, db.stats.read().unwrap().writes);
782    ///
783    /// let value_pop_back = ValuePopBack { pop_back: Some(2) };
784    /// let value_response = db.try_pop_back(&key, value_pop_back).unwrap().unwrap();
785    ///
786    /// assert_eq!(value_response, vec![value3, value2]);
787    /// assert_eq!(3, db.stats.read().unwrap().writes);
788    /// ```
789    pub fn try_pop_back(
790        &self,
791        key: &str,
792        value_pop_back: ValuePopBack,
793    ) -> Result<Option<Vec<Value>>> {
794        let mut stats = self.stats.write().unwrap();
795        stats.inc_requests();
796
797        let key_index = self.indexes.key.write().unwrap();
798        let id = *key_index.get(key).unwrap();
799
800        let mut values = self.values.write().unwrap();
801        let original_value = values.get(&id).ok_or(Error::NotFound)?.clone();
802
803        let mut return_values = vec![];
804        let value = match original_value.value {
805            Value::Array(original_value_vec) => match value_pop_back.pop_back {
806                None => {
807                    let mut new_value = original_value_vec;
808                    let pop_value = new_value.pop_back();
809                    if let Some(pop_value) = pop_value {
810                        return_values.append(&mut vec![pop_value]);
811                    }
812
813                    Value::Array(new_value)
814                }
815                Some(mut pop_back) => {
816                    if pop_back > original_value_vec.len() {
817                        pop_back = original_value_vec.len();
818                    }
819
820                    let mut new_value = original_value_vec;
821
822                    for _i in 1..=pop_back {
823                        let pop_value = new_value.pop_back();
824                        if let Some(pop_value) = pop_value {
825                            return_values.append(&mut vec![pop_value]);
826                        }
827                    }
828
829                    Value::Array(new_value)
830                }
831            },
832            _ => return Ok(None),
833        };
834
835        let now = Utc::now();
836        let value_record = ValueRecord::new(
837            id,
838            &original_value.key,
839            &value,
840            original_value.created_at,
841            original_value.delete_at,
842            now,
843        );
844        values.insert(id, value_record);
845        let result = values.get(&id).cloned();
846
847        match result {
848            None => Ok(None),
849            Some(result) => {
850                stats.inc_writes();
851
852                let mut updated_at_index = self.indexes.updated_at.write().unwrap();
853                updated_at_index.remove(&original_value.updated_at.timestamp_nanos());
854                updated_at_index.insert(result.updated_at.timestamp_nanos(), id);
855
856                Ok(Some(return_values))
857            }
858        }
859    }
860
861    /// Tries to pop a value from the front of an existing record in the database using the specified key.
862    ///
863    /// # Examples
864    ///
865    /// ```
866    /// use alex_db_lib::{config::Config, db::Db, value_record::{Value, ValuePopFront, ValuePost}};
867    /// use std::collections::VecDeque;
868    ///
869    /// let config = Config::default();
870    /// let mut db = Db::new(config);
871    ///
872    /// assert_eq!(0, db.stats.read().unwrap().writes);
873    ///
874    /// let key = "test_key".to_string();
875    /// let value1 = Value::String("test_value1".to_string());
876    /// let value2 = Value::String("test_value2".to_string());
877    /// let value3 = Value::Integer(100);
878    /// let value4 = Value::Integer(1000);
879    /// let value_array = Value::Array(VecDeque::from([value1.clone(), value2.clone(), value3.clone(), value4.clone()]));
880    /// let value_post = ValuePost { key: key.clone(), ttl: None, value: value_array.clone() };
881    /// let value_response = db.try_create(value_post).unwrap().unwrap();
882    ///
883    /// assert_eq!(value_response.key, key);
884    /// assert_eq!(value_response.value, value_array);
885    /// assert_eq!(1, db.stats.read().unwrap().writes);
886    ///
887    /// let value_pop_front = ValuePopFront { pop_front: None };
888    /// let value_response = db.try_pop_front(&key, value_pop_front).unwrap().unwrap();
889    ///
890    /// assert_eq!(value_response, vec![value1]);
891    /// assert_eq!(2, db.stats.read().unwrap().writes);
892    ///
893    /// let value_pop_front = ValuePopFront { pop_front: Some(2) };
894    /// let value_response = db.try_pop_front(&key, value_pop_front).unwrap().unwrap();
895    ///
896    /// assert_eq!(value_response, vec![value2, value3]);
897    /// assert_eq!(3, db.stats.read().unwrap().writes);
898    /// ```
899    pub fn try_pop_front(
900        &self,
901        key: &str,
902        value_pop_front: ValuePopFront,
903    ) -> Result<Option<Vec<Value>>> {
904        let mut stats = self.stats.write().unwrap();
905        stats.inc_requests();
906
907        let key_index = self.indexes.key.write().unwrap();
908        let id = *key_index.get(key).unwrap();
909
910        let mut values = self.values.write().unwrap();
911        let original_value = values.get(&id).ok_or(Error::NotFound)?.clone();
912
913        let mut return_values = vec![];
914        let value = match original_value.value {
915            Value::Array(original_value_vec) => match value_pop_front.pop_front {
916                None => {
917                    let mut new_value = original_value_vec;
918                    let pop_value = new_value.pop_front();
919                    if let Some(pop_value) = pop_value {
920                        return_values.append(&mut vec![pop_value]);
921                    }
922
923                    Value::Array(new_value)
924                }
925                Some(mut pop_front) => {
926                    if pop_front > original_value_vec.len() {
927                        pop_front = original_value_vec.len();
928                    }
929                    let mut new_value = original_value_vec;
930
931                    for _i in 1..=pop_front {
932                        let pop_value = new_value.pop_front();
933                        if let Some(pop_value) = pop_value {
934                            return_values.append(&mut vec![pop_value]);
935                        }
936                    }
937
938                    Value::Array(new_value)
939                }
940            },
941            _ => return Ok(None),
942        };
943
944        let now = Utc::now();
945        let value_record = ValueRecord::new(
946            id,
947            &original_value.key,
948            &value,
949            original_value.created_at,
950            original_value.delete_at,
951            now,
952        );
953        values.insert(id, value_record);
954        let result = values.get(&id).cloned();
955
956        match result {
957            None => Ok(None),
958            Some(result) => {
959                stats.inc_writes();
960
961                let mut updated_at_index = self.indexes.updated_at.write().unwrap();
962                updated_at_index.remove(&original_value.updated_at.timestamp_nanos());
963                updated_at_index.insert(result.updated_at.timestamp_nanos(), id);
964
965                Ok(Some(return_values))
966            }
967        }
968    }
969
970    /// Tries to prepend a value to an existing record in the database using the specified key.
971    ///
972    /// # Examples
973    ///
974    /// ```
975    /// use alex_db_lib::{config::Config, db::Db, value_record::{Value, ValuePost, ValuePrepend}};
976    /// use std::collections::VecDeque;
977    ///
978    /// let config = Config::default();
979    /// let mut db = Db::new(config);
980    ///
981    /// assert_eq!(0, db.stats.read().unwrap().writes);
982    ///
983    /// let key = "test_key".to_string();
984    /// let value1 = Value::String("test_value".to_string());
985    /// let value1_array = Value::Array(VecDeque::from([value1.clone()]));
986    /// let value_post = ValuePost { key: key.clone(), ttl: None, value: value1_array.clone()};
987    /// let value_response = db.try_create(value_post).unwrap().unwrap();
988    ///
989    /// assert_eq!(value_response.key, key);
990    /// assert_eq!(value_response.value, value1_array);
991    /// assert_eq!(1, db.stats.read().unwrap().writes);
992    ///
993    /// let value2 = Value::Integer(100);
994    /// let value2_array = Value::Array(VecDeque::from([value2.clone()]));
995    /// let value_prepend = ValuePrepend { prepend: value2_array.clone()};
996    /// let value_response = db.try_prepend(&key, value_prepend).unwrap().unwrap();
997    ///
998    /// assert_eq!(value_response.key, key);
999    /// assert_eq!(value_response.value, Value::Array(VecDeque::from([value2, value1])));
1000    /// assert_eq!(2, db.stats.read().unwrap().writes);
1001    /// ```
1002    pub fn try_prepend(
1003        &self,
1004        key: &str,
1005        value_prepend: ValuePrepend,
1006    ) -> Result<Option<ValueResponse>> {
1007        let mut stats = self.stats.write().unwrap();
1008        stats.inc_requests();
1009
1010        let key_index = self.indexes.key.write().unwrap();
1011        let id = *key_index.get(key).unwrap();
1012
1013        let mut values = self.values.write().unwrap();
1014        let original_value = values.get(&id).ok_or(Error::NotFound)?.clone();
1015
1016        let value = match (original_value.value, value_prepend.prepend) {
1017            (Value::Array(original_value_vec), Value::Array(value_prepend_vec)) => {
1018                let mut new_value = original_value_vec;
1019
1020                for value_prepend_item in value_prepend_vec {
1021                    new_value.push_front(value_prepend_item);
1022                }
1023
1024                Value::Array(new_value)
1025            }
1026            _ => return Ok(None),
1027        };
1028
1029        let now = Utc::now();
1030        let value_record = ValueRecord::new(
1031            id,
1032            &original_value.key,
1033            &value,
1034            original_value.created_at,
1035            original_value.delete_at,
1036            now,
1037        );
1038        values.insert(id, value_record);
1039        let result = values.get(&id).cloned();
1040
1041        match result {
1042            None => Ok(None),
1043            Some(result) => {
1044                stats.inc_writes();
1045
1046                let mut updated_at_index = self.indexes.updated_at.write().unwrap();
1047                updated_at_index.remove(&original_value.updated_at.timestamp_nanos());
1048                updated_at_index.insert(result.updated_at.timestamp_nanos(), id);
1049
1050                Ok(Some(result.into()))
1051            }
1052        }
1053    }
1054
1055    /// Tries to read a record from the database using the specified key.
1056    ///
1057    /// # Examples
1058    ///
1059    /// ```
1060    /// use alex_db_lib::{config::Config, db::Db, value_record::{Value, ValuePost}};
1061    ///
1062    /// let config = Config::default();
1063    /// let mut db = Db::new(config);
1064    ///
1065    /// assert_eq!(0, db.stats.read().unwrap().reads);
1066    ///
1067    /// let key = "test_key".to_string();
1068    /// let value = Value::Integer(10);
1069    /// let value_post = ValuePost { key: key.clone(), ttl: None, value: value.clone()};
1070    /// db.try_create(value_post);
1071    /// let value_response = db.try_read(&key).unwrap().unwrap();
1072    ///
1073    /// assert_eq!(value_response.key, key);
1074    /// assert_eq!(value_response.value, value);
1075    /// assert_eq!(1, db.stats.read().unwrap().reads);
1076    /// ```
1077    pub fn try_read(&self, key: &str) -> Result<Option<ValueResponse>> {
1078        let mut stats = self.stats.write().unwrap();
1079        stats.inc_requests();
1080
1081        let key_index = self.indexes.key.read().unwrap();
1082        let id = key_index.get(key);
1083
1084        match id {
1085            None => Ok(None),
1086            Some(id) => {
1087                let values = self.values.read().unwrap();
1088                let result = values.get(id).cloned();
1089
1090                match result {
1091                    None => Ok(None),
1092                    Some(result) => {
1093                        stats.inc_reads();
1094
1095                        Ok(Some(result.into()))
1096                    }
1097                }
1098            }
1099        }
1100    }
1101
1102    /// Tries to update a record in the database using the specified key.
1103    ///
1104    /// # Examples
1105    ///
1106    /// ```
1107    /// use alex_db_lib::{config::Config, db::Db, value_record::{Value, ValuePost, ValuePut}};
1108    ///
1109    /// let config = Config::default();
1110    /// let mut db = Db::new(config);
1111    ///
1112    /// assert_eq!(0, db.stats.read().unwrap().writes);
1113    ///
1114    /// let key = "test_key".to_string();
1115    /// let value = Value::String("test_value".to_string());
1116    /// let value_post = ValuePost { key: key.clone(), ttl: None, value: value.clone()};
1117    /// let value_response = db.try_create(value_post).unwrap().unwrap();
1118    ///
1119    /// assert_eq!(value_response.key, key);
1120    /// assert_eq!(value_response.value, value);
1121    /// assert_eq!(1, db.stats.read().unwrap().writes);
1122    ///
1123    /// let value = Value::Integer(100);
1124    /// let value_put = ValuePut { ttl: None, value: value.clone()};
1125    /// let value_response = db.try_update(&key, value_put).unwrap().unwrap();
1126    ///
1127    /// assert_eq!(value_response.key, key);
1128    /// assert_eq!(value_response.value, value);
1129    /// assert_eq!(2, db.stats.read().unwrap().writes);
1130    /// ```
1131    pub fn try_update(&self, key: &str, value_put: ValuePut) -> Result<Option<ValueResponse>> {
1132        let mut stats = self.stats.write().unwrap();
1133        stats.inc_requests();
1134
1135        let key_index = self.indexes.key.read().unwrap();
1136        let id = *key_index.get(key).unwrap();
1137
1138        let mut values = self.values.write().unwrap();
1139        let original_value = values.get(&id).ok_or(Error::NotFound)?.clone();
1140
1141        let now = Utc::now();
1142        let delete_at = value_put.ttl.map(|ttl| now + Duration::seconds(ttl));
1143        let value_record = ValueRecord::new(
1144            id,
1145            &original_value.key,
1146            &value_put.value,
1147            original_value.created_at,
1148            delete_at,
1149            now,
1150        );
1151        values.insert(id, value_record);
1152        let result = values.get(&id).cloned();
1153
1154        match result {
1155            None => Ok(None),
1156            Some(result) => {
1157                stats.inc_writes();
1158
1159                let mut delete_at_index = self.indexes.delete_at.write().unwrap();
1160                if let Some(original_value_delete_at) = original_value.delete_at {
1161                    delete_at_index.remove(&original_value_delete_at.timestamp_nanos());
1162                }
1163                if let Some(delete_at) = delete_at {
1164                    delete_at_index.insert(delete_at.timestamp_nanos(), id);
1165                }
1166
1167                let mut updated_at_index = self.indexes.updated_at.write().unwrap();
1168                updated_at_index.remove(&original_value.updated_at.timestamp_nanos());
1169                updated_at_index.insert(result.updated_at.timestamp_nanos(), id);
1170
1171                Ok(Some(result.into()))
1172            }
1173        }
1174    }
1175}
1176
1177#[derive(Debug, Deserialize)]
1178#[serde(rename_all = "snake_case")]
1179pub enum Direction {
1180    Asc,
1181    Desc,
1182}
1183
1184#[derive(Debug, Deserialize)]
1185#[serde(rename_all = "snake_case")]
1186pub enum Sort {
1187    CreatedAt,
1188    DeleteAt,
1189    Key,
1190    UpdatedAt,
1191}