use std::path::Path;
use rusqlite::Connection;
use tracing::{debug, info};
use crate::core::config::expand_path;
use crate::core::errors::{Result, TgaError};
pub mod azdo_iterations;
pub mod collection_runs;
pub mod migrations;
pub mod work_items;
pub use azdo_iterations::{list_iterations, upsert_iteration};
pub use collection_runs::{is_week_collected, record_collection_run, repo_count_for_week};
pub use work_items::{
get_work_item, get_work_items_for_commit, link_commit_work_item, list_work_items,
upsert_work_item, WorkItemRow,
};
pub struct Database {
conn: Connection,
}
impl Database {
pub fn open(path: &Path) -> Result<Database> {
let resolved = expand_path(path);
debug!(path = %resolved.display(), "opening database");
let conn = Connection::open(&resolved)?;
Self::apply_pragmas(&conn)?;
let mut db = Database { conn };
migrations::run(&mut db.conn)?;
info!(path = %resolved.display(), "database ready");
Ok(db)
}
pub fn open_in_memory() -> Result<Database> {
let conn = Connection::open_in_memory()?;
Self::apply_pragmas(&conn)?;
let mut db = Database { conn };
migrations::run(&mut db.conn)?;
Ok(db)
}
fn apply_pragmas(conn: &Connection) -> Result<()> {
let mode: String = conn
.query_row("PRAGMA journal_mode=WAL", [], |row| row.get(0))
.map_err(TgaError::from)?;
debug!(journal_mode = %mode, "applied WAL pragma");
conn.execute_batch(
"PRAGMA synchronous = NORMAL; \
PRAGMA foreign_keys = ON; \
PRAGMA cache_size = -65536; \
PRAGMA temp_store = MEMORY; \
PRAGMA mmap_size = 268435456;",
)?;
debug!("applied SQLite tuning pragmas (cache=64MB, mmap=256MB, temp=memory)");
Ok(())
}
pub fn connection(&self) -> &Connection {
&self.conn
}
pub fn connection_mut(&mut self) -> &mut Connection {
&mut self.conn
}
pub fn journal_mode(&self) -> Result<String> {
let mode: String = self
.conn
.query_row("PRAGMA journal_mode", [], |row| row.get(0))
.map_err(TgaError::from)?;
Ok(mode)
}
pub fn schema_version(&self) -> Result<i64> {
let v: i64 = self
.conn
.query_row(
"SELECT COALESCE(MAX(version), 0) FROM schema_migrations",
[],
|row| row.get(0),
)
.map_err(TgaError::from)?;
Ok(v)
}
}