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)
 
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 
38 {
42 };
@ IDX_ASYNC
Definition: DatabaseWorkerPool.h:39
@ IDX_SIZE
Definition: DatabaseWorkerPool.h:41
@ IDX_SYNCH
Definition: DatabaseWorkerPool.h:40

Constructor & Destructor Documentation

◆ DatabaseWorkerPool()

template<class T >
DatabaseWorkerPool< T >::DatabaseWorkerPool
61 :
65{
66 WPFatal(mysql_thread_safe(), "Used MySQL library isn't thread-safe.");
67
68#if !defined(MARIADB_VERSION_ID) || MARIADB_VERSION_ID < 100600
69 bool isSupportClientDB = mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION;
70 bool isSameClientDB = mysql_get_client_version() == MYSQL_VERSION_ID;
71#else // MariaDB 10.6+
72 bool isSupportClientDB = mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION;
73 bool isSameClientDB = true; // Client version 3.2.3?
74#endif
75
76 WPFatal(isSupportClientDB, "AzerothCore does not support MySQL versions below 5.7 or MariaDB versions below 10.5.\n\nFound version: {} / {}. Server compiled with: {}.\nSearch the wiki for ACE00043 in Common Errors (https://www.azerothcore.org/wiki/common-errors#ace00043).",
77 mysql_get_client_info(), mysql_get_client_version(), MYSQL_VERSION_ID);
78 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).",
79 mysql_get_client_info(), mysql_get_client_version(), MYSQL_VERSION_ID);
80}
#define WPFatal(cond,...)
Definition: Errors.h:59
#define MIN_MYSQL_CLIENT_VERSION
Definition: DatabaseWorkerPool.cpp:47
Definition: PCQueue.h:29
uint8 _synch_threads
Definition: DatabaseWorkerPool.h:222
uint8 _async_threads
Definition: DatabaseWorkerPool.h:222
std::unique_ptr< ProducerConsumerQueue< SQLOperation * > > _queue
Queue shared by async worker threads.
Definition: DatabaseWorkerPool.h:218

References MIN_MYSQL_CLIENT_VERSION, and WPFatal.

◆ ~DatabaseWorkerPool()

template<class T >
DatabaseWorkerPool< T >::~DatabaseWorkerPool
84{
85 _queue->Cancel();
86}

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.

284{
285#ifdef ACORE_DEBUG
289 switch (transaction->GetSize())
290 {
291 case 0:
292 LOG_DEBUG("sql.driver", "Transaction contains 0 queries. Not executing.");
293 break;
294 case 1:
295 LOG_DEBUG("sql.driver", "Warning: Transaction only holds 1 query, consider removing Transaction context in code.");
296 break;
297 default:
298 break;
299 }
300#endif // ACORE_DEBUG
301
303 TransactionFuture result = task->GetFuture();
304 Enqueue(task);
305 return TransactionCallback(std::move(result));
306}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:171
std::future< bool > TransactionFuture
Definition: DatabaseEnvFwd.h:59
void Enqueue(SQLOperation *op)
Definition: DatabaseWorkerPool.cpp:431
Definition: Transaction.h:97
TransactionFuture GetFuture()
Definition: Transaction.h:101
Definition: Transaction.h:110

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.

235{
236 PreparedStatementTask* task = new PreparedStatementTask(stmt, true);
237 // Store future result before enqueueing - task might get already processed and deleted before returning from this method
238 PreparedQueryResultFuture result = task->GetFuture();
239 Enqueue(task);
240 return QueryCallback(std::move(result));
241}
std::future< PreparedQueryResult > PreparedQueryResultFuture
Definition: DatabaseEnvFwd.h:47
Definition: PreparedStatement.h:171
PreparedQueryResultFuture GetFuture()
Definition: PreparedStatement.h:177
Definition: QueryCallback.h:30

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.

225{
226 BasicStatementTask* task = new BasicStatementTask(sql, true);
227 // Store future result before enqueueing - task might get already processed and deleted before returning from this method
228 QueryResultFuture result = task->GetFuture();
229 Enqueue(task);
230 return QueryCallback(std::move(result));
231}
std::future< QueryResult > QueryResultFuture
Definition: DatabaseEnvFwd.h:29
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.

255{
256 return std::make_shared<Transaction<T>>();
257}

◆ 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.

125{
126 LOG_INFO("sql.driver", "Closing down DatabasePool '{}'.", GetDatabaseName());
127
129 _connections[IDX_ASYNC].clear();
130
131 LOG_INFO("sql.driver", "Asynchronous connections on DatabasePool '{}' terminated. Proceeding with synchronous connections.",
133
138 _connections[IDX_SYNCH].clear();
139
140 LOG_INFO("sql.driver", "All connections on DatabasePool '{}' closed.", GetDatabaseName());
141}
#define LOG_INFO(filterType__,...)
Definition: Log.h:167
std::array< std::vector< std::unique_ptr< T > >, IDX_SIZE > _connections
Definition: DatabaseWorkerPool.h:219
std::string_view GetDatabaseName() const
Definition: DatabaseWorkerPool.cpp:471

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.

261{
262#ifdef ACORE_DEBUG
266 switch (transaction->GetSize())
267 {
268 case 0:
269 LOG_DEBUG("sql.driver", "Transaction contains 0 queries. Not executing.");
270 return;
271 case 1:
272 LOG_DEBUG("sql.driver", "Warning: Transaction only holds 1 query, consider removing Transaction context in code.");
273 break;
274 default:
275 break;
276 }
277#endif // ACORE_DEBUG
278
279 Enqueue(new TransactionTask(transaction));
280}
Definition: Transaction.h:76

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.

245{
246 SQLQueryHolderTask* task = new SQLQueryHolderTask(holder);
247 // Store future result before enqueueing - task might get already processed and deleted before returning from this method
248 QueryResultHolderFuture result = task->GetFuture();
249 Enqueue(task);
250 return { std::move(holder), std::move(result) };
251}
std::future< void > QueryResultHolderFuture
Definition: DatabaseEnvFwd.h:75
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.

310{
311 T* connection = GetFreeConnection();
312 int errorCode = connection->ExecuteTransaction(transaction);
313
314 if (!errorCode)
315 {
316 connection->Unlock(); // OK, operation succesful
317 return;
318 }
319
322 if (errorCode == ER_LOCK_DEADLOCK)
323 {
324 //todo: handle multiple sync threads deadlocking in a similar way as async threads
325 uint8 loopBreaker = 5;
326
327 for (uint8 i = 0; i < loopBreaker; ++i)
328 {
329 if (!connection->ExecuteTransaction(transaction))
330 break;
331 }
332 }
333
335 transaction->Cleanup();
336
337 connection->Unlock();
338}
std::uint8_t uint8
Definition: Define.h:110
T * GetFreeConnection()
Definition: DatabaseWorkerPool.cpp:443

◆ 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

506{
507 T* connection = GetFreeConnection();
508 connection->Execute(stmt);
509 connection->Unlock();
510
512 delete stmt;
513}

◆ 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.

495{
496 if (sql.empty())
497 return;
498
499 T* connection = GetFreeConnection();
500 connection->Execute(sql);
501 connection->Unlock();
502}

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.

97 {
98 if (sql.empty())
99 return;
100
101 DirectExecute(Acore::StringFormatFmt(sql, std::forward<Args>(args)...));
102 }
std::string StringFormatFmt(std::string_view fmt, Args &&... args)
Definition: StringFormat.h:44
void DirectExecute(std::string_view sql)
Definition: DatabaseWorkerPool.cpp:494

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

◆ Enqueue()

template<class T >
void DatabaseWorkerPool< T >::Enqueue ( SQLOperation op)
private
432{
433 _queue->Push(op);
434}

◆ EscapeString() [1/2]

template<class T >
unsigned long DatabaseWorkerPool< T >::EscapeString ( char *  to,
char const *  from,
unsigned long  length 
)
private
423{
424 if (!to || !from || !length)
425 return 0;
426
427 return _connections[IDX_SYNCH].front()->EscapeString(to, from, length);
428}

◆ EscapeString() [2/2]

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

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

348{
349 if (str.empty())
350 return;
351
352 char* buf = new char[str.size() * 2 + 1];
353 EscapeString(buf, str.c_str(), uint32(str.size()));
354 str = buf;
355 delete[] buf;
356}
std::uint32_t uint32
Definition: Define.h:108
void EscapeString(std::string &str)
Apply escape string'ing for current collation. (utf8)
Definition: DatabaseWorkerPool.cpp:347

◆ 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.

488{
490 Enqueue(task);
491}

◆ 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.

478{
479 if (sql.empty())
480 return;
481
482 BasicStatementTask* task = new BasicStatementTask(sql);
483 Enqueue(task);
484}

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.

74 {
75 if (sql.empty())
76 return;
77
78 Execute(Acore::StringFormatFmt(sql, std::forward<Args>(args)...));
79 }
void Execute(std::string_view sql)
Definition: DatabaseWorkerPool.cpp:477

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

◆ 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.

526{
527 if (!trans)
528 Execute(stmt);
529 else
530 trans->Append(stmt);
531}

◆ 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.

517{
518 if (!trans)
519 Execute(sql);
520 else
521 trans->Append(sql);
522}

◆ GetConnectionInfo()

template<class T >
MySQLConnectionInfo const * DatabaseWorkerPool< T >::GetConnectionInfo ( ) const
inline
58 {
59 return _connectionInfo.get();
60 }
std::unique_ptr< MySQLConnectionInfo > _connectionInfo
Definition: DatabaseWorkerPool.h:220

References DatabaseWorkerPool< T >::_connectionInfo.

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

◆ GetDatabaseName()

template<class T >
std::string_view DatabaseWorkerPool< T >::GetDatabaseName
private
472{
473 return std::string_view{ _connectionInfo->database };
474}

◆ 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

444{
445#ifdef ACORE_DEBUG
446 if (_warnSyncQueries)
447 {
448 std::ostringstream ss;
449 ss << boost::stacktrace::stacktrace();
450 LOG_WARN("sql.performances", "Sync query at:\n{}", ss.str());
451 }
452#endif
453
454 uint8 i = 0;
455 auto const num_cons = _connections[IDX_SYNCH].size();
456 T* connection = nullptr;
457
459 for (;;)
460 {
461 connection = _connections[IDX_SYNCH][++i % num_cons].get();
463 if (connection->LockIfReady())
464 break;
465 }
466
467 return connection;
468}
#define LOG_WARN(filterType__,...)
Definition: Log.h:163

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.

342{
343 return new PreparedStatement<T>(index, _preparedStatementSize[index]);
344}
Definition: PreparedStatement.h:158
std::vector< uint8 > _preparedStatementSize
Definition: DatabaseWorkerPool.h:221

◆ 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.

360{
362 for (auto& connection : _connections[IDX_SYNCH])
363 {
364 if (connection->LockIfReady())
365 {
366 connection->Ping();
367 connection->Unlock();
368 }
369 }
370
374 auto const count = _connections[IDX_ASYNC].size();
375
376 for (uint8 i = 0; i < count; ++i)
378}
Definition: DatabaseWorkerPool.cpp:51

◆ Open()

template<class T >
uint32 DatabaseWorkerPool< T >::Open
99{
100 WPFatal(_connectionInfo.get(), "Connection info was not set!");
101
102 LOG_INFO("sql.driver", "Opening DatabasePool '{}'. Asynchronous connections: {}, synchronous connections: {}.",
104
106
107 if (error)
108 return error;
109
111
112 if (!error)
113 {
114 LOG_INFO("sql.driver", "DatabasePool '{}' opened successfully. {} total connections running.",
116 }
117
118 LOG_INFO("sql.driver", " ");
119
120 return error;
121}
uint32 OpenConnections(InternalIndex type, uint8 numConnections)
Definition: DatabaseWorkerPool.cpp:381

References LOG_INFO, and WPFatal.

Referenced by DatabaseLoader::AddDatabase().

◆ OpenConnections()

template<class T >
uint32 DatabaseWorkerPool< T >::OpenConnections ( InternalIndex  type,
uint8  numConnections 
)
private
382{
383 for (uint8 i = 0; i < numConnections; ++i)
384 {
385 // Create the connection
386 auto connection = [&]
387 {
388 switch (type)
389 {
390 case IDX_ASYNC:
391 return std::make_unique<T>(_queue.get(), *_connectionInfo);
392 case IDX_SYNCH:
393 return std::make_unique<T>(*_connectionInfo);
394 default:
395 ABORT();
396 }
397 }();
398
399 if (uint32 error = connection->Open())
400 {
401 // Failed to open a connection or invalid version, abort and cleanup
402 _connections[type].clear();
403 return error;
404 }
405 else if (connection->GetServerVersion() < MIN_MYSQL_SERVER_VERSION)
406 {
407 LOG_ERROR("sql.driver", "AzerothCore does not support MySQL versions below 5.7 or MariaDB versions below 10.5.\n\nFound server version: {}. Server compiled with: {}.",
408 connection->GetServerVersion(), MYSQL_VERSION_ID);
409 return 1;
410 }
411 else
412 {
413 _connections[type].push_back(std::move(connection));
414 }
415 }
416
417 // Everything is fine
418 return 0;
419}
#define ABORT
Definition: Errors.h:76
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
#define MIN_MYSQL_SERVER_VERSION
Definition: DatabaseWorkerPool.cpp:46

References ABORT, LOG_ERROR, and MIN_MYSQL_SERVER_VERSION.

◆ PrepareStatements()

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

Prepares all prepared statements.

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

206{
207 auto connection = GetFreeConnection();
208 PreparedResultSet* ret = connection->Query(stmt);
209 connection->Unlock();
210
212 delete stmt;
213
214 if (!ret || !ret->GetRowCount())
215 {
216 delete ret;
217 return PreparedQueryResult(nullptr);
218 }
219
220 return PreparedQueryResult(ret);
221}
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition: DatabaseEnvFwd.h:46
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.

189{
190 auto connection = GetFreeConnection();
191
192 ResultSet* result = connection->Query(sql);
193 connection->Unlock();
194
195 if (!result || !result->GetRowCount() || !result->NextRow())
196 {
197 delete result;
198 return QueryResult(nullptr);
199 }
200
201 return QueryResult(result);
202}
std::shared_ptr< ResultSet > QueryResult
Definition: DatabaseEnvFwd.h:28
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.

120 {
121 if (sql.empty())
122 return QueryResult(nullptr);
123
124 return Query(Acore::StringFormatFmt(sql, std::forward<Args>(args)...));
125 }
QueryResult Query(std::string_view sql)
Definition: DatabaseWorkerPool.cpp:188

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

◆ QueueSize()

template<class T >
size_t DatabaseWorkerPool< T >::QueueSize
438{
439 return _queue->Size();
440}

◆ SetConnectionInfo()

template<class T >
void DatabaseWorkerPool< T >::SetConnectionInfo ( std::string_view  infoString,
uint8 const  asyncThreads,
uint8 const  synchThreads 
)
90{
91 _connectionInfo = std::make_unique<MySQLConnectionInfo>(infoString);
92
93 _async_threads = asyncThreads;
94 _synch_threads = synchThreads;
95}

Referenced by DatabaseLoader::AddDatabase().

◆ WarnAboutSyncQueries()

template<class T >
void DatabaseWorkerPool< T >::WarnAboutSyncQueries ( bool  warn)
inline
196 {
197#ifdef ACORE_DEBUG
198 _warnSyncQueries = warn;
199#endif
200 }

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