use rusqlite::{Connection, OptionalExtension}; use crate::config::Config; #[derive(Debug)] pub struct Case { pub id: String, pub n_runs: CaseType, } #[derive(Debug)] pub enum CaseType { Paired { n_runs_diag: u8, n_runs_mrd: u8 }, Diag { n_runs: u8 }, } pub struct DBCases { conn: Connection, } impl DBCases { pub fn new(config: &Config) -> anyhow::Result { let conn = Connection::open(&config.db_cases_path)?; Ok(DBCases { conn }) } pub fn add_case(&self, case: &Case) -> anyhow::Result<()> { match case.n_runs { CaseType::Paired { n_runs_diag, n_runs_mrd, } => { self.conn.execute( "INSERT INTO cases (id, type, n_runs_diag, n_runs_mrd) VALUES (?1, ?2, ?3, ?4)", (&case.id, "Paired", n_runs_diag, n_runs_mrd), )?; } CaseType::Diag { n_runs } => { self.conn.execute( "INSERT INTO cases (id, type, n_runs) VALUES (?1, ?2, ?3)", (&case.id, "Diag", n_runs), )?; } } Ok(()) } pub fn remove_case(&self, id: &str) -> anyhow::Result<()> { self.conn.execute("DELETE FROM cases WHERE id = ?1", [id])?; Ok(()) } pub fn search_case(&self, id: &str) -> anyhow::Result> { let mut stmt = self .conn .prepare("SELECT id, type, n_runs_diag, n_runs_mrd, n_runs FROM cases WHERE id = ?1")?; let case = stmt .query_row([id], |row| { let case_type: String = row.get(1)?; let n_runs = match case_type.as_str() { "Paired" => CaseType::Paired { n_runs_diag: row.get(2)?, n_runs_mrd: row.get(3)?, }, "Diag" => CaseType::Diag { n_runs: row.get(4)?, }, _ => { return Err(rusqlite::Error::InvalidColumnType( 1, "Unknown case type".into(), rusqlite::types::Type::Text, )) } }; Ok(Case { id: row.get(0)?, n_runs, }) }).optional()?; Ok(case) } pub fn create_table(&self) -> anyhow::Result<()> { self.conn.execute( "CREATE TABLE IF NOT EXISTS cases ( id TEXT PRIMARY KEY, type TEXT NOT NULL, n_runs_diag INTEGER, n_runs_mrd INTEGER, n_runs INTEGER )", [], )?; Ok(()) } }