hms_db/
manager.rs

1use crate::{constants::DB_FILE, db::HmsDb, prelude::*};
2use diesel::{Connection, SqliteConnection};
3use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
4use hms_common::app_dir_client::AppDirClient;
5
6pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
7
8#[derive(Debug)]
9pub struct HmsDbManager<'a, P>
10where
11    P: AppDirClient,
12{
13    pub app_dir_client: &'a P,
14}
15
16impl<'a, P> HmsDbManager<'a, P>
17where
18    P: AppDirClient,
19{
20    pub fn new(app_dir_client: &'a P) -> HmsDbManager<P> {
21        HmsDbManager { app_dir_client }
22    }
23
24    pub fn db_exists(&self) -> Result<bool> {
25        let db_path = self.app_dir_client.get_app_dir_path()?.join(DB_FILE);
26        Ok(db_path.exists())
27    }
28
29    pub fn db_has_pending_migrations(&self) -> Result<bool> {
30        self.with_db(|db| {
31            db.conn.has_pending_migration(MIGRATIONS).map_err(|e| {
32                HmsDbError::MigrationError(format!("Unable to determine pending migrations: {}", e))
33            })
34        })
35    }
36
37    pub fn run_pending_migrations(&self) -> Result<()> {
38        self.with_db(|db| match db.conn.run_pending_migrations(MIGRATIONS) {
39            Ok(_) => Ok(()),
40            Err(e) => Err(HmsDbError::MigrationError(format!(
41                "Unable to run pending migrations: {}",
42                e
43            ))),
44        })
45    }
46
47    pub fn with_db<F, R>(&self, f: F) -> Result<R>
48    where
49        F: FnOnce(&mut HmsDb) -> Result<R>,
50    {
51        let database_path = self.app_dir_client.get_app_dir_path()?.join(DB_FILE);
52        let mut conn = SqliteConnection::establish(&database_path.to_string_lossy())?;
53
54        conn.transaction(|conn| {
55            let mut db = HmsDb { conn };
56            f(&mut db)
57        })
58    }
59}