From 62b4b8b22df3c6aaf8569e984f258878e52c860b Mon Sep 17 00:00:00 2001 From: "Aaron K. Clark" Date: Sun, 17 May 2026 19:25:22 -0500 Subject: [PATCH] fix(setup): make TimeTracker.sql idempotent against an existing schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit setup/TimeTracker.sql is the pg_dump-produced bootstrap script. It wasn't authored with idempotency in mind: \`CREATE SCHEMA dbo\` (no IF NOT EXISTS), followed by ~40 statements that include \`CREATE TABLE\` without IF NOT EXISTS and \`ALTER TABLE ADD CONSTRAINT\` (which has no IF NOT EXISTS form at all). Result: \`docker compose up setup\` against a populated postgres volume exits 3 with "schema dbo already exists", which in turn prevents the chained \`migrate\` service from running, which left the docs in PR #56 with the \`docker compose down -v\` papercut. Rather than retrofit IF-NOT-EXISTS guards to every individual statement (and lose on ADD CONSTRAINT), gate the entire file at the top with a psql \\if check: SELECT EXISTS ( SELECT 1 FROM information_schema.schemata WHERE schema_name = 'dbo' ) AS dbo_exists \\gset \\if :dbo_exists \\echo 'dbo schema already exists — setup/TimeTracker.sql is a no-op' \\q \\endif If the schema is there, psql exits 0 with a friendly message; the chained migrate service then runs as designed. If the schema isn't there, the rest of the pg_dump body executes exactly as before. Verified locally against the running compose postgres: - DROP SCHEMA dbo CASCADE → fresh run exit 0, 14 tables created - immediate re-run → "no-op" message, exit 0 - subsequent migrate service still works (verified earlier this session) Co-Authored-By: Claude Opus 4.7 (1M context) --- setup/TimeTracker.sql | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/setup/TimeTracker.sql b/setup/TimeTracker.sql index 9ad5ee48..9f92bf60 100644 --- a/setup/TimeTracker.sql +++ b/setup/TimeTracker.sql @@ -16,6 +16,26 @@ SET xmloption = content; SET client_min_messages = warning; SET row_security = off; +-- +-- Idempotency guard. If the dbo schema already exists, treat this +-- bootstrap script as a no-op rather than failing on CREATE SCHEMA. +-- That makes \`docker compose up\` survive re-runs against a populated +-- postgres-data volume without needing \`down -v\` first. +-- +-- The rest of the file is pg_dump output that wasn't authored with +-- idempotency in mind (CREATE TABLE without IF NOT EXISTS, ALTER +-- TABLE ADD CONSTRAINT which has no IF NOT EXISTS form, etc.). +-- Rather than retrofit IF NOT EXISTS to ~40 statements piecemeal, +-- we gate the whole file on whether the schema is already present. +-- +SELECT EXISTS ( + SELECT 1 FROM information_schema.schemata WHERE schema_name = 'dbo' +) AS dbo_exists \gset +\if :dbo_exists +\echo 'dbo schema already exists — setup/TimeTracker.sql is a no-op' +\q +\endif + -- -- Name: dbo; Type: SCHEMA; Schema: -; Owner: timetracker --