diff options
author | Shauren <shauren.trinity@gmail.com> | 2017-01-11 23:45:03 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2017-01-11 23:45:03 +0100 |
commit | fcabeed7544285f3244465ccfc5337c59e63c6b0 (patch) | |
tree | 49d09527fb6e43738e12b52fbfc38030c0b4b46d /src/server/database/Database | |
parent | 1cb9d05e29a333a49014ca10230f8a490928c3d0 (diff) |
Core/DBLayer: Added new async query callback api
Diffstat (limited to 'src/server/database/Database')
-rw-r--r-- | src/server/database/Database/QueryCallback.cpp | 98 | ||||
-rw-r--r-- | src/server/database/Database/QueryCallback.h | 55 | ||||
-rw-r--r-- | src/server/database/Database/QueryCallbackProcessor.cpp | 41 | ||||
-rw-r--r-- | src/server/database/Database/QueryCallbackProcessor.h | 39 |
4 files changed, 233 insertions, 0 deletions
diff --git a/src/server/database/Database/QueryCallback.cpp b/src/server/database/Database/QueryCallback.cpp new file mode 100644 index 00000000000..92bb80a0b60 --- /dev/null +++ b/src/server/database/Database/QueryCallback.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2008-2017 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/>. + */ + +#include "QueryCallback.h" + +QueryCallbackNew::QueryCallbackNew(std::future<QueryResult>&& result) : _string(std::move(result)), _isPrepared(false) +{ +} + +QueryCallbackNew::QueryCallbackNew(std::future<PreparedQueryResult>&& result) : _prepared(std::move(result)), _isPrepared(true) +{ +} + +QueryCallbackNew::QueryCallbackNew(QueryCallbackNew&& right) +{ + MoveFrom(std::move(right)); +} + +QueryCallbackNew& QueryCallbackNew::operator=(QueryCallbackNew&& right) +{ + MoveFrom(std::move(right)); + return *this; +} + +QueryCallbackNew::~QueryCallbackNew() +{ + DestroyCurrentMember(); +} + +QueryCallbackNew&& QueryCallbackNew::WithCallback(std::function<void(QueryResult)>&& callback) +{ + ASSERT(!_isPrepared, "Attempted to set callback function for string query on a prepared async query"); + _string.Callback = std::move(callback); + return std::move(*this); +} + +QueryCallbackNew&& QueryCallbackNew::WithPreparedCallback(std::function<void(PreparedQueryResult)>&& callback) +{ + ASSERT(_isPrepared, "Attempted to set callback function for prepared query on a string async query"); + _prepared.Callback = std::move(callback); + return std::move(*this); +} + +QueryCallbackNew::Status QueryCallbackNew::InvokeIfReady() +{ + if (!_isPrepared) + { + if (_string.Result.valid() && _string.Result.wait_for(std::chrono::seconds(0)) == std::future_status::ready) + { + std::function<void(QueryResult)> cb(std::move(_string.Callback)); + cb(_string.Result.get()); + return !_string.Callback ? Completed : NextStep; + } + } + else + { + if (_prepared.Result.valid() && _prepared.Result.wait_for(std::chrono::seconds(0)) == std::future_status::ready) + { + std::function<void(PreparedQueryResult)> cb(std::move(_prepared.Callback)); + cb(_prepared.Result.get()); + return !_prepared.Callback ? Completed : NextStep; + } + } + + return NotReady; +} + +void QueryCallbackNew::MoveFrom(QueryCallbackNew&& other) +{ + DestroyCurrentMember(); + _isPrepared = other._isPrepared; + if (!_isPrepared) + _string = std::move(other._string); + else + _prepared = std::move(other._prepared); +} + +void QueryCallbackNew::DestroyCurrentMember() +{ + if (!_isPrepared) + _string.~String(); + else + _prepared.~Prepared(); +} diff --git a/src/server/database/Database/QueryCallback.h b/src/server/database/Database/QueryCallback.h index 73e53dbe3f4..a0aa69ee952 100644 --- a/src/server/database/Database/QueryCallback.h +++ b/src/server/database/Database/QueryCallback.h @@ -28,6 +28,61 @@ typedef std::promise<PreparedQueryResult> PreparedQueryResultPromise; #define CALLBACK_STAGE_INVALID uint8(-1) +class TC_DATABASE_API QueryCallbackNew +{ + struct String + { + explicit String(std::future<QueryResult>&& result) : Result(std::move(result)) { } + String(String&&) = default; + String& operator=(String&&) = default; + ~String() { } + + std::future<QueryResult> Result; + std::function<void(QueryResult)> Callback; + }; + + struct Prepared + { + explicit Prepared(std::future<PreparedQueryResult>&& result) : Result(std::move(result)) { } + Prepared(Prepared&&) = default; + Prepared& operator=(Prepared&&) = default; + ~Prepared() { } + + std::future<PreparedQueryResult> Result; + std::function<void(PreparedQueryResult)> Callback; + }; + +public: + explicit QueryCallbackNew(std::future<QueryResult>&& result); + explicit QueryCallbackNew(std::future<PreparedQueryResult>&& result); + QueryCallbackNew(QueryCallbackNew&& right); + QueryCallbackNew& operator=(QueryCallbackNew&& right); + ~QueryCallbackNew(); + + QueryCallbackNew&& WithCallback(std::function<void(QueryResult)>&& callback); + QueryCallbackNew&& WithPreparedCallback(std::function<void(PreparedQueryResult)>&& callback); + + enum Status + { + NotReady, + NextStep, + Completed + }; + + Status InvokeIfReady(); + +private: + void MoveFrom(QueryCallbackNew&& other); + void DestroyCurrentMember(); + + union + { + String _string; + Prepared _prepared; + }; + bool _isPrepared; +}; + template <typename Result, typename ParamType, bool chain = false> class QueryCallback { diff --git a/src/server/database/Database/QueryCallbackProcessor.cpp b/src/server/database/Database/QueryCallbackProcessor.cpp new file mode 100644 index 00000000000..0eaa1c2352c --- /dev/null +++ b/src/server/database/Database/QueryCallbackProcessor.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2008-2017 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/>. + */ + +#include "QueryCallbackProcessor.h" +#include "QueryCallback.h" +#include <algorithm> + +QueryCallbackProcessor::QueryCallbackProcessor() +{ +} + +QueryCallbackProcessor::~QueryCallbackProcessor() +{ +} + +void QueryCallbackProcessor::AddQuery(QueryCallbackNew&& query) +{ + _callbacks.emplace_back(std::move(query)); +} + +void QueryCallbackProcessor::ProcessReadyQueries() +{ + _callbacks.erase(std::remove_if(_callbacks.begin(), _callbacks.end(), [](QueryCallbackNew& callback) + { + return callback.InvokeIfReady() == QueryCallbackNew::Completed; + }), _callbacks.end()); +} diff --git a/src/server/database/Database/QueryCallbackProcessor.h b/src/server/database/Database/QueryCallbackProcessor.h new file mode 100644 index 00000000000..a570a3fc1b9 --- /dev/null +++ b/src/server/database/Database/QueryCallbackProcessor.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008-2017 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 QueryCallbackProcessor_h__ +#define QueryCallbackProcessor_h__ + +#include "Define.h" +#include <vector> + +class QueryCallbackNew; + +class TC_DATABASE_API QueryCallbackProcessor +{ +public: + QueryCallbackProcessor(); + ~QueryCallbackProcessor(); + + void AddQuery(QueryCallbackNew&& query); + void ProcessReadyQueries(); + +private: + std::vector<QueryCallbackNew> _callbacks; +}; + +#endif // QueryCallbackProcessor_h__ |