mirror of
https://github.com/mangosfour/server.git
synced 2025-12-27 10:37:02 +00:00
[11284] Implement prepared statements for INSERT+DELETE+UPDATE SQL requests. Should improve player save performance + lower MySQL server CPU usage.
Note: PostgreSQL does not have prepared statements implemented using native APIs. Huge thanks to Undergarun, kero99 and Vinolentus. Signed-off-by: Ambal <pogrebniak@gala.net>
This commit is contained in:
parent
d9374d936f
commit
40ef9cbf2f
24 changed files with 1823 additions and 488 deletions
167
src/game/Pet.cpp
167
src/game/Pet.cpp
|
|
@ -377,52 +377,65 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
|||
_SaveAuras();
|
||||
|
||||
uint32 ownerLow = GetOwnerGuid().GetCounter();
|
||||
std::string name = m_name;
|
||||
CharacterDatabase.escape_string(name);
|
||||
// remove current data
|
||||
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND id = '%u'", ownerLow, m_charmInfo->GetPetNumber());
|
||||
static SqlStatementID delPet ;
|
||||
static SqlStatementID insPet ;
|
||||
|
||||
SqlStatement stmt = CharacterDatabase.CreateStatement(delPet, "DELETE FROM character_pet WHERE owner = ? AND id = ?");
|
||||
stmt.PExecute(ownerLow, m_charmInfo->GetPetNumber());
|
||||
|
||||
// prevent duplicate using slot (except PET_SAVE_NOT_IN_SLOT)
|
||||
if (mode <= PET_SAVE_LAST_STABLE_SLOT)
|
||||
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u'",
|
||||
PET_SAVE_NOT_IN_SLOT, ownerLow, uint32(mode) );
|
||||
{
|
||||
static SqlStatementID updPet ;
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(updPet, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ?");
|
||||
stmt.PExecute(uint32(PET_SAVE_NOT_IN_SLOT), ownerLow, uint32(mode));
|
||||
}
|
||||
|
||||
// prevent existence another hunter pet in PET_SAVE_AS_CURRENT and PET_SAVE_NOT_IN_SLOT
|
||||
if (getPetType()==HUNTER_PET && (mode==PET_SAVE_AS_CURRENT||mode > PET_SAVE_LAST_STABLE_SLOT))
|
||||
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u')",
|
||||
ownerLow, PET_SAVE_AS_CURRENT, PET_SAVE_LAST_STABLE_SLOT);
|
||||
// save pet
|
||||
std::ostringstream ss;
|
||||
ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) "
|
||||
<< "VALUES ("
|
||||
<< m_charmInfo->GetPetNumber() << ", "
|
||||
<< GetEntry() << ", "
|
||||
<< ownerLow << ", "
|
||||
<< GetNativeDisplayId() << ", "
|
||||
<< getLevel() << ", "
|
||||
<< GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", "
|
||||
<< uint32(m_charmInfo->GetReactState()) << ", "
|
||||
<< uint32(mode) << ", '"
|
||||
<< name.c_str() << "', "
|
||||
<< uint32(HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ? 0 : 1) << ", "
|
||||
<< (curhealth < 1 ? 1 : curhealth) << ", "
|
||||
<< curmana << ", "
|
||||
<< GetPower(POWER_HAPPINESS) << ", '";
|
||||
{
|
||||
static SqlStatementID del ;
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(del, "DELETE FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?)");
|
||||
stmt.PExecute(ownerLow, uint32(PET_SAVE_AS_CURRENT), uint32(PET_SAVE_LAST_STABLE_SLOT));
|
||||
}
|
||||
|
||||
// save pet
|
||||
SqlStatement savePet = CharacterDatabase.CreateStatement(insPet, "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, "
|
||||
"curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
savePet.addUInt32(m_charmInfo->GetPetNumber());
|
||||
savePet.addUInt32(GetEntry());
|
||||
savePet.addUInt32(ownerLow);
|
||||
savePet.addUInt32(GetNativeDisplayId());
|
||||
savePet.addUInt32(getLevel());
|
||||
savePet.addUInt32(GetUInt32Value(UNIT_FIELD_PETEXPERIENCE));
|
||||
savePet.addUInt32(uint32(m_charmInfo->GetReactState()));
|
||||
savePet.addUInt32(uint32(mode));
|
||||
savePet.addString(m_name);
|
||||
savePet.addUInt32(uint32(HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ? 0 : 1));
|
||||
savePet.addUInt32((curhealth < 1 ? 1 : curhealth));
|
||||
savePet.addUInt32(curmana);
|
||||
savePet.addUInt32(GetPower(POWER_HAPPINESS));
|
||||
|
||||
std::ostringstream ss;
|
||||
for(uint32 i = ACTION_BAR_INDEX_START; i < ACTION_BAR_INDEX_END; ++i)
|
||||
{
|
||||
ss << uint32(m_charmInfo->GetActionBarEntry(i)->GetType()) << " "
|
||||
<< uint32(m_charmInfo->GetActionBarEntry(i)->GetAction()) << " ";
|
||||
};
|
||||
savePet.addString(ss);
|
||||
|
||||
ss << "', "
|
||||
<< time(NULL) << ", "
|
||||
<< uint32(m_resetTalentsCost) << ", "
|
||||
<< uint64(m_resetTalentsTime) << ", "
|
||||
<< GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", "
|
||||
<< uint32(getPetType()) << ")";
|
||||
savePet.addUInt64(uint64(time(NULL)));
|
||||
savePet.addUInt32(uint32(m_resetTalentsCost));
|
||||
savePet.addUInt64(uint64(m_resetTalentsTime));
|
||||
savePet.addUInt32(GetUInt32Value(UNIT_CREATED_BY_SPELL));
|
||||
savePet.addUInt32(uint32(getPetType()));
|
||||
|
||||
CharacterDatabase.Execute( ss.str().c_str() );
|
||||
savePet.Execute();
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
// delete
|
||||
|
|
@ -438,11 +451,26 @@ void Pet::DeleteFromDB(uint32 guidlow, bool separate_transaction)
|
|||
if(separate_transaction)
|
||||
CharacterDatabase.BeginTransaction();
|
||||
|
||||
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE id = '%u'", guidlow);
|
||||
CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE id = '%u'", guidlow);
|
||||
CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", guidlow);
|
||||
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u'", guidlow);
|
||||
CharacterDatabase.PExecute("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", guidlow);
|
||||
static SqlStatementID delPet ;
|
||||
static SqlStatementID delDeclName ;
|
||||
static SqlStatementID delAuras ;
|
||||
static SqlStatementID delSpells ;
|
||||
static SqlStatementID delSpellCD ;
|
||||
|
||||
SqlStatement stmt = CharacterDatabase.CreateStatement(delPet, "DELETE FROM character_pet WHERE id = ?");
|
||||
stmt.PExecute(guidlow);
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(delDeclName, "DELETE FROM character_pet_declinedname WHERE id = ?");
|
||||
stmt.PExecute(guidlow);
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(delAuras, "DELETE FROM pet_aura WHERE guid = ?");
|
||||
stmt.PExecute(guidlow);
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(delSpells, "DELETE FROM pet_spell WHERE guid = ?");
|
||||
stmt.PExecute(guidlow);
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(delSpellCD, "DELETE FROM pet_spell_cooldown WHERE guid = ?");
|
||||
stmt.PExecute(guidlow);
|
||||
|
||||
if(separate_transaction)
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
|
@ -1126,7 +1154,11 @@ void Pet::_LoadSpellCooldowns()
|
|||
|
||||
void Pet::_SaveSpellCooldowns()
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", m_charmInfo->GetPetNumber());
|
||||
static SqlStatementID delSpellCD ;
|
||||
static SqlStatementID insSpellCD ;
|
||||
|
||||
SqlStatement stmt = CharacterDatabase.CreateStatement(delSpellCD, "DELETE FROM pet_spell_cooldown WHERE guid = ?");
|
||||
stmt.PExecute(m_charmInfo->GetPetNumber());
|
||||
|
||||
time_t curTime = time(NULL);
|
||||
|
||||
|
|
@ -1137,7 +1169,8 @@ void Pet::_SaveSpellCooldowns()
|
|||
m_CreatureSpellCooldowns.erase(itr++);
|
||||
else
|
||||
{
|
||||
CharacterDatabase.PExecute("INSERT INTO pet_spell_cooldown (guid,spell,time) VALUES ('%u', '%u', '" UI64FMTD "')", m_charmInfo->GetPetNumber(), itr->first, uint64(itr->second));
|
||||
stmt = CharacterDatabase.CreateStatement(insSpellCD, "INSERT INTO pet_spell_cooldown (guid,spell,time) VALUES (?, ?, ?)");
|
||||
stmt.PExecute(m_charmInfo->GetPetNumber(), itr->first, uint64(itr->second));
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
|
@ -1163,6 +1196,9 @@ void Pet::_LoadSpells()
|
|||
|
||||
void Pet::_SaveSpells()
|
||||
{
|
||||
static SqlStatementID delSpell ;
|
||||
static SqlStatementID insSpell ;
|
||||
|
||||
for (PetSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
|
||||
{
|
||||
++next;
|
||||
|
|
@ -1174,15 +1210,26 @@ void Pet::_SaveSpells()
|
|||
switch(itr->second.state)
|
||||
{
|
||||
case PETSPELL_REMOVED:
|
||||
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first);
|
||||
m_spells.erase(itr);
|
||||
{
|
||||
SqlStatement stmt = CharacterDatabase.CreateStatement(delSpell, "DELETE FROM pet_spell WHERE guid = ? and spell = ?");
|
||||
stmt.PExecute(m_charmInfo->GetPetNumber(), itr->first);
|
||||
m_spells.erase(itr);
|
||||
}
|
||||
continue;
|
||||
case PETSPELL_CHANGED:
|
||||
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first);
|
||||
CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second.active);
|
||||
{
|
||||
SqlStatement stmt = CharacterDatabase.CreateStatement(delSpell, "DELETE FROM pet_spell WHERE guid = ? and spell = ?");
|
||||
stmt.PExecute(m_charmInfo->GetPetNumber(), itr->first);
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(insSpell, "INSERT INTO pet_spell (guid,spell,active) VALUES (?, ?, ?)");
|
||||
stmt.PExecute(m_charmInfo->GetPetNumber(), itr->first, uint32(itr->second.active));
|
||||
}
|
||||
break;
|
||||
case PETSPELL_NEW:
|
||||
CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second.active);
|
||||
{
|
||||
SqlStatement stmt = CharacterDatabase.CreateStatement(insSpell, "INSERT INTO pet_spell (guid,spell,active) VALUES (?, ?, ?)");
|
||||
stmt.PExecute(m_charmInfo->GetPetNumber(), itr->first, uint32(itr->second.active));
|
||||
}
|
||||
break;
|
||||
case PETSPELL_UNCHANGED:
|
||||
continue;
|
||||
|
|
@ -1286,7 +1333,11 @@ void Pet::_LoadAuras(uint32 timediff)
|
|||
|
||||
void Pet::_SaveAuras()
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
|
||||
static SqlStatementID delAuras ;
|
||||
static SqlStatementID insAuras ;
|
||||
|
||||
SqlStatement stmt = CharacterDatabase.CreateStatement(delAuras, "DELETE FROM pet_aura WHERE guid = ?");
|
||||
stmt.PExecute(m_charmInfo->GetPetNumber());
|
||||
|
||||
SpellAuraHolderMap const& auraHolders = GetSpellAuraHolderMap();
|
||||
|
||||
|
|
@ -1340,14 +1391,28 @@ void Pet::_SaveAuras()
|
|||
|
||||
if (!effIndexMask)
|
||||
continue;
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(insAuras, "INSERT INTO pet_aura (guid, caster_guid, item_guid, spell, stackcount, remaincharges, basepoints0, basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
CharacterDatabase.PExecute("INSERT INTO pet_aura (guid, caster_guid, item_guid, spell, stackcount, remaincharges, basepoints0, basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) VALUES "
|
||||
"('%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%u')",
|
||||
m_charmInfo->GetPetNumber(), holder->GetCasterGuid().GetRawValue(), holder->GetCastItemGuid().GetCounter(), holder->GetId(), holder->GetStackAmount(), holder->GetAuraCharges(),
|
||||
damage[EFFECT_INDEX_0], damage[EFFECT_INDEX_1], damage[EFFECT_INDEX_2],
|
||||
maxduration[EFFECT_INDEX_0], maxduration[EFFECT_INDEX_1], maxduration[EFFECT_INDEX_2],
|
||||
remaintime[EFFECT_INDEX_0], remaintime[EFFECT_INDEX_1], remaintime[EFFECT_INDEX_2],
|
||||
effIndexMask);
|
||||
stmt.addUInt32(m_charmInfo->GetPetNumber());
|
||||
stmt.addUInt64(holder->GetCasterGuid().GetRawValue());
|
||||
stmt.addUInt32(holder->GetCastItemGuid().GetCounter());
|
||||
stmt.addUInt32(holder->GetId());
|
||||
stmt.addUInt32(holder->GetStackAmount());
|
||||
stmt.addUInt8(holder->GetAuraCharges());
|
||||
|
||||
for (int i = EFFECT_INDEX_0; i <= EFFECT_INDEX_2; ++i )
|
||||
stmt.addInt32(damage[i]);
|
||||
|
||||
for (int i = EFFECT_INDEX_0; i <= EFFECT_INDEX_2; ++i )
|
||||
stmt.addInt32(maxduration[i]);
|
||||
|
||||
for (int i = EFFECT_INDEX_0; i <= EFFECT_INDEX_2; ++i )
|
||||
stmt.addInt32(remaintime[i]);
|
||||
|
||||
stmt.addUInt32(effIndexMask);
|
||||
stmt.Execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue