use std::sync::{Arc, LazyLock};
use dashmap::DashMap;
use crate::Result;
use crate::error::DbError;
use crate::executor::mapper::Mapper;
use crate::executor::session::Session;
use crate::udbc::DEFAULT_DB_NAME;
use crate::udbc::driver::Driver;
pub static U: LazyLock<DriverManager> = LazyLock::new(DriverManager::new);
pub struct DriverManager {
pools: DashMap<String, Arc<dyn Driver>>,
}
impl Default for DriverManager {
fn default() -> Self {
Self::new()
}
}
impl DriverManager {
pub fn new() -> Self {
Self {
pools: DashMap::new(),
}
}
pub fn register(&self, driver: impl Driver + 'static) -> Result<()> {
let name = driver.name().to_string();
if name == DEFAULT_DB_NAME && self.pools.contains_key(&name) {
return Err(DbError::DriverError(format!(
"Driver with name '{}' already registered",
name
)));
}
self.pools.insert(name, Arc::new(driver));
Ok(())
}
pub fn assets(&self, pattern: &str) -> Result<()> {
crate::mapper_loader::load(pattern).map_err(|e| {
DbError::MapperLoadError(format!("Failed to load mapper assets from pattern: {}", e))
})
}
pub fn session(&self) -> Option<Session> {
self.session_by_name(DEFAULT_DB_NAME)
}
pub fn session_by_name(&self, db_name: &str) -> Option<Session> {
self.pools
.get(db_name)
.map(|v| Session::new(v.value().clone()))
}
pub fn mapper(&self) -> Option<Mapper> {
self.mapper_by_name(DEFAULT_DB_NAME)
}
pub fn mapper_by_name(&self, db_name: &str) -> Option<Mapper> {
self.pools
.get(db_name)
.map(|v| Mapper::new(v.value().clone()))
}
}