Core/DBLayer:

- Rewrite Field class to be able to store both binary prepared statement data and data from adhoc query resultsets
- Buffer the data of prepared statements using ResultSet and Field classes and let go of mysql c api structures after PreparedResultSet constructor. Fixes a race condition and thus a possible crash/data corruption (issue pointed out to Derex, basic suggestion by raczman)
- Conform PreparedResultSet and ResultSet to the same design standards, and using Field class as data buffer class for both
* NOTE: This means the fetching methods are uniform again, using ¨Field* fields = result->Fetch();¨ and access to elements trough fields[x].
* NOTE: for access to the correct row in prepared statements, ¨Field* fields = result->Fetch();¨ must ALWAYS be called inside the do { }while(result->NextRow()) loop.
* NOTE: This means that Field::GetString() returns std::string object and Field::GetCString() returns const char* pointer.

Still experimental and all that jazz, not recommended for production servers until feedback is given.

--HG--
branch : trunk
This commit is contained in:
Machiavelli
2010-09-24 22:16:21 +02:00
parent b46b498141
commit 3c6dc32030
47 changed files with 1003 additions and 875 deletions
+7 -7
View File
@@ -2210,17 +2210,17 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
if (result)
{
Field* fields = result->Fetch();
username = fields[0].GetCppString();
username = fields[0].GetString();
security = fields[1].GetUInt32();
email = fields[2].GetCppString();
email = fields[2].GetString();
if (email.empty())
email = "-";
if (!m_session || m_session->GetSecurity() >= AccountTypes(security))
{
last_ip = fields[3].GetCppString();
last_login = fields[4].GetCppString();
last_ip = fields[3].GetString();
last_login = fields[4].GetString();
}
else
{
@@ -2528,7 +2528,7 @@ bool ChatHandler::HandleWpEventCommand(const char* args)
a4 = fields[2].GetUInt32();
a5 = fields[3].GetUInt32();
a6 = fields[4].GetUInt32();
a7 = fields[5].GetString();
a7 = fields[5].GetCString();
a8 = fields[6].GetFloat();
a9 = fields[7].GetFloat();
a10 = fields[8].GetFloat();
@@ -3856,7 +3856,7 @@ bool ChatHandler::LookupPlayerSearchCommand(QueryResult result, int32 limit)
Field* fields = result->Fetch();
uint32 acc_id = fields[0].GetUInt32();
std::string acc_name = fields[1].GetCppString();
std::string acc_name = fields[1].GetString();
QueryResult chars = CharacterDatabase.PQuery("SELECT guid,name FROM characters WHERE account = '%u'", acc_id);
if (chars)
@@ -3870,7 +3870,7 @@ bool ChatHandler::LookupPlayerSearchCommand(QueryResult result, int32 limit)
{
Field* charfields = chars->Fetch();
guid = charfields[0].GetUInt64();
name = charfields[1].GetCppString();
name = charfields[1].GetString();
PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER,name.c_str(),guid);
++i;
+39 -32
View File
@@ -324,21 +324,21 @@ bool ChatHandler::HandleReloadCreatureTemplateCommand(const char* args)
const_cast<CreatureInfo*>(cInfo)->Modelid3 = fields[7].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->Modelid4 = fields[8].GetUInt32();
size_t len = 0;
if (const char* temp = fields[9].GetString())
if (const char* temp = fields[9].GetCString())
{
delete[] cInfo->Name;
len = strlen(temp)+1;
const_cast<CreatureInfo*>(cInfo)->Name = new char[len];
strncpy(cInfo->Name, temp, len);
}
if (const char* temp = fields[10].GetString())
if (const char* temp = fields[10].GetCString())
{
delete[] cInfo->SubName;
len = strlen(temp)+1;
const_cast<CreatureInfo*>(cInfo)->SubName = new char[len];
strncpy(cInfo->SubName, temp, len);
}
if (const char* temp = fields[11].GetString())
if (const char* temp = fields[11].GetCString())
{
delete[] cInfo->IconName;
len = strlen(temp)+1;
@@ -397,7 +397,7 @@ bool ChatHandler::HandleReloadCreatureTemplateCommand(const char* args)
const_cast<CreatureInfo*>(cInfo)->VehicleId = fields[61].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->mingold = fields[62].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->maxgold = fields[63].GetUInt32();
if (const char* temp = fields[64].GetString())
if (const char* temp = fields[64].GetCString())
{
delete[] cInfo->AIName;
len = strlen(temp)+1;
@@ -421,7 +421,7 @@ bool ChatHandler::HandleReloadCreatureTemplateCommand(const char* args)
const_cast<CreatureInfo*>(cInfo)->equipmentId = fields[79].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->MechanicImmuneMask = fields[80].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->flags_extra = fields[81].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->ScriptID = sObjectMgr.GetScriptId(fields[82].GetString());
const_cast<CreatureInfo*>(cInfo)->ScriptID = sObjectMgr.GetScriptId(fields[82].GetCString());
sObjectMgr.CheckCreatureTemplate(cInfo);
@@ -2649,7 +2649,7 @@ bool ChatHandler::HandleListItemCommand(const char *args)
uint32 item_slot = fields[2].GetUInt32();
uint32 owner_guid = fields[3].GetUInt32();
uint32 owner_acc = fields[4].GetUInt32();
std::string owner_name = fields[5].GetCppString();
std::string owner_name = fields[5].GetString();
char const* item_pos = 0;
if (Player::IsEquipmentPos(item_bag,item_slot))
@@ -2700,9 +2700,9 @@ bool ChatHandler::HandleListItemCommand(const char *args)
uint32 item_s = fields[1].GetUInt32();
uint32 item_r = fields[2].GetUInt32();
uint32 item_s_acc = fields[3].GetUInt32();
std::string item_s_name = fields[4].GetCppString();
std::string item_s_name = fields[4].GetString();
uint32 item_r_acc = fields[5].GetUInt32();
std::string item_r_name = fields[6].GetCppString();
std::string item_r_name = fields[6].GetString();
char const* item_pos = "[in mail]";
@@ -2743,7 +2743,7 @@ bool ChatHandler::HandleListItemCommand(const char *args)
uint32 item_guid = fields[0].GetUInt32();
uint32 owner = fields[1].GetUInt32();
uint32 owner_acc = fields[2].GetUInt32();
std::string owner_name = fields[3].GetCppString();
std::string owner_name = fields[3].GetString();
char const* item_pos = "[in auction]";
@@ -2770,7 +2770,7 @@ bool ChatHandler::HandleListItemCommand(const char *args)
Field *fields = result->Fetch();
uint32 item_guid = fields[0].GetUInt32();
uint32 guild_guid = fields[1].GetUInt32();
std::string guild_name = fields[2].GetCppString();
std::string guild_name = fields[2].GetString();
char const* item_pos = "[in guild bank]";
@@ -5895,7 +5895,7 @@ bool ChatHandler::HandleBanInfoCharacterCommand(const char *args)
return false;
}
target_guid = resultCharacter->GetUInt32(0);
target_guid = (*resultCharacter)[0].GetUInt32();
}
else
target_guid = target->GetGUIDLow();
@@ -5909,15 +5909,17 @@ bool ChatHandler::HandleBanInfoCharacterCommand(const char *args)
PSendSysMessage(LANG_BANINFO_BANHISTORY, name.c_str());
do
{
time_t unbandate = time_t(result->GetUInt64(3));
Field* fields = result->Fetch();
time_t unbandate = time_t(fields[3].GetUInt64());
bool active = false;
if (result->GetUInt8(2) && (!result->GetUInt64(1) || unbandate >= time(NULL)))
if (fields[2].GetUInt8() && (!fields[1].GetUInt64() || unbandate >= time(NULL)))
active = true;
bool permanent = (result->GetUInt64(1) == uint64(0));
std::string bantime = permanent ? GetTrinityString(LANG_BANINFO_INFINITE) : secsToTimeString(result->GetUInt64(1), true);
bool permanent = (fields[1].GetUInt64() == uint64(0));
std::string bantime = permanent ? GetTrinityString(LANG_BANINFO_INFINITE) : secsToTimeString(fields[1].GetUInt64(), true);
PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
result->GetCString(0), bantime.c_str(), active ? GetTrinityString(LANG_BANINFO_YES) : GetTrinityString(LANG_BANINFO_NO), result->GetCString(4), result->GetCString(5));
} while (result->NextRow());
fields[0].GetCString(), bantime.c_str(), active ? GetTrinityString(LANG_BANINFO_YES) : GetTrinityString(LANG_BANINFO_NO), fields[4].GetCString(), fields[5].GetCString());
}
while (result->NextRow());
return true;
}
@@ -6006,12 +6008,14 @@ bool ChatHandler::HandleBanListCharacterCommand(const char *args)
{
do
{
Field* fields = result->Fetch();
PreparedStatement* stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_GET_BANNED_NAME);
stmt2->setUInt32(0, result->GetUInt32(0));
stmt2->setUInt32(0, fields[0].GetUInt32());
PreparedQueryResult banresult = CharacterDatabase.Query(stmt2);
if (banresult)
PSendSysMessage("%s", banresult->GetCString(0));
} while (result->NextRow());
PSendSysMessage("%s", (*banresult)[0].GetCString());
}
while (result->NextRow());
}
// Console wide output
else
@@ -6023,38 +6027,41 @@ bool ChatHandler::HandleBanListCharacterCommand(const char *args)
{
SendSysMessage("-------------------------------------------------------------------------------");
std::string char_name;
Field* fields = result->Fetch();
char_name = result->GetString(1);
std::string char_name = fields[1].GetString();
PreparedStatement* stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_GET_BANINFO_LIST);
stmt2->setUInt32(0, result->GetUInt32(0));
stmt2->setUInt32(0, fields[0].GetUInt32());
PreparedQueryResult banInfo = CharacterDatabase.Query(stmt2);
if (banInfo)
{
Field* banFields = banInfo->Fetch();
do
{
time_t t_ban = banInfo->GetUInt64(0);
time_t t_ban = banFields[0].GetUInt64();
tm* aTm_ban = localtime(&t_ban);
if (banInfo->GetUInt64(0) == banInfo->GetUInt64(1))
if (banFields[0].GetUInt64() == banFields[1].GetUInt64())
{
PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
char_name.c_str(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
banInfo->GetCString(2), banInfo->GetCString(3));
banFields[2].GetCString(), banFields[3].GetCString());
}
else
{
time_t t_unban = banInfo->GetUInt64(1);
time_t t_unban = banFields[1].GetUInt64();
tm* aTm_unban = localtime(&t_unban);
PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
char_name.c_str(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
banInfo->GetCString(2), banInfo->GetCString(3));
banFields[2].GetCString(), banFields[3].GetCString());
}
} while (banInfo->NextRow());
}
while (banInfo->NextRow());
}
} while (result->NextRow());
}
while (result->NextRow());
SendSysMessage(" =============================================================================== ");
}
@@ -6128,7 +6135,7 @@ bool ChatHandler::HandleBanListHelper(QueryResult result)
// "account" case, name can be get in same query
if (result->GetFieldCount() > 1)
account_name = fields[1].GetCppString();
account_name = fields[1].GetString();
// "character" case, name need extract from another DB
else
sAccountMgr.GetName (account_id,account_name);
@@ -7537,7 +7544,7 @@ bool ChatHandler::HandleListFreezeCommand(const char * /*args*/)
do
{
Field *fields = result->Fetch();
std::string fplayers = fields[0].GetCppString();
std::string fplayers = fields[0].GetString();
PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS,fplayers.c_str());
} while (result->NextRow());