Centralise error handling in SQLite manager
This commit is contained in:
parent
8a8ea5fb94
commit
5a615ad3a3
1 changed files with 45 additions and 77 deletions
|
|
@ -24,7 +24,7 @@ impl SqliteManager {
|
||||||
|
|
||||||
// The order of the items is undefined.
|
// The order of the items is undefined.
|
||||||
pub async fn films_overview(&self) -> Result<Vec<FilmOverview>, DataManagerError> {
|
pub async fn films_overview(&self) -> Result<Vec<FilmOverview>, DataManagerError> {
|
||||||
let overview = self
|
self
|
||||||
.client
|
.client
|
||||||
.conn(|connection| {
|
.conn(|connection| {
|
||||||
connection
|
connection
|
||||||
|
|
@ -33,38 +33,18 @@ impl SqliteManager {
|
||||||
select uuid, name, original_name, release_date, runtime_minutes
|
select uuid, name, original_name, release_date, runtime_minutes
|
||||||
from films
|
from films
|
||||||
",
|
",
|
||||||
)
|
)?
|
||||||
.expect("films overview statement should be valid SQL")
|
.query(())?
|
||||||
.query(())
|
|
||||||
.expect("parameters in films overview query should match those in its statement")
|
|
||||||
.map(row_to_film_overview)
|
.map(row_to_film_overview)
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
.await;
|
.await
|
||||||
|
.map_err(convert_error)
|
||||||
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,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The order of the items is undefined.
|
// The order of the items is undefined.
|
||||||
pub async fn series_overview(&self) -> Result<Vec<SeriesOverview>, DataManagerError> {
|
pub async fn series_overview(&self) -> Result<Vec<SeriesOverview>, DataManagerError> {
|
||||||
let overview = self
|
self
|
||||||
.client
|
.client
|
||||||
.conn(|connection| {
|
.conn(|connection| {
|
||||||
connection
|
connection
|
||||||
|
|
@ -76,33 +56,13 @@ impl SqliteManager {
|
||||||
where series.uuid = seasons.series and seasons.uuid = episodes.season
|
where series.uuid = seasons.series and seasons.uuid = episodes.season
|
||||||
group by series.uuid
|
group by series.uuid
|
||||||
",
|
",
|
||||||
)
|
)?
|
||||||
.expect("series overview statement should be valid SQL")
|
.query(())?
|
||||||
.query(())
|
|
||||||
.expect("parameters in series overview query should match those in its statement")
|
|
||||||
.map(row_to_series_overview)
|
.map(row_to_series_overview)
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
.await;
|
.await
|
||||||
|
.map_err(convert_error)
|
||||||
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,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,21 +88,13 @@ async fn create_client(data_dir: &OsStr) -> Result<Client, DataManagerError> {
|
||||||
let shared_path = shared_path_os_str
|
let shared_path = shared_path_os_str
|
||||||
.to_str()
|
.to_str()
|
||||||
.expect("shared database path should be valid Unicode");
|
.expect("shared database path should be valid Unicode");
|
||||||
connection
|
connection.execute("attach database :path as shared", &[(":path", shared_path)])?;
|
||||||
.execute("attach database :path as shared", &[(":path", shared_path)])
|
|
||||||
.expect(
|
|
||||||
"shared database attaching statement should be valid SQL with matching parameters",
|
|
||||||
);
|
|
||||||
|
|
||||||
let local_path_os_str = concat_os_str!(&data_dir, "/local.sqlite");
|
let local_path_os_str = concat_os_str!(&data_dir, "/local.sqlite");
|
||||||
let local_path = local_path_os_str
|
let local_path = local_path_os_str
|
||||||
.to_str()
|
.to_str()
|
||||||
.expect("local database path should be valid Unicode");
|
.expect("local database path should be valid Unicode");
|
||||||
connection
|
connection.execute("attach database :path as local", &[(":path", local_path)])?;
|
||||||
.execute("attach database :path as local", &[(":path", local_path)])
|
|
||||||
.expect(
|
|
||||||
"local database attaching statement should be valid SQL with matching parameters",
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|
@ -151,19 +103,7 @@ async fn create_client(data_dir: &OsStr) -> Result<Client, DataManagerError> {
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
client.map_err(|async_sqlite_error| match async_sqlite_error {
|
client.map_err(convert_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,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn row_to_film_overview(row: &Row) -> rusqlite::Result<FilmOverview> {
|
fn row_to_film_overview(row: &Row) -> rusqlite::Result<FilmOverview> {
|
||||||
|
|
@ -196,8 +136,36 @@ fn row_to_series_overview(row: &Row) -> rusqlite::Result<SeriesOverview> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
fn convert_error(async_sqlite_error: async_sqlite::Error) -> DataManagerError {
|
||||||
enum DBType {
|
match async_sqlite_error {
|
||||||
Shared,
|
async_sqlite::Error::Closed => {
|
||||||
Local,
|
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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue