use tokio_postgres::Client;
use super::error::ApplyError;
pub async fn bootstrap_metadata(client: &mut Client) -> Result<(), ApplyError> {
client.batch_execute(SQL_BOOTSTRAP_SCHEMA).await?;
let row = client
.query_one(
"SELECT COALESCE(max(version), 0)::int FROM pgevolve.bootstrap_version",
&[],
)
.await?;
let current: i32 = row.get(0);
for m in BOOTSTRAP_MIGRATIONS.iter().filter(|m| m.version > current) {
let tx = client.transaction().await?;
tx.batch_execute(m.sql).await?;
tx.execute(
"INSERT INTO pgevolve.bootstrap_version (version, applied_at)
VALUES ($1, now())",
&[&m.version],
)
.await?;
tx.commit().await?;
}
Ok(())
}
struct BootstrapMigration {
version: i32,
sql: &'static str,
}
const SQL_BOOTSTRAP_SCHEMA: &str = "\
CREATE SCHEMA IF NOT EXISTS pgevolve;
CREATE TABLE IF NOT EXISTS pgevolve.bootstrap_version (
version int PRIMARY KEY,
applied_at timestamptz NOT NULL DEFAULT now()
);
";
const BOOTSTRAP_MIGRATIONS: &[BootstrapMigration] = &[BootstrapMigration {
version: 1,
sql: "\
CREATE TABLE pgevolve.apply_log (
apply_id uuid PRIMARY KEY,
plan_id text NOT NULL,
plan_hash text NOT NULL,
pgevolve_version text NOT NULL,
source_rev text,
target_identity text NOT NULL,
actor text,
started_at timestamptz NOT NULL DEFAULT now(),
finished_at timestamptz,
status text NOT NULL
CHECK (status IN ('running','succeeded','failed','aborted')),
error_message text
);
CREATE INDEX apply_log_started_at_idx ON pgevolve.apply_log (started_at DESC);
CREATE TABLE pgevolve.plan_steps (
apply_id uuid NOT NULL REFERENCES pgevolve.apply_log(apply_id) ON DELETE CASCADE,
step_no int NOT NULL,
group_no int NOT NULL,
kind text NOT NULL,
destructive boolean NOT NULL,
targets text[] NOT NULL,
sql_text text NOT NULL,
started_at timestamptz,
finished_at timestamptz,
status text NOT NULL
CHECK (status IN ('pending','running','succeeded','failed','rolled_back','skipped')),
error_message text,
PRIMARY KEY (apply_id, step_no)
);
CREATE TABLE pgevolve.lock (
singleton boolean PRIMARY KEY DEFAULT true CHECK (singleton),
held_by text,
held_since timestamptz,
pgevolve_version text
);
INSERT INTO pgevolve.lock (singleton) VALUES (true);
",
}];