In process of separating cache from database.
This commit is contained in:
		@@ -1,10 +1,12 @@
 | 
				
			|||||||
use rand::{distributions::Alphanumeric, Rng, thread_rng};
 | 
					use super::{DBError, SessionData, Store};
 | 
				
			||||||
use super::{DBError, Store, SessionData};
 | 
					use async_std::{fs::write, path::Path};
 | 
				
			||||||
 | 
					use rand::{distributions::Alphanumeric, thread_rng, Rng};
 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
    cell::Cell,
 | 
					    cell::Cell,
 | 
				
			||||||
    time::{Duration, Instant},
 | 
					    time::{Duration, Instant},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone)]
 | 
				
			||||||
enum DataType {
 | 
					enum DataType {
 | 
				
			||||||
    DBMap(Store),
 | 
					    DBMap(Store),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -40,40 +42,24 @@ impl SessionData for DataType {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct Entry {
 | 
					struct Entry {
 | 
				
			||||||
    data: DataType,
 | 
					    data: DataType,
 | 
				
			||||||
 | 
					    filename: String,
 | 
				
			||||||
    last_used: Cell<Instant>,
 | 
					    last_used: Cell<Instant>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Entry {
 | 
					impl Entry {
 | 
				
			||||||
    fn new(data_type: &str) -> Result<Self, DBError> {
 | 
					    async fn new(filename: String, data: DataType) -> Result<Self, DBError> {
 | 
				
			||||||
        let data = match DataType::new(data_type) {
 | 
					        if Path::new(&filename).exists().await {
 | 
				
			||||||
            Ok(item) => item,
 | 
					            return Err(DBError::new("entry already exists"));
 | 
				
			||||||
            Err(err) => return Err(err),
 | 
					        }
 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        Ok(Self {
 | 
					        Ok(Self {
 | 
				
			||||||
            data: data,
 | 
					            data: data,
 | 
				
			||||||
 | 
					            filename: filename,
 | 
				
			||||||
            last_used: Cell::new(Instant::now()),
 | 
					            last_used: Cell::new(Instant::now()),
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn elapsed(&self) -> Duration {
 | 
					    async fn get(&self) -> Result<DataType, DBError> {
 | 
				
			||||||
        self.last_used.get().elapsed()
 | 
					        Ok(self.data.clone())
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl SessionData for Entry {
 | 
					 | 
				
			||||||
    fn add(&mut self, key: &str, value: &str, data: &str) -> Result<Vec<String>, DBError> {
 | 
					 | 
				
			||||||
        self.last_used.set(Instant::now());
 | 
					 | 
				
			||||||
        self.data.add(key, value, data)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn eq(&self, key: &str, value: &str) -> Result<Vec<String>, DBError> {
 | 
					 | 
				
			||||||
        self.last_used.set(Instant::now());
 | 
					 | 
				
			||||||
        self.data.eq(key, value)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn list(&self, keys: Vec<&str>) -> Result<Vec<String>, DBError> {
 | 
					 | 
				
			||||||
        self.last_used.set(Instant::now());
 | 
					 | 
				
			||||||
        self.data.list(keys)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -86,7 +72,7 @@ impl Cache {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod datatype {
 | 
					mod datatype_sesssion {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
@@ -119,74 +105,54 @@ mod datatype {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod entry {
 | 
					mod datatype_file {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    // Test file data traits here.
 | 
				
			||||||
    fn invalid_cache_type() -> Result<(), DBError> {
 | 
					}
 | 
				
			||||||
        match Entry::new("uydg") {
 | 
					
 | 
				
			||||||
            Ok(_) => Err(DBError::new("invalid data type should raise an error")),
 | 
					#[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) => {
 | 
					            Err(err) => {
 | 
				
			||||||
                assert_eq!(err.to_string(), "invalid data type");
 | 
					                assert_eq!(err.to_string(), "entry already exists");
 | 
				
			||||||
                Ok(())
 | 
					                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<String> = 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)]
 | 
					#[cfg(test)]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
mod cache;
 | 
					mod cache;
 | 
				
			||||||
mod store;
 | 
					 | 
				
			||||||
pub mod error;
 | 
					pub mod error;
 | 
				
			||||||
 | 
					mod store;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use async_std::{
 | 
					use async_std::{
 | 
				
			||||||
    fs::{create_dir, read, remove_file, write},
 | 
					    fs::{create_dir, read, remove_file, write},
 | 
				
			||||||
@@ -8,7 +8,6 @@ use async_std::{
 | 
				
			|||||||
    sync::{Arc, Mutex},
 | 
					    sync::{Arc, Mutex},
 | 
				
			||||||
    task::{sleep, spawn},
 | 
					    task::{sleep, spawn},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use store::Store;
 | 
					 | 
				
			||||||
use error::DBError;
 | 
					use error::DBError;
 | 
				
			||||||
use rand::{distributions::Alphanumeric, thread_rng, Rng};
 | 
					use rand::{distributions::Alphanumeric, thread_rng, Rng};
 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
@@ -16,6 +15,7 @@ use std::{
 | 
				
			|||||||
    fmt, slice, str,
 | 
					    fmt, slice, str,
 | 
				
			||||||
    time::{Duration, Instant},
 | 
					    time::{Duration, Instant},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					use store::Store;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const DATA: &str = "data";
 | 
					const DATA: &str = "data";
 | 
				
			||||||
const ENTRY: &str = "databases";
 | 
					const ENTRY: &str = "databases";
 | 
				
			||||||
@@ -404,11 +404,13 @@ mod data {
 | 
				
			|||||||
        let id = "*gsdfg";
 | 
					        let id = "*gsdfg";
 | 
				
			||||||
        let output = mtt.db.add("database", name, id).await;
 | 
					        let output = mtt.db.add("database", name, id).await;
 | 
				
			||||||
        assert_eq!(output.session, [id], "should update session info.");
 | 
					        assert_eq!(output.session, [id], "should update session info.");
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
        assert_eq!(
 | 
					        assert_eq!(
 | 
				
			||||||
            mtt.db.list(["database"].to_vec()).await.unwrap(),
 | 
					            mtt.db.list(["database"].to_vec()).await.unwrap(),
 | 
				
			||||||
            [name],
 | 
					            [name],
 | 
				
			||||||
            "Should list the databases."
 | 
					            "Should list the databases."
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					        */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user