pepe_pg/
lib.rs

1use diesel::{connection::LoadConnection, migration::MigrationConnection, pg::Pg, Connection};
2use diesel_migrations::{EmbeddedMigrations, MigrationHarness};
3
4#[derive(thiserror::Error, Debug)]
5pub enum ConnectionError {
6    #[error("diesel error: {0}")]
7    Diesel(diesel::ConnectionError),
8}
9
10#[derive(thiserror::Error, Debug)]
11pub enum MigrationError {
12    #[error("database migration: {0}")]
13    GetMigration(String),
14    #[error("there are {0} pending migrations")]
15    PendingMigration(usize),
16}
17
18pub fn new_connection(
19    connection_url: &str,
20) -> Result<impl LoadConnection<Backend = Pg> + MigrationConnection<Backend = Pg>, ConnectionError>
21{
22    diesel::PgConnection::establish(connection_url).map_err(ConnectionError::Diesel)
23}
24
25#[cfg(feature = "tracing")]
26pub fn new_connection_with_tracing(
27    connection_url: &str,
28) -> Result<impl Connection<Backend = Pg> + LoadConnection<Backend = Pg>, ConnectionError> {
29    diesel_tracing::pg::InstrumentedPgConnection::establish(connection_url)
30        .map_err(ConnectionError::Diesel)
31}
32
33pub fn check_pending_migrations(
34    conn: &mut (impl LoadConnection<Backend = Pg> + MigrationConnection<Backend = Pg> + 'static),
35    migrations: EmbeddedMigrations,
36) -> Result<(), MigrationError> {
37    match count_pending_migrations(conn, migrations)? {
38        0 => Ok(()),
39        n => Err(MigrationError::PendingMigration(n)),
40    }
41}
42
43fn count_pending_migrations(
44    conn: &mut (impl LoadConnection<Backend = Pg> + MigrationConnection<Backend = Pg> + 'static),
45    migrations: EmbeddedMigrations,
46) -> Result<usize, MigrationError> {
47    let count_pending_migrations = MigrationHarness::pending_migrations(conn, migrations)
48        .map_err(|e| MigrationError::GetMigration(e.to_string()))?
49        .len();
50    Ok(count_pending_migrations)
51}