summaryrefslogtreecommitdiff
path: root/schist_desktop_gui/src/database_connection.rs
diff options
context:
space:
mode:
Diffstat (limited to 'schist_desktop_gui/src/database_connection.rs')
-rw-r--r--schist_desktop_gui/src/database_connection.rs71
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))
+ }
+}