diff options
Diffstat (limited to 'schist_desktop_gui/src/database_connection.rs')
| -rw-r--r-- | schist_desktop_gui/src/database_connection.rs | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/schist_desktop_gui/src/database_connection.rs b/schist_desktop_gui/src/database_connection.rs new file mode 100644 index 0000000..99fbe2d --- /dev/null +++ b/schist_desktop_gui/src/database_connection.rs @@ -0,0 +1,71 @@ +use std::{fmt, path::PathBuf}; + +use anyhow::Context; +use diesel::{Connection, SqliteConnection}; +use diesel_migrations::MigrationHarness; +use schist_models::migrations::MIGRATIONS; + +pub struct DatabaseConnection { + pub connection: diesel::SqliteConnection, + pub file_path: PathBuf, +} + +impl DatabaseConnection { + pub fn establish(file_path: PathBuf) -> DatabaseConnectionResult { + DatabaseConnectionResult { + connection: Self::establish_sqlite_connection(&file_path), + file_path: file_path, + } + } + + fn establish_sqlite_connection(file_path: &PathBuf) -> anyhow::Result<SqliteConnection> { + let file_path_str = file_path + .to_str() + .with_context(|| format!("Failed to get database path from {:?}", file_path))?; + let mut connection = diesel::SqliteConnection::establish(&file_path_str) + .with_context(|| format!("Failed to connect to database at {}", file_path_str))?; + connection + .run_pending_migrations(MIGRATIONS) + .map_err(anyhow::Error::from_boxed) + .with_context(|| { + format!( + "Failed to run pending migrations on database at {}", + file_path_str + ) + })?; + Ok(connection) + } +} + +impl fmt::Debug for DatabaseConnection { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SqliteConnection") + .field("file_path", &self.file_path) + .finish() + } +} + +pub struct DatabaseConnectionResult { + pub connection: anyhow::Result<SqliteConnection>, + pub file_path: PathBuf, +} + +impl DatabaseConnectionResult { + pub fn ok(self) -> Result<DatabaseConnection, (PathBuf, anyhow::Error)> { + self.try_into() + } +} + +impl TryFrom<DatabaseConnectionResult> for DatabaseConnection { + type Error = (PathBuf, anyhow::Error); + + fn try_from(result: DatabaseConnectionResult) -> Result<Self, Self::Error> { + result + .connection + .map(|connection| DatabaseConnection { + connection, + file_path: result.file_path.clone(), + }) + .map_err(|err| (result.file_path, err)) + } +} |
