From 894fcbcd02305748a798bcf06e2523d28132ef87 Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Mon, 13 Feb 2023 10:19:20 -0500 Subject: [PATCH] In process of separating cache from database. --- src/morethantext/cache.rs | 142 +++++++++++++++----------------------- src/morethantext/mod.rs | 6 +- 2 files changed, 58 insertions(+), 90 deletions(-) diff --git a/src/morethantext/cache.rs b/src/morethantext/cache.rs index 493b1f0..42c11af 100644 --- a/src/morethantext/cache.rs +++ b/src/morethantext/cache.rs @@ -1,10 +1,12 @@ -use rand::{distributions::Alphanumeric, Rng, thread_rng}; -use super::{DBError, Store, SessionData}; +use super::{DBError, SessionData, Store}; +use async_std::{fs::write, path::Path}; +use rand::{distributions::Alphanumeric, thread_rng, Rng}; use std::{ cell::Cell, time::{Duration, Instant}, }; +#[derive(Clone)] enum DataType { DBMap(Store), } @@ -40,40 +42,24 @@ impl SessionData for DataType { struct Entry { data: DataType, + filename: String, last_used: Cell, } impl Entry { - fn new(data_type: &str) -> Result { - let data = match DataType::new(data_type) { - Ok(item) => item, - Err(err) => return Err(err), - }; + async fn new(filename: String, data: DataType) -> Result { + if Path::new(&filename).exists().await { + return Err(DBError::new("entry already exists")); + } Ok(Self { data: data, + filename: filename, last_used: Cell::new(Instant::now()), }) } - fn elapsed(&self) -> Duration { - self.last_used.get().elapsed() - } -} - -impl SessionData for Entry { - fn add(&mut self, key: &str, value: &str, data: &str) -> Result, DBError> { - self.last_used.set(Instant::now()); - self.data.add(key, value, data) - } - - fn eq(&self, key: &str, value: &str) -> Result, DBError> { - self.last_used.set(Instant::now()); - self.data.eq(key, value) - } - - fn list(&self, keys: Vec<&str>) -> Result, DBError> { - self.last_used.set(Instant::now()); - self.data.list(keys) + async fn get(&self) -> Result { + Ok(self.data.clone()) } } @@ -86,7 +72,7 @@ impl Cache { } #[cfg(test)] -mod datatype { +mod datatype_sesssion { use super::*; #[test] @@ -119,74 +105,54 @@ mod datatype { } #[cfg(test)] -mod entry { +mod datatype_file { use super::*; - #[test] - fn invalid_cache_type() -> Result<(), DBError> { - match Entry::new("uydg") { - Ok(_) => Err(DBError::new("invalid data type should raise an error")), + // Test file data traits here. +} + +#[cfg(test)] +mod entry { + use super::*; + use tempfile::tempdir; + + #[async_std::test] + async fn create() { + let dir = tempdir().unwrap(); + let mut data = DataType::new("store").unwrap(); + data.add("database", "roger", "moore").unwrap(); + let filepath = dir.path().join("wiliam"); + let filename = filepath.to_str().unwrap(); + let item = Entry::new(filename.to_string(), data.clone()) + .await + .unwrap(); + let output = item.get().await.unwrap(); + assert_eq!( + data.list(["database"].to_vec()).unwrap(), + output.list(["database"].to_vec()).unwrap() + ); + } + + #[async_std::test] + async fn no_over_writes() -> Result<(), DBError> { + let dir = tempdir().unwrap(); + let id = "wicked"; + let file = dir.path().join(id); + let filename = file.to_str().unwrap(); + write(&file, b"previous").await.unwrap(); + let data = DataType::new("store").unwrap(); + match Entry::new(filename.to_string(), data).await { + Ok(_) => { + return Err(DBError::new( + "Should produce an error for an existing Entry", + )) + } Err(err) => { - assert_eq!(err.to_string(), "invalid data type"); + assert_eq!(err.to_string(), "entry already exists"); Ok(()) } } } - - #[test] - fn create_storage() { - let entry = Entry::new("store").unwrap(); - assert!( - Duration::from_secs(1) > entry.elapsed(), - "Entry last used should be now." - ); - let expected: Vec = Vec::new(); - assert_eq!(entry.list(["database"].to_vec()).unwrap(), expected); - } - - #[test] - fn add_database_to_storage() { - let mut entry = Entry::new("store").unwrap(); - entry - .last_used - .set(Instant::now() - Duration::from_secs(500)); - let name = "roger"; - let id = "cormick"; - entry.add("database", name, id).unwrap(); - assert!( - Duration::from_secs(1) > entry.elapsed(), - "Entry last used should be now." - ); - assert_eq!(entry.eq("database", name).unwrap(), [id].to_vec()); - } - - #[test] - fn get_database_from_storage() { - let mut entry = Entry::new("store").unwrap(); - let name = "jessica"; - entry.add("database", name, "rabbit").unwrap(); - entry - .last_used - .set(Instant::now() - Duration::from_secs(500)); - entry.eq("database", name).unwrap(); - assert!( - Duration::from_secs(1) > entry.elapsed(), - "Entry last used should be now." - ); - } - - #[test] - fn list_database_from_storage() { - let entry = Entry::new("store").unwrap(); - entry - .last_used - .set(Instant::now() - Duration::from_secs(500)); - entry.list(["database"].to_vec()).unwrap(); - assert!( - Duration::from_secs(1) > entry.elapsed(), - "Entry last used should be now." - ); - } } #[cfg(test)] diff --git a/src/morethantext/mod.rs b/src/morethantext/mod.rs index e4f856e..b2a4f9b 100644 --- a/src/morethantext/mod.rs +++ b/src/morethantext/mod.rs @@ -1,6 +1,6 @@ mod cache; -mod store; pub mod error; +mod store; use async_std::{ fs::{create_dir, read, remove_file, write}, @@ -8,7 +8,6 @@ use async_std::{ sync::{Arc, Mutex}, task::{sleep, spawn}, }; -use store::Store; use error::DBError; use rand::{distributions::Alphanumeric, thread_rng, Rng}; use std::{ @@ -16,6 +15,7 @@ use std::{ fmt, slice, str, time::{Duration, Instant}, }; +use store::Store; const DATA: &str = "data"; const ENTRY: &str = "databases"; @@ -404,11 +404,13 @@ mod data { let id = "*gsdfg"; let output = mtt.db.add("database", name, id).await; assert_eq!(output.session, [id], "should update session info."); + /* assert_eq!( mtt.db.list(["database"].to_vec()).await.unwrap(), [name], "Should list the databases." ); + */ } }