AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
DatabaseWorkerPool< T > Class Template Reference

#include "DatabaseWorkerPool.h"

Public Types

typedef T::Statements PreparedStatementIndex
 

Public Member Functions

 DatabaseWorkerPool ()
 
 ~DatabaseWorkerPool ()
 
void SetConnectionInfo (std::string_view infoString, uint8 const asyncThreads, uint8 const synchThreads)
 
uint32 Open ()
 
void Close ()
 
bool PrepareStatements ()
 Prepares all prepared statements.
 
MySQLConnectionInfo const * GetConnectionInfo () const
 
void Execute (std::string_view sql)
 
template<typename... Args>
void Execute (std::string_view sql, Args &&... args)
 
void Execute (PreparedStatement< T > *stmt)
 
void DirectExecute (std::string_view sql)
 
template<typename... Args>
void DirectExecute (std::string_view sql, Args &&... args)
 
void DirectExecute (PreparedStatement< T > *stmt)
 
QueryResult Query (std::string_view sql)
 
template<typename... Args>
QueryResult Query (std::string_view sql, Args &&... args)
 
PreparedQueryResult Query (PreparedStatement< T > *stmt)
 
QueryCallback AsyncQuery (std::string_view sql)
 
QueryCallback AsyncQuery (PreparedStatement< T > *stmt)
 
SQLQueryHolderCallback DelayQueryHolder (std::shared_ptr< SQLQueryHolder< T > > holder)
 
SQLTransaction< T > BeginTransaction ()
 Begins an automanaged transaction pointer that will automatically rollback if not commited. (Autocommit=0)
 
void CommitTransaction (SQLTransaction< T > transaction)
 
TransactionCallback AsyncCommitTransaction (SQLTransaction< T > transaction)
 
void DirectCommitTransaction (SQLTransaction< T > &transaction)
 
void ExecuteOrAppend (SQLTransaction< T > &trans, std::string_view sql)
 
void ExecuteOrAppend (SQLTransaction< T > &trans, PreparedStatement< T > *stmt)
 
PreparedStatement< T > * GetPreparedStatement (PreparedStatementIndex index)
 
void EscapeString (std::string &str)
 Apply escape string'ing for current collation. (utf8)
 
void KeepAlive ()
 Keeps all our MySQL connections alive, prevent the server from disconnecting us.
 
void WarnAboutSyncQueries (bool warn)
 
std::size_t QueueSize () const
 

Private Types

enum  InternalIndex {
  IDX_ASYNC ,
  IDX_SYNCH ,
  IDX_SIZE
}
 

Private Member Functions

uint32 OpenConnections (InternalIndex type, uint8 numConnections)
 
unsigned long EscapeString (char *to, char const *from, unsigned long length)
 
void Enqueue (SQLOperation *op)
 
T * GetFreeConnection ()
 
std::string_view GetDatabaseName () const
 

Private Attributes

std::unique_ptr< ProducerConsumerQueue< SQLOperation * > > _queue
 Queue shared by async worker threads.
 
std::array< std::vector< std::unique_ptr< T > >, IDX_SIZE_connections
 
std::unique_ptr< MySQLConnectionInfo_connectionInfo
 
std::vector< uint8_preparedStatementSize
 
uint8 _async_threads
 
uint8 _synch_threads
 

Detailed Description

template<class T>
class DatabaseWorkerPool< T >

Member Typedef Documentation

◆ PreparedStatementIndex

template<class T >
typedef T::Statements DatabaseWorkerPool< T >::PreparedStatementIndex

Other

Member Enumeration Documentation

◆ InternalIndex

template<class T >
enum DatabaseWorkerPool::InternalIndex
private
Enumerator
IDX_ASYNC 
IDX_SYNCH 
IDX_SIZE 
52 {
56 };
@ IDX_ASYNC
Definition DatabaseWorkerPool.h:53
@ IDX_SIZE
Definition DatabaseWorkerPool.h:55
@ IDX_SYNCH
Definition DatabaseWorkerPool.h:54

Constructor & Destructor Documentation

◆ DatabaseWorkerPool()

template<class T >
DatabaseWorkerPool< T >::DatabaseWorkerPool ( )
55 :
59{
60 WPFatal(mysql_thread_safe(), "Used MySQL library isn't thread-safe.");
61
62 bool isSupportClientDB = mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION;
63 bool isSameClientDB = mysql_get_client_version() == MYSQL_VERSION_ID;
64
65 WPFatal(isSupportClientDB, "AzerothCore does not support MySQL versions below 8.0\n\nFound version: {} / {}. Server compiled with: {}.\nSearch the wiki for ACE00043 in Common Errors (https://www.azerothcore.org/wiki/common-errors#ace00043).",
66 mysql_get_client_info(), mysql_get_client_version(), MYSQL_VERSION_ID);
67 WPFatal(isSameClientDB, "Used MySQL library version ({} id {}) does not match the version id used to compile AzerothCore (id {}).\nSearch the wiki for ACE00046 in Common Errors (https://www.azerothcore.org/wiki/common-errors#ace00046).",
68 mysql_get_client_info(), mysql_get_client_version(), MYSQL_VERSION_ID);
69}
#define MIN_MYSQL_CLIENT_VERSION
Definition DatabaseWorkerPool.h:33
#define WPFatal(cond,...)
Definition Errors.h:59
uint8 _synch_threads
Definition DatabaseWorkerPool.h:236
uint8 _async_threads
Definition DatabaseWorkerPool.h:236
std::unique_ptr< ProducerConsumerQueue< SQLOperation * > > _queue
Queue shared by async worker threads.
Definition DatabaseWorkerPool.h:232
Definition PCQueue.h:28

References MIN_MYSQL_CLIENT_VERSION, and WPFatal.

◆ ~DatabaseWorkerPool()

template<class T >
DatabaseWorkerPool< T >::~DatabaseWorkerPool ( )
73{
74 _queue->Cancel();
75}

Member Function Documentation

◆ AsyncCommitTransaction()

template<class T >
TransactionCallback DatabaseWorkerPool< T >::AsyncCommitTransaction ( SQLTransaction< T >  transaction)

Enqueues a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations were appended to the transaction will be respected during execution.

277{
278#ifdef ACORE_DEBUG
282 switch (transaction->GetSize())
283 {
284 case 0:
285 LOG_DEBUG("sql.driver", "Transaction contains 0 queries. Not executing.");
286 break;
287 case 1:
288 LOG_DEBUG("sql.driver", "Warning: Transaction only holds 1 query, consider removing Transaction context in code.");
289 break;
290 default:
291 break;
292 }
293#endif // ACORE_DEBUG
294
296 TransactionFuture result = task->GetFuture();
297 Enqueue(task);
298 return TransactionCallback(std::move(result));
299}
std::future< bool > TransactionFuture
Definition DatabaseEnvFwd.h:58
#define LOG_DEBUG(filterType__,...)
Definition Log.h:169
void Enqueue(SQLOperation *op)
Definition DatabaseWorkerPool.cpp:469
Definition Transaction.h:109
Definition Transaction.h:96
TransactionFuture GetFuture()
Definition Transaction.h:100

References TransactionWithResultTask::GetFuture(), and LOG_DEBUG.

◆ AsyncQuery() [1/2]

template<class T >
QueryCallback DatabaseWorkerPool< T >::AsyncQuery ( PreparedStatement< T > *  stmt)

Enqueues a query in prepared format that will set the value of the PreparedQueryResultFuture return object as soon as the query is executed. The return value is then processed in ProcessQueryCallback methods. Statement must be prepared with CONNECTION_ASYNC flag.

228{
229 PreparedStatementTask* task = new PreparedStatementTask(stmt, true);
230 // Store future result before enqueueing - task might get already processed and deleted before returning from this method
231 PreparedQueryResultFuture result = task->GetFuture();
232 Enqueue(task);
233 return QueryCallback(std::move(result));
234}
std::future< PreparedQueryResult > PreparedQueryResultFuture
Definition DatabaseEnvFwd.h:46
Definition PreparedStatement.h:170
PreparedQueryResultFuture GetFuture()
Definition PreparedStatement.h:176
Definition QueryCallback.h:29

References PreparedStatementTask::GetFuture().

◆ AsyncQuery() [2/2]

template<class T >
QueryCallback DatabaseWorkerPool< T >::AsyncQuery ( std::string_view  sql)

Asynchronous query (with resultset) methods. Enqueues a query in string format that will set the value of the QueryResultFuture return object as soon as the query is executed. The return value is then processed in ProcessQueryCallback methods.

218{
219 BasicStatementTask* task = new BasicStatementTask(sql, true);
220 // Store future result before enqueueing - task might get already processed and deleted before returning from this method
221 QueryResultFuture result = task->GetFuture();
222 Enqueue(task);
223 return QueryCallback(std::move(result));
224}
std::future< QueryResult > QueryResultFuture
Definition DatabaseEnvFwd.h:28
Definition AdhocStatement.h:27
QueryResultFuture GetFuture() const
Definition AdhocStatement.h:33

References BasicStatementTask::GetFuture().

◆ BeginTransaction()

template<class T >
SQLTransaction< T > DatabaseWorkerPool< T >::BeginTransaction ( )

Begins an automanaged transaction pointer that will automatically rollback if not commited. (Autocommit=0)

Transaction context methods.

248{
249 return std::make_shared<Transaction<T>>();
250}

◆ Close()

template<class T >
void DatabaseWorkerPool< T >::Close ( )

Closes the actualy MySQL connection.

Shut down the synchronous connections There's no need for locking the connection, because DatabaseWorkerPool<>::Close should only be called after any other thread tasks in the core have exited, meaning there can be no concurrent access at this point.

114{
115 LOG_INFO("sql.driver", "Closing down DatabasePool '{}'. Waiting for {} queries to finish...", GetDatabaseName(), _queue->Size());
116
117 // Gracefully close async query queue, worker threads will block when the destructor
118 // is called from the .clear() functions below until the queue is empty
119 _queue->Shutdown();
120
122 _connections[IDX_ASYNC].clear();
123
124 LOG_INFO("sql.driver", "Asynchronous connections on DatabasePool '{}' terminated. Proceeding with synchronous connections.",
126
131 _connections[IDX_SYNCH].clear();
132
133 LOG_INFO("sql.driver", "All connections on DatabasePool '{}' closed.", GetDatabaseName());
134}
#define LOG_INFO(filterType__,...)
Definition Log.h:165
std::array< std::vector< std::unique_ptr< T > >, IDX_SIZE > _connections
Definition DatabaseWorkerPool.h:233
std::string_view GetDatabaseName() const
Definition DatabaseWorkerPool.cpp:509

References LOG_INFO.

Referenced by DatabaseLoader::AddDatabase().

◆ CommitTransaction()

template<class T >
void DatabaseWorkerPool< T >::CommitTransaction ( SQLTransaction< T >  transaction)

Enqueues a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations were appended to the transaction will be respected during execution.

254{
255#ifdef ACORE_DEBUG
259 switch (transaction->GetSize())
260 {
261 case 0:
262 LOG_DEBUG("sql.driver", "Transaction contains 0 queries. Not executing.");
263 return;
264 case 1:
265 LOG_DEBUG("sql.driver", "Warning: Transaction only holds 1 query, consider removing Transaction context in code.");
266 break;
267 default:
268 break;
269 }
270#endif // ACORE_DEBUG
271
272 Enqueue(new TransactionTask(transaction));
273}
Definition Transaction.h:75

References LOG_DEBUG.

◆ DelayQueryHolder()

template<class T >
SQLQueryHolderCallback DatabaseWorkerPool< T >::DelayQueryHolder ( std::shared_ptr< SQLQueryHolder< T > >  holder)

Enqueues a vector of SQL operations (can be both adhoc and prepared) that will set the value of the QueryResultHolderFuture 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.

238{
239 SQLQueryHolderTask* task = new SQLQueryHolderTask(holder);
240 // Store future result before enqueueing - task might get already processed and deleted before returning from this method
241 QueryResultHolderFuture result = task->GetFuture();
242 Enqueue(task);
243 return { std::move(holder), std::move(result) };
244}
std::future< void > QueryResultHolderFuture
Definition DatabaseEnvFwd.h:74
Definition QueryHolder.h:53
QueryResultHolderFuture GetFuture()
Definition QueryHolder.h:61

References SQLQueryHolderTask::GetFuture().

◆ DirectCommitTransaction()

template<class T >
void DatabaseWorkerPool< T >::DirectCommitTransaction ( SQLTransaction< T > &  transaction)

Directly executes a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations were appended to the transaction will be respected during execution.

Handle MySQL Errno 1213 without extending deadlock to the core itself

Todo:
More elegant way

Clean up now.

303{
304 T* connection = GetFreeConnection();
305 int errorCode = connection->ExecuteTransaction(transaction);
306
307 if (!errorCode)
308 {
309 connection->Unlock(); // OK, operation succesful
310 return;
311 }
312
315 if (errorCode == ER_LOCK_DEADLOCK)
316 {
317 //todo: handle multiple sync threads deadlocking in a similar way as async threads
318 uint8 loopBreaker = 5;
319
320 for (uint8 i = 0; i < loopBreaker; ++i)
321 {
322 if (!connection->ExecuteTransaction(transaction))
323 break;
324 }
325 }
326
328 transaction->Cleanup();
329
330 connection->Unlock();
331}
std::uint8_t uint8
Definition Define.h:109
T * GetFreeConnection()
Definition DatabaseWorkerPool.cpp:481

◆ DirectExecute() [1/3]

template<class T >
void DatabaseWorkerPool< T >::DirectExecute ( PreparedStatement< T > *  stmt)

Directly executes a one-way SQL operation in prepared statement format, that will block the calling thread until finished. Statement must be prepared with the CONNECTION_SYNCH flag.

Delete proxy-class. Not needed anymore

544{
545 T* connection = GetFreeConnection();
546 connection->Execute(stmt);
547 connection->Unlock();
548
550 delete stmt;
551}

◆ DirectExecute() [2/3]

template<class T >
void DatabaseWorkerPool< T >::DirectExecute ( std::string_view  sql)

Direct synchronous one-way statement methods. Directly executes a one-way SQL operation in string format, that will block the calling thread until finished. This method should only be used for queries that are only executed once, e.g during startup.

533{
534 if (sql.empty())
535 return;
536
537 T* connection = GetFreeConnection();
538 connection->Execute(sql);
539 connection->Unlock();
540}

Referenced by DBUpdater< T >::Apply(), and DatabaseWorkerPool< T >::DirectExecute().

◆ DirectExecute() [3/3]

template<class T >
template<typename... Args>
void DatabaseWorkerPool< T >::DirectExecute ( std::string_view  sql,
Args &&...  args 
)
inline

Directly executes a one-way SQL operation in string format -with variable args-, that will block the calling thread until finished. This method should only be used for queries that are only executed once, e.g during startup.

111 {
112 if (sql.empty())
113 return;
114
115 DirectExecute(Acore::StringFormat(sql, std::forward<Args>(args)...));
116 }
void DirectExecute(std::string_view sql)
Definition DatabaseWorkerPool.cpp:532
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default AC string format function.
Definition StringFormat.h:34

References DatabaseWorkerPool< T >::DirectExecute(), and Acore::StringFormat().

◆ Enqueue()

template<class T >
void DatabaseWorkerPool< T >::Enqueue ( SQLOperation op)
private
470{
471 _queue->Push(op);
472}

◆ EscapeString() [1/2]

template<class T >
unsigned long DatabaseWorkerPool< T >::EscapeString ( char *  to,
char const *  from,
unsigned long  length 
)
private
461{
462 if (!to || !from || !length)
463 return 0;
464
465 return _connections[IDX_SYNCH].front()->EscapeString(to, from, length);
466}

◆ EscapeString() [2/2]

template<class T >
void DatabaseWorkerPool< T >::EscapeString ( std::string &  str)

Apply escape string'ing for current collation. (utf8)

341{
342 if (str.empty())
343 return;
344
345 char* buf = new char[str.size() * 2 + 1];
346 EscapeString(buf, str.c_str(), uint32(str.size()));
347 str = buf;
348 delete[] buf;
349}
std::uint32_t uint32
Definition Define.h:107
void EscapeString(std::string &str)
Apply escape string'ing for current collation. (utf8)
Definition DatabaseWorkerPool.cpp:340

◆ Execute() [1/3]

template<class T >
void DatabaseWorkerPool< T >::Execute ( PreparedStatement< T > *  stmt)

Enqueues a one-way SQL operation in prepared statement format that will be executed asynchronously. Statement must be prepared with CONNECTION_ASYNC flag.

526{
528 Enqueue(task);
529}

◆ Execute() [2/3]

template<class T >
void DatabaseWorkerPool< T >::Execute ( std::string_view  sql)

Delayed one-way statement methods. Enqueues a one-way SQL operation in string format that will be executed asynchronously. This method should only be used for queries that are only executed once, e.g during startup.

516{
517 if (sql.empty())
518 return;
519
520 BasicStatementTask* task = new BasicStatementTask(sql);
521 Enqueue(task);
522}

Referenced by DatabaseWorkerPool< T >::Execute().

◆ Execute() [3/3]

template<class T >
template<typename... Args>
void DatabaseWorkerPool< T >::Execute ( std::string_view  sql,
Args &&...  args 
)
inline

Enqueues a one-way SQL operation in string format -with variable args- that will be executed asynchronously. This method should only be used for queries that are only executed once, e.g during startup.

88 {
89 if (sql.empty())
90 return;
91
92 Execute(Acore::StringFormat(sql, std::forward<Args>(args)...));
93 }
void Execute(std::string_view sql)
Definition DatabaseWorkerPool.cpp:515

References DatabaseWorkerPool< T >::Execute(), and Acore::StringFormat().

◆ ExecuteOrAppend() [1/2]

template<class T >
void DatabaseWorkerPool< T >::ExecuteOrAppend ( SQLTransaction< T > &  trans,
PreparedStatement< T > *  stmt 
)

Method used to execute prepared statements in a diverse context. Will be wrapped in a transaction if valid object is present, otherwise executed standalone.

564{
565 if (!trans)
566 Execute(stmt);
567 else
568 trans->Append(stmt);
569}

◆ ExecuteOrAppend() [2/2]

template<class T >
void DatabaseWorkerPool< T >::ExecuteOrAppend ( SQLTransaction< T > &  trans,
std::string_view  sql 
)

Method used to execute ad-hoc statements in a diverse context. Will be wrapped in a transaction if valid object is present, otherwise executed standalone.

555{
556 if (!trans)
557 Execute(sql);
558 else
559 trans->Append(sql);
560}

◆ GetConnectionInfo()

template<class T >
MySQLConnectionInfo const * DatabaseWorkerPool< T >::GetConnectionInfo ( ) const
inline
72 {
73 return _connectionInfo.get();
74 }
std::unique_ptr< MySQLConnectionInfo > _connectionInfo
Definition DatabaseWorkerPool.h:234

References DatabaseWorkerPool< T >::_connectionInfo.

Referenced by DBUpdater< T >::ApplyFile(), DBUpdater< T >::ApplyFile(), DBUpdater< T >::Create(), and DBUpdater< T >::Update().

◆ GetDatabaseName()

template<class T >
std::string_view DatabaseWorkerPool< T >::GetDatabaseName ( ) const
private
510{
511 return std::string_view{ _connectionInfo->database };
512}

◆ GetFreeConnection()

template<class T >
T * DatabaseWorkerPool< T >::GetFreeConnection ( )
private

Gets a free connection in the synchronous connection pool. Caller MUST call t->Unlock() after touching the MySQL context to prevent deadlocks.

Block forever until a connection is free

Must be matched with t->Unlock() or you will get deadlocks

482{
483#ifdef ACORE_DEBUG
484 if (_warnSyncQueries)
485 {
486 std::ostringstream ss;
487 ss << boost::stacktrace::stacktrace();
488 LOG_WARN("sql.performances", "Sync query at:\n{}", ss.str());
489 }
490#endif
491
492 uint8 i = 0;
493 auto const num_cons = _connections[IDX_SYNCH].size();
494 T* connection = nullptr;
495
497 for (;;)
498 {
499 connection = _connections[IDX_SYNCH][++i % num_cons].get();
501 if (connection->LockIfReady())
502 break;
503 }
504
505 return connection;
506}
#define LOG_WARN(filterType__,...)
Definition Log.h:161

References LOG_WARN.

◆ GetPreparedStatement()

template<class T >
PreparedStatement< T > * DatabaseWorkerPool< T >::GetPreparedStatement ( PreparedStatementIndex  index)

Automanaged (internally) pointer to a prepared statement object for usage in upper level code. Pointer is deleted in this->DirectExecute(PreparedStatement*), this->Query(PreparedStatement*) or PreparedStatementTask::~PreparedStatementTask. This object is not tied to the prepared statement on the MySQL context yet until execution.

335{
336 return new PreparedStatement<T>(index, _preparedStatementSize[index]);
337}
std::vector< uint8 > _preparedStatementSize
Definition DatabaseWorkerPool.h:235
Definition PreparedStatement.h:157

◆ KeepAlive()

template<class T >
void DatabaseWorkerPool< T >::KeepAlive ( )

Keeps all our MySQL connections alive, prevent the server from disconnecting us.

Ping synchronous connections

Assuming all worker threads are free, every worker thread will receive 1 ping operation request If one or more worker threads are busy, the ping operations will not be split evenly, but this doesn't matter as the sole purpose is to prevent connections from idling.

353{
355 for (auto& connection : _connections[IDX_SYNCH])
356 {
357 if (connection->LockIfReady())
358 {
359 connection->Ping();
360 connection->Unlock();
361 }
362 }
363
367 auto const count = _connections[IDX_ASYNC].size();
368
369 for (uint8 i = 0; i < count; ++i)
371}
Definition DatabaseWorkerPool.cpp:45

◆ Open()

template<class T >
uint32 DatabaseWorkerPool< T >::Open ( )
88{
89 WPFatal(_connectionInfo.get(), "Connection info was not set!");
90
91 LOG_INFO("sql.driver", "Opening DatabasePool '{}'. Asynchronous connections: {}, synchronous connections: {}.",
93
95
96 if (error)
97 return error;
98
100
101 if (!error)
102 {
103 LOG_INFO("sql.driver", "DatabasePool '{}' opened successfully. {} total connections running.",
105 }
106
107 LOG_INFO("sql.driver", " ");
108
109 return error;
110}
uint32 OpenConnections(InternalIndex type, uint8 numConnections)
Definition DatabaseWorkerPool.cpp:418

References LOG_INFO, and WPFatal.

Referenced by DatabaseLoader::AddDatabase().

◆ OpenConnections()

template<class T >
uint32 DatabaseWorkerPool< T >::OpenConnections ( InternalIndex  type,
uint8  numConnections 
)
private
419{
420 for (uint8 i = 0; i < numConnections; ++i)
421 {
422 // Create the connection
423 auto connection = [&]
424 {
425 switch (type)
426 {
427 case IDX_ASYNC:
428 return std::make_unique<T>(_queue.get(), *_connectionInfo);
429 case IDX_SYNCH:
430 return std::make_unique<T>(*_connectionInfo);
431 default:
432 ABORT();
433 }
434 }();
435
436 if (uint32 error = connection->Open())
437 {
438 // Failed to open a connection or invalid version, abort and cleanup
439 _queue->Cancel();
440 _connections[type].clear();
441 return error;
442 }
443 else if (DatabaseIncompatibleVersion(connection->GetServerInfo()))
444 {
445 LOG_ERROR("sql.driver", "AzerothCore does not support MySQL versions below 8.0\n\nFound server version: {}. Server compiled with: {}.",
446 connection->GetServerInfo(), MYSQL_VERSION_ID);
447 return 1;
448 }
449 else
450 {
451 _connections[type].push_back(std::move(connection));
452 }
453 }
454
455 // Everything is fine
456 return 0;
457}
bool DatabaseIncompatibleVersion(std::string const mysqlVersion)
Returns true if the version string given is incompatible.
Definition DatabaseWorkerPool.cpp:387
#define ABORT
Definition Errors.h:76
#define LOG_ERROR(filterType__,...)
Definition Log.h:157

References ABORT, DatabaseIncompatibleVersion(), and LOG_ERROR.

◆ PrepareStatements()

template<class T >
bool DatabaseWorkerPool< T >::PrepareStatements ( )

Prepares all prepared statements.

138{
139 for (auto const& connections : _connections)
140 {
141 for (auto const& connection : connections)
142 {
143 connection->LockIfReady();
144 if (!connection->PrepareStatements())
145 {
146 connection->Unlock();
147 Close();
148 return false;
149 }
150 else
151 connection->Unlock();
152
153 std::size_t const preparedSize = connection->m_stmts.size();
154 if (_preparedStatementSize.size() < preparedSize)
155 _preparedStatementSize.resize(preparedSize);
156
157 for (std::size_t i = 0; i < preparedSize; ++i)
158 {
159 // already set by another connection
160 // (each connection only has prepared statements of it's own type sync/async)
161 if (_preparedStatementSize[i] > 0)
162 continue;
163
164 if (MySQLPreparedStatement* stmt = connection->m_stmts[i].get())
165 {
166 uint32 const paramCount = stmt->GetParameterCount();
167
168 // WH only supports uint8 indices.
169 ASSERT(paramCount < std::numeric_limits<uint8>::max());
170
171 _preparedStatementSize[i] = static_cast<uint8>(paramCount);
172 }
173 }
174 }
175 }
176
177 return true;
178}
#define ASSERT
Definition Errors.h:68
void Close()
Definition DatabaseWorkerPool.cpp:113
Definition MySQLPreparedStatement.h:34

References ASSERT, and Close.

Referenced by DatabaseLoader::AddDatabase().

◆ Query() [1/3]

template<class T >
PreparedQueryResult DatabaseWorkerPool< T >::Query ( PreparedStatement< T > *  stmt)

Directly executes an SQL query in prepared format that will block the calling thread until finished. Returns reference counted auto pointer, no need for manual memory management in upper level code. Statement must be prepared with CONNECTION_SYNCH flag.

Delete proxy-class. Not needed anymore

199{
200 auto connection = GetFreeConnection();
201 PreparedResultSet* ret = connection->Query(stmt);
202 connection->Unlock();
203
205 delete stmt;
206
207 if (!ret || !ret->GetRowCount())
208 {
209 delete ret;
210 return PreparedQueryResult(nullptr);
211 }
212
213 return PreparedQueryResult(ret);
214}
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition DatabaseEnvFwd.h:45
Definition QueryResult.h:99
uint64 GetRowCount() const
Definition QueryResult.h:105

References PreparedResultSet::GetRowCount().

◆ Query() [2/3]

template<class T >
QueryResult DatabaseWorkerPool< T >::Query ( std::string_view  sql)

Synchronous query (with resultset) methods. Directly executes an SQL query in string format that will block the calling thread until finished. Returns reference counted auto pointer, no need for manual memory management in upper level code.

182{
183 auto connection = GetFreeConnection();
184
185 ResultSet* result = connection->Query(sql);
186 connection->Unlock();
187
188 if (!result || !result->GetRowCount() || !result->NextRow())
189 {
190 delete result;
191 return QueryResult(nullptr);
192 }
193
194 return QueryResult(result);
195}
std::shared_ptr< ResultSet > QueryResult
Definition DatabaseEnvFwd.h:27
Definition QueryResult.h:49
uint64 GetRowCount() const
Definition QueryResult.h:55
bool NextRow()
Definition QueryResult.cpp:188

References ResultSet::GetRowCount(), and ResultSet::NextRow().

Referenced by DatabaseWorkerPool< T >::Query(), and DBUpdater< T >::Retrieve().

◆ Query() [3/3]

template<class T >
template<typename... Args>
QueryResult DatabaseWorkerPool< T >::Query ( std::string_view  sql,
Args &&...  args 
)
inline

Directly executes an SQL query in string format -with variable args- that will block the calling thread until finished. Returns reference counted auto pointer, no need for manual memory management in upper level code.

134 {
135 if (sql.empty())
136 return QueryResult(nullptr);
137
138 return Query(Acore::StringFormat(sql, std::forward<Args>(args)...));
139 }
QueryResult Query(std::string_view sql)
Definition DatabaseWorkerPool.cpp:181

References DatabaseWorkerPool< T >::Query(), and Acore::StringFormat().

◆ QueueSize()

template<class T >
std::size_t DatabaseWorkerPool< T >::QueueSize ( ) const
476{
477 return _queue->Size();
478}

◆ SetConnectionInfo()

template<class T >
void DatabaseWorkerPool< T >::SetConnectionInfo ( std::string_view  infoString,
uint8 const  asyncThreads,
uint8 const  synchThreads 
)
79{
80 _connectionInfo = std::make_unique<MySQLConnectionInfo>(infoString);
81
82 _async_threads = asyncThreads;
83 _synch_threads = synchThreads;
84}

Referenced by DatabaseLoader::AddDatabase().

◆ WarnAboutSyncQueries()

template<class T >
void DatabaseWorkerPool< T >::WarnAboutSyncQueries ( bool  warn)
inline
210 {
211#ifdef ACORE_DEBUG
212 _warnSyncQueries = warn;
213#endif
214 }

Member Data Documentation

◆ _async_threads

template<class T >
uint8 DatabaseWorkerPool< T >::_async_threads
private

◆ _connectionInfo

template<class T >
std::unique_ptr<MySQLConnectionInfo> DatabaseWorkerPool< T >::_connectionInfo
private

◆ _connections

template<class T >
std::array<std::vector<std::unique_ptr<T> >, IDX_SIZE> DatabaseWorkerPool< T >::_connections
private

◆ _preparedStatementSize

template<class T >
std::vector<uint8> DatabaseWorkerPool< T >::_preparedStatementSize
private

◆ _queue

template<class T >
std::unique_ptr<ProducerConsumerQueue<SQLOperation*> > DatabaseWorkerPool< T >::_queue
private

Queue shared by async worker threads.

◆ _synch_threads

template<class T >
uint8 DatabaseWorkerPool< T >::_synch_threads
private

The documentation for this class was generated from the following files: