c3p0_pg 0.24.0

A good friend for r2d2
Documentation
use crate::json::{PgC3p0Json, PgC3p0JsonBuilder};
use crate::pool::{PgC3p0Pool, PgConnection};
use c3p0_common::error::C3p0Error;
use c3p0_common::json::builder::C3p0JsonBuilder;
use c3p0_common::json::codec::DefaultJsonCodec;
use c3p0_common::pool::SqlConnection;

use c3p0_common::migrate::*;

pub trait PgC3p0MigrateBuilder {
    fn build(self) -> C3p0Migrate<PgConnection, PgC3p0Pool, PgMigrator>;
}

impl PgC3p0MigrateBuilder for C3p0MigrateBuilder<PgConnection, PgC3p0Pool> {
    fn build(self) -> C3p0Migrate<PgConnection, PgC3p0Pool, PgMigrator> {
        C3p0Migrate::new(
            self.table,
            self.schema,
            self.migrations,
            self.c3p0,
            PgMigrator {},
        )
    }
}

#[derive(Clone)]
pub struct PgMigrator {}

impl Migrator for PgMigrator {
    type CONN = PgConnection;
    type C3P0 = PgC3p0Pool;
    type C3P0JSON = PgC3p0Json<MigrationData, DefaultJsonCodec>;

    fn build_cp30_json(
        &self,
        table: String,
        schema: Option<String>,
    ) -> PgC3p0Json<MigrationData, DefaultJsonCodec> {
        C3p0JsonBuilder::<PgC3p0Pool>::new(table)
            .with_schema_name(schema)
            .build()
    }

    fn lock_table(
        &self,
        c3p0_json: &PgC3p0Json<MigrationData, DefaultJsonCodec>,
        conn: &PgConnection,
    ) -> Result<(), C3p0Error> {
        conn.batch_execute(&format!(
            "LOCK TABLE {} IN ACCESS EXCLUSIVE MODE",
            c3p0_json.queries().qualified_table_name
        ))
    }

    fn lock_first_migration_row(
        &self,
        c3p0_json: &PgC3p0Json<MigrationData, DefaultJsonCodec>,
        conn: &PgConnection,
    ) -> Result<(), C3p0Error> {
        let lock_sql = format!(
            r#"select * from {} where {}->>'migration_id' = $1 FOR UPDATE"#,
            c3p0_json.queries().qualified_table_name,
            c3p0_json.queries().data_field_name
        );
        conn.fetch_one(&lock_sql, &[&C3P0_INIT_MIGRATION_ID], |_| Ok(()))
    }
}