use std::collections::BTreeMap;
use monsta_proto::*;
use tokio::sync::Mutex;
use crate::{database::Database, Error, Result};
pub struct Universe {
inner: Mutex<Inner>,
}
struct Inner {
databases: BTreeMap<u64, Database>,
database_ids: BTreeMap<String, u64>,
next_database_id: u64,
}
impl Universe {
pub fn new() -> Self {
let inner = Inner {
databases: BTreeMap::new(),
database_ids: BTreeMap::new(),
next_database_id: 1,
};
Self {
inner: Mutex::new(inner),
}
}
pub async fn database(&self, id: u64) -> Option<Database> {
let inner = self.inner.lock().await;
inner.databases.get(&id).cloned()
}
pub async fn create_database(&self, spec: DatabaseSpec) -> Result<Database> {
let mut inner = self.inner.lock().await;
if inner.database_ids.contains_key(&spec.name) {
return Err(Error::AlreadyExists(format!("database name {}", spec.name)));
}
let id = inner.next_database_id;
inner.next_database_id += 1;
let name = spec.name.clone();
let db = Database::new(id, spec);
inner.databases.insert(id, db.clone());
inner.database_ids.insert(name, id);
Ok(db)
}
pub async fn lookup_database(&self, name: &str) -> Option<Database> {
let inner = self.inner.lock().await;
inner
.database_ids
.get(name)
.and_then(|id| inner.databases.get(id).cloned())
}
}