diff --git a/common/repositories/base/base_character_auras_repository.h b/common/repositories/base/base_character_auras_repository.h index b2334e5ce..ec4b83d6d 100644 --- a/common/repositories/base/base_character_auras_repository.h +++ b/common/repositories/base/base_character_auras_repository.h @@ -6,7 +6,7 @@ * Any modifications to base repositories are to be made by the generator only * * @generator ./utils/scripts/generators/repository-generator.pl - * @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories + * @docs https://docs.eqemu.io/developer/repositories */ #ifndef EQEMU_BASE_CHARACTER_AURAS_REPOSITORY_H @@ -16,6 +16,7 @@ #include "../../strings.h" #include + class BaseCharacterAurasRepository { public: struct CharacterAuras { @@ -112,8 +113,9 @@ public: { auto results = db.QueryDatabase( fmt::format( - "{} WHERE id = {} LIMIT 1", + "{} WHERE {} = {} LIMIT 1", BaseSelect(), + PrimaryKey(), character_auras_id ) ); @@ -338,6 +340,66 @@ public: return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0); } + static std::string BaseReplace() + { + return fmt::format( + "REPLACE INTO {} ({}) ", + TableName(), + ColumnsRaw() + ); + } + + static int ReplaceOne( + Database& db, + const CharacterAuras &e + ) + { + std::vector v; + + v.push_back(std::to_string(e.id)); + v.push_back(std::to_string(e.slot)); + v.push_back(std::to_string(e.spell_id)); + + auto results = db.QueryDatabase( + fmt::format( + "{} VALUES ({})", + BaseReplace(), + Strings::Implode(",", v) + ) + ); + + return (results.Success() ? results.RowsAffected() : 0); + } + + static int ReplaceMany( + Database& db, + const std::vector &entries + ) + { + std::vector insert_chunks; + + for (auto &e: entries) { + std::vector v; + + v.push_back(std::to_string(e.id)); + v.push_back(std::to_string(e.slot)); + v.push_back(std::to_string(e.spell_id)); + + insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); + } + + std::vector v; + + auto results = db.QueryDatabase( + fmt::format( + "{} VALUES {}", + BaseReplace(), + Strings::Implode(",", insert_chunks) + ) + ); + + return (results.Success() ? results.RowsAffected() : 0); + } }; #endif //EQEMU_BASE_CHARACTER_AURAS_REPOSITORY_H diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 81c81d45e..91f6a2d19 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -33,6 +33,7 @@ #include "../common/repositories/character_bandolier_repository.h" #include "../common/repositories/character_currency_repository.h" #include "../common/repositories/character_alternate_abilities_repository.h" +#include "../common/repositories/character_auras_repository.h" #include #include @@ -3080,33 +3081,47 @@ void ZoneDatabase::LoadBuffs(Client *client) void ZoneDatabase::SaveAuras(Client *c) { - auto query = StringFormat("DELETE FROM `character_auras` WHERE `id` = %u", c->CharacterID()); - auto results = database.QueryDatabase(query); - if (!results.Success()) - return; + CharacterAurasRepository::DeleteOne(database, c->CharacterID()); - const auto &auras = c->GetAuraMgr(); - for (int i = 0; i < auras.count; ++i) { - auto aura = auras.auras[i].aura; - if (aura && aura->AuraZones()) { - query = StringFormat("INSERT INTO `character_auras` (id, slot, spell_id) VALUES(%u, %d, %d)", - c->CharacterID(), i, aura->GetAuraID()); - auto results = database.QueryDatabase(query); - if (!results.Success()) - return; + std::vector v; + + auto e = CharacterAurasRepository::NewEntity(); + + const auto& auras = c->GetAuraMgr(); + + for (int slot_id = 0; slot_id < auras.count; ++slot_id) { + Aura* a = auras.auras[slot_id].aura; + if (a && a->AuraZones()) { + e.id = c->CharacterID(); + e.slot = slot_id; + e.spell_id = a->GetAuraID(); + + v.emplace_back(e); } } + + if (!v.empty()) { + CharacterAurasRepository::ReplaceMany(database, v); + } } void ZoneDatabase::LoadAuras(Client *c) { - auto query = StringFormat("SELECT `spell_id` FROM `character_auras` WHERE `id` = %u ORDER BY `slot`", c->CharacterID()); - auto results = database.QueryDatabase(query); - if (!results.Success()) - return; + const auto& l = CharacterAurasRepository::GetWhere( + database, + fmt::format( + "`id` = {} ORDER BY `slot`", + c->CharacterID() + ) + ); - for (auto& row = results.begin(); row != results.end(); ++row) - c->MakeAura(Strings::ToInt(row[0])); + if (l.empty()) { + return; + } + + for (const auto& e : l) { + c->MakeAura(e.spell_id); + } } void ZoneDatabase::SavePetInfo(Client *client)