diff --git a/common/database_instances.cpp b/common/database_instances.cpp index 372c6751f..f0bdda42e 100644 --- a/common/database_instances.cpp +++ b/common/database_instances.cpp @@ -493,6 +493,12 @@ void Database::DeleteInstance(uint16 instance_id) query = StringFormat("DELETE FROM spawn_condition_values WHERE instance_id=%u", instance_id); QueryDatabase(query); + query = fmt::format("DELETE FROM dynamic_zones WHERE instance_id={}", instance_id); + QueryDatabase(query); + + query = fmt::format("DELETE FROM expedition_details WHERE instance_id={}", instance_id); + QueryDatabase(query); + BuryCorpsesInInstance(instance_id); } @@ -582,8 +588,8 @@ void Database::PurgeExpiredInstances() QueryDatabase(fmt::format("DELETE FROM respawn_times WHERE instance_id IN ({})", imploded_instance_ids)); QueryDatabase(fmt::format("DELETE FROM spawn_condition_values WHERE instance_id IN ({})", imploded_instance_ids)); QueryDatabase(fmt::format("UPDATE character_corpses SET is_buried = 1, instance_id = 0 WHERE instance_id IN ({})", imploded_instance_ids)); - - + QueryDatabase(fmt::format("DELETE FROM dynamic_zones WHERE instance_id IN ({})", imploded_instance_ids)); + QueryDatabase(fmt::format("DELETE FROM expedition_details WHERE instance_id IN ({})", imploded_instance_ids)); } void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration) diff --git a/common/database_schema.h b/common/database_schema.h index 0b6536d96..ad0b227cb 100644 --- a/common/database_schema.h +++ b/common/database_schema.h @@ -66,6 +66,7 @@ namespace DatabaseSchema { {"character_tribute", "id"}, {"completed_tasks", "charid"}, {"data_buckets", "id"}, + {"expedition_character_lockouts", "character_id"}, {"faction_values", "char_id"}, {"friends", "charid"}, {"guild_members", "char_id"}, @@ -131,6 +132,7 @@ namespace DatabaseSchema { "completed_tasks", "data_buckets", "discovered_items", + "expedition_character_lockouts", "faction_values", "friends", "guild_bank", @@ -305,7 +307,11 @@ namespace DatabaseSchema { "banned_ips", "bug_reports", "bugs", + "dynamic_zones", "eventlog", + "expedition_details", + "expedition_lockouts", + "expedition_members", "gm_ips", "group_id", "group_leaders", diff --git a/utils/sql/git/required/wip_dynamiczones.sql b/utils/sql/git/required/wip_dynamiczones.sql index c38487e31..dcc4575a2 100644 --- a/utils/sql/git/required/wip_dynamiczones.sql +++ b/utils/sql/git/required/wip_dynamiczones.sql @@ -17,8 +17,7 @@ CREATE TABLE `dynamic_zones` ( `zone_in_heading` FLOAT NOT NULL DEFAULT 0, `has_zone_in` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (`id`), - UNIQUE INDEX `instance_id` (`instance_id`), - CONSTRAINT `FK_dynamic_zones_instance_list` FOREIGN KEY (`instance_id`) REFERENCES `instance_list` (`id`) ON DELETE CASCADE + UNIQUE INDEX `instance_id` (`instance_id`) ) COLLATE='utf8mb4_general_ci' ENGINE=InnoDB diff --git a/utils/sql/git/required/wip_expeditions.sql b/utils/sql/git/required/wip_expeditions.sql index 27ca3f5ae..971880e37 100644 --- a/utils/sql/git/required/wip_expeditions.sql +++ b/utils/sql/git/required/wip_expeditions.sql @@ -1,7 +1,7 @@ CREATE TABLE `expedition_details` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `uuid` VARCHAR(36) NOT NULL, - `instance_id` INT(10) NULL DEFAULT NULL, + `instance_id` INT(10) NOT NULL, `expedition_name` VARCHAR(128) NOT NULL, `leader_id` INT(10) UNSIGNED NOT NULL DEFAULT 0, `min_players` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0, @@ -9,8 +9,7 @@ CREATE TABLE `expedition_details` ( `add_replay_on_join` TINYINT(3) UNSIGNED NOT NULL DEFAULT 1, `is_locked` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (`id`), - UNIQUE INDEX `instance_id` (`instance_id`), - CONSTRAINT `FK_expedition_details_instance_list` FOREIGN KEY (`instance_id`) REFERENCES `instance_list` (`id`) ON DELETE SET NULL + UNIQUE INDEX `instance_id` (`instance_id`) ) COLLATE='utf8mb4_general_ci' ENGINE=InnoDB @@ -24,8 +23,7 @@ CREATE TABLE `expedition_lockouts` ( `duration` INT(10) UNSIGNED NOT NULL DEFAULT 0, `from_expedition_uuid` VARCHAR(36) NOT NULL, PRIMARY KEY (`id`), - UNIQUE INDEX `expedition_id_event_name` (`expedition_id`, `event_name`), - CONSTRAINT `FK_expedition_lockouts_expedition_details` FOREIGN KEY (`expedition_id`) REFERENCES `expedition_details` (`id`) ON DELETE CASCADE + UNIQUE INDEX `expedition_id_event_name` (`expedition_id`, `event_name`) ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB @@ -36,8 +34,7 @@ CREATE TABLE `expedition_members` ( `expedition_id` INT(10) UNSIGNED NOT NULL DEFAULT 0, `character_id` INT(10) UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (`id`), - UNIQUE INDEX `expedition_id_character_id` (`expedition_id`, `character_id`), - CONSTRAINT `FK_expedition_members_expedition_details` FOREIGN KEY (`expedition_id`) REFERENCES `expedition_details` (`id`) ON DELETE CASCADE + UNIQUE INDEX `expedition_id_character_id` (`expedition_id`, `character_id`) ) COLLATE='utf8mb4_general_ci' ENGINE=InnoDB @@ -46,11 +43,11 @@ ENGINE=InnoDB CREATE TABLE `expedition_character_lockouts` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `character_id` INT(10) UNSIGNED NOT NULL, + `expedition_name` VARCHAR(128) NOT NULL, + `event_name` VARCHAR(256) NOT NULL, `expire_time` DATETIME NOT NULL DEFAULT current_timestamp(), `duration` INT(10) UNSIGNED NOT NULL DEFAULT 0, `from_expedition_uuid` VARCHAR(36) NOT NULL, - `expedition_name` VARCHAR(128) NOT NULL, - `event_name` VARCHAR(256) NOT NULL, `is_pending` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE INDEX `character_id_expedition_name_event_name` (`character_id`, `expedition_name`, `event_name`) diff --git a/world/expedition.cpp b/world/expedition.cpp index 98675a7c9..7bd77b6c7 100644 --- a/world/expedition.cpp +++ b/world/expedition.cpp @@ -206,22 +206,33 @@ void ExpeditionCache::Process() void ExpeditionDatabase::PurgeExpiredExpeditions() { std::string query = SQL( - DELETE expedition - FROM expedition_details expedition - LEFT JOIN instance_list ON expedition.instance_id = instance_list.id - LEFT JOIN ( - SELECT expedition_id, COUNT(*) member_count - FROM expedition_members - GROUP BY expedition_id - ) AS expedition_members - ON expedition_members.expedition_id = expedition.id + SELECT + expedition_details.id + FROM expedition_details + LEFT JOIN instance_list ON expedition_details.instance_id = instance_list.id + LEFT JOIN + ( + SELECT expedition_id, COUNT(*) member_count + FROM expedition_members + GROUP BY expedition_id + ) expedition_members + ON expedition_members.expedition_id = expedition_details.id WHERE - expedition.instance_id IS NULL + instance_list.id IS NULL OR expedition_members.member_count IS NULL OR (instance_list.start_time + instance_list.duration) <= UNIX_TIMESTAMP(); ); - database.QueryDatabase(query); + auto results = database.QueryDatabase(query); + if (results.Success()) + { + std::vector expedition_ids; + for (auto row = results.begin(); row != results.end(); ++row) + { + expedition_ids.emplace_back(static_cast(strtoul(row[0], nullptr, 10))); + } + ExpeditionDatabase::DeleteExpeditions(expedition_ids); + } } void ExpeditionDatabase::PurgeExpiredCharacterLockouts() @@ -330,6 +341,8 @@ Expedition ExpeditionDatabase::LoadExpedition(uint32_t expedition_id) void ExpeditionDatabase::DeleteExpeditions(const std::vector& expedition_ids) { + LogExpeditionsDetail("Deleting [{}] expedition(s)", expedition_ids.size()); + std::string expedition_ids_query; for (const auto& expedition_id : expedition_ids) { @@ -345,16 +358,15 @@ void ExpeditionDatabase::DeleteExpeditions(const std::vector& expediti ); database.QueryDatabase(query); - // todo: if not using foreign key constraints - //query = fmt::format( - // "DELETE FROM expedition_members WHERE expedition_id IN ({});", expedition_ids_query - //); - //database.QueryDatabase(query); + query = fmt::format( + "DELETE FROM expedition_members WHERE expedition_id IN ({});", expedition_ids_query + ); + database.QueryDatabase(query); - //query = fmt::format( - // "DELETE FROM expedition_lockouts WHERE expedition_id IN ({});", expedition_ids_query - //); - //database.QueryDatabase(query); + query = fmt::format( + "DELETE FROM expedition_lockouts WHERE expedition_id IN ({});", expedition_ids_query + ); + database.QueryDatabase(query); } }