From ffedd458cbda154e7203d8f5964468880d7ea904 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Wed, 29 Jul 2026 16:51:14 +0300 Subject: [PATCH] Update: 2026-07-29 16:51:14 --- backend/scripts/run_v2_migration.sh | 47 ++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/backend/scripts/run_v2_migration.sh b/backend/scripts/run_v2_migration.sh index e80b092..fa6463b 100755 --- a/backend/scripts/run_v2_migration.sh +++ b/backend/scripts/run_v2_migration.sh @@ -22,24 +22,40 @@ DUMP="$REPO/intaleqDBV2.sql" STAMP="$(date +%Y%m%d-%H%M%S)" BACKUP="$HOME/backup_mainDB_before_migration_$STAMP.sql" -SRC_DB="intaleqDBV2" # تُنشأ الآن داخل حاوية mysql من الملف -DST_DB="mainDB" # الهدف — نفس ما يشير إليه DB_PRIMARY_NAME_V2 - [[ -f "$ENV_FILE" ]] || { echo "✘ $ENV_FILE not found"; exit 1; } [[ -f "$DUMP" ]] || { echo "✘ $DUMP not found"; exit 1; } -ROOT_PW="$(grep -E '^MYSQL_ROOT_PASSWORD=' "$ENV_FILE" | cut -d= -f2- | tr -d '"'"'"'')" -APP_USER="$(grep -E '^DB_PRIMARY_USER_V2=' "$ENV_FILE" | cut -d= -f2- | tr -d '"'"'"'')" -CFG_DST="$(grep -E '^DB_PRIMARY_NAME_V2=' "$ENV_FILE" | cut -d= -f2- | tr -d '"'"'"'')" -[[ -n "$ROOT_PW" ]] || { echo "✘ MYSQL_ROOT_PASSWORD missing from $ENV_FILE"; exit 1; } +# آخر تعريف يفوز — نفس ما يفعله docker compose عند تكرار المفتاح في env_file +env_get() { grep -E "^$1=" "$ENV_FILE" | tail -n1 | cut -d= -f2- | tr -d '"'"'"'' ; } -# حارس الانعكاس: ما يشير إليه الباك إند هو ما نكتب فيه، لا غير -if [[ "$CFG_DST" != "$DST_DB" ]]; then - echo "✘ ABORT: DB_PRIMARY_NAME_V2 is '$CFG_DST' but this script writes to '$DST_DB'." - echo " Fix docker/.env or this script — do not guess." +ROOT_PW="$(env_get MYSQL_ROOT_PASSWORD)" +APP_USER="$(env_get DB_PRIMARY_USER_V2)" +APP_PASS="$(env_get DB_PRIMARY_PASS_V2)" + +# الهدف يُقرأ من البيئة ولا يُثبَّت هنا: الهدف هو بالتعريف ما يتكلم معه +# الباك إند، وأي اسم مكتوب في السكربت سيكون تخميناً يخالف النشر الفعلي. +DST_DB="$(env_get DB_PRIMARY_NAME_V2)" +SRC_DB="$(env_get SRC_DB_NAME)" +SRC_USER="$(env_get SRC_DB_USER)" +SRC_PASS="$(env_get SRC_DB_PASS)" + +[[ -n "$ROOT_PW" ]] || { echo "✘ MYSQL_ROOT_PASSWORD missing from $ENV_FILE"; exit 1; } +[[ -n "$DST_DB" ]] || { echo "✘ DB_PRIMARY_NAME_V2 missing from $ENV_FILE"; exit 1; } +[[ -n "$SRC_DB" ]] || SRC_DB="intaleqDBV2" + +# حارس الانعكاس — الوحيد الذي لا يُتجاوز +if [[ "$SRC_DB" == "$DST_DB" ]]; then + echo "✘ ABORT: source and target are the same database ($DST_DB)." + echo " SRC_DB_NAME must be the OLD db; DB_PRIMARY_NAME_V2 the NEW one." exit 1 fi -if [[ "$SRC_DB" == "$DST_DB" ]]; then echo "✘ ABORT: source == target"; exit 1; fi + +# بيانات دخول المصدر يجب أن تكون لمستخدم موجود فعلاً — القيم المنسوخة من +# .env.example لا تعمل على نشر غيّر أسماء المستخدمين. +if [[ "$SRC_USER" != "$APP_USER" ]]; then + echo "⚠️ SRC_DB_USER ('$SRC_USER') differs from DB_PRIMARY_USER_V2 ('$APP_USER')." + echo " Unless that user really exists, set SRC_DB_USER/SRC_DB_PASS to the app user." +fi # دوال التنفيذ داخل الحاويات sql_root() { $DC exec -T mysql mysql -uroot -p"$ROOT_PW" "$@"; } @@ -95,8 +111,11 @@ else $DC exec -T mysql mysql -uroot -p"$ROOT_PW" "$SRC_DB" < "$DUMP" echo " ✔ imported" fi -# صلاحية قراءة فقط لمستخدم التطبيق — الترحيل لا يكتب في المصدر إطلاقاً -sql_root -e "GRANT SELECT ON \`$SRC_DB\`.* TO '$APP_USER'@'%'; FLUSH PRIVILEGES;" +# صلاحية قراءة فقط لمستخدم المصدر — الترحيل لا يكتب في المصدر إطلاقاً +sql_root -e "GRANT SELECT ON \`$SRC_DB\`.* TO '$SRC_USER'@'%'; FLUSH PRIVILEGES;" +# تأكيد أن بيانات الدخول تعمل فعلاً قبل الوصول إلى مرحلة الكتابة +$DC exec -T mysql mysql -u"$SRC_USER" -p"$SRC_PASS" -N -B -e "SELECT 1 FROM \`$SRC_DB\`.driver LIMIT 1" >/dev/null 2>&1 \ + || { echo "✘ SRC_DB_USER/SRC_DB_PASS cannot read $SRC_DB — fix them in docker/.env, then: docker compose -f docker/docker-compose.yml up -d php"; exit 1; } sql_root -N -B -e "SELECT CONCAT(' drivers=',(SELECT COUNT(*) FROM \`$SRC_DB\`.driver), ' passengers=',(SELECT COUNT(*) FROM \`$SRC_DB\`.passengers), ' cars=',(SELECT COUNT(*) FROM \`$SRC_DB\`.CarRegistration))"