69 行
1.8 KiB
Bash
可执行文件
69 行
1.8 KiB
Bash
可执行文件
#!/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."
|