use directories::ProjectDirs;
use std::path::{Path, PathBuf};
use thiserror::Error;
use super::schema;
#[derive(Error, Debug)]
pub enum DatabaseError {
#[error("Database error: {0}")]
Database(#[from] turso::Error),
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("Home directory not found")]
NoHomeDirectory,
}
pub(super) type Result<T> = std::result::Result<T, DatabaseError>;
#[derive(Debug)]
pub struct Database {
_db: turso::Database,
conn: turso::Connection,
path: PathBuf,
}
impl Database {
pub async fn open_default() -> Result<Self> {
let path = Self::default_path()?;
Self::open(&path).await
}
pub async fn open(path: &Path) -> Result<Self> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let db = turso::Builder::new_local(&path.to_string_lossy())
.build()
.await?;
let conn = db.connect()?;
schema::init_schema(&conn).await?;
Ok(Self {
_db: db,
conn,
path: path.to_path_buf(),
})
}
pub fn default_path() -> Result<PathBuf> {
if let Some(proj_dirs) = ProjectDirs::from("network", "kogito", "warcraft-rs") {
let data_dir = proj_dirs.data_dir();
Ok(data_dir.join("mpq-hashes.db"))
} else {
Err(DatabaseError::NoHomeDirectory)
}
}
pub fn connection(&self) -> &turso::Connection {
&self.conn
}
pub fn path(&self) -> &Path {
&self.path
}
}