Geoffrey-rs/geoffrey_db/src/database.rs

114 lines
2.8 KiB
Rust
Raw Normal View History

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<Self> {
let db = sled::open(db_path)?;
Ok(Self {
db,
})
}
fn get_tree<T>(&self) -> Result<sled::Tree> where T: GeoffreyDatabaseModel {
Ok(self.db.open_tree::<String>(T::tree())?)
}
pub fn insert<T>(&self, mut model: T) -> Result<T> 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::<T>()?;
let id_bytes = u64_to_bytes(id);
tree.insert(id_bytes, model.to_bytes()?)?;
Ok(model)
}
pub fn get<T>(&self, id: u64) -> Result<Option<T>> where T: GeoffreyDatabaseModel {
let tree = self.get_tree::<T>()?;
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>(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>(player.clone()).unwrap();
let p3 = DB.get::<Player>(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>(player.clone()).unwrap();
let shop = Shop::new("cool shop123", Position::default(), player.id.unwrap(), None);
let shop2 = DB.insert::<Shop>(shop.clone()).unwrap();
assert_eq!(shop.name(), shop2.name());
let shop3 = DB.get::<Shop>(shop2.id.unwrap()).unwrap().unwrap();
assert_eq!(shop3.id, shop2.id);
cleanup();
}
}