#![cfg(feature = "openapi")]
use std::fs::File;
use anyhow::Result;
use openapiv3::OpenAPI;
use sqlx::{Connection, Executor};
use sqldiff::Schema;
#[derive(Parser)]
#[command(author, version, about)]
struct Cli {
#[clap(long)]
dry: bool,
}
#[tokio::main]
async fn main() -> Result<()> {
let url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let schema_name = "public";
let mut conn = sqlx::postgres::PgConnection::connect(&url).await?;
let current = Schema::try_from_database(&mut conn, schema_name).await?;
let openapi_file = std::env::var("OPENAPI_FILE").expect("OPENAPI_FILE must be set");
let spec: OpenAPI = serde_yaml::from_reader(File::open(openapi_file)?)?;
let desired = Schema::try_from(spec)?;
let migration = current.migrate_to(desired, Options {})?;
if migration.statements.is_empty() {
println!("No migration needed");
return Ok(())
}
let dry = !std::env::var("RUN").map(|s| s == "1").unwrap_or(false);
if dry {
println!("Dry run. Set RUN=1 to execute.");
}
for statement in migration.statements {
let statement = statement.prepare(schema_name);
println!("{}", statement);
if !dry {
conn.execute(&*statement).await?;
}
}
Ok(())
}