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}