calathea/src/db/mod.rs

70 lines
1.8 KiB
Rust

mod models;
#[rustfmt::skip]
mod schema;
use diesel::{
r2d2::{ConnectionManager, Pool},
SqliteConnection,
};
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
use std::{error::Error, fmt, path::Path};
pub use models::event::{Event, NewEvent, EVENT_TYPES};
pub use models::image::{Image, NewImage};
pub use models::plant::{NewPlant, Plant};
pub use models::session::Session;
pub use models::user::{NewUser, User};
pub type DbPool = Pool<ConnectionManager<SqliteConnection>>;
pub type DbResult<T> = Result<T, DbError>;
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations");
#[derive(Debug)]
pub enum DbError {
Pool(diesel::r2d2::PoolError),
Db(diesel::result::Error),
}
impl fmt::Display for DbError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Pool(_) => write!(f, "failed to acquire connection from pool"),
Self::Db(_) => write!(f, "error while executing query"),
}
}
}
impl Error for DbError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Pool(err) => Some(err),
Self::Db(err) => Some(err),
}
}
}
impl From<diesel::r2d2::PoolError> for DbError {
fn from(value: diesel::r2d2::PoolError) -> Self {
Self::Pool(value)
}
}
impl From<diesel::result::Error> for DbError {
fn from(value: diesel::result::Error) -> Self {
Self::Db(value)
}
}
pub fn initialize_db(path: impl AsRef<Path>, run_migrations: bool) -> Result<DbPool, DbError> {
let manager = ConnectionManager::<SqliteConnection>::new(path.as_ref().to_string_lossy());
let pool = Pool::new(manager)?;
if run_migrations {
pool.get()?.run_pending_migrations(MIGRATIONS).unwrap();
}
Ok(pool)
}