You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.7 KiB
Bash

#!/usr/bin/env sh
# Apply SQL migrations to PostgreSQL (Docker Compose service "postgres" by default).
#
# By default skips 000001_* (bootstrap + seeds): Docker initdb runs it on first volume
# create; re-applying breaks on duplicate INSERTs. Set MIGRATE_INCLUDE_BOOTSTRAP=1 to
# include it (empty DB, no initdb hook).
#
# Usage:
# ./scripts/migrate.sh
# DB_USER=myuser DB_NAME=mydb ./scripts/migrate.sh
# MIGRATE_INCLUDE_BOOTSTRAP=1 ./scripts/migrate.sh
set -eu
ROOT_DIR="$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)"
MIGRATIONS_DIR="${ROOT_DIR}/backend/migrations"
DB_USER="${DB_USER:-autohero}"
DB_NAME="${DB_NAME:-autohero}"
COMPOSE_FILE="${COMPOSE_FILE:-${ROOT_DIR}/docker-compose.yml}"
cd "${ROOT_DIR}"
if ! docker compose -f "${COMPOSE_FILE}" exec -T postgres pg_isready -U "${DB_USER}" -d "${DB_NAME}" >/dev/null 2>&1; then
echo "migrate.sh: postgres is not ready or container is not running. Start: docker compose up -d postgres" >&2
exit 1
fi
apply_file() {
f="$1"
name="$(basename "$f")"
echo "Applying ${name}..."
docker compose -f "${COMPOSE_FILE}" exec -T postgres \
psql -v ON_ERROR_STOP=1 -U "${DB_USER}" -d "${DB_NAME}" < "$f"
}
# Sorted list (000001, 000002, ...); skip 000001 unless MIGRATE_INCLUDE_BOOTSTRAP=1
found=0
for f in $(find "${MIGRATIONS_DIR}" -maxdepth 1 -name '*.sql' | sort); do
found=1
base="$(basename "$f")"
case "${base}" in
000001_*.sql)
if [ "${MIGRATE_INCLUDE_BOOTSTRAP:-0}" != "1" ]; then
echo "Skipping ${base} (set MIGRATE_INCLUDE_BOOTSTRAP=1 to apply bootstrap on an empty DB)"
continue
fi
;;
esac
apply_file "$f"
done
if [ "${found}" -eq 0 ]; then
echo "migrate.sh: no .sql files in ${MIGRATIONS_DIR}" >&2
exit 1
fi
echo "Done."