diff --git a/src/persist/sqlite_manager.rs b/src/persist/sqlite_manager.rs index f3ace8a..ef46186 100644 --- a/src/persist/sqlite_manager.rs +++ b/src/persist/sqlite_manager.rs @@ -24,7 +24,7 @@ impl SqliteManager { // The order of the items is undefined. pub async fn films_overview(&self) -> Result, DataManagerError> { - let overview = self + self .client .conn(|connection| { connection @@ -33,38 +33,18 @@ impl SqliteManager { select uuid, name, original_name, release_date, runtime_minutes from films ", - ) - .expect("films overview statement should be valid SQL") - .query(()) - .expect("parameters in films overview query should match those in its statement") + )? + .query(())? .map(row_to_film_overview) .collect() }) - .await; - - overview.map_err(|async_sqlite_error| match async_sqlite_error { - async_sqlite::Error::Closed => { - panic!("database connection should remain open as long as the application is running") - } - async_sqlite::Error::Rusqlite(rusqlite_error) => match rusqlite_error { - rusqlite::Error::InvalidColumnIndex(_) => { - panic!("column indices obtained from films overview query should exist") - } - rusqlite::Error::InvalidColumnName(_) => { - panic!("column names obtained from films overview query should exist") - } - rusqlite::Error::InvalidColumnType(..) => panic!( - "values obtained from films overview query should have a type matching their column" - ), - _ => DataManagerError::UnknownDBError, - }, - _ => DataManagerError::UnknownDBError, - }) + .await + .map_err(convert_error) } // The order of the items is undefined. pub async fn series_overview(&self) -> Result, DataManagerError> { - let overview = self + self .client .conn(|connection| { connection @@ -76,33 +56,13 @@ impl SqliteManager { where series.uuid = seasons.series and seasons.uuid = episodes.season group by series.uuid ", - ) - .expect("series overview statement should be valid SQL") - .query(()) - .expect("parameters in series overview query should match those in its statement") + )? + .query(())? .map(row_to_series_overview) .collect() }) - .await; - - overview.map_err(|async_sqlite_error| match async_sqlite_error { - async_sqlite::Error::Closed => { - panic!("database connection should remain open as long as the application is running") - } - async_sqlite::Error::Rusqlite(rusqlite_error) => match rusqlite_error { - rusqlite::Error::InvalidColumnIndex(_) => { - panic!("column indices obtained from series overview query should exist") - } - rusqlite::Error::InvalidColumnName(_) => { - panic!("column names obtained from series overview query should exist") - } - rusqlite::Error::InvalidColumnType(..) => panic!( - "values obtained from series overview query should have a type matching their column" - ), - _ => DataManagerError::UnknownDBError, - }, - _ => DataManagerError::UnknownDBError, - }) + .await + .map_err(convert_error) } } @@ -128,21 +88,13 @@ async fn create_client(data_dir: &OsStr) -> Result { let shared_path = shared_path_os_str .to_str() .expect("shared database path should be valid Unicode"); - connection - .execute("attach database :path as shared", &[(":path", shared_path)]) - .expect( - "shared database attaching statement should be valid SQL with matching parameters", - ); + connection.execute("attach database :path as shared", &[(":path", shared_path)])?; let local_path_os_str = concat_os_str!(&data_dir, "/local.sqlite"); let local_path = local_path_os_str .to_str() .expect("local database path should be valid Unicode"); - connection - .execute("attach database :path as local", &[(":path", local_path)]) - .expect( - "local database attaching statement should be valid SQL with matching parameters", - ); + connection.execute("attach database :path as local", &[(":path", local_path)])?; Ok(()) }) @@ -151,19 +103,7 @@ async fn create_client(data_dir: &OsStr) -> Result { }) .await; - client.map_err(|async_sqlite_error| match async_sqlite_error { - async_sqlite::Error::Closed => { - panic!("database connection should remain open as long as the application is running") - } - async_sqlite::Error::Rusqlite(rusqlite_error) => match rusqlite_error { - rusqlite::Error::SqliteFailure(sqlite_error, _) => match sqlite_error.code { - rusqlite::ffi::ErrorCode::CannotOpen => DataManagerError::CannotOpenDB, - _ => DataManagerError::UnknownDBError, - }, - _ => DataManagerError::UnknownDBError, - }, - _ => DataManagerError::UnknownDBError, - }) + client.map_err(convert_error) } fn row_to_film_overview(row: &Row) -> rusqlite::Result { @@ -196,8 +136,36 @@ fn row_to_series_overview(row: &Row) -> rusqlite::Result { }) } -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -enum DBType { - Shared, - Local, +fn convert_error(async_sqlite_error: async_sqlite::Error) -> DataManagerError { + match async_sqlite_error { + async_sqlite::Error::Closed => { + panic!("database connection should remain open as long as the application is running") + } + async_sqlite::Error::Rusqlite(rusqlite_error) => match rusqlite_error { + rusqlite::Error::SqliteFailure(sqlite_error, _) => match sqlite_error.code { + rusqlite::ffi::ErrorCode::CannotOpen => DataManagerError::CannotOpenDB, + _ => DataManagerError::UnknownDBError, + }, + rusqlite::Error::InvalidColumnIndex(_) => { + panic!("column indices obtained from query should exist") + } + rusqlite::Error::InvalidColumnName(_) => { + panic!("column names obtained from query should exist") + } + rusqlite::Error::InvalidColumnType(..) => { + panic!("values obtained from query should have a type matching their column") + } + rusqlite::Error::InvalidParameterCount(..) => { + panic!("number of bound parameters should match that in the statement") + } + rusqlite::Error::ExecuteReturnedResults => { + panic!("execution of statement returned data when it shouldn't") + } + rusqlite::Error::MultipleStatement => { + panic!("multiple statements present when there should be one") + } + _ => DataManagerError::UnknownDBError, + }, + _ => DataManagerError::UnknownDBError, + } }