Database revision refactor

This commit is contained in:
Foereaper 2015-08-20 00:22:34 +02:00
parent 025ca0692e
commit b37de3b83e
8 changed files with 131 additions and 104 deletions

View File

@ -116,7 +116,6 @@ bool ChatHandler::HandleServerInfoCommand(char* /*args*/)
{ SendSysMessage(LANG_USING_SCRIPT_LIB_NONE); }
PSendSysMessage(LANG_USING_WORLD_DB, sWorld.GetDBVersion());
PSendSysMessage(LANG_USING_EVENT_AI, sWorld.GetCreatureEventAIVersion());
PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum);
PSendSysMessage(LANG_UPTIME, str.c_str());

View File

@ -84,6 +84,9 @@
// WARDEN
#include "WardenCheckMgr.h"
#include <iostream>
#include <sstream>
INSTANTIATE_SINGLETON_1(World);
extern void LoadGameObjectModelList();
@ -2066,22 +2069,25 @@ void World::UpdateMaxSessionCounters()
void World::LoadDBVersion()
{
QueryResult* result = WorldDatabase.Query("SELECT version, creature_ai_version FROM db_version LIMIT 1");
QueryResult* result = WorldDatabase.Query("SELECT version, structure, content FROM db_version ORDER BY version DESC, structure DESC, content DESC LIMIT 1");
if (result)
{
Field* fields = result->Fetch();
m_DBVersion = fields[0].GetCppString();
m_CreatureEventAIVersion = fields[1].GetCppString();
uint32 version = fields[0].GetUInt32();
uint32 structure = fields[1].GetUInt32();
uint32 content = fields[2].GetUInt32();
delete result;
std::stringstream ss;
ss << "Version: " << version << ", Structure: " << structure << ", Content: " << content;
m_DBVersion = ss.str();
}
if (m_DBVersion.empty())
{ m_DBVersion = "Unknown world database."; }
if (m_CreatureEventAIVersion.empty())
{ m_CreatureEventAIVersion = "Unknown creature EventAI."; }
}
void World::setConfig(eConfigUInt32Values index, char const* fieldname, uint32 defvalue)

View File

@ -601,7 +601,6 @@ class World
// used World DB version
void LoadDBVersion();
char const* GetDBVersion() { return m_DBVersion.c_str(); }
char const* GetCreatureEventAIVersion() { return m_CreatureEventAIVersion.c_str(); }
/**
@ -692,7 +691,6 @@ class World
// used versions
std::string m_DBVersion;
std::string m_CreatureEventAIVersion;
// List of Maps that should be force-loaded on startup
std::set<uint32>* m_configForceLoadMapIds;

View File

@ -465,7 +465,8 @@ bool Master::_StartDB()
return false;
}
if (!WorldDatabase.CheckRequiredField("db_version", REVISION_DB_MANGOS))
///- Check the World database version
if(!WorldDatabase.CheckDatabaseVersion(DATABASE_WORLD))
{
///- Wait for already started DB delay threads to end
WorldDatabase.HaltDelayThread();
@ -494,7 +495,8 @@ bool Master::_StartDB()
return false;
}
if (!CharacterDatabase.CheckRequiredField("character_db_version", REVISION_DB_CHARACTERS))
///- Check the Character database version
if (!CharacterDatabase.CheckDatabaseVersion(DATABASE_CHARACTER))
{
///- Wait for already started DB delay threads to end
WorldDatabase.HaltDelayThread();
@ -527,7 +529,8 @@ bool Master::_StartDB()
return false;
}
if (!LoginDatabase.CheckRequiredField("realmd_db_version", REVISION_DB_REALMD))
///- Check the Realm database version
if (!LoginDatabase.CheckDatabaseVersion(DATABASE_REALMD))
{
///- Wait for already started DB delay threads to end
WorldDatabase.HaltDelayThread();
@ -560,7 +563,6 @@ bool Master::_StartDB()
sWorld.LoadDBVersion();
sLog.outString("Using World DB: %s", sWorld.GetDBVersion());
sLog.outString("Using creature EventAI: %s", sWorld.GetCreatureEventAIVersion());
sLog.outString();
return true;
}

@ -1 +1 @@
Subproject commit 9c9e7ae7919e1cd5ce1f454520b9adf3316e2137
Subproject commit da60a5b8481ce8e02cf24614287ebc0e4930d278

View File

@ -25,6 +25,7 @@
#include "DatabaseEnv.h"
#include "Config/Config.h"
#include "Database/SqlOperations.h"
#include "revision.h"
#include <ctime>
#include <iostream>
@ -452,92 +453,78 @@ bool Database::RollbackTransaction()
return true;
}
bool Database::CheckRequiredField(char const* table_name, char const* required_name)
bool Database::CheckDatabaseVersion(DatabaseTypes database)
{
// check required field
QueryResult* result = PQuery("SELECT %s FROM %s LIMIT 1", required_name, table_name);
if (result)
{
delete result;
return true;
}
const DBVersion& dbversion = databaseVersions[database];
// check fail, prepare readabale error message
// Fetch the database version table information
QueryResult* result = Query("SELECT version, structure, content, description FROM db_version ORDER BY version DESC, structure DESC, content DESC LIMIT 1");
// search current required_* field in DB
const char* db_name;
if (!strcmp(table_name, "db_version"))
{ db_name = "WORLD"; }
else if (!strcmp(table_name, "character_db_version"))
{ db_name = "CHARACTER"; }
else if (!strcmp(table_name, "realmd_db_version"))
{ db_name = "REALMD"; }
else
{ db_name = "UNKNOWN"; }
char const* req_sql_update_name = required_name + strlen("required_");
QueryNamedResult* result2 = PQueryNamed("SELECT * FROM %s LIMIT 1", table_name);
if (result2)
{
QueryFieldNames const& namesMap = result2->GetFieldNames();
std::string reqName;
for (QueryFieldNames::const_iterator itr = namesMap.begin(); itr != namesMap.end(); ++itr)
{
if (itr->substr(0, 9) == "required_")
{
reqName = *itr;
break;
}
}
delete result2;
std::string cur_sql_update_name = reqName.substr(strlen("required_"), reqName.npos);
if (!reqName.empty())
{
sLog.outErrorDb("The table `%s` in your [%s] database indicates that this database is out of date!", table_name, db_name);
sLog.outErrorDb();
sLog.outErrorDb(" [A] You have: --> `%s.sql`", cur_sql_update_name.c_str());
sLog.outErrorDb();
sLog.outErrorDb(" [B] You need: --> `%s.sql`", req_sql_update_name);
sLog.outErrorDb();
sLog.outErrorDb("You must apply all updates after [A] to [B] to use mangos with this database.");
sLog.outErrorDb("These updates are included in the sql/updates folder.");
sLog.outErrorDb("Please read the included [README] in sql/updates for instructions on updating.");
}
else
{
sLog.outErrorDb("The table `%s` in your [%s] database is missing its version info.", table_name, db_name);
sLog.outErrorDb("MaNGOS can not find the version info needed to check that the db is up to date.");
sLog.outErrorDb();
sLog.outErrorDb("This revision of MaNGOS requires a database updated to:");
sLog.outErrorDb("`%s.sql`", req_sql_update_name);
sLog.outErrorDb();
if (!strcmp(db_name, "WORLD"))
{ sLog.outErrorDb("Post this error to your database provider forum or find a solution there."); }
else
{ sLog.outErrorDb("Reinstall your [%s] database with the included sql file in the sql folder.", db_name); }
}
}
else
{
sLog.outErrorDb("The table `%s` in your [%s] database is missing or corrupt.", table_name, db_name);
sLog.outErrorDb("MaNGOS can not find the version info needed to check that the db is up to date.");
// db_version table does not exist or is empty
if (!result)
{
sLog.outErrorDb("The table `db_version` in your [%s] database is missing or corrupt.", dbversion.dbname.c_str());
sLog.outErrorDb();
sLog.outErrorDb("This revision of mangos requires a database updated to:");
sLog.outErrorDb("`%s.sql`", req_sql_update_name);
sLog.outErrorDb(" [A] You have database Version: MaNGOS can not verify your database version or its existence!");
sLog.outErrorDb();
if (!strcmp(db_name, "WORLD"))
{ sLog.outErrorDb("Post this error to your database provider forum or find a solution there."); }
else
{ sLog.outErrorDb("Reinstall your [%s] database with the included sql file in the sql folder.", db_name); }
sLog.outErrorDb(" [B] You need database Version: %u", dbversion.expected_version);
sLog.outErrorDb(" Structure: %u", dbversion.expected_structure);
sLog.outErrorDb(" Content: %u", dbversion.expected_content);
sLog.outErrorDb(" Description: %s", dbversion.description.c_str());
sLog.outErrorDb();
sLog.outErrorDb("Please verify your database location or your database integrity.");
return false;
}
return false;
Field* fields = result->Fetch();
uint32 version = fields[0].GetUInt32();
uint32 structure = fields[1].GetUInt32();
uint32 content = fields[2].GetUInt32();
std::string description = fields[3].GetCppString();
delete result;
// Structure does not match the required version
if (structure != dbversion.expected_structure)
{
sLog.outErrorDb("The table `db_version` indicates that your [%s] database does not match the expected structure!", dbversion.dbname.c_str());
sLog.outErrorDb();
sLog.outErrorDb(" [A] You have database Version: %u", version);
sLog.outErrorDb(" Structure: %u", structure);
sLog.outErrorDb(" Content: %u", content);
sLog.outErrorDb(" Description: %s", description.c_str());
sLog.outErrorDb();
sLog.outErrorDb(" [B] You need database Version: %u", dbversion.expected_version);
sLog.outErrorDb(" Structure: %u", dbversion.expected_structure);
sLog.outErrorDb(" Content: %u", dbversion.expected_content);
sLog.outErrorDb(" Description: %s", dbversion.description.c_str());
sLog.outErrorDb();
sLog.outErrorDb("You must apply all updates after [A] to [B] to use MaNGOS with this database.");
sLog.outErrorDb("These updates are included in the database/%s/Updates folder.", dbversion.dbname.c_str());
return false;
}
// DB is not up to date, but structure is correct. Send warning but start core
if (version != dbversion.expected_version || content != dbversion.expected_content)
{
sLog.outErrorDb("The table `db_version` indicates that your [%s] database does not match the expected version!", dbversion.dbname.c_str());
sLog.outErrorDb();
sLog.outErrorDb(" [A] You have database Version: %u", version);
sLog.outErrorDb(" Structure: %u", structure);
sLog.outErrorDb(" Content: %u", content);
sLog.outErrorDb(" Description: %s", description.c_str());
sLog.outErrorDb();
sLog.outErrorDb(" [B] You need database Version: %u", dbversion.expected_version);
sLog.outErrorDb(" Structure: %u", dbversion.expected_structure);
sLog.outErrorDb(" Content: %u", dbversion.expected_content);
sLog.outErrorDb(" Description: %s", dbversion.description.c_str());
sLog.outErrorDb();
sLog.outErrorDb("You are missing content updates or you have content updates beyond the expected core version.");
sLog.outErrorDb("It is recommended to run ALL database updates up to the required core version.");
sLog.outErrorDb("These updates are included in the database/%s/Updates folder.", dbversion.dbname.c_str());
};
return true;
}
bool Database::ExecuteStmt(const SqlStatementID& id, SqlStmtParameters* params)

View File

@ -25,6 +25,7 @@
#ifndef DATABASE_H
#define DATABASE_H
#include "revision.h"
#include "Threading/Threading.h"
#include "Utilities/UnorderedMapSet.h"
#include "Database/SqlDelayThread.h"
@ -43,6 +44,29 @@ class Database;
#define MAX_QUERY_LEN (32*1024)
enum DatabaseTypes
{
DATABASE_WORLD,
DATABASE_REALMD,
DATABASE_CHARACTER,
COUNT_DATABASES,
};
struct DBVersion
{
std::string dbname;
uint32 expected_version;
uint32 expected_structure;
uint32 expected_content;
std::string description;
};
const DBVersion databaseVersions[COUNT_DATABASES] = {
{ "World", WORLD_DB_VERSION_NR, WORLD_DB_STRUCTURE_NR, WORLD_DB_CONTENT_NR, WORLD_DB_UPDATE_DESCRIPTION }, // DATABASE_WORLD
{ "Realmd", REALMD_DB_VERSION_NR, REALMD_DB_STRUCTURE_NR, REALMD_DB_CONTENT_NR, WORLD_DB_UPDATE_DESCRIPTION }, // DATABASE_REALMD
{ "Character", CHAR_DB_VERSION_NR, CHAR_DB_STRUCTURE_NR, CHAR_DB_CONTENT_NR, WORLD_DB_UPDATE_DESCRIPTION }, // DATABASE_CHARACTER
};
/**
* @brief
*
@ -613,13 +637,12 @@ class Database
void ProcessResultQueue();
/**
* @brief
*
* @param table_name
* @param required_name
* @return bool
*/
bool CheckRequiredField(char const* table_name, char const* required_name);
* @brief Function to check that the database version matches expected core version
*
* @param DatabaseTypes
* @return bool
*/
bool CheckDatabaseVersion(DatabaseTypes database);
/**
* @brief
*

View File

@ -24,8 +24,20 @@
#ifndef MANGOS_H_REVISION
#define MANGOS_H_REVISION
#define REVISION_NR "21000"
#define REVISION_DB_CHARACTERS "required_21000_01_warden_action"
#define REVISION_DB_MANGOS "required_21000_18_Update_for_quest_502_and_5203"
#define REVISION_DB_REALMD "required_20150722_01_realmcharacters_remove_constraint"
#define REVISION_NR "21000"
#define REALMD_DB_VERSION_NR 21
#define REALMD_DB_STRUCTURE_NR 1
#define REALMD_DB_CONTENT_NR 0
#define REALMD_DB_UPDATE_DESCRIPTION "revision_refactor"
#define CHAR_DB_VERSION_NR 21
#define CHAR_DB_STRUCTURE_NR 1
#define CHAR_DB_CONTENT_NR 0
#define CHAR_DB_UPDATE_DESCRIPTION "revision_refactor"
#define WORLD_DB_VERSION_NR 21
#define WORLD_DB_STRUCTURE_NR 1
#define WORLD_DB_CONTENT_NR 0
#define WORLD_DB_UPDATE_DESCRIPTION "revision_refactor"
#endif // __REVISION_H__