case.rs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. use rusqlite::{Connection, OptionalExtension};
  2. use crate::config::Config;
  3. #[derive(Debug)]
  4. pub struct Case {
  5. pub id: String,
  6. pub n_runs: CaseType,
  7. }
  8. #[derive(Debug)]
  9. pub enum CaseType {
  10. Paired { n_runs_diag: u8, n_runs_mrd: u8 },
  11. Diag { n_runs: u8 },
  12. }
  13. pub struct DBCases {
  14. conn: Connection,
  15. }
  16. impl DBCases {
  17. pub fn new(config: &Config) -> anyhow::Result<Self> {
  18. let conn = Connection::open(&config.db_cases_path)?;
  19. Ok(DBCases { conn })
  20. }
  21. pub fn add_case(&self, case: &Case) -> anyhow::Result<()> {
  22. match case.n_runs {
  23. CaseType::Paired {
  24. n_runs_diag,
  25. n_runs_mrd,
  26. } => {
  27. self.conn.execute(
  28. "INSERT INTO cases (id, type, n_runs_diag, n_runs_mrd) VALUES (?1, ?2, ?3, ?4)",
  29. (&case.id, "Paired", n_runs_diag, n_runs_mrd),
  30. )?;
  31. }
  32. CaseType::Diag { n_runs } => {
  33. self.conn.execute(
  34. "INSERT INTO cases (id, type, n_runs) VALUES (?1, ?2, ?3)",
  35. (&case.id, "Diag", n_runs),
  36. )?;
  37. }
  38. }
  39. Ok(())
  40. }
  41. pub fn remove_case(&self, id: &str) -> anyhow::Result<()> {
  42. self.conn.execute("DELETE FROM cases WHERE id = ?1", [id])?;
  43. Ok(())
  44. }
  45. pub fn search_case(&self, id: &str) -> anyhow::Result<Option<Case>> {
  46. let mut stmt = self
  47. .conn
  48. .prepare("SELECT id, type, n_runs_diag, n_runs_mrd, n_runs FROM cases WHERE id = ?1")?;
  49. let case = stmt
  50. .query_row([id], |row| {
  51. let case_type: String = row.get(1)?;
  52. let n_runs = match case_type.as_str() {
  53. "Paired" => CaseType::Paired {
  54. n_runs_diag: row.get(2)?,
  55. n_runs_mrd: row.get(3)?,
  56. },
  57. "Diag" => CaseType::Diag {
  58. n_runs: row.get(4)?,
  59. },
  60. _ => {
  61. return Err(rusqlite::Error::InvalidColumnType(
  62. 1,
  63. "Unknown case type".into(),
  64. rusqlite::types::Type::Text,
  65. ))
  66. }
  67. };
  68. Ok(Case {
  69. id: row.get(0)?,
  70. n_runs,
  71. })
  72. }).optional()?;
  73. Ok(case)
  74. }
  75. pub fn create_table(&self) -> anyhow::Result<()> {
  76. self.conn.execute(
  77. "CREATE TABLE IF NOT EXISTS cases (
  78. id TEXT PRIMARY KEY,
  79. type TEXT NOT NULL,
  80. n_runs_diag INTEGER,
  81. n_runs_mrd INTEGER,
  82. n_runs INTEGER
  83. )",
  84. [],
  85. )?;
  86. Ok(())
  87. }
  88. }