dataplane_sdk/core/db/
memory.rs1#![allow(clippy::unwrap_used)]
3
4use std::{
5 collections::HashMap,
6 sync::{Arc, RwLock},
7};
8
9use crate::core::error::DbResult;
10
11use super::tx::{Transaction, TransactionalContext};
12
13#[derive(Clone)]
14pub struct MemoryRepo<T>(Arc<RwLock<HashMap<String, T>>>);
15
16impl<T> Default for MemoryRepo<T> {
17 fn default() -> Self {
18 MemoryRepo(Arc::default())
19 }
20}
21
22impl<T: Clone> MemoryRepo<T> {
23 pub async fn create(&self, id: &str, entity: &T) -> DbResult<()> {
24 let mut map = self.0.write().unwrap();
25 if map.contains_key(id) {
26 return Err(crate::core::error::DbError::AlreadyExists(format!(
27 "Entity with id {} already exists",
28 id
29 )));
30 }
31 map.insert(id.to_string(), entity.clone());
32 Ok(())
33 }
34
35 pub async fn fetch_by_id(&self, flow_id: &str) -> DbResult<Option<T>> {
36 let map = self.0.read().unwrap();
37 Ok(map.get(flow_id).cloned())
38 }
39
40 pub async fn update(&self, id: &str, entity: &T) -> DbResult<()> {
41 let mut map = self.0.write().unwrap();
42 if map.contains_key(id) {
43 map.insert(id.to_string(), entity.clone());
44 Ok(())
45 } else {
46 Err(crate::core::error::DbError::NotFound(format!(
47 "Entity with id {} not found",
48 id
49 )))
50 }
51 }
52
53 pub async fn filter<F>(&self, predicate: F) -> DbResult<Vec<T>>
54 where
55 F: Fn(&T) -> bool,
56 {
57 let map = self.0.read().unwrap();
58 Ok(map.values().filter(|e| predicate(e)).cloned().collect())
59 }
60
61 pub async fn delete(&self, id: &str) -> DbResult<()> {
62 let mut map = self.0.write().unwrap();
63 if map.remove(id).is_some() {
64 Ok(())
65 } else {
66 Err(crate::core::error::DbError::NotFound(format!(
67 "Entity with id {} not found",
68 id
69 )))
70 }
71 }
72}
73
74pub struct MemoryContext;
75
76pub struct MemoryTransaction;
77
78#[async_trait::async_trait]
79impl Transaction for MemoryTransaction {
80 async fn commit(self) -> DbResult<()> {
81 Ok(())
82 }
83
84 async fn rollback(self) -> DbResult<()> {
85 Ok(())
86 }
87}
88
89#[async_trait::async_trait]
90impl TransactionalContext for MemoryContext {
91 type Transaction = MemoryTransaction;
92
93 async fn begin(&self) -> DbResult<Self::Transaction> {
94 Ok(MemoryTransaction)
95 }
96}