Added a basic commit function.
This commit is contained in:
parent
933d48a47c
commit
05d445c58b
@ -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();
|
||||||
|
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user