qm_pg/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
mod config;
mod db;

use sqlx::Executor;

pub use crate::config::Config as DbConfig;
pub use crate::db::DB;

pub async fn ensure(app_name: &str, cfgs: &[&DbConfig]) -> anyhow::Result<()> {
    for cfg in cfgs {
        let db = DB::new_root(app_name, cfg).await?;
        let databases = sqlx::query!("SELECT datname FROM pg_database;")
            .fetch_all(db.pool())
            .await?;

        if let Some(database) = cfg.database() {
            if !databases.iter().any(|d| d.datname == database) {
                db.pool()
                    .execute(format!("CREATE DATABASE {database}").as_str())
                    .await?;
            }
        }

        if let Some((username, password)) = cfg.username().zip(cfg.password()) {
            let users = sqlx::query!("SELECT usename FROM pg_catalog.pg_user;")
                .fetch_all(db.pool())
                .await?;
            if !users.iter().any(|u| u.usename.as_deref() == Some(username)) {
                db.pool()
                    .execute(
                        format!("CREATE USER {username} WITH SUPERUSER PASSWORD '{password}'")
                            .as_str(),
                    )
                    .await?;
            }
        }
    }
    Ok(())
}