diff options
Diffstat (limited to 'src/server/database')
| -rw-r--r-- | src/server/database/Database/DatabaseWorkerPool.h | 6 | ||||
| -rw-r--r-- | src/server/database/Database/Implementation/WorldDatabase.cpp | 4 | ||||
| -rw-r--r-- | src/server/database/Database/QueryCallback.h | 209 | ||||
| -rw-r--r-- | src/server/database/Updater/DBUpdater.cpp | 14 | ||||
| -rw-r--r-- | src/server/database/Updater/UpdateFetcher.cpp | 16 | ||||
| -rw-r--r-- | src/server/database/Updater/UpdateFetcher.h | 1 |
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; |
