mod db;
mod error;
mod layers;
mod memory;
pub use self::memory::{MemoryCollection, MemoryManager};
pub use db::DB;
pub use error::Error;
pub trait DatabaseManager<C>: Sync + Send
where
C: DatabaseCollection,
{
fn default() -> Self;
fn create_collection(&self, identifier: &str) -> C;
}
pub trait DatabaseCollection: Sync + Send {
fn get(&self, key: &str) -> Result<Vec<u8>, Error>;
fn put(&self, key: &str, data: Vec<u8>) -> Result<(), Error>;
fn del(&self, key: &str) -> Result<(), Error>;
fn iter<'a>(
&'a self,
reverse: bool,
prefix: String,
) -> Box<dyn Iterator<Item = (String, Vec<u8>)> + 'a>;
}
#[macro_export]
macro_rules! test_database_manager_trait {
($name:ident: $type:ty: $type2:ty) => {
mod $name {
#[allow(unused_imports)]
use super::*;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
struct Data {
id: usize,
value: String,
}
#[allow(dead_code)]
fn get_data() -> Result<Vec<Vec<u8>>, Error> {
let data1 = Data {
id: 1,
value: "A".into(),
};
let data2 = Data {
id: 2,
value: "B".into(),
};
let data3 = Data {
id: 3,
value: "C".into(),
};
let Ok(data1) = bincode::serialize::<Data>(&data1) else {
return Err(Error::SerializeError);
};
let Ok(data2) = bincode::serialize::<Data>(&data2) else {
return Err(Error::SerializeError);
};
let Ok(data3) = bincode::serialize::<Data>(&data3) else {
return Err(Error::SerializeError);
};
Ok(vec![data1, data2, data3])
}
#[test]
fn basic_operations_test() {
let db = <$type>::default();
let first_collection: $type2 = db.create_collection("first");
let data = get_data().unwrap();
let result = first_collection.put("a", data[0].clone());
assert!(result.is_ok());
let result = first_collection.put("b", data[1].clone());
assert!(result.is_ok());
let result = first_collection.put("c", data[2].clone());
assert!(result.is_ok());
let result = first_collection.get("a");
assert!(result.is_ok());
assert_eq!(result.unwrap(), data[0]);
let result = first_collection.get("b");
assert!(result.is_ok());
assert_eq!(result.unwrap(), data[1]);
let result = first_collection.get("c");
assert!(result.is_ok());
assert_eq!(result.unwrap(), data[2]);
let result = first_collection.del("a");
assert!(result.is_ok());
let result = first_collection.del("b");
assert!(result.is_ok());
let result = first_collection.del("c");
assert!(result.is_ok());
let result = first_collection.get("a");
assert!(result.is_err());
let result = first_collection.get("b");
assert!(result.is_err());
let result = first_collection.get("c");
assert!(result.is_err());
}
#[test]
fn partitions_test() {
let db = <$type>::default();
let first_collection: $type2 = db.create_collection("first");
let second_collection: $type2 = db.create_collection("second");
let data = get_data().unwrap();
let result = first_collection.put("a", data[0].to_owned());
assert!(result.is_ok());
let result = second_collection.put("b", data[1].to_owned());
assert!(result.is_ok());
let result = first_collection.get("b");
assert_eq!(result.unwrap(), data[1]);
let result = second_collection.get("a");
assert_eq!(result.unwrap(), data[0]);
}
#[allow(dead_code)]
fn build_state(collection: &$type2) {
let data = get_data().unwrap();
let result = collection.put("a", data[0].to_owned());
assert!(result.is_ok());
let result = collection.put("b", data[1].to_owned());
assert!(result.is_ok());
let result = collection.put("c", data[2].to_owned());
assert!(result.is_ok());
}
#[allow(dead_code)]
fn build_initial_data() -> (Vec<&'static str>, Vec<Vec<u8>>) {
let keys = vec!["a", "b", "c"];
let data = get_data().unwrap();
let values = vec![data[0].to_owned(), data[1].to_owned(), data[2].to_owned()];
(keys, values)
}
#[test]
fn iterator_test() {
let db = <$type>::default();
let first_collection: $type2 = db.create_collection("first");
build_state(&first_collection);
let mut iter = first_collection.iter(false, "first".to_string());
assert!(iter.next().is_none());
let mut iter = first_collection.iter(false, "".to_string());
let (keys, data) = build_initial_data();
for i in 0..3 {
let (key, val) = iter.next().unwrap();
assert_eq!(keys[i], key);
assert_eq!(data[i], val);
}
assert!(iter.next().is_none());
}
#[test]
fn rev_iterator_test() {
let db = <$type>::default();
let first_collection: $type2 = db.create_collection("first");
build_state(&first_collection);
let mut iter = first_collection.iter(true, "first".to_string());
assert!(iter.next().is_none());
let mut iter = first_collection.iter(true, "".to_string());
let (keys, data) = build_initial_data();
for i in (0..3).rev() {
let (key, val) = iter.next().unwrap();
assert_eq!(keys[i], key);
assert_eq!(data[i], val);
}
assert!(iter.next().is_none());
}
}
};
}