DB Layer:

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

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

--HG--
branch : trunk
This commit is contained in:
Machiavelli
2010-08-21 03:19:25 +02:00
parent a7498d2f56
commit 994186f267
49 changed files with 861 additions and 774 deletions
+5 -7
View File
@@ -27,8 +27,6 @@
#include "Util.h" #include "Util.h"
#include "SHA1.h" #include "SHA1.h"
extern DatabaseType LoginDatabase;
AccountMgr::AccountMgr() 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 character_tutorial WHERE account = '%u'",accid);
CharacterDatabase.PExecute("DELETE FROM account_data 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); trans->PAppend("DELETE FROM account WHERE id='%d'", accid);
LoginDatabase.PExecute("DELETE FROM account_access WHERE id ='%d'", accid); trans->PAppend("DELETE FROM account_access WHERE id ='%d'", accid);
LoginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid='%d'", accid); trans->PAppend("DELETE FROM realmcharacters WHERE acctid='%d'", accid);
LoginDatabase.CommitTransaction(); LoginDatabase.CommitTransaction(trans);
return AOR_OK; return AOR_OK;
} }
+13 -11
View File
@@ -440,13 +440,13 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin
void AchievementMgr::DeleteFromDB(uint32 lowguid) void AchievementMgr::DeleteFromDB(uint32 lowguid)
{ {
CharacterDatabase.BeginTransaction (); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = %u",lowguid); trans->PAppend("DELETE FROM character_achievement WHERE guid = %u",lowguid);
CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = %u",lowguid); trans->PAppend("DELETE FROM character_achievement_progress WHERE guid = %u",lowguid);
CharacterDatabase.CommitTransaction (); CharacterDatabase.CommitTransaction(trans);
} }
void AchievementMgr::SaveToDB() void AchievementMgr::SaveToDB(SQLTransaction& trans)
{ {
if (!m_completedAchievements.empty()) if (!m_completedAchievements.empty())
{ {
@@ -485,8 +485,8 @@ void AchievementMgr::SaveToDB()
if (need_execute) if (need_execute)
{ {
CharacterDatabase.Execute(ssdel.str().c_str()); trans->Append(ssdel.str().c_str());
CharacterDatabase.Execute(ssins.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 || need_execute_ins)
{ {
if (need_execute_del) if (need_execute_del)
CharacterDatabase.Execute(ssdel.str().c_str()); trans->Append(ssdel.str().c_str());
if (need_execute_ins) 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); MailDraft draft(subject, text);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (item) if (item)
{ {
// save new item before send // 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 // item
draft.AddItem(item); draft.AddItem(item);
} }
draft.SendMailTo(GetPlayer(), MailSender(MAIL_CREATURE, reward->sender)); draft.SendMailTo(trans, GetPlayer(), MailSender(MAIL_CREATURE, reward->sender));
CharacterDatabase.CommitTransaction(trans);
} }
} }
@@ -244,7 +244,7 @@ class AchievementMgr
void Reset(); void Reset();
static void DeleteFromDB(uint32 lowguid); static void DeleteFromDB(uint32 lowguid);
void LoadFromDB(QueryResult_AutoPtr achievementResult, QueryResult_AutoPtr criteriaResult); 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 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 UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1 = 0, uint32 miscvalue2 = 0, Unit *unit = NULL, uint32 time = 0);
void CompletedAchievement(AchievementEntry const* entry); void CompletedAchievement(AchievementEntry const* entry);
@@ -88,7 +88,7 @@ uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32
} }
//does not clear ram //does not clear ram
void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction) void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction, SQLTransaction& trans)
{ {
Item *pItem = GetAItem(auction->item_guidlow); Item *pItem = GetAItem(auction->item_guidlow);
if (!pItem) if (!pItem)
@@ -146,7 +146,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
// set owner to bidder (to prevent delete item with sender char deleting) // set owner to bidder (to prevent delete item with sender char deleting)
// owner in `data` will set at mail receive and item extracting // 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) if (bidder)
{ {
@@ -157,11 +157,11 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
MailDraft(msgAuctionWonSubject.str(), msgAuctionWonBody.str()) MailDraft(msgAuctionWonSubject.str(), msgAuctionWonBody.str())
.AddItem(pItem) .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); uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
Player *owner = sObjectMgr.GetPlayer(owner_guid); 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()); sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str());
MailDraft(msgAuctionSalePendingSubject.str(), msgAuctionSalePendingBody.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 //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); uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
Player *owner = sObjectMgr.GetPlayer(owner_guid); Player *owner = sObjectMgr.GetPlayer(owner_guid);
@@ -224,12 +224,12 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction)
} }
MailDraft(msgAuctionSuccessfulSubject.str(), auctionSuccessfulBody.str()) MailDraft(msgAuctionSuccessfulSubject.str(), auctionSuccessfulBody.str())
.AddMoney(profit) .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 //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 //return an item in auction to its owner by mail
Item *pItem = GetAItem(auction->item_guidlow); Item *pItem = GetAItem(auction->item_guidlow);
@@ -250,10 +250,58 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry * auction)
MailDraft(subject.str(), "") // TODO: fix body MailDraft(subject.str(), "") // TODO: fix body
.AddItem(pItem) .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() void AuctionHouseMgr::LoadAuctionItems()
{ {
// data needs to be at first place for Item::LoadFromDB // data needs to be at first place for Item::LoadFromDB
@@ -342,6 +390,10 @@ void AuctionHouseMgr::LoadAuctions()
barGoLink bar(AuctionCount); 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; AuctionEntry *aItem;
do do
@@ -366,7 +418,7 @@ void AuctionHouseMgr::LoadAuctions()
CreatureData const* auctioneerData = sObjectMgr.GetCreatureData(aItem->auctioneer); CreatureData const* auctioneerData = sObjectMgr.GetCreatureData(aItem->auctioneer);
if (!auctioneerData) if (!auctioneerData)
{ {
aItem->DeleteFromDB(); aItem->DeleteFromDB(trans);
sLog.outError("Auction %u has not a existing auctioneer (GUID : %u)", aItem->Id, aItem->auctioneer); sLog.outError("Auction %u has not a existing auctioneer (GUID : %u)", aItem->Id, aItem->auctioneer);
delete aItem; delete aItem;
continue; continue;
@@ -375,7 +427,7 @@ void AuctionHouseMgr::LoadAuctions()
CreatureInfo const* auctioneerInfo = sObjectMgr.GetCreatureTemplate(auctioneerData->id); CreatureInfo const* auctioneerInfo = sObjectMgr.GetCreatureTemplate(auctioneerData->id);
if (!auctioneerInfo) 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); sLog.outError("Auction %u has not a existing auctioneer (GUID : %u Entry: %u)", aItem->Id, aItem->auctioneer,auctioneerData->id);
delete aItem; delete aItem;
continue; continue;
@@ -384,7 +436,7 @@ void AuctionHouseMgr::LoadAuctions()
aItem->auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(auctioneerInfo->faction_A); aItem->auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(auctioneerInfo->faction_A);
if (!aItem->auctionHouseEntry) if (!aItem->auctionHouseEntry)
{ {
aItem->DeleteFromDB(); aItem->DeleteFromDB(trans);
sLog.outError("Auction %u has auctioneer (GUID : %u Entry: %u) with wrong faction %u", sLog.outError("Auction %u has auctioneer (GUID : %u Entry: %u) with wrong faction %u",
aItem->Id, aItem->auctioneer,auctioneerData->id,auctioneerInfo->faction_A); aItem->Id, aItem->auctioneer,auctioneerData->id,auctioneerInfo->faction_A);
delete aItem; 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) // and item_template in fact (GetAItem will fail if problematic in result check in AuctionHouseMgr::LoadAuctionItems)
if (!GetAItem(aItem->item_guidlow)) 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); sLog.outError("Auction %u has not a existing item : %u", aItem->Id, aItem->item_guidlow);
delete aItem; delete aItem;
continue; continue;
@@ -405,6 +457,8 @@ void AuctionHouseMgr::LoadAuctions()
} while (result->NextRow()); } while (result->NextRow());
CharacterDatabase.CommitTransaction(trans);
sLog.outString(); sLog.outString();
sLog.outString(">> Loaded %u auctions", AuctionCount); sLog.outString(">> Loaded %u auctions", AuctionCount);
} }
@@ -506,35 +560,20 @@ void AuctionHouseObject::Update()
if (!result) if (!result)
return; return;
if (result->GetRowCount() == 0)
return;
vector<uint32> expiredAuctions;
do 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 // from auctionhousehandler.cpp, creates auction pointer & player pointer
AuctionEntry* auction = GetAuction(*iter); AuctionEntry* auction = GetAuction(result->Fetch()->GetUInt32());
// Erase the auction from the vector.
expiredAuctions.erase(iter);
if (!auction) if (!auction)
continue; continue;
SQLTransaction trans = CharacterDatabase.BeginTransaction();
///- Either cancel the auction if there was no bidder ///- Either cancel the auction if there was no bidder
if (auction->bidder == 0) if (auction->bidder == 0)
{ {
sAuctionMgr.SendAuctionExpiredMail(auction); sAuctionMgr.SendAuctionExpiredMail(auction, trans);
sScriptMgr.OnAuctionExpire(this, auction); sScriptMgr.OnAuctionExpire(this, auction);
} }
///- Or perform the transaction ///- Or perform the transaction
@@ -543,19 +582,21 @@ void AuctionHouseObject::Update()
//we should send an "item sold" message if the seller is online //we should send an "item sold" message if the seller is online
//we send the item to the winner //we send the item to the winner
//we send the money to the seller //we send the money to the seller
sAuctionMgr.SendAuctionSuccessfulMail(auction); sAuctionMgr.SendAuctionSuccessfulMail(auction, trans);
sAuctionMgr.SendAuctionWonMail(auction); sAuctionMgr.SendAuctionWonMail(auction, trans);
sScriptMgr.OnAuctionSuccessful(this, auction); sScriptMgr.OnAuctionSuccessful(this, auction);
} }
///- In any case clear the auction
CharacterDatabase.BeginTransaction();
auction->DeleteFromDB();
uint32 item_template = auction->item_template; 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); 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) void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount)
@@ -746,16 +787,14 @@ uint32 AuctionEntry::GetAuctionOutBid() const
return outbid; return outbid;
} }
void AuctionEntry::DeleteFromDB() const void AuctionEntry::DeleteFromDB(SQLTransaction& trans) const
{ {
//No SQL injection (Id is integer) trans->PAppend("DELETE FROM auctionhouse WHERE id = '%u'",Id);
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",Id);
} }
void AuctionEntry::SaveToDB() const void AuctionEntry::SaveToDB(SQLTransaction& trans) const
{ {
//No SQL injection (no strings) trans->PAppend("INSERT INTO auctionhouse (id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit) "
CharacterDatabase.PExecute("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')", "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); Id, auctioneer, item_guidlow, item_template, owner, buyout, (uint64)expire_time, bidder, bid, startbid, deposit);
} }
@@ -66,8 +66,8 @@ struct AuctionEntry
uint32 GetAuctionCut() const; uint32 GetAuctionCut() const;
uint32 GetAuctionOutBid() const; uint32 GetAuctionOutBid() const;
bool BuildAuctionInfo(WorldPacket & data) const; bool BuildAuctionInfo(WorldPacket & data) const;
void DeleteFromDB() const; void DeleteFromDB(SQLTransaction& trans) const;
void SaveToDB() const; void SaveToDB(SQLTransaction& trans) const;
}; };
//this class is used as auctionhouse instance //this class is used as auctionhouse instance
@@ -138,10 +138,13 @@ class AuctionHouseMgr
} }
//auction messages //auction messages
void SendAuctionWonMail(AuctionEntry * auction); void SendAuctionWonMail(AuctionEntry * auction, SQLTransaction& trans);
void SendAuctionSalePendingMail(AuctionEntry * auction); void SendAuctionSalePendingMail(AuctionEntry * auction, SQLTransaction& trans);
void SendAuctionSuccessfulMail(AuctionEntry * auction); void SendAuctionSuccessfulMail(AuctionEntry * auction, SQLTransaction& trans);
void SendAuctionExpiredMail(AuctionEntry * auction); 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 uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem);
static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId); static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId);
+14 -16
View File
@@ -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 // ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB
CharacterDatabase.escape_string(ArenaTeamName); 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 WHERE arenateamid='%u'", m_TeamId); - MAX(arenateam)+1 not exist
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", m_TeamId); trans->PAppend("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("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) "
"VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')", "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); 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); "('%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); AddMember(m_CaptainGuid);
sLog.outArena("New ArenaTeam created [Id: %u] [Type: %u] [Captain GUID: %u]", GetId(), GetType(), GetCaptain()); 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()) if (Player *player = session->GetPlayer())
sLog.outArena("Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId()); sLog.outArena("Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId());
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", m_TeamId); trans->PAppend("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 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
CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", m_TeamId); trans->PAppend("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", m_TeamId);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
sObjectMgr.RemoveArenaTeam(m_TeamId); sObjectMgr.RemoveArenaTeam(m_TeamId);
} }
@@ -734,13 +734,11 @@ void ArenaTeam::SaveToDB()
{ {
// save team and member stats to db // save team and member stats to db
// called after a match has ended, or when calculating arena_points // called after a match has ended, or when calculating arena_points
CharacterDatabase.BeginTransaction(); SQLTransaction trans = 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()); 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) for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{ 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.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);
}
CharacterDatabase.CommitTransaction();
} }
void ArenaTeam::FinishWeek() void ArenaTeam::FinishWeek()
+5 -1
View File
@@ -2395,8 +2395,12 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
// from console show not existed sender // from console show not existed sender
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); 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) 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); std::string nameLink = playerLink(target_name);
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
+10 -3
View File
@@ -6818,16 +6818,19 @@ bool ChatHandler::HandleSendItemsCommand(const char *args)
// fill mail // fill mail
MailDraft draft(subject, text); MailDraft draft(subject, text);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) 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)) 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.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); std::string nameLink = playerLink(receiver_name);
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
@@ -6873,9 +6876,13 @@ bool ChatHandler::HandleSendMoneyCommand(const char *args)
// from console show not existed sender // from console show not existed sender
MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
MailDraft(subject, text) MailDraft(subject, text)
.AddMoney(money) .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); std::string nameLink = playerLink(receiver_name);
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
+7 -7
View File
@@ -105,8 +105,8 @@ bool Corpse::Create(uint32 guidlow, Player *owner)
void Corpse::SaveToDB() void Corpse::SaveToDB()
{ {
// prevent DB data inconsistence problems and duplicates // prevent DB data inconsistence problems and duplicates
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
DeleteFromDB(); DeleteFromDB(trans);
std::ostringstream ss; 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 (" 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()) << ", " << uint32(GetType()) << ", "
<< int(GetInstanceId()) << ", " << int(GetInstanceId()) << ", "
<< uint16(GetPhaseMask()) << ")"; // prevent out of range error << uint16(GetPhaseMask()) << ")"; // prevent out of range error
CharacterDatabase.Execute(ss.str().c_str()); trans->Append(ss.str().c_str());
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
void Corpse::DeleteBonesFromWorld() void Corpse::DeleteBonesFromWorld()
@@ -149,14 +149,14 @@ void Corpse::DeleteBonesFromWorld()
AddObjectToRemoveList(); AddObjectToRemoveList();
} }
void Corpse::DeleteFromDB() void Corpse::DeleteFromDB(SQLTransaction& trans)
{ {
if (GetType() == CORPSE_BONES) if (GetType() == CORPSE_BONES)
// only specific bones // only specific bones
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%d'", GetGUIDLow()); trans->PAppend("DELETE FROM corpse WHERE guid = '%d'", GetGUIDLow());
else else
// all corpses (not bones) // 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) bool Corpse::LoadFromDB(uint32 guid, Field *fields)
+1 -1
View File
@@ -64,7 +64,7 @@ class Corpse : public WorldObject, public GridObject<Corpse>
bool LoadFromDB(uint32 guid, Field *fields); bool LoadFromDB(uint32 guid, Field *fields);
void DeleteBonesFromWorld(); void DeleteBonesFromWorld();
void DeleteFromDB(); void DeleteFromDB(SQLTransaction& trans);
uint64 const& GetOwnerGUID() const { return GetUInt64Value(CORPSE_FIELD_OWNER); } uint64 const& GetOwnerGUID() const { return GetUInt64Value(CORPSE_FIELD_OWNER); }
+10 -10
View File
@@ -1052,9 +1052,9 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
data.spawnMask = spawnMask; data.spawnMask = spawnMask;
// updated in DB // 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; std::ostringstream ss;
ss << "INSERT INTO creature VALUES (" ss << "INSERT INTO creature VALUES ("
@@ -1077,9 +1077,9 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
<< (m_isDeadByDefault ? 1 : 0) << "," //is_dead << (m_isDeadByDefault ? 1 : 0) << "," //is_dead
<< GetDefaultMovementType() << ")"; //default movement generator type << 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) void Creature::SelectLevel(const CreatureInfo *cinfo)
@@ -1348,12 +1348,12 @@ void Creature::DeleteFromDB()
sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
sObjectMgr.DeleteCreatureData(m_DBTableGuid); sObjectMgr.DeleteCreatureData(m_DBTableGuid);
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);
WorldDatabase.PExecute("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid); trans->PAppend("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecute("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid); trans->PAppend("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecute("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid); trans->PAppend("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.CommitTransaction(); WorldDatabase.CommitTransaction(trans);
} }
bool Creature::canSeeOrDetect(Unit const* u, bool detect, bool /*inVisibleList*/, bool /*is3dDistance*/) const bool Creature::canSeeOrDetect(Unit const* u, bool detect, bool /*inVisibleList*/, bool /*is3dDistance*/) const
@@ -644,10 +644,10 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
<< uint32(GetGoAnimProgress()) << ", " << uint32(GetGoAnimProgress()) << ", "
<< uint32(GetGoState()) << ")"; << uint32(GetGoState()) << ")";
WorldDatabase.BeginTransaction(); SQLTransaction trans = WorldDatabase.BeginTransaction();
WorldDatabase.PExecute("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid); trans->PAppend("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecute(ss.str().c_str()); trans->Append(ss.str().c_str());
WorldDatabase.CommitTransaction(); WorldDatabase.CommitTransaction(trans);
} }
bool GameObject::LoadFromDB(uint32 guid, Map *map) bool GameObject::LoadFromDB(uint32 guid, Map *map)
@@ -102,9 +102,9 @@ bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner)
return true; 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) 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; return true;
} }
void Bag::DeleteFromDB() void Bag::DeleteFromDB(SQLTransaction& trans)
{ {
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i) for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
if (m_bagslot[i]) if (m_bagslot[i])
m_bagslot[i]->DeleteFromDB(); m_bagslot[i]->DeleteFromDB(trans);
Item::DeleteFromDB(); Item::DeleteFromDB(trans);
} }
uint32 Bag::GetFreeSlots() const uint32 Bag::GetFreeSlots() const
@@ -54,11 +54,11 @@ class Bag : public Item
// DB operations // DB operations
// overwrite virtual Item::SaveToDB // overwrite virtual Item::SaveToDB
void SaveToDB(); void SaveToDB(SQLTransaction& trans);
// overwrite virtual Item::LoadFromDB // overwrite virtual Item::LoadFromDB
bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result, uint32 entry); bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result, uint32 entry);
// overwrite virtual Item::DeleteFromDB // overwrite virtual Item::DeleteFromDB
void DeleteFromDB(); void DeleteFromDB(SQLTransaction& trans);
void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const; void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const;
+14 -14
View File
@@ -301,7 +301,7 @@ void Item::UpdateDuration(Player* owner, uint32 diff)
SetState(ITEM_CHANGED, owner); // save new time in database SetState(ITEM_CHANGED, owner); // save new time in database
} }
void Item::SaveToDB() void Item::SaveToDB(SQLTransaction& trans)
{ {
uint32 guid = GetGUIDLow(); uint32 guid = GetGUIDLow();
switch (uState) switch (uState)
@@ -334,7 +334,7 @@ void Item::SaveToDB()
ss << GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME) << ",'"; ss << GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME) << ",'";
ss << text << "')"; ss << text << "')";
CharacterDatabase.Execute(ss.str().c_str()); trans->Append(ss.str().c_str());
}break; }break;
case ITEM_CHANGED: case ITEM_CHANGED:
{ {
@@ -364,16 +364,16 @@ void Item::SaveToDB()
ss << ", playedTime = " << GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME); ss << ", playedTime = " << GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME);
ss << ", text = '" << text << "' WHERE guid = " << guid; 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)) 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; }break;
case ITEM_REMOVED: 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)) 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; delete this;
return; return;
} }
@@ -471,14 +471,14 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result
return true; 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 ItemPrototype const *Item::GetProto() const
@@ -1103,11 +1103,11 @@ void Item::BuildUpdate(UpdateDataMapType& data_map)
void Item::SaveRefundDataToDB() void Item::SaveRefundDataToDB()
{ {
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM item_refund_instance WHERE item_guid = '%u'", GetGUIDLow()); trans->PAppend("DELETE FROM item_refund_instance WHERE item_guid = '%u'", GetGUIDLow());
CharacterDatabase.PExecute("INSERT INTO item_refund_instance (`item_guid`,`player_guid`,`paidMoney`,`paidExtendedCost`)" trans->PAppend("INSERT INTO item_refund_instance (`item_guid`,`player_guid`,`paidMoney`,`paidExtendedCost`)"
" VALUES('%u','%u','%u','%u')", GetGUIDLow(), GetRefundRecipient(), GetPaidMoney(), GetPaidExtendedCost()); " VALUES('%u','%u','%u','%u')", GetGUIDLow(), GetRefundRecipient(), GetPaidMoney(), GetPaidExtendedCost());
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
void Item::DeleteRefundDataFromDB() void Item::DeleteRefundDataFromDB()
+3 -3
View File
@@ -244,10 +244,10 @@ class Item : public Object
bool IsBoundAccountWide() const { return (GetProto()->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT) != 0; } bool IsBoundAccountWide() const { return (GetProto()->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT) != 0; }
bool IsBindedNotWith(Player const* player) const; bool IsBindedNotWith(Player const* player) const;
bool IsBoundByEnchant() 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 bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result, uint32 entry);
virtual void DeleteFromDB(); virtual void DeleteFromDB(SQLTransaction& trans);
void DeleteFromInventoryDB(); void DeleteFromInventoryDB(SQLTransaction& trans);
void SaveRefundDataToDB(); void SaveRefundDataToDB();
void DeleteRefundDataFromDB(); void DeleteRefundDataFromDB();
+33 -35
View File
@@ -262,12 +262,12 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c
// PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning)) // PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning))
if (fields[7].GetUInt32() != 0) if (fields[7].GetUInt32() != 0)
{ {
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'", 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()); 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()); 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 // 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 curhealth = GetHealth();
uint32 curmana = GetPower(POWER_MANA); uint32 curmana = GetPower(POWER_MANA);
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
// save auras before possibly removing them // save auras before possibly removing them
_SaveAuras(); _SaveAuras(trans);
// stable and not in slot saves // stable and not in slot saves
if (mode > PET_SAVE_AS_CURRENT) if (mode > PET_SAVE_AS_CURRENT)
{
RemoveAllAuras(); RemoveAllAuras();
}
_SaveSpells(); _SaveSpells(trans);
_SaveSpellCooldowns(); _SaveSpellCooldowns(trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
// current/stable/not_in_slot // current/stable/not_in_slot
if (mode >= PET_SAVE_AS_CURRENT) if (mode >= PET_SAVE_AS_CURRENT)
@@ -397,18 +395,18 @@ void Pet::SavePetToDB(PetSaveMode mode)
uint32 owner = GUID_LOPART(GetOwnerGUID()); uint32 owner = GUID_LOPART(GetOwnerGUID());
std::string name = m_name; std::string name = m_name;
CharacterDatabase.escape_string(name); CharacterDatabase.escape_string(name);
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
// remove current data // 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) // prevent duplicate using slot (except PET_SAVE_NOT_IN_SLOT)
if (mode <= PET_SAVE_LAST_STABLE_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)); PET_SAVE_NOT_IN_SLOT, owner, uint32(mode));
// prevent existence another hunter pet in PET_SAVE_AS_CURRENT and PET_SAVE_NOT_IN_SLOT // 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)) 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); owner,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
// save pet // save pet
std::ostringstream ss; std::ostringstream ss;
@@ -441,8 +439,8 @@ void Pet::SavePetToDB(PetSaveMode mode)
<< GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", " << GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", "
<< uint32(getPetType()) << ")"; << uint32(getPetType()) << ")";
CharacterDatabase.Execute(ss.str().c_str()); trans->Append(ss.str().c_str());
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
// delete // delete
else else
@@ -454,13 +452,13 @@ void Pet::SavePetToDB(PetSaveMode mode)
void Pet::DeleteFromDB(uint32 guidlow) void Pet::DeleteFromDB(uint32 guidlow)
{ {
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE id = '%u'", guidlow); trans->PAppend("DELETE FROM character_pet WHERE id = '%u'", guidlow);
CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE id = '%u'", guidlow); trans->PAppend("DELETE FROM character_pet_declinedname WHERE id = '%u'", guidlow);
CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", guidlow); trans->PAppend("DELETE FROM pet_aura WHERE guid = '%u'", guidlow);
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u'", guidlow); trans->PAppend("DELETE FROM pet_spell WHERE guid = '%u'", guidlow);
CharacterDatabase.PExecute("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", guidlow); trans->PAppend("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", guidlow);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
void Pet::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState 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); time_t curTime = time(NULL);
@@ -1156,7 +1154,7 @@ void Pet::_SaveSpellCooldowns()
m_CreatureSpellCooldowns.erase(itr++); m_CreatureSpellCooldowns.erase(itr++);
else 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; ++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) 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) switch (itr->second.state)
{ {
case PETSPELL_REMOVED: 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); m_spells.erase(itr);
continue; continue;
case PETSPELL_CHANGED: case PETSPELL_CHANGED:
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);
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; break;
case PETSPELL_NEW: 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; break;
case PETSPELL_UNCHANGED: case PETSPELL_UNCHANGED:
continue; 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) 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')", "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, 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], itr->second->GetStackAmount(), damage[0], damage[1], damage[2], baseDamage[0], baseDamage[1], baseDamage[2],
+3 -3
View File
@@ -191,11 +191,11 @@ class Pet : public Guardian
bool IsPetAura(Aura const* aura); bool IsPetAura(Aura const* aura);
void _LoadSpellCooldowns(); void _LoadSpellCooldowns();
void _SaveSpellCooldowns(); void _SaveSpellCooldowns(SQLTransaction& trans);
void _LoadAuras(uint32 timediff); void _LoadAuras(uint32 timediff);
void _SaveAuras(); void _SaveAuras(SQLTransaction& trans);
void _LoadSpells(); 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 addSpell(uint32 spell_id,ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
bool learnSpell(uint32 spell_id); bool learnSpell(uint32 spell_id);
+176 -149
View File
@@ -2736,7 +2736,12 @@ void Player::GiveLevel(uint8 level)
pet->SynchronizeLevelWithOwner(); pet->SynchronizeLevelWithOwner();
if (MailLevelReward const* mailReward = sObjectMgr.GetMailLevelReward(level,getRaceMask())) 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); 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 curTime = time(NULL);
time_t infTime = curTime + infinityCooldownDelayCheck; time_t infTime = curTime + infinityCooldownDelayCheck;
@@ -3959,7 +3964,7 @@ void Player::_SaveSpellCooldowns()
} }
// if something changed execute // if something changed execute
if (!first_round) if (!first_round)
CharacterDatabase.Execute(ss.str().c_str()); trans->Append(ss.str().c_str());
} }
uint32 Player::resetTalentsCost() const 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); SetFreeTalentPoints(talentPointsForLevel);
@@ -4416,6 +4423,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
// Completely remove from the database // Completely remove from the database
case CHAR_DELETE_REMOVE: case CHAR_DELETE_REMOVE:
{ {
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// Return back all mails with COD and Item 0 1 2 3 4 5 6 7 // 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); 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) if (resultMail)
@@ -4435,13 +4443,13 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
// We can return mail now // We can return mail now
// So firstly delete the old one // 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 // Mail is not from player
if (mailType != MAIL_NORMAL) if (mailType != MAIL_NORMAL)
{ {
if (has_items) 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; continue;
} }
@@ -4465,7 +4473,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
ItemPrototype const* itemProto = sObjectMgr.GetItemPrototype(item_template); ItemPrototype const* itemProto = sObjectMgr.GetItemPrototype(item_template);
if (!itemProto) 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; 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)) if (!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER), resultItems, item_template))
{ {
pItem->FSetState(ITEM_REMOVED); pItem->FSetState(ITEM_REMOVED);
pItem->SaveToDB(); // it also deletes item object! pItem->SaveToDB(trans); // it also deletes item object!
continue; 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)); 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); 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 // NOW we can finally clear other DB data related to character
CharacterDatabase.BeginTransaction();
if (resultPets) if (resultPets)
{ {
do do
@@ -4508,41 +4515,41 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
} while (resultPets->NextRow()); } while (resultPets->NextRow());
} }
CharacterDatabase.PExecute("DELETE FROM characters WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM characters WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_account_data WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_account_data WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_declinedname WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_action WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_action WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_aura WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_gifts WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_homebind WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_homebind WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_instance WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_inventory WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_queststatus WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_queststatus WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_reputation WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_reputation WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_spell WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_spell_cooldown WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_spell_cooldown WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM gm_tickets WHERE playerGuid = '%u'", guid); trans->PAppend("DELETE FROM gm_tickets WHERE playerGuid = '%u'", guid);
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE owner_guid = '%u'",guid); trans->PAppend("DELETE FROM item_instance WHERE owner_guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_social WHERE guid = '%u' OR friend='%u'",guid,guid); trans->PAppend("DELETE FROM character_social WHERE guid = '%u' OR friend='%u'",guid,guid);
CharacterDatabase.PExecute("DELETE FROM mail WHERE receiver = '%u'",guid); trans->PAppend("DELETE FROM mail WHERE receiver = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE receiver = '%u'",guid); trans->PAppend("DELETE FROM mail_items WHERE receiver = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u'",guid); trans->PAppend("DELETE FROM character_pet WHERE owner = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u'",guid); trans->PAppend("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 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 '456' AND '467' " // Realm First Level 80
"AND achievement NOT BETWEEN '1400' AND '1427' " // Realm First Raid Achievements "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 "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); trans->PAppend("DELETE FROM character_achievement_progress WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_equipmentsets WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_equipmentsets WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE PlayerGuid1 = '%u' OR PlayerGuid2 = '%u'",guid, guid); trans->PAppend("DELETE FROM guild_eventlog WHERE PlayerGuid1 = '%u' OR PlayerGuid2 = '%u'",guid, guid);
CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE PlayerGuid = '%u'",guid); trans->PAppend("DELETE FROM guild_bank_eventlog WHERE PlayerGuid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_battleground_data WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_battleground_data WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_glyphs WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_glyphs WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_queststatus_daily WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_queststatus_daily WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_talent WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_talent WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_skills WHERE guid = '%u'",guid); trans->PAppend("DELETE FROM character_skills WHERE guid = '%u'",guid);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
break; break;
} }
// The character gets unlinked from the account, the name gets freed up and appears as deleted ingame // 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; 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; TotalCost = costs;
} }
else if (GetMoney() < costs) else if (GetMoney() < costs)
@@ -14429,7 +14440,12 @@ void Player::RewardQuest(Quest const *pQuest, uint32 reward, Object* questGiver,
// Send reward mail // Send reward mail
if (uint32 mail_template_id = pQuest->GetRewMailTemplateId()) 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()) if (pQuest->IsDaily())
{ {
@@ -16668,6 +16684,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
if (result) if (result)
{ {
std::list<Item*> problematicItems; std::list<Item*> problematicItems;
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// prevent items from being added to the queue when stored // prevent items from being added to the queue when stored
m_itemUpdateQueueBlocked = true; m_itemUpdateQueueBlocked = true;
@@ -16683,8 +16700,8 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
if (!proto) if (!proto)
{ {
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid); trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%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); sLog.outError("Player::_LoadInventory: Player %s has an unknown item (id: #%u) in inventory, deleted.", GetName(),item_id);
continue; 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); 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); CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
item->FSetState(ITEM_REMOVED); item->FSetState(ITEM_REMOVED);
item->SaveToDB(); // it also deletes item object ! item->SaveToDB(trans); // it also deletes item object !
continue; continue;
} }
@@ -16705,7 +16722,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
{ {
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid); CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
item->FSetState(ITEM_REMOVED); item->FSetState(ITEM_REMOVED);
item->SaveToDB(); // it also deletes item object ! item->SaveToDB(trans); // it also deletes item object !
continue; continue;
} }
@@ -16714,7 +16731,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
{ {
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid); CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
item->FSetState(ITEM_REMOVED); item->FSetState(ITEM_REMOVED);
item->SaveToDB(); // it also deletes item object ! item->SaveToDB(trans); // it also deletes item object !
continue; continue;
} }
@@ -16723,7 +16740,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
if (item->GetPlayedTime() > (2*HOUR)) if (item->GetPlayedTime() > (2*HOUR))
{ {
sLog.outDebug("Item::LoadFromDB, Item GUID: %u: refund time expired, deleting refund data and removing refundable flag.", item->GetGUIDLow()); 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); item->RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE);
} }
else else
@@ -16839,8 +16856,9 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
draft.AddItem(item); 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()) //if (isAlive())
_ApplyAllItemMods(); _ApplyAllItemMods();
@@ -16854,6 +16872,7 @@ void Player::_LoadMailedItems(Mail *mail)
if (!result) if (!result)
return; return;
SQLTransaction trans = CharacterDatabase.BeginTransaction();
do do
{ {
Field *fields = result->Fetch(); Field *fields = result->Fetch();
@@ -16867,8 +16886,8 @@ void Player::_LoadMailedItems(Mail *mail)
if (!proto) 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); 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); trans->PAppend("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 item_instance WHERE guid = '%u'", item_guid_low);
continue; 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); 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); CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
item->FSetState(ITEM_REMOVED); item->FSetState(ITEM_REMOVED);
item->SaveToDB(); // it also deletes item object ! item->SaveToDB(trans); // it also deletes item object !
continue; continue;
} }
AddMItem(item); AddMItem(item);
} while (result->NextRow()); } while (result->NextRow());
CharacterDatabase.CommitTransaction(trans);
} }
void Player::_LoadMailInit(QueryResult_AutoPtr resultUnread, QueryResult_AutoPtr resultDelivery) void Player::_LoadMailInit(QueryResult_AutoPtr resultUnread, QueryResult_AutoPtr resultDelivery)
@@ -17737,36 +17758,36 @@ void Player::SaveToDB()
ss << uint32(GetByteValue(PLAYER_FIELD_BYTES, 2)); ss << uint32(GetByteValue(PLAYER_FIELD_BYTES, 2));
ss << ")"; 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 if (m_mailsUpdated) //save mails only when needed
_SaveMail(); _SaveMail(trans);
_SaveBGData(); _SaveBGData(trans);
_SaveInventory(); _SaveInventory(trans);
_SaveQuestStatus(); _SaveQuestStatus(trans);
_SaveDailyQuestStatus(); _SaveDailyQuestStatus(trans);
_SaveWeeklyQuestStatus(); _SaveWeeklyQuestStatus(trans);
_SaveTalents(); _SaveTalents(trans);
_SaveSpells(); _SaveSpells(trans);
_SaveSpellCooldowns(); _SaveSpellCooldowns(trans);
_SaveActions(); _SaveActions(trans);
_SaveAuras(); _SaveAuras(trans);
_SaveSkills(); _SaveSkills(trans);
m_achievementMgr.SaveToDB(); m_achievementMgr.SaveToDB(trans);
m_reputationMgr.SaveToDB(); m_reputationMgr.SaveToDB(trans);
_SaveEquipmentSets(); _SaveEquipmentSets(trans);
GetSession()->SaveTutorialsData(); // changed only while character in game GetSession()->SaveTutorialsData(trans); // changed only while character in game
_SaveGlyphs(); _SaveGlyphs(trans);
// check if stats should only be saved on logout // check if stats should only be saved on logout
// save stats can be out of transaction // save stats can be out of transaction
if (m_session->isLogingOut() || !sWorld.getConfig(CONFIG_STATS_SAVE_ONLY_ON_LOGOUT)) 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). // save pet (hunter pet level and experience and all type pets health/mana).
if (Pet* pet = GetPet()) 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 // fast save function for item/money cheating preventing - save only inventory and money state
void Player::SaveInventoryAndGoldToDB() void Player::SaveInventoryAndGoldToDB(SQLTransaction& trans)
{ {
_SaveInventory(); _SaveInventory(trans);
SaveGoldToDB(); 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();) for (ActionButtonList::iterator itr = m_actionButtons.begin(); itr != m_actionButtons.end();)
{ {
switch (itr->second.uState) switch (itr->second.uState)
{ {
case ACTIONBUTTON_NEW: 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()); GetGUIDLow(), m_activeSpec, (uint32)itr->first, (uint32)itr->second.GetAction(), (uint32)itr->second.GetType());
itr->second.uState = ACTIONBUTTON_UNCHANGED; itr->second.uState = ACTIONBUTTON_UNCHANGED;
++itr; ++itr;
break; break;
case ACTIONBUTTON_CHANGED: 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); (uint32)itr->second.GetAction(), (uint32)itr->second.GetType(), GetGUIDLow(), (uint32)itr->first, m_activeSpec);
itr->second.uState = ACTIONBUTTON_UNCHANGED; itr->second.uState = ACTIONBUTTON_UNCHANGED;
++itr; ++itr;
break; break;
case ACTIONBUTTON_DELETED: 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++); m_actionButtons.erase(itr++);
break; break;
default: 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) 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')", "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, GetGUIDLow(), itr->second->GetCasterGUID(), itr->second->GetId(), effMask, recalculateMask,
itr->second->GetStackAmount(), damage[0], damage[1], damage[2], baseDamage[0], baseDamage[1], baseDamage[2], 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 // force items in buyback slots to new state
// and remove those that aren't already // and remove those that aren't already
@@ -17864,8 +17885,8 @@ void Player::_SaveInventory()
Item *item = m_items[i]; Item *item = m_items[i];
if (!item || item->GetState() == ITEM_NEW) if (!item || item->GetState() == ITEM_NEW)
continue; continue;
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow()); trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item->GetGUIDLow()); trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", item->GetGUIDLow());
m_items[i]->FSetState(ITEM_NEW); m_items[i]->FSetState(ITEM_NEW);
} }
@@ -17942,25 +17963,25 @@ void Player::_SaveInventory()
switch (item->GetState()) switch (item->GetState())
{ {
case ITEM_NEW: 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; break;
case ITEM_CHANGED: case ITEM_CHANGED:
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow()); trans->PAppend("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("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; break;
case ITEM_REMOVED: 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; break;
case ITEM_UNCHANGED: case ITEM_UNCHANGED:
break; 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(); m_itemUpdateQueue.clear();
} }
void Player::_SaveMail() void Player::_SaveMail(SQLTransaction& trans)
{ {
if (!m_mailsLoaded) if (!m_mailsLoaded)
return; return;
@@ -17970,12 +17991,12 @@ void Player::_SaveMail()
Mail *m = (*itr); Mail *m = (*itr);
if (m->state == MAIL_STATE_CHANGED) 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); m->HasItems() ? 1 : 0, (uint64)m->expire_time, (uint64)m->deliver_time, m->money, m->COD, m->checked, m->messageID);
if (m->removedItems.size()) if (m->removedItems.size())
{ {
for (std::vector<uint32>::iterator itr2 = m->removedItems.begin(); itr2 != m->removedItems.end(); ++itr2) 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->removedItems.clear();
} }
m->state = MAIL_STATE_UNCHANGED; m->state = MAIL_STATE_UNCHANGED;
@@ -17984,9 +18005,9 @@ void Player::_SaveMail()
{ {
if (m->HasItems()) if (m->HasItems())
for (std::vector<MailItemInfo>::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2) 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); trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid);
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID); trans->PAppend("DELETE FROM mail WHERE id = '%u'", m->messageID);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_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; m_mailsUpdated = false;
} }
void Player::_SaveQuestStatus() void Player::_SaveQuestStatus(SQLTransaction& trans)
{ {
// we don't need transactions here. // we don't need transactions here.
for (QuestStatusMap::iterator i = mQuestStatus.begin(); i != mQuestStatus.end(); ++i) for (QuestStatusMap::iterator i = mQuestStatus.begin(); i != mQuestStatus.end(); ++i)
@@ -18015,12 +18036,12 @@ void Player::_SaveQuestStatus()
switch (i->second.uState) switch (i->second.uState)
{ {
case QUEST_NEW : 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')", "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]); 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; break;
case QUEST_CHANGED : 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); 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; break;
case QUEST_UNCHANGED: case QUEST_UNCHANGED:
@@ -18030,7 +18051,7 @@ void Player::_SaveQuestStatus()
} }
} }
void Player::_SaveDailyQuestStatus() void Player::_SaveDailyQuestStatus(SQLTransaction& trans)
{ {
if (!m_DailyQuestChanged) if (!m_DailyQuestChanged)
return; 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 // save last daily quest time for all quests: we need only mostly reset time for reset check anyway
// we don't need transactions here. // 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) 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)) 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)); 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()) if (!m_WeeklyQuestChanged || m_weeklyquests.empty())
return; return;
// we don't need transactions here. // 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) for (QuestSet::const_iterator iter = m_weeklyquests.begin(); iter != m_weeklyquests.end(); ++iter)
{ {
uint32 quest_id = *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; m_WeeklyQuestChanged = false;
} }
void Player::_SaveSkills() void Player::_SaveSkills(SQLTransaction& trans)
{ {
// we don't need transactions here. // we don't need transactions here.
for (SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end();) for (SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end();)
@@ -18078,7 +18099,7 @@ void Player::_SaveSkills()
if (itr->second.uState == SKILL_DELETED) 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++); mSkillStatus.erase(itr++);
continue; continue;
} }
@@ -18090,11 +18111,11 @@ void Player::_SaveSkills()
switch (itr->second.uState) switch (itr->second.uState)
{ {
case SKILL_NEW: 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); GetGUIDLow(), itr->first, value, max);
break; break;
case SKILL_CHANGED: 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); value, max, GetGUIDLow(), itr->first);
break; 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();) 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) 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 // add only changed/new not dependent spells
if (!itr->second->dependent && (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED)) 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) if (itr->second->state == PLAYERSPELL_REMOVED)
{ {
@@ -18131,13 +18152,13 @@ void Player::_SaveSpells()
// save player stats -- only for external usage // save player stats -- only for external usage
// real stats will be recalculated on player login // 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 // 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)) if (!sWorld.getConfig(CONFIG_MIN_LEVEL_STAT_SAVE) || getLevel() < sWorld.getConfig(CONFIG_MIN_LEVEL_STAT_SAVE))
return; return;
CharacterDatabase.PExecute("DELETE FROM character_stats WHERE guid = '%u'", GetGUIDLow()); trans->PAppend("DELETE FROM character_stats WHERE guid = '%u'", GetGUIDLow());
std::ostringstream ss; std::ostringstream ss;
ss << "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, " 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, " "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_ATTACK_POWER) << ", "
<< GetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) << ", " << GetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) << ", "
<< GetBaseSpellPowerBonus() << ")"; << GetBaseSpellPowerBonus() << ")";
CharacterDatabase.Execute(ss.str().c_str()); trans->Append(ss.str().c_str());
} }
void Player::outDebugValues() const 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.PExecute("DELETE FROM petition_sign WHERE playerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type);
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (type == 10) if (type == 10)
{ {
CharacterDatabase.PExecute("DELETE FROM petition WHERE ownerguid = '%u'", GUID_LOPART(guid)); trans->PAppend("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_sign WHERE ownerguid = '%u'", GUID_LOPART(guid));
} }
else else
{ {
CharacterDatabase.PExecute("DELETE FROM petition 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);
CharacterDatabase.PExecute("DELETE FROM petition_sign 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) void Player::LeaveAllArenaTeams(uint64 guid)
@@ -21507,13 +21528,14 @@ void Player::AutoUnequipOffhandIfNeed(bool force /*= false*/)
else else
{ {
MoveItemFromInventory(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true); MoveItemFromInventory(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true);
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
offItem->DeleteFromInventoryDB(); // deletes item from character's inventory offItem->DeleteFromInventoryDB(trans); // 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 offItem->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
CharacterDatabase.CommitTransaction();
std::string subject = GetSession()->GetTrinityString(LANG_NOT_EQUIPPED_ITEM); 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; 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();) for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end();)
{ {
@@ -23533,7 +23555,7 @@ void Player::_SaveEquipmentSets()
case EQUIPMENT_SET_CHANGED: case EQUIPMENT_SET_CHANGED:
CharacterDatabase.escape_string(eqset.Name); CharacterDatabase.escape_string(eqset.Name);
CharacterDatabase.escape_string(eqset.IconName); 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.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.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; eqset.state = EQUIPMENT_SET_UNCHANGED;
@@ -23542,27 +23564,27 @@ void Player::_SaveEquipmentSets()
case EQUIPMENT_SET_NEW: case EQUIPMENT_SET_NEW:
CharacterDatabase.escape_string(eqset.Name); CharacterDatabase.escape_string(eqset.Name);
CharacterDatabase.escape_string(eqset.IconName); 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], 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.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; eqset.state = EQUIPMENT_SET_UNCHANGED;
++itr; ++itr;
break; break;
case EQUIPMENT_SET_DELETED: 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++); m_EquipmentSets.erase(itr++);
break; 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) if (m_bgData.bgInstanceID)
{ {
/* guid, bgInstanceID, bgTeam, x, y, z, o, map, taxi[0], taxi[1], mountSpell */ /* 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(), 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); 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()); } 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) 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]); 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 (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
{ {
for (PlayerTalentMap::iterator itr = m_talents[i]->begin(); itr != m_talents[i]->end();) for (PlayerTalentMap::iterator itr = m_talents[i]->begin(); itr != m_talents[i]->end();)
{ {
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED) 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) 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) if (itr->second->state == PLAYERSPELL_REMOVED)
{ {
@@ -23701,23 +23723,26 @@ void Player::UpdateSpecCount(uint8 count)
if (m_activeSpec >= count) if (m_activeSpec >= count)
ActivateSpec(0); ActivateSpec(0);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// Copy spec data // Copy spec data
if (count > curCount) 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) 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); GetGUIDLow(), uint32(itr->first), uint32(itr->second.GetAction()), uint32(itr->second.GetType()), 1);
} }
// Delete spec data for removed spec. // Delete spec data for removed spec.
else if (count < curCount) else if (count < curCount)
{ {
_SaveActions(); _SaveActions(trans);
CharacterDatabase.PExecute("DELETE FROM character_action WHERE spec<>'%u' AND guid='%u'",m_activeSpec, GetGUIDLow()); trans->PAppend("DELETE FROM character_action WHERE spec<>'%u' AND guid='%u'",m_activeSpec, GetGUIDLow());
m_activeSpec = 0; m_activeSpec = 0;
} }
CharacterDatabase.CommitTransaction(trans);
SetSpecsCount(count); SetSpecsCount(count);
@@ -23740,7 +23765,9 @@ void Player::ActivateSpec(uint8 spec)
if (IsNonMeleeSpellCasted(false)) if (IsNonMeleeSpellCasted(false))
InterruptNonMeleeSpells(false); InterruptNonMeleeSpells(false);
_SaveActions(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
_SaveActions(trans);
CharacterDatabase.CommitTransaction(trans);
UnsummonPetTemporaryIfAny(); UnsummonPetTemporaryIfAny();
ClearComboPointHolders(); ClearComboPointHolders();
+18 -17
View File
@@ -1422,8 +1422,9 @@ class Player : public Unit, public GridObject<Player>
/*********************************************************/ /*********************************************************/
void SaveToDB(); void SaveToDB();
void SaveInventoryAndGoldToDB(); // fast save function for item/money cheating preventing void SaveInventoryAndGoldToDB(SQLTransaction& trans); // fast save function for item/money cheating preventing
void SaveGoldToDB(); void SaveGoldToDB(SQLTransaction& trans);
static void SetUInt32ValueInArray(Tokens& data,uint16 index, uint32 value); static void SetUInt32ValueInArray(Tokens& data,uint16 index, uint32 value);
static void SetFloatValueInArray(Tokens& data,uint16 index, float 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); 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 RemoveArenaSpellCooldowns();
void RemoveAllSpellCooldown(); void RemoveAllSpellCooldown();
void _LoadSpellCooldowns(QueryResult_AutoPtr result); void _LoadSpellCooldowns(QueryResult_AutoPtr result);
void _SaveSpellCooldowns(); void _SaveSpellCooldowns(SQLTransaction& trans);
void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; } void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; }
void UpdatePotionCooldown(Spell* spell = NULL); void UpdatePotionCooldown(Spell* spell = NULL);
@@ -2428,20 +2429,20 @@ class Player : public Unit, public GridObject<Player>
/*** SAVE SYSTEM ***/ /*** SAVE SYSTEM ***/
/*********************************************************/ /*********************************************************/
void _SaveActions(); void _SaveActions(SQLTransaction& trans);
void _SaveAuras(); void _SaveAuras(SQLTransaction& trans);
void _SaveInventory(); void _SaveInventory(SQLTransaction& trans);
void _SaveMail(); void _SaveMail(SQLTransaction& trans);
void _SaveQuestStatus(); void _SaveQuestStatus(SQLTransaction& trans);
void _SaveDailyQuestStatus(); void _SaveDailyQuestStatus(SQLTransaction& trans);
void _SaveWeeklyQuestStatus(); void _SaveWeeklyQuestStatus(SQLTransaction& trans);
void _SaveSkills(); void _SaveSkills(SQLTransaction& trans);
void _SaveSpells(); void _SaveSpells(SQLTransaction& trans);
void _SaveEquipmentSets(); void _SaveEquipmentSets(SQLTransaction& trans);
void _SaveBGData(); void _SaveBGData(SQLTransaction& trans);
void _SaveGlyphs(); void _SaveGlyphs(SQLTransaction& trans);
void _SaveTalents(); void _SaveTalents(SQLTransaction& trans);
void _SaveStats(); void _SaveStats(SQLTransaction& trans);
void _SetCreateBits(UpdateMask *updateMask, Player *target) const; void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
void _SetUpdateBits(UpdateMask *updateMask, Player *target) const; void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;
+13 -13
View File
@@ -181,10 +181,10 @@ void GameEventMgr::StopEvent(uint16 event_id, bool overwrite)
std::map<uint32 /*condition id*/, GameEventFinishCondition>::iterator itr; std::map<uint32 /*condition id*/, GameEventFinishCondition>::iterator itr;
for (itr = mGameEvent[event_id].conditions.begin(); itr != mGameEvent[event_id].conditions.end(); ++itr) for (itr = mGameEvent[event_id].conditions.begin(); itr != mGameEvent[event_id].conditions.end(); ++itr)
itr->second.done = 0; itr->second.done = 0;
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM game_event_save WHERE event_id = '%u'",event_id); trans->PAppend("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); trans->PAppend("DELETE FROM game_event_condition_save WHERE event_id = '%u'",event_id);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
} }
} }
@@ -1627,10 +1627,10 @@ void GameEventMgr::HandleQuestComplete(uint32 quest_id)
if (citr->second.done > citr->second.reqNum) if (citr->second.done > citr->second.reqNum)
citr->second.done = citr->second.reqNum; citr->second.done = citr->second.reqNum;
// save the change to db // save the change to db
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM game_event_condition_save WHERE event_id = '%u' AND condition_id = '%u'",event_id,condition); trans->PAppend("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); 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(); CharacterDatabase.CommitTransaction(trans);
// check if all conditions are met, if so, update the event state // check if all conditions are met, if so, update the event state
if (CheckOneGameEventConditions(event_id)) if (CheckOneGameEventConditions(event_id))
{ {
@@ -1663,13 +1663,13 @@ bool GameEventMgr::CheckOneGameEventConditions(uint16 event_id)
void GameEventMgr::SaveWorldEventStateToDB(uint16 event_id) void GameEventMgr::SaveWorldEventStateToDB(uint16 event_id)
{ {
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM game_event_save WHERE event_id = '%u'",event_id); trans->PAppend("DELETE FROM game_event_save WHERE event_id = '%u'",event_id);
if (mGameEvent[event_id].nextstart) 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 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); 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(); CharacterDatabase.CommitTransaction(trans);
} }
void GameEventMgr::HandleWorldEventGossip(Player *plr, Creature *c) void GameEventMgr::HandleWorldEventGossip(Player *plr, Creature *c)
+3 -1
View File
@@ -295,7 +295,9 @@ Corpse* ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool /*insign
// map->Remove(corpse, false); // map->Remove(corpse, false);
// remove corpse from DB // 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.. :) // we don't want bones to save some cpu.. :)
delete corpse; delete corpse;
+4 -3
View File
@@ -9040,9 +9040,10 @@ void ObjectMgr::_AddOrUpdateGMTicket(GM_Ticket &ticket)
ss << ticket.closed << "', '"; ss << ticket.closed << "', '";
ss << ticket.assignedToGM << "', '"; ss << ticket.assignedToGM << "', '";
ss << comment << "');"; ss << comment << "');";
CharacterDatabase.BeginTransaction();
CharacterDatabase.Execute(ss.str().c_str()); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.CommitTransaction(); trans->Append(ss.str().c_str());
CharacterDatabase.CommitTransaction(trans);
} }
void ObjectMgr::RemoveGMTicket(GM_Ticket *ticket, int64 source, bool permanently) void ObjectMgr::RemoveGMTicket(GM_Ticket *ticket, int64 source, bool permanently)
+17 -18
View File
@@ -116,20 +116,19 @@ bool Group::Create(const uint64 &guid, const char * name)
Player::ConvertInstancesToGroup(leader, this, guid); Player::ConvertInstancesToGroup(leader, this, guid);
if (!AddMember(guid, name))
return false;
// store group in database // store group in database
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM groups WHERE guid ='%u'", lowguid); trans->PAppend("DELETE FROM groups WHERE guid ='%u'", lowguid);
CharacterDatabase.PExecute("DELETE FROM group_member WHERE guid ='%u'", lowguid); trans->PAppend("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) " 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')", "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), 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); 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.CommitTransaction(trans);
CharacterDatabase.RollbackTransaction();
return false;
}
CharacterDatabase.CommitTransaction();
} }
else if (!AddMember(guid, name)) else if (!AddMember(guid, name))
return false; return false;
@@ -497,10 +496,10 @@ void Group::Disband(bool hideDestroy)
if (!isBGGroup()) if (!isBGGroup())
{ {
uint32 lowguid = GUID_LOPART(m_guid); uint32 lowguid = GUID_LOPART(m_guid);
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM groups WHERE guid=%u", lowguid); trans->PAppend("DELETE FROM groups WHERE guid=%u", lowguid);
CharacterDatabase.PExecute("DELETE FROM group_member WHERE guid=%u", lowguid); trans->PAppend("DELETE FROM group_member WHERE guid=%u", lowguid);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL);
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL);
} }
@@ -1334,14 +1333,14 @@ void Group::_setLeader(const uint64 &guid)
if (!isBGGroup()) if (!isBGGroup())
{ {
// TODO: set a time limit to have this function run rarely cause it can be slow // 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 // update the group's bound instances when changing leaders
// remove all permanent binds from the group // remove all permanent binds from the group
// in the DB also remove solo binds that will be replaced with permbinds // in the DB also remove solo binds that will be replaced with permbinds
// from the new leader // from the new leader
CharacterDatabase.PExecute( trans->PAppend(
"DELETE FROM group_instance WHERE guid=%u AND (permanent = 1 OR " "DELETE FROM group_instance WHERE guid=%u AND (permanent = 1 OR "
"instance IN (SELECT instance FROM character_instance WHERE guid = '%u')" "instance IN (SELECT instance FROM character_instance WHERE guid = '%u')"
")", GUID_LOPART(m_guid), GUID_LOPART(slot->guid) ")", GUID_LOPART(m_guid), GUID_LOPART(slot->guid)
@@ -1371,8 +1370,8 @@ void Group::_setLeader(const uint64 &guid)
Player::ConvertInstancesToGroup(player, this, slot->guid); Player::ConvertInstancesToGroup(player, this, slot->guid);
// update the group leader // update the group leader
CharacterDatabase.PExecute("UPDATE groups SET leaderGuid='%u' WHERE guid='%u'", GUID_LOPART(slot->guid), GUID_LOPART(m_guid)); trans->PAppend("UPDATE groups SET leaderGuid='%u' WHERE guid='%u'", GUID_LOPART(slot->guid), GUID_LOPART(m_guid));
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
m_leaderGuid = slot->guid; m_leaderGuid = slot->guid;
+101 -101
View File
@@ -88,13 +88,13 @@ bool Guild::Create(Player* leader, std::string gname)
CharacterDatabase.escape_string(dbGINFO); CharacterDatabase.escape_string(dbGINFO);
CharacterDatabase.escape_string(dbMOTD); 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 WHERE guildid='%u'", Id); - MAX(guildid)+1 not exist
CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guildid='%u'", m_Id); trans->PAppend("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("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 "')", "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); 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()); CreateDefaultGuildRanks(lSession->GetSessionDbLocaleIndex());
@@ -335,16 +335,16 @@ bool Guild::LoadRanksFromDB(QueryResult_AutoPtr guildRanksResult)
if (broken_ranks) if (broken_ranks)
{ {
sLog.outError("Guild %u has broken `guild_rank` data, repairing...", m_Id); sLog.outError("Guild %u has broken `guild_rank` data, repairing...", m_Id);
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid='%u'", m_Id); trans->PAppend("DELETE FROM guild_rank WHERE guildid='%u'", m_Id);
for (size_t i = 0; i < m_Ranks.size(); ++i) for (size_t i = 0; i < m_Ranks.size(); ++i)
{ {
std::string name = m_Ranks[i].Name; std::string name = m_Ranks[i].Name;
uint32 rights = m_Ranks[i].Rights; uint32 rights = m_Ranks[i].Rights;
CharacterDatabase.escape_string(name); 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; return true;
@@ -710,19 +710,19 @@ void Guild::Disband()
DelMember(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER), true); DelMember(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER), true);
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM guild WHERE guildid = '%u'", m_Id); trans->PAppend("DELETE FROM guild WHERE guildid = '%u'", m_Id);
CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid = '%u'", m_Id); trans->PAppend("DELETE FROM guild_rank WHERE guildid = '%u'", m_Id);
CharacterDatabase.PExecute("DELETE FROM guild_bank_tab 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 //Free bank tab used memory and delete items stored in them
DeleteGuildBankItems(true); DeleteGuildBankItems(true);
CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid = '%u'", m_Id); trans->PAppend("DELETE FROM guild_bank_item WHERE guildid = '%u'", m_Id);
CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid = '%u'", m_Id); trans->PAppend("DELETE FROM guild_bank_right WHERE guildid = '%u'", m_Id);
CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid = '%u'", m_Id); trans->PAppend("DELETE FROM guild_bank_eventlog WHERE guildid = '%u'", m_Id);
CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid = '%u'", m_Id); trans->PAppend("DELETE FROM guild_eventlog WHERE guildid = '%u'", m_Id);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
sObjectMgr.RemoveGuild(m_Id); sObjectMgr.RemoveGuild(m_Id);
} }
@@ -1093,10 +1093,10 @@ void Guild::CreateNewBankTab()
uint32 tabId = GetPurchasedTabs(); // next free id uint32 tabId = GetPurchasedTabs(); // next free id
m_TabListMap.push_back(new GuildBankTab); m_TabListMap.push_back(new GuildBankTab);
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid='%u' AND TabId='%u'", m_Id, tabId); trans->PAppend("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); trans->PAppend("INSERT INTO guild_bank_tab (guildid,TabId) VALUES ('%u','%u')", m_Id, tabId);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
void Guild::SetGuildBankTabInfo(uint8 TabId, std::string Name, std::string Icon) 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"); 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); uint32 MoneyWithDrawRight = GetMemberMoneyWithdrawRem(LowGuid);
if (MoneyWithDrawRight < amount || GetGuildBankMoney() < amount) if (MoneyWithDrawRight < amount || GetGuildBankMoney() < amount)
return false; return false;
SetBankMoney(GetGuildBankMoney()-amount); SetBankMoney(GetGuildBankMoney()-amount, trans);
if (MoneyWithDrawRight < WITHDRAW_MONEY_UNLIMITED) if (MoneyWithDrawRight < WITHDRAW_MONEY_UNLIMITED)
{ {
@@ -1227,25 +1227,25 @@ bool Guild::MemberMoneyWithdraw(uint32 amount, uint32 LowGuid)
if (itr == members.end()) if (itr == members.end())
return false; return false;
itr->second.BankRemMoney -= amount; 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); itr->second.BankRemMoney, m_Id, LowGuid);
} }
return true; 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!! if (money < 0) // I don't know how this happens, it does!!
money = 0; money = 0;
m_GuildBankMoney = money; 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 // 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); uint32 SlotsWithDrawRight = GetMemberSlotWithdrawRem(LowGuid, TabId);
@@ -1258,7 +1258,7 @@ bool Guild::MemberItemWithdraw(uint8 TabId, uint32 LowGuid)
if (itr == members.end()) if (itr == members.end())
return false; return false;
--itr->second.BankRemSlotsTab[TabId]; --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); uint32(TabId), itr->second.BankRemSlotsTab[TabId], m_Id, LowGuid);
} }
return true; return true;
@@ -1552,7 +1552,7 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
sLog.outDebug("WORLD: Sent (MSG_GUILD_BANK_LOG_QUERY)"); 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 //create Event
GuildBankEventLogEntry NewEvent; GuildBankEventLogEntry NewEvent;
@@ -1587,9 +1587,9 @@ void Guild::LogBankEvent(uint8 EventType, uint8 TabId, uint32 PlayerGuidLow, uin
} }
//save event to database //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); 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) if (!pItem)
return NULL; return NULL;
@@ -1653,18 +1653,18 @@ Item* Guild::StoreItem(uint8 tabId, GuildItemPosCountVec const& dest, Item* pIte
if (itr == dest.end()) if (itr == dest.end())
{ {
lastItem = _StoreItem(tabId, slot, pItem, count, false); lastItem = _StoreItem(tabId, slot, pItem, count, false, trans);
break; break;
} }
lastItem = _StoreItem(tabId, slot, pItem, count, true); lastItem = _StoreItem(tabId, slot, pItem, count, true, trans);
} }
return lastItem; return lastItem;
} }
// Return stored item (if stored to stack, it can diff. from pItem). And pItem ca be deleted in this case. // 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) if (!pItem)
return NULL; 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); pItem->SetUInt64Value(ITEM_FIELD_OWNER, 0);
AddGBankItemToDB(GetId(), tab, slot, pItem->GetGUIDLow(), pItem->GetEntry()); AddGBankItemToDB(GetId(), tab, slot, pItem->GetGUIDLow(), pItem->GetEntry());
pItem->FSetState(ITEM_NEW); 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; 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->SetCount(pItem2->GetCount() + count);
pItem2->FSetState(ITEM_CHANGED); 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) if (!clone)
{ {
pItem->RemoveFromWorld(); pItem->RemoveFromWorld();
pItem->DeleteFromDB(); pItem->DeleteFromDB(trans);
delete pItem; 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; 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)); GetId(), uint32(tab), uint32(slot));
} }
@@ -1954,15 +1954,15 @@ void Guild::SwapItems(Player * pl, uint8 BankTab, uint8 BankTabSlot, uint8 BankT
return; return;
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), SplitedAmount, BankTabDst); LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), SplitedAmount, BankTabDst);
pl->ItemRemovedQuestCheck(pItemSrc->GetEntry(), SplitedAmount); pl->ItemRemovedQuestCheck(pItemSrc->GetEntry(), SplitedAmount);
pItemSrc->SetCount(pItemSrc->GetCount() - SplitedAmount); pItemSrc->SetCount(pItemSrc->GetCount() - SplitedAmount);
pItemSrc->FSetState(ITEM_CHANGED); pItemSrc->FSetState(ITEM_CHANGED);
pItemSrc->SaveToDB(); // not in inventory and can be save standalone pItemSrc->SaveToDB(trans); // not in inventory and can be save standalone
StoreItem(BankTabDst, dest, pNewItem); StoreItem(BankTabDst, dest, pNewItem, trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
else // non split 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); uint8 msg = CanStoreItem(BankTabDst, BankTabSlotDst, gDest, pItemSrc->GetCount(), pItemSrc, false);
if (msg == EQUIP_ERR_OK) // merge to if (msg == EQUIP_ERR_OK) // merge to
{ {
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst); LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst);
RemoveItem(BankTab, BankTabSlot); RemoveItem(BankTab, BankTabSlot, trans);
StoreItem(BankTabDst, gDest, pItemSrc); StoreItem(BankTabDst, gDest, pItemSrc, trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
else // swap else // swap
{ {
@@ -2007,15 +2007,15 @@ void Guild::SwapItems(Player * pl, uint8 BankTab, uint8 BankTabSlot, uint8 BankT
return; return;
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
LogBankEvent(GUILD_BANK_LOG_MOVE_ITEM, BankTab, pl->GetGUIDLow(), pItemSrc->GetEntry(), pItemSrc->GetCount(), BankTabDst); LogBankEvent(trans, 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); LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, BankTabDst, pl->GetGUIDLow(), pItemDst->GetEntry(), pItemDst->GetCount(), BankTab);
RemoveItem(BankTab, BankTabSlot); RemoveItem(BankTab, BankTabSlot, trans);
RemoveItem(BankTabDst, BankTabSlotDst); RemoveItem(BankTabDst, BankTabSlotDst, trans);
StoreItem(BankTab, gSrc, pItemDst); StoreItem(BankTab, gSrc, pItemDst, trans);
StoreItem(BankTabDst, gDest, pItemSrc); StoreItem(BankTabDst, gDest, pItemSrc, trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
} }
DisplayGuildBankContentUpdate(BankTab,BankTabSlot,BankTab == BankTabDst ? BankTabSlotDst : -1); DisplayGuildBankContentUpdate(BankTab,BankTabSlot,BankTab == BankTabDst ? BankTabSlotDst : -1);
@@ -2062,17 +2062,17 @@ void Guild::MoveFromBankToChar(Player * pl, uint8 BankTab, uint8 BankTabSlot, ui
return; return;
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), SplitedAmount); LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), SplitedAmount);
pItemBank->SetCount(pItemBank->GetCount()-SplitedAmount); pItemBank->SetCount(pItemBank->GetCount()-SplitedAmount);
pItemBank->FSetState(ITEM_CHANGED); 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->MoveItemToInventory(dest, pNewItem, true);
pl->SaveInventoryAndGoldToDB(); pl->SaveInventoryAndGoldToDB(trans);
MemberItemWithdraw(BankTab, pl->GetGUIDLow()); MemberItemWithdraw(BankTab, pl->GetGUIDLow(), trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
else // Bank -> Char swap with slot (move) else // Bank -> Char swap with slot (move)
{ {
@@ -2085,15 +2085,15 @@ void Guild::MoveFromBankToChar(Player * pl, uint8 BankTab, uint8 BankTabSlot, ui
if (remRight <= 0) if (remRight <= 0)
return; return;
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount()); 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->MoveItemToInventory(dest, pItemBank, true);
pl->SaveInventoryAndGoldToDB(); pl->SaveInventoryAndGoldToDB(trans);
MemberItemWithdraw(BankTab, pl->GetGUIDLow()); MemberItemWithdraw(BankTab, pl->GetGUIDLow(), trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
else // Bank <-> Char swap items else // Bank <-> Char swap items
{ {
@@ -2146,25 +2146,25 @@ void Guild::MoveFromBankToChar(Player * pl, uint8 BankTab, uint8 BankTabSlot, ui
} }
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount()); LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount());
if (pItemChar) 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) if (pItemChar)
{ {
pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true); pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
pItemChar->DeleteFromInventoryDB(); pItemChar->DeleteFromInventoryDB(trans);
} }
if (pItemChar) if (pItemChar)
StoreItem(BankTab, gDest, pItemChar); StoreItem(BankTab, gDest, pItemChar, trans);
pl->MoveItemToInventory(iDest, pItemBank, true); pl->MoveItemToInventory(iDest, pItemBank, true);
pl->SaveInventoryAndGoldToDB(); pl->SaveInventoryAndGoldToDB(trans);
MemberItemWithdraw(BankTab, pl->GetGUIDLow()); MemberItemWithdraw(BankTab, pl->GetGUIDLow(), trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
} }
DisplayGuildBankContentUpdate(BankTab,BankTabSlot); 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); pItemChar->GetProto()->Name1, pItemChar->GetEntry(), SplitedAmount,m_Id);
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
LogBankEvent(GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), SplitedAmount); LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), SplitedAmount);
pl->ItemRemovedQuestCheck(pItemChar->GetEntry(), SplitedAmount); pl->ItemRemovedQuestCheck(pItemChar->GetEntry(), SplitedAmount);
pItemChar->SetCount(pItemChar->GetCount()-SplitedAmount); pItemChar->SetCount(pItemChar->GetCount()-SplitedAmount);
pItemChar->SetState(ITEM_CHANGED, pl); pItemChar->SetState(ITEM_CHANGED, pl);
pl->SaveInventoryAndGoldToDB(); pl->SaveInventoryAndGoldToDB(trans);
StoreItem(BankTab, dest, pNewItem); StoreItem(BankTab, dest, pNewItem, trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
DisplayGuildBankContentUpdate(BankTab, dest); DisplayGuildBankContentUpdate(BankTab, dest);
} }
@@ -2245,15 +2245,15 @@ void Guild::MoveFromCharToBank(Player * pl, uint8 PlayerBag, uint8 PlayerSlot, u
m_Id); m_Id);
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
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());
pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true); pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
pItemChar->DeleteFromInventoryDB(); pItemChar->DeleteFromInventoryDB(trans);
StoreItem(BankTab, dest, pItemChar); StoreItem(BankTab, dest, pItemChar, trans);
pl->SaveInventoryAndGoldToDB(); pl->SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
DisplayGuildBankContentUpdate(BankTab, dest); DisplayGuildBankContentUpdate(BankTab, dest);
} }
@@ -2295,23 +2295,23 @@ void Guild::MoveFromCharToBank(Player * pl, uint8 PlayerBag, uint8 PlayerSlot, u
m_Id); m_Id);
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (pItemBank) if (pItemBank)
LogBankEvent(GUILD_BANK_LOG_WITHDRAW_ITEM, BankTab, pl->GetGUIDLow(), pItemBank->GetEntry(), pItemBank->GetCount()); LogBankEvent(trans, 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_DEPOSIT_ITEM, BankTab, pl->GetGUIDLow(), pItemChar->GetEntry(), pItemChar->GetCount());
pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true); pl->MoveItemFromInventory(PlayerBag, PlayerSlot, true);
pItemChar->DeleteFromInventoryDB(); pItemChar->DeleteFromInventoryDB(trans);
if (pItemBank) if (pItemBank)
RemoveItem(BankTab, BankTabSlot); RemoveItem(BankTab, BankTabSlot, trans);
StoreItem(BankTab,gDest,pItemChar); StoreItem(BankTab,gDest,pItemChar, trans);
if (pItemBank) if (pItemBank)
pl->MoveItemToInventory(iDest, pItemBank, true); pl->MoveItemToInventory(iDest, pItemBank, true);
pl->SaveInventoryAndGoldToDB(); pl->SaveInventoryAndGoldToDB(trans);
if (pItemBank) if (pItemBank)
MemberItemWithdraw(BankTab, pl->GetGUIDLow()); MemberItemWithdraw(BankTab, pl->GetGUIDLow(), trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
DisplayGuildBankContentUpdate(BankTab, gDest); DisplayGuildBankContentUpdate(BankTab, gDest);
} }
@@ -2350,7 +2350,7 @@ void Guild::BroadcastEvent(GuildEvents event, uint64 guid, uint8 strCount, std::
sLog.outDebug("WORLD: Sent SMSG_GUILD_EVENT"); 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) for (size_t i = 0; i < m_TabListMap.size(); ++i)
{ {
@@ -2361,7 +2361,7 @@ void Guild::DeleteGuildBankItems( bool alsoInDB /*= false*/ )
pItem->RemoveFromWorld(); pItem->RemoveFromWorld();
if (alsoInDB) if (alsoInDB)
pItem->DeleteFromDB(); pItem->DeleteFromDB(trans);
delete pItem; delete pItem;
} }
+8 -8
View File
@@ -294,7 +294,7 @@ class Guild
void CreateDefaultGuildRanks(int locale_idx); void CreateDefaultGuildRanks(int locale_idx);
void Disband(); void Disband();
void DeleteGuildBankItems(bool alsoInDB = false); void DeleteGuildBankItems(bool alsoInDB = false, SQLTransaction& trans = SQLTransaction(NULL));
typedef std::map<uint32, MemberSlot> MemberList; typedef std::map<uint32, MemberSlot> MemberList;
typedef std::vector<RankInfo> RankList; typedef std::vector<RankInfo> RankList;
@@ -412,11 +412,11 @@ class Guild
void LoadGuildBankFromDB(); void LoadGuildBankFromDB();
// Money deposit/withdraw // Money deposit/withdraw
void SendMoneyInfo(WorldSession *session, uint32 LowGuid); 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; } uint64 GetGuildBankMoney() { return m_GuildBankMoney; }
void SetBankMoney(int64 money); void SetBankMoney(int64 money, SQLTransaction& trans);
// per days // per days
bool MemberItemWithdraw(uint8 TabId, uint32 LowGuid); bool MemberItemWithdraw(uint8 TabId, uint32 LowGuid, SQLTransaction& trans);
uint32 GetMemberSlotWithdrawRem(uint32 LowGuid, uint8 TabId); uint32 GetMemberSlotWithdrawRem(uint32 LowGuid, uint8 TabId);
uint32 GetMemberMoneyWithdrawRem(uint32 LowGuid); uint32 GetMemberMoneyWithdrawRem(uint32 LowGuid);
void SetBankMoneyPerDay(uint32 rankId, uint32 money); void SetBankMoneyPerDay(uint32 rankId, uint32 money);
@@ -428,7 +428,7 @@ class Guild
// Guild Bank Event Logs // Guild Bank Event Logs
void LoadGuildBankEventLogFromDB(); void LoadGuildBankEventLogFromDB();
void DisplayGuildBankLogs(WorldSession *session, uint8 TabId); 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); bool AddGBankItemToDB(uint32 GuildId, uint32 BankTab , uint32 BankTabSlot , uint32 GUIDLow, uint32 Entry);
protected: protected:
@@ -473,8 +473,8 @@ class Guild
// used only from high level Swap/Move functions // used only from high level Swap/Move functions
Item* GetItem(uint8 TabId, uint8 SlotId); Item* GetItem(uint8 TabId, uint8 SlotId);
uint8 CanStoreItem(uint8 tab, uint8 slot, GuildItemPosCountVec& dest, uint32 count, Item *pItem, bool swap = false) const; 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); Item* StoreItem(uint8 tab, GuildItemPosCountVec const& pos, Item *pItem, SQLTransaction& trans);
void RemoveItem(uint8 tab, uint8 slot); void RemoveItem(uint8 tab, uint8 slot, SQLTransaction& trans);
void DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2 = -1); void DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2 = -1);
void DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec const& slots); void DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec const& slots);
@@ -482,6 +482,6 @@ class Guild
void AppendDisplayGuildBankSlot(WorldPacket& data, GuildBankTab const *tab, int32 slot); 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_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; 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 #endif
+10 -10
View File
@@ -124,11 +124,11 @@ InstanceSave *InstanceSaveManager::GetInstanceSave(uint32 InstanceId)
void InstanceSaveManager::DeleteInstanceFromDB(uint32 instanceid) void InstanceSaveManager::DeleteInstanceFromDB(uint32 instanceid)
{ {
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'", instanceid); trans->PAppend("DELETE FROM instance WHERE id = '%u'", instanceid);
CharacterDatabase.PExecute("DELETE FROM character_instance WHERE instance = '%u'", instanceid); trans->PAppend("DELETE FROM character_instance WHERE instance = '%u'", instanceid);
CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", instanceid); trans->PAppend("DELETE FROM group_instance WHERE instance = '%u'", instanceid);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
// respawn times should be deleted only when the map gets unloaded // 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 // delete them from the DB, even if not loaded
CharacterDatabase.BeginTransaction(); SQLTransaction trans = 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); 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);
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); 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);
CharacterDatabase.PExecute("DELETE FROM instance WHERE map = '%u' and difficulty='%u'", mapid, difficulty); trans->PAppend("DELETE FROM instance WHERE map = '%u' and difficulty='%u'", mapid, difficulty);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
// calculate the next reset time // calculate the next reset time
uint32 diff = sWorld.getConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; uint32 diff = sWorld.getConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR;
+38 -38
View File
@@ -245,6 +245,8 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data)
MailDraft draft(subject, body); MailDraft draft(subject, body);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (items_count > 0 || money > 0) if (items_count > 0 || money > 0)
{ {
if (items_count > 0) if (items_count > 0)
@@ -260,12 +262,11 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data)
item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable
pl->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true); pl->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true);
CharacterDatabase.BeginTransaction();
item->DeleteFromInventoryDB(); // deletes item from character's inventory item->DeleteFromInventoryDB(trans); // 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->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 // 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()); trans->PAppend("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", GUID_LOPART(rc), item->GetGUIDLow());
CharacterDatabase.CommitTransaction();
draft.AddItem(item); draft.AddItem(item);
} }
@@ -287,11 +288,10 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data)
draft draft
.AddMoney(money) .AddMoney(money)
.AddCOD(COD) .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(trans);
pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(trans);
CharacterDatabase.CommitTransaction();
} }
//called when mail is read //called when mail is read
@@ -366,10 +366,10 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data)
} }
//we can return mail now //we can return mail now
//so firstly delete the old one //so firstly delete the old one
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", mailId); // needed? trans->PAppend("DELETE FROM mail WHERE id = '%u'", mailId); // needed?
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", mailId); trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", mailId);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
pl->RemoveMail(mailId); pl->RemoveMail(mailId);
// only return mail if the player exists (and delete if not existing) // 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); uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, it, false);
if (msg == EQUIP_ERR_OK) if (msg == EQUIP_ERR_OK)
{ {
SQLTransaction trans = CharacterDatabase.BeginTransaction();
m->RemoveItem(itemId); m->RemoveItem(itemId);
m->removedItems.push_back(itemId); m->removedItems.push_back(itemId);
@@ -473,7 +474,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data)
{ {
MailDraft(m->subject, "") MailDraft(m->subject, "")
.AddMoney(m->COD) .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)); 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 uint32 count = it->GetCount(); // save counts before store and possible merge with deleting
pl->MoveItemToInventory(dest,it,true); pl->MoveItemToInventory(dest,it,true);
CharacterDatabase.BeginTransaction(); pl->SaveInventoryAndGoldToDB(trans);
pl->SaveInventoryAndGoldToDB(); pl->_SaveMail(trans);
pl->_SaveMail(); CharacterDatabase.CommitTransaction(trans);
CharacterDatabase.CommitTransaction();
pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemId, count); 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; pl->m_mailsUpdated = true;
// save money and mail to prevent cheating // save money and mail to prevent cheating
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
pl->SaveGoldToDB(); pl->SaveGoldToDB(trans);
pl->_SaveMail(); pl->_SaveMail(trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
//called when player lists his received mails //called when player lists his received mails
@@ -826,7 +826,7 @@ MailDraft& MailDraft::AddItem(Item* item)
m_items[item->GetGUIDLow()] = item; return *this; m_items[item->GetGUIDLow()] = item; return *this;
} }
void MailDraft::prepareItems(Player* receiver) void MailDraft::prepareItems(Player* receiver, SQLTransaction& trans)
{ {
if (!m_mailTemplateId || !m_mailTemplateItemsNeed) if (!m_mailTemplateId || !m_mailTemplateItemsNeed)
return; return;
@@ -845,21 +845,21 @@ void MailDraft::prepareItems(Player* receiver)
{ {
if (Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,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); 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) for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
{ {
Item* item = mailItemIter->second; Item* item = mailItemIter->second;
if (inDB) 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; delete item;
} }
@@ -875,9 +875,11 @@ void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32
if (!receiver) if (!receiver)
rc_account = sObjectMgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER)); rc_account = sObjectMgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(receiver_guid, 0, HIGHGUID_PLAYER));
SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (!receiver && !rc_account) // sender not exist if (!receiver && !rc_account) // sender not exist
{ {
deleteIncludedItems(true); deleteIncludedItems(true, trans);
return; return;
} }
@@ -890,30 +892,29 @@ void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32
needItemDelay = sender_acc != rc_account; needItemDelay = sender_acc != rc_account;
// set owner to new receiver (to prevent delete item with sender char deleting) // 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) for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
{ {
Item* item = mailItemIter->second; 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 // 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. // If theres is an item, there is a one hour delivery delay.
uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0; uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
// will delete item or place to receiver mail list // 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 Player* pReceiver = receiver.GetPlayer(); // can be NULL
if (pReceiver) if (pReceiver)
prepareItems(pReceiver); // generate mail template items prepareItems(pReceiver, trans); // generate mail template items
uint32 mailId = sObjectMgr.GenerateMailID(); uint32 mailId = sObjectMgr.GenerateMailID();
@@ -937,20 +938,19 @@ void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sende
// Add to DB // Add to DB
std::string safe_subject = GetSubject(); std::string safe_subject = GetSubject();
std::string safe_body = GetBody(); std::string safe_body = GetBody();
CharacterDatabase.BeginTransaction();
CharacterDatabase.escape_string(safe_subject); CharacterDatabase.escape_string(safe_subject);
CharacterDatabase.escape_string(safe_body); 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')", "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); 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) for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
{ {
Item* item = mailItemIter->second; 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 // For online receiver update in game mail status and data
if (pReceiver) if (pReceiver)
+6 -3
View File
@@ -128,16 +128,19 @@ class MailDraft
uint32 GetMoney() const { return m_money; } uint32 GetMoney() const { return m_money; }
uint32 GetCOD() const { return m_COD; } uint32 GetCOD() const { return m_COD; }
std::string const& GetBody() const { return m_body; } std::string const& GetBody() const { return m_body; }
public: // modifiers public: // modifiers
MailDraft& AddItem(Item* item); MailDraft& AddItem(Item* item);
MailDraft& AddMoney(uint32 money) { m_money = money; return *this; } MailDraft& AddMoney(uint32 money) { m_money = money; return *this; }
MailDraft& AddCOD(uint32 COD) { m_COD = COD; return *this; } MailDraft& AddCOD(uint32 COD) { m_COD = COD; return *this; }
public: // finishers public: // finishers
void SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid); 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: private:
void deleteIncludedItems(bool inDB = false); void deleteIncludedItems(bool inDB = false, SQLTransaction& trans = SQLTransaction(NULL));
void prepareItems(Player* receiver); // called from SendMailTo for generate mailTemplateBase items void prepareItems(Player* receiver, SQLTransaction& trans); // called from SendMailTo for generate mailTemplateBase items
uint16 m_mailTemplateId; uint16 m_mailTemplateId;
bool m_mailTemplateItemsNeed; bool m_mailTemplateItemsNeed;
+3 -3
View File
@@ -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) for (FactionStateList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
{ {
if (itr->second.Changed) if (itr->second.Changed)
{ {
CharacterDatabase.PExecute("DELETE FROM character_reputation WHERE guid = '%u' AND faction='%u'", m_player->GetGUIDLow(), itr->second.ID); trans->PAppend("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("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; itr->second.Changed = false;
} }
} }
+1 -1
View File
@@ -68,7 +68,7 @@ class ReputationMgr
m_visibleFactionCount(0), m_honoredFactionCount(0), m_reveredFactionCount(0), m_exaltedFactionCount(0) {} m_visibleFactionCount(0), m_honoredFactionCount(0), m_reveredFactionCount(0), m_exaltedFactionCount(0) {}
~ReputationMgr() {} ~ReputationMgr() {}
void SaveToDB(); void SaveToDB(SQLTransaction& trans);
void LoadFromDB(QueryResult_AutoPtr result); void LoadFromDB(QueryResult_AutoPtr result);
public: // statics public: // statics
static const int32 PointsInRank[MAX_REPUTATION_RANK]; static const int32 PointsInRank[MAX_REPUTATION_RANK];
@@ -113,53 +113,6 @@ void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction)
SendPacket(&data); 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 //this void creates new auction and adds auction to some auctionhouse
void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
{ {
@@ -284,12 +237,12 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
pl->MoveItemFromInventory(it->GetBagSlot(), it->GetSlot(), true); pl->MoveItemFromInventory(it->GetBagSlot(), it->GetSlot(), true);
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
it->DeleteFromInventoryDB(); it->DeleteFromInventoryDB(trans);
it->SaveToDB(); // recursive and not have transaction guard into self, not in inventiory and can be save standalone it->SaveToDB(trans); // recursive and not have transaction guard into self, not in inventiory and can be save standalone
AH->SaveToDB(); AH->SaveToDB(trans);
pl->SaveInventoryAndGoldToDB(); pl->SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK); SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK);
@@ -359,6 +312,8 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
return; return;
} }
SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (price < auction->buyout || auction->buyout == 0) if (price < auction->buyout || auction->buyout == 0)
{ {
if (auction->bidder > 0) if (auction->bidder > 0)
@@ -368,7 +323,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
else else
{ {
// mail to last bidder and return money // mail to last bidder and return money
SendAuctionOutbiddedMail(auction, price); sAuctionMgr.SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans);
pl->ModifyMoney(-int32(price)); pl->ModifyMoney(-int32(price));
} }
} }
@@ -379,9 +334,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
auction->bid = price; auction->bid = price;
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price);
// after this update we should save player's money ... trans->PAppend("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id);
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("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); SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0);
} }
@@ -394,26 +347,27 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
{ {
pl->ModifyMoney(-int32(auction->buyout)); pl->ModifyMoney(-int32(auction->buyout));
if (auction->bidder) //buyout for bidded auction .. if (auction->bidder) //buyout for bidded auction ..
SendAuctionOutbiddedMail(auction, auction->buyout); sAuctionMgr.SendAuctionOutbiddedMail(auction, auction->buyout, GetPlayer(), trans);
} }
auction->bidder = pl->GetGUIDLow(); auction->bidder = pl->GetGUIDLow();
auction->bid = auction->buyout; auction->bid = auction->buyout;
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout);
sAuctionMgr.SendAuctionSalePendingMail(auction); //- Mails must be under transaction control too to prevent data loss
sAuctionMgr.SendAuctionSuccessfulMail(auction); sAuctionMgr.SendAuctionSalePendingMail(auction, trans);
sAuctionMgr.SendAuctionWonMail(auction); sAuctionMgr.SendAuctionSuccessfulMail(auction, trans);
sAuctionMgr.SendAuctionWonMail(auction, trans);
SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK); SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK);
CharacterDatabase.BeginTransaction(); auction->DeleteFromDB(trans);
auction->DeleteFromDB();
uint32 item_template = auction->item_template; uint32 item_template = auction->item_template;
sAuctionMgr.RemoveAItem(auction->item_guidlow); sAuctionMgr.RemoveAItem(auction->item_guidlow);
auctionHouse->RemoveAuction(auction, item_template); auctionHouse->RemoveAuction(auction, item_template);
} }
pl->SaveInventoryAndGoldToDB(); pl->SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
//this void is called when auction_owner cancels his auction //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); AuctionEntry *auction = auctionHouse->GetAuction(auctionId);
Player *pl = GetPlayer(); Player *pl = GetPlayer();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (auction && auction->owner == pl->GetGUIDLow()) if (auction && auction->owner == pl->GetGUIDLow())
{ {
Item *pItem = sAuctionMgr.GetAItem(auction->item_guidlow); 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 if (pl->GetMoney() < auctionCut) //player doesn't have enough money, maybe message needed
return; return;
//some auctionBidderNotification would be needed, but don't know that parts.. //some auctionBidderNotification would be needed, but don't know that parts..
SendAuctionCancelledToBidderMail(auction); sAuctionMgr.SendAuctionCancelledToBidderMail(auction, trans);
pl->ModifyMoney(-int32(auctionCut)); pl->ModifyMoney(-int32(auctionCut));
} }
// Return the item by mail // Return the item by mail
@@ -462,7 +417,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
// item will deleted or added to received mail list // item will deleted or added to received mail list
MailDraft(msgAuctionCanceledOwner.str(), "") // TODO: fix body MailDraft(msgAuctionCanceledOwner.str(), "") // TODO: fix body
.AddItem(pItem) .AddItem(pItem)
.SendMailTo(pl, auction, MAIL_CHECK_MASK_COPIED); .SendMailTo(trans, pl, auction, MAIL_CHECK_MASK_COPIED);
} }
else else
{ {
@@ -483,13 +438,14 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
SendAuctionCommandResult(auction->Id, AUCTION_CANCEL, AUCTION_OK); SendAuctionCommandResult(auction->Id, AUCTION_CANCEL, AUCTION_OK);
// Now remove the auction // Now remove the auction
CharacterDatabase.BeginTransaction();
pl->SaveInventoryAndGoldToDB(); pl->SaveInventoryAndGoldToDB(trans);
auction->DeleteFromDB(); auction->DeleteFromDB(trans);
CharacterDatabase.CommitTransaction(trans);
uint32 item_template = auction->item_template; uint32 item_template = auction->item_template;
sAuctionMgr.RemoveAItem(auction->item_guidlow); sAuctionMgr.RemoveAItem(auction->item_guidlow);
auctionHouse->RemoveAuction(auction, item_template); auctionHouse->RemoveAuction(auction, item_template);
CharacterDatabase.CommitTransaction();
} }
//called when player lists his bids //called when player lists his bids
@@ -1041,11 +1041,11 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data)
for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
CharacterDatabase.escape_string(declinedname.name[i]); CharacterDatabase.escape_string(declinedname.name[i]);
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid = '%u'", GUID_LOPART(guid)); trans->PAppend("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')", 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()); 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); WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
data << uint32(0); // OK data << uint32(0); // OK
@@ -887,13 +887,11 @@ void WorldSession::HandleGuildBankDepositMoney(WorldPacket & recv_data)
if (!pGuild->GetPurchasedTabs()) if (!pGuild->GetPurchasedTabs())
return; return;
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money); pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money, trans);
GetPlayer()->ModifyMoney(-int(money)); GetPlayer()->ModifyMoney(-int(money));
GetPlayer()->SaveGoldToDB(); GetPlayer()->SaveGoldToDB(trans);
CharacterDatabase.CommitTransaction();
// logging money // logging money
if (_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) if (_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
@@ -903,7 +901,9 @@ void WorldSession::HandleGuildBankDepositMoney(WorldPacket & recv_data)
} }
// log // 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->DisplayGuildBankTabsInfo(this);
pGuild->DisplayGuildBankContent(this, 0); pGuild->DisplayGuildBankContent(this, 0);
@@ -941,21 +941,18 @@ void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket & recv_data)
if (!pGuild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_WITHDRAW_GOLD)) if (!pGuild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_WITHDRAW_GOLD))
return; return;
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (!pGuild->MemberMoneyWithdraw(money, GetPlayer()->GetGUIDLow())) if (!pGuild->MemberMoneyWithdraw(money, GetPlayer()->GetGUIDLow(), trans))
{
CharacterDatabase.RollbackTransaction();
return; return;
}
GetPlayer()->ModifyMoney(money); GetPlayer()->ModifyMoney(money);
GetPlayer()->SaveGoldToDB(); GetPlayer()->SaveGoldToDB(trans);
CharacterDatabase.CommitTransaction();
// Log // 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->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
pGuild->DisplayGuildBankTabsInfo(this); pGuild->DisplayGuildBankTabsInfo(this);
@@ -1120,8 +1120,8 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data)
return; return;
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = 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)); 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()); item->SetEntry(gift->GetEntry());
switch (item->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 // after save it will be impossible to remove the item from the queue
item->RemoveFromUpdateQueueOf(_player); 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; uint32 count = 1;
_player->DestroyItemCount(gift, count, true); _player->DestroyItemCount(gift, count, true);
@@ -863,7 +863,12 @@ void WorldSession::HandleRepairItemOpcode(WorldPacket & recv_data)
Guild *pGuild = sObjectMgr.GetGuildById(GuildId); Guild *pGuild = sObjectMgr.GetGuildById(GuildId);
if (!pGuild) if (!pGuild)
return; 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()); pGuild->SendMoneyInfo(this, _player->GetGUIDLow());
} }
} }
@@ -601,19 +601,19 @@ void WorldSession::HandlePetRename(WorldPacket & recv_data)
} }
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (isdeclined) if (isdeclined)
{ {
for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
CharacterDatabase.escape_string(declinedname.name[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()); trans->PAppend("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("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()); 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.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()); 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(); CharacterDatabase.CommitTransaction(trans);
pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL)); pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
} }
@@ -225,12 +225,12 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
sLog.outDebug("Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str()); sLog.outDebug("Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str());
CharacterDatabase.escape_string(name); CharacterDatabase.escape_string(name);
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str()); trans->PAppend("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()); trans->PAppend("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')", trans->PAppend("INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES ('%u', '%u', '%s', '%u')",
_player->GetGUIDLow(), charter->GetGUIDLow(), name.c_str(), type); _player->GetGUIDLow(), charter->GetGUIDLow(), name.c_str(), type);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
} }
void WorldSession::HandlePetitionShowSignOpcode(WorldPacket & recv_data) void WorldSession::HandlePetitionShowSignOpcode(WorldPacket & recv_data)
@@ -845,10 +845,10 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data)
} }
} }
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); trans->PAppend("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); trans->PAppend("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
// created // created
sLog.outDebug("TURN IN PETITION GUID %u", GUID_LOPART(petitionguid)); sLog.outDebug("TURN IN PETITION GUID %u", GUID_LOPART(petitionguid));
@@ -480,10 +480,10 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
trader->m_trade = NULL; trader->m_trade = NULL;
// desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards) // desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards)
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
_player->SaveInventoryAndGoldToDB(); _player->SaveInventoryAndGoldToDB(trans);
trader->SaveInventoryAndGoldToDB(); trader->SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE);
SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE);
+13 -17
View File
@@ -625,11 +625,11 @@ void WorldSession::SetAccountData(AccountDataType type, time_t time_, std::strin
{ {
uint32 acc = GetAccountId(); uint32 acc = GetAccountId();
CharacterDatabase.BeginTransaction (); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type); trans->PAppend("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type);
CharacterDatabase.escape_string(data); CharacterDatabase.escape_string(data);
CharacterDatabase.PExecute("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str()); trans->PAppend("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str());
CharacterDatabase.CommitTransaction (); CharacterDatabase.CommitTransaction(trans);
} }
else else
{ {
@@ -637,11 +637,11 @@ void WorldSession::SetAccountData(AccountDataType type, time_t time_, std::strin
if (!m_GUIDLow) if (!m_GUIDLow)
return; return;
CharacterDatabase.BeginTransaction (); SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM character_account_data WHERE guid='%u' AND type='%u'", m_GUIDLow, type); trans->PAppend("DELETE FROM character_account_data WHERE guid='%u' AND type='%u'", m_GUIDLow, type);
CharacterDatabase.escape_string(data); CharacterDatabase.escape_string(data);
CharacterDatabase.PExecute("INSERT INTO character_account_data VALUES ('%u','%u','%u','%s')", m_GUIDLow, type, (uint32)time_, data.c_str()); trans->PAppend("INSERT INTO character_account_data VALUES ('%u','%u','%u','%s')", m_GUIDLow, type, (uint32)time_, data.c_str());
CharacterDatabase.CommitTransaction (); CharacterDatabase.CommitTransaction(trans);
} }
m_accountData[type].Time = time_; m_accountData[type].Time = time_;
@@ -689,7 +689,7 @@ void WorldSession::SendTutorialsData()
SendPacket(&data); SendPacket(&data);
} }
void WorldSession::SaveTutorialsData() void WorldSession::SaveTutorialsData(SQLTransaction& trans)
{ {
if (!m_TutorialsChanged) if (!m_TutorialsChanged)
return; return;
@@ -701,14 +701,10 @@ void WorldSession::SaveTutorialsData()
Rows = result->Fetch()[0].GetUInt32(); Rows = result->Fetch()[0].GetUInt32();
if (Rows) if (Rows)
{ 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'",
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'",
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()); 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 else
{ 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]);
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]);
}
m_TutorialsChanged = false; m_TutorialsChanged = false;
} }
@@ -994,7 +990,7 @@ void WorldSession::ProcessQueryCallbacks()
//! HandleAddFriendOpcode //! HandleAddFriendOpcode
if (m_addFriendCallback.IsReady()) if (m_addFriendCallback.IsReady())
{ {
const std::string& param = m_addFriendCallback.GetParam(); std::string param = m_addFriendCallback.GetParam();
m_addFriendCallback.GetResult(result); m_addFriendCallback.GetResult(result);
HandleAddFriendOpcodeCallBack(result, param); HandleAddFriendOpcodeCallBack(result, param);
m_addFriendCallback.FreeResult(); m_addFriendCallback.FreeResult();
@@ -1003,7 +999,7 @@ void WorldSession::ProcessQueryCallbacks()
//- HandleCharRenameOpcode //- HandleCharRenameOpcode
if (m_charRenameCallback.IsReady()) if (m_charRenameCallback.IsReady())
{ {
const std::string& param = m_charRenameCallback.GetParam(); std::string param = m_charRenameCallback.GetParam();
m_charRenameCallback.GetResult(result); m_charRenameCallback.GetResult(result);
HandleChangePlayerNameOpcodeCallBack(result, param); HandleChangePlayerNameOpcodeCallBack(result, param);
m_charRenameCallback.FreeResult(); m_charRenameCallback.FreeResult();
+1 -3
View File
@@ -229,7 +229,7 @@ class WorldSession
void LoadAccountData(QueryResult_AutoPtr result, uint32 mask); void LoadAccountData(QueryResult_AutoPtr result, uint32 mask);
void LoadTutorialsData(); void LoadTutorialsData();
void SendTutorialsData(); void SendTutorialsData();
void SaveTutorialsData(); void SaveTutorialsData(SQLTransaction& trans);
uint32 GetTutorialInt(uint32 intId) uint32 GetTutorialInt(uint32 intId)
{ {
return m_Tutorials[intId]; return m_Tutorials[intId];
@@ -250,8 +250,6 @@ class WorldSession
void SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError = 0); 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 SendAuctionBidderNotification(uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template);
void SendAuctionOwnerNotification(AuctionEntry * auction); void SendAuctionOwnerNotification(AuctionEntry * auction);
void SendAuctionOutbiddedMail(AuctionEntry * auction, uint32 newPrice);
void SendAuctionCancelledToBidderMail(AuctionEntry* auction);
//Item Enchantment //Item Enchantment
void SendEnchantmentLog(uint64 Target, uint64 Caster,uint32 ItemID,uint32 SpellID); void SendEnchantmentLog(uint64 Target, uint64 Caster,uint32 ItemID,uint32 SpellID);
+4 -4
View File
@@ -369,7 +369,7 @@ DumpReturn PlayerDumpWriter::WriteDump(const std::string& file, uint32 guid)
} }
// Reading - High-level functions // 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) void fixNULLfields(std::string &line)
{ {
@@ -436,7 +436,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
typedef PetIds::value_type PetIdsPair; typedef PetIds::value_type PetIdsPair;
PetIds petids; PetIds petids;
CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
while (!feof(fin)) while (!feof(fin))
{ {
if (!fgets(buf, 32000, fin)) if (!fgets(buf, 32000, fin))
@@ -629,10 +629,10 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
fixNULLfields(line); fixNULLfields(line);
CharacterDatabase.Execute(line.c_str()); trans->Append(line.c_str());
} }
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction(trans);
sObjectMgr.m_hiItemGuid += items.size(); sObjectMgr.m_hiItemGuid += items.size();
sObjectMgr.m_mailid += mails.size(); sObjectMgr.m_mailid += mails.size();
+2
View File
@@ -30,8 +30,10 @@
#include "DatabaseWorkerPool.h" #include "DatabaseWorkerPool.h"
#include "MySQLThreading.h" #include "MySQLThreading.h"
#include "Transaction.h"
typedef DatabaseWorkerPool DatabaseType; typedef DatabaseWorkerPool DatabaseType;
#define _LIKE_ "LIKE" #define _LIKE_ "LIKE"
#define _TABLE_SIM_ "`" #define _TABLE_SIM_ "`"
#define _CONCAT3_(A,B,C) "CONCAT( " A " , " B " , " C " )" #define _CONCAT3_(A,B,C) "CONCAT( " A " , " B " , " C " )"
@@ -16,7 +16,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "DatabaseEnv.h"
#include "DatabaseWorkerPool.h" #include "DatabaseWorkerPool.h"
#include "MySQLConnection.h" #include "MySQLConnection.h"
#include "DatabaseEnv.h" #include "DatabaseEnv.h"
@@ -183,43 +182,25 @@ QueryResult_AutoPtr DatabaseWorkerPool::PQuery(const char* sql, ...)
return Query(szQuery); return Query(szQuery);
} }
void DatabaseWorkerPool::BeginTransaction() SQLTransaction DatabaseWorkerPool::BeginTransaction()
{ {
ACE_Guard<ACE_Thread_Mutex> guard(m_transQueues_mtx); return SQLTransaction(new Transaction);
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) void DatabaseWorkerPool::CommitTransaction(SQLTransaction transaction)
{
#ifdef _DEBUG
if (transaction->GetSize() == 0)
{ {
itr->second->ForcefulDelete(); sLog.outError("Transaction contains 0 queries");
delete itr->second;
}
m_tranQueues[tranThread] = new TransactionTask();
return; return;
}
void DatabaseWorkerPool::RollbackTransaction()
{
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;
itr->second = NULL;
} }
} if (transaction->GetSize() == 1)
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)
{ {
Enqueue(itr->second); sLog.outDetail("Warning: Transaction only holds 1 query, consider removing Transaction context in code.");
itr->second = NULL;
} }
#endif
Enqueue(new TransactionTask(transaction));
} }
ACE_Future<QueryResult_AutoPtr> DatabaseWorkerPool::AsyncQuery(const char* sql) 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); ACE_Guard<ACE_Thread_Mutex> guard(m_connectionMap_mtx);
itr = m_sync_connections.find(ACE_Based::Thread::current()); itr = m_sync_connections.find(ACE_Based::Thread::current());
if (itr != m_sync_connections.end()) if (itr != m_sync_connections.end())
return itr->second; conn = itr->second;
} }
/*! Bundled threads */ /*! Bundled threads */
conn = m_bundle_conn; conn = m_bundle_conn;
@@ -28,6 +28,7 @@
#include "QueryResult.h" #include "QueryResult.h"
#include "Callback.h" #include "Callback.h"
#include "MySQLConnection.h" #include "MySQLConnection.h"
#include "Transaction.h"
enum MySQLThreadBundle enum MySQLThreadBundle
{ {
@@ -73,9 +74,8 @@ class DatabaseWorkerPool
ACE_Future<QueryResult_AutoPtr> AsyncPQuery(const char* sql, ...); ACE_Future<QueryResult_AutoPtr> AsyncPQuery(const char* sql, ...);
QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder); QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder);
void BeginTransaction(); SQLTransaction BeginTransaction();
void RollbackTransaction(); void CommitTransaction(SQLTransaction transaction);
void CommitTransaction();
void escape_string(std::string& str) void escape_string(std::string& str)
{ {
@@ -117,8 +117,6 @@ class DatabaseWorkerPool
MySQLConnection* m_bundle_conn; //! Bundled connection (see Database.ThreadBundleMask config) MySQLConnection* m_bundle_conn; //! Bundled connection (see Database.ThreadBundleMask config)
AtomicUInt m_connections; //! Counter of MySQL connections; AtomicUInt m_connections; //! Counter of MySQL connections;
std::string m_infoString; //! Infostring that is passed on to child 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 #endif
+1 -48
View File
@@ -16,9 +16,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "DatabaseEnv.h"
#include "SQLOperation.h" #include "SQLOperation.h"
#include "MySQLConnection.h" #include "MySQLConnection.h"
#include "Log.h"
/*! Basic, ad-hoc queries. */ /*! Basic, ad-hoc queries. */
BasicStatementTask::BasicStatementTask(const char* sql) : BasicStatementTask::BasicStatementTask(const char* sql) :
@@ -53,53 +53,6 @@ bool BasicStatementTask::Execute()
return m_conn->Execute(m_sql); 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) bool SQLQueryHolder::SetQuery(size_t index, const char *sql)
{ {
if (m_queries.size() <= index) if (m_queries.size() <= index)
-12
View File
@@ -59,19 +59,7 @@ class BasicStatementTask : public SQLOperation
QueryResultFuture m_result; QueryResultFuture m_result;
}; };
/*! Transactions */
class TransactionTask : public SQLOperation
{
public:
TransactionTask();
~TransactionTask();
void ForcefulDelete();
bool Execute();
private:
std::queue<char*> m_queries;
};
class SQLQueryHolder class SQLQueryHolder
{ {
@@ -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;
}
+59
View File
@@ -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