fix(sql): fix sql script
This commit is contained in:
101
scripts/db/rollback.sh
Normal file
101
scripts/db/rollback.sh
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)"
|
||||
|
||||
load_database_url_from_env_file() {
|
||||
local env_file="$1"
|
||||
local line value
|
||||
while IFS= read -r line || [[ -n "${line}" ]]; do
|
||||
line="${line#"${line%%[![:space:]]*}"}"
|
||||
[[ -z "${line}" || "${line}" == \#* ]] && continue
|
||||
line="${line#export }"
|
||||
if [[ "${line}" == DATABASE_URL=* ]]; then
|
||||
value="${line#DATABASE_URL=}"
|
||||
value="${value%$'\r'}"
|
||||
value="${value%\"}"
|
||||
value="${value#\"}"
|
||||
value="${value%\'}"
|
||||
value="${value#\'}"
|
||||
printf '%s' "${value}"
|
||||
return 0
|
||||
fi
|
||||
done < "${env_file}"
|
||||
return 1
|
||||
}
|
||||
|
||||
DATABASE_URL="${DATABASE_URL:-}"
|
||||
if [[ -z "${DATABASE_URL}" && -f "${ROOT_DIR}/.env" ]]; then
|
||||
DATABASE_URL="$(load_database_url_from_env_file "${ROOT_DIR}/.env" || true)"
|
||||
fi
|
||||
if [[ -z "${DATABASE_URL}" ]]; then
|
||||
echo "DATABASE_URL is required (export it, or set it in ${ROOT_DIR}/.env)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v psql >/dev/null 2>&1; then
|
||||
echo "psql not found in PATH"
|
||||
exit 127
|
||||
fi
|
||||
|
||||
CONFIRM="${CONFIRM:-0}"
|
||||
if [[ "${CONFIRM}" != "1" ]]; then
|
||||
echo "Refusing to run rollback without CONFIRM=1"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET_VERSION="${TARGET_VERSION:-}"
|
||||
STEPS="${STEPS:-1}"
|
||||
|
||||
if ! psql "${DATABASE_URL}" -v ON_ERROR_STOP=1 -c "SELECT 1 FROM iam_schema_migrations LIMIT 1" >/dev/null 2>&1; then
|
||||
echo "No iam_schema_migrations table found; nothing to rollback"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
applied_versions=()
|
||||
while IFS= read -r v; do
|
||||
[[ -n "${v}" ]] && applied_versions+=( "${v}" )
|
||||
done < <(psql "${DATABASE_URL}" -At -c "SELECT version FROM iam_schema_migrations ORDER BY version DESC")
|
||||
|
||||
if [[ ${#applied_versions[@]} -eq 0 ]]; then
|
||||
echo "No applied migrations; nothing to rollback"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
to_rollback=()
|
||||
if [[ -n "${TARGET_VERSION}" ]]; then
|
||||
for v in "${applied_versions[@]}"; do
|
||||
if [[ "${v}" > "${TARGET_VERSION}" ]]; then
|
||||
to_rollback+=( "${v}" )
|
||||
fi
|
||||
done
|
||||
else
|
||||
count=0
|
||||
for v in "${applied_versions[@]}"; do
|
||||
to_rollback+=( "${v}" )
|
||||
count=$((count + 1))
|
||||
if [[ "${count}" -ge "${STEPS}" ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ ${#to_rollback[@]} -eq 0 ]]; then
|
||||
echo "No migrations to rollback"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for v in "${to_rollback[@]}"; do
|
||||
down_file="${SCRIPT_DIR}/rollback/${v}.down.sql"
|
||||
if [[ ! -f "${down_file}" ]]; then
|
||||
echo "Missing rollback script: ${down_file}"
|
||||
exit 1
|
||||
fi
|
||||
echo "Rolling back ${v}"
|
||||
psql "${DATABASE_URL}" -v ON_ERROR_STOP=1 -f "${down_file}"
|
||||
psql "${DATABASE_URL}" -v ON_ERROR_STOP=1 -c "DELETE FROM iam_schema_migrations WHERE version='${v}'"
|
||||
done
|
||||
|
||||
echo "Rollback completed"
|
||||
|
||||
Reference in New Issue
Block a user