aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMachiavelli <none@none>2010-08-21 03:19:25 +0200
committerMachiavelli <none@none>2010-08-21 03:19:25 +0200
commit994186f2672547761392c71ed15ded2a83e8c20d (patch)
tree53eec0c7571642b9490d2a664671cb216a730993
parenta7498d2f560e24b2ae3b4f6cc46ea2223a41e16f (diff)
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
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp12
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp24
-rw-r--r--src/server/game/Achievements/AchievementMgr.h2
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp129
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.h15
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.cpp30
-rw-r--r--src/server/game/Chat/Commands/Level1.cpp6
-rw-r--r--src/server/game/Chat/Commands/Level3.cpp13
-rw-r--r--src/server/game/Entities/Corpse/Corpse.cpp14
-rw-r--r--src/server/game/Entities/Corpse/Corpse.h2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp20
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp8
-rw-r--r--src/server/game/Entities/Item/Container/Bag.cpp10
-rw-r--r--src/server/game/Entities/Item/Container/Bag.h4
-rw-r--r--src/server/game/Entities/Item/Item.cpp28
-rw-r--r--src/server/game/Entities/Item/Item.h6
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp68
-rw-r--r--src/server/game/Entities/Pet/Pet.h6
-rw-r--r--src/server/game/Entities/Player/Player.cpp333
-rw-r--r--src/server/game/Entities/Player/Player.h35
-rw-r--r--src/server/game/Events/GameEventMgr.cpp26
-rw-r--r--src/server/game/Globals/ObjectAccessor.cpp4
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp7
-rw-r--r--src/server/game/Groups/Group.cpp35
-rw-r--r--src/server/game/Guilds/Guild.cpp202
-rw-r--r--src/server/game/Guilds/Guild.h16
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.cpp20
-rw-r--r--src/server/game/Mails/Mail.cpp76
-rw-r--r--src/server/game/Mails/Mail.h9
-rw-r--r--src/server/game/Reputation/ReputationMgr.cpp6
-rw-r--r--src/server/game/Reputation/ReputationMgr.h2
-rw-r--r--src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp98
-rw-r--r--src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp8
-rw-r--r--src/server/game/Server/Protocol/Handlers/GuildHandler.cpp27
-rw-r--r--src/server/game/Server/Protocol/Handlers/ItemHandler.cpp8
-rw-r--r--src/server/game/Server/Protocol/Handlers/NPCHandler.cpp7
-rw-r--r--src/server/game/Server/Protocol/Handlers/PetHandler.cpp10
-rw-r--r--src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp18
-rw-r--r--src/server/game/Server/Protocol/Handlers/TradeHandler.cpp8
-rw-r--r--src/server/game/Server/WorldSession.cpp30
-rw-r--r--src/server/game/Server/WorldSession.h4
-rw-r--r--src/server/game/Tools/PlayerDump.cpp8
-rw-r--r--src/server/shared/Database/DatabaseEnv.h2
-rw-r--r--src/server/shared/Database/DatabaseWorkerPool.cpp43
-rw-r--r--src/server/shared/Database/DatabaseWorkerPool.h8
-rw-r--r--src/server/shared/Database/SQLOperation.cpp49
-rw-r--r--src/server/shared/Database/SQLOperation.h12
-rw-r--r--src/server/shared/Database/Transaction.cpp72
-rw-r--r--src/server/shared/Database/Transaction.h59
49 files changed, 863 insertions, 776 deletions
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp
index 8a53daa8278..fac696546d1 100644
--- a/src/server/game/Accounts/AccountMgr.cpp
+++ b/src/server/game/Accounts/AccountMgr.cpp
@@ -27,8 +27,6 @@
#include "Util.h"
#include "SHA1.h"
-extern DatabaseType LoginDatabase;
-
AccountMgr::AccountMgr()
{}
@@ -86,13 +84,13 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
CharacterDatabase.PExecute("DELETE FROM character_tutorial WHERE account = '%u'",accid);
CharacterDatabase.PExecute("DELETE FROM account_data WHERE account = '%u'",accid);
- LoginDatabase.BeginTransaction();
+ SQLTransaction trans = LoginDatabase.BeginTransaction();
- LoginDatabase.PExecute("DELETE FROM account WHERE id='%d'", accid);
- LoginDatabase.PExecute("DELETE FROM account_access WHERE id ='%d'", accid);
- LoginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid='%d'", accid);
+ trans->PAppend("DELETE FROM account WHERE id='%d'", accid);
+ trans->PAppend("DELETE FROM account_access WHERE id ='%d'", accid);
+ trans->PAppend("DELETE FROM realmcharacters WHERE acctid='%d'", accid);
- LoginDatabase.CommitTransaction();
+ LoginDatabase.CommitTransaction(trans);
return AOR_OK;
}
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 13df36dbc96..58cd7f25140 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -440,13 +440,13 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin
void AchievementMgr::DeleteFromDB(uint32 lowguid)
{
- CharacterDatabase.BeginTransaction ();
- CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = %u",lowguid);
- CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = %u",lowguid);
- CharacterDatabase.CommitTransaction ();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM character_achievement WHERE guid = %u",lowguid);
+ trans->PAppend("DELETE FROM character_achievement_progress WHERE guid = %u",lowguid);
+ CharacterDatabase.CommitTransaction(trans);
}
-void AchievementMgr::SaveToDB()
+void AchievementMgr::SaveToDB(SQLTransaction& trans)
{
if (!m_completedAchievements.empty())
{
@@ -485,8 +485,8 @@ void AchievementMgr::SaveToDB()
if (need_execute)
{
- CharacterDatabase.Execute(ssdel.str().c_str());
- CharacterDatabase.Execute(ssins.str().c_str());
+ trans->Append(ssdel.str().c_str());
+ trans->Append(ssins.str().c_str());
}
}
@@ -545,9 +545,9 @@ void AchievementMgr::SaveToDB()
if (need_execute_del || need_execute_ins)
{
if (need_execute_del)
- CharacterDatabase.Execute(ssdel.str().c_str());
+ trans->Append(ssdel.str().c_str());
if (need_execute_ins)
- CharacterDatabase.Execute(ssins.str().c_str());
+ trans->Append(ssins.str().c_str());
}
}
}
@@ -1953,16 +1953,18 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
MailDraft draft(subject, text);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (item)
{
// save new item before send
- item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
+ item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted
// item
draft.AddItem(item);
}
- draft.SendMailTo(GetPlayer(), MailSender(MAIL_CREATURE, reward->sender));
+ draft.SendMailTo(trans, GetPlayer(), MailSender(MAIL_CREATURE, reward->sender));
+ CharacterDatabase.CommitTransaction(trans);
}
}
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index f0da91c2fa6..7c6d9f0b003 100644
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -244,7 +244,7 @@ class AchievementMgr
void Reset();
static void DeleteFromDB(uint32 lowguid);
void LoadFromDB(QueryResult_AutoPtr achievementResult, QueryResult_AutoPtr criteriaResult);
- void SaveToDB();
+ void SaveToDB(SQLTransaction& trans);
void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1 = 0, uint32 miscvalue2 = 0, bool evenIfCriteriaComplete = false);
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1 = 0, uint32 miscvalue2 = 0, Unit *unit = NULL, uint32 time = 0);
void CompletedAchievement(AchievementEntry const* entry);
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index 11918bff2ef..0c004d62726 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -88,7 +88,7 @@ uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32
}
//does not clear ram
-void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
+void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction, SQLTransaction& trans)
{
Item *pItem = GetAItem(auction->item_guidlow);
if (!pItem)
@@ -146,7 +146,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
// set owner to bidder (to prevent delete item with sender char deleting)
// owner in `data` will set at mail receive and item extracting
- CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
+ trans->PAppend("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
if (bidder)
{
@@ -157,11 +157,11 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
MailDraft(msgAuctionWonSubject.str(), msgAuctionWonBody.str())
.AddItem(pItem)
- .SendMailTo(MailReceiver(bidder,auction->bidder), auction, MAIL_CHECK_MASK_COPIED);
+ .SendMailTo(trans, MailReceiver(bidder,auction->bidder), auction, MAIL_CHECK_MASK_COPIED);
}
}
-void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry * auction)
+void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry * auction, SQLTransaction& trans)
{
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
Player *owner = sObjectMgr.GetPlayer(owner_guid);
@@ -186,12 +186,12 @@ void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry * auction)
sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str());
MailDraft(msgAuctionSalePendingSubject.str(), msgAuctionSalePendingBody.str())
- .SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_COPIED);
+ .SendMailTo(trans, MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_COPIED);
}
}
//call this method to send mail to auction owner, when auction is successful, it does not clear ram
-void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction)
+void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction, SQLTransaction& trans)
{
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
Player *owner = sObjectMgr.GetPlayer(owner_guid);
@@ -224,12 +224,12 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction)
}
MailDraft(msgAuctionSuccessfulSubject.str(), auctionSuccessfulBody.str())
.AddMoney(profit)
- .SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_COPIED, sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY));
+ .SendMailTo(trans, MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_COPIED, sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY));
}
}
//does not clear ram
-void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry * auction)
+void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry * auction, SQLTransaction& trans)
{
//return an item in auction to its owner by mail
Item *pItem = GetAItem(auction->item_guidlow);
@@ -250,10 +250,58 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry * auction)
MailDraft(subject.str(), "") // TODO: fix body
.AddItem(pItem)
- .SendMailTo(MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_COPIED);
+ .SendMailTo(trans, MailReceiver(owner,auction->owner), auction, MAIL_CHECK_MASK_COPIED, 0);
}
}
+//this function sends mail to old bidder
+void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPrice, Player* newBidder, SQLTransaction& trans)
+{
+ uint64 oldBidder_guid = MAKE_NEW_GUID(auction->bidder,0, HIGHGUID_PLAYER);
+ Player *oldBidder = sObjectMgr.GetPlayer(oldBidder_guid);
+
+ uint32 oldBidder_accId = 0;
+ if (!oldBidder)
+ oldBidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(oldBidder_guid);
+
+ // old bidder exist
+ if (oldBidder || oldBidder_accId)
+ {
+ std::ostringstream msgAuctionOutbiddedSubject;
+ msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED << ":0:0";
+
+ if (oldBidder && newBidder)
+ oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, newBidder->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template);
+
+ MailDraft(msgAuctionOutbiddedSubject.str(), "") // TODO: fix body
+ .AddMoney(auction->bid)
+ .SendMailTo(trans, MailReceiver(oldBidder, auction->bidder), auction, MAIL_CHECK_MASK_COPIED);
+ }
+}
+
+//this function sends mail, when auction is cancelled to old bidder
+void AuctionHouseMgr::SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans)
+{
+ uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
+ Player *bidder = sObjectMgr.GetPlayer(bidder_guid);
+
+ uint32 bidder_accId = 0;
+ if (!bidder)
+ bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid);
+
+ // bidder exist
+ if (bidder || bidder_accId)
+ {
+ std::ostringstream msgAuctionCancelledSubject;
+ msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER << ":0:0";
+
+ MailDraft(msgAuctionCancelledSubject.str(), "") // TODO: fix body
+ .AddMoney(auction->bid)
+ .SendMailTo(trans, MailReceiver(bidder, auction->bidder), auction, MAIL_CHECK_MASK_COPIED);
+ }
+}
+
+
void AuctionHouseMgr::LoadAuctionItems()
{
// data needs to be at first place for Item::LoadFromDB
@@ -342,6 +390,10 @@ void AuctionHouseMgr::LoadAuctions()
barGoLink bar(AuctionCount);
+ //- TODO: Get rid of horrible design so we don't have to use transaction here to statisfy
+ //- function parameters.
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
AuctionEntry *aItem;
do
@@ -366,7 +418,7 @@ void AuctionHouseMgr::LoadAuctions()
CreatureData const* auctioneerData = sObjectMgr.GetCreatureData(aItem->auctioneer);
if (!auctioneerData)
{
- aItem->DeleteFromDB();
+ aItem->DeleteFromDB(trans);
sLog.outError("Auction %u has not a existing auctioneer (GUID : %u)", aItem->Id, aItem->auctioneer);
delete aItem;
continue;
@@ -375,7 +427,7 @@ void AuctionHouseMgr::LoadAuctions()
CreatureInfo const* auctioneerInfo = sObjectMgr.GetCreatureTemplate(auctioneerData->id);
if (!auctioneerInfo)
{
- aItem->DeleteFromDB();
+ aItem->DeleteFromDB(trans);
sLog.outError("Auction %u has not a existing auctioneer (GUID : %u Entry: %u)", aItem->Id, aItem->auctioneer,auctioneerData->id);
delete aItem;
continue;
@@ -384,7 +436,7 @@ void AuctionHouseMgr::LoadAuctions()
aItem->auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(auctioneerInfo->faction_A);
if (!aItem->auctionHouseEntry)
{
- aItem->DeleteFromDB();
+ aItem->DeleteFromDB(trans);
sLog.outError("Auction %u has auctioneer (GUID : %u Entry: %u) with wrong faction %u",
aItem->Id, aItem->auctioneer,auctioneerData->id,auctioneerInfo->faction_A);
delete aItem;
@@ -395,7 +447,7 @@ void AuctionHouseMgr::LoadAuctions()
// and item_template in fact (GetAItem will fail if problematic in result check in AuctionHouseMgr::LoadAuctionItems)
if (!GetAItem(aItem->item_guidlow))
{
- aItem->DeleteFromDB();
+ aItem->DeleteFromDB(trans);
sLog.outError("Auction %u has not a existing item : %u", aItem->Id, aItem->item_guidlow);
delete aItem;
continue;
@@ -405,6 +457,8 @@ void AuctionHouseMgr::LoadAuctions()
} while (result->NextRow());
+ CharacterDatabase.CommitTransaction(trans);
+
sLog.outString();
sLog.outString(">> Loaded %u auctions", AuctionCount);
}
@@ -506,35 +560,20 @@ void AuctionHouseObject::Update()
if (!result)
return;
- if (result->GetRowCount() == 0)
- return;
-
- vector<uint32> expiredAuctions;
-
do
{
- uint32 tmpdata = result->Fetch()->GetUInt32();
- expiredAuctions.push_back(tmpdata);
- }
- while (result->NextRow());
-
- while (!expiredAuctions.empty())
- {
- vector<uint32>::iterator iter = expiredAuctions.begin();
-
// from auctionhousehandler.cpp, creates auction pointer & player pointer
- AuctionEntry* auction = GetAuction(*iter);
-
- // Erase the auction from the vector.
- expiredAuctions.erase(iter);
+ AuctionEntry* auction = GetAuction(result->Fetch()->GetUInt32());
if (!auction)
continue;
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
///- Either cancel the auction if there was no bidder
if (auction->bidder == 0)
{
- sAuctionMgr.SendAuctionExpiredMail(auction);
+ sAuctionMgr.SendAuctionExpiredMail(auction, trans);
sScriptMgr.OnAuctionExpire(this, auction);
}
///- Or perform the transaction
@@ -543,19 +582,21 @@ void AuctionHouseObject::Update()
//we should send an "item sold" message if the seller is online
//we send the item to the winner
//we send the money to the seller
- sAuctionMgr.SendAuctionSuccessfulMail(auction);
- sAuctionMgr.SendAuctionWonMail(auction);
+ sAuctionMgr.SendAuctionSuccessfulMail(auction, trans);
+ sAuctionMgr.SendAuctionWonMail(auction, trans);
sScriptMgr.OnAuctionSuccessful(this, auction);
}
- ///- In any case clear the auction
- CharacterDatabase.BeginTransaction();
- auction->DeleteFromDB();
uint32 item_template = auction->item_template;
- sAuctionMgr.RemoveAItem(auction->item_guidlow);
+
+ ///- In any case clear the auction
+ auction->DeleteFromDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
+
RemoveAuction(auction, item_template);
- CharacterDatabase.CommitTransaction();
+ sAuctionMgr.RemoveAItem(auction->item_guidlow);
}
+ while (result->NextRow());
}
void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount)
@@ -746,16 +787,14 @@ uint32 AuctionEntry::GetAuctionOutBid() const
return outbid;
}
-void AuctionEntry::DeleteFromDB() const
+void AuctionEntry::DeleteFromDB(SQLTransaction& trans) const
{
- //No SQL injection (Id is integer)
- CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",Id);
+ trans->PAppend("DELETE FROM auctionhouse WHERE id = '%u'",Id);
}
-void AuctionEntry::SaveToDB() const
+void AuctionEntry::SaveToDB(SQLTransaction& trans) const
{
- //No SQL injection (no strings)
- CharacterDatabase.PExecute("INSERT INTO auctionhouse (id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit) "
+ trans->PAppend("INSERT INTO auctionhouse (id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit) "
"VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '%u', '%u', '%u', '%u')",
Id, auctioneer, item_guidlow, item_template, owner, buyout, (uint64)expire_time, bidder, bid, startbid, deposit);
}
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h
index d81d68cb366..7fbee6e9132 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.h
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h
@@ -66,8 +66,8 @@ struct AuctionEntry
uint32 GetAuctionCut() const;
uint32 GetAuctionOutBid() const;
bool BuildAuctionInfo(WorldPacket & data) const;
- void DeleteFromDB() const;
- void SaveToDB() const;
+ void DeleteFromDB(SQLTransaction& trans) const;
+ void SaveToDB(SQLTransaction& trans) const;
};
//this class is used as auctionhouse instance
@@ -138,10 +138,13 @@ class AuctionHouseMgr
}
//auction messages
- void SendAuctionWonMail(AuctionEntry * auction);
- void SendAuctionSalePendingMail(AuctionEntry * auction);
- void SendAuctionSuccessfulMail(AuctionEntry * auction);
- void SendAuctionExpiredMail(AuctionEntry * auction);
+ void SendAuctionWonMail(AuctionEntry * auction, SQLTransaction& trans);
+ void SendAuctionSalePendingMail(AuctionEntry * auction, SQLTransaction& trans);
+ void SendAuctionSuccessfulMail(AuctionEntry * auction, SQLTransaction& trans);
+ void SendAuctionExpiredMail(AuctionEntry * auction, SQLTransaction& trans);
+ void SendAuctionOutbiddedMail(AuctionEntry * auction, uint32 newPrice, Player* newBidder, SQLTransaction& trans);
+ void SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans);
+
static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem);
static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId);
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index 51c5cecd6f6..d72aa75b952 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -78,16 +78,16 @@ bool ArenaTeam::Create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam
// ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB
CharacterDatabase.escape_string(ArenaTeamName);
- CharacterDatabase.BeginTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
// CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid='%u'", m_TeamId); - MAX(arenateam)+1 not exist
- CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", m_TeamId);
- CharacterDatabase.PExecute("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) "
+ trans->PAppend("DELETE FROM arena_team_member WHERE arenateamid='%u'", m_TeamId);
+ trans->PAppend("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) "
"VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')",
m_TeamId, ArenaTeamName.c_str(), GUID_LOPART(m_CaptainGuid), m_Type, m_BackgroundColor, m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor);
- CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES "
+ trans->PAppend("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES "
"('%u', '%u', '%u', '%u', '%u', '%u', '%u')", m_TeamId, m_stats.rating, m_stats.games_week, m_stats.wins_week, m_stats.games_season, m_stats.wins_season, m_stats.rank);
- CharacterDatabase.CommitTransaction();
+ CharacterDatabase.CommitTransaction(trans);
AddMember(m_CaptainGuid);
sLog.outArena("New ArenaTeam created [Id: %u] [Type: %u] [Captain GUID: %u]", GetId(), GetType(), GetCaptain());
@@ -320,11 +320,11 @@ void ArenaTeam::Disband(WorldSession *session)
if (Player *player = session->GetPlayer())
sLog.outArena("Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId());
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", m_TeamId);
- CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", m_TeamId); //< this should be alredy done by calling DelMember(memberGuids[j]); for each member
- CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", m_TeamId);
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM arena_team WHERE arenateamid = '%u'", m_TeamId);
+ trans->PAppend("DELETE FROM arena_team_member WHERE arenateamid = '%u'", m_TeamId); //< this should be alredy done by calling DelMember(memberGuids[j]); for each member
+ trans->PAppend("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", m_TeamId);
+ CharacterDatabase.CommitTransaction(trans);
sObjectMgr.RemoveArenaTeam(m_TeamId);
}
@@ -734,13 +734,11 @@ void ArenaTeam::SaveToDB()
{
// save team and member stats to db
// called after a match has ended, or when calculating arena_points
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u',games = '%u',played = '%u',rank = '%u',wins = '%u',wins2 = '%u' WHERE arenateamid = '%u'", m_stats.rating, m_stats.games_week, m_stats.games_season, m_stats.rank, m_stats.wins_week, m_stats.wins_season, GetId());
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("UPDATE arena_team_stats SET rating = '%u',games = '%u',played = '%u',rank = '%u',wins = '%u',wins2 = '%u' WHERE arenateamid = '%u'", m_stats.rating, m_stats.games_week, m_stats.games_season, m_stats.rank, m_stats.wins_week, m_stats.wins_season, GetId());
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
- {
- CharacterDatabase.PExecute("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u', personal_rating = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, itr->personal_rating, m_TeamId, GUID_LOPART(itr->guid));
- }
- CharacterDatabase.CommitTransaction();
+ trans->PAppend("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u', personal_rating = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, itr->personal_rating, m_TeamId, GUID_LOPART(itr->guid));
+ CharacterDatabase.CommitTransaction(trans);
}
void ArenaTeam::FinishWeek()
diff --git a/src/server/game/Chat/Commands/Level1.cpp b/src/server/game/Chat/Commands/Level1.cpp
index f483dc2540e..c9ef15c50ad 100644
--- a/src/server/game/Chat/Commands/Level1.cpp
+++ b/src/server/game/Chat/Commands/Level1.cpp
@@ -2395,8 +2395,12 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
// from console show not existed sender
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
+ //- TODO: Fix poor design
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
MailDraft(subject, text)
- .SendMailTo(MailReceiver(target,GUID_LOPART(target_guid)),sender);
+ .SendMailTo(trans, MailReceiver(target,GUID_LOPART(target_guid)),sender);
+
+ CharacterDatabase.CommitTransaction(trans);
std::string nameLink = playerLink(target_name);
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp
index 14cf5e0b858..d712dcdac91 100644
--- a/src/server/game/Chat/Commands/Level3.cpp
+++ b/src/server/game/Chat/Commands/Level3.cpp
@@ -6818,16 +6818,19 @@ bool ChatHandler::HandleSendItemsCommand(const char *args)
// fill mail
MailDraft draft(subject, text);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
{
if (Item* item = Item::CreateItem(itr->first,itr->second,m_session ? m_session->GetPlayer() : 0))
{
- item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
+ item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted
draft.AddItem(item);
}
}
- draft.SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)), sender);
+ draft.SendMailTo(trans, MailReceiver(receiver,GUID_LOPART(receiver_guid)), sender);
+ CharacterDatabase.CommitTransaction(trans);
std::string nameLink = playerLink(receiver_name);
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
@@ -6873,9 +6876,13 @@ bool ChatHandler::HandleSendMoneyCommand(const char *args)
// from console show not existed sender
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
MailDraft(subject, text)
.AddMoney(money)
- .SendMailTo(MailReceiver(receiver,GUID_LOPART(receiver_guid)),sender);
+ .SendMailTo(trans, MailReceiver(receiver,GUID_LOPART(receiver_guid)),sender);
+
+ CharacterDatabase.CommitTransaction(trans);
std::string nameLink = playerLink(receiver_name);
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index 8bc557964c2..dff6caf5d94 100644
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -105,8 +105,8 @@ bool Corpse::Create(uint32 guidlow, Player *owner)
void Corpse::SaveToDB()
{
// prevent DB data inconsistence problems and duplicates
- CharacterDatabase.BeginTransaction();
- DeleteFromDB();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ DeleteFromDB(trans);
std::ostringstream ss;
ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,displayId,itemCache,bytes1,bytes2,guild,flags,dynFlags,time,corpse_type,instance,phaseMask) VALUES ("
@@ -131,8 +131,8 @@ void Corpse::SaveToDB()
<< uint32(GetType()) << ", "
<< int(GetInstanceId()) << ", "
<< uint16(GetPhaseMask()) << ")"; // prevent out of range error
- CharacterDatabase.Execute(ss.str().c_str());
- CharacterDatabase.CommitTransaction();
+ trans->Append(ss.str().c_str());
+ CharacterDatabase.CommitTransaction(trans);
}
void Corpse::DeleteBonesFromWorld()
@@ -149,14 +149,14 @@ void Corpse::DeleteBonesFromWorld()
AddObjectToRemoveList();
}
-void Corpse::DeleteFromDB()
+void Corpse::DeleteFromDB(SQLTransaction& trans)
{
if (GetType() == CORPSE_BONES)
// only specific bones
- CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%d'", GetGUIDLow());
+ trans->PAppend("DELETE FROM corpse WHERE guid = '%d'", GetGUIDLow());
else
// all corpses (not bones)
- CharacterDatabase.PExecute("DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'", GUID_LOPART(GetOwnerGUID()));
+ trans->PAppend("DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'", GUID_LOPART(GetOwnerGUID()));
}
bool Corpse::LoadFromDB(uint32 guid, Field *fields)
diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h
index e3d8c702972..d3bb6fbf6a6 100644
--- a/src/server/game/Entities/Corpse/Corpse.h
+++ b/src/server/game/Entities/Corpse/Corpse.h
@@ -64,7 +64,7 @@ class Corpse : public WorldObject, public GridObject<Corpse>
bool LoadFromDB(uint32 guid, Field *fields);
void DeleteBonesFromWorld();
- void DeleteFromDB();
+ void DeleteFromDB(SQLTransaction& trans);
uint64 const& GetOwnerGUID() const { return GetUInt64Value(CORPSE_FIELD_OWNER); }
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index f64cdb57e5f..0f2bbcab186 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -1052,9 +1052,9 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
data.spawnMask = spawnMask;
// updated in DB
- WorldDatabase.BeginTransaction();
+ SQLTransaction trans = WorldDatabase.BeginTransaction();
- WorldDatabase.PExecute("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
+ trans->PAppend("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
std::ostringstream ss;
ss << "INSERT INTO creature VALUES ("
@@ -1077,9 +1077,9 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
<< (m_isDeadByDefault ? 1 : 0) << "," //is_dead
<< GetDefaultMovementType() << ")"; //default movement generator type
- WorldDatabase.PExecute(ss.str().c_str());
+ trans->Append(ss.str().c_str());
- WorldDatabase.CommitTransaction();
+ WorldDatabase.CommitTransaction(trans);
}
void Creature::SelectLevel(const CreatureInfo *cinfo)
@@ -1348,12 +1348,12 @@ void Creature::DeleteFromDB()
sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
sObjectMgr.DeleteCreatureData(m_DBTableGuid);
- WorldDatabase.BeginTransaction();
- WorldDatabase.PExecute("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
- WorldDatabase.PExecute("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid);
- WorldDatabase.PExecute("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid);
- WorldDatabase.PExecute("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid);
- WorldDatabase.CommitTransaction();
+ SQLTransaction trans = WorldDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
+ trans->PAppend("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid);
+ trans->PAppend("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid);
+ trans->PAppend("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid);
+ WorldDatabase.CommitTransaction(trans);
}
bool Creature::canSeeOrDetect(Unit const* u, bool detect, bool /*inVisibleList*/, bool /*is3dDistance*/) const
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 89f17450a83..f1c823001bc 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -644,10 +644,10 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
<< uint32(GetGoAnimProgress()) << ", "
<< uint32(GetGoState()) << ")";
- WorldDatabase.BeginTransaction();
- WorldDatabase.PExecute("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid);
- WorldDatabase.PExecute(ss.str().c_str());
- WorldDatabase.CommitTransaction();
+ SQLTransaction trans = WorldDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid);
+ trans->Append(ss.str().c_str());
+ WorldDatabase.CommitTransaction(trans);
}
bool GameObject::LoadFromDB(uint32 guid, Map *map)
diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp
index 8a1e978b73f..c5f747ff322 100644
--- a/src/server/game/Entities/Item/Container/Bag.cpp
+++ b/src/server/game/Entities/Item/Container/Bag.cpp
@@ -102,9 +102,9 @@ bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner)
return true;
}
-void Bag::SaveToDB()
+void Bag::SaveToDB(SQLTransaction& trans)
{
- Item::SaveToDB();
+ Item::SaveToDB(trans);
}
bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result, uint32 entry)
@@ -125,13 +125,13 @@ bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result,
return true;
}
-void Bag::DeleteFromDB()
+void Bag::DeleteFromDB(SQLTransaction& trans)
{
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
if (m_bagslot[i])
- m_bagslot[i]->DeleteFromDB();
+ m_bagslot[i]->DeleteFromDB(trans);
- Item::DeleteFromDB();
+ Item::DeleteFromDB(trans);
}
uint32 Bag::GetFreeSlots() const
diff --git a/src/server/game/Entities/Item/Container/Bag.h b/src/server/game/Entities/Item/Container/Bag.h
index 6d4f65cf8cc..c704272309b 100644
--- a/src/server/game/Entities/Item/Container/Bag.h
+++ b/src/server/game/Entities/Item/Container/Bag.h
@@ -54,11 +54,11 @@ class Bag : public Item
// DB operations
// overwrite virtual Item::SaveToDB
- void SaveToDB();
+ void SaveToDB(SQLTransaction& trans);
// overwrite virtual Item::LoadFromDB
bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result, uint32 entry);
// overwrite virtual Item::DeleteFromDB
- void DeleteFromDB();
+ void DeleteFromDB(SQLTransaction& trans);
void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const;
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index ef7ac10634a..4e615052cba 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -301,7 +301,7 @@ void Item::UpdateDuration(Player* owner, uint32 diff)
SetState(ITEM_CHANGED, owner); // save new time in database
}
-void Item::SaveToDB()
+void Item::SaveToDB(SQLTransaction& trans)
{
uint32 guid = GetGUIDLow();
switch (uState)
@@ -334,7 +334,7 @@ void Item::SaveToDB()
ss << GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME) << ",'";
ss << text << "')";
- CharacterDatabase.Execute(ss.str().c_str());
+ trans->Append(ss.str().c_str());
}break;
case ITEM_CHANGED:
{
@@ -364,16 +364,16 @@ void Item::SaveToDB()
ss << ", playedTime = " << GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME);
ss << ", text = '" << text << "' WHERE guid = " << guid;
- CharacterDatabase.Execute(ss.str().c_str());
+ trans->Append(ss.str().c_str());
if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
- CharacterDatabase.PExecute("UPDATE character_gifts SET guid = '%u' WHERE item_guid = '%u'", GUID_LOPART(GetOwnerGUID()),GetGUIDLow());
+ trans->PAppend("UPDATE character_gifts SET guid = '%u' WHERE item_guid = '%u'", GUID_LOPART(GetOwnerGUID()),GetGUIDLow());
}break;
case ITEM_REMOVED:
{
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", guid);
+ trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", guid);
if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
- CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", GetGUIDLow());
+ trans->PAppend("DELETE FROM character_gifts WHERE item_guid = '%u'", GetGUIDLow());
delete this;
return;
}
@@ -471,14 +471,14 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result
return true;
}
-void Item::DeleteFromDB()
+void Item::DeleteFromDB(SQLTransaction& trans)
{
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'",GetGUIDLow());
+ trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'",GetGUIDLow());
}
-void Item::DeleteFromInventoryDB()
+void Item::DeleteFromInventoryDB(SQLTransaction& trans)
{
- CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'",GetGUIDLow());
+ trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'",GetGUIDLow());
}
ItemPrototype const *Item::GetProto() const
@@ -1103,11 +1103,11 @@ void Item::BuildUpdate(UpdateDataMapType& data_map)
void Item::SaveRefundDataToDB()
{
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM item_refund_instance WHERE item_guid = '%u'", GetGUIDLow());
- CharacterDatabase.PExecute("INSERT INTO item_refund_instance (`item_guid`,`player_guid`,`paidMoney`,`paidExtendedCost`)"
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM item_refund_instance WHERE item_guid = '%u'", GetGUIDLow());
+ trans->PAppend("INSERT INTO item_refund_instance (`item_guid`,`player_guid`,`paidMoney`,`paidExtendedCost`)"
" VALUES('%u','%u','%u','%u')", GetGUIDLow(), GetRefundRecipient(), GetPaidMoney(), GetPaidExtendedCost());
- CharacterDatabase.CommitTransaction();
+ CharacterDatabase.CommitTransaction(trans);
}
void Item::DeleteRefundDataFromDB()
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index bab9bc9060a..25b4b69a607 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -244,10 +244,10 @@ class Item : public Object
bool IsBoundAccountWide() const { return (GetProto()->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT) != 0; }
bool IsBindedNotWith(Player const* player) const;
bool IsBoundByEnchant() const;
- virtual void SaveToDB();
+ virtual void SaveToDB(SQLTransaction& trans);
virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result, uint32 entry);
- virtual void DeleteFromDB();
- void DeleteFromInventoryDB();
+ virtual void DeleteFromDB(SQLTransaction& trans);
+ void DeleteFromInventoryDB(SQLTransaction& trans);
void SaveRefundDataToDB();
void DeleteRefundDataFromDB();
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index e6ee2dcae74..f5780f1c696 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -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],
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index 36e4b7ce727..48f36ca8c07 100644
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -191,11 +191,11 @@ class Pet : public Guardian
bool IsPetAura(Aura const* aura);
void _LoadSpellCooldowns();
- void _SaveSpellCooldowns();
+ void _SaveSpellCooldowns(SQLTransaction& trans);
void _LoadAuras(uint32 timediff);
- void _SaveAuras();
+ void _SaveAuras(SQLTransaction& trans);
void _LoadSpells();
- void _SaveSpells();
+ void _SaveSpells(SQLTransaction& trans);
bool addSpell(uint32 spell_id,ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
bool learnSpell(uint32 spell_id);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index f016bb88117..4a1bab14cd1 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2736,7 +2736,12 @@ void Player::GiveLevel(uint8 level)
pet->SynchronizeLevelWithOwner();
if (MailLevelReward const* mailReward = sObjectMgr.GetMailLevelReward(level,getRaceMask()))
- MailDraft(mailReward->mailTemplateId).SendMailTo(this,MailSender(MAIL_CREATURE,mailReward->senderEntry));
+ {
+ //- TODO: Poor design of mail system
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ MailDraft(mailReward->mailTemplateId).SendMailTo(trans, this,MailSender(MAIL_CREATURE,mailReward->senderEntry));
+ CharacterDatabase.CommitTransaction(trans);
+ }
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
}
@@ -3925,9 +3930,9 @@ void Player::_LoadSpellCooldowns(QueryResult_AutoPtr result)
}
}
-void Player::_SaveSpellCooldowns()
+void Player::_SaveSpellCooldowns(SQLTransaction& trans)
{
- CharacterDatabase.PExecute("DELETE FROM character_spell_cooldown WHERE guid = '%u'", GetGUIDLow());
+ trans->PAppend("DELETE FROM character_spell_cooldown WHERE guid = '%u'", GetGUIDLow());
time_t curTime = time(NULL);
time_t infTime = curTime + infinityCooldownDelayCheck;
@@ -3959,7 +3964,7 @@ void Player::_SaveSpellCooldowns()
}
// if something changed execute
if (!first_round)
- CharacterDatabase.Execute(ss.str().c_str());
+ trans->Append(ss.str().c_str());
}
uint32 Player::resetTalentsCost() const
@@ -4059,7 +4064,9 @@ bool Player::resetTalents(bool no_cost)
}
}
- _SaveSpells();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ _SaveSpells(trans);
+ CharacterDatabase.CommitTransaction(trans);
SetFreeTalentPoints(talentPointsForLevel);
@@ -4416,6 +4423,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
// Completely remove from the database
case CHAR_DELETE_REMOVE:
{
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
// Return back all mails with COD and Item 0 1 2 3 4 5 6 7
QueryResult_AutoPtr resultMail = CharacterDatabase.PQuery("SELECT id,messageType,mailTemplateId,sender,subject,body,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid);
if (resultMail)
@@ -4435,13 +4443,13 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
// We can return mail now
// So firstly delete the old one
- CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", mail_id);
+ trans->PAppend("DELETE FROM mail WHERE id = '%u'", mail_id);
// Mail is not from player
if (mailType != MAIL_NORMAL)
{
if (has_items)
- CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id);
+ trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id);
continue;
}
@@ -4465,7 +4473,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
ItemPrototype const* itemProto = sObjectMgr.GetItemPrototype(item_template);
if (!itemProto)
{
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item_guidlow);
+ trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", item_guidlow);
continue;
}
@@ -4473,7 +4481,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
if (!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER), resultItems, item_template))
{
pItem->FSetState(ITEM_REMOVED);
- pItem->SaveToDB(); // it also deletes item object!
+ pItem->SaveToDB(trans); // it also deletes item object!
continue;
}
@@ -4483,7 +4491,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
}
}
- CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id);
+ trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id);
uint32 pl_account = sObjectMgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
@@ -4497,7 +4505,6 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
QueryResult_AutoPtr resultPets = CharacterDatabase.PQuery("SELECT id FROM character_pet WHERE owner = '%u'",guid);
// NOW we can finally clear other DB data related to character
- CharacterDatabase.BeginTransaction();
if (resultPets)
{
do
@@ -4508,41 +4515,41 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
} while (resultPets->NextRow());
}
- CharacterDatabase.PExecute("DELETE FROM characters WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_account_data WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_action WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_homebind WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_queststatus WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_reputation WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_spell_cooldown WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM gm_tickets WHERE playerGuid = '%u'", guid);
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE owner_guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_social WHERE guid = '%u' OR friend='%u'",guid,guid);
- CharacterDatabase.PExecute("DELETE FROM mail WHERE receiver = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM mail_items WHERE receiver = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = '%u' " // NOTE: These achievements have flags & 256 in DBC.
+ trans->PAppend("DELETE FROM characters WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_account_data WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_declinedname WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_action WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_aura WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_gifts WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_homebind WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_instance WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_inventory WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_queststatus WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_reputation WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_spell WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_spell_cooldown WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM gm_tickets WHERE playerGuid = '%u'", guid);
+ trans->PAppend("DELETE FROM item_instance WHERE owner_guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_social WHERE guid = '%u' OR friend='%u'",guid,guid);
+ trans->PAppend("DELETE FROM mail WHERE receiver = '%u'",guid);
+ trans->PAppend("DELETE FROM mail_items WHERE receiver = '%u'",guid);
+ trans->PAppend("DELETE FROM character_pet WHERE owner = '%u'",guid);
+ trans->PAppend("DELETE FROM character_pet_declinedname WHERE owner = '%u'",guid);
+ trans->PAppend("DELETE FROM character_achievement WHERE guid = '%u' " // NOTE: These achievements have flags & 256 in DBC.
"AND achievement NOT BETWEEN '456' AND '467' " // Realm First Level 80
"AND achievement NOT BETWEEN '1400' AND '1427' " // Realm First Raid Achievements
"AND achievement NOT IN(1463, 3117, 3259) ", guid); // Realm First Northen Vanguard + Raid Achievements
- CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_equipmentsets WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE PlayerGuid1 = '%u' OR PlayerGuid2 = '%u'",guid, guid);
- CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE PlayerGuid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_battleground_data WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_glyphs WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_queststatus_daily WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_talent WHERE guid = '%u'",guid);
- CharacterDatabase.PExecute("DELETE FROM character_skills WHERE guid = '%u'",guid);
-
- CharacterDatabase.CommitTransaction();
+ trans->PAppend("DELETE FROM character_achievement_progress WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_equipmentsets WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM guild_eventlog WHERE PlayerGuid1 = '%u' OR PlayerGuid2 = '%u'",guid, guid);
+ trans->PAppend("DELETE FROM guild_bank_eventlog WHERE PlayerGuid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_battleground_data WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_glyphs WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_queststatus_daily WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_talent WHERE guid = '%u'",guid);
+ trans->PAppend("DELETE FROM character_skills WHERE guid = '%u'",guid);
+
+ CharacterDatabase.CommitTransaction(trans);
break;
}
// The character gets unlinked from the account, the name gets freed up and appears as deleted ingame
@@ -5071,7 +5078,11 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g
return TotalCost;
}
- pGuild->MemberMoneyWithdraw(costs, GetGUIDLow());
+ //- TODO: Fix bad function call design
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ pGuild->MemberMoneyWithdraw(costs, GetGUIDLow(), trans);
+ CharacterDatabase.CommitTransaction(trans);
+
TotalCost = costs;
}
else if (GetMoney() < costs)
@@ -14429,7 +14440,12 @@ void Player::RewardQuest(Quest const *pQuest, uint32 reward, Object* questGiver,
// Send reward mail
if (uint32 mail_template_id = pQuest->GetRewMailTemplateId())
- MailDraft(mail_template_id).SendMailTo(this, questGiver, MAIL_CHECK_MASK_HAS_BODY, pQuest->GetRewMailDelaySecs());
+ {
+ //- TODO: Poor design of mail system
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ MailDraft(mail_template_id).SendMailTo(trans, this, questGiver, MAIL_CHECK_MASK_HAS_BODY, pQuest->GetRewMailDelaySecs());
+ CharacterDatabase.CommitTransaction(trans);
+ }
if (pQuest->IsDaily())
{
@@ -16668,6 +16684,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
if (result)
{
std::list<Item*> problematicItems;
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
// prevent items from being added to the queue when stored
m_itemUpdateQueueBlocked = true;
@@ -16683,8 +16700,8 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
if (!proto)
{
- CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item_guid);
+ trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
+ trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", item_guid);
sLog.outError("Player::_LoadInventory: Player %s has an unknown item (id: #%u) in inventory, deleted.", GetName(),item_id);
continue;
}
@@ -16696,7 +16713,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
sLog.outError("Player::_LoadInventory: Player %s has broken item (id: #%u) in inventory, deleted.", GetName(),item_id);
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
item->FSetState(ITEM_REMOVED);
- item->SaveToDB(); // it also deletes item object !
+ item->SaveToDB(trans); // it also deletes item object !
continue;
}
@@ -16705,7 +16722,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
{
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
item->FSetState(ITEM_REMOVED);
- item->SaveToDB(); // it also deletes item object !
+ item->SaveToDB(trans); // it also deletes item object !
continue;
}
@@ -16714,7 +16731,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
{
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
item->FSetState(ITEM_REMOVED);
- item->SaveToDB(); // it also deletes item object !
+ item->SaveToDB(trans); // it also deletes item object !
continue;
}
@@ -16723,7 +16740,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
if (item->GetPlayedTime() > (2*HOUR))
{
sLog.outDebug("Item::LoadFromDB, Item GUID: %u: refund time expired, deleting refund data and removing refundable flag.", item->GetGUIDLow());
- CharacterDatabase.PExecute("DELETE FROM item_refund_instance WHERE item_guid = '%u'", item->GetGUIDLow());
+ trans->PAppend("DELETE FROM item_refund_instance WHERE item_guid = '%u'", item->GetGUIDLow());
item->RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE);
}
else
@@ -16839,8 +16856,9 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
draft.AddItem(item);
}
- draft.SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM), MAIL_CHECK_MASK_COPIED);
+ draft.SendMailTo(trans, this, MailSender(this, MAIL_STATIONERY_GM), MAIL_CHECK_MASK_COPIED);
}
+ CharacterDatabase.CommitTransaction(trans);
}
//if (isAlive())
_ApplyAllItemMods();
@@ -16854,6 +16872,7 @@ void Player::_LoadMailedItems(Mail *mail)
if (!result)
return;
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
do
{
Field *fields = result->Fetch();
@@ -16867,8 +16886,8 @@ void Player::_LoadMailedItems(Mail *mail)
if (!proto)
{
sLog.outError("Player %u has unknown item_template (ProtoType) in mailed items(GUID: %u template: %u) in mail (%u), deleted.", GetGUIDLow(), item_guid_low, item_template,mail->messageID);
- CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item_guid_low);
+ trans->PAppend("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
+ trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", item_guid_low);
continue;
}
@@ -16879,12 +16898,14 @@ void Player::_LoadMailedItems(Mail *mail)
sLog.outError("Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, item_guid_low);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
item->FSetState(ITEM_REMOVED);
- item->SaveToDB(); // it also deletes item object !
+ item->SaveToDB(trans); // it also deletes item object !
continue;
}
AddMItem(item);
} while (result->NextRow());
+
+ CharacterDatabase.CommitTransaction(trans);
}
void Player::_LoadMailInit(QueryResult_AutoPtr resultUnread, QueryResult_AutoPtr resultDelivery)
@@ -17737,36 +17758,36 @@ void Player::SaveToDB()
ss << uint32(GetByteValue(PLAYER_FIELD_BYTES, 2));
ss << ")";
- CharacterDatabase.BeginTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
- CharacterDatabase.Execute(ss.str().c_str());
+ trans->Append(ss.str().c_str());
if (m_mailsUpdated) //save mails only when needed
- _SaveMail();
-
- _SaveBGData();
- _SaveInventory();
- _SaveQuestStatus();
- _SaveDailyQuestStatus();
- _SaveWeeklyQuestStatus();
- _SaveTalents();
- _SaveSpells();
- _SaveSpellCooldowns();
- _SaveActions();
- _SaveAuras();
- _SaveSkills();
- m_achievementMgr.SaveToDB();
- m_reputationMgr.SaveToDB();
- _SaveEquipmentSets();
- GetSession()->SaveTutorialsData(); // changed only while character in game
- _SaveGlyphs();
+ _SaveMail(trans);
+
+ _SaveBGData(trans);
+ _SaveInventory(trans);
+ _SaveQuestStatus(trans);
+ _SaveDailyQuestStatus(trans);
+ _SaveWeeklyQuestStatus(trans);
+ _SaveTalents(trans);
+ _SaveSpells(trans);
+ _SaveSpellCooldowns(trans);
+ _SaveActions(trans);
+ _SaveAuras(trans);
+ _SaveSkills(trans);
+ m_achievementMgr.SaveToDB(trans);
+ m_reputationMgr.SaveToDB(trans);
+ _SaveEquipmentSets(trans);
+ GetSession()->SaveTutorialsData(trans); // changed only while character in game
+ _SaveGlyphs(trans);
// check if stats should only be saved on logout
// save stats can be out of transaction
if (m_session->isLogingOut() || !sWorld.getConfig(CONFIG_STATS_SAVE_ONLY_ON_LOGOUT))
- _SaveStats();
+ _SaveStats(trans);
- CharacterDatabase.CommitTransaction();
+ CharacterDatabase.CommitTransaction(trans);
// save pet (hunter pet level and experience and all type pets health/mana).
if (Pet* pet = GetPet())
@@ -17775,37 +17796,37 @@ void Player::SaveToDB()
}
// fast save function for item/money cheating preventing - save only inventory and money state
-void Player::SaveInventoryAndGoldToDB()
+void Player::SaveInventoryAndGoldToDB(SQLTransaction& trans)
{
- _SaveInventory();
- SaveGoldToDB();
+ _SaveInventory(trans);
+ SaveGoldToDB(trans);
}
-void Player::SaveGoldToDB()
+void Player::SaveGoldToDB(SQLTransaction& trans)
{
- CharacterDatabase.PExecute("UPDATE characters SET money = '%u' WHERE guid = '%u'", GetMoney(), GetGUIDLow());
+ trans->PAppend("UPDATE characters SET money = '%u' WHERE guid = '%u'", GetMoney(), GetGUIDLow());
}
-void Player::_SaveActions()
+void Player::_SaveActions(SQLTransaction& trans)
{
for (ActionButtonList::iterator itr = m_actionButtons.begin(); itr != m_actionButtons.end();)
{
switch (itr->second.uState)
{
case ACTIONBUTTON_NEW:
- CharacterDatabase.PExecute("INSERT INTO character_action (guid,spec,button,action,type) VALUES ('%u', '%u', '%u', '%u', '%u')",
+ trans->PAppend("INSERT INTO character_action (guid,spec,button,action,type) VALUES ('%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), m_activeSpec, (uint32)itr->first, (uint32)itr->second.GetAction(), (uint32)itr->second.GetType());
itr->second.uState = ACTIONBUTTON_UNCHANGED;
++itr;
break;
case ACTIONBUTTON_CHANGED:
- CharacterDatabase.PExecute("UPDATE character_action SET action = '%u', type = '%u' WHERE guid = '%u' AND button = '%u' AND spec = '%u'",
+ trans->PAppend("UPDATE character_action SET action = '%u', type = '%u' WHERE guid = '%u' AND button = '%u' AND spec = '%u'",
(uint32)itr->second.GetAction(), (uint32)itr->second.GetType(), GetGUIDLow(), (uint32)itr->first, m_activeSpec);
itr->second.uState = ACTIONBUTTON_UNCHANGED;
++itr;
break;
case ACTIONBUTTON_DELETED:
- CharacterDatabase.PExecute("DELETE FROM character_action WHERE guid = '%u' and button = '%u' and spec = '%u'", GetGUIDLow(), (uint32)itr->first, m_activeSpec);
+ trans->PAppend("DELETE FROM character_action WHERE guid = '%u' and button = '%u' and spec = '%u'", GetGUIDLow(), (uint32)itr->first, m_activeSpec);
m_actionButtons.erase(itr++);
break;
default:
@@ -17815,9 +17836,9 @@ void Player::_SaveActions()
}
}
-void Player::_SaveAuras()
+void Player::_SaveAuras(SQLTransaction& trans)
{
- CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow());
+ trans->PAppend("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow());
for (AuraMap::const_iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end() ; ++itr)
{
@@ -17847,7 +17868,7 @@ void Player::_SaveAuras()
}
}
- CharacterDatabase.PExecute("INSERT INTO character_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 character_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')",
GetGUIDLow(), itr->second->GetCasterGUID(), itr->second->GetId(), effMask, recalculateMask,
itr->second->GetStackAmount(), damage[0], damage[1], damage[2], baseDamage[0], baseDamage[1], baseDamage[2],
@@ -17855,7 +17876,7 @@ void Player::_SaveAuras()
}
}
-void Player::_SaveInventory()
+void Player::_SaveInventory(SQLTransaction& trans)
{
// force items in buyback slots to new state
// and remove those that aren't already
@@ -17864,8 +17885,8 @@ void Player::_SaveInventory()
Item *item = m_items[i];
if (!item || item->GetState() == ITEM_NEW)
continue;
- CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item->GetGUIDLow());
+ trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
+ trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", item->GetGUIDLow());
m_items[i]->FSetState(ITEM_NEW);
}
@@ -17942,25 +17963,25 @@ void Player::_SaveInventory()
switch (item->GetState())
{
case ITEM_NEW:
- CharacterDatabase.PExecute("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
+ trans->PAppend("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
break;
case ITEM_CHANGED:
- CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
- CharacterDatabase.PExecute("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
+ trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
+ trans->PAppend("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
break;
case ITEM_REMOVED:
- CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
+ trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
break;
case ITEM_UNCHANGED:
break;
}
- item->SaveToDB(); // item have unchanged inventory record and can be save standalone
+ item->SaveToDB(trans); // item have unchanged inventory record and can be save standalone
}
m_itemUpdateQueue.clear();
}
-void Player::_SaveMail()
+void Player::_SaveMail(SQLTransaction& trans)
{
if (!m_mailsLoaded)
return;
@@ -17970,12 +17991,12 @@ void Player::_SaveMail()
Mail *m = (*itr);
if (m->state == MAIL_STATE_CHANGED)
{
- CharacterDatabase.PExecute("UPDATE mail SET has_items = '%u',expire_time = '" UI64FMTD "', deliver_time = '" UI64FMTD "',money = '%u',cod = '%u',checked = '%u' WHERE id = '%u'",
+ trans->PAppend("UPDATE mail SET has_items = '%u',expire_time = '" UI64FMTD "', deliver_time = '" UI64FMTD "',money = '%u',cod = '%u',checked = '%u' WHERE id = '%u'",
m->HasItems() ? 1 : 0, (uint64)m->expire_time, (uint64)m->deliver_time, m->money, m->COD, m->checked, m->messageID);
if (m->removedItems.size())
{
for (std::vector<uint32>::iterator itr2 = m->removedItems.begin(); itr2 != m->removedItems.end(); ++itr2)
- CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", *itr2);
+ trans->PAppend("DELETE FROM mail_items WHERE item_guid = '%u'", *itr2);
m->removedItems.clear();
}
m->state = MAIL_STATE_UNCHANGED;
@@ -17984,9 +18005,9 @@ void Player::_SaveMail()
{
if (m->HasItems())
for (std::vector<MailItemInfo>::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid);
- CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID);
- CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", m->messageID);
+ trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid);
+ trans->PAppend("DELETE FROM mail WHERE id = '%u'", m->messageID);
+ trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", m->messageID);
}
}
@@ -18007,7 +18028,7 @@ void Player::_SaveMail()
m_mailsUpdated = false;
}
-void Player::_SaveQuestStatus()
+void Player::_SaveQuestStatus(SQLTransaction& trans)
{
// we don't need transactions here.
for (QuestStatusMap::iterator i = mQuestStatus.begin(); i != mQuestStatus.end(); ++i)
@@ -18015,12 +18036,12 @@ void Player::_SaveQuestStatus()
switch (i->second.uState)
{
case QUEST_NEW :
- CharacterDatabase.PExecute("INSERT INTO character_queststatus (guid,quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4) "
+ trans->PAppend("INSERT INTO character_queststatus (guid,quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4) "
"VALUES ('%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), i->first, i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / IN_MILLISECONDS+ sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3]);
break;
case QUEST_CHANGED :
- CharacterDatabase.PExecute("UPDATE character_queststatus SET status = '%u',rewarded = '%u',explored = '%u',timer = '" UI64FMTD "',mobcount1 = '%u',mobcount2 = '%u',mobcount3 = '%u',mobcount4 = '%u',itemcount1 = '%u',itemcount2 = '%u',itemcount3 = '%u',itemcount4 = '%u' WHERE guid = '%u' AND quest = '%u' ",
+ trans->PAppend("UPDATE character_queststatus SET status = '%u',rewarded = '%u',explored = '%u',timer = '" UI64FMTD "',mobcount1 = '%u',mobcount2 = '%u',mobcount3 = '%u',mobcount4 = '%u',itemcount1 = '%u',itemcount2 = '%u',itemcount3 = '%u',itemcount4 = '%u' WHERE guid = '%u' AND quest = '%u' ",
i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / IN_MILLISECONDS + sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3], GetGUIDLow(), i->first);
break;
case QUEST_UNCHANGED:
@@ -18030,7 +18051,7 @@ void Player::_SaveQuestStatus()
}
}
-void Player::_SaveDailyQuestStatus()
+void Player::_SaveDailyQuestStatus(SQLTransaction& trans)
{
if (!m_DailyQuestChanged)
return;
@@ -18040,32 +18061,32 @@ void Player::_SaveDailyQuestStatus()
// save last daily quest time for all quests: we need only mostly reset time for reset check anyway
// we don't need transactions here.
- CharacterDatabase.PExecute("DELETE FROM character_queststatus_daily WHERE guid = '%u'",GetGUIDLow());
+ trans->PAppend("DELETE FROM character_queststatus_daily WHERE guid = '%u'",GetGUIDLow());
for (uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
if (GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx))
- CharacterDatabase.PExecute("INSERT INTO character_queststatus_daily (guid,quest,time) VALUES ('%u', '%u','" UI64FMTD "')",
+ trans->PAppend("INSERT INTO character_queststatus_daily (guid,quest,time) VALUES ('%u', '%u','" UI64FMTD "')",
GetGUIDLow(), GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx),uint64(m_lastDailyQuestTime));
}
-void Player::_SaveWeeklyQuestStatus()
+void Player::_SaveWeeklyQuestStatus(SQLTransaction& trans)
{
if (!m_WeeklyQuestChanged || m_weeklyquests.empty())
return;
// we don't need transactions here.
- CharacterDatabase.PExecute("DELETE FROM character_queststatus_weekly WHERE guid = '%u'",GetGUIDLow());
+ trans->PAppend("DELETE FROM character_queststatus_weekly WHERE guid = '%u'",GetGUIDLow());
for (QuestSet::const_iterator iter = m_weeklyquests.begin(); iter != m_weeklyquests.end(); ++iter)
{
uint32 quest_id = *iter;
- CharacterDatabase.PExecute("INSERT INTO character_queststatus_weekly (guid,quest) VALUES ('%u', '%u')", GetGUIDLow(), quest_id);
+ trans->PAppend("INSERT INTO character_queststatus_weekly (guid,quest) VALUES ('%u', '%u')", GetGUIDLow(), quest_id);
}
m_WeeklyQuestChanged = false;
}
-void Player::_SaveSkills()
+void Player::_SaveSkills(SQLTransaction& trans)
{
// we don't need transactions here.
for (SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end();)
@@ -18078,7 +18099,7 @@ void Player::_SaveSkills()
if (itr->second.uState == SKILL_DELETED)
{
- CharacterDatabase.PExecute("DELETE FROM character_skills WHERE guid = '%u' AND skill = '%u' ", GetGUIDLow(), itr->first);
+ trans->PAppend("DELETE FROM character_skills WHERE guid = '%u' AND skill = '%u' ", GetGUIDLow(), itr->first);
mSkillStatus.erase(itr++);
continue;
}
@@ -18090,11 +18111,11 @@ void Player::_SaveSkills()
switch (itr->second.uState)
{
case SKILL_NEW:
- CharacterDatabase.PExecute("INSERT INTO character_skills (guid, skill, value, max) VALUES ('%u', '%u', '%u', '%u')",
+ trans->PAppend("INSERT INTO character_skills (guid, skill, value, max) VALUES ('%u', '%u', '%u', '%u')",
GetGUIDLow(), itr->first, value, max);
break;
case SKILL_CHANGED:
- CharacterDatabase.PExecute("UPDATE character_skills SET value = '%u',max = '%u'WHERE guid = '%u' AND skill = '%u' ",
+ trans->PAppend("UPDATE character_skills SET value = '%u',max = '%u'WHERE guid = '%u' AND skill = '%u' ",
value, max, GetGUIDLow(), itr->first);
break;
};
@@ -18104,16 +18125,16 @@ void Player::_SaveSkills()
}
}
-void Player::_SaveSpells()
+void Player::_SaveSpells(SQLTransaction& trans)
{
for (PlayerSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end();)
{
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
- CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first);
+ trans->PAppend("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first);
// add only changed/new not dependent spells
if (!itr->second->dependent && (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED))
- CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,active,disabled) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0);
+ trans->PAppend("INSERT INTO character_spell (guid,spell,active,disabled) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0);
if (itr->second->state == PLAYERSPELL_REMOVED)
{
@@ -18131,13 +18152,13 @@ void Player::_SaveSpells()
// save player stats -- only for external usage
// real stats will be recalculated on player login
-void Player::_SaveStats()
+void Player::_SaveStats(SQLTransaction& trans)
{
// check if stat saving is enabled and if char level is high enough
if (!sWorld.getConfig(CONFIG_MIN_LEVEL_STAT_SAVE) || getLevel() < sWorld.getConfig(CONFIG_MIN_LEVEL_STAT_SAVE))
return;
- CharacterDatabase.PExecute("DELETE FROM character_stats WHERE guid = '%u'", GetGUIDLow());
+ trans->PAppend("DELETE FROM character_stats WHERE guid = '%u'", GetGUIDLow());
std::ostringstream ss;
ss << "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, "
"strength, agility, stamina, intellect, spirit, armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, "
@@ -18160,7 +18181,7 @@ void Player::_SaveStats()
<< GetUInt32Value(UNIT_FIELD_ATTACK_POWER) << ", "
<< GetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) << ", "
<< GetBaseSpellPowerBonus() << ")";
- CharacterDatabase.Execute(ss.str().c_str());
+ trans->Append(ss.str().c_str());
}
void Player::outDebugValues() const
@@ -19084,18 +19105,18 @@ void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type)
CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE playerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type);
}
- CharacterDatabase.BeginTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (type == 10)
{
- CharacterDatabase.PExecute("DELETE FROM petition WHERE ownerguid = '%u'", GUID_LOPART(guid));
- CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE ownerguid = '%u'", GUID_LOPART(guid));
+ trans->PAppend("DELETE FROM petition WHERE ownerguid = '%u'", GUID_LOPART(guid));
+ trans->PAppend("DELETE FROM petition_sign WHERE ownerguid = '%u'", GUID_LOPART(guid));
}
else
{
- CharacterDatabase.PExecute("DELETE FROM petition WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type);
- CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type);
+ trans->PAppend("DELETE FROM petition WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type);
+ trans->PAppend("DELETE FROM petition_sign WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type);
}
- CharacterDatabase.CommitTransaction();
+ CharacterDatabase.CommitTransaction(trans);
}
void Player::LeaveAllArenaTeams(uint64 guid)
@@ -21507,13 +21528,14 @@ void Player::AutoUnequipOffhandIfNeed(bool force /*= false*/)
else
{
MoveItemFromInventory(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true);
- CharacterDatabase.BeginTransaction();
- offItem->DeleteFromInventoryDB(); // deletes item from character's inventory
- offItem->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
- CharacterDatabase.CommitTransaction();
-
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ offItem->DeleteFromInventoryDB(trans); // deletes item from character's inventory
+ offItem->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
+
std::string subject = GetSession()->GetTrinityString(LANG_NOT_EQUIPPED_ITEM);
- MailDraft(subject, "There were problems with equipping one or several items").AddItem(offItem).SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM), MAIL_CHECK_MASK_COPIED);
+ MailDraft(subject, "There were problems with equipping one or several items").AddItem(offItem).SendMailTo(trans, this, MailSender(this, MAIL_STATIONERY_GM), MAIL_CHECK_MASK_COPIED);
+
+ CharacterDatabase.CommitTransaction(trans);
}
}
@@ -23519,7 +23541,7 @@ void Player::SetEquipmentSet(uint32 index, EquipmentSet eqset)
eqslot.state = old_state == EQUIPMENT_SET_NEW ? EQUIPMENT_SET_NEW : EQUIPMENT_SET_CHANGED;
}
-void Player::_SaveEquipmentSets()
+void Player::_SaveEquipmentSets(SQLTransaction& trans)
{
for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end();)
{
@@ -23533,7 +23555,7 @@ void Player::_SaveEquipmentSets()
case EQUIPMENT_SET_CHANGED:
CharacterDatabase.escape_string(eqset.Name);
CharacterDatabase.escape_string(eqset.IconName);
- CharacterDatabase.PExecute("UPDATE character_equipmentsets SET name='%s', iconname='%s', item0='%u', item1='%u', item2='%u', item3='%u', item4='%u', item5='%u', item6='%u', item7='%u', item8='%u', item9='%u', item10='%u', item11='%u', item12='%u', item13='%u', item14='%u', item15='%u', item16='%u', item17='%u', item18='%u' WHERE guid='%u' AND setguid='"UI64FMTD"' AND setindex='%u'",
+ trans->PAppend("UPDATE character_equipmentsets SET name='%s', iconname='%s', item0='%u', item1='%u', item2='%u', item3='%u', item4='%u', item5='%u', item6='%u', item7='%u', item8='%u', item9='%u', item10='%u', item11='%u', item12='%u', item13='%u', item14='%u', item15='%u', item16='%u', item17='%u', item18='%u' WHERE guid='%u' AND setguid='"UI64FMTD"' AND setindex='%u'",
eqset.Name.c_str(), eqset.IconName.c_str(), eqset.Items[0], eqset.Items[1], eqset.Items[2], eqset.Items[3], eqset.Items[4], eqset.Items[5], eqset.Items[6], eqset.Items[7],
eqset.Items[8], eqset.Items[9], eqset.Items[10], eqset.Items[11], eqset.Items[12], eqset.Items[13], eqset.Items[14], eqset.Items[15], eqset.Items[16], eqset.Items[17], eqset.Items[18], GetGUIDLow(), eqset.Guid, index);
eqset.state = EQUIPMENT_SET_UNCHANGED;
@@ -23542,27 +23564,27 @@ void Player::_SaveEquipmentSets()
case EQUIPMENT_SET_NEW:
CharacterDatabase.escape_string(eqset.Name);
CharacterDatabase.escape_string(eqset.IconName);
- CharacterDatabase.PExecute("INSERT INTO character_equipmentsets VALUES ('%u', '"UI64FMTD"', '%u', '%s', '%s', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
+ trans->PAppend("INSERT INTO character_equipmentsets VALUES ('%u', '"UI64FMTD"', '%u', '%s', '%s', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), eqset.Guid, index, eqset.Name.c_str(), eqset.IconName.c_str(), eqset.Items[0], eqset.Items[1], eqset.Items[2], eqset.Items[3], eqset.Items[4], eqset.Items[5], eqset.Items[6], eqset.Items[7],
eqset.Items[8], eqset.Items[9], eqset.Items[10], eqset.Items[11], eqset.Items[12], eqset.Items[13], eqset.Items[14], eqset.Items[15], eqset.Items[16], eqset.Items[17], eqset.Items[18]);
eqset.state = EQUIPMENT_SET_UNCHANGED;
++itr;
break;
case EQUIPMENT_SET_DELETED:
- CharacterDatabase.PExecute("DELETE FROM character_equipmentsets WHERE setguid="UI64FMTD, eqset.Guid);
+ trans->PAppend("DELETE FROM character_equipmentsets WHERE setguid="UI64FMTD, eqset.Guid);
m_EquipmentSets.erase(itr++);
break;
}
}
}
-void Player::_SaveBGData()
+void Player::_SaveBGData(SQLTransaction& trans)
{
- CharacterDatabase.PExecute("DELETE FROM character_battleground_data WHERE guid='%u'", GetGUIDLow());
+ trans->PAppend("DELETE FROM character_battleground_data WHERE guid='%u'", GetGUIDLow());
if (m_bgData.bgInstanceID)
{
/* guid, bgInstanceID, bgTeam, x, y, z, o, map, taxi[0], taxi[1], mountSpell */
- CharacterDatabase.PExecute("INSERT INTO character_battleground_data VALUES ('%u', '%u', '%u', '%f', '%f', '%f', '%f', '%u', '%u', '%u', '%u')",
+ trans->PAppend("INSERT INTO character_battleground_data VALUES ('%u', '%u', '%u', '%f', '%f', '%f', '%f', '%u', '%u', '%u', '%u')",
GetGUIDLow(), m_bgData.bgInstanceID, m_bgData.bgTeam, m_bgData.joinPos.GetPositionX(), m_bgData.joinPos.GetPositionY(), m_bgData.joinPos.GetPositionZ(),
m_bgData.joinPos.GetOrientation(), m_bgData.joinPos.GetMapId(), m_bgData.taxiPath[0], m_bgData.taxiPath[1], m_bgData.mountSpell);
}
@@ -23641,12 +23663,12 @@ void Player::_LoadGlyphs(QueryResult_AutoPtr result)
} while (result->NextRow());
}
-void Player::_SaveGlyphs()
+void Player::_SaveGlyphs(SQLTransaction& trans)
{
- CharacterDatabase.PExecute("DELETE FROM character_glyphs WHERE guid='%u'",GetGUIDLow());
+ trans->PAppend("DELETE FROM character_glyphs WHERE guid='%u'",GetGUIDLow());
for (uint8 spec = 0; spec < m_specsCount; ++spec)
{
- CharacterDatabase.PExecute("INSERT INTO character_glyphs VALUES('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
+ trans->PAppend("INSERT INTO character_glyphs VALUES('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), spec, m_Glyphs[spec][0], m_Glyphs[spec][1], m_Glyphs[spec][2], m_Glyphs[spec][3], m_Glyphs[spec][4], m_Glyphs[spec][5]);
}
}
@@ -23666,17 +23688,17 @@ void Player::_LoadTalents(QueryResult_AutoPtr result)
}
}
-void Player::_SaveTalents()
+void Player::_SaveTalents(SQLTransaction& trans)
{
for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
{
for (PlayerTalentMap::iterator itr = m_talents[i]->begin(); itr != m_talents[i]->end();)
{
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
- CharacterDatabase.PExecute("DELETE FROM character_talent WHERE guid = '%u' and spell = '%u' and spec = '%u'", GetGUIDLow(), itr->first, itr->second->spec);
+ trans->PAppend("DELETE FROM character_talent WHERE guid = '%u' and spell = '%u' and spec = '%u'", GetGUIDLow(), itr->first, itr->second->spec);
if (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED)
- CharacterDatabase.PExecute("INSERT INTO character_talent (guid,spell,spec) VALUES ('%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->spec);
+ trans->PAppend("INSERT INTO character_talent (guid,spell,spec) VALUES ('%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->spec);
if (itr->second->state == PLAYERSPELL_REMOVED)
{
@@ -23701,23 +23723,26 @@ void Player::UpdateSpecCount(uint8 count)
if (m_activeSpec >= count)
ActivateSpec(0);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
// Copy spec data
if (count > curCount)
{
- _SaveActions(); // make sure the button list is cleaned up
+ _SaveActions(trans); // make sure the button list is cleaned up
for (ActionButtonList::iterator itr = m_actionButtons.begin(); itr != m_actionButtons.end(); ++itr)
- CharacterDatabase.PExecute("INSERT INTO character_action (guid,button,action,type,spec) VALUES ('%u', '%u', '%u', '%u', '%u')",
+ trans->PAppend("INSERT INTO character_action (guid,button,action,type,spec) VALUES ('%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), uint32(itr->first), uint32(itr->second.GetAction()), uint32(itr->second.GetType()), 1);
}
// Delete spec data for removed spec.
else if (count < curCount)
{
- _SaveActions();
- CharacterDatabase.PExecute("DELETE FROM character_action WHERE spec<>'%u' AND guid='%u'",m_activeSpec, GetGUIDLow());
+ _SaveActions(trans);
+ trans->PAppend("DELETE FROM character_action WHERE spec<>'%u' AND guid='%u'",m_activeSpec, GetGUIDLow());
m_activeSpec = 0;
}
-
+
+ CharacterDatabase.CommitTransaction(trans);
SetSpecsCount(count);
@@ -23740,7 +23765,9 @@ void Player::ActivateSpec(uint8 spec)
if (IsNonMeleeSpellCasted(false))
InterruptNonMeleeSpells(false);
- _SaveActions();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ _SaveActions(trans);
+ CharacterDatabase.CommitTransaction(trans);
UnsummonPetTemporaryIfAny();
ClearComboPointHolders();
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 24233681a23..26acb7266c0 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1422,8 +1422,9 @@ class Player : public Unit, public GridObject<Player>
/*********************************************************/
void SaveToDB();
- void SaveInventoryAndGoldToDB(); // fast save function for item/money cheating preventing
- void SaveGoldToDB();
+ void SaveInventoryAndGoldToDB(SQLTransaction& trans); // fast save function for item/money cheating preventing
+ void SaveGoldToDB(SQLTransaction& trans);
+
static void SetUInt32ValueInArray(Tokens& data,uint16 index, uint32 value);
static void SetFloatValueInArray(Tokens& data,uint16 index, float value);
static void Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair);
@@ -1617,7 +1618,7 @@ class Player : public Unit, public GridObject<Player>
void RemoveArenaSpellCooldowns();
void RemoveAllSpellCooldown();
void _LoadSpellCooldowns(QueryResult_AutoPtr result);
- void _SaveSpellCooldowns();
+ void _SaveSpellCooldowns(SQLTransaction& trans);
void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; }
void UpdatePotionCooldown(Spell* spell = NULL);
@@ -2428,20 +2429,20 @@ class Player : public Unit, public GridObject<Player>
/*** SAVE SYSTEM ***/
/*********************************************************/
- void _SaveActions();
- void _SaveAuras();
- void _SaveInventory();
- void _SaveMail();
- void _SaveQuestStatus();
- void _SaveDailyQuestStatus();
- void _SaveWeeklyQuestStatus();
- void _SaveSkills();
- void _SaveSpells();
- void _SaveEquipmentSets();
- void _SaveBGData();
- void _SaveGlyphs();
- void _SaveTalents();
- void _SaveStats();
+ void _SaveActions(SQLTransaction& trans);
+ void _SaveAuras(SQLTransaction& trans);
+ void _SaveInventory(SQLTransaction& trans);
+ void _SaveMail(SQLTransaction& trans);
+ void _SaveQuestStatus(SQLTransaction& trans);
+ void _SaveDailyQuestStatus(SQLTransaction& trans);
+ void _SaveWeeklyQuestStatus(SQLTransaction& trans);
+ void _SaveSkills(SQLTransaction& trans);
+ void _SaveSpells(SQLTransaction& trans);
+ void _SaveEquipmentSets(SQLTransaction& trans);
+ void _SaveBGData(SQLTransaction& trans);
+ void _SaveGlyphs(SQLTransaction& trans);
+ void _SaveTalents(SQLTransaction& trans);
+ void _SaveStats(SQLTransaction& trans);
void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index 4f9fc0f5b9a..f94f61063ca 100644
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -181,10 +181,10 @@ void GameEventMgr::StopEvent(uint16 event_id, bool overwrite)
std::map<uint32 /*condition id*/, GameEventFinishCondition>::iterator itr;
for (itr = mGameEvent[event_id].conditions.begin(); itr != mGameEvent[event_id].conditions.end(); ++itr)
itr->second.done = 0;
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM game_event_save WHERE event_id = '%u'",event_id);
- CharacterDatabase.PExecute("DELETE FROM game_event_condition_save WHERE event_id = '%u'",event_id);
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM game_event_save WHERE event_id = '%u'",event_id);
+ trans->PAppend("DELETE FROM game_event_condition_save WHERE event_id = '%u'",event_id);
+ CharacterDatabase.CommitTransaction(trans);
}
}
}
@@ -1627,10 +1627,10 @@ void GameEventMgr::HandleQuestComplete(uint32 quest_id)
if (citr->second.done > citr->second.reqNum)
citr->second.done = citr->second.reqNum;
// save the change to db
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM game_event_condition_save WHERE event_id = '%u' AND condition_id = '%u'",event_id,condition);
- CharacterDatabase.PExecute("INSERT INTO game_event_condition_save (event_id, condition_id, done) VALUES (%u,%u,%f)",event_id,condition,citr->second.done);
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM game_event_condition_save WHERE event_id = '%u' AND condition_id = '%u'",event_id,condition);
+ trans->PAppend("INSERT INTO game_event_condition_save (event_id, condition_id, done) VALUES (%u,%u,%f)",event_id,condition,citr->second.done);
+ CharacterDatabase.CommitTransaction(trans);
// check if all conditions are met, if so, update the event state
if (CheckOneGameEventConditions(event_id))
{
@@ -1663,13 +1663,13 @@ bool GameEventMgr::CheckOneGameEventConditions(uint16 event_id)
void GameEventMgr::SaveWorldEventStateToDB(uint16 event_id)
{
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM game_event_save WHERE event_id = '%u'",event_id);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM game_event_save WHERE event_id = '%u'",event_id);
if (mGameEvent[event_id].nextstart)
- CharacterDatabase.PExecute("INSERT INTO game_event_save (event_id, state, next_start) VALUES ('%u','%u',FROM_UNIXTIME("UI64FMTD"))",event_id,mGameEvent[event_id].state,(uint64)(mGameEvent[event_id].nextstart));
+ trans->PAppend("INSERT INTO game_event_save (event_id, state, next_start) VALUES ('%u','%u',FROM_UNIXTIME("UI64FMTD"))",event_id,mGameEvent[event_id].state,(uint64)(mGameEvent[event_id].nextstart));
else
- CharacterDatabase.PExecute("INSERT INTO game_event_save (event_id, state, next_start) VALUES ('%u','%u','0000-00-00 00:00:00')",event_id,mGameEvent[event_id].state);
- CharacterDatabase.CommitTransaction();
+ trans->PAppend("INSERT INTO game_event_save (event_id, state, next_start) VALUES ('%u','%u','0000-00-00 00:00:00')",event_id,mGameEvent[event_id].state);
+ CharacterDatabase.CommitTransaction(trans);
}
void GameEventMgr::HandleWorldEventGossip(Player *plr, Creature *c)
diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp
index fdb13637263..c781fe86916 100644
--- a/src/server/game/Globals/ObjectAccessor.cpp
+++ b/src/server/game/Globals/ObjectAccessor.cpp
@@ -295,7 +295,9 @@ Corpse* ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool /*insign
// map->Remove(corpse, false);
// remove corpse from DB
- corpse->DeleteFromDB();
+ SQLTransaction trans = WorldDatabase.BeginTransaction();
+ corpse->DeleteFromDB(trans);
+ WorldDatabase.CommitTransaction(trans);
// we don't want bones to save some cpu.. :)
delete corpse;
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index e60fc55250b..247cbdeb6b1 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -9040,9 +9040,10 @@ void ObjectMgr::_AddOrUpdateGMTicket(GM_Ticket &ticket)
ss << ticket.closed << "', '";
ss << ticket.assignedToGM << "', '";
ss << comment << "');";
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.Execute(ss.str().c_str());
- CharacterDatabase.CommitTransaction();
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->Append(ss.str().c_str());
+ CharacterDatabase.CommitTransaction(trans);
}
void ObjectMgr::RemoveGMTicket(GM_Ticket *ticket, int64 source, bool permanently)
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 837f7d3ad77..7a8ffb061b5 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -116,20 +116,19 @@ bool Group::Create(const uint64 &guid, const char * name)
Player::ConvertInstancesToGroup(leader, this, guid);
+ if (!AddMember(guid, name))
+ return false;
+
// store group in database
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM groups WHERE guid ='%u'", lowguid);
- CharacterDatabase.PExecute("DELETE FROM group_member WHERE guid ='%u'", lowguid);
- CharacterDatabase.PExecute("INSERT INTO groups (guid,leaderGuid,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,groupType,difficulty,raiddifficulty) "
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM groups WHERE guid ='%u'", lowguid);
+ trans->PAppend("DELETE FROM group_member WHERE guid ='%u'", lowguid);
+ trans->PAppend("INSERT INTO groups (guid,leaderGuid,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,groupType,difficulty,raiddifficulty) "
"VALUES ('%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u','%u')",
lowguid, GUID_LOPART(m_leaderGuid), uint32(m_lootMethod),
GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7], uint8(m_groupType), uint32(m_dungeonDifficulty), m_raidDifficulty);
- if (!AddMember(guid, name))
- {
- CharacterDatabase.RollbackTransaction();
- return false;
- }
- CharacterDatabase.CommitTransaction();
+
+ CharacterDatabase.CommitTransaction(trans);
}
else if (!AddMember(guid, name))
return false;
@@ -497,10 +496,10 @@ void Group::Disband(bool hideDestroy)
if (!isBGGroup())
{
uint32 lowguid = GUID_LOPART(m_guid);
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM groups WHERE guid=%u", lowguid);
- CharacterDatabase.PExecute("DELETE FROM group_member WHERE guid=%u", lowguid);
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM groups WHERE guid=%u", lowguid);
+ trans->PAppend("DELETE FROM group_member WHERE guid=%u", lowguid);
+ CharacterDatabase.CommitTransaction(trans);
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL);
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL);
}
@@ -1334,14 +1333,14 @@ void Group::_setLeader(const uint64 &guid)
if (!isBGGroup())
{
// TODO: set a time limit to have this function run rarely cause it can be slow
- CharacterDatabase.BeginTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
// update the group's bound instances when changing leaders
// remove all permanent binds from the group
// in the DB also remove solo binds that will be replaced with permbinds
// from the new leader
- CharacterDatabase.PExecute(
+ trans->PAppend(
"DELETE FROM group_instance WHERE guid=%u AND (permanent = 1 OR "
"instance IN (SELECT instance FROM character_instance WHERE guid = '%u')"
")", GUID_LOPART(m_guid), GUID_LOPART(slot->guid)
@@ -1371,8 +1370,8 @@ void Group::_setLeader(const uint64 &guid)
Player::ConvertInstancesToGroup(player, this, slot->guid);
// update the group leader
- CharacterDatabase.PExecute("UPDATE groups SET leaderGuid='%u' WHERE guid='%u'", GUID_LOPART(slot->guid), GUID_LOPART(m_guid));
- CharacterDatabase.CommitTransaction();
+ trans->PAppend("UPDATE groups SET leaderGuid='%u' WHERE guid='%u'", GUID_LOPART(slot->guid), GUID_LOPART(m_guid));
+ CharacterDatabase.CommitTransaction(trans);
}
m_leaderGuid = slot->guid;
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 6e59773b57a..0617e66ef7b 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -88,13 +88,13 @@ bool Guild::Create(Player* leader, std::string gname)
CharacterDatabase.escape_string(dbGINFO);
CharacterDatabase.escape_string(dbMOTD);
- CharacterDatabase.BeginTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
// CharacterDatabase.PExecute("DELETE FROM guild WHERE guildid='%u'", Id); - MAX(guildid)+1 not exist
- CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guildid='%u'", m_Id);
- CharacterDatabase.PExecute("INSERT INTO guild (guildid,name,leaderguid,info,motd,createdate,EmblemStyle,EmblemColor,BorderStyle,BorderColor,BackgroundColor,BankMoney) "
+ trans->PAppend("DELETE FROM guild_member WHERE guildid='%u'", m_Id);
+ trans->PAppend("INSERT INTO guild (guildid,name,leaderguid,info,motd,createdate,EmblemStyle,EmblemColor,BorderStyle,BorderColor,BackgroundColor,BankMoney) "
"VALUES('%u','%s','%u', '%s', '%s', UNIX_TIMESTAMP(NOW()),'%u','%u','%u','%u','%u','" UI64FMTD "')",
m_Id, gname.c_str(), GUID_LOPART(m_LeaderGuid), dbGINFO.c_str(), dbMOTD.c_str(), m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor, m_BackgroundColor, m_GuildBankMoney);
- CharacterDatabase.CommitTransaction();
+ CharacterDatabase.CommitTransaction(trans);
CreateDefaultGuildRanks(lSession->GetSessionDbLocaleIndex());
@@ -335,16 +335,16 @@ bool Guild::LoadRanksFromDB(QueryResult_AutoPtr guildRanksResult)
if (broken_ranks)
{
sLog.outError("Guild %u has broken `guild_rank` data, repairing...", m_Id);
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid='%u'", m_Id);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM guild_rank WHERE guildid='%u'", m_Id);
for (size_t i = 0; i < m_Ranks.size(); ++i)
{
std::string name = m_Ranks[i].Name;
uint32 rights = m_Ranks[i].Rights;
CharacterDatabase.escape_string(name);
- CharacterDatabase.PExecute("INSERT INTO guild_rank (guildid,rid,rname,rights) VALUES ('%u', '%u', '%s', '%u')", m_Id, uint32(i), name.c_str(), rights);
+ trans->PAppend("INSERT INTO guild_rank (guildid,rid,rname,rights) VALUES ('%u', '%u', '%s', '%u')", m_Id, uint32(i), name.c_str(), rights);
}
- CharacterDatabase.CommitTransaction();
+ CharacterDatabase.CommitTransaction(trans);
}
return true;
@@ -710,19 +710,19 @@ void Guild::Disband()
DelMember(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER), true);
}
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM guild WHERE guildid = '%u'", m_Id);
- CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid = '%u'", m_Id);
- CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid = '%u'", m_Id);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM guild WHERE guildid = '%u'", m_Id);
+ trans->PAppend("DELETE FROM guild_rank WHERE guildid = '%u'", m_Id);
+ trans->PAppend("DELETE FROM guild_bank_tab WHERE guildid = '%u'", m_Id);
//Free bank tab used memory and delete items stored in them
DeleteGuildBankItems(true);
- CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid = '%u'", m_Id);
- CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid = '%u'", m_Id);
- CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid = '%u'", m_Id);
- CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid = '%u'", m_Id);
- CharacterDatabase.CommitTransaction();
+ trans->PAppend("DELETE FROM guild_bank_item WHERE guildid = '%u'", m_Id);
+ trans->PAppend("DELETE FROM guild_bank_right WHERE guildid = '%u'", m_Id);
+ trans->PAppend("DELETE FROM guild_bank_eventlog WHERE guildid = '%u'", m_Id);
+ trans->PAppend("DELETE FROM guild_eventlog WHERE guildid = '%u'", m_Id);
+ CharacterDatabase.CommitTransaction(trans);
sObjectMgr.RemoveGuild(m_Id);
}
@@ -1093,10 +1093,10 @@ void Guild::CreateNewBankTab()
uint32 tabId = GetPurchasedTabs(); // next free id
m_TabListMap.push_back(new GuildBankTab);
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid='%u' AND TabId='%u'", m_Id, tabId);
- CharacterDatabase.PExecute("INSERT INTO guild_bank_tab (guildid,TabId) VALUES ('%u','%u')", m_Id, tabId);
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM guild_bank_tab WHERE guildid='%u' AND TabId='%u'", m_Id, tabId);
+ trans->PAppend("INSERT INTO guild_bank_tab (guildid,TabId) VALUES ('%u','%u')", m_Id, tabId);
+ CharacterDatabase.CommitTransaction(trans);
}
void Guild::SetGuildBankTabInfo(uint8 TabId, std::string Name, std::string Icon)
@@ -1212,14 +1212,14 @@ void Guild::SendMoneyInfo(WorldSession *session, uint32 LowGuid)
sLog.outDebug("WORLD: Sent MSG_GUILD_BANK_MONEY_WITHDRAWN");
}
-bool Guild::MemberMoneyWithdraw(uint32 amount, uint32 LowGuid)
+bool Guild::MemberMoneyWithdraw(uint32 amount, uint32 LowGuid, SQLTransaction& trans)
{
uint32 MoneyWithDrawRight = GetMemberMoneyWithdrawRem(LowGuid);
if (MoneyWithDrawRight < amount || GetGuildBankMoney() < amount)
return false;
- SetBankMoney(GetGuildBankMoney()-amount);
+ SetBankMoney(GetGuildBankMoney()-amount, trans);
if (MoneyWithDrawRight < WITHDRAW_MONEY_UNLIMITED)
{
@@ -1227,25 +1227,25 @@ bool Guild::MemberMoneyWithdraw(uint32 amount, uint32 LowGuid)
if (itr == members.end())
return false;
itr->second.BankRemMoney -= amount;
- CharacterDatabase.PExecute("UPDATE guild_member SET BankRemMoney='%u' WHERE guildid='%u' AND guid='%u'",
+ trans->PAppend("UPDATE guild_member SET BankRemMoney='%u' WHERE guildid='%u' AND guid='%u'",
itr->second.BankRemMoney, m_Id, LowGuid);
}
return true;
}
-void Guild::SetBankMoney(int64 money)
+void Guild::SetBankMoney(int64 money, SQLTransaction& trans)
{
if (money < 0) // I don't know how this happens, it does!!
money = 0;
m_GuildBankMoney = money;
- CharacterDatabase.PExecute("UPDATE guild SET BankMoney='" UI64FMTD "' WHERE guildid='%u'", money, m_Id);
+ trans->PAppend("UPDATE guild SET BankMoney='" UI64FMTD "' WHERE guildid='%u'", money, m_Id);
}
// *************************************************
// Item per day and money per day related
-bool Guild::MemberItemWithdraw(uint8 TabId, uint32 LowGuid)
+bool Guild::MemberItemWithdraw(uint8 TabId, uint32 LowGuid, SQLTransaction& trans)
{
uint32 SlotsWithDrawRight = GetMemberSlotWithdrawRem(LowGuid, TabId);
@@ -1258,7 +1258,7 @@ bool Guild::MemberItemWithdraw(uint8 TabId, uint32 LowGuid)
if (itr == members.end())
return false;
--itr->second.BankRemSlotsTab[TabId];
- CharacterDatabase.PExecute("UPDATE guild_member SET BankRemSlotsTab%u='%u' WHERE guildid='%u' AND guid='%u'",
+ trans->PAppend("UPDATE guild_member SET BankRemSlotsTab%u='%u' WHERE guildid='%u' AND guid='%u'",
uint32(TabId), itr->second.BankRemSlotsTab[TabId], m_Id, LowGuid);
}
return true;
@@ -1552,7 +1552,7 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
sLog.outDebug("WORLD: Sent (MSG_GUILD_BANK_LOG_QUERY)");
}
-void Guild::LogBankEvent(uint8 EventType, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount, uint8 DestTabId)
+void Guild::LogBankEvent(SQLTransaction& trans, uint8 EventType, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount, uint8 DestTabId)
{
//create Event
GuildBankEventLogEntry NewEvent;
@@ -1587,9 +1587,9 @@ void Guild::LogBankEvent(uint8 EventType, uint8 TabId, uint32 PlayerGuidLow, uin
}
//save event to database
- CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u' AND TabId='%u'", m_Id, currentLogGuid, currentTabId);
+ trans->PAppend("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u' AND TabId='%u'", m_Id, currentLogGuid, currentTabId);
- CharacterDatabase.PExecute("INSERT INTO guild_bank_eventlog (guildid,LogGuid,TabId,EventType,PlayerGuid,ItemOrMoney,ItemStackCount,DestTabId,TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','%u','%u','" UI64FMTD "')",
+ trans->PAppend("INSERT INTO guild_bank_eventlog (guildid,LogGuid,TabId,EventType,PlayerGuid,ItemOrMoney,ItemStackCount,DestTabId,TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','%u','%u','" UI64FMTD "')",
m_Id, currentLogGuid, currentTabId, uint32(NewEvent.EventType), NewEvent.PlayerGuid, NewEvent.ItemOrMoney, uint32(NewEvent.ItemStackCount), uint32(NewEvent.DestTabId), NewEvent.TimeStamp);
}
@@ -1637,7 +1637,7 @@ void Guild::AppendDisplayGuildBankSlot(WorldPacket& data, GuildBankTab const *ta
}
}
-Item* Guild::StoreItem(uint8 tabId, GuildItemPosCountVec const& dest, Item* pItem)
+Item* Guild::StoreItem(uint8 tabId, GuildItemPosCountVec const& dest, Item* pItem, SQLTransaction& trans)
{
if (!pItem)
return NULL;
@@ -1653,18 +1653,18 @@ Item* Guild::StoreItem(uint8 tabId, GuildItemPosCountVec const& dest, Item* pIte
if (itr == dest.end())
{
- lastItem = _StoreItem(tabId, slot, pItem, count, false);
+ lastItem = _StoreItem(tabId, slot, pItem, count, false, trans);
break;
}
- lastItem = _StoreItem(tabId, slot, pItem, count, true);
+ lastItem = _StoreItem(tabId, slot, pItem, count, true, trans);
}
return lastItem;
}
// Return stored item (if stored to stack, it can diff. from pItem). And pItem ca be deleted in this case.
-Item* Guild::_StoreItem(uint8 tab, uint8 slot, Item *pItem, uint32 count, bool clone)
+Item* Guild::_StoreItem(uint8 tab, uint8 slot, Item *pItem, uint32 count, bool clone, SQLTransaction& trans)
{
if (!pItem)
return NULL;
@@ -1689,7 +1689,7 @@ Item* Guild::_StoreItem(uint8 tab, uint8 slot, Item *pItem, uint32 count, bool c
pItem->SetUInt64Value(ITEM_FIELD_OWNER, 0);
AddGBankItemToDB(GetId(), tab, slot, pItem->GetGUIDLow(), pItem->GetEntry());
pItem->FSetState(ITEM_NEW);
- pItem->SaveToDB(); // not in inventory and can be save standalone
+ pItem->SaveToDB(trans); // not in inventory and can be save standalone
return pItem;
}
@@ -1697,12 +1697,12 @@ Item* Guild::_StoreItem(uint8 tab, uint8 slot, Item *pItem, uint32 count, bool c
{
pItem2->SetCount(pItem2->GetCount() + count);
pItem2->FSetState(ITEM_CHANGED);
- pItem2->SaveToDB(); // not in inventory and can be save standalone
+ pItem2->SaveToDB(trans); // not in inventory and can be save standalone
if (!clone)
{
pItem->RemoveFromWorld();
- pItem->DeleteFromDB();
+ pItem->DeleteFromDB(trans);
delete pItem;
}
@@ -1710,10 +1710,10 @@ Item* Guild::_StoreItem(uint8 tab, uint8 slot, Item *pItem, uint32 count, bool c
}
}
-void Guild::RemoveItem(uint8 tab, uint8 slot)
+void Guild::RemoveItem(uint8 tab, uint8 slot, SQLTransaction& trans)
{
m_TabListMap[tab]->Slots[slot] = NULL;
- CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid='%u' AND TabId='%u' AND SlotId='%u'",
+ trans->PAppend("DELETE FROM guild_bank_item WHERE guildid='%u' AND TabId='%u' AND SlotId='%u'",
GetId(), uint32(tab), uint32(slot));
}
@@ -1954,15 +1954,15 @@ void Guild::SwapItems(Player * pl, uint8 BankTab, uint8 BankTabSlot, uint8 BankT
return;
}
- CharacterDatabase.BeginTransaction();
- LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), SplitedAmount, BankTabDst);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), SplitedAmount, BankTabDst);
pl->ItemRemovedQuestCheck(pItemSrc->GetEntry(), SplitedAmount);
pItemSrc->SetCount(pItemSrc->GetCount() - SplitedAmount);
pItemSrc->FSetState(ITEM_CHANGED);
- pItemSrc->SaveToDB(); // not in inventory and can be save standalone
- StoreItem(BankTabDst, dest, pNewItem);
- CharacterDatabase.CommitTransaction();
+ pItemSrc->SaveToDB(trans); // not in inventory and can be save standalone
+ StoreItem(BankTabDst, dest, pNewItem, trans);
+ CharacterDatabase.CommitTransaction(trans);
}
else // non split
{
@@ -1970,12 +1970,12 @@ void Guild::SwapItems(Player * pl, uint8 BankTab, uint8 BankTabSlot, uint8 BankT
uint8 msg = CanStoreItem(BankTabDst, BankTabSlotDst, gDest, pItemSrc->GetCount(), pItemSrc, false);
if (msg == EQUIP_ERR_OK) // merge to
{
- CharacterDatabase.BeginTransaction();
- LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst);
- RemoveItem(BankTab, BankTabSlot);
- StoreItem(BankTabDst, gDest, pItemSrc);
- CharacterDatabase.CommitTransaction();
+ RemoveItem(BankTab, BankTabSlot, trans);
+ StoreItem(BankTabDst, gDest, pItemSrc, trans);
+ CharacterDatabase.CommitTransaction(trans);
}
else // swap
{
@@ -2007,15 +2007,15 @@ void Guild::SwapItems(Player * pl, uint8 BankTab, uint8 BankTabSlot, uint8 BankT
return;
}
- CharacterDatabase.BeginTransaction();
- LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst);
- LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTabDst, pl->GetGUIDLow(), pItemDst->GetEntry(), pItemDst->GetCount(), BankTab);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst);
+ LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, BankTabDst, pl->GetGUIDLow(), pItemDst->GetEntry(), pItemDst->GetCount(), BankTab);
- RemoveItem(BankTab, BankTabSlot);
- RemoveItem(BankTabDst, BankTabSlotDst);
- StoreItem(BankTab, gSrc, pItemDst);
- StoreItem(BankTabDst, gDest, pItemSrc);
- CharacterDatabase.CommitTransaction();
+ RemoveItem(BankTab, BankTabSlot, trans);
+ RemoveItem(BankTabDst, BankTabSlotDst, trans);
+ StoreItem(BankTab, gSrc, pItemDst, trans);
+ StoreItem(BankTabDst, gDest, pItemSrc, trans);
+ CharacterDatabase.CommitTransaction(trans);
}
}
DisplayGuildBankContentUpdate(BankTab,BankTabSlot,BankTab == BankTabDst ? BankTabSlotDst : -1);
@@ -2062,17 +2062,17 @@ void Guild::MoveFromBankToChar(Player * pl, uint8 BankTab, uint8 BankTabSlot, ui
return;
}
- CharacterDatabase.BeginTransaction();
- LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), SplitedAmount);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), SplitedAmount);
pItemBank->SetCount(pItemBank->GetCount()-SplitedAmount);
pItemBank->FSetState(ITEM_CHANGED);
- pItemBank->SaveToDB(); // not in inventory and can be save standalone
+ pItemBank->SaveToDB(trans); // not in inventory and can be save standalone
pl->MoveItemToInventory(dest, pNewItem, true);
- pl->SaveInventoryAndGoldToDB();
+ pl->SaveInventoryAndGoldToDB(trans);
- MemberItemWithdraw(BankTab, pl->GetGUIDLow());
- CharacterDatabase.CommitTransaction();
+ MemberItemWithdraw(BankTab, pl->GetGUIDLow(), trans);
+ CharacterDatabase.CommitTransaction(trans);
}
else // Bank -> Char swap with slot (move)
{
@@ -2085,15 +2085,15 @@ void Guild::MoveFromBankToChar(Player * pl, uint8 BankTab, uint8 BankTabSlot, ui
if (remRight <= 0)
return;
- CharacterDatabase.BeginTransaction();
- LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
- RemoveItem(BankTab, BankTabSlot);
+ RemoveItem(BankTab, BankTabSlot, trans);
pl->MoveItemToInventory(dest, pItemBank, true);
- pl->SaveInventoryAndGoldToDB();
+ pl->SaveInventoryAndGoldToDB(trans);
- MemberItemWithdraw(BankTab, pl->GetGUIDLow());
- CharacterDatabase.CommitTransaction();
+ MemberItemWithdraw(BankTab, pl->GetGUIDLow(), trans);
+ CharacterDatabase.CommitTransaction(trans);
}
else // Bank <-> Char swap items
{
@@ -2146,25 +2146,25 @@ void Guild::MoveFromBankToChar(Player * pl, uint8 BankTab, uint8 BankTabSlot, ui
}
}
- CharacterDatabase.BeginTransaction();
- LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
if (pItemChar)
- LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
+ LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
- RemoveItem(BankTab, BankTabSlot);
+ RemoveItem(BankTab, BankTabSlot, trans);
if (pItemChar)
{
pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
- pItemChar->DeleteFromInventoryDB();
+ pItemChar->DeleteFromInventoryDB(trans);
}
if (pItemChar)
- StoreItem(BankTab, gDest, pItemChar);
+ StoreItem(BankTab, gDest, pItemChar, trans);
pl->MoveItemToInventory(iDest, pItemBank, true);
- pl->SaveInventoryAndGoldToDB();
+ pl->SaveInventoryAndGoldToDB(trans);
- MemberItemWithdraw(BankTab, pl->GetGUIDLow());
- CharacterDatabase.CommitTransaction();
+ MemberItemWithdraw(BankTab, pl->GetGUIDLow(), trans);
+ CharacterDatabase.CommitTransaction(trans);
}
}
DisplayGuildBankContentUpdate(BankTab,BankTabSlot);
@@ -2218,15 +2218,15 @@ void Guild::MoveFromCharToBank(Player * pl, uint8 PlayerBag, uint8 PlayerSlot, u
pItemChar->GetProto()->Name1, pItemChar->GetEntry(), SplitedAmount,m_Id);
}
- CharacterDatabase.BeginTransaction();
- LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), SplitedAmount);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), SplitedAmount);
pl->ItemRemovedQuestCheck(pItemChar->GetEntry(), SplitedAmount);
pItemChar->SetCount(pItemChar->GetCount()-SplitedAmount);
pItemChar->SetState(ITEM_CHANGED, pl);
- pl->SaveInventoryAndGoldToDB();
- StoreItem(BankTab, dest, pNewItem);
- CharacterDatabase.CommitTransaction();
+ pl->SaveInventoryAndGoldToDB(trans);
+ StoreItem(BankTab, dest, pNewItem, trans);
+ CharacterDatabase.CommitTransaction(trans);
DisplayGuildBankContentUpdate(BankTab, dest);
}
@@ -2245,15 +2245,15 @@ void Guild::MoveFromCharToBank(Player * pl, uint8 PlayerBag, uint8 PlayerSlot, u
m_Id);
}
- CharacterDatabase.BeginTransaction();
- LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
- pItemChar->DeleteFromInventoryDB();
+ pItemChar->DeleteFromInventoryDB(trans);
- StoreItem(BankTab, dest, pItemChar);
- pl->SaveInventoryAndGoldToDB();
- CharacterDatabase.CommitTransaction();
+ StoreItem(BankTab, dest, pItemChar, trans);
+ pl->SaveInventoryAndGoldToDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
DisplayGuildBankContentUpdate(BankTab, dest);
}
@@ -2295,23 +2295,23 @@ void Guild::MoveFromCharToBank(Player * pl, uint8 PlayerBag, uint8 PlayerSlot, u
m_Id);
}
- CharacterDatabase.BeginTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (pItemBank)
- LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
- LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
+ LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
+ LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
- pItemChar->DeleteFromInventoryDB();
+ pItemChar->DeleteFromInventoryDB(trans);
if (pItemBank)
- RemoveItem(BankTab, BankTabSlot);
+ RemoveItem(BankTab, BankTabSlot, trans);
- StoreItem(BankTab,gDest,pItemChar);
+ StoreItem(BankTab,gDest,pItemChar, trans);
if (pItemBank)
pl->MoveItemToInventory(iDest, pItemBank, true);
- pl->SaveInventoryAndGoldToDB();
+ pl->SaveInventoryAndGoldToDB(trans);
if (pItemBank)
- MemberItemWithdraw(BankTab, pl->GetGUIDLow());
- CharacterDatabase.CommitTransaction();
+ MemberItemWithdraw(BankTab, pl->GetGUIDLow(), trans);
+ CharacterDatabase.CommitTransaction(trans);
DisplayGuildBankContentUpdate(BankTab, gDest);
}
@@ -2350,7 +2350,7 @@ void Guild::BroadcastEvent(GuildEvents event, uint64 guid, uint8 strCount, std::
sLog.outDebug("WORLD: Sent SMSG_GUILD_EVENT");
}
-void Guild::DeleteGuildBankItems( bool alsoInDB /*= false*/ )
+void Guild::DeleteGuildBankItems( bool alsoInDB /*= false*/, SQLTransaction& trans)
{
for (size_t i = 0; i < m_TabListMap.size(); ++i)
{
@@ -2361,7 +2361,7 @@ void Guild::DeleteGuildBankItems( bool alsoInDB /*= false*/ )
pItem->RemoveFromWorld();
if (alsoInDB)
- pItem->DeleteFromDB();
+ pItem->DeleteFromDB(trans);
delete pItem;
}
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index 02840da82d3..fcf7429fbd1 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -294,7 +294,7 @@ class Guild
void CreateDefaultGuildRanks(int locale_idx);
void Disband();
- void DeleteGuildBankItems(bool alsoInDB = false);
+ void DeleteGuildBankItems(bool alsoInDB = false, SQLTransaction& trans = SQLTransaction(NULL));
typedef std::map<uint32, MemberSlot> MemberList;
typedef std::vector<RankInfo> RankList;
@@ -412,11 +412,11 @@ class Guild
void LoadGuildBankFromDB();
// Money deposit/withdraw
void SendMoneyInfo(WorldSession *session, uint32 LowGuid);
- bool MemberMoneyWithdraw(uint32 amount, uint32 LowGuid);
+ bool MemberMoneyWithdraw(uint32 amount, uint32 LowGuid, SQLTransaction& trans);
uint64 GetGuildBankMoney() { return m_GuildBankMoney; }
- void SetBankMoney(int64 money);
+ void SetBankMoney(int64 money, SQLTransaction& trans);
// per days
- bool MemberItemWithdraw(uint8 TabId, uint32 LowGuid);
+ bool MemberItemWithdraw(uint8 TabId, uint32 LowGuid, SQLTransaction& trans);
uint32 GetMemberSlotWithdrawRem(uint32 LowGuid, uint8 TabId);
uint32 GetMemberMoneyWithdrawRem(uint32 LowGuid);
void SetBankMoneyPerDay(uint32 rankId, uint32 money);
@@ -428,7 +428,7 @@ class Guild
// Guild Bank Event Logs
void LoadGuildBankEventLogFromDB();
void DisplayGuildBankLogs(WorldSession *session, uint8 TabId);
- void LogBankEvent(uint8 EventType, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount=0, uint8 DestTabId=0);
+ void LogBankEvent(SQLTransaction& trans, uint8 EventType, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount=0, uint8 DestTabId=0);
bool AddGBankItemToDB(uint32 GuildId, uint32 BankTab , uint32 BankTabSlot , uint32 GUIDLow, uint32 Entry);
protected:
@@ -473,8 +473,8 @@ class Guild
// used only from high level Swap/Move functions
Item* GetItem(uint8 TabId, uint8 SlotId);
uint8 CanStoreItem(uint8 tab, uint8 slot, GuildItemPosCountVec& dest, uint32 count, Item *pItem, bool swap = false) const;
- Item* StoreItem(uint8 tab, GuildItemPosCountVec const& pos, Item *pItem);
- void RemoveItem(uint8 tab, uint8 slot);
+ Item* StoreItem(uint8 tab, GuildItemPosCountVec const& pos, Item *pItem, SQLTransaction& trans);
+ void RemoveItem(uint8 tab, uint8 slot, SQLTransaction& trans);
void DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2 = -1);
void DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec const& slots);
@@ -482,6 +482,6 @@ class Guild
void AppendDisplayGuildBankSlot(WorldPacket& data, GuildBankTab const *tab, int32 slot);
uint8 _CanStoreItem_InSpecificSlot(uint8 tab, uint8 slot, GuildItemPosCountVec& dest, uint32& count, bool swap, Item *pSrcItem) const;
uint8 _CanStoreItem_InTab(uint8 tab, GuildItemPosCountVec& dest, uint32& count, bool merge, Item *pSrcItem, uint8 skip_slot) const;
- Item* _StoreItem(uint8 tab, uint8 slot, Item *pItem, uint32 count, bool clone);
+ Item* _StoreItem(uint8 tab, uint8 slot, Item *pItem, uint32 count, bool clone, SQLTransaction& trans);
};
#endif
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index 9e3e6eaa07f..54a713bf47e 100644
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -124,11 +124,11 @@ InstanceSave *InstanceSaveManager::GetInstanceSave(uint32 InstanceId)
void InstanceSaveManager::DeleteInstanceFromDB(uint32 instanceid)
{
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'", instanceid);
- CharacterDatabase.PExecute("DELETE FROM character_instance WHERE instance = '%u'", instanceid);
- CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", instanceid);
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM instance WHERE id = '%u'", instanceid);
+ trans->PAppend("DELETE FROM character_instance WHERE instance = '%u'", instanceid);
+ trans->PAppend("DELETE FROM group_instance WHERE instance = '%u'", instanceid);
+ CharacterDatabase.CommitTransaction(trans);
// respawn times should be deleted only when the map gets unloaded
}
@@ -648,11 +648,11 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b
}
// delete them from the DB, even if not loaded
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM character_instance USING character_instance LEFT JOIN instance ON character_instance.instance = id WHERE map = '%u' and difficulty='%u'", mapid, difficulty);
- CharacterDatabase.PExecute("DELETE FROM group_instance USING group_instance LEFT JOIN instance ON group_instance.instance = id WHERE map = '%u' and difficulty='%u'", mapid, difficulty);
- CharacterDatabase.PExecute("DELETE FROM instance WHERE map = '%u' and difficulty='%u'", mapid, difficulty);
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM character_instance USING character_instance LEFT JOIN instance ON character_instance.instance = id WHERE map = '%u' and difficulty='%u'", mapid, difficulty);
+ trans->PAppend("DELETE FROM group_instance USING group_instance LEFT JOIN instance ON group_instance.instance = id WHERE map = '%u' and difficulty='%u'", mapid, difficulty);
+ trans->PAppend("DELETE FROM instance WHERE map = '%u' and difficulty='%u'", mapid, difficulty);
+ CharacterDatabase.CommitTransaction(trans);
// calculate the next reset time
uint32 diff = sWorld.getConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR;
diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp
index beee96c0d91..00d82ca6860 100644
--- a/src/server/game/Mails/Mail.cpp
+++ b/src/server/game/Mails/Mail.cpp
@@ -245,6 +245,8 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data)
MailDraft draft(subject, body);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
if (items_count > 0 || money > 0)
{
if (items_count > 0)
@@ -260,12 +262,11 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data)
item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable
pl->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true);
- CharacterDatabase.BeginTransaction();
- item->DeleteFromInventoryDB(); // deletes item from character's inventory
- item->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
+
+ item->DeleteFromInventoryDB(trans); // deletes item from character's inventory
+ item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
// owner in data will set at mail receive and item extracting
- CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", GUID_LOPART(rc), item->GetGUIDLow());
- CharacterDatabase.CommitTransaction();
+ trans->PAppend("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", GUID_LOPART(rc), item->GetGUIDLow());
draft.AddItem(item);
}
@@ -287,11 +288,10 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data)
draft
.AddMoney(money)
.AddCOD(COD)
- .SendMailTo(MailReceiver(receive, GUID_LOPART(rc)), pl, body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay);
+ .SendMailTo(trans, MailReceiver(receive, GUID_LOPART(rc)), pl, body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay);
- CharacterDatabase.BeginTransaction();
- pl->SaveInventoryAndGoldToDB();
- CharacterDatabase.CommitTransaction();
+ pl->SaveInventoryAndGoldToDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
}
//called when mail is read
@@ -366,10 +366,10 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data)
}
//we can return mail now
//so firstly delete the old one
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", mailId); // needed?
- CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", mailId);
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM mail WHERE id = '%u'", mailId); // needed?
+ trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", mailId);
+ CharacterDatabase.CommitTransaction(trans);
pl->RemoveMail(mailId);
// only return mail if the player exists (and delete if not existing)
@@ -436,6 +436,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data)
uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, it, false);
if (msg == EQUIP_ERR_OK)
{
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
m->RemoveItem(itemId);
m->removedItems.push_back(itemId);
@@ -473,7 +474,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data)
{
MailDraft(m->subject, "")
.AddMoney(m->COD)
- .SendMailTo(MailReceiver(receive, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT);
+ .SendMailTo(trans, MailReceiver(receive, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT);
}
pl->ModifyMoney(-int32(m->COD));
@@ -486,10 +487,9 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data)
uint32 count = it->GetCount(); // save counts before store and possible merge with deleting
pl->MoveItemToInventory(dest,it,true);
- CharacterDatabase.BeginTransaction();
- pl->SaveInventoryAndGoldToDB();
- pl->_SaveMail();
- CharacterDatabase.CommitTransaction();
+ pl->SaveInventoryAndGoldToDB(trans);
+ pl->_SaveMail(trans);
+ CharacterDatabase.CommitTransaction(trans);
pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemId, count);
}
@@ -524,10 +524,10 @@ void WorldSession::HandleMailTakeMoney(WorldPacket & recv_data)
pl->m_mailsUpdated = true;
// save money and mail to prevent cheating
- CharacterDatabase.BeginTransaction();
- pl->SaveGoldToDB();
- pl->_SaveMail();
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ pl->SaveGoldToDB(trans);
+ pl->_SaveMail(trans);
+ CharacterDatabase.CommitTransaction(trans);
}
//called when player lists his received mails
@@ -826,7 +826,7 @@ MailDraft& MailDraft::AddItem(Item* item)
m_items[item->GetGUIDLow()] = item; return *this;
}
-void MailDraft::prepareItems(Player* receiver)
+void MailDraft::prepareItems(Player* receiver, SQLTransaction& trans)
{
if (!m_mailTemplateId || !m_mailTemplateItemsNeed)
return;
@@ -845,21 +845,21 @@ void MailDraft::prepareItems(Player* receiver)
{
if (Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,receiver))
{
- item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
+ item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted
AddItem(item);
}
}
}
}
-void MailDraft::deleteIncludedItems(bool inDB /*= false*/)
+void MailDraft::deleteIncludedItems(bool inDB /*= false*/, SQLTransaction& trans)
{
for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
{
Item* item = mailItemIter->second;
if (inDB)
- CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", item->GetGUIDLow());
+ trans->PAppend("DELETE FROM item_instance WHERE guid='%u'", item->GetGUIDLow());
delete item;
}
@@ -875,9 +875,11 @@ void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32
if (!receiver)
rc_account = sObjectMgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
if (!receiver && !rc_account) // sender not exist
{
- deleteIncludedItems(true);
+ deleteIncludedItems(true, trans);
return;
}
@@ -890,30 +892,29 @@ void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32
needItemDelay = sender_acc != rc_account;
// set owner to new receiver (to prevent delete item with sender char deleting)
- CharacterDatabase.BeginTransaction();
for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
{
Item* item = mailItemIter->second;
- item->SaveToDB(); // item not in inventory and can be save standalone
+ item->SaveToDB(trans); // item not in inventory and can be save standalone
// owner in data will set at mail receive and item extracting
- CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", receiver_guid, item->GetGUIDLow());
+ trans->PAppend("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", receiver_guid, item->GetGUIDLow());
}
- CharacterDatabase.CommitTransaction();
}
// If theres is an item, there is a one hour delivery delay.
uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
// will delete item or place to receiver mail list
- SendMailTo(MailReceiver(receiver,receiver_guid), MailSender(MAIL_NORMAL, sender_guid), MAIL_CHECK_MASK_RETURNED, deliver_delay);
+ SendMailTo(trans,MailReceiver(receiver,receiver_guid), MailSender(MAIL_NORMAL, sender_guid), MAIL_CHECK_MASK_RETURNED, deliver_delay);
+ CharacterDatabase.CommitTransaction(trans);
}
-void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked, uint32 deliver_delay)
+void MailDraft::SendMailTo(SQLTransaction& trans, MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked, uint32 deliver_delay)
{
Player* pReceiver = receiver.GetPlayer(); // can be NULL
if (pReceiver)
- prepareItems(pReceiver); // generate mail template items
+ prepareItems(pReceiver, trans); // generate mail template items
uint32 mailId = sObjectMgr.GenerateMailID();
@@ -937,20 +938,19 @@ void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sende
// Add to DB
std::string safe_subject = GetSubject();
std::string safe_body = GetBody();
- CharacterDatabase.BeginTransaction();
+
CharacterDatabase.escape_string(safe_subject);
CharacterDatabase.escape_string(safe_body);
- CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,body,has_items,expire_time,deliver_time,money,cod,checked) "
+ trans->PAppend("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,body,has_items,expire_time,deliver_time,money,cod,checked) "
"VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%s', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%d')",
mailId, sender.GetMailMessageType(), sender.GetStationery(), GetMailTemplateId(), sender.GetSenderId(), receiver.GetPlayerGUIDLow(), safe_subject.c_str(), safe_body.c_str(),(m_items.empty() ? 0 : 1), (uint64)expire_time, (uint64)deliver_time, m_money, m_COD, checked);
for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
{
Item* item = mailItemIter->second;
- CharacterDatabase.PExecute("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')", mailId, item->GetGUIDLow(), item->GetEntry(), receiver.GetPlayerGUIDLow());
+ trans->PAppend("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')", mailId, item->GetGUIDLow(), item->GetEntry(), receiver.GetPlayerGUIDLow());
}
- CharacterDatabase.CommitTransaction();
// For online receiver update in game mail status and data
if (pReceiver)
diff --git a/src/server/game/Mails/Mail.h b/src/server/game/Mails/Mail.h
index b0103897864..83a346d31c1 100644
--- a/src/server/game/Mails/Mail.h
+++ b/src/server/game/Mails/Mail.h
@@ -128,16 +128,19 @@ class MailDraft
uint32 GetMoney() const { return m_money; }
uint32 GetCOD() const { return m_COD; }
std::string const& GetBody() const { return m_body; }
+
public: // modifiers
MailDraft& AddItem(Item* item);
MailDraft& AddMoney(uint32 money) { m_money = money; return *this; }
MailDraft& AddCOD(uint32 COD) { m_COD = COD; return *this; }
+
public: // finishers
void SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid);
- void SendMailTo(MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked = MAIL_CHECK_MASK_NONE, uint32 deliver_delay = 0);
+ void SendMailTo(SQLTransaction& trans, MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked = MAIL_CHECK_MASK_NONE, uint32 deliver_delay = 0);
+
private:
- void deleteIncludedItems(bool inDB = false);
- void prepareItems(Player* receiver); // called from SendMailTo for generate mailTemplateBase items
+ void deleteIncludedItems(bool inDB = false, SQLTransaction& trans = SQLTransaction(NULL));
+ void prepareItems(Player* receiver, SQLTransaction& trans); // called from SendMailTo for generate mailTemplateBase items
uint16 m_mailTemplateId;
bool m_mailTemplateItemsNeed;
diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp
index 224092097ce..adf6c9a7433 100644
--- a/src/server/game/Reputation/ReputationMgr.cpp
+++ b/src/server/game/Reputation/ReputationMgr.cpp
@@ -508,14 +508,14 @@ void ReputationMgr::LoadFromDB(QueryResult_AutoPtr result)
}
}
-void ReputationMgr::SaveToDB()
+void ReputationMgr::SaveToDB(SQLTransaction& trans)
{
for (FactionStateList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
{
if (itr->second.Changed)
{
- CharacterDatabase.PExecute("DELETE FROM character_reputation WHERE guid = '%u' AND faction='%u'", m_player->GetGUIDLow(), itr->second.ID);
- CharacterDatabase.PExecute("INSERT INTO character_reputation (guid,faction,standing,flags) VALUES ('%u', '%u', '%i', '%u')", m_player->GetGUIDLow(), itr->second.ID, itr->second.Standing, itr->second.Flags);
+ trans->PAppend("DELETE FROM character_reputation WHERE guid = '%u' AND faction='%u'", m_player->GetGUIDLow(), itr->second.ID);
+ trans->PAppend("INSERT INTO character_reputation (guid,faction,standing,flags) VALUES ('%u', '%u', '%i', '%u')", m_player->GetGUIDLow(), itr->second.ID, itr->second.Standing, itr->second.Flags);
itr->second.Changed = false;
}
}
diff --git a/src/server/game/Reputation/ReputationMgr.h b/src/server/game/Reputation/ReputationMgr.h
index 4c0fd778a4d..b3a01ffc86d 100644
--- a/src/server/game/Reputation/ReputationMgr.h
+++ b/src/server/game/Reputation/ReputationMgr.h
@@ -68,7 +68,7 @@ class ReputationMgr
m_visibleFactionCount(0), m_honoredFactionCount(0), m_reveredFactionCount(0), m_exaltedFactionCount(0) {}
~ReputationMgr() {}
- void SaveToDB();
+ void SaveToDB(SQLTransaction& trans);
void LoadFromDB(QueryResult_AutoPtr result);
public: // statics
static const int32 PointsInRank[MAX_REPUTATION_RANK];
diff --git a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp b/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp
index 3bd6cad64c6..3f399db9ac1 100644
--- a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp
@@ -113,53 +113,6 @@ void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction)
SendPacket(&data);
}
-//this function sends mail to old bidder
-void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPrice)
-{
- uint64 oldBidder_guid = MAKE_NEW_GUID(auction->bidder,0, HIGHGUID_PLAYER);
- Player *oldBidder = sObjectMgr.GetPlayer(oldBidder_guid);
-
- uint32 oldBidder_accId = 0;
- if (!oldBidder)
- oldBidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(oldBidder_guid);
-
- // old bidder exist
- if (oldBidder || oldBidder_accId)
- {
- std::ostringstream msgAuctionOutbiddedSubject;
- msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED << ":0:0";
-
- if (oldBidder && _player)
- oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template);
-
- MailDraft(msgAuctionOutbiddedSubject.str(), "") // TODO: fix body
- .AddMoney(auction->bid)
- .SendMailTo(MailReceiver(oldBidder, auction->bidder), auction, MAIL_CHECK_MASK_COPIED);
- }
-}
-
-//this function sends mail, when auction is cancelled to old bidder
-void WorldSession::SendAuctionCancelledToBidderMail(AuctionEntry* auction)
-{
- uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
- Player *bidder = sObjectMgr.GetPlayer(bidder_guid);
-
- uint32 bidder_accId = 0;
- if (!bidder)
- bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid);
-
- // bidder exist
- if (bidder || bidder_accId)
- {
- std::ostringstream msgAuctionCancelledSubject;
- msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER << ":0:0";
-
- MailDraft(msgAuctionCancelledSubject.str(), "") // TODO: fix body
- .AddMoney(auction->bid)
- .SendMailTo(MailReceiver(bidder, auction->bidder), auction, MAIL_CHECK_MASK_COPIED);
- }
-}
-
//this void creates new auction and adds auction to some auctionhouse
void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
{
@@ -284,12 +237,12 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
pl->MoveItemFromInventory(it->GetBagSlot(), it->GetSlot(), true);
- CharacterDatabase.BeginTransaction();
- it->DeleteFromInventoryDB();
- it->SaveToDB(); // recursive and not have transaction guard into self, not in inventiory and can be save standalone
- AH->SaveToDB();
- pl->SaveInventoryAndGoldToDB();
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ it->DeleteFromInventoryDB(trans);
+ it->SaveToDB(trans); // recursive and not have transaction guard into self, not in inventiory and can be save standalone
+ AH->SaveToDB(trans);
+ pl->SaveInventoryAndGoldToDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK);
@@ -359,6 +312,8 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
return;
}
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
if (price < auction->buyout || auction->buyout == 0)
{
if (auction->bidder > 0)
@@ -368,7 +323,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
else
{
// mail to last bidder and return money
- SendAuctionOutbiddedMail(auction, price);
+ sAuctionMgr.SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans);
pl->ModifyMoney(-int32(price));
}
}
@@ -379,9 +334,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
auction->bid = price;
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price);
- // after this update we should save player's money ...
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id);
+ trans->PAppend("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id);
SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0);
}
@@ -394,26 +347,27 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
{
pl->ModifyMoney(-int32(auction->buyout));
if (auction->bidder) //buyout for bidded auction ..
- SendAuctionOutbiddedMail(auction, auction->buyout);
+ sAuctionMgr.SendAuctionOutbiddedMail(auction, auction->buyout, GetPlayer(), trans);
}
auction->bidder = pl->GetGUIDLow();
auction->bid = auction->buyout;
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout);
- sAuctionMgr.SendAuctionSalePendingMail(auction);
- sAuctionMgr.SendAuctionSuccessfulMail(auction);
- sAuctionMgr.SendAuctionWonMail(auction);
+ //- Mails must be under transaction control too to prevent data loss
+ sAuctionMgr.SendAuctionSalePendingMail(auction, trans);
+ sAuctionMgr.SendAuctionSuccessfulMail(auction, trans);
+ sAuctionMgr.SendAuctionWonMail(auction, trans);
SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK);
- CharacterDatabase.BeginTransaction();
- auction->DeleteFromDB();
+ auction->DeleteFromDB(trans);
+
uint32 item_template = auction->item_template;
sAuctionMgr.RemoveAItem(auction->item_guidlow);
auctionHouse->RemoveAuction(auction, item_template);
}
- pl->SaveInventoryAndGoldToDB();
- CharacterDatabase.CommitTransaction();
+ pl->SaveInventoryAndGoldToDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
}
//this void is called when auction_owner cancels his auction
@@ -441,6 +395,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
AuctionEntry *auction = auctionHouse->GetAuction(auctionId);
Player *pl = GetPlayer();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (auction && auction->owner == pl->GetGUIDLow())
{
Item *pItem = sAuctionMgr.GetAItem(auction->item_guidlow);
@@ -452,7 +407,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
if (pl->GetMoney() < auctionCut) //player doesn't have enough money, maybe message needed
return;
//some auctionBidderNotification would be needed, but don't know that parts..
- SendAuctionCancelledToBidderMail(auction);
+ sAuctionMgr.SendAuctionCancelledToBidderMail(auction, trans);
pl->ModifyMoney(-int32(auctionCut));
}
// Return the item by mail
@@ -462,7 +417,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
// item will deleted or added to received mail list
MailDraft(msgAuctionCanceledOwner.str(), "") // TODO: fix body
.AddItem(pItem)
- .SendMailTo(pl, auction, MAIL_CHECK_MASK_COPIED);
+ .SendMailTo(trans, pl, auction, MAIL_CHECK_MASK_COPIED);
}
else
{
@@ -483,13 +438,14 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
SendAuctionCommandResult(auction->Id, AUCTION_CANCEL, AUCTION_OK);
// Now remove the auction
- CharacterDatabase.BeginTransaction();
- pl->SaveInventoryAndGoldToDB();
- auction->DeleteFromDB();
+
+ pl->SaveInventoryAndGoldToDB(trans);
+ auction->DeleteFromDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
+
uint32 item_template = auction->item_template;
sAuctionMgr.RemoveAItem(auction->item_guidlow);
auctionHouse->RemoveAuction(auction, item_template);
- CharacterDatabase.CommitTransaction();
}
//called when player lists his bids
diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
index 01c1392f35b..e6aec50179d 100644
--- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
@@ -1041,11 +1041,11 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data)
for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
CharacterDatabase.escape_string(declinedname.name[i]);
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid = '%u'", GUID_LOPART(guid));
- CharacterDatabase.PExecute("INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u','%s','%s','%s','%s','%s')",
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM character_declinedname WHERE guid = '%u'", GUID_LOPART(guid));
+ trans->PAppend("INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u','%s','%s','%s','%s','%s')",
GUID_LOPART(guid), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str());
- CharacterDatabase.CommitTransaction();
+ CharacterDatabase.CommitTransaction(trans);
WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
data << uint32(0); // OK
diff --git a/src/server/game/Server/Protocol/Handlers/GuildHandler.cpp b/src/server/game/Server/Protocol/Handlers/GuildHandler.cpp
index d20284ae8f4..15bead6860d 100644
--- a/src/server/game/Server/Protocol/Handlers/GuildHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/GuildHandler.cpp
@@ -887,13 +887,11 @@ void WorldSession::HandleGuildBankDepositMoney(WorldPacket & recv_data)
if (!pGuild->GetPurchasedTabs())
return;
- CharacterDatabase.BeginTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
- pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money);
+ pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money, trans);
GetPlayer()->ModifyMoney(-int(money));
- GetPlayer()->SaveGoldToDB();
-
- CharacterDatabase.CommitTransaction();
+ GetPlayer()->SaveGoldToDB(trans);
// logging money
if (_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
@@ -903,7 +901,9 @@ void WorldSession::HandleGuildBankDepositMoney(WorldPacket & recv_data)
}
// log
- pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
+ pGuild->LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
+
+ CharacterDatabase.CommitTransaction(trans);
pGuild->DisplayGuildBankTabsInfo(this);
pGuild->DisplayGuildBankContent(this, 0);
@@ -941,21 +941,18 @@ void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket & recv_data)
if (!pGuild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_WITHDRAW_GOLD))
return;
- CharacterDatabase.BeginTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
- if (!pGuild->MemberMoneyWithdraw(money, GetPlayer()->GetGUIDLow()))
- {
- CharacterDatabase.RollbackTransaction();
+ if (!pGuild->MemberMoneyWithdraw(money, GetPlayer()->GetGUIDLow(), trans))
return;
- }
GetPlayer()->ModifyMoney(money);
- GetPlayer()->SaveGoldToDB();
-
- CharacterDatabase.CommitTransaction();
+ GetPlayer()->SaveGoldToDB(trans);
// Log
- pGuild->LogBankEvent(GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
+ pGuild->LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
+
+ CharacterDatabase.CommitTransaction(trans);
pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
pGuild->DisplayGuildBankTabsInfo(this);
diff --git a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp b/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp
index 86c81172a61..cc973b25fbd 100644
--- a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp
@@ -1120,8 +1120,8 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data)
return;
}
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("INSERT INTO character_gifts VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(item->GetOwnerGUID()), item->GetGUIDLow(), item->GetEntry(), item->GetUInt32Value(ITEM_FIELD_FLAGS));
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("INSERT INTO character_gifts VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(item->GetOwnerGUID()), item->GetGUIDLow(), item->GetEntry(), item->GetUInt32Value(ITEM_FIELD_FLAGS));
item->SetEntry(gift->GetEntry());
switch (item->GetEntry())
@@ -1141,9 +1141,9 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data)
{
// after save it will be impossible to remove the item from the queue
item->RemoveFromUpdateQueueOf(_player);
- item->SaveToDB(); // item gave inventory record unchanged and can be save standalone
+ item->SaveToDB(trans); // item gave inventory record unchanged and can be save standalone
}
- CharacterDatabase.CommitTransaction();
+ CharacterDatabase.CommitTransaction(trans);
uint32 count = 1;
_player->DestroyItemCount(gift, count, true);
diff --git a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp b/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
index 6e36c963277..37f2f4b4b62 100644
--- a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
@@ -863,7 +863,12 @@ void WorldSession::HandleRepairItemOpcode(WorldPacket & recv_data)
Guild *pGuild = sObjectMgr.GetGuildById(GuildId);
if (!pGuild)
return;
- pGuild->LogBankEvent(GUILD_BANK_LOG_REPAIR_MONEY, 0, _player->GetGUIDLow(), TotalCost);
+
+ //- TODO: Fix poor function call design
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ pGuild->LogBankEvent(trans, GUILD_BANK_LOG_REPAIR_MONEY, 0, _player->GetGUIDLow(), TotalCost);
+ CharacterDatabase.CommitTransaction(trans);
+
pGuild->SendMoneyInfo(this, _player->GetGUIDLow());
}
}
diff --git a/src/server/game/Server/Protocol/Handlers/PetHandler.cpp b/src/server/game/Server/Protocol/Handlers/PetHandler.cpp
index 71454ce428f..8b0c496a89d 100644
--- a/src/server/game/Server/Protocol/Handlers/PetHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/PetHandler.cpp
@@ -601,19 +601,19 @@ void WorldSession::HandlePetRename(WorldPacket & recv_data)
}
}
- CharacterDatabase.BeginTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (isdeclined)
{
for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
CharacterDatabase.escape_string(declinedname.name[i]);
- CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
- CharacterDatabase.PExecute("INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u','%u','%s','%s','%s','%s','%s')",
+ trans->PAppend("DELETE FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
+ trans->PAppend("INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u','%u','%s','%s','%s','%s','%s')",
pet->GetCharmInfo()->GetPetNumber(), _player->GetGUIDLow(), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str());
}
CharacterDatabase.escape_string(name);
- CharacterDatabase.PExecute("UPDATE character_pet SET name = '%s', renamed = '1' WHERE owner = '%u' AND id = '%u'", name.c_str(), _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
- CharacterDatabase.CommitTransaction();
+ trans->PAppend("UPDATE character_pet SET name = '%s', renamed = '1' WHERE owner = '%u' AND id = '%u'", name.c_str(), _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
+ CharacterDatabase.CommitTransaction(trans);
pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
}
diff --git a/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp b/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp
index 5248fb93289..6e9bf7e742b 100644
--- a/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp
@@ -225,12 +225,12 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
sLog.outDebug("Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str());
CharacterDatabase.escape_string(name);
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str());
- CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str());
- CharacterDatabase.PExecute("INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES ('%u', '%u', '%s', '%u')",
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM petition WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str());
+ trans->PAppend("DELETE FROM petition_sign WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str());
+ trans->PAppend("INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES ('%u', '%u', '%s', '%u')",
_player->GetGUIDLow(), charter->GetGUIDLow(), name.c_str(), type);
- CharacterDatabase.CommitTransaction();
+ CharacterDatabase.CommitTransaction(trans);
}
void WorldSession::HandlePetitionShowSignOpcode(WorldPacket & recv_data)
@@ -845,10 +845,10 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data)
}
}
- CharacterDatabase.BeginTransaction();
- CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
- CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ trans->PAppend("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ CharacterDatabase.CommitTransaction(trans);
// created
sLog.outDebug("TURN IN PETITION GUID %u", GUID_LOPART(petitionguid));
diff --git a/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp b/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp
index 33bc48ace50..9a31c3b415c 100644
--- a/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp
@@ -480,10 +480,10 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
trader->m_trade = NULL;
// desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards)
- CharacterDatabase.BeginTransaction();
- _player->SaveInventoryAndGoldToDB();
- trader->SaveInventoryAndGoldToDB();
- CharacterDatabase.CommitTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ _player->SaveInventoryAndGoldToDB(trans);
+ trader->SaveInventoryAndGoldToDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE);
SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE);
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index a28b76e3190..fb702947855 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -625,11 +625,11 @@ void WorldSession::SetAccountData(AccountDataType type, time_t time_, std::strin
{
uint32 acc = GetAccountId();
- CharacterDatabase.BeginTransaction ();
- CharacterDatabase.PExecute("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type);
CharacterDatabase.escape_string(data);
- CharacterDatabase.PExecute("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str());
- CharacterDatabase.CommitTransaction ();
+ trans->PAppend("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str());
+ CharacterDatabase.CommitTransaction(trans);
}
else
{
@@ -637,11 +637,11 @@ void WorldSession::SetAccountData(AccountDataType type, time_t time_, std::strin
if (!m_GUIDLow)
return;
- CharacterDatabase.BeginTransaction ();
- CharacterDatabase.PExecute("DELETE FROM character_account_data WHERE guid='%u' AND type='%u'", m_GUIDLow, type);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ trans->PAppend("DELETE FROM character_account_data WHERE guid='%u' AND type='%u'", m_GUIDLow, type);
CharacterDatabase.escape_string(data);
- CharacterDatabase.PExecute("INSERT INTO character_account_data VALUES ('%u','%u','%u','%s')", m_GUIDLow, type, (uint32)time_, data.c_str());
- CharacterDatabase.CommitTransaction ();
+ trans->PAppend("INSERT INTO character_account_data VALUES ('%u','%u','%u','%s')", m_GUIDLow, type, (uint32)time_, data.c_str());
+ CharacterDatabase.CommitTransaction(trans);
}
m_accountData[type].Time = time_;
@@ -689,7 +689,7 @@ void WorldSession::SendTutorialsData()
SendPacket(&data);
}
-void WorldSession::SaveTutorialsData()
+void WorldSession::SaveTutorialsData(SQLTransaction& trans)
{
if (!m_TutorialsChanged)
return;
@@ -701,14 +701,10 @@ void WorldSession::SaveTutorialsData()
Rows = result->Fetch()[0].GetUInt32();
if (Rows)
- {
- CharacterDatabase.PExecute("UPDATE character_tutorial SET tut0='%u', tut1='%u', tut2='%u', tut3='%u', tut4='%u', tut5='%u', tut6='%u', tut7='%u' WHERE account = '%u'",
+ trans->PAppend("UPDATE character_tutorial SET tut0='%u', tut1='%u', tut2='%u', tut3='%u', tut4='%u', tut5='%u', tut6='%u', tut7='%u' WHERE account = '%u'",
m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7], GetAccountId());
- }
else
- {
- CharacterDatabase.PExecute("INSERT INTO character_tutorial (account,tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7) VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", GetAccountId(), m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7]);
- }
+ trans->PAppend("INSERT INTO character_tutorial (account,tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7) VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", GetAccountId(), m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7]);
m_TutorialsChanged = false;
}
@@ -994,7 +990,7 @@ void WorldSession::ProcessQueryCallbacks()
//! HandleAddFriendOpcode
if (m_addFriendCallback.IsReady())
{
- const std::string& param = m_addFriendCallback.GetParam();
+ std::string param = m_addFriendCallback.GetParam();
m_addFriendCallback.GetResult(result);
HandleAddFriendOpcodeCallBack(result, param);
m_addFriendCallback.FreeResult();
@@ -1003,7 +999,7 @@ void WorldSession::ProcessQueryCallbacks()
//- HandleCharRenameOpcode
if (m_charRenameCallback.IsReady())
{
- const std::string& param = m_charRenameCallback.GetParam();
+ std::string param = m_charRenameCallback.GetParam();
m_charRenameCallback.GetResult(result);
HandleChangePlayerNameOpcodeCallBack(result, param);
m_charRenameCallback.FreeResult();
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 26bfbcf7b1f..75aff32af5d 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -229,7 +229,7 @@ class WorldSession
void LoadAccountData(QueryResult_AutoPtr result, uint32 mask);
void LoadTutorialsData();
void SendTutorialsData();
- void SaveTutorialsData();
+ void SaveTutorialsData(SQLTransaction& trans);
uint32 GetTutorialInt(uint32 intId)
{
return m_Tutorials[intId];
@@ -250,8 +250,6 @@ class WorldSession
void SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError = 0);
void SendAuctionBidderNotification(uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template);
void SendAuctionOwnerNotification(AuctionEntry * auction);
- void SendAuctionOutbiddedMail(AuctionEntry * auction, uint32 newPrice);
- void SendAuctionCancelledToBidderMail(AuctionEntry* auction);
//Item Enchantment
void SendEnchantmentLog(uint64 Target, uint64 Caster,uint32 ItemID,uint32 SpellID);
diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp
index 4fed5faa7dd..5dd0ed97dc7 100644
--- a/src/server/game/Tools/PlayerDump.cpp
+++ b/src/server/game/Tools/PlayerDump.cpp
@@ -369,7 +369,7 @@ DumpReturn PlayerDumpWriter::WriteDump(const std::string& file, uint32 guid)
}
// Reading - High-level functions
-#define ROLLBACK(DR) {CharacterDatabase.RollbackTransaction(); fclose(fin); return (DR);}
+#define ROLLBACK(DR) {fclose(fin); return (DR);}
void fixNULLfields(std::string &line)
{
@@ -436,7 +436,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
typedef PetIds::value_type PetIdsPair;
PetIds petids;
- CharacterDatabase.BeginTransaction();
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
while (!feof(fin))
{
if (!fgets(buf, 32000, fin))
@@ -629,10 +629,10 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
fixNULLfields(line);
- CharacterDatabase.Execute(line.c_str());
+ trans->Append(line.c_str());
}
- CharacterDatabase.CommitTransaction();
+ CharacterDatabase.CommitTransaction(trans);
sObjectMgr.m_hiItemGuid += items.size();
sObjectMgr.m_mailid += mails.size();
diff --git a/src/server/shared/Database/DatabaseEnv.h b/src/server/shared/Database/DatabaseEnv.h
index a878a358760..d6aa7dc9b41 100644
--- a/src/server/shared/Database/DatabaseEnv.h
+++ b/src/server/shared/Database/DatabaseEnv.h
@@ -30,8 +30,10 @@
#include "DatabaseWorkerPool.h"
#include "MySQLThreading.h"
+#include "Transaction.h"
typedef DatabaseWorkerPool DatabaseType;
+
#define _LIKE_ "LIKE"
#define _TABLE_SIM_ "`"
#define _CONCAT3_(A,B,C) "CONCAT( " A " , " B " , " C " )"
diff --git a/src/server/shared/Database/DatabaseWorkerPool.cpp b/src/server/shared/Database/DatabaseWorkerPool.cpp
index 538a3535efd..654caf33511 100644
--- a/src/server/shared/Database/DatabaseWorkerPool.cpp
+++ b/src/server/shared/Database/DatabaseWorkerPool.cpp
@@ -16,7 +16,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "DatabaseEnv.h"
#include "DatabaseWorkerPool.h"
#include "MySQLConnection.h"
#include "DatabaseEnv.h"
@@ -183,43 +182,25 @@ QueryResult_AutoPtr DatabaseWorkerPool::PQuery(const char* sql, ...)
return Query(szQuery);
}
-void DatabaseWorkerPool::BeginTransaction()
+SQLTransaction DatabaseWorkerPool::BeginTransaction()
{
- ACE_Guard<ACE_Thread_Mutex> guard(m_transQueues_mtx);
- ACE_Based::Thread* tranThread = ACE_Based::Thread::current(); // owner of this transaction
- TransactionQueues::iterator itr = m_tranQueues.find(tranThread);
- if (itr != m_tranQueues.end() && itr->second != NULL)
- {
- itr->second->ForcefulDelete();
- delete itr->second;
- }
- m_tranQueues[tranThread] = new TransactionTask();
- return;
+ return SQLTransaction(new Transaction);
}
-void DatabaseWorkerPool::RollbackTransaction()
+void DatabaseWorkerPool::CommitTransaction(SQLTransaction transaction)
{
- ACE_Guard<ACE_Thread_Mutex> guard(m_transQueues_mtx);
- ACE_Based::Thread* tranThread = ACE_Based::Thread::current(); // owner of this transaction
- TransactionQueues::iterator itr = m_tranQueues.find(tranThread);
- if (itr != m_tranQueues.end() && itr->second != NULL)
+ #ifdef _DEBUG
+ if (transaction->GetSize() == 0)
{
- itr->second->ForcefulDelete();
- delete itr->second;
- itr->second = NULL;
+ sLog.outError("Transaction contains 0 queries");
+ return;
}
-}
-
-void DatabaseWorkerPool::CommitTransaction()
-{
- ACE_Guard<ACE_Thread_Mutex> guard(m_transQueues_mtx);
- ACE_Based::Thread* tranThread = ACE_Based::Thread::current(); // owner of this transaction
- TransactionQueues::iterator itr = m_tranQueues.find(tranThread);
- if (itr != m_tranQueues.end() && itr->second != NULL)
+ if (transaction->GetSize() == 1)
{
- Enqueue(itr->second);
- itr->second = NULL;
+ sLog.outDetail("Warning: Transaction only holds 1 query, consider removing Transaction context in code.");
}
+ #endif
+ Enqueue(new TransactionTask(transaction));
}
ACE_Future<QueryResult_AutoPtr> DatabaseWorkerPool::AsyncQuery(const char* sql)
@@ -258,7 +239,7 @@ MySQLConnection* DatabaseWorkerPool::GetConnection()
ACE_Guard<ACE_Thread_Mutex> guard(m_connectionMap_mtx);
itr = m_sync_connections.find(ACE_Based::Thread::current());
if (itr != m_sync_connections.end())
- return itr->second;
+ conn = itr->second;
}
/*! Bundled threads */
conn = m_bundle_conn;
diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h
index 6443d05b0dd..2a1350888a2 100644
--- a/src/server/shared/Database/DatabaseWorkerPool.h
+++ b/src/server/shared/Database/DatabaseWorkerPool.h
@@ -28,6 +28,7 @@
#include "QueryResult.h"
#include "Callback.h"
#include "MySQLConnection.h"
+#include "Transaction.h"
enum MySQLThreadBundle
{
@@ -73,9 +74,8 @@ class DatabaseWorkerPool
ACE_Future<QueryResult_AutoPtr> AsyncPQuery(const char* sql, ...);
QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder);
- void BeginTransaction();
- void RollbackTransaction();
- void CommitTransaction();
+ SQLTransaction BeginTransaction();
+ void CommitTransaction(SQLTransaction transaction);
void escape_string(std::string& str)
{
@@ -117,8 +117,6 @@ class DatabaseWorkerPool
MySQLConnection* m_bundle_conn; //! Bundled connection (see Database.ThreadBundleMask config)
AtomicUInt m_connections; //! Counter of MySQL connections;
std::string m_infoString; //! Infostring that is passed on to child connections.
- TransactionQueues m_tranQueues; //! Transaction queues from diff. threads
- ACE_Thread_Mutex m_transQueues_mtx; //! To guard m_transQueues
};
#endif
diff --git a/src/server/shared/Database/SQLOperation.cpp b/src/server/shared/Database/SQLOperation.cpp
index 1cd45a4c0b6..a3eda4b7239 100644
--- a/src/server/shared/Database/SQLOperation.cpp
+++ b/src/server/shared/Database/SQLOperation.cpp
@@ -16,9 +16,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "DatabaseEnv.h"
#include "SQLOperation.h"
#include "MySQLConnection.h"
+#include "Log.h"
/*! Basic, ad-hoc queries. */
BasicStatementTask::BasicStatementTask(const char* sql) :
@@ -53,53 +53,6 @@ bool BasicStatementTask::Execute()
return m_conn->Execute(m_sql);
}
-/*! Transactions. */
-TransactionTask::TransactionTask()
-{
-}
-
-TransactionTask::~TransactionTask()
-{
-
-}
-
-void TransactionTask::ForcefulDelete()
-{
- while (!m_queries.empty())
- {
- free((void*)const_cast<char*>(m_queries.front()));
- m_queries.pop();
- }
-}
-
-bool TransactionTask::Execute()
-{
- if (m_queries.empty())
- return false;
-
- const char* sql;
-
- m_conn->BeginTransaction();
- while (!m_queries.empty())
- {
- sql = m_queries.front();
- if (!m_conn->Execute(sql))
- {
- free((void*)const_cast<char*>(sql));
- m_queries.pop();
- m_conn->RollbackTransaction();
- ForcefulDelete();
- return false;
- }
-
- free((void*)const_cast<char*>(sql));
- m_queries.pop();
- }
-
- m_conn->CommitTransaction();
- return true;
-}
-
bool SQLQueryHolder::SetQuery(size_t index, const char *sql)
{
if (m_queries.size() <= index)
diff --git a/src/server/shared/Database/SQLOperation.h b/src/server/shared/Database/SQLOperation.h
index a8238802e31..0c5fe08d94e 100644
--- a/src/server/shared/Database/SQLOperation.h
+++ b/src/server/shared/Database/SQLOperation.h
@@ -59,19 +59,7 @@ class BasicStatementTask : public SQLOperation
QueryResultFuture m_result;
};
-/*! Transactions */
-class TransactionTask : public SQLOperation
-{
- public:
- TransactionTask();
- ~TransactionTask();
- void ForcefulDelete();
-
- bool Execute();
- private:
- std::queue<char*> m_queries;
-};
class SQLQueryHolder
{
diff --git a/src/server/shared/Database/Transaction.cpp b/src/server/shared/Database/Transaction.cpp
new file mode 100644
index 00000000000..a364728b2d0
--- /dev/null
+++ b/src/server/shared/Database/Transaction.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Transaction.h"
+
+void Transaction::Append(const char* sql)
+{
+ m_queries.push(strdup(sql));
+}
+
+void Transaction::PAppend(const char* sql, ...)
+{
+ va_list ap;
+ char szQuery [MAX_QUERY_LEN];
+ va_start(ap, sql);
+ int res = vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
+ va_end(ap);
+
+ Append(szQuery);
+}
+
+void Transaction::Cleanup()
+{
+ while (!m_queries.empty())
+ {
+ free((void*)const_cast<char*>(m_queries.front()));
+ m_queries.pop();
+ }
+}
+
+bool TransactionTask::Execute()
+{
+ std::queue<char*>& queries = m_trans->m_queries;
+ if (queries.empty())
+ return false;
+
+ const char* sql;
+
+ m_conn->BeginTransaction();
+ while (!queries.empty())
+ {
+ sql = queries.front();
+ if (!m_conn->Execute(sql))
+ {
+ free((void*)const_cast<char*>(sql));
+ queries.pop();
+ m_conn->RollbackTransaction();
+ return false;
+ }
+
+ free((void*)const_cast<char*>(sql));
+ queries.pop();
+ }
+
+ m_conn->CommitTransaction();
+ return true;
+}
diff --git a/src/server/shared/Database/Transaction.h b/src/server/shared/Database/Transaction.h
new file mode 100644
index 00000000000..e94ca053e32
--- /dev/null
+++ b/src/server/shared/Database/Transaction.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _TRANSACTION_H
+#define _TRANSACTION_H
+
+/*! Transactions, high level class. */
+class Transaction
+{
+ friend class TransactionTask;
+ public:
+ ~Transaction() { Cleanup(); }
+
+ void Append(const char* sql);
+ void PAppend(const char* sql, ...);
+
+ size_t GetSize() { return m_queries.size(); }
+
+ protected:
+ void Cleanup();
+ std::queue<char*> m_queries;
+
+ private:
+ bool m_actioned;
+};
+typedef ACE_Refcounted_Auto_Ptr<Transaction, ACE_Null_Mutex> SQLTransaction;
+
+/*! Low level class*/
+class TransactionTask : public SQLOperation
+{
+ friend class DatabaseWorkerPool;
+ friend class DatabaseWorker;
+
+ public:
+ TransactionTask(SQLTransaction trans) : m_trans(trans) {} ;
+ ~TransactionTask(){};
+
+ protected:
+ bool Execute();
+
+ SQLTransaction m_trans;
+};
+
+#endif \ No newline at end of file