DB Layer:

- Make SQL Transactions actual objects used in code. (Thanks to Derex for the idea)
* Uncommitted transactions will be automatically rolled back and cleaned up using ACE_Refcounted_Auto_Ptr, so no need to call Rollback() in the code.
* Prevents recursive transactions and makes developers aware of transactions going on.
* Gets rid of unneccesary overhead iterating over a concurrent map.
- Some cleanups in affected code, including better usage of transaction control in AH / mail related code to prevent data loss.

*** Experimental, use at own risk, recommended to backup your DBs. ***

--HG--
branch : trunk
This commit is contained in:
Machiavelli
2010-08-21 03:19:25 +02:00
parent a7498d2f56
commit 994186f267
49 changed files with 861 additions and 774 deletions
+33 -35
View File
@@ -262,12 +262,12 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c
// PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning))
if (fields[7].GetUInt32() != 0)
{
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'",
SQLTransaction trans = CharacterDatabase.BeginTransaction();
trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'",
PET_SAVE_NOT_IN_SLOT, ownerid, PET_SAVE_AS_CURRENT, m_charmInfo->GetPetNumber());
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND id = '%u'",
trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND id = '%u'",
PET_SAVE_AS_CURRENT, ownerid, m_charmInfo->GetPetNumber());
CharacterDatabase.CommitTransaction();
CharacterDatabase.CommitTransaction(trans);
}
// Send fake summon spell cast - this is needed for correct cooldown application for spells
@@ -377,19 +377,17 @@ void Pet::SavePetToDB(PetSaveMode mode)
uint32 curhealth = GetHealth();
uint32 curmana = GetPower(POWER_MANA);
CharacterDatabase.BeginTransaction();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// save auras before possibly removing them
_SaveAuras();
_SaveAuras(trans);
// stable and not in slot saves
if (mode > PET_SAVE_AS_CURRENT)
{
RemoveAllAuras();
}
_SaveSpells();
_SaveSpellCooldowns();
CharacterDatabase.CommitTransaction();
_SaveSpells(trans);
_SaveSpellCooldowns(trans);
CharacterDatabase.CommitTransaction(trans);
// current/stable/not_in_slot
if (mode >= PET_SAVE_AS_CURRENT)
@@ -397,18 +395,18 @@ void Pet::SavePetToDB(PetSaveMode mode)
uint32 owner = GUID_LOPART(GetOwnerGUID());
std::string name = m_name;
CharacterDatabase.escape_string(name);
CharacterDatabase.BeginTransaction();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// remove current data
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND id = '%u'", owner,m_charmInfo->GetPetNumber());
trans->PAppend("DELETE FROM character_pet WHERE owner = '%u' AND id = '%u'", owner,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'",
trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u'",
PET_SAVE_NOT_IN_SLOT, owner, 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')",
trans->PAppend("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u')",
owner,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
// save pet
std::ostringstream ss;
@@ -441,8 +439,8 @@ void Pet::SavePetToDB(PetSaveMode mode)
<< GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", "
<< uint32(getPetType()) << ")";
CharacterDatabase.Execute(ss.str().c_str());
CharacterDatabase.CommitTransaction();
trans->Append(ss.str().c_str());
CharacterDatabase.CommitTransaction(trans);
}
// delete
else
@@ -454,13 +452,13 @@ void Pet::SavePetToDB(PetSaveMode mode)
void Pet::DeleteFromDB(uint32 guidlow)
{
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);
CharacterDatabase.CommitTransaction();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
trans->PAppend("DELETE FROM character_pet WHERE id = '%u'", guidlow);
trans->PAppend("DELETE FROM character_pet_declinedname WHERE id = '%u'", guidlow);
trans->PAppend("DELETE FROM pet_aura WHERE guid = '%u'", guidlow);
trans->PAppend("DELETE FROM pet_spell WHERE guid = '%u'", guidlow);
trans->PAppend("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", guidlow);
CharacterDatabase.CommitTransaction(trans);
}
void Pet::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState
@@ -1143,9 +1141,9 @@ void Pet::_LoadSpellCooldowns()
}
}
void Pet::_SaveSpellCooldowns()
void Pet::_SaveSpellCooldowns(SQLTransaction& trans)
{
CharacterDatabase.PExecute("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", m_charmInfo->GetPetNumber());
trans->PAppend("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", m_charmInfo->GetPetNumber());
time_t curTime = time(NULL);
@@ -1156,7 +1154,7 @@ 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));
trans->PAppend("INSERT INTO pet_spell_cooldown (guid,spell,time) VALUES ('%u', '%u', '" UI64FMTD "')", m_charmInfo->GetPetNumber(), itr->first, uint64(itr->second));
++itr;
}
}
@@ -1178,7 +1176,7 @@ void Pet::_LoadSpells()
}
}
void Pet::_SaveSpells()
void Pet::_SaveSpells(SQLTransaction& trans)
{
for (PetSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
{
@@ -1191,15 +1189,15 @@ 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);
trans->PAppend("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", 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);
trans->PAppend("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first);
trans->PAppend("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, 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);
trans->PAppend("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second.active);
break;
case PETSPELL_UNCHANGED:
continue;
@@ -1278,9 +1276,9 @@ void Pet::_LoadAuras(uint32 timediff)
}
}
void Pet::_SaveAuras()
void Pet::_SaveAuras(SQLTransaction& trans)
{
CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
trans->PAppend("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
for (AuraMap::const_iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end() ; ++itr)
{
@@ -1311,7 +1309,7 @@ void Pet::_SaveAuras()
}
}
CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges) "
trans->PAppend("INSERT INTO pet_aura (guid,caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges) "
"VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')",
m_charmInfo->GetPetNumber(), itr->second->GetCasterGUID(), itr->second->GetId(), effMask, recalculateMask,
itr->second->GetStackAmount(), damage[0], damage[1], damage[2], baseDamage[0], baseDamage[1], baseDamage[2],