Fix pdump write command and add check to pdump load (#106)
This commit is contained in:
parent
f3ea3e102c
commit
424b55389d
@ -236,7 +236,7 @@ bool changetokGuid(std::string& str, int n, std::map<uint32, uint32>& guidMap, u
|
|||||||
return changetoknth(str, n, chritem, false, nonzero);
|
return changetoknth(str, n, chritem, false, nonzero);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CreateDumpString(char const* tableName, QueryResult* result)
|
std::string CreateDumpString(char const* tableName, char const* tableColumnNamesAsChars, QueryResult* result)
|
||||||
{
|
{
|
||||||
if (!tableName || !result)
|
if (!tableName || !result)
|
||||||
{
|
{
|
||||||
@ -244,7 +244,7 @@ std::string CreateDumpString(char const* tableName, QueryResult* result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << "INSERT INTO `" << tableName << "` VALUES (";
|
ss << "INSERT INTO `" << tableName << "` ("<< tableColumnNamesAsChars <<") VALUES (";
|
||||||
Field* fields = result->Fetch();
|
Field* fields = result->Fetch();
|
||||||
for (uint32 i = 0; i < result->GetFieldCount(); ++i)
|
for (uint32 i = 0; i < result->GetFieldCount(); ++i)
|
||||||
{
|
{
|
||||||
@ -364,7 +364,26 @@ void PlayerDumpWriter::DumpTableContent(std::string& dump, uint32 guid, char con
|
|||||||
wherestr = GenerateWhereStr(fieldname, guid);
|
wherestr = GenerateWhereStr(fieldname, guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryResult* result = CharacterDatabase.PQuery("SELECT * FROM `%s` WHERE `%s`", tableFrom, wherestr.c_str());
|
//fetch table columns
|
||||||
|
std::string tableColumnNamesStr = "";
|
||||||
|
QueryNamedResult* resNames = CharacterDatabase.PQueryNamed("SELECT * FROM `%s` LIMIT 1", tableFrom);
|
||||||
|
if (!resNames)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// There will be a result since if not teh code does not hit lines before... so no check needed
|
||||||
|
QueryFieldNames const& namesMap = resNames->GetFieldNames();
|
||||||
|
|
||||||
|
for (QueryFieldNames::const_iterator itr = namesMap.begin(); itr != namesMap.end(); ++itr)
|
||||||
|
{
|
||||||
|
tableColumnNamesStr += "`" + *itr +"`,";
|
||||||
|
}
|
||||||
|
// remove last character of tableColumnNamesStr = ","
|
||||||
|
tableColumnNamesStr.pop_back();
|
||||||
|
namesMap.empty();
|
||||||
|
|
||||||
|
// fetch results of the table
|
||||||
|
QueryResult* result = CharacterDatabase.PQuery("SELECT %s FROM `%s` WHERE %s", tableColumnNamesStr.c_str(), tableFrom, wherestr.c_str());
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -390,7 +409,7 @@ void PlayerDumpWriter::DumpTableContent(std::string& dump, uint32 guid, char con
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dump += CreateDumpString(tableTo, result);
|
dump += CreateDumpString(tableTo, tableColumnNamesStr.c_str(), result);
|
||||||
dump += "\n";
|
dump += "\n";
|
||||||
}
|
}
|
||||||
while (result->NextRow());
|
while (result->NextRow());
|
||||||
@ -405,38 +424,29 @@ std::string PlayerDumpWriter::GetDump(uint32 guid)
|
|||||||
std::string dump;
|
std::string dump;
|
||||||
|
|
||||||
dump += "IMPORTANT NOTE: This sql queries not created for apply directly, use '.pdump load' command in console or client chat instead.\n";
|
dump += "IMPORTANT NOTE: This sql queries not created for apply directly, use '.pdump load' command in console or client chat instead.\n";
|
||||||
dump += "IMPORTANT NOTE: NOT APPLY ITS DIRECTLY to character DB or you will DAMAGE and CORRUPT character DB\n\n";
|
dump += "IMPORTANT NOTE: NOT APPLY ITS DIRECTLY to character DB or you will DAMAGE and CORRUPT character DB\n";
|
||||||
|
|
||||||
// revision check guard
|
// revision check guard
|
||||||
QueryNamedResult* result = CharacterDatabase.QueryNamed("SELECT * FROM `db_version` LIMIT 1");
|
// Check the revision of character DB which will be the first line of the whole version/structure set
|
||||||
|
QueryResult* result = CharacterDatabase.Query("SELECT `version`, `structure`, `description`, `comment` FROM `db_version` ORDER BY `version` DESC, `structure` DESC, `content` ASC LIMIT 1");
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
QueryFieldNames const& namesMap = result->GetFieldNames();
|
Field* fields = result->Fetch();
|
||||||
std::string reqName;
|
|
||||||
for (QueryFieldNames::const_iterator itr = namesMap.begin(); itr != namesMap.end(); ++itr)
|
dump += "DUMPED_WITH:"+std::to_string(fields[0].GetInt16())
|
||||||
{
|
+ "." + std::to_string(fields[1].GetInt16()) + ".X "
|
||||||
if (itr->substr(0, 9) == "required_")
|
+" CHAR. DB VERSION ( "
|
||||||
{
|
+ fields[2].GetCppString() + " / "
|
||||||
reqName = *itr;
|
+ fields[3].GetCppString() +
|
||||||
break;
|
")\n\n"
|
||||||
}
|
;
|
||||||
}
|
|
||||||
|
|
||||||
if (!reqName.empty())
|
|
||||||
{
|
|
||||||
// this will fail at wrong character DB version
|
|
||||||
dump += "UPDATE `version` SET `" + reqName + "` = 1 WHERE FALSE;\n\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sLog.outError("Character DB Table 'db_version' does not have revision guard field, revision guard query not added to pdump.");
|
|
||||||
}
|
|
||||||
|
|
||||||
delete result;
|
delete result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sLog.outError("Character DB not have 'db_version' table, revision guard query not added to pdump.");
|
sLog.outError("Character DB not have 'db_version' table");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DumpTable* itr = &dumpTables[0]; itr->isValid(); ++itr)
|
for (DumpTable* itr = &dumpTables[0]; itr->isValid(); ++itr)
|
||||||
@ -570,16 +580,38 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add required_ check
|
// Check db version corresp.
|
||||||
if (line.substr(nw_pos, 41) == "UPDATE `db_version` SET `required_`")
|
std::string dbVersionLinePrefix = line.substr(nw_pos, 12);
|
||||||
{
|
|
||||||
if (!CharacterDatabase.Execute(line.c_str()))
|
|
||||||
{
|
|
||||||
ROLLBACK(DUMP_FILE_BROKEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
if (dbVersionLinePrefix =="DUMPED_WITH:")
|
||||||
|
{
|
||||||
|
QueryResult* result = CharacterDatabase.Query("SELECT `version`, `structure`, `description`, `comment` FROM `db_version` ORDER BY `version` DESC, `structure` DESC, `content` ASC LIMIT 1");
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
Field* fields = result->Fetch();
|
||||||
|
// Only version / structure is needed
|
||||||
|
std::string dbversion = std::to_string(fields[0].GetInt16()) + "." + std::to_string(fields[1].GetInt16())+".X";
|
||||||
|
size_t dbversionLen = dbversion.size();
|
||||||
|
|
||||||
|
std::string dbversionInDumpFile = line.substr(nw_pos+12, dbversionLen);
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
|
||||||
|
if (dbversionInDumpFile != dbversion)
|
||||||
|
{
|
||||||
|
sLog.outError("LoadPlayerDump: Cannot load player dump - file version is %s, DB needs %s", dbversionInDumpFile.c_str(), dbversion.c_str());
|
||||||
|
ROLLBACK(DUMP_DB_VERSION_MISMATCH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// determine table name and load type
|
// determine table name and load type
|
||||||
std::string tn = gettablename(line);
|
std::string tn = gettablename(line);
|
||||||
|
@ -63,6 +63,7 @@ enum DumpReturn
|
|||||||
DUMP_TOO_MANY_CHARS,
|
DUMP_TOO_MANY_CHARS,
|
||||||
DUMP_UNEXPECTED_END,
|
DUMP_UNEXPECTED_END,
|
||||||
DUMP_FILE_BROKEN,
|
DUMP_FILE_BROKEN,
|
||||||
|
DUMP_DB_VERSION_MISMATCH
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlayerDump
|
class PlayerDump
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 692e744f80ece7cbac6a2fa5cd96a7481a0c7b89
|
Subproject commit 3d46391e769b40f3d1ba170de67ef8d139f67540
|
Loading…
x
Reference in New Issue
Block a user