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}