sqlite.rs (1552B)
1 use rusqlite::{Connection, Row, Statement}; 2 use thiserror::Error; 3 4 pub use rusqlite::{ 5 types::Type as SqliteType, Error as RustqliteError, Result as SqliteResult, Row as SqliteRow, 6 }; 7 8 #[derive(Debug, Error)] 9 pub enum SqliteError { 10 #[error("Failed to open SQLite DB at `{path}`: {source}")] 11 ConnectionError { 12 path: String, 13 #[source] 14 source: rusqlite::Error, 15 }, 16 #[error("Failed to prepare SQL statement: {0}")] 17 PrepareError(#[source] rusqlite::Error), 18 #[error("Failed to run SQL query: {0}")] 19 QueryError(#[source] rusqlite::Error), 20 #[error("Failed to collect query results: {0}")] 21 CollectError(#[source] rusqlite::Error), 22 } 23 24 pub fn sqlite_conn(db_path: &str) -> Result<Connection, SqliteError> { 25 Connection::open(db_path).map_err(|e| SqliteError::ConnectionError { 26 path: db_path.to_string(), 27 source: e, 28 }) 29 } 30 31 pub fn sqlite_stmt<'a>(conn: &'a Connection, stmt: &'a str) -> Result<Statement<'a>, SqliteError> { 32 conn.prepare(stmt).map_err(SqliteError::PrepareError) 33 } 34 35 pub fn sqlite_stmt_querymap<'a, T, F>( 36 stmt: &'a mut Statement<'a>, 37 map_fn: F, 38 ) -> Result<Vec<T>, SqliteError> 39 where 40 F: Fn(&Row) -> rusqlite::Result<T>, 41 T: 'a, 42 { 43 let mapped = stmt 44 .query_map([], map_fn) 45 .map_err(SqliteError::QueryError)?; 46 mapped 47 .collect::<Result<Vec<_>, _>>() 48 .map_err(SqliteError::CollectError) 49 } 50 51 pub fn row_u64_at(row: &SqliteRow, idx: usize) -> SqliteResult<u64> { 52 let v: u32 = row.get(idx)?; 53 Ok(v as u64) 54 }