Skip to main content

waypoint_core/commands/
diff.rs

1//! Compare live database schema against a target and generate migration SQL.
2
3use serde::Serialize;
4use tokio_postgres::Client;
5
6use crate::config::WaypointConfig;
7use crate::error::Result;
8use crate::schema::{self, SchemaDiff};
9
10/// Target to compare the current schema against.
11pub enum DiffTarget {
12    /// Compare against another database identified by its connection URL.
13    Database(String),
14}
15
16/// Report produced by the diff command.
17#[derive(Debug, Serialize)]
18pub struct DiffReport {
19    /// List of individual schema differences found.
20    pub diffs: Vec<SchemaDiff>,
21    /// DDL SQL statements generated to reconcile the differences.
22    pub generated_sql: String,
23    /// Whether any differences were detected.
24    pub has_changes: bool,
25}
26
27/// Execute the diff command.
28pub async fn execute(
29    client: &Client,
30    config: &WaypointConfig,
31    target: DiffTarget,
32) -> Result<DiffReport> {
33    let schema_name = &config.migrations.schema;
34
35    // Introspect the current database schema
36    let current = schema::introspect(client, schema_name).await?;
37
38    let target_snapshot = match target {
39        DiffTarget::Database(ref url) => {
40            let target_client = crate::db::connect(url).await?;
41            schema::introspect(&target_client, schema_name).await?
42        }
43    };
44
45    let diffs = schema::diff(&current, &target_snapshot);
46    let generated_sql = schema::generate_ddl(&diffs);
47    let has_changes = !diffs.is_empty();
48
49    Ok(DiffReport {
50        diffs,
51        generated_sql,
52        has_changes,
53    })
54}