aboutsummaryrefslogtreecommitdiff
path: root/src/server/database
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/database')
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.h6
-rw-r--r--src/server/database/Database/Implementation/WorldDatabase.cpp4
-rw-r--r--src/server/database/Database/QueryCallback.h209
-rw-r--r--src/server/database/Updater/DBUpdater.cpp14
-rw-r--r--src/server/database/Updater/UpdateFetcher.cpp16
-rw-r--r--src/server/database/Updater/UpdateFetcher.h1
6 files changed, 224 insertions, 26 deletions
diff --git a/src/server/database/Database/DatabaseWorkerPool.h b/src/server/database/Database/DatabaseWorkerPool.h
index d883366237f..ffdde91c0a6 100644
--- a/src/server/database/Database/DatabaseWorkerPool.h
+++ b/src/server/database/Database/DatabaseWorkerPool.h
@@ -19,7 +19,7 @@
#define _DATABASEWORKERPOOL_H
#include "Common.h"
-#include "Callback.h"
+#include "QueryCallback.h"
#include "MySQLConnection.h"
#include "Transaction.h"
#include "DatabaseWorker.h"
@@ -120,7 +120,7 @@ class DatabaseWorkerPool
//! This method should only be used for queries that are only executed once, e.g during startup.
void DirectExecute(const char* sql)
{
- if (!sql)
+ if (Trinity::IsFormatEmptyOrNull(sql))
return;
T* connection = GetFreeConnection();
@@ -175,7 +175,7 @@ class DatabaseWorkerPool
template<typename Format, typename... Args>
QueryResult PQuery(Format&& sql, Args&&... args)
{
- if (!sql)
+ if (Trinity::IsFormatEmptyOrNull(sql))
return QueryResult(nullptr);
return Query(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str());
diff --git a/src/server/database/Database/Implementation/WorldDatabase.cpp b/src/server/database/Database/Implementation/WorldDatabase.cpp
index 7a183d5bf78..83720c1a996 100644
--- a/src/server/database/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/database/Database/Implementation/WorldDatabase.cpp
@@ -30,8 +30,8 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_SEL_SMARTAI_WP, "SELECT entry, pointid, position_x, position_y, position_z FROM waypoints ORDER BY entry, pointid", CONNECTION_SYNCH);
PrepareStatement(WORLD_DEL_GAMEOBJECT, "DELETE FROM gameobject WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_DEL_EVENT_GAMEOBJECT, "DELETE FROM game_event_gameobject WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(WORLD_INS_GRAVEYARD_ZONE, "INSERT INTO game_graveyard_zone (id, ghost_zone, faction) VALUES (?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(WORLD_DEL_GRAVEYARD_ZONE, "DELETE FROM game_graveyard_zone WHERE id = ? AND ghost_zone = ? AND faction = ?", CONNECTION_ASYNC);
+ PrepareStatement(WORLD_INS_GRAVEYARD_ZONE, "INSERT INTO graveyard_zone (ID, GhostZone, Faction) VALUES (?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(WORLD_DEL_GRAVEYARD_ZONE, "DELETE FROM graveyard_zone WHERE ID = ? AND GhostZone = ? AND Faction = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_INS_GAME_TELE, "INSERT INTO game_tele (id, position_x, position_y, position_z, orientation, map, name) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_DEL_GAME_TELE, "DELETE FROM game_tele WHERE name = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_INS_NPC_VENDOR, "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
diff --git a/src/server/database/Database/QueryCallback.h b/src/server/database/Database/QueryCallback.h
new file mode 100644
index 00000000000..5f6ae74da4f
--- /dev/null
+++ b/src/server/database/Database/QueryCallback.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _QUERY_CALLBACK_H
+#define _QUERY_CALLBACK_H
+
+#include <future>
+#include "QueryResult.h"
+
+typedef std::future<QueryResult> QueryResultFuture;
+typedef std::promise<QueryResult> QueryResultPromise;
+typedef std::future<PreparedQueryResult> PreparedQueryResultFuture;
+typedef std::promise<PreparedQueryResult> PreparedQueryResultPromise;
+
+#define CALLBACK_STAGE_INVALID uint8(-1)
+
+template <typename Result, typename ParamType, bool chain = false>
+class QueryCallback
+{
+ public:
+ QueryCallback() : _param(), _stage(chain ? 0 : CALLBACK_STAGE_INVALID) { }
+
+ //! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
+ void SetFutureResult(std::future<Result> value)
+ {
+ _result = std::move(value);
+ }
+
+ std::future<Result>& GetFutureResult()
+ {
+ return _result;
+ }
+
+ int IsReady()
+ {
+ return _result.valid() && _result.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
+ }
+
+ void GetResult(Result& res)
+ {
+ res = _result.get();
+ }
+
+ void FreeResult()
+ {
+ // Nothing to do here, the constructor of std::future will take care of the cleanup
+ }
+
+ void SetParam(ParamType value)
+ {
+ _param = value;
+ }
+
+ ParamType GetParam()
+ {
+ return _param;
+ }
+
+ //! Resets the stage of the callback chain
+ void ResetStage()
+ {
+ if (!chain)
+ return;
+
+ _stage = 0;
+ }
+
+ //! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
+ void NextStage()
+ {
+ if (!chain)
+ return;
+
+ ++_stage;
+ }
+
+ //! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
+ uint8 GetStage()
+ {
+ return _stage;
+ }
+
+ //! Resets all underlying variables (param, result and stage)
+ void Reset()
+ {
+ SetParam(ParamType());
+ FreeResult();
+ ResetStage();
+ }
+
+ private:
+ std::future<Result> _result;
+ ParamType _param;
+ uint8 _stage;
+
+ QueryCallback(QueryCallback const& right) = delete;
+ QueryCallback& operator=(QueryCallback const& right) = delete;
+};
+
+template <typename Result, typename ParamType1, typename ParamType2, bool chain = false>
+class QueryCallback_2
+{
+ public:
+ QueryCallback_2() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) { }
+
+ //! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
+ void SetFutureResult(std::future<Result> value)
+ {
+ _result = std::move(value);
+ }
+
+ std::future<Result>& GetFutureResult()
+ {
+ return _result;
+ }
+
+ int IsReady()
+ {
+ return _result.valid() && _result.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
+ }
+
+ void GetResult(Result& res)
+ {
+ res = _result.get();
+ }
+
+ void FreeResult()
+ {
+ // Nothing to do here, the constructor of std::future will take care of the cleanup
+ }
+
+ void SetFirstParam(ParamType1 value)
+ {
+ _param_1 = value;
+ }
+
+ void SetSecondParam(ParamType2 value)
+ {
+ _param_2 = value;
+ }
+
+ ParamType1 GetFirstParam()
+ {
+ return _param_1;
+ }
+
+ ParamType2 GetSecondParam()
+ {
+ return _param_2;
+ }
+
+ //! Resets the stage of the callback chain
+ void ResetStage()
+ {
+ if (!chain)
+ return;
+
+ _stage = 0;
+ }
+
+ //! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
+ void NextStage()
+ {
+ if (!chain)
+ return;
+
+ ++_stage;
+ }
+
+ //! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
+ uint8 GetStage()
+ {
+ return _stage;
+ }
+
+ //! Resets all underlying variables (param, result and stage)
+ void Reset()
+ {
+ SetFirstParam(NULL);
+ SetSecondParam(NULL);
+ FreeResult();
+ ResetStage();
+ }
+
+ private:
+ std::future<Result> _result;
+ ParamType1 _param_1;
+ ParamType2 _param_2;
+ uint8 _stage;
+
+ QueryCallback_2(QueryCallback_2 const& right) = delete;
+ QueryCallback_2& operator=(QueryCallback_2 const& right) = delete;
+};
+
+#endif // _QUERY_CALLBACK_H
diff --git a/src/server/database/Updater/DBUpdater.cpp b/src/server/database/Updater/DBUpdater.cpp
index 3be81e85715..85213a7f709 100644
--- a/src/server/database/Updater/DBUpdater.cpp
+++ b/src/server/database/Updater/DBUpdater.cpp
@@ -55,7 +55,7 @@ bool DBUpdaterUtil::CheckExecutable()
}
}
- TC_LOG_FATAL("sql.updates", "Didn't find executeable mysql binary at \'%s\' or in path, correct the path in the *.conf (\"Updates.MySqlCLIPath\").",
+ TC_LOG_FATAL("sql.updates", "Didn't find any executable MySQL binary at \'%s\' or in path, correct the path in the *.conf (\"MySQLExecutable\").",
absolute(exe).generic_string().c_str());
return false;
@@ -178,7 +178,7 @@ bool DBUpdater<T>::Create(DatabaseWorkerPool<T>& pool)
// Path of temp file
static Path const temp("create_table.sql");
- // Create temporary query to use external mysql cli
+ // Create temporary query to use external MySQL CLi
std::ofstream file(temp.generic_string());
if (!file.is_open())
{
@@ -197,7 +197,7 @@ bool DBUpdater<T>::Create(DatabaseWorkerPool<T>& pool)
}
catch (UpdateException&)
{
- TC_LOG_FATAL("sql.updates", "Failed to create database %s! Has the user `CREATE` priviliges?", pool.GetConnectionInfo()->database.c_str());
+ TC_LOG_FATAL("sql.updates", "Failed to create database %s! Does the user (named in *.conf) have `CREATE` privileges on the MySQL server?", pool.GetConnectionInfo()->database.c_str());
boost::filesystem::remove(temp);
return false;
}
@@ -280,7 +280,7 @@ bool DBUpdater<T>::Populate(DatabaseWorkerPool<T>& pool)
{
case LOCATION_REPOSITORY:
{
- TC_LOG_ERROR("sql.updates", ">> Base file \"%s\" is missing, try to clone the source again.",
+ TC_LOG_ERROR("sql.updates", ">> Base file \"%s\" is missing. Try fixing it by cloning the source again.",
base.generic_string().c_str());
break;
@@ -288,7 +288,7 @@ bool DBUpdater<T>::Populate(DatabaseWorkerPool<T>& pool)
case LOCATION_DOWNLOAD:
{
TC_LOG_ERROR("sql.updates", ">> File \"%s\" is missing, download it from \"https://github.com/TrinityCore/TrinityCore/releases\"" \
- " and place it in your server directory.", base.filename().generic_string().c_str());
+ " and place it in your worldserver directory.", base.filename().generic_string().c_str());
break;
}
}
@@ -355,7 +355,7 @@ void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& hos
if (!std::isdigit(port_or_socket[0]))
{
- // We can't check here if host == "." because is named localhost if socket option is enabled
+ // We can't check if host == "." here, because it is named localhost if socket option is enabled
args.push_back("-P0");
args.push_back("--protocol=SOCKET");
args.push_back("-S" + port_or_socket);
@@ -383,7 +383,7 @@ void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& hos
if (ret != EXIT_SUCCESS)
{
TC_LOG_FATAL("sql.updates", "Applying of file \'%s\' to database \'%s\' failed!" \
- " If you are an user pull the latest revision from the repository. If you are a developer fix your sql query.",
+ " If you are a user, pull the latest revision from the repository. If you are a developer, fix your sql query.",
path.generic_string().c_str(), pool.GetConnectionInfo()->database.c_str());
throw UpdateException("update failed");
diff --git a/src/server/database/Updater/UpdateFetcher.cpp b/src/server/database/Updater/UpdateFetcher.cpp
index 6f67867c52b..7dc0a307ca2 100644
--- a/src/server/database/Updater/UpdateFetcher.cpp
+++ b/src/server/database/Updater/UpdateFetcher.cpp
@@ -18,6 +18,7 @@
#include "UpdateFetcher.h"
#include "Log.h"
#include "Util.h"
+#include "SHA1.h"
#include <fstream>
#include <chrono>
@@ -25,7 +26,6 @@
#include <sstream>
#include <exception>
#include <unordered_map>
-#include <openssl/sha.h>
using namespace boost::filesystem;
@@ -209,9 +209,8 @@ UpdateResult UpdateFetcher::Update(bool const redundancyChecks,
}
}
- // Calculate hash
- std::string const hash =
- CalculateHash(ReadSQLUpdate(availableQuery.first));
+ // Calculate a Sha1 hash based on query content.
+ std::string const hash = CalculateSHA1Hash(ReadSQLUpdate(availableQuery.first));
UpdateMode mode = MODE_APPLY;
@@ -334,15 +333,6 @@ UpdateResult UpdateFetcher::Update(bool const redundancyChecks,
return UpdateResult(importedUpdates, countRecentUpdates, countArchivedUpdates);
}
-std::string UpdateFetcher::CalculateHash(std::string const& query) const
-{
- // Calculate a Sha1 hash based on query content.
- unsigned char digest[SHA_DIGEST_LENGTH];
- SHA1((unsigned char*)query.c_str(), query.length(), (unsigned char*)&digest);
-
- return ByteArrayToHexStr(digest, SHA_DIGEST_LENGTH);
-}
-
uint32 UpdateFetcher::Apply(Path const& path) const
{
using Time = std::chrono::high_resolution_clock;
diff --git a/src/server/database/Updater/UpdateFetcher.h b/src/server/database/Updater/UpdateFetcher.h
index a17658818ce..cabc3c2fce3 100644
--- a/src/server/database/Updater/UpdateFetcher.h
+++ b/src/server/database/Updater/UpdateFetcher.h
@@ -112,7 +112,6 @@ private:
AppliedFileStorage ReceiveAppliedFiles() const;
std::string ReadSQLUpdate(Path const& file) const;
- std::string CalculateHash(std::string const& query) const;
uint32 Apply(Path const& path) const;