203 lines
5.2 KiB
Rust
203 lines
5.2 KiB
Rust
use rand::{distributions::Alphanumeric, Rng, thread_rng};
|
|
use super::{DBError, Store, SessionData};
|
|
use std::{
|
|
cell::Cell,
|
|
time::{Duration, Instant},
|
|
};
|
|
|
|
enum DataType {
|
|
DBMap(Store),
|
|
}
|
|
|
|
impl DataType {
|
|
fn new(data_type: &str) -> Result<Self, DBError> {
|
|
match data_type {
|
|
"store" => Ok(DataType::DBMap(Store::new())),
|
|
_ => Err(DBError::new("invalid data type")),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SessionData for DataType {
|
|
fn add(&mut self, key: &str, value: &str, data: &str) -> Result<Vec<String>, DBError> {
|
|
match self {
|
|
DataType::DBMap(dbs) => dbs.add(key, value, data),
|
|
}
|
|
}
|
|
|
|
fn eq(&self, key: &str, value: &str) -> Result<Vec<String>, DBError> {
|
|
match self {
|
|
DataType::DBMap(dbs) => dbs.eq(key, value),
|
|
}
|
|
}
|
|
|
|
fn list(&self, keys: Vec<&str>) -> Result<Vec<String>, DBError> {
|
|
match self {
|
|
DataType::DBMap(dbs) => dbs.list(keys),
|
|
}
|
|
}
|
|
}
|
|
|
|
struct Entry {
|
|
data: DataType,
|
|
last_used: Cell<Instant>,
|
|
}
|
|
|
|
impl Entry {
|
|
fn new(data_type: &str) -> Result<Self, DBError> {
|
|
let data = match DataType::new(data_type) {
|
|
Ok(item) => item,
|
|
Err(err) => return Err(err),
|
|
};
|
|
Ok(Self {
|
|
data: data,
|
|
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<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)
|
|
}
|
|
}
|
|
|
|
struct Cache;
|
|
|
|
impl Cache {
|
|
async fn new(dir: &str) -> Self {
|
|
Self
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod datatype {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn invalid_cache_type() -> Result<(), DBError> {
|
|
match DataType::new("dkhgdl") {
|
|
Ok(_) => Err(DBError::new("invalid data type should raise an error")),
|
|
Err(err) => {
|
|
assert_eq!(err.to_string(), "invalid data type");
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn create_storage() {
|
|
let dbs = DataType::new("store").unwrap();
|
|
let expected: Vec<String> = Vec::new();
|
|
assert_eq!(dbs.list(["database"].to_vec()).unwrap(), expected);
|
|
}
|
|
|
|
#[test]
|
|
fn update_storage() {
|
|
let mut dbs = DataType::new("store").unwrap();
|
|
let name = "new_database";
|
|
let id = "someid";
|
|
dbs.add("database", name, id).unwrap();
|
|
assert_eq!(dbs.eq("database", name).unwrap(), [id].to_vec());
|
|
assert_eq!(dbs.list(["database"].to_vec()).unwrap(), [name].to_vec());
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod entry {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn invalid_cache_type() -> Result<(), DBError> {
|
|
match Entry::new("uydg") {
|
|
Ok(_) => Err(DBError::new("invalid data type should raise an error")),
|
|
Err(err) => {
|
|
assert_eq!(err.to_string(), "invalid data type");
|
|
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)]
|
|
mod cache {
|
|
use super::*;
|
|
use tempfile::tempdir;
|
|
|
|
#[async_std::test]
|
|
async fn create() {
|
|
let dir = tempdir().unwrap();
|
|
Cache::new(dir.path().to_str().unwrap()).await;
|
|
}
|
|
}
|