Files
moonwell-core/import-custom-sql.sh
T

247 lines
7.1 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${ENV_FILE:-$ROOT_DIR/.env}"
if [[ -f "$ENV_FILE" ]]; then
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
fi
IMPORT_MYTHICPLUS_SQL="${ACORE_IMPORT_MYTHICPLUS_SQL:-1}"
IMPORT_STORE_SQL="${ACORE_IMPORT_STORE_SQL:-1}"
usage() {
cat <<EOF
Usage: $(basename "$0")
Imports required custom SQL that lives outside the normal AzerothCore module paths.
Currently this bootstraps the MythicPlus and Store Lua packages.
EOF
}
log() {
printf '[import-custom-sql] %s\n' "$*"
}
mysql_query() {
local database="$1"
local sql="$2"
docker compose exec -T ac-database bash -lc \
"mysql -N -s -uroot -p\"\$MYSQL_ROOT_PASSWORD\" \"$database\"" <<<"$sql"
}
mysql_exec() {
local database="${1:-}"
local sql="$2"
if [[ -n "$database" ]]; then
docker compose exec -T ac-database bash -lc \
"mysql -uroot -p\"\$MYSQL_ROOT_PASSWORD\" \"$database\"" <<<"$sql"
else
docker compose exec -T ac-database bash -lc \
"mysql -uroot -p\"\$MYSQL_ROOT_PASSWORD\"" <<<"$sql"
fi
}
table_exists() {
local database="$1"
local table_name="$2"
local result
result="$(mysql_query "information_schema" \
"SELECT COUNT(*) FROM tables WHERE table_schema = '${database}' AND table_name = '${table_name}';")"
[[ "$result" == "1" ]]
}
database_exists() {
local database="$1"
local result
result="$(mysql_query "information_schema" \
"SELECT COUNT(*) FROM schemata WHERE schema_name = '${database}';")"
[[ "$result" == "1" ]]
}
import_sql_file() {
local database="$1"
local file_path="$2"
if [[ ! -f "$file_path" ]]; then
printf 'SQL file not found: %s\n' "$file_path" >&2
exit 1
fi
log "importing $(basename "$file_path") into ${database}"
docker compose exec -T ac-database bash -lc \
"mysql -uroot -p\"\$MYSQL_ROOT_PASSWORD\" \"$database\"" < "$file_path"
}
require_integer_flag() {
local name="$1"
local value="$2"
if ! [[ "$value" =~ ^[01]$ ]]; then
printf '%s must be 0 or 1, got: %s\n' "$name" "$value" >&2
exit 1
fi
}
maybe_import_table() {
local database="$1"
local table_name="$2"
local file_path="$3"
if table_exists "$database" "$table_name"; then
log "table ${database}.${table_name} already exists, skipping"
return 0
fi
import_sql_file "$database" "$file_path"
}
import_mythicplus_sql() {
if [[ "$IMPORT_MYTHICPLUS_SQL" == "0" ]]; then
log "MythicPlus SQL import disabled, skipped"
return 0
fi
if [[ ! -d "$ROOT_DIR/sql/Mythic+" ]]; then
log "sql/Mythic+ directory not found, skipped"
return 0
fi
maybe_import_table "acore_characters" "character_mythic_history" \
"$ROOT_DIR/sql/Mythic+/characters/character_mythic_history.sql"
maybe_import_table "acore_characters" "character_mythic_keys" \
"$ROOT_DIR/sql/Mythic+/characters/character_mythic_keys.sql"
maybe_import_table "acore_characters" "character_mythic_rating" \
"$ROOT_DIR/sql/Mythic+/characters/character_mythic_rating.sql"
maybe_import_table "acore_characters" "character_mythic_vault" \
"$ROOT_DIR/sql/Mythic+/characters/character_mythic_vault.sql"
maybe_import_table "acore_characters" "character_mythic_weekly_affixes" \
"$ROOT_DIR/sql/Mythic+/characters/character_mythic_weekly_affixes.sql"
maybe_import_table "acore_world" "world_mythic_loot" \
"$ROOT_DIR/sql/Mythic+/world/world_mythic_loot.sql"
maybe_import_table "acore_world" "world_vault_loot" \
"$ROOT_DIR/sql/Mythic+/world/world_vault_loot.sql"
if [[ "$(mysql_query "acore_world" "
SELECT
CASE
WHEN EXISTS (SELECT 1 FROM creature_template WHERE entry = 900001)
AND EXISTS (SELECT 1 FROM item_template WHERE entry = 900100)
AND EXISTS (SELECT 1 FROM gameobject_template WHERE entry = 900000)
AND EXISTS (SELECT 1 FROM creature WHERE id1 = 900001 OR id2 = 900001 OR id3 = 900001)
AND EXISTS (SELECT 1 FROM gameobject WHERE id = 900000)
THEN 1
ELSE 0
END;
")" == "0" ]]; then
log "repairing MythicPlus world bootstrap entries"
mysql_exec "acore_world" "
DELETE FROM creature WHERE id1 = 900001 OR id2 = 900001 OR id3 = 900001;
DELETE FROM gameobject WHERE id = 900000;
DELETE FROM creature_template_locale WHERE entry = 900001;
DELETE FROM item_template_locale WHERE ID = 900100;
DELETE FROM creature_template_model WHERE CreatureID = 900001;
DELETE FROM creature_template WHERE entry = 900001;
DELETE FROM item_template WHERE entry = 900100;
DELETE FROM gameobject_template WHERE entry = 900000;
"
import_sql_file "acore_world" "$ROOT_DIR/sql/Mythic+/world/creature_and_keystones.sql"
else
log "MythicPlus creature bootstrap already exists, skipping"
fi
}
import_store_sql() {
local store_sql_file="$ROOT_DIR/sql/Store.sql"
local temp_sql=""
if [[ "$IMPORT_STORE_SQL" == "0" ]]; then
log "Store SQL import disabled, skipped"
return 0
fi
if [[ ! -d "$ROOT_DIR/lua_scripts/Store_System" ]]; then
log "lua_scripts/Store_System directory not found, skipped"
return 0
fi
if [[ ! -f "$store_sql_file" ]]; then
log "sql/Store.sql not found, skipped"
return 0
fi
if ! database_exists "store"; then
log "creating database store"
mysql_exec "" "CREATE DATABASE IF NOT EXISTS \`store\` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
fi
temp_sql="$(mktemp)"
{
printf 'CREATE DATABASE IF NOT EXISTS `store` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;\n'
printf 'USE `store`;\n'
awk '
BEGIN { skip = 0 }
skip {
if ($0 ~ /;[[:space:]]*$/) {
skip = 0
}
next
}
$0 ~ /^INSERT INTO `store_logs` / {
skip = 1
next
}
{
sub(/^INSERT INTO /, "INSERT IGNORE INTO ")
print
}
' "$store_sql_file"
} > "$temp_sql"
log "bootstrapping store database"
mysql_exec "" "$(cat "$temp_sql")"
rm -f "$temp_sql"
}
if (($# > 0)); then
case "$1" in
-h|--help)
usage
exit 0
;;
*)
printf 'Unknown option: %s\n\n' "$1" >&2
usage >&2
exit 1
;;
esac
fi
require_integer_flag "ACORE_IMPORT_MYTHICPLUS_SQL" "$IMPORT_MYTHICPLUS_SQL"
require_integer_flag "ACORE_IMPORT_STORE_SQL" "$IMPORT_STORE_SQL"
cd "$ROOT_DIR"
if ! docker compose ps --status running --services | grep -qx 'ac-database'; then
printf 'ac-database is not running. Start the database first.\n' >&2
exit 1
fi
import_mythicplus_sql
import_store_sql
log "custom SQL bootstrap completed"