use crate::error::Result; use std::path::Path; use geoffrey_models::GeoffreyDatabaseModel; use crate::u64_to_bytes; pub struct Database { db: sled::Db, } impl Database { pub fn new(db_path: &Path) -> Result { let db = sled::open(db_path)?; Ok(Self { db, }) } fn get_tree(&self) -> Result where T: GeoffreyDatabaseModel { Ok(self.db.open_tree::(T::tree())?) } pub fn insert(&self, mut model: T) -> Result where T: GeoffreyDatabaseModel { let id = match model.id() { Some(id) => id, None => { let id = self.db.generate_id()?; model.set_id(id); id } }; let tree = self.get_tree::()?; let id_bytes = u64_to_bytes(id); tree.insert(id_bytes, model.to_bytes()?)?; Ok(model) } pub fn get(&self, id: u64) -> Result> where T: GeoffreyDatabaseModel { let tree = self.get_tree::()?; let id_bytes = u64_to_bytes(id); if let Some(bytes) = tree.get(id_bytes)? { Ok(Some(T::try_from_bytes(&bytes)?)) } else { Ok(None) } } } #[cfg(test)] mod tests { use crate::database::{Database}; use std::path::Path; use geoffrey_models::models::player::{Player, UserID}; use lazy_static::lazy_static; use geoffrey_models::models::shop::Shop; use geoffrey_models::models::{Location, Position}; lazy_static! { static ref DB: Database = Database::new(Path::new("../database")).unwrap(); } fn cleanup() { DB.db.clear().unwrap(); } #[test] fn test_insert() { let player = Player::new("CoolZero123", UserID::DiscordUUID(0)); let p2 = DB.insert::(player.clone()).unwrap(); assert!(p2.id.is_some()); assert_eq!(player.name, p2.name); cleanup(); } #[test] fn test_get() { let player = Player::new("CoolZero123", UserID::DiscordUUID(0)); let p2 = DB.insert::(player.clone()).unwrap(); let p3 = DB.get::(p2.id.unwrap()).unwrap(); assert!(p3.is_some()); assert_eq!(p3.unwrap().name, player.name); cleanup(); } #[test] fn test_shop() { let player = Player::new("CoolZero123", UserID::DiscordUUID(0)); let player= DB.insert::(player.clone()).unwrap(); let shop = Shop::new("cool shop123", Position::default(), player.id.unwrap(), None); let shop2 = DB.insert::(shop.clone()).unwrap(); assert_eq!(shop.name(), shop2.name()); let shop3 = DB.get::(shop2.id.unwrap()).unwrap().unwrap(); assert_eq!(shop3.id, shop2.id); cleanup(); } }