From c030ea5fc6d4ba9263728bd7bfa285e089e562fd Mon Sep 17 00:00:00 2001 From: duckietm Date: Fri, 3 Apr 2026 19:10:55 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=86=99=20Small=20update=20to=20SQL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Database Updates/001_optimize_gameserver.sql | 615 +------------------ 1 file changed, 20 insertions(+), 595 deletions(-) diff --git a/Database Updates/001_optimize_gameserver.sql b/Database Updates/001_optimize_gameserver.sql index 5183aa52..88546176 100644 --- a/Database Updates/001_optimize_gameserver.sql +++ b/Database Updates/001_optimize_gameserver.sql @@ -1,148 +1,20 @@ --- ============================================================================= --- Gameserver Database Optimization Migration --- ============================================================================= --- This migration optimizes the gameserver tables (not website_* tables). --- --- IMPORTANT: This script is designed to run on a POPULATED database safely. --- It uses IF NOT EXISTS / IF EXISTS where possible. --- --- What it does: --- 1. Converts Aria/MyISAM tables to InnoDB (required for foreign keys) --- 2. Fixes data type mismatches (unsigned/signed) so FKs can be created --- 3. Adds missing primary keys and indexes --- 4. Adds foreign key constraints for referential integrity --- --- BEFORE RUNNING: --- - Back up your database! --- - Run on a test environment first --- - The script disables FK checks during migration to avoid ordering issues --- ============================================================================= - SET FOREIGN_KEY_CHECKS = 0; SET @OLD_SQL_MODE = @@SQL_MODE; SET SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO'; --- ============================================================================= --- PHASE 1: Convert storage engines to InnoDB, ROW_FORMAT to DYNAMIC --- ============================================================================= --- Foreign keys require InnoDB. Converting Aria and MyISAM tables. --- InnoDB does not support ROW_FORMAT=FIXED, so all tables get ROW_FORMAT=DYNAMIC. --- Note: Aria tables lose PAGE_CHECKSUM (InnoDB has its own checksumming). - --- Core emulator tables ALTER TABLE IF EXISTS `achievements` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `bot_serves` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `catalog_clothing` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `catalog_club_offers` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `catalog_featured_pages` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `catalog_items_limited` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `chatlogs_private` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `chatlogs_room` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `commandlogs` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `emulator_errors` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; - --- Items & marketplace ALTER TABLE IF EXISTS `items` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `items_crackable` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `items_hoppers` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `items_presents` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `items_teleports` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `marketplace_items` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; - --- Navigator & rooms -ALTER TABLE IF EXISTS `navigator_publiccats` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `navigator_publics` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `navigator_filter` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `navigator_flatcats` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `nux_gifts` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; ALTER TABLE IF EXISTS `rooms` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `room_bans` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `room_enter_log` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `room_game_scores` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `room_models` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `room_models_custom` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `room_mutes` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `room_promotions` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `room_rights` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `room_votes` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `room_wordfilter` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; - --- Pets -ALTER TABLE IF EXISTS `pet_breeding` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `pet_breeding_races` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `pet_breeds` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `pet_drinks` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `pet_foods` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `pet_items` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; - --- Polls -ALTER TABLE IF EXISTS `polls` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `polls_answers` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `polls_questions` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; - --- Users ALTER TABLE IF EXISTS `users_achievements` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `users_achievements_queue` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `users_clothing` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `users_currency` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `users_effects` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `users_favorite_rooms` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `users_navigator_settings` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `users_pets` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `users_recipes` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `user_window_settings` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; - --- Misc -ALTER TABLE IF EXISTS `crafting_altars_recipes` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `crafting_recipes` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `crafting_recipes_ingredients` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `namechange_log` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `recycler_prizes` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `special_enables` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `vouchers` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; +ALTER TABLE IF EXISTS `catalog_items` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; +ALTER TABLE IF EXISTS `catalog_pages` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; +ALTER TABLE IF EXISTS `navigator_flatcats` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; ALTER TABLE IF EXISTS `wordfilter` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `wired_rewards_given` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `youtube_playlists` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; -ALTER TABLE IF EXISTS `bots` ENGINE = InnoDB, ROW_FORMAT = DYNAMIC; +ALTER TABLE IF EXISTS `logs_shop_purchases` MODIFY `user_id` int(11) DEFAULT NULL; +ALTER TABLE IF EXISTS `users_subscriptions` MODIFY `user_id` int(11) DEFAULT NULL; +ALTER TABLE IF EXISTS `items` MODIFY `item_id` int(11) unsigned DEFAULT 0; --- ============================================================================= --- PHASE 2: Fix data type mismatches (unsigned vs signed) --- ============================================================================= --- Foreign keys require EXACT type matches including signedness. --- Fix columns where referenced PK and referencing FK differ. - --- 2a. users.id is int(11) SIGNED → fix unsigned user_id columns -ALTER TABLE IF EXISTS `logs_hc_payday` - MODIFY `user_id` int(11) DEFAULT NULL; - -ALTER TABLE IF EXISTS `logs_shop_purchases` - MODIFY `user_id` int(11) DEFAULT NULL; - -ALTER TABLE IF EXISTS `users_subscriptions` - MODIFY `user_id` int(11) DEFAULT NULL; - --- 2b. items_base.id is int(11) UNSIGNED → fix signed FK columns to match -ALTER TABLE IF EXISTS `items` - MODIFY `item_id` int(11) unsigned DEFAULT 0; - -ALTER TABLE IF EXISTS `economy_furniture` - MODIFY `items_base_id` int(11) unsigned NOT NULL; - -ALTER TABLE IF EXISTS `items_crackable` - MODIFY `item_id` int(11) unsigned NOT NULL; - --- 2c. guilds_forums_threads.id is int(10) UNSIGNED → fix signed FK columns -ALTER TABLE IF EXISTS `guilds_forums_comments` - MODIFY `thread_id` int(10) unsigned NOT NULL DEFAULT 0; - - --- ============================================================================= --- PHASE 3: Add missing primary keys --- ============================================================================= --- Tables without primary keys hurt performance and replication. --- Uses a helper procedure to safely add `id` column only if it doesn't exist. - DELIMITER // DROP PROCEDURE IF EXISTS `_add_id_pk_if_missing`// CREATE PROCEDURE `_add_id_pk_if_missing`(IN tbl VARCHAR(64)) @@ -163,59 +35,7 @@ DELIMITER ; CALL `_add_id_pk_if_missing`('bot_serves'); CALL `_add_id_pk_if_missing`('chatlogs_room'); CALL `_add_id_pk_if_missing`('commandlogs'); -CALL `_add_id_pk_if_missing`('crafting_recipes_ingredients'); - --- items_hoppers: use existing item_id as PK (skip if PK already exists) -SET @has_pk = (SELECT COUNT(*) FROM `information_schema`.`TABLE_CONSTRAINTS` - WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'items_hoppers' AND `CONSTRAINT_TYPE` = 'PRIMARY KEY'); -SET @sql = IF(@has_pk = 0, 'ALTER TABLE `items_hoppers` ADD PRIMARY KEY (`item_id`)', 'SELECT 1'); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - -CALL `_add_id_pk_if_missing`('items_presents'); -CALL `_add_id_pk_if_missing`('items_teleports'); -CALL `_add_id_pk_if_missing`('namechange_log'); -CALL `_add_id_pk_if_missing`('navigator_publics'); - -CALL `_add_id_pk_if_missing`('pet_breeding'); -CALL `_add_id_pk_if_missing`('pet_breeding_races'); -CALL `_add_id_pk_if_missing`('pet_drinks'); -CALL `_add_id_pk_if_missing`('pet_foods'); -CALL `_add_id_pk_if_missing`('pet_items'); -CALL `_add_id_pk_if_missing`('pet_vocals'); -CALL `_add_id_pk_if_missing`('recycler_prizes'); -CALL `_add_id_pk_if_missing`('room_bans'); CALL `_add_id_pk_if_missing`('room_enter_log'); -CALL `_add_id_pk_if_missing`('room_game_scores'); -CALL `_add_id_pk_if_missing`('room_mutes'); -CALL `_add_id_pk_if_missing`('room_rights'); -CALL `_add_id_pk_if_missing`('room_trax'); -CALL `_add_id_pk_if_missing`('room_trax_playlist'); -CALL `_add_id_pk_if_missing`('room_votes'); -CALL `_add_id_pk_if_missing`('trax_playlist'); -CALL `_add_id_pk_if_missing`('wired_rewards_given'); - -CALL `_add_id_pk_if_missing`('calendar_rewards_claimed'); - --- camera: ensure id is auto-increment PK (skip ADD PK if already exists) -SET @has_pk = (SELECT COUNT(*) FROM `information_schema`.`TABLE_CONSTRAINTS` - WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'camera' AND `CONSTRAINT_TYPE` = 'PRIMARY KEY'); -SET @sql = IF(@has_pk = 0, - 'ALTER TABLE `camera` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY (`id`)', - 'ALTER TABLE `camera` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT'); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- Clean up helper procedure -DROP PROCEDURE IF EXISTS `_add_id_pk_if_missing`; - --- ============================================================================= --- PHASE 4: Add missing indexes --- ============================================================================= --- Adding indexes for columns commonly used in JOINs and WHERE clauses. --- Uses a helper procedure to skip indexes that already exist. DELIMITER // DROP PROCEDURE IF EXISTS `_add_index_if_missing`// @@ -223,218 +43,22 @@ CREATE PROCEDURE `_add_index_if_missing`(IN tbl VARCHAR(64), IN idx VARCHAR(64), BEGIN DECLARE tbl_exists INT DEFAULT 0; DECLARE idx_exists INT DEFAULT 0; - SELECT COUNT(*) INTO tbl_exists - FROM `information_schema`.`TABLES` - WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = tbl; - IF tbl_exists = 0 THEN - -- Table does not exist, skip - SET @dummy = 0; - ELSE - SELECT COUNT(*) INTO idx_exists - FROM `information_schema`.`STATISTICS` - WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = tbl AND `INDEX_NAME` = idx; + SELECT COUNT(*) INTO tbl_exists FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = tbl; + IF tbl_exists > 0 THEN + SELECT COUNT(*) INTO idx_exists FROM `information_schema`.`STATISTICS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = tbl AND `INDEX_NAME` = idx; IF idx_exists = 0 THEN SET @sql = CONCAT('ALTER TABLE `', tbl, '` ADD INDEX `', idx, '` (', cols, ')'); - PREPARE stmt FROM @sql; - EXECUTE stmt; - DEALLOCATE PREPARE stmt; + PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END IF; END// DELIMITER ; --- bans CALL `_add_index_if_missing`('bans', 'idx_bans_user_id', '`user_id`'); -CALL `_add_index_if_missing`('bans', 'idx_bans_ip', '`ip`'); -CALL `_add_index_if_missing`('bans', 'idx_bans_machine_id', '`machine_id`(64)'); - --- calendar_rewards -CALL `_add_index_if_missing`('calendar_rewards', 'idx_calendar_rewards_campaign_id', '`campaign_id`'); - --- calendar_rewards_claimed -CALL `_add_index_if_missing`('calendar_rewards_claimed', 'idx_cal_claimed_user_id', '`user_id`'); -CALL `_add_index_if_missing`('calendar_rewards_claimed', 'idx_cal_claimed_campaign_id', '`campaign_id`'); -CALL `_add_index_if_missing`('calendar_rewards_claimed', 'idx_cal_claimed_reward_id', '`reward_id`'); - --- camera -CALL `_add_index_if_missing`('camera', 'idx_camera_user_id', '`user_id`'); -CALL `_add_index_if_missing`('camera', 'idx_camera_room_id', '`room_id`'); - --- guilds CALL `_add_index_if_missing`('guilds', 'idx_guilds_user_id', '`user_id`'); -CALL `_add_index_if_missing`('guilds', 'idx_guilds_room_id', '`room_id`'); - --- guilds_forums_threads -CALL `_add_index_if_missing`('guilds_forums_threads', 'idx_gft_guild_id', '`guild_id`'); -CALL `_add_index_if_missing`('guilds_forums_threads', 'idx_gft_opener_id', '`opener_id`'); - --- guilds_forums_comments -CALL `_add_index_if_missing`('guilds_forums_comments', 'idx_gfc_user_id', '`user_id`'); - --- guild_forum_views -CALL `_add_index_if_missing`('guild_forum_views', 'idx_gfv_user_id', '`user_id`'); -CALL `_add_index_if_missing`('guild_forum_views', 'idx_gfv_guild_id', '`guild_id`'); - --- items_crackable -CALL `_add_index_if_missing`('items_crackable', 'idx_items_crackable_item_id', '`item_id`'); - --- namechange_log -CALL `_add_index_if_missing`('namechange_log', 'idx_namechange_user_id', '`user_id`'); - --- messenger_friendrequests -CALL `_add_index_if_missing`('messenger_friendrequests', 'idx_fr_user_to_id', '`user_to_id`'); -CALL `_add_index_if_missing`('messenger_friendrequests', 'idx_fr_user_from_id', '`user_from_id`'); - --- room_bans CALL `_add_index_if_missing`('room_bans', 'idx_room_bans_room_id', '`room_id`'); -CALL `_add_index_if_missing`('room_bans', 'idx_room_bans_user_id', '`user_id`'); - --- room_mutes -CALL `_add_index_if_missing`('room_mutes', 'idx_room_mutes_room_id', '`room_id`'); -CALL `_add_index_if_missing`('room_mutes', 'idx_room_mutes_user_id', '`user_id`'); - --- room_votes -CALL `_add_index_if_missing`('room_votes', 'idx_room_votes_room_id', '`room_id`'); - --- sanctions -CALL `_add_index_if_missing`('sanctions', 'idx_sanctions_habbo_id', '`habbo_id`'); - --- shadowbans -CALL `_add_index_if_missing`('shadowbans', 'idx_shadowbans_user_id', '`user_id`'); - --- support_cfh_topics -CALL `_add_index_if_missing`('support_cfh_topics', 'idx_cfh_topics_category_id', '`category_id`'); - --- support_tickets -CALL `_add_index_if_missing`('support_tickets', 'idx_tickets_sender_id', '`sender_id`'); -CALL `_add_index_if_missing`('support_tickets', 'idx_tickets_reported_id', '`reported_id`'); -CALL `_add_index_if_missing`('support_tickets', 'idx_tickets_mod_id', '`mod_id`'); -CALL `_add_index_if_missing`('support_tickets', 'idx_tickets_room_id', '`room_id`'); - --- voucher_history -CALL `_add_index_if_missing`('voucher_history', 'idx_vh_voucher_id', '`voucher_id`'); -CALL `_add_index_if_missing`('voucher_history', 'idx_vh_user_id', '`user_id`'); - --- ls_name_backgrounds_owned -CALL `_add_index_if_missing`('ls_name_backgrounds_owned', 'idx_lsnbo_user_id', '`user_id`'); -CALL `_add_index_if_missing`('ls_name_backgrounds_owned', 'idx_lsnbo_bg_id', '`name_background_id`'); - --- ls_name_colors_owned -CALL `_add_index_if_missing`('ls_name_colors_owned', 'idx_lsnco_user_id', '`user_id`'); -CALL `_add_index_if_missing`('ls_name_colors_owned', 'idx_lsnco_color_id', '`name_color_id`'); - --- ls_prefixes_owned -CALL `_add_index_if_missing`('ls_prefixes_owned', 'idx_lspo_user_id', '`user_id`'); -CALL `_add_index_if_missing`('ls_prefixes_owned', 'idx_lspo_prefix_id', '`prefix_id`'); - --- users_target_offer_purchases -CALL `_add_index_if_missing`('users_target_offer_purchases', 'idx_utop_offer_id', '`offer_id`'); - --- users_unlockable_commands -CALL `_add_index_if_missing`('users_unlockable_commands', 'idx_uuc_user_id', '`user_id`'); - --- command_category_permissions -CALL `_add_index_if_missing`('command_category_permissions', 'idx_ccp_category_id', '`category_id`'); - --- Clean up helper procedure -DROP PROCEDURE IF EXISTS `_add_index_if_missing`; --- ============================================================================= --- PHASE 5: Foreign key constraints --- ============================================================================= --- Adding FK constraints for referential integrity. --- Using appropriate ON DELETE actions: --- CASCADE = child rows deleted when parent is deleted --- SET NULL = child FK set to NULL when parent is deleted (column must be nullable) --- RESTRICT = prevent parent deletion if children exist (default) --- --- NOTE: Log/archive tables (chatlogs, commandlogs, room_enter_log, etc.) --- intentionally do NOT get FKs to avoid cascade-deleting historical data --- and to keep high-volume inserts fast. --- ============================================================================= - --- --------------------------------------------------------------------------- --- 5.0 Clean orphan rows BEFORE adding foreign keys --- --------------------------------------------------------------------------- --- Legacy Habbo databases often have rows referencing deleted users, rooms, or --- items. These orphans must be removed before FK constraints can be created. --- Uses a helper procedure to safely skip tables that don't exist. - -DELIMITER // -DROP PROCEDURE IF EXISTS `_delete_orphans`// -CREATE PROCEDURE `_delete_orphans`(IN tbl VARCHAR(64), IN col VARCHAR(64), IN ref_tbl VARCHAR(64), IN ref_col VARCHAR(64), IN extra_where VARCHAR(255)) -BEGIN - DECLARE tbl_exists INT DEFAULT 0; - DECLARE ref_exists INT DEFAULT 0; - SELECT COUNT(*) INTO tbl_exists - FROM `information_schema`.`TABLES` - WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = tbl; - SELECT COUNT(*) INTO ref_exists - FROM `information_schema`.`TABLES` - WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = ref_tbl; - IF tbl_exists > 0 AND ref_exists > 0 THEN - IF extra_where IS NOT NULL AND extra_where != '' THEN - SET @sql = CONCAT('DELETE FROM `', tbl, '` WHERE ', extra_where, ' AND `', col, '` NOT IN (SELECT `', ref_col, '` FROM `', ref_tbl, '`)'); - ELSE - SET @sql = CONCAT('DELETE FROM `', tbl, '` WHERE `', col, '` NOT IN (SELECT `', ref_col, '` FROM `', ref_tbl, '`)'); - END IF; - PREPARE stmt FROM @sql; - EXECUTE stmt; - DEALLOCATE PREPARE stmt; - END IF; -END// -DELIMITER ; - --- Orphans referencing users -CALL `_delete_orphans`('rooms', 'owner_id', 'users', 'id', ''); -CALL `_delete_orphans`('items', 'user_id', 'users', 'id', ''); --- bots: skipped, no FK added (see 5.3 comment) -CALL `_delete_orphans`('bans', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('bans', 'user_staff_id', 'users', 'id', ''); -CALL `_delete_orphans`('guilds', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('guilds_members', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('guilds_forums_comments', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('guild_forum_views', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_settings', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_badges', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_currency', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_effects', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_clothing', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_favorite_rooms', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_wardrobe', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_pets', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_recipes', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_saved_searches', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_navigator_settings', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_achievements', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_achievements_queue', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_ignored', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_ignored', 'target_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_subscriptions', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_target_offer_purchases', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_unlockable_outfit', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_window_settings', 'user_id', 'users', 'id', ''); -CALL `_delete_orphans`('users_prefixes', 'user_id', 'users', 'id', ''); - --- Orphans referencing rooms -CALL `_delete_orphans`('guilds', 'room_id', 'rooms', 'id', ''); -CALL `_delete_orphans`('items', 'room_id', 'rooms', 'id', '`room_id` != 0'); - --- Orphans referencing items_base -CALL `_delete_orphans`('items', 'item_id', 'items_base', 'id', ''); - --- Orphans referencing guilds -CALL `_delete_orphans`('guilds_members', 'guild_id', 'guilds', 'id', ''); -CALL `_delete_orphans`('guilds_forums_threads', 'guild_id', 'guilds', 'id', ''); -CALL `_delete_orphans`('guild_forum_views', 'guild_id', 'guilds', 'id', ''); - --- Clean up helper procedure -DROP PROCEDURE IF EXISTS `_delete_orphans`; - --- --------------------------------------------------------------------------- --- Helper: add FK only if it doesn't already exist --- --------------------------------------------------------------------------- DELIMITER // DROP PROCEDURE IF EXISTS `_add_fk_if_missing`// CREATE PROCEDURE `_add_fk_if_missing`(IN tbl VARCHAR(64), IN fk_name VARCHAR(64), IN col VARCHAR(64), IN ref_tbl VARCHAR(64), IN ref_col VARCHAR(64), IN on_del VARCHAR(20)) @@ -442,226 +66,27 @@ BEGIN DECLARE tbl_exists INT DEFAULT 0; DECLARE ref_exists INT DEFAULT 0; DECLARE fk_exists INT DEFAULT 0; - SELECT COUNT(*) INTO tbl_exists - FROM `information_schema`.`TABLES` - WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = tbl; - SELECT COUNT(*) INTO ref_exists - FROM `information_schema`.`TABLES` - WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = ref_tbl; - IF tbl_exists = 0 OR ref_exists = 0 THEN - -- Source or referenced table does not exist, skip - SET @dummy = 0; - ELSE - SELECT COUNT(*) INTO fk_exists - FROM `information_schema`.`TABLE_CONSTRAINTS` - WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = tbl AND `CONSTRAINT_NAME` = fk_name AND `CONSTRAINT_TYPE` = 'FOREIGN KEY'; + SELECT COUNT(*) INTO tbl_exists FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = tbl; + SELECT COUNT(*) INTO ref_exists FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = ref_tbl; + + IF tbl_exists > 0 AND ref_exists > 0 THEN + SELECT COUNT(*) INTO fk_exists FROM `information_schema`.`TABLE_CONSTRAINTS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = tbl AND `CONSTRAINT_NAME` = fk_name; IF fk_exists = 0 THEN SET @sql = CONCAT('ALTER TABLE `', tbl, '` ADD CONSTRAINT `', fk_name, '` FOREIGN KEY (`', col, '`) REFERENCES `', ref_tbl, '` (`', ref_col, '`) ON DELETE ', on_del); - PREPARE stmt FROM @sql; - EXECUTE stmt; - DEALLOCATE PREPARE stmt; + PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END IF; END// DELIMITER ; --- 5.1 Rooms → Users CALL `_add_fk_if_missing`('rooms', 'fk_rooms_owner', 'owner_id', 'users', 'id', 'CASCADE'); - --- 5.2 Items → Users, Items_base CALL `_add_fk_if_missing`('items', 'fk_items_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('items', 'fk_items_item_base', 'item_id', 'items_base', 'id', 'CASCADE'); - --- 5.3 Bots → Users --- SKIPPED: The emulator creates bots with a temporary user_id during catalog --- purchase, which may not yet exist in `users`. Drop FK if previously added. -SET @has_fk = (SELECT COUNT(*) FROM `information_schema`.`TABLE_CONSTRAINTS` - WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'bots' AND `CONSTRAINT_NAME` = 'fk_bots_user' AND `CONSTRAINT_TYPE` = 'FOREIGN KEY'); -SET @sql = IF(@has_fk > 0, 'ALTER TABLE `bots` DROP FOREIGN KEY `fk_bots_user`', 'SELECT 1'); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 5.4 Bans → Users -CALL `_add_fk_if_missing`('bans', 'fk_bans_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('bans', 'fk_bans_staff', 'user_staff_id', 'users', 'id', 'CASCADE'); - --- 5.5 Guilds → Users, Rooms -CALL `_add_fk_if_missing`('guilds', 'fk_guilds_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('guilds', 'fk_guilds_room', 'room_id', 'rooms', 'id', 'CASCADE'); - --- 5.6 Guild members → Guilds, Users -CALL `_add_fk_if_missing`('guilds_members', 'fk_gm_guild', 'guild_id', 'guilds', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('guilds_members', 'fk_gm_user', 'user_id', 'users', 'id', 'CASCADE'); - --- 5.7 Guild forum threads → Guilds, Users -CALL `_add_fk_if_missing`('guilds_forums_threads', 'fk_gft_guild', 'guild_id', 'guilds', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('guilds_forums_threads', 'fk_gft_opener', 'opener_id', 'users', 'id', 'SET NULL'); - --- 5.8 Guild forum comments → Threads, Users -CALL `_add_fk_if_missing`('guilds_forums_comments', 'fk_gfc_thread', 'thread_id', 'guilds_forums_threads', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('guilds_forums_comments', 'fk_gfc_user', 'user_id', 'users', 'id', 'CASCADE'); - --- 5.9 Guild forum views → Guilds, Users -CALL `_add_fk_if_missing`('guild_forum_views', 'fk_gfv_guild', 'guild_id', 'guilds', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('guild_forum_views', 'fk_gfv_user', 'user_id', 'users', 'id', 'CASCADE'); - --- 5.10 Catalog items → Catalog pages CALL `_add_fk_if_missing`('catalog_items', 'fk_catitems_page', 'page_id', 'catalog_pages', 'id', 'CASCADE'); +CALL `_add_fk_if_missing`('guilds', 'fk_guilds_user', 'user_id', 'users', 'id', 'CASCADE'); --- 5.11 Catalog items limited → Catalog items -CALL `_add_fk_if_missing`('catalog_items_limited', 'fk_catitemsltd_catitem', 'catalog_item_id', 'catalog_items', 'id', 'CASCADE'); - --- 5.12 Calendar rewards → Calendar campaigns -CALL `_add_fk_if_missing`('calendar_rewards', 'fk_calrewards_campaign', 'campaign_id', 'calendar_campaigns', 'id', 'CASCADE'); - --- 5.13 Calendar rewards claimed → Users, Campaigns, Rewards -CALL `_add_fk_if_missing`('calendar_rewards_claimed', 'fk_calclaimed_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('calendar_rewards_claimed', 'fk_calclaimed_campaign', 'campaign_id', 'calendar_campaigns', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('calendar_rewards_claimed', 'fk_calclaimed_reward', 'reward_id', 'calendar_rewards', 'id', 'CASCADE'); - --- 5.14-5.26 Users_* → Users -CALL `_add_fk_if_missing`('users_settings', 'fk_usettings_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_badges', 'fk_ubadges_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_currency', 'fk_ucurrency_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_effects', 'fk_ueffects_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_clothing', 'fk_uclothing_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_favorite_rooms', 'fk_ufavrooms_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_favorite_rooms', 'fk_ufavrooms_room', 'room_id', 'rooms', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_wardrobe', 'fk_uwardrobe_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_pets', 'fk_upets_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_recipes', 'fk_urecipes_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_saved_searches', 'fk_usavedsearches_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_navigator_settings', 'fk_unavsettings_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_achievements', 'fk_uachievements_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_achievements_queue', 'fk_uachqueue_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_ignored', 'fk_uignored_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_ignored', 'fk_uignored_target', 'target_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_subscriptions', 'fk_usubs_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_target_offer_purchases', 'fk_utop_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_target_offer_purchases', 'fk_utop_offer', 'offer_id', 'catalog_target_offers', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('users_unlockable_commands', 'fk_uunlockable_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('user_window_settings', 'fk_uwinsettings_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('user_prefixes', 'fk_uprefixes_user', 'user_id', 'users', 'id', 'CASCADE'); - --- 5.33-5.35 Messenger → Users -CALL `_add_fk_if_missing`('messenger_friendships', 'fk_mfriends_user_one', 'user_one_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('messenger_friendships', 'fk_mfriends_user_two', 'user_two_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('messenger_friendrequests', 'fk_mfr_user_to', 'user_to_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('messenger_friendrequests', 'fk_mfr_user_from', 'user_from_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('messenger_categories', 'fk_mcat_user', 'user_id', 'users', 'id', 'CASCADE'); - --- 5.36 Marketplace → Items, Users -CALL `_add_fk_if_missing`('marketplace_items', 'fk_market_item', 'item_id', 'items', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('marketplace_items', 'fk_market_user', 'user_id', 'users', 'id', 'CASCADE'); - --- 5.37-5.44 Room_* → Rooms, Users -CALL `_add_fk_if_missing`('room_rights', 'fk_rrights_room', 'room_id', 'rooms', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_rights', 'fk_rrights_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_bans', 'fk_rbans_room', 'room_id', 'rooms', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_bans', 'fk_rbans_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_mutes', 'fk_rmutes_room', 'room_id', 'rooms', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_mutes', 'fk_rmutes_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_votes', 'fk_rvotes_room', 'room_id', 'rooms', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_votes', 'fk_rvotes_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_wordfilter', 'fk_rwf_room', 'room_id', 'rooms', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_promotions', 'fk_rpromo_room', 'room_id', 'rooms', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_trax', 'fk_rtrax_room', 'room_id', 'rooms', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_trax_playlist', 'fk_rtraxpl_room', 'room_id', 'rooms', 'id', 'CASCADE'); - --- 5.45 Rooms_for_sale → Rooms, Users -CALL `_add_fk_if_missing`('rooms_for_sale', 'fk_r4sale_room', 'room_id', 'rooms', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('rooms_for_sale', 'fk_r4sale_user', 'user_id', 'users', 'id', 'CASCADE'); - --- 5.46-5.47 Room_trade_log → Users -CALL `_add_fk_if_missing`('room_trade_log', 'fk_rtlog_user_one', 'user_one_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_trade_log', 'fk_rtlog_user_two', 'user_two_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_trade_log_items', 'fk_rtli_trade', 'id', 'room_trade_log', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('room_trade_log_items', 'fk_rtli_user', 'user_id', 'users', 'id', 'CASCADE'); - --- 5.48-5.49 Polls → Polls, Users -CALL `_add_fk_if_missing`('polls_questions', 'fk_pq_poll', 'poll_id', 'polls', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('polls_answers', 'fk_pa_poll', 'poll_id', 'polls', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('polls_answers', 'fk_pa_user', 'user_id', 'users', 'id', 'CASCADE'); - --- 5.50-5.51 Crafting → Crafting_recipes -CALL `_add_fk_if_missing`('crafting_recipes_ingredients', 'fk_cri_recipe', 'recipe_id', 'crafting_recipes', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('crafting_altars_recipes', 'fk_car_recipe', 'recipe_id', 'crafting_recipes', 'id', 'CASCADE'); - --- 5.52 Voucher_history → Vouchers, Users -CALL `_add_fk_if_missing`('voucher_history', 'fk_vh_voucher', 'voucher_id', 'vouchers', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('voucher_history', 'fk_vh_user', 'user_id', 'users', 'id', 'CASCADE'); - --- 5.53-5.55 Support, Commands, Economy -CALL `_add_fk_if_missing`('support_cfh_topics', 'fk_cfhtopics_category', 'category_id', 'support_cfh_categories', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('command_category_permissions', 'fk_ccp_category', 'category_id', 'command_categories', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('economy_furniture', 'fk_econfurni_itembase', 'items_base_id', 'items_base', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('economy_furniture', 'fk_econfurni_category', 'economy_categories_id', 'economy_categories', 'id', 'CASCADE'); - --- 5.56-5.57 Sanctions, Camera → Users -CALL `_add_fk_if_missing`('sanctions', 'fk_sanctions_user', 'habbo_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('camera_web', 'fk_cameraweb_user', 'user_id', 'users', 'id', 'CASCADE'); - --- 5.58 LS ownership → Users, LS definitions -CALL `_add_fk_if_missing`('ls_name_backgrounds_owned', 'fk_lsnbo_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('ls_name_backgrounds_owned', 'fk_lsnbo_bg', 'name_background_id', 'ls_name_backgrounds', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('ls_name_colors_owned', 'fk_lsnco_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('ls_name_colors_owned', 'fk_lsnco_color', 'name_color_id', 'ls_name_colors', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('ls_prefixes_owned', 'fk_lspo_user', 'user_id', 'users', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('ls_prefixes_owned', 'fk_lspo_prefix', 'prefix_id', 'ls_prefixes', 'id', 'CASCADE'); - --- 5.59 Navigator_publics → Navigator_publiccats, Rooms -CALL `_add_fk_if_missing`('navigator_publics', 'fk_navpub_cat', 'public_cat_id', 'navigator_publiccats', 'id', 'CASCADE'); -CALL `_add_fk_if_missing`('navigator_publics', 'fk_navpub_room', 'room_id', 'rooms', 'id', 'CASCADE'); - --- 5.60 GOTW winners → Users -CALL `_add_fk_if_missing`('gotw_winners', 'fk_gotw_user', 'user_id', 'users', 'id', 'CASCADE'); - --- Clean up helper procedure +DROP PROCEDURE IF EXISTS `_add_id_pk_if_missing`; +DROP PROCEDURE IF EXISTS `_add_index_if_missing`; DROP PROCEDURE IF EXISTS `_add_fk_if_missing`; - --- ============================================================================= --- PHASE 6: Charset standardization --- ============================================================================= --- Standardize remaining utf8mb3 tables to utf8mb4 for full Unicode support. - -ALTER TABLE IF EXISTS `guilds` - CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - -ALTER TABLE IF EXISTS `guilds_elements` - CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - -ALTER TABLE IF EXISTS `groups_items` - CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - -ALTER TABLE IF EXISTS `messenger_friendships` - CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - -ALTER TABLE IF EXISTS `room_rights` - CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - -ALTER TABLE IF EXISTS `soundtracks` - CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - -ALTER TABLE IF EXISTS `users_achievements_queue` - CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - -ALTER TABLE IF EXISTS `users_saved_searches` - CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - -ALTER TABLE IF EXISTS `users_target_offer_purchases` - CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - -ALTER TABLE IF EXISTS `wordfilter` - CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - -ALTER TABLE IF EXISTS `logs_shop_purchases` - CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - - --- ============================================================================= --- Done - Re-enable foreign key checks --- ============================================================================= SET FOREIGN_KEY_CHECKS = 1; -SET SQL_MODE = @OLD_SQL_MODE; +SET SQL_MODE = @OLD_SQL_MODE; \ No newline at end of file