feat(project): init
This commit is contained in:
91
scripts/db/verify.sh
Executable file
91
scripts/db/verify.sh
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)"
|
||||
MIGRATIONS_DIR="${ROOT_DIR}/migrations"
|
||||
VERIFY_DIR="${SCRIPT_DIR}/verify"
|
||||
|
||||
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
|
||||
|
||||
checksum_hex_of_file() {
|
||||
local file="$1"
|
||||
if command -v sha384sum >/dev/null 2>&1; then
|
||||
sha384sum "${file}" | awk '{print $1}'
|
||||
return 0
|
||||
fi
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
openssl dgst -sha384 -binary "${file}" | xxd -p -c 256
|
||||
return 0
|
||||
fi
|
||||
echo "sha384sum or openssl is required to compute sqlx checksum" >&2
|
||||
return 127
|
||||
}
|
||||
|
||||
psql "${DATABASE_URL}" -v ON_ERROR_STOP=1 -c "CREATE TABLE IF NOT EXISTS _sqlx_migrations (version BIGINT PRIMARY KEY, description TEXT NOT NULL, installed_on TIMESTAMPTZ NOT NULL DEFAULT now(), success BOOLEAN NOT NULL, checksum BYTEA NOT NULL, execution_time BIGINT NOT NULL)"
|
||||
|
||||
echo "Checking migration checksums in _sqlx_migrations..."
|
||||
|
||||
shopt -s nullglob
|
||||
migrations=( "${MIGRATIONS_DIR}/"*.sql )
|
||||
for file in "${migrations[@]}"; do
|
||||
base="$(basename "${file}")"
|
||||
version_str="${base%%_*}"
|
||||
version_num="$((10#${version_str}))"
|
||||
expected_checksum="$(checksum_hex_of_file "${file}")"
|
||||
actual_checksum="$(psql "${DATABASE_URL}" -At -c "SELECT encode(checksum,'hex') FROM _sqlx_migrations WHERE version=${version_num} AND success=true LIMIT 1" || true)"
|
||||
|
||||
if [[ -n "${actual_checksum}" && "${actual_checksum}" != "${expected_checksum}" ]]; then
|
||||
echo "Checksum mismatch: version=${version_str} expected=${expected_checksum} actual=${actual_checksum}"
|
||||
exit 2
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Running schema verify scripts..."
|
||||
|
||||
verify_files=( "${VERIFY_DIR}/"*.sql )
|
||||
if [[ ${#verify_files[@]} -eq 0 ]]; then
|
||||
echo "No verify files found: ${VERIFY_DIR}/*.sql"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for file in "${verify_files[@]}"; do
|
||||
base="$(basename "${file}")"
|
||||
echo "Verifying ${base}"
|
||||
psql "${DATABASE_URL}" -v ON_ERROR_STOP=1 -f "${file}" >/dev/null
|
||||
done
|
||||
|
||||
echo "Verify completed"
|
||||
Reference in New Issue
Block a user