use rusqlite::Connection; use std::collections::HashMap; use std::path::PathBuf; use std::sync::{Arc, Mutex}; use crate::error::{AppError, AppResult}; pub struct DatabaseManager { connections: HashMap, base_path: PathBuf, } impl DatabaseManager { pub fn new(base_path: PathBuf) -> Self { Self { connections: HashMap::new(), base_path, } } pub fn get_db_path(&self, user_id: &str) -> PathBuf { self.base_path.join(format!("eritors-local-{}.db", user_id)) } pub fn initialize(&mut self, user_id: &str) -> AppResult<()> { if self.connections.contains_key(user_id) { return Ok(()); } let db_path = self.get_db_path(user_id); if let Some(parent) = db_path.parent() { std::fs::create_dir_all(parent)?; } let conn = Connection::open(&db_path)?; conn.execute_batch("PRAGMA journal_mode=WAL;")?; conn.execute_batch("PRAGMA foreign_keys=ON;")?; self.connections.insert(user_id.to_string(), conn); Ok(()) } pub fn get_connection(&self, user_id: &str) -> AppResult<&Connection> { self.connections .get(user_id) .ok_or_else(|| AppError::Database(rusqlite::Error::InvalidParameterName( format!("No database connection for user: {}", user_id), ))) } pub fn close(&mut self, user_id: &str) { self.connections.remove(user_id); } } pub type DbManager = Arc>; pub fn create_db_manager(base_path: PathBuf) -> DbManager { Arc::new(Mutex::new(DatabaseManager::new(base_path))) }