use std::path::Path;
use rusqlite::Connection;
use thiserror::Error;
use super::schema;
use crate::config;
#[derive(Debug, Error)]
pub enum DbError {
#[error("sqlite error: {0}")]
Sqlite(#[from] rusqlite::Error),
#[error("io error: {0}")]
Io(#[from] std::io::Error),
}
pub struct Database {
pub conn: Connection,
}
impl Database {
pub fn open(path: &Path) -> Result<Self, DbError> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let conn = Connection::open(path)?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let _ = std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o600));
}
conn.pragma_update(None, "journal_mode", "wal")?;
conn.pragma_update(None, "foreign_keys", "on")?;
conn.pragma_update(None, "busy_timeout", 5000)?;
conn.pragma_update(None, "synchronous", "normal")?;
let _ = conn.execute_batch("PRAGMA wal_checkpoint(PASSIVE)");
schema::create_tables(&conn)?;
Ok(Self { conn })
}
pub fn open_default() -> Result<Self, DbError> {
Self::open(&config::db_path())
}
}