use crate::catalog::Catalog;
use crate::commands::diff_output::{DiffContext, DiffFormat, has_differences, output_diff};
use crate::config::{Config, ObjectFilter};
use crate::diff::plan;
use crate::schema_ops::apply_current_schema_to_shadow;
use anyhow::Result;
use std::path::Path;
#[derive(Debug)]
pub struct MigrateDiffArgs {
pub format: DiffFormat,
pub output_sql: Option<String>,
}
impl Default for MigrateDiffArgs {
fn default() -> Self {
Self {
format: DiffFormat::Detailed,
output_sql: None,
}
}
}
pub async fn cmd_migrate_diff(
config: &Config,
root_dir: &Path,
args: MigrateDiffArgs,
target: &crate::config::TargetUrl,
shadow: &crate::config::ShadowDatabase,
) -> Result<()> {
eprintln!("Checking target database for drift...\n");
eprintln!("Loading schema files...");
let schema_catalog = apply_current_schema_to_shadow(config, root_dir, shadow).await?;
eprintln!("Loading target database...");
let target_pool =
crate::db::connection::connect_to_database(target.as_str(), "target database").await?;
let filter = ObjectFilter::from_config(config);
let target_catalog = Catalog::load_managed(&target_pool, &filter).await?;
eprintln!("Computing differences...\n");
let ordered_steps = plan(&target_catalog, &schema_catalog)?;
let context = DiffContext::new("target database", "schema files");
output_diff(
&ordered_steps,
&args.format,
&context,
&target_catalog,
&schema_catalog,
args.output_sql.as_deref(),
)?;
if has_differences(&ordered_steps) {
eprintln!("\nDrift detected! Target database differs from schema files.");
std::process::exit(1);
} else {
eprintln!("No drift detected. Target database matches schema files.");
}
Ok(())
}