aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/shared')
-rw-r--r--src/server/shared/DataStores/DB2StorageLoader.cpp16
-rw-r--r--src/server/shared/DataStores/DB2Store.h210
-rw-r--r--src/server/shared/Database/Implementation/HotfixDatabase.cpp164
-rw-r--r--src/server/shared/Database/Implementation/HotfixDatabase.h73
4 files changed, 290 insertions, 173 deletions
diff --git a/src/server/shared/DataStores/DB2StorageLoader.cpp b/src/server/shared/DataStores/DB2StorageLoader.cpp
index 6878a3b9b87..67bf3008ca2 100644
--- a/src/server/shared/DataStores/DB2StorageLoader.cpp
+++ b/src/server/shared/DataStores/DB2StorageLoader.cpp
@@ -169,14 +169,14 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
for (uint32 i = 1; i < fieldCount; i++)
{
fieldsOffset[i] = fieldsOffset[i - 1];
- if (fmt[i - 1] == 'b' || fmt[i - 1] == 'X')
+ if (fmt[i - 1] == 'b')
fieldsOffset[i] += 1;
else
fieldsOffset[i] += 4;
}
- data = new unsigned char[recordSize*recordCount+stringSize];
- stringTable = data + recordSize*recordCount;
+ data = new unsigned char[recordSize * recordCount + stringSize];
+ stringTable = data + recordSize * recordCount;
if (fread(data, recordSize * recordCount + stringSize, 1, f) != 1)
{
@@ -368,10 +368,6 @@ char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* da
offset += sizeof(char*);
break;
}
- case FT_NA:
- case FT_NA_BYTE:
- case FT_SORT:
- break;
default:
ASSERT(false, "unknown format character %c", format[x]);
}
@@ -434,7 +430,7 @@ char* DB2DatabaseLoader::Load(const char* format, int32 preparedStatement, uint3
return nullptr;
uint32 const fieldCount = strlen(format);
- if (fieldCount + 1 /*VerifiedBuild*/ != result->GetFieldCount())
+ if (fieldCount != result->GetFieldCount())
return nullptr;
// get struct size and index pos
@@ -569,7 +565,9 @@ char* DB2DatabaseLoader::Load(const char* format, int32 preparedStatement, uint3
void DB2DatabaseLoader::LoadStrings(const char* format, int32 preparedStatement, uint32 locale, char**& indexTable, std::list<char*>& stringPool)
{
- PreparedQueryResult result = HotfixDatabase.Query(HotfixDatabase.GetPreparedStatement(preparedStatement));
+ PreparedStatement* stmt = HotfixDatabase.GetPreparedStatement(preparedStatement);
+ stmt->setString(0, localeNames[locale]);
+ PreparedQueryResult result = HotfixDatabase.Query(stmt);
if (!result)
return;
diff --git a/src/server/shared/DataStores/DB2Store.h b/src/server/shared/DataStores/DB2Store.h
index 48c9ed3c12a..c45a25689cc 100644
--- a/src/server/shared/DataStores/DB2Store.h
+++ b/src/server/shared/DataStores/DB2Store.h
@@ -28,142 +28,125 @@ class DB2StorageBase
public:
virtual ~DB2StorageBase() { }
- uint32 GetHash() const { return tableHash; }
+ uint32 GetHash() const { return _tableHash; }
virtual bool HasRecord(uint32 id) const = 0;
virtual void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const = 0;
+ virtual void EraseRecord(uint32 id) = 0;
+
protected:
- uint32 tableHash;
+ uint32 _tableHash;
};
template<class T>
-class DB2Storage;
-
-template<class T>
-bool DB2StorageHasEntry(DB2Storage<T> const& store, uint32 id)
-{
- return store.LookupEntry(id) != NULL;
-}
-
-template<class T>
-void WriteDB2RecordToPacket(DB2Storage<T> const& store, uint32 id, uint32 locale, ByteBuffer& buffer)
-{
- uint8 const* entry = (uint8 const*)store.LookupEntry(id);
- ASSERT(entry);
-
- std::string format = store.GetFormat();
- for (uint32 i = 0; i < format.length(); ++i)
- {
- switch (format[i])
- {
- case FT_IND:
- case FT_INT:
- buffer << *(uint32*)entry;
- entry += 4;
- break;
- case FT_FLOAT:
- buffer << *(float*)entry;
- entry += 4;
- break;
- case FT_BYTE:
- buffer << *(uint8*)entry;
- entry += 1;
- break;
- case FT_STRING:
- {
- LocalizedString* locStr = *(LocalizedString**)entry;
- if (locStr->Str[locale][0] == '\0')
- locale = 0;
-
- char const* str = locStr->Str[locale];
- size_t len = strlen(str);
- buffer << uint16(len);
- buffer.WriteString(str, len);
- entry += sizeof(char*);
- break;
- }
- case FT_NA:
- case FT_SORT:
- buffer << uint32(0);
- break;
- case FT_NA_BYTE:
- buffer << uint8(0);
- break;
- }
- }
-}
-
-template<class T>
class DB2Storage : public DB2StorageBase
{
typedef std::list<char*> StringPoolList;
- typedef bool(*EntryChecker)(DB2Storage<T> const&, uint32);
- typedef void(*PacketWriter)(DB2Storage<T> const&, uint32, uint32, ByteBuffer&);
public:
- DB2Storage(char const* f, int32 preparedStmtIndex = -1, EntryChecker checkEntry = nullptr, PacketWriter writePacket = nullptr)
- : nCount(0), fieldCount(0), fmt(f), m_dataTable(nullptr), m_dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex)
+ DB2Storage(char const* f, int32 preparedStmtIndex = -1)
+ : _indexTableSize(0), _fieldCount(0), _format(f), _dataTable(nullptr), _dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex)
{
- indexTable.asT = NULL;
- CheckEntry = checkEntry ? checkEntry : (EntryChecker)&DB2StorageHasEntry<T>;
- WritePacket = writePacket ? writePacket : (PacketWriter)&WriteDB2RecordToPacket<T>;
+ _indexTable.AsT = NULL;
}
~DB2Storage() { Clear(); }
- bool HasRecord(uint32 id) const { return CheckEntry(*this, id); }
- T const* LookupEntry(uint32 id) const { return (id >= nCount) ? NULL : indexTable.asT[id]; }
- uint32 GetNumRows() const { return nCount; }
- char const* GetFormat() const { return fmt; }
- uint32 GetFieldCount() const { return fieldCount; }
- void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const
+ bool HasRecord(uint32 id) const override { return id < _indexTableSize && _indexTable.AsT[id] != nullptr; }
+ void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const override
{
- WritePacket(*this, id, locale, buffer);
+ ASSERT(id < _indexTableSize);
+ char const* entry = _indexTable.AsChar[id];
+ ASSERT(entry);
+
+ std::size_t fields = strlen(_format);
+ for (uint32 i = 0; i < fields; ++i)
+ {
+ switch (_format[i])
+ {
+ case FT_IND:
+ case FT_INT:
+ buffer << *(uint32*)entry;
+ entry += 4;
+ break;
+ case FT_FLOAT:
+ buffer << *(float*)entry;
+ entry += 4;
+ break;
+ case FT_BYTE:
+ buffer << *(uint8*)entry;
+ entry += 1;
+ break;
+ case FT_STRING:
+ {
+ LocalizedString* locStr = *(LocalizedString**)entry;
+ if (locStr->Str[locale][0] == '\0')
+ locale = 0;
+
+ char const* str = locStr->Str[locale];
+ std::size_t len = strlen(str);
+ buffer << uint16(len ? len + 1 : 0);
+ if (len)
+ {
+ buffer.append(str, len);
+ buffer << uint8(0);
+ }
+ entry += sizeof(LocalizedString*);
+ break;
+ }
+ }
+ }
}
+ void EraseRecord(uint32 id) override { if (id < _indexTableSize) _indexTable.AsT[id] = nullptr; }
+
+ T const* LookupEntry(uint32 id) const { return (id >= _indexTableSize) ? nullptr : _indexTable.AsT[id]; }
+ uint32 GetNumRows() const { return _indexTableSize; }
+ char const* GetFormat() const { return _format; }
+ uint32 GetFieldCount() const { return _fieldCount; }
bool Load(char const* fn, uint32 locale)
{
DB2FileLoader db2;
// Check if load was successful, only then continue
- if (!db2.Load(fn, fmt))
+ if (!db2.Load(fn, _format))
return false;
- fieldCount = db2.GetCols();
- tableHash = db2.GetHash();
+ _fieldCount = db2.GetCols();
+ _tableHash = db2.GetHash();
// load raw non-string data
- m_dataTable = reinterpret_cast<T*>(db2.AutoProduceData(fmt, nCount, indexTable.asChar));
+ _dataTable = reinterpret_cast<T*>(db2.AutoProduceData(_format, _indexTableSize, _indexTable.AsChar));
// create string holders for loaded string fields
- if (char* stringHolders = db2.AutoProduceStringsArrayHolders(fmt, (char*)m_dataTable))
+ if (char* stringHolders = db2.AutoProduceStringsArrayHolders(_format, (char*)_dataTable))
{
- m_stringPoolList.push_back(stringHolders);
+ _stringPoolList.push_back(stringHolders);
// load strings from db2 data
- if (char* stringBlock = db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale))
- m_stringPoolList.push_back(stringBlock);
+ if (char* stringBlock = db2.AutoProduceStrings(_format, (char*)_dataTable, locale))
+ _stringPoolList.push_back(stringBlock);
}
// error in db2 file at loading if NULL
- return indexTable.asT != NULL;
+ return _indexTable.AsT != NULL;
}
bool LoadStringsFrom(char const* fn, uint32 locale)
{
// DB2 must be already loaded using Load
- if (!indexTable.asT)
+ if (!_indexTable.AsT)
return false;
DB2FileLoader db2;
// Check if load was successful, only then continue
- if (!db2.Load(fn, fmt))
+ if (!db2.Load(fn, _format))
return false;
// load strings from another locale db2 data
- if (DB2FileLoader::GetFormatStringFieldCount(fmt))
- if (char* stringBlock = db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale))
- m_stringPoolList.push_back(stringBlock);
+ if (DB2FileLoader::GetFormatStringFieldCount(_format))
+ if (char* stringBlock = db2.AutoProduceStrings(_format, (char*)_dataTable, locale))
+ _stringPoolList.push_back(stringBlock);
return true;
}
@@ -173,11 +156,11 @@ public:
return;
char* extraStringHolders = nullptr;
- if (char* dataTable = DB2DatabaseLoader().Load(fmt, _hotfixStatement, nCount, indexTable.asChar, extraStringHolders, m_stringPoolList))
- m_dataTableEx = reinterpret_cast<T*>(dataTable);
+ if (char* dataTable = DB2DatabaseLoader().Load(_format, _hotfixStatement, _indexTableSize, _indexTable.AsChar, extraStringHolders, _stringPoolList))
+ _dataTableEx = reinterpret_cast<T*>(dataTable);
if (extraStringHolders)
- m_stringPoolList.push_back(extraStringHolders);
+ _stringPoolList.push_back(extraStringHolders);
}
void LoadStringsFromDB(uint32 locale)
@@ -185,50 +168,47 @@ public:
if (_hotfixStatement == -1)
return;
- if (!DB2FileLoader::GetFormatStringFieldCount(fmt))
+ if (!DB2FileLoader::GetFormatStringFieldCount(_format))
return;
- DB2DatabaseLoader().LoadStrings(fmt, _hotfixStatement + locale, locale, indexTable.asChar, m_stringPoolList);
+ DB2DatabaseLoader().LoadStrings(_format, _hotfixStatement + 1, locale, _indexTable.AsChar, _stringPoolList);
}
void Clear()
{
- if (!indexTable.asT)
+ if (!_indexTable.AsT)
return;
- delete[] reinterpret_cast<char*>(indexTable.asT);
- indexTable.asT = nullptr;
+ delete[] reinterpret_cast<char*>(_indexTable.AsT);
+ _indexTable.AsT = nullptr;
- delete[] reinterpret_cast<char*>(m_dataTable);
- m_dataTable = nullptr;
+ delete[] reinterpret_cast<char*>(_dataTable);
+ _dataTable = nullptr;
- delete[] reinterpret_cast<char*>(m_dataTableEx);
- m_dataTableEx = nullptr;
+ delete[] reinterpret_cast<char*>(_dataTableEx);
+ _dataTableEx = nullptr;
- while (!m_stringPoolList.empty())
+ while (!_stringPoolList.empty())
{
- delete[] m_stringPoolList.front();
- m_stringPoolList.pop_front();
+ delete[] _stringPoolList.front();
+ _stringPoolList.pop_front();
}
- nCount = 0;
+ _indexTableSize = 0;
}
- EntryChecker CheckEntry;
- PacketWriter WritePacket;
-
private:
- uint32 nCount;
- uint32 fieldCount;
- char const* fmt;
+ uint32 _indexTableSize;
+ uint32 _fieldCount;
+ char const* _format;
union
{
- T** asT;
- char** asChar;
- } indexTable;
- T* m_dataTable;
- T* m_dataTableEx;
- StringPoolList m_stringPoolList;
+ T** AsT;
+ char** AsChar;
+ } _indexTable;
+ T* _dataTable;
+ T* _dataTableEx;
+ StringPoolList _stringPoolList;
int32 _hotfixStatement;
};
diff --git a/src/server/shared/Database/Implementation/HotfixDatabase.cpp b/src/server/shared/Database/Implementation/HotfixDatabase.cpp
index 2003433ec40..559ddd18b1e 100644
--- a/src/server/shared/Database/Implementation/HotfixDatabase.cpp
+++ b/src/server/shared/Database/Implementation/HotfixDatabase.cpp
@@ -16,31 +16,11 @@
*/
#include "HotfixDatabase.h"
-#include "Util.h"
-
-/*
- Hotfix database statements are constructed in a special way
- Each db2 storage that contains localized string data
- must declare a prepared statement for each locale in the same order as
- locales are defined (enforced during compilation)
-
- '@' character is replaced with locale index for PrepareStatement call
-*/
// Force locale statments to appear exactly in locale declaration order, right after normal data fetch statement
-#define PREPARE_LOCALE_STMT(stmtBase, loc, sql, con) \
- static_assert(stmtBase + loc == stmtBase##_##loc, "Invalid prepared statement index for " STRINGIZE(stmtBase##_##loc)); \
- PrepareLocaleStatement(stmtBase##_##loc, loc, sql, con);
-
-#define PREPARE_LOCALE_STMTS(stmtBase, sql, con) \
- PREPARE_LOCALE_STMT(stmtBase, LOCALE_koKR, sql, con) \
- PREPARE_LOCALE_STMT(stmtBase, LOCALE_frFR, sql, con) \
- PREPARE_LOCALE_STMT(stmtBase, LOCALE_deDE, sql, con) \
- PREPARE_LOCALE_STMT(stmtBase, LOCALE_zhCN, sql, con) \
- PREPARE_LOCALE_STMT(stmtBase, LOCALE_zhTW, sql, con) \
- PREPARE_LOCALE_STMT(stmtBase, LOCALE_esES, sql, con) \
- PREPARE_LOCALE_STMT(stmtBase, LOCALE_esMX, sql, con) \
- PREPARE_LOCALE_STMT(stmtBase, LOCALE_ruRU, sql, con)
+#define PREPARE_LOCALE_STMT(stmtBase, sql, con) \
+ static_assert(stmtBase + 1 == stmtBase##_LOCALE, "Invalid prepared statement index for " #stmtBase "_LOCALE"); \
+ PrepareStatement(stmtBase##_LOCALE, sql, con);
void HotfixDatabaseConnection::DoPrepareStatements()
{
@@ -48,20 +28,132 @@ void HotfixDatabaseConnection::DoPrepareStatements()
m_stmts.resize(MAX_HOTFIXDATABASE_STATEMENTS);
// BroadcastText.db2
- PrepareStatement(HOTFIX_SEL_BROADCAST_TEXT, "SELECT * FROM broadcast_text ORDER BY ID DESC", CONNECTION_SYNCH);
- PREPARE_LOCALE_STMTS(HOTFIX_SEL_BROADCAST_TEXT, "SELECT ID, MaleText_loc@, FemaleText_loc@ FROM locales_broadcast_text", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_BROADCAST_TEXT, "SELECT ID, Language, MaleText, FemaleText, EmoteID1, EmoteID2, EmoteID3, "
+ "EmoteDelay1, EmoteDelay2, EmoteDelay3, SoundID, UnkEmoteID, Type FROM broadcast_text ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_BROADCAST_TEXT, "SELECT ID, MaleText_lang, FemaleText_lang FROM broadcast_text_locale WHERE locale = ?", CONNECTION_SYNCH);
- // TaxiPathNode.db2
- PrepareStatement(HOTFIX_SEL_TAXI_PATH_NODE, "SELECT * FROM taxi_path_node ORDER BY ID DESC", CONNECTION_SYNCH);
-}
+ // CurvePoint.db2
+ PrepareStatement(HOTFIX_SEL_CURVE_POINT, "SELECT ID, CurveID, `Index`, X, Y FROM curve_point ORDER BY ID DESC", CONNECTION_SYNCH);
-void HotfixDatabaseConnection::PrepareLocaleStatement(uint32 index, uint32 localeIndex, const char* sql, ConnectionFlags flags)
-{
- Tokenizer tokens(sql, '@');
- std::ostringstream stmt;
- stmt << tokens[0];
- for (std::size_t i = 1; i < tokens.size(); ++i)
- stmt << localeIndex << tokens[i];
+ // Holidays.db2
+ PrepareStatement(HOTFIX_SEL_HOLIDAYS, "SELECT ID, Duration1, Duration2, Duration3, Duration4, Duration5, Duration6, Duration7, Duration8, Duration9, Duration10, "
+ "Date1, Date2, Date3, Date4, Date5, Date6, Date7, Date8, Date9, Date10, Date11, Date12, Date13, Date14, Date15, Date16, Region, Looping, "
+ "CalendarFlags1, CalendarFlags2, CalendarFlags3, CalendarFlags4, CalendarFlags5, CalendarFlags6, CalendarFlags7, CalendarFlags8, CalendarFlags9, CalendarFlags10, "
+ "HolidayNameID, HolidayDescriptionID, TextureFilename, Priority, CalendarFilterType, Flags FROM holidays ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_HOLIDAYS, "SELECT ID, TextureFilename_lang FROM holidays_locale WHERE locale = ?", CONNECTION_SYNCH);
+
+ // ItemAppearance.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_APPEARANCE, "SELECT ID, DisplayID, IconFileDataID FROM item_appearance ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemBonus.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_BONUS, "SELECT ID, BonusListID, Type, Value1, Value2, `Index` FROM item_bonus ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemBonusTreeNode.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_BONUS_TREE_NODE, "SELECT ID, BonusTreeID, BonusTreeModID, SubTreeID, BonusListID FROM item_bonus_tree_node ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemCurrencyCost.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_CURRENCY_COST, "SELECT ID, ItemID FROM item_currency_cost ORDER BY ItemID DESC", CONNECTION_SYNCH);
+
+ // ItemEffect.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_EFFECT, "SELECT ID, ItemID, OrderIndex, SpellID, `Trigger`, Charges, Cooldown, "
+ "Category, CategoryCooldown FROM item_effect ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // Item.db2
+ PrepareStatement(HOTFIX_SEL_ITEM, "SELECT ID, Class, SubClass, SoundOverrideSubclass, Material, InventoryType, Sheath, "
+ "FileDataID, GroupSoundsID FROM item ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemExtendedCost.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_EXTENDED_COST, "SELECT ID, RequiredHonorPoints, RequiredArenaPoints, RequiredArenaSlot, "
+ "RequiredItem1, RequiredItem2, RequiredItem3, RequiredItem4, RequiredItem5, "
+ "RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, "
+ "RequiredPersonalArenaRating, ItemPurchaseGroup, "
+ "RequiredCurrency1, RequiredCurrency2, RequiredCurrency3, RequiredCurrency4, RequiredCurrency5, "
+ "RequiredCurrencyCount1, RequiredCurrencyCount2, RequiredCurrencyCount3, RequiredCurrencyCount4, RequiredCurrencyCount5, "
+ "RequiredFactionId, RequiredFactionStanding, RequirementFlags, RequiredAchievement FROM item_extended_cost ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemModifiedAppearance.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_MODIFIED_APPEARANCE, "SELECT ID, ItemID, AppearanceModID, AppearanceID, "
+ "IconFileDataID, `Index` FROM item_modified_appearance ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // Item-sparse.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_SPARSE, "SELECT ID, Quality, Flags1, Flags2, Flags3, Unk1, Unk2, BuyCount, BuyPrice, SellPrice, InventoryType, "
+ "AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, RequiredSpell, RequiredHonorRank, RequiredCityRank, "
+ "RequiredReputationFaction, RequiredReputationRank, MaxCount, Stackable, ContainerSlots, "
+ "ItemStatType1, ItemStatType2, ItemStatType3, ItemStatType4, ItemStatType5, ItemStatType6, ItemStatType7, ItemStatType8, ItemStatType9, ItemStatType10, "
+ "ItemStatValue1, ItemStatValue2, ItemStatValue3, ItemStatValue4, ItemStatValue5, ItemStatValue6, ItemStatValue7, ItemStatValue8, ItemStatValue9, ItemStatValue10, "
+ "ItemStatAllocation1, ItemStatAllocation2, ItemStatAllocation3, ItemStatAllocation4, ItemStatAllocation5, "
+ "ItemStatAllocation6, ItemStatAllocation7, ItemStatAllocation8, ItemStatAllocation9, ItemStatAllocation10, "
+ "ItemStatSocketCostMultiplier1, ItemStatSocketCostMultiplier2, ItemStatSocketCostMultiplier3, ItemStatSocketCostMultiplier4, ItemStatSocketCostMultiplier5, "
+ "ItemStatSocketCostMultiplier6, ItemStatSocketCostMultiplier7, ItemStatSocketCostMultiplier8, ItemStatSocketCostMultiplier9, ItemStatSocketCostMultiplier10, "
+ "ScalingStatDistribution, DamageType, Delay, RangedModRange, Bonding, Name, Name2, Name3, Name4, Description, PageText, LanguageID, PageMaterial, "
+ "StartQuest, LockID, Material, Sheath, RandomProperty, RandomSuffix, ItemSet, Area, Map, BagFamily, TotemCategory, "
+ "SocketColor1, SocketColor2, SocketColor3, SocketBonus, GemProperties, ArmorDamageModifier, Duration, ItemLimitCategory, "
+ "HolidayID, StatScalingFactor, CurrencySubstitutionID, CurrencySubstitutionCount, ItemNameDescriptionID FROM item_sparse ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_ITEM_SPARSE, "SELECT ID, Name_lang, Name2_lang, Name3_lang, Name4_lang, Description_lang FROM item_sparse_locale WHERE locale = ?", CONNECTION_SYNCH);
+
+ // ItemXBonusTree.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_X_BONUS_TREE, "SELECT ID, ItemID, BonusTreeID FROM item_x_bonus_tree ORDER BY ID DESC", CONNECTION_SYNCH);
- PrepareStatement(index, stmt.str().c_str(), flags);
+ // KeyChain.db2
+ PrepareStatement(HOTFIX_SEL_KEY_CHAIN, "SELECT Id, Key1, Key2, Key3, Key4, Key5, Key6, Key7, Key8, Key9, Key10, Key11, Key12, Key13, Key14, Key15, Key16, "
+ "Key17, Key18, Key19, Key20, Key21, Key22, Key23, Key24, Key25, Key26, Key27, Key28, Key29, Key30, Key31, Key32 FROM key_chain ORDER BY Id DESC", CONNECTION_SYNCH);
+
+ // Mount.db2
+ PrepareStatement(HOTFIX_SEL_MOUNT, "SELECT Id, MountTypeId, DisplayId, Flags, Name, Description, SourceDescription, "
+ "Source, SpellId, PlayerConditionId FROM mount ORDER BY Id DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_MOUNT, "SELECT ID, Name_lang, Description_lang, SourceDescription_lang FROM mount_locale WHERE locale = ?", CONNECTION_SYNCH);
+
+ // OverrideSpellData.db2
+ PrepareStatement(HOTFIX_SEL_OVERRIDE_SPELL_DATA, "SELECT ID, SpellID1, SpellID2, SpellID3, SpellID4, SpellID5, "
+ "SpellID6, SpellID7, SpellID8, SpellID9, SpellID10, Flags, PlayerActionbarFileDataID FROM override_spell_data ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // PhaseGroup.db2
+ PrepareStatement(HOTFIX_SEL_PHASE_GROUP, "SELECT ID, PhaseID, PhaseGroupID FROM phase_group ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellAuraRestrictions.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_AURA_RESTRICTIONS, "SELECT ID, CasterAuraState, TargetAuraState, ExcludeCasterAuraState, ExcludeTargetAuraState, "
+ "CasterAuraSpell, TargetAuraSpell, ExcludeCasterAuraSpell, ExcludeTargetAuraSpell FROM spell_aura_restrictions ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellCastingRequirements.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_CASTING_REQUIREMENTS, "SELECT ID, FacingCasterFlags, MinFactionID, MinReputation, "
+ "RequiredAreasID, RequiredAuraVision, RequiresSpellFocus FROM spell_casting_requirements ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellClassOptions.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_CLASS_OPTIONS, "SELECT ID, ModalNextSpell, SpellClassMask1, SpellClassMask2, SpellClassMask3, SpellClassMask4, "
+ "SpellClassSet FROM spell_class_options ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellLearnSpell.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_LEARN_SPELL, "SELECT ID, LearnSpellID, SpellID, OverridesSpellID FROM spell_learn_spell ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellMisc.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_MISC, "SELECT ID, Attributes, AttributesEx, AttributesExB, AttributesExC, AttributesExD, AttributesExE, "
+ "AttributesExF, AttributesExG, AttributesExH, AttributesExI, AttributesExJ, AttributesExK, AttributesExL, AttributesExM, "
+ "CastingTimeIndex, DurationIndex, RangeIndex, Speed, SpellVisualID1, SpellVisualID2, SpellIconID, ActiveIconID, "
+ "SchoolMask, MultistrikeSpeedMod FROM spell_misc ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ PrepareStatement(HOTFIX_SEL_SPELL_POWER, "SELECT ID, SpellID, PowerIndex, PowerType, ManaCost, ManaCostPerLevel, ManaCostPerSecond, ManaCostAdditional, "
+ "PowerDisplayID, UnitPowerBarID, ManaCostPercentage, ManaCostPercentagePerSecond, RequiredAura, HealthCostPercentage FROM spell_power ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellReagents.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_REAGENTS, "SELECT ID, Reagent1, Reagent2, Reagent3, Reagent4, Reagent5, Reagent6, Reagent7, Reagent8, "
+ "ReagentCount1, ReagentCount2, ReagentCount3, ReagentCount4, ReagentCount5, ReagentCount6, ReagentCount7, ReagentCount8, "
+ "CurrencyID, CurrencyCount FROM spell_reagents ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellRuneCost.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_RUNE_COST, "SELECT ID, Blood, Unholy, Frost, Chromatic, RunicPower FROM spell_rune_cost ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellTotems.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_TOTEMS, "SELECT ID, RequiredTotemCategoryID1, RequiredTotemCategoryID2, Totem1, Totem2 FROM spell_totems ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // TaxiNodes.db2
+ PrepareStatement(HOTFIX_SEL_TAXI_NODES, "SELECT ID, MapID, PosX, PosY, PosZ, Name, MountCreatureID1, MountCreatureID2, ConditionID, "
+ "Flags, MapOffsetX, MapOffsetY FROM taxi_nodes ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_TAXI_NODES, "SELECT ID, Name_lang FROM taxi_nodes_locale WHERE locale = ?", CONNECTION_SYNCH);
+
+ // TaxiPath.db2
+ PrepareStatement(HOTFIX_SEL_TAXI_PATH, "SELECT ID, `From`, `To`, Cost FROM taxi_path ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // TaxiPathNode.db2
+ PrepareStatement(HOTFIX_SEL_TAXI_PATH_NODE, "SELECT ID, PathID, NodeIndex, MapID, LocX, LocY, LocZ, Flags, Delay, "
+ "ArrivalEventID, DepartureEventID FROM taxi_path_node ORDER BY ID DESC", CONNECTION_SYNCH);
}
diff --git a/src/server/shared/Database/Implementation/HotfixDatabase.h b/src/server/shared/Database/Implementation/HotfixDatabase.h
index 37234277838..5ea7cc481aa 100644
--- a/src/server/shared/Database/Implementation/HotfixDatabase.h
+++ b/src/server/shared/Database/Implementation/HotfixDatabase.h
@@ -30,9 +30,6 @@ class HotfixDatabaseConnection : public MySQLConnection
//- Loads database type specific prepared statements
void DoPrepareStatements() override;
-
- private:
- void PrepareLocaleStatement(uint32 index, uint32 localeIndex, const char* sql, ConnectionFlags flags);
};
typedef DatabaseWorkerPool<HotfixDatabaseConnection> HotfixDatabaseWorkerPool;
@@ -43,21 +40,71 @@ enum HotfixDatabaseStatements
{DB}_{SEL/INS/UPD/DEL/REP}_{Summary of data changed}
When updating more than one field, consider looking at the calling function
name for a suiting suffix.
-
- DB2 locale loading statements must have the name of base statement with locale enum value name suffix
*/
HOTFIX_SEL_BROADCAST_TEXT,
- HOTFIX_SEL_BROADCAST_TEXT_LOCALE_koKR,
- HOTFIX_SEL_BROADCAST_TEXT_LOCALE_frFR,
- HOTFIX_SEL_BROADCAST_TEXT_LOCALE_deDE,
- HOTFIX_SEL_BROADCAST_TEXT_LOCALE_zhCN,
- HOTFIX_SEL_BROADCAST_TEXT_LOCALE_zhTW,
- HOTFIX_SEL_BROADCAST_TEXT_LOCALE_esES,
- HOTFIX_SEL_BROADCAST_TEXT_LOCALE_esMX,
- HOTFIX_SEL_BROADCAST_TEXT_LOCALE_ruRU,
+ HOTFIX_SEL_BROADCAST_TEXT_LOCALE,
+
+ HOTFIX_SEL_CURVE_POINT,
+
+ HOTFIX_SEL_HOLIDAYS,
+ HOTFIX_SEL_HOLIDAYS_LOCALE,
+
+ HOTFIX_SEL_ITEM_APPEARANCE,
+
+ HOTFIX_SEL_ITEM_BONUS,
+
+ HOTFIX_SEL_ITEM_BONUS_TREE_NODE,
+
+ HOTFIX_SEL_ITEM_CURRENCY_COST,
+
+ HOTFIX_SEL_ITEM_EFFECT,
+
+ HOTFIX_SEL_ITEM,
+
+ HOTFIX_SEL_ITEM_EXTENDED_COST,
+
+ HOTFIX_SEL_ITEM_MODIFIED_APPEARANCE,
+
+ HOTFIX_SEL_ITEM_SPARSE,
+ HOTFIX_SEL_ITEM_SPARSE_LOCALE,
+
+ HOTFIX_SEL_ITEM_X_BONUS_TREE,
+
+ HOTFIX_SEL_KEY_CHAIN,
+
+ HOTFIX_SEL_MOUNT,
+ HOTFIX_SEL_MOUNT_LOCALE,
+
+ HOTFIX_SEL_OVERRIDE_SPELL_DATA,
+
+ HOTFIX_SEL_PHASE_GROUP,
+
+ HOTFIX_SEL_SPELL_AURA_RESTRICTIONS,
+
+ HOTFIX_SEL_SPELL_CASTING_REQUIREMENTS,
+
+ HOTFIX_SEL_SPELL_CLASS_OPTIONS,
+
+ HOTFIX_SEL_SPELL_LEARN_SPELL,
+
+ HOTFIX_SEL_SPELL_MISC,
+
+ HOTFIX_SEL_SPELL_POWER,
+
+ HOTFIX_SEL_SPELL_REAGENTS,
+
+ HOTFIX_SEL_SPELL_RUNE_COST,
+
+ HOTFIX_SEL_SPELL_TOTEMS,
+
+ HOTFIX_SEL_TAXI_NODES,
+ HOTFIX_SEL_TAXI_NODES_LOCALE,
+
+ HOTFIX_SEL_TAXI_PATH,
HOTFIX_SEL_TAXI_PATH_NODE,
+
MAX_HOTFIXDATABASE_STATEMENTS
};