cleanup: validation and integrations for importing data

This commit is contained in:
uprightbass360
2025-11-22 16:49:01 -05:00
parent 5c9f1d7389
commit 71c1be1b46
17 changed files with 6797 additions and 369 deletions

View File

@@ -1,57 +1,167 @@
#!/bin/bash
# Fix item import for backup-merged characters
#
# Usage:
# fix-item-import.sh [OPTIONS]
#
# Options:
# --backup-dir DIR Path to backup directory (required)
# --account-ids IDS Comma-separated account IDs (e.g., "451,452")
# --char-guids GUIDS Comma-separated character GUIDs (e.g., "4501,4502,4503")
# --mysql-password PW MySQL root password (or use MYSQL_ROOT_PASSWORD env var)
# --mysql-container NAME MySQL container name (default: ac-mysql)
# --auth-db NAME Auth database name (default: acore_auth)
# --characters-db NAME Characters database name (default: acore_characters)
# -h, --help Show this help message
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
COLOR_RED='\033[0;31m'
COLOR_GREEN='\033[0;32m'
COLOR_YELLOW='\033[1;33m'
COLOR_BLUE='\033[0;34m'
COLOR_CYAN='\033[0;36m'
COLOR_RESET='\033[0m'
# Source common library
if [ -f "$SCRIPT_DIR/lib/common.sh" ]; then
source "$SCRIPT_DIR/lib/common.sh"
else
echo "ERROR: Common library not found at $SCRIPT_DIR/lib/common.sh" >&2
exit 1
fi
log(){ printf '%b\n' "${COLOR_GREEN}$*${COLOR_RESET}"; }
info(){ printf '%b\n' "${COLOR_CYAN}$*${COLOR_RESET}"; }
warn(){ printf '%b\n' "${COLOR_YELLOW}$*${COLOR_RESET}"; }
err(){ printf '%b\n' "${COLOR_RED}$*${COLOR_RESET}"; }
fatal(){ err "$*"; exit 1; }
# Default values (can be overridden by environment or command line)
BACKUP_DIR="${BACKUP_DIR:-}"
ACCOUNT_IDS="${ACCOUNT_IDS:-}"
CHAR_GUIDS="${CHAR_GUIDS:-}"
MYSQL_PW="${MYSQL_ROOT_PASSWORD:-}"
MYSQL_CONTAINER="${MYSQL_CONTAINER:-ac-mysql}"
AUTH_DB="${AUTH_DB:-acore_auth}"
CHARACTERS_DB="${CHARACTERS_DB:-acore_characters}"
MYSQL_PW="azerothcore123"
BACKUP_DIR="/nfs/containers/ac-backup"
AUTH_DB="acore_auth"
CHARACTERS_DB="acore_characters"
# Show help message
show_help() {
cat << EOF
Fix item import for backup-merged characters
# Verify parameters
[[ -d "$BACKUP_DIR" ]] || fatal "Backup directory not found: $BACKUP_DIR"
Usage:
fix-item-import.sh [OPTIONS]
Options:
--backup-dir DIR Path to backup directory (required)
--account-ids IDS Comma-separated account IDs (e.g., "451,452")
--char-guids GUIDS Comma-separated character GUIDs (e.g., "4501,4502,4503")
--mysql-password PW MySQL root password (or use MYSQL_ROOT_PASSWORD env var)
--mysql-container NAME MySQL container name (default: ac-mysql)
--auth-db NAME Auth database name (default: acore_auth)
--characters-db NAME Characters database name (default: acore_characters)
-h, --help Show this help message
Environment Variables:
BACKUP_DIR Alternative to --backup-dir
ACCOUNT_IDS Alternative to --account-ids
CHAR_GUIDS Alternative to --char-guids
MYSQL_ROOT_PASSWORD Alternative to --mysql-password
MYSQL_CONTAINER Alternative to --mysql-container
AUTH_DB Alternative to --auth-db
CHARACTERS_DB Alternative to --characters-db
Example:
fix-item-import.sh \\
--backup-dir /path/to/backup \\
--account-ids "451,452" \\
--char-guids "4501,4502,4503" \\
--mysql-password "azerothcore123"
EOF
exit 0
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--backup-dir)
BACKUP_DIR="$2"
shift 2
;;
--account-ids)
ACCOUNT_IDS="$2"
shift 2
;;
--char-guids)
CHAR_GUIDS="$2"
shift 2
;;
--mysql-password)
MYSQL_PW="$2"
shift 2
;;
--mysql-container)
MYSQL_CONTAINER="$2"
shift 2
;;
--auth-db)
AUTH_DB="$2"
shift 2
;;
--characters-db)
CHARACTERS_DB="$2"
shift 2
;;
-h|--help)
show_help
;;
*)
fatal "Unknown option: $1\nUse --help for usage information"
;;
esac
done
# Validate required parameters
if [ -z "$BACKUP_DIR" ]; then
fatal "Backup directory not specified. Use --backup-dir or set BACKUP_DIR environment variable."
fi
if [ ! -d "$BACKUP_DIR" ]; then
fatal "Backup directory not found: $BACKUP_DIR"
fi
if [ -z "$ACCOUNT_IDS" ]; then
fatal "Account IDs not specified. Use --account-ids or set ACCOUNT_IDS environment variable."
fi
if [ -z "$CHAR_GUIDS" ]; then
fatal "Character GUIDs not specified. Use --char-guids or set CHAR_GUIDS environment variable."
fi
if [ -z "$MYSQL_PW" ]; then
fatal "MySQL password not specified. Use --mysql-password or set MYSQL_ROOT_PASSWORD environment variable."
fi
# Setup temp directory
TEMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TEMP_DIR"' EXIT
# MySQL connection helper
mysql_exec(){
# MySQL connection helpers (override common.sh defaults with script-specific values)
mysql_exec_local(){
local db="$1"
docker exec -i ac-mysql mysql -uroot -p"$MYSQL_PW" "$db" 2>/dev/null
docker exec -i "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PW" "$db" 2>/dev/null
}
mysql_query(){
mysql_query_local(){
local db="$1"
local query="$2"
docker exec ac-mysql mysql -uroot -p"$MYSQL_PW" -N -B "$db" -e "$query" 2>/dev/null
docker exec "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PW" -N -B "$db" -e "$query" 2>/dev/null
}
log "═══════════════════════════════════════════════════════════"
log " FIXING ITEM IMPORT FOR BACKUP-MERGED CHARACTERS"
log "═══════════════════════════════════════════════════════════"
# Find characters that were imported from the backup (accounts 451, 452)
# Find characters that were imported from the backup
log "Finding characters that need item restoration..."
IMPORTED_CHARS=$(mysql_query "$CHARACTERS_DB" "SELECT name, guid FROM characters WHERE account IN (451, 452);")
info "Looking for characters with account IDs: $ACCOUNT_IDS"
IMPORTED_CHARS=$(mysql_query_local "$CHARACTERS_DB" "SELECT name, guid FROM characters WHERE account IN ($ACCOUNT_IDS);")
if [[ -z "$IMPORTED_CHARS" ]]; then
fatal "No imported characters found (accounts 451, 452)"
fatal "No imported characters found with account IDs: $ACCOUNT_IDS"
fi
info "Found imported characters:"
@@ -60,7 +170,8 @@ echo "$IMPORTED_CHARS" | while read -r char_name char_guid; do
done
# Check current item count for these characters
CURRENT_ITEM_COUNT=$(mysql_query "$CHARACTERS_DB" "SELECT COUNT(*) FROM item_instance WHERE owner_guid IN (4501, 4502, 4503);")
info "Checking existing items for character GUIDs: $CHAR_GUIDS"
CURRENT_ITEM_COUNT=$(mysql_query_local "$CHARACTERS_DB" "SELECT COUNT(*) FROM item_instance WHERE owner_guid IN ($CHAR_GUIDS);")
info "Current items for imported characters: $CURRENT_ITEM_COUNT"
if [[ "$CURRENT_ITEM_COUNT" != "0" ]]; then
@@ -94,26 +205,26 @@ log "Creating staging database..."
STAGE_CHARS_DB="fix_stage_chars_$$"
# Drop any existing staging database
docker exec ac-mysql mysql -uroot -p"$MYSQL_PW" -e "DROP DATABASE IF EXISTS $STAGE_CHARS_DB;" 2>/dev/null || true
docker exec "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PW" -e "DROP DATABASE IF EXISTS $STAGE_CHARS_DB;" 2>/dev/null || true
# Create staging database
docker exec ac-mysql mysql -uroot -p"$MYSQL_PW" -e "CREATE DATABASE $STAGE_CHARS_DB;" 2>/dev/null
docker exec "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PW" -e "CREATE DATABASE $STAGE_CHARS_DB;" 2>/dev/null
# Cleanup staging database on exit
cleanup_staging(){
if [[ -n "${STAGE_CHARS_DB:-}" ]]; then
docker exec ac-mysql mysql -uroot -p"$MYSQL_PW" -e "DROP DATABASE IF EXISTS $STAGE_CHARS_DB;" 2>/dev/null || true
docker exec "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PW" -e "DROP DATABASE IF EXISTS $STAGE_CHARS_DB;" 2>/dev/null || true
fi
}
trap 'cleanup_staging; rm -rf "$TEMP_DIR"' EXIT
# Load backup into staging database
info "Loading backup into staging database..."
sed "s/\`acore_characters\`/\`$STAGE_CHARS_DB\`/g; s/USE \`acore_characters\`;/USE \`$STAGE_CHARS_DB\`;/g" "$TEMP_DIR/characters.sql" | \
docker exec -i ac-mysql mysql -uroot -p"$MYSQL_PW" 2>/dev/null
sed "s/\`$CHARACTERS_DB\`/\`$STAGE_CHARS_DB\`/g; s/USE \`$CHARACTERS_DB\`;/USE \`$STAGE_CHARS_DB\`;/g" "$TEMP_DIR/characters.sql" | \
docker exec -i "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PW" 2>/dev/null
# Get current database state
CURRENT_MAX_ITEM_GUID=$(mysql_query "$CHARACTERS_DB" "SELECT COALESCE(MAX(guid), 0) FROM item_instance;")
CURRENT_MAX_ITEM_GUID=$(mysql_query_local "$CHARACTERS_DB" "SELECT COALESCE(MAX(guid), 0) FROM item_instance;")
ITEM_OFFSET=$((CURRENT_MAX_ITEM_GUID + 10000))
info "Current max item GUID: $CURRENT_MAX_ITEM_GUID"
@@ -121,22 +232,32 @@ info "Item GUID offset: +$ITEM_OFFSET"
# Create character mapping for the imported characters
log "Creating character mapping..."
mysql_exec "$STAGE_CHARS_DB" <<EOF
info "Building character GUID mapping from staging database..."
# Create mapping table dynamically based on imported characters
mysql_exec_local "$STAGE_CHARS_DB" <<EOF
CREATE TABLE character_guid_map (
old_guid INT UNSIGNED PRIMARY KEY,
new_guid INT UNSIGNED,
name VARCHAR(12)
);
EOF
# Populate mapping by matching character names from staging to current database
# This assumes character names are unique identifiers
mysql_exec_local "$STAGE_CHARS_DB" <<EOF
INSERT INTO character_guid_map (old_guid, new_guid, name)
VALUES
(1, 4501, 'Artimage'),
(2, 4502, 'Flombey'),
(3, 4503, 'Hammertime');
SELECT
s.guid as old_guid,
c.guid as new_guid,
c.name
FROM $STAGE_CHARS_DB.characters s
JOIN $CHARACTERS_DB.characters c ON s.name = c.name
WHERE c.account IN ($ACCOUNT_IDS);
EOF
# Create item GUID mapping
mysql_exec "$STAGE_CHARS_DB" <<EOF
mysql_exec_local "$STAGE_CHARS_DB" <<EOF
CREATE TABLE item_guid_map (
old_guid INT UNSIGNED PRIMARY KEY,
new_guid INT UNSIGNED,
@@ -153,7 +274,7 @@ INNER JOIN character_guid_map cm ON i.owner_guid = cm.old_guid;
EOF
# Check how many items will be imported
ITEMS_TO_IMPORT=$(mysql_query "$STAGE_CHARS_DB" "SELECT COUNT(*) FROM item_guid_map;")
ITEMS_TO_IMPORT=$(mysql_query_local "$STAGE_CHARS_DB" "SELECT COUNT(*) FROM item_guid_map;")
info "Items to import: $ITEMS_TO_IMPORT"
if [[ "$ITEMS_TO_IMPORT" == "0" ]]; then
@@ -195,7 +316,7 @@ EOSQL
)
ITEM_SQL_EXPANDED=$(echo "$ITEM_SQL" | sed "s/STAGE_CHARS_DB/$STAGE_CHARS_DB/g")
ITEM_RESULT=$(echo "$ITEM_SQL_EXPANDED" | docker exec -i ac-mysql mysql -uroot -p"$MYSQL_PW" "$CHARACTERS_DB" 2>&1)
ITEM_RESULT=$(echo "$ITEM_SQL_EXPANDED" | docker exec -i "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PW" "$CHARACTERS_DB" 2>&1)
if echo "$ITEM_RESULT" | grep -q "ERROR"; then
err "Item import failed:"
echo "$ITEM_RESULT" | grep "ERROR" >&2
@@ -217,7 +338,7 @@ EOSQL
)
INV_SQL_EXPANDED=$(echo "$INV_SQL" | sed "s/STAGE_CHARS_DB/$STAGE_CHARS_DB/g")
INV_RESULT=$(echo "$INV_SQL_EXPANDED" | docker exec -i ac-mysql mysql -uroot -p"$MYSQL_PW" "$CHARACTERS_DB" 2>&1)
INV_RESULT=$(echo "$INV_SQL_EXPANDED" | docker exec -i "$MYSQL_CONTAINER" mysql -uroot -p"$MYSQL_PW" "$CHARACTERS_DB" 2>&1)
if echo "$INV_RESULT" | grep -q "ERROR"; then
err "Inventory import failed:"
echo "$INV_RESULT" | grep "ERROR" >&2
@@ -225,8 +346,8 @@ if echo "$INV_RESULT" | grep -q "ERROR"; then
fi
# Report counts
ITEMS_IMPORTED=$(mysql_query "$CHARACTERS_DB" "SELECT COUNT(*) FROM item_instance WHERE owner_guid IN (4501, 4502, 4503);")
INV_IMPORTED=$(mysql_query "$CHARACTERS_DB" "SELECT COUNT(*) FROM character_inventory WHERE guid IN (4501, 4502, 4503);")
ITEMS_IMPORTED=$(mysql_query_local "$CHARACTERS_DB" "SELECT COUNT(*) FROM item_instance WHERE owner_guid IN ($CHAR_GUIDS);")
INV_IMPORTED=$(mysql_query_local "$CHARACTERS_DB" "SELECT COUNT(*) FROM character_inventory WHERE guid IN ($CHAR_GUIDS);")
info "Items imported: $ITEMS_IMPORTED"
info "Inventory slots imported: $INV_IMPORTED"