[Sync] Project Sync plus Revision changes

The main revision system changes are based on FoeReapers work in:
b37de3b83e
This commit is contained in:
Antz 2016-03-24 17:58:53 +00:00 committed by Antz
parent f5e2d53ccc
commit bf4b6fafc5
39 changed files with 684 additions and 416 deletions

View file

@ -149,7 +149,16 @@ typedef off_t ACE_OFF_T;
#endif
#define UI64FMTD ACE_UINT64_FORMAT_SPECIFIER
#if defined(__APPLE__)
# ifdef I64FMT
# undef I64FMT
# endif
# define I64FMT "%016llX"
# define UI64FMTD "%llu"
#else
# define UI64FMTD ACE_UINT64_FORMAT_SPECIFIER
#endif
#define UI64LIT(N) ACE_UINT64_LITERAL(N)
#define SI64FMTD ACE_INT64_FORMAT_SPECIFIER

View file

@ -50,7 +50,6 @@ bool DBCFileLoader::Load(const char* filename, const char* fmt)
}
EndianConvert(header);
if (header != 0x43424457) //'WDBC'
{
fclose(f);
@ -366,11 +365,9 @@ char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable, Loc
break;
case DBC_FF_STRING:
{
char** holder = *((char***)(&dataTable[offset]));
char** slot = &holder[loc];
// fill only not filled entries
if (*slot == nullStr)
char** slot = (char**)(&dataTable[offset]);
if (!*slot || !** slot)
{
const char* st = getRecord(y).getString(x);
*slot = stringPool + (st - (const char*)stringTable);

View file

@ -25,6 +25,7 @@
#include "DatabaseEnv.h"
#include "Config/Config.h"
#include "Database/SqlOperations.h"
#include "revision.h"
#include <ctime>
#include <iostream>
@ -34,6 +35,21 @@
#define MIN_CONNECTION_POOL_SIZE 1
#define MAX_CONNECTION_POOL_SIZE 16
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, REALMD_DB_UPDATE_DESCRIPTION }, // DATABASE_REALMD
{ "Character", CHAR_DB_VERSION_NR, CHAR_DB_STRUCTURE_NR, CHAR_DB_CONTENT_NR, CHAR_DB_UPDATE_DESCRIPTION }, // DATABASE_CHARACTER
};
//////////////////////////////////////////////////////////////////////////
SqlPreparedStatement* SqlConnection::CreateStatement(const std::string& fmt)
{
@ -178,6 +194,7 @@ void Database::InitDelayThread()
// New delay thread for delay execute
m_threadBody = CreateDelayThread(); // will deleted at m_delayThread delete
m_TransStorage = new ACE_TSS<Database::TransHelper>();
m_delayThread = new ACE_Based::Thread(m_threadBody);
}
@ -187,9 +204,11 @@ void Database::HaltDelayThread()
m_threadBody->Stop(); // Stop event
m_delayThread->wait(); // Wait for flush to DB
delete m_TransStorage;
delete m_delayThread; // This also deletes m_threadBody
m_delayThread = NULL;
m_threadBody = NULL;
m_TransStorage=NULL;
}
void Database::ThreadStart()
@ -333,7 +352,7 @@ bool Database::Execute(const char* sql)
if (!m_pAsyncConn)
{ return false; }
SqlTransaction* pTrans = m_TransStorage->get();
SqlTransaction* pTrans = (*m_TransStorage)->get();
if (pTrans)
{
// add SQL request to trans queue
@ -399,7 +418,7 @@ bool Database::BeginTransaction()
// initiate transaction on current thread
// currently we do not support queued transactions
m_TransStorage->init();
(*m_TransStorage)->init();
return true;
}
@ -409,7 +428,7 @@ bool Database::CommitTransaction()
{ return false; }
// check if we have pending transaction
if (!m_TransStorage->get())
if (!(*m_TransStorage)->get())
{ return false; }
// if async execution is not available
@ -417,7 +436,7 @@ bool Database::CommitTransaction()
{ return CommitTransactionDirect(); }
// add SqlTransaction to the async queue
m_threadBody->Delay(m_TransStorage->detach());
m_threadBody->Delay((*m_TransStorage)->detach());
return true;
}
@ -427,11 +446,11 @@ bool Database::CommitTransactionDirect()
{ return false; }
// check if we have pending transaction
if (!m_TransStorage->get())
if (!(*m_TransStorage)->get())
{ return false; }
// directly execute SqlTransaction
SqlTransaction* pTrans = m_TransStorage->detach();
SqlTransaction* pTrans = (*m_TransStorage)->detach();
pTrans->Execute(m_pAsyncConn);
delete pTrans;
@ -443,101 +462,93 @@ bool Database::RollbackTransaction()
if (!m_pAsyncConn)
{ return false; }
if (!m_TransStorage->get())
if (!(*m_TransStorage)->get())
{ return false; }
// remove scheduled transaction
m_TransStorage->reset();
(*m_TransStorage)->reset();
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 (version != dbversion.expected_version || 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 (content > dbversion.expected_content)
{
sLog.outErrorDb("You have not updated the core for few DB [%s] updates!", dbversion.dbname.c_str());
sLog.outErrorDb("Current DB content is %u, core expects %u", content, dbversion.expected_content);
sLog.outErrorDb("This is ok for now but should not last long.");
}
else if (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)
@ -545,7 +556,7 @@ bool Database::ExecuteStmt(const SqlStatementID& id, SqlStmtParameters* params)
if (!m_pAsyncConn)
{ return false; }
SqlTransaction* pTrans = m_TransStorage->get();
SqlTransaction* pTrans = (*m_TransStorage)->get();
if (pTrans)
{
// add SQL request to trans queue

View file

@ -43,6 +43,14 @@ class Database;
#define MAX_QUERY_LEN (32*1024)
enum DatabaseTypes
{
DATABASE_WORLD,
DATABASE_REALMD,
DATABASE_CHARACTER,
COUNT_DATABASES,
};
/**
* @brief
*
@ -613,13 +621,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
*
@ -651,7 +658,7 @@ class Database
Database() :
m_nQueryConnPoolSize(1), m_pAsyncConn(NULL), m_pResultQueue(NULL),
m_threadBody(NULL), m_delayThread(NULL), m_bAllowAsyncTransactions(false),
m_iStmtIndex(-1), m_logSQL(false), m_pingIntervallms(0)
m_iStmtIndex(-1), m_logSQL(false), m_pingIntervallms(0), m_TransStorage(NULL)
{
m_nQueryCounter = -1;
}
@ -679,7 +686,7 @@ class Database
* @brief
*
*/
class TransHelper
class TransHelper
{
public:
/**
@ -730,7 +737,7 @@ class Database
*
*/
typedef ACE_TSS<Database::TransHelper> DBTransHelperTSS;
Database::DBTransHelperTSS m_TransStorage; /**< TODO */
Database::DBTransHelperTSS *m_TransStorage; /**< TODO */
///< DB connections
/**
@ -781,7 +788,7 @@ class Database
SqlResultQueue* m_pResultQueue; /**< Transaction queues from diff. threads */
SqlDelayThread* m_threadBody; /**< Pointer to delay sql executer (owned by m_delayThread) */
ACE_Based::Thread* m_delayThread; /**< Pointer to executer thread */
ACE_Based::Thread* m_delayThread; /**< Pointer to executer thread */
bool m_bAllowAsyncTransactions; /**< flag which specifies if async transactions are enabled */

View file

@ -114,7 +114,7 @@ class Field
*
* @return int8
*/
int8 GetInt8() const { return mValue ? static_cast<int8>(atol(mValue)) : int8(0); }
int8 GetInt8() const { return mValue ? static_cast<int8>(atol(mValue)) : int8(0); }
/**
* @brief
*
@ -154,29 +154,29 @@ class Field
{
uint64 value = 0;
if (!mValue || sscanf(mValue, UI64FMTD, &value) == -1)
return 0;
{ return 0; }
return value;
}
}
/**
* @brief
*
* @return int64
*/
uint64 GetInt64() const
{
int64 value = 0;
if (!mValue || sscanf(mValue, SI64FMTD, &value) == -1)
return 0;
uint64 GetInt64() const
{
int64 value = 0;
if (!mValue || sscanf(mValue, SI64FMTD, &value) == -1)
return 0;
return value;
}
return value;
}
/**
* @brief
*
* @param type
*/
/**
* @brief
*
* @param type
*/
void SetType(enum DataTypes type) { mType = type; }
/**

View file

@ -162,7 +162,7 @@ void SQLStorage::prepareToLoad(uint32 maxRecordId, uint32 recordCount, uint32 re
// Set index array
m_Index = new char*[maxRecordId];
memset(m_Index, NULL, maxRecordId * sizeof(char*));
memset(m_Index, 0, maxRecordId * sizeof(char*));
SQLStorageBase::prepareToLoad(maxRecordId, recordCount, recordSize);
}

View file

@ -42,7 +42,7 @@
// Format is YYYYMMDDRR where RR is the change in the conf file
// for that day.
#ifndef MANGOSD_CONFIG_VERSION
# define MANGOSD_CONFIG_VERSION 2015010201
# define MANGOSD_CONFIG_VERSION 2016031901
#endif
#ifndef REALMD_CONFIG_VERSION
# define REALMD_CONFIG_VERSION 2010062001

View file

@ -131,7 +131,7 @@ Thread::~Thread()
}
// initialize Thread's class static member
Thread::ThreadStorage Thread::m_ThreadStorage;
Thread::ThreadStorage *Thread::m_ThreadStorage = NULL;
ThreadPriority Thread::m_TpEnum;
bool Thread::start()
@ -142,6 +142,8 @@ bool Thread::start()
// incRef before spawing the thread, otherwise Thread::ThreadTask() might call decRef and delete m_task
m_task->incReference();
m_ThreadStorage = new ACE_TSS<Thread>();
bool res = (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0);
if (res)
@ -160,6 +162,8 @@ bool Thread::wait()
m_iThreadId = 0;
m_hThreadHandle = 0;
delete m_ThreadStorage;
m_ThreadStorage = NULL;
return (_res == 0);
}
@ -174,6 +178,8 @@ void Thread::destroy()
m_iThreadId = 0;
m_hThreadHandle = 0;
delete m_ThreadStorage;
m_ThreadStorage = NULL;
// reference set at ACE_Thread::spawn
m_task->decReference();
@ -217,14 +223,14 @@ ACE_hthread_t Thread::currentHandle()
Thread* Thread::current()
{
Thread* _thread = m_ThreadStorage.ts_object();
Thread* _thread = (*m_ThreadStorage).ts_object();
if (!_thread)
{
_thread = new Thread();
_thread->m_iThreadId = Thread::currentId();
_thread->m_hThreadHandle = Thread::currentHandle();
Thread* _oldValue = m_ThreadStorage.ts_object(_thread);
Thread* _oldValue = (*m_ThreadStorage).ts_object(_thread);
delete _oldValue;
}

View file

@ -226,7 +226,7 @@ namespace ACE_Based
*
*/
typedef ACE_TSS<Thread> ThreadStorage;
static ThreadStorage m_ThreadStorage; /**< global object - container for Thread class representation of every thread */
static ThreadStorage *m_ThreadStorage; /**< global object - container for Thread class representation of every thread */
static ThreadPriority m_TpEnum; /**< use this object to determine current OS thread priority values mapped to enum Priority{} */
};
}

View file

@ -79,5 +79,5 @@ void BitStream::Print()
for (uint32 i = 0; i < GetLength(); ++i)
ss << uint32(GetBit(i)) << " ";
sLog.outDebug(ss.str().c_str());
sLog.outDebug("%s", ss.str().c_str());
}

View file

@ -41,7 +41,7 @@ class BarGoLink
*/
explicit BarGoLink(int row_count);
explicit BarGoLink(uint32 row_count); // row_count < ACE_INT32_MAX
explicit BarGoLink(uint64 row_count); // row_count < ACE_INT32_MAX
explicit BarGoLink(uint64 row_count); // row_count < ACE_INT64_MAX
/**
* @brief
*

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2016 MaNGOS project <https://getmangos.eu>
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
*
* 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
@ -422,17 +422,6 @@ bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr)
return true;
}
bool Utf8ToUpperOnlyLatin(std::string &utf8String)
{
std::wstring wstr;
if (!Utf8toWStr(utf8String, wstr))
return false;
std::transform(wstr.begin(), wstr.end(), wstr.begin(), wcharToUpperOnlyLatin);
return WStrToUtf8(wstr, utf8String);
}
bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str)
{
try

View file

@ -2,7 +2,7 @@
* MaNGOS is a full featured server for World of Warcraft, supporting
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
*
* Copyright (C) 2005-2016 MaNGOS project <https://getmangos.eu>
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
*
* 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
@ -282,13 +282,7 @@ inline bool Utf8toWStr(const std::string& utf8str, wchar_t* wstr, size_t& wsize)
{
return Utf8toWStr(utf8str.c_str(), utf8str.size(), wstr, wsize);
}
/**
* @brief
*
* @param utf8String
* @return bool
*/
bool Utf8ToUpperOnlyLatin(std::string &utf8String);
/**
* @brief
*

View file

@ -24,8 +24,20 @@
#ifndef MANGOS_H_REVISION
#define MANGOS_H_REVISION
#define REVISION_NR "12778"
#define REVISION_DB_CHARACTERS "required_12712_01_characters_characters"
#define REVISION_DB_MANGOS "required_12752_01_mangos_reputation_spillover_template"
#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 2
#define REALMD_DB_UPDATE_DESCRIPTION "dbdocs update"
#define CHAR_DB_VERSION_NR 21
#define CHAR_DB_STRUCTURE_NR 2
#define CHAR_DB_CONTENT_NR 1
#define CHAR_DB_UPDATE_DESCRIPTION "match_client_limits"
#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__