Skip to content

cloudiful/db-init

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cloudiful-db-init

Shared helpers for project-local db_init binaries that use PostgreSQL and SQLx migrations.

The crate is intentionally small. It does not try to own your migration path, your config schema, or your project-specific post-migration work. Instead, it gives each repository a reusable toolkit for:

  • optional .env loading
  • database URL resolution with explicit priority
  • PostgreSQL connection setup
  • SQLx migration execution
  • optional post-migration hooks

Why this shape

Different projects still need to keep some ownership:

  • sqlx::migrate!() paths are compile-time and should stay in the calling repository
  • env/config priority often varies by application
  • seed, backfill, and repair steps are business logic and usually should not live inside a generic migration helper

Example

use anyhow::{Context, Result, anyhow};
use cloudiful_db_init::{
    DbInitOptions, init_database_with_hook, load_dotenv_if_exists, resolve_database_url,
};
use config::{ReadOptions, read};
use serde::{Deserialize, Serialize};
use sqlx::migrate::Migrator;

static MIGRATOR: Migrator = sqlx::migrate!("../migrations");

#[derive(Debug, Default, Deserialize, Serialize)]
struct DbInitConfig {
    app_db: Option<AppDbConfig>,
}

#[derive(Debug, Default, Deserialize, Serialize)]
struct AppDbConfig {
    url: Option<String>,
}

#[tokio::main]
async fn main() {
    if let Err(error) = run().await {
        eprintln!("fatal: {error:#}");
        std::process::exit(1);
    }
}

async fn run() -> Result<()> {
    load_dotenv_if_exists(".env")?;

    let resolution = resolve_database_url(
        None,
        &["CONTEXT69_APP_DB__URL", "DATABASE_URL"],
        || {
            let config: DbInitConfig = read(
                "context69",
                Some(ReadOptions::with_env_prefix("CONTEXT69_")),
            )
            .map_err(|error| anyhow!(error).context("failed to load application config"))?;
            Ok(config.app_db.and_then(|app_db| app_db.url))
        },
    )?;

    init_database_with_hook(
        &resolution.database_url,
        &MIGRATOR,
        DbInitOptions::default(),
        |_pool| async { Ok(()) },
    )
    .await?;

    println!("database init completed");
    Ok(())
}

Release

This repository publishes to crates.io from the v* tag workflow in .github/workflows/publish.yml.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages