Adding putting a database into a store.
This commit is contained in:
		@@ -11,8 +11,11 @@ const ENTRY: &str = "EntryPoint";
 | 
			
		||||
enum ErrorCode {
 | 
			
		||||
    // General
 | 
			
		||||
    Undefined(String),
 | 
			
		||||
    // Cache Entry
 | 
			
		||||
    // Cache
 | 
			
		||||
    EntryNotFound(String),
 | 
			
		||||
    InvalidCommitData,
 | 
			
		||||
    // Store
 | 
			
		||||
    DatabaseAlreadyExists(String),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl fmt::Display for ErrorCode {
 | 
			
		||||
@@ -20,6 +23,10 @@ impl fmt::Display for ErrorCode {
 | 
			
		||||
        match self {
 | 
			
		||||
            ErrorCode::Undefined(msg) => write!(f, "{}", msg),
 | 
			
		||||
            ErrorCode::EntryNotFound(id) => write!(f, "entry '{}' was not found", id),
 | 
			
		||||
            ErrorCode::InvalidCommitData => write!(f, "commit data was not a database store"),
 | 
			
		||||
            ErrorCode::DatabaseAlreadyExists(name) => {
 | 
			
		||||
                write!(f, "database '{}' already exists", name)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -44,6 +51,23 @@ mod errorcodes {
 | 
			
		||||
            assert_eq!(err.to_string(), format!("entry '{}' was not found", item));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn invalid_commit_data() {
 | 
			
		||||
        let err = ErrorCode::InvalidCommitData;
 | 
			
		||||
        assert_eq!(err.to_string(), "commit data was not a database store");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn database_already_exists() {
 | 
			
		||||
        for item in ITEMS {
 | 
			
		||||
            let err = ErrorCode::DatabaseAlreadyExists(item.to_string());
 | 
			
		||||
            assert_eq!(
 | 
			
		||||
                err.to_string(),
 | 
			
		||||
                format!("database '{}' already exists", item)
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
@@ -117,11 +141,109 @@ mod errors {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
struct Store;
 | 
			
		||||
struct Storage {
 | 
			
		||||
    id: Option<String>,
 | 
			
		||||
    data: Option<DataType>,
 | 
			
		||||
    // delete: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Storage {
 | 
			
		||||
    fn from_id<S>(id: S) -> Self
 | 
			
		||||
    where
 | 
			
		||||
        S: Into<String>,
 | 
			
		||||
    {
 | 
			
		||||
        Self {
 | 
			
		||||
            id: Some(id.into()),
 | 
			
		||||
            data: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn from_datatype(dt: DataType) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            id: None,
 | 
			
		||||
            data: Some(dt),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod storage {
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn from_id_with_str() {
 | 
			
		||||
        let ids = ["first", "second"];
 | 
			
		||||
        for id in ids {
 | 
			
		||||
            let output = Storage::from_id(id);
 | 
			
		||||
            assert_eq!(output.id, Some(id.to_string()));
 | 
			
		||||
            assert!(
 | 
			
		||||
                output.data.is_none(),
 | 
			
		||||
                "The storage data should have been Non."
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn from_id_with_string() {
 | 
			
		||||
        let id = "my_id".to_string();
 | 
			
		||||
        let output = Storage::from_id(id.clone());
 | 
			
		||||
        assert_eq!(output.id, Some(id));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn from_store() {
 | 
			
		||||
        let output = Storage::from_datatype(DataType::new("store"));
 | 
			
		||||
        assert!(output.id.is_none(), "id should be None.");
 | 
			
		||||
        assert!(output.data.is_some(), "There should be data");
 | 
			
		||||
        let result = output.data.unwrap();
 | 
			
		||||
        match result {
 | 
			
		||||
            DataType::DBMap(_) => (),
 | 
			
		||||
            _ => assert!(false, "{:?} should have been DataType::DBMap.", result),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn from_database() {
 | 
			
		||||
        let output = Storage::from_datatype(DataType::new("database"));
 | 
			
		||||
        let result = output.data.unwrap();
 | 
			
		||||
        match result {
 | 
			
		||||
            DataType::TableMap(_) => (),
 | 
			
		||||
            _ => assert!(false, "{:?} should have been DataType::TableMap.", result),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
struct Store {
 | 
			
		||||
    data: HashMap<String, Storage>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Store {
 | 
			
		||||
    fn new() -> Self {
 | 
			
		||||
        Self {}
 | 
			
		||||
        Self {
 | 
			
		||||
            data: HashMap::new(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn add_new<S>(&mut self, name: S) -> Result<(), MTTError>
 | 
			
		||||
    where
 | 
			
		||||
        S: Into<String>,
 | 
			
		||||
    {
 | 
			
		||||
        let dbname = name.into();
 | 
			
		||||
        match self.get(&dbname) {
 | 
			
		||||
            Some(_) => Err(MTTError::from_code(ErrorCode::DatabaseAlreadyExists(
 | 
			
		||||
                dbname,
 | 
			
		||||
            ))),
 | 
			
		||||
            None => {
 | 
			
		||||
                self.data
 | 
			
		||||
                    .insert(dbname, Storage::from_datatype(DataType::new("database")));
 | 
			
		||||
                Ok(())
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn get(&self, name: &str) -> Option<&Storage> {
 | 
			
		||||
        self.data.get(name)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -130,8 +252,68 @@ mod stores {
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn create() {
 | 
			
		||||
        Store::new();
 | 
			
		||||
    fn get_no_database() -> Result<(), MTTError> {
 | 
			
		||||
        let store = Store::new();
 | 
			
		||||
        match store.get("missing_name") {
 | 
			
		||||
            Some(_) => Err(MTTError::new("should have returned None")),
 | 
			
		||||
            None => Ok(()),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn add_database_str() {
 | 
			
		||||
        let mut store = Store::new();
 | 
			
		||||
        let names = ["first", "second"];
 | 
			
		||||
        for name in names {
 | 
			
		||||
            store.add_new(name).unwrap();
 | 
			
		||||
            let output = store.get(name).unwrap();
 | 
			
		||||
            assert!(output.data.is_some(), "There should be a data type.");
 | 
			
		||||
            match output.data.clone().unwrap() {
 | 
			
		||||
                DataType::TableMap(_) => (),
 | 
			
		||||
                _ => assert!(
 | 
			
		||||
                    false,
 | 
			
		||||
                    "{:?} should have been DataType::TableMap.",
 | 
			
		||||
                    output.data
 | 
			
		||||
                ),
 | 
			
		||||
            }
 | 
			
		||||
            assert!(output.id.is_none(), "Should not have an id.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn add_database_string() {
 | 
			
		||||
        let mut store = Store::new();
 | 
			
		||||
        let name = "third".to_string();
 | 
			
		||||
        store.add_new(name.clone()).unwrap();
 | 
			
		||||
        let output = store.get(&name).unwrap();
 | 
			
		||||
        match output.data.clone().unwrap() {
 | 
			
		||||
            DataType::TableMap(_) => (),
 | 
			
		||||
            _ => assert!(
 | 
			
		||||
                false,
 | 
			
		||||
                "{:?} should have been DataType::TableMap.",
 | 
			
		||||
                output.data
 | 
			
		||||
            ),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn no_duplicate_database_names() -> Result<(), MTTError> {
 | 
			
		||||
        let mut store = Store::new();
 | 
			
		||||
        let name = "duplicate";
 | 
			
		||||
        store.add_new(name).unwrap();
 | 
			
		||||
        match store.add_new(name) {
 | 
			
		||||
            Ok(_) => Err(MTTError::new("should have been an error")),
 | 
			
		||||
            Err(err) => match err.code {
 | 
			
		||||
                ErrorCode::DatabaseAlreadyExists(dbname) => {
 | 
			
		||||
                    assert_eq!(dbname, name);
 | 
			
		||||
                    Ok(())
 | 
			
		||||
                }
 | 
			
		||||
                _ => Err(MTTError::new(format!(
 | 
			
		||||
                    "{:?} should have been DatabaseAlreadyExists.",
 | 
			
		||||
                    err.code
 | 
			
		||||
                ))),
 | 
			
		||||
            },
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -207,11 +389,19 @@ struct CacheQuery {
 | 
			
		||||
 | 
			
		||||
struct CacheCommit {
 | 
			
		||||
    reply: Sender<FromCache>,
 | 
			
		||||
    // data: DataType,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl CacheCommit {
 | 
			
		||||
    fn new(channel: Sender<FromCache>) -> Self {
 | 
			
		||||
        Self { reply: channel }
 | 
			
		||||
    fn new(data: DataType, channel: Sender<FromCache>) -> Result<Self, MTTError> {
 | 
			
		||||
        match data {
 | 
			
		||||
            DataType::DBMap(_) => (),
 | 
			
		||||
            _ => return Err(MTTError::from_code(ErrorCode::InvalidCommitData)),
 | 
			
		||||
        }
 | 
			
		||||
        Ok(Self {
 | 
			
		||||
            // data: data,
 | 
			
		||||
            reply: channel,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -219,9 +409,27 @@ mod commits {
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn create() {
 | 
			
		||||
    fn create() -> Result<(), MTTError> {
 | 
			
		||||
        let (s, _) = unbounded();
 | 
			
		||||
        CacheCommit::new(s);
 | 
			
		||||
        match CacheCommit::new(DataType::new("store"), s) {
 | 
			
		||||
            Ok(_) => Ok(()),
 | 
			
		||||
            Err(err) => Err(err),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn bad_data_type() -> Result<(), MTTError> {
 | 
			
		||||
        let (s, _) = unbounded();
 | 
			
		||||
        match CacheCommit::new(DataType::new("database"), s) {
 | 
			
		||||
            Ok(_) => Err(MTTError::new("CacheCommit::new did not return error")),
 | 
			
		||||
            Err(err) => match err.code {
 | 
			
		||||
                ErrorCode::InvalidCommitData => Ok(()),
 | 
			
		||||
                _ => Err(MTTError::new(format!(
 | 
			
		||||
                    "{:?} is not the correct error",
 | 
			
		||||
                    err.code
 | 
			
		||||
                ))),
 | 
			
		||||
            },
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -363,7 +571,7 @@ mod caches {
 | 
			
		||||
        let dir = tempdir().unwrap();
 | 
			
		||||
        let s_cache = start_cache(dir.path()).await;
 | 
			
		||||
        let (s, r) = unbounded();
 | 
			
		||||
        let msg = ToCache::Commit(CacheCommit::new(s));
 | 
			
		||||
        let msg = ToCache::Commit(CacheCommit::new(DataType::new("store"), s).unwrap());
 | 
			
		||||
        s_cache.send(msg).await.unwrap();
 | 
			
		||||
        let result = r.recv().await.unwrap();
 | 
			
		||||
        match result {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user