use diesel::{connection::LoadConnection, migration::MigrationConnection, pg::Pg, Connection};
use diesel_migrations::{EmbeddedMigrations, MigrationHarness};
#[derive(thiserror::Error, Debug)]
pub enum ConnectionError {
#[error("diesel error: {0}")]
Diesel(diesel::ConnectionError),
}
#[derive(thiserror::Error, Debug)]
pub enum MigrationError {
#[error("database migration: {0}")]
GetMigration(String),
#[error("there are {0} pending migrations")]
PendingMigration(usize),
}
pub fn new_connection(
connection_url: &str,
) -> Result<
impl Connection<Backend = Pg> + LoadConnection<Backend = Pg> + MigrationConnection<Backend = Pg>,
ConnectionError,
> {
diesel::PgConnection::establish(connection_url).map_err(ConnectionError::Diesel)
}
#[cfg(feature = "tracing")]
pub fn new_connection_with_tracing(
connection_url: &str,
) -> Result<impl Connection<Backend = Pg> + LoadConnection<Backend = Pg>, ConnectionError> {
diesel_tracing::pg::InstrumentedPgConnection::establish(connection_url)
.map_err(ConnectionError::Diesel)
}
pub fn check_pending_migrations(
conn: &mut (impl Connection<Backend = Pg>
+ LoadConnection<Backend = Pg>
+ MigrationConnection<Backend = Pg>
+ 'static),
migrations: EmbeddedMigrations,
) -> Result<(), MigrationError> {
match count_pending_migrations(conn, migrations)? {
0 => Ok(()),
n => Err(MigrationError::PendingMigration(n)),
}
}
fn count_pending_migrations(
conn: &mut (impl Connection<Backend = Pg>
+ LoadConnection<Backend = Pg>
+ MigrationConnection<Backend = Pg>
+ 'static),
migrations: EmbeddedMigrations,
) -> Result<usize, MigrationError> {
let count_pending_migrations = MigrationHarness::pending_migrations(conn, migrations)
.map_err(|e| MigrationError::GetMigration(e.to_string()))?
.len();
Ok(count_pending_migrations)
}