Core/DBLayer: Add nicer api for SQLQueryHolders

This commit is contained in:
Shauren
2020-08-01 15:28:42 +02:00
committed by Ovahlord
parent 040140b4ea
commit 6d4b396f7b
8 changed files with 52 additions and 17 deletions

View File

@@ -86,6 +86,8 @@ using HotfixDatabaseQueryHolder = SQLQueryHolder<HotfixDatabaseConnection>;
using LoginDatabaseQueryHolder = SQLQueryHolder<LoginDatabaseConnection>;
using WorldDatabaseQueryHolder = SQLQueryHolder<WorldDatabaseConnection>;
class SQLQueryHolderCallback;
// mysql
struct MySQLHandle;
struct MySQLResult;

View File

@@ -223,7 +223,7 @@ QueryCallback DatabaseWorkerPool<T>::AsyncQuery(PreparedStatement<T>* stmt)
}
template <class T>
QueryResultHolderFuture DatabaseWorkerPool<T>::DelayQueryHolder(SQLQueryHolder<T>* holder)
SQLQueryHolderCallback DatabaseWorkerPool<T>::DelayQueryHolder(SQLQueryHolder<T>* holder)
{
SQLQueryHolderTask* task = new SQLQueryHolderTask(holder);
// Store future result before enqueueing - task might get already processed and deleted before returning from this method

View File

@@ -160,7 +160,7 @@ class DatabaseWorkerPool
//! return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
//! Any prepared statements added to this holder need to be prepared with the CONNECTION_ASYNC flag.
QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder<T>* holder);
SQLQueryHolderCallback DelayQueryHolder(SQLQueryHolder<T>* holder);
/**
Transaction context methods.

View File

@@ -92,3 +92,14 @@ bool SQLQueryHolderTask::Execute()
m_result.set_value(m_holder);
return true;
}
bool SQLQueryHolderCallback::InvokeIfReady()
{
if (m_future.valid() && m_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
m_callback(m_future.get());
return true;
}
return false;
}

View File

@@ -64,4 +64,23 @@ class TC_DATABASE_API SQLQueryHolderTask : public SQLOperation
QueryResultHolderFuture GetFuture() { return m_result.get_future(); }
};
class TC_DATABASE_API SQLQueryHolderCallback
{
public:
SQLQueryHolderCallback(QueryResultHolderFuture&& future) : m_future(std::move(future)) { }
SQLQueryHolderCallback(SQLQueryHolderCallback&&) = default;
SQLQueryHolderCallback& operator=(SQLQueryHolderCallback&&) = default;
void AfterComplete(std::function<void(SQLQueryHolderBase*)> callback) &
{
m_callback = std::move(callback);
}
bool InvokeIfReady();
QueryResultHolderFuture m_future;
std::function<void(SQLQueryHolderBase*)> m_callback;
};
#endif

View File

@@ -797,7 +797,10 @@ void WorldSession::HandleContinuePlayerLogin()
SendPacket(WorldPackets::Auth::ResumeComms(CONNECTION_TYPE_INSTANCE).Write());
_charLoginCallback = CharacterDatabase.DelayQueryHolder(holder);
AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase* holder)
{
HandlePlayerLogin(static_cast<LoginQueryHolder*>(holder));
});
}
void WorldSession::AbortLogin(WorldPackets::Character::LoginFailureReason reason)

View File

@@ -1124,13 +1124,7 @@ void WorldSession::ProcessQueryCallbacks()
{
_queryProcessor.ProcessReadyCallbacks();
_transactionCallbacks.ProcessReadyCallbacks();
if (_realmAccountLoginCallback.valid() && _realmAccountLoginCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
InitializeSessionCallback(static_cast<LoginDatabaseQueryHolder*>(_realmAccountLoginCallback.get()));
//! HandlePlayerLoginOpcode
if (_charLoginCallback.valid() && _charLoginCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
HandlePlayerLogin(reinterpret_cast<LoginQueryHolder*>(_charLoginCallback.get()));
_queryHolderProcessor.ProcessReadyCallbacks();
}
TransactionCallback& WorldSession::AddTransactionCallback(TransactionCallback&& callback)
@@ -1138,6 +1132,11 @@ TransactionCallback& WorldSession::AddTransactionCallback(TransactionCallback&&
return _transactionCallbacks.AddCallback(std::move(callback));
}
SQLQueryHolderCallback& WorldSession::AddQueryHolderCallback(SQLQueryHolderCallback&& callback)
{
return _queryHolderProcessor.AddCallback(std::move(callback));
}
void WorldSession::InitWarden(BigNumber* k, std::string const& os)
{
if (os == "Win")
@@ -1213,10 +1212,13 @@ void WorldSession::InitializeSession()
return;
}
_realmAccountLoginCallback = CharacterDatabase.DelayQueryHolder(realmHolder);
AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(realmHolder)).AfterComplete([this](SQLQueryHolderBase* holder)
{
InitializeSessionCallback(static_cast<AccountInfoQueryHolderPerRealm*>(holder));
});
}
void WorldSession::InitializeSessionCallback(LoginDatabaseQueryHolder* realmHolder)
void WorldSession::InitializeSessionCallback(CharacterDatabaseQueryHolder* realmHolder)
{
LoadAccountData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::GLOBAL_ACCOUNT_DATA), GLOBAL_CACHE_MASK);
LoadTutorialsData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS));

View File

@@ -417,7 +417,7 @@ class TC_GAME_API WorldSession
void SendClientCacheVersion(uint32 version);
void InitializeSession();
void InitializeSessionCallback(LoginDatabaseQueryHolder* realmHolder);
void InitializeSessionCallback(CharacterDatabaseQueryHolder* realmHolder);
rbac::RBACData* GetRBACData();
bool HasPermission(uint32 permissionId);
@@ -1212,6 +1212,7 @@ class TC_GAME_API WorldSession
public:
QueryCallbackProcessor& GetQueryProcessor() { return _queryProcessor; }
TransactionCallback& AddTransactionCallback(TransactionCallback&& callback);
SQLQueryHolderCallback& AddQueryHolderCallback(SQLQueryHolderCallback&& callback);
// Compact Unit Frames (4.x)
void HandleSaveCUFProfiles(WorldPacket& recvPacket);
@@ -1220,12 +1221,9 @@ class TC_GAME_API WorldSession
private:
void ProcessQueryCallbacks();
QueryResultHolderFuture _realmAccountLoginCallback;
QueryResultHolderFuture _guildRenameCallback;
QueryResultHolderFuture _charLoginCallback;
QueryCallbackProcessor _queryProcessor;
AsyncCallbackProcessor<TransactionCallback> _transactionCallbacks;
AsyncCallbackProcessor<SQLQueryHolderCallback> _queryHolderProcessor;
friend class World;
protected: