tracksolid_timescale_grafan.../run_migrations.sh

103 lines
4.2 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# run_migrations.sh — Tracksolid DB Migration Runner
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Applies any pending numbered SQL migration files in order.
# Safe to run on every deployment — skips already-applied migrations.
#
# Usage:
# ./run_migrations.sh # auto-detect container + DB
# ./run_migrations.sh --dry-run # show what would run, don't apply
#
# Called by Coolify post-deployment command:
# bash /app/run_migrations.sh
#
# How it tracks applied migrations:
# Creates tracksolid.schema_migrations table on first run.
# Records the filename of every successfully applied migration.
# Skips any file already recorded in that table.
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
set -euo pipefail
# ── Config ────────────────────────────────────────────────────────────────────
DB_NAME="${DB_NAME:-tracksolid_db}"
DB_USER="${DB_USER:-postgres}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DRY_RUN=false
# ── Argument parsing ──────────────────────────────────────────────────────────
for arg in "$@"; do
case $arg in
--dry-run) DRY_RUN=true ;;
esac
done
# ── Resolve TimescaleDB container ─────────────────────────────────────────────
TS_DB=$(docker ps --filter "name=timescale_db" --format "{{.Names}}" | head -1)
if [[ -z "$TS_DB" ]]; then
echo "ERROR: no running timescale_db container found." >&2
exit 1
fi
echo "Using container: $TS_DB"
# ── Helper: run SQL against the DB ───────────────────────────────────────────
run_sql() {
docker exec -i "$TS_DB" psql -U "$DB_USER" -d "$DB_NAME" "$@"
}
# ── Ensure migration tracking table exists ───────────────────────────────────
run_sql -c "
CREATE TABLE IF NOT EXISTS tracksolid.schema_migrations (
filename TEXT PRIMARY KEY,
applied_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
" > /dev/null
# ── Find and apply pending migrations ────────────────────────────────────────
MIGRATION_FILES=$(find "$SCRIPT_DIR" -maxdepth 1 -name '[0-9][0-9]_*.sql' | sort)
if [[ -z "$MIGRATION_FILES" ]]; then
echo "No migration files found in $SCRIPT_DIR"
exit 0
fi
APPLIED=0
SKIPPED=0
for filepath in $MIGRATION_FILES; do
filename=$(basename "$filepath")
# Check if already applied
already_applied=$(run_sql -t -c \
"SELECT COUNT(*) FROM tracksolid.schema_migrations WHERE filename = '$filename';" \
2>/dev/null | tr -d '[:space:]')
if [[ "$already_applied" == "1" ]]; then
echo " SKIP $filename (already applied)"
((SKIPPED++)) || true
continue
fi
if [[ "$DRY_RUN" == "true" ]]; then
echo " PENDING $filename (would apply)"
continue
fi
echo " APPLY $filename ..."
if run_sql < "$filepath"; then
# Record successful application
run_sql -c \
"INSERT INTO tracksolid.schema_migrations (filename) VALUES ('$filename');" \
> /dev/null
echo " OK $filename"
((APPLIED++)) || true
else
echo " FAIL $filename — aborting migration run" >&2
exit 1
fi
done
echo ""
echo "Migrations complete: $APPLIED applied, $SKIPPED skipped."