#!/usr/bin/env bash # 洪荒大陆 · 数据库迁移脚本 # 用法: # ./scripts/migrate.sh # 执行 up 迁移 # ./scripts/migrate.sh down # 执行 down 迁移 set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # 加载 .env(若存在),也允许通过环境变量直接传入 DATABASE_URL if [ -f "$PROJECT_ROOT/.env" ]; then set -a # shellcheck source=/dev/null source "$PROJECT_ROOT/.env" set +a fi if [ -z "${DATABASE_URL:-}" ]; then echo "Error: DATABASE_URL is not set. Please create .env from .env.example or export DATABASE_URL." >&2 exit 1 fi if ! command -v psql >/dev/null 2>&1; then echo "Error: psql command not found. Please install PostgreSQL client." >&2 exit 1 fi # 等待数据库可达 wait_for_db() { local timeout="${DB_WAIT_TIMEOUT:-30}" local elapsed=0 echo "Waiting for database to be available..." until psql "$DATABASE_URL" -c "SELECT 1;" >/dev/null 2>&1; do if [ "$elapsed" -ge "$timeout" ]; then echo "Error: database not available after ${timeout}s (DATABASE_URL=$DATABASE_URL)" >&2 exit 1 fi printf "." sleep 1 elapsed=$((elapsed + 1)) done echo " OK" } wait_for_db MIGRATION_DIR="$PROJECT_ROOT/database/migrations" MIGRATION_PREFIX="001_init_schema" COMMAND="${1:-up}" if [ "$COMMAND" == "down" ]; then SQL_FILE="$MIGRATION_DIR/${MIGRATION_PREFIX}.down.sql" echo "Running migration DOWN: $SQL_FILE" else SQL_FILE="$MIGRATION_DIR/${MIGRATION_PREFIX}.up.sql" echo "Running migration UP: $SQL_FILE" fi if [ ! -f "$SQL_FILE" ]; then echo "Error: migration file not found: $SQL_FILE" >&2 exit 1 fi psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f "$SQL_FILE" echo "Migration '$COMMAND' completed successfully."