ciboulette2pg 0.1.3

Library to execute Ciboulette query to Postgres and build responses back
Documentation
use lazy_static::lazy_static;
use std::str::FromStr;
use std::sync::Mutex;
use uuid::Uuid;

mod embedded_migrations {
    use refinery::embed_migrations;
    embed_migrations!("./tests_migrations");
}

lazy_static! {
    static ref BASILIQ_DATABASE_URL: String =
        std::env::var("DATABASE_URL").expect("the database url to be set");
    static ref BASILIQ_DEFAULT_DATABASE: String = format!("basiliq_test_{}", Uuid::new_v4());
    static ref BASILIQ_DEFAULT_DATABASE_INIT: Mutex<bool> = Mutex::new(false);
}

pub async fn run_migrations(db_name: &str) {
    let mut config = refinery::config::Config::from_env_var("DATABASE_URL")
        .expect("to parse the basiliq database url")
        .set_db_name(db_name);
    embedded_migrations::migrations::runner()
        .run_async(&mut config)
        .await
        .expect("to apply migrations");
}

fn connect_to_management_pool() -> sqlx::PgPool {
    let num = num_cpus::get();

    sqlx::pool::PoolOptions::new()
        .min_connections(1)
        .max_connections(num as u32)
        .connect_lazy(&BASILIQ_DATABASE_URL)
        .expect("to initialize the management Postgres connection pool")
}
pub async fn init_db() -> (String, sqlx::PgPool) {
    let management_pool = connect_to_management_pool();
    {
        let mut init_bool = BASILIQ_DEFAULT_DATABASE_INIT
            .lock()
            .expect("the database management mutex is poisoned");
        {
            if !*init_bool {
                sqlx::query(
                    format!("CREATE DATABASE \"{}\";", BASILIQ_DEFAULT_DATABASE.as_str()).as_str(),
                )
                .execute(&management_pool)
                .await
                .expect("to create a new database");
                run_migrations(BASILIQ_DEFAULT_DATABASE.as_str()).await;
                *init_bool = true;
            }
        }
    }
    let db_name = format!("basiliq_test_{}", Uuid::new_v4());
    sqlx::query(
        format!(
            "CREATE DATABASE \"{}\" WITH TEMPLATE \"{}\";",
            db_name.as_str(),
            BASILIQ_DEFAULT_DATABASE.as_str()
        )
        .as_str(),
    )
    .execute(&management_pool)
    .await
    .expect("to create a new database");
    let conn_opt = sqlx::postgres::PgConnectOptions::from_str(&BASILIQ_DATABASE_URL)
        .expect("to parse the basiliq database url")
        .database(db_name.as_str());
    let pool = sqlx::pool::PoolOptions::new()
        .min_connections(1)
        .max_connections(3)
        .connect_lazy_with(conn_opt);
    (db_name, pool)
}

pub async fn deinit_db(db_id: String) {
    let management_pool = connect_to_management_pool();
    sqlx::query(format!("DROP DATABASE \"{}\"", db_id.as_str(),).as_str())
        .execute(&management_pool)
        .await
        .expect("to create a new database");
}