Added a basic commit function.

This commit is contained in:
Jeff Baskin 2023-06-29 00:17:49 -04:00
parent 933d48a47c
commit 05d445c58b
2 changed files with 75 additions and 19 deletions

View File

@ -1,21 +1,29 @@
use super::{ErrorCode, FromCache, MTTError, Store, ToCache, ENTRY}; use super::{ErrorCode, FromCache, MTTError, Store, ToCache, ENTRY};
use async_std::{channel::Receiver, path::PathBuf}; use async_std::{channel::Receiver, path::PathBuf};
use std::collections::HashMap;
pub struct Cache; pub struct Cache {
data: HashMap<String, Store>,
}
impl Cache { impl Cache {
pub async fn new<P>(_dir: P) -> Self pub async fn new<P>(_dir: P) -> Self
where where
P: Into<PathBuf>, P: Into<PathBuf>,
{ {
Self {} let mut data = HashMap::new();
data.insert(ENTRY.to_string(), Store::new());
Self { data: data }
} }
pub async fn listen(&self, listener: Receiver<ToCache>) { pub async fn listen(&mut self, listener: Receiver<ToCache>) {
loop { loop {
match listener.recv().await.unwrap() { match listener.recv().await.unwrap() {
ToCache::Get(data) => { ToCache::Get(data) => {
data.result.send(self.get(data.id)).await.unwrap(); data.result.send(self.get(data.data)).await.unwrap();
}
ToCache::Commit(data) => {
data.result.send(self.commit(data.data)).await.unwrap();
} }
} }
} }
@ -26,12 +34,16 @@ impl Cache {
S: Into<String>, S: Into<String>,
{ {
let idd = id.into(); let idd = id.into();
if idd == ENTRY { match self.data.get(&idd) {
FromCache::Str(Store::new()) Some(store) => FromCache::Str(store.clone()),
} else { None => FromCache::Error(MTTError::from_code(ErrorCode::IDNotFound(idd))),
FromCache::Error(MTTError::from_code(ErrorCode::IDNotFound(idd)))
} }
} }
pub fn commit(&mut self, data: Store) -> FromCache {
self.data.insert(ENTRY.to_string(), data).unwrap();
FromCache::Ok
}
} }
#[cfg(test)] #[cfg(test)]
@ -80,12 +92,27 @@ mod engine {
} }
Ok(()) Ok(())
} }
#[async_std::test]
async fn commit_database() {
let dir = tempdir().unwrap();
let mut cache = Cache::new(dir.path()).await;
let mut store = Store::new();
let db = "garfield";
store.add(db).unwrap();
cache.commit(store.clone());
let output = cache.get(ENTRY);
match output {
FromCache::Str(result) => assert_eq!(result.list(), store.list()),
_ => assert!(false, "{:?} is not FromCache::Str", output),
}
}
} }
#[cfg(test)] #[cfg(test)]
mod messages { mod messages {
use super::{ use super::{
super::{start_db, CacheGet}, super::{start_db, ToCacheMsg},
*, *,
}; };
use async_std::channel::unbounded; use async_std::channel::unbounded;
@ -97,8 +124,8 @@ mod messages {
let mtt = start_db(dir.path()).await.unwrap(); let mtt = start_db(dir.path()).await.unwrap();
let in_s = mtt.to_cache.clone(); let in_s = mtt.to_cache.clone();
let (out_s, out_r) = unbounded(); let (out_s, out_r) = unbounded();
let msg = CacheGet { let msg = ToCacheMsg {
id: ENTRY.to_string(), data: ENTRY.to_string(),
result: out_s, result: out_s,
}; };
in_s.send(ToCache::Get(msg)).await.unwrap(); in_s.send(ToCache::Get(msg)).await.unwrap();
@ -115,8 +142,8 @@ mod messages {
let mtt = start_db(dir.path()).await.unwrap(); let mtt = start_db(dir.path()).await.unwrap();
let in_s = mtt.to_cache.clone(); let in_s = mtt.to_cache.clone();
let (out_s, out_r) = unbounded(); let (out_s, out_r) = unbounded();
let msg = CacheGet { let msg = ToCacheMsg {
id: "bad_id!".to_string(), data: "bad_id!".to_string(),
result: out_s, result: out_s,
}; };
in_s.send(ToCache::Get(msg)).await.unwrap(); in_s.send(ToCache::Get(msg)).await.unwrap();

View File

@ -16,18 +16,20 @@ use store::Store;
const ENTRY: &str = "EntryPoint"; const ENTRY: &str = "EntryPoint";
#[derive(Debug)] #[derive(Debug)]
pub struct CacheGet { pub struct ToCacheMsg<D> {
id: String, data: D,
result: Sender<FromCache>, result: Sender<FromCache>,
} }
#[derive(Debug)] #[derive(Debug)]
pub enum ToCache { pub enum ToCache {
Get(CacheGet), Get(ToCacheMsg<String>),
Commit(ToCacheMsg<Store>),
} }
#[derive(Debug)] #[derive(Debug)]
pub enum FromCache { pub enum FromCache {
Ok,
Str(Store), Str(Store),
Error(MTTError), Error(MTTError),
} }
@ -73,14 +75,29 @@ impl MoreThanText {
async fn session(&self) -> Result<Store, MTTError> { async fn session(&self) -> Result<Store, MTTError> {
let (s, r) = unbounded(); let (s, r) = unbounded();
let msg = CacheGet { let msg = ToCacheMsg {
id: ENTRY.to_string(), data: ENTRY.to_string(),
result: s, result: s,
}; };
self.to_cache.send(ToCache::Get(msg)).await.unwrap(); self.to_cache.send(ToCache::Get(msg)).await.unwrap();
match r.recv().await.unwrap() { match r.recv().await.unwrap() {
FromCache::Str(store) => Ok(store), FromCache::Str(store) => Ok(store),
FromCache::Error(err) => Err(err), FromCache::Error(err) => Err(err),
_ => unreachable!(),
}
}
async fn commit(&self, store: Store) -> Result<(), MTTError> {
let (s, r) = unbounded();
let msg = ToCacheMsg {
data: store,
result: s,
};
self.to_cache.send(ToCache::Commit(msg)).await.unwrap();
match r.recv().await.unwrap() {
FromCache::Ok => Ok(()),
FromCache::Error(err) => Err(err),
_ => unreachable!(),
} }
} }
} }
@ -100,6 +117,18 @@ mod mtt {
let expected: Vec<String> = Vec::new(); let expected: Vec<String> = Vec::new();
assert_eq!(store.list(), expected); assert_eq!(store.list(), expected);
} }
#[async_std::test]
async fn commit_db() {
let dir = tempdir().unwrap();
let db = "fred";
let mtt = start_db(dir.path()).await.unwrap();
let mut store = mtt.session().await.unwrap();
store.add(db).unwrap();
mtt.commit(store).await.unwrap();
let store2 = mtt.session().await.unwrap();
assert_eq!(store2.list(), [db]);
}
} }
pub async fn start_db<P>(dir: P) -> Result<MoreThanText, MTTError> pub async fn start_db<P>(dir: P) -> Result<MoreThanText, MTTError>
@ -109,7 +138,7 @@ where
let path = dir.into(); let path = dir.into();
let (s, r) = unbounded(); let (s, r) = unbounded();
spawn(async move { spawn(async move {
let cache = Cache::new(path).await; let mut cache = Cache::new(path).await;
cache.listen(r).await; cache.listen(r).await;
}); });
Ok(MoreThanText::new(s)) Ok(MoreThanText::new(s))