TrinityCore
Loading...
Searching...
No Matches
MySQLConnection Class Referenceabstract

#include <MySQLConnection.h>

Public Member Functions

 MySQLConnection (MySQLConnectionInfo &connInfo)
 
 MySQLConnection (ProducerConsumerQueue< SQLOperation * > *queue, MySQLConnectionInfo &connInfo)
 Constructor for synchronous connections. More...
 
virtual ~MySQLConnection ()
 Constructor for asynchronous connections. More...
 
virtual uint32 Open ()
 
void Close ()
 
bool PrepareStatements ()
 
bool Execute (char const *sql)
 
bool Execute (PreparedStatementBase *stmt)
 
ResultSetQuery (char const *sql)
 
PreparedResultSetQuery (PreparedStatementBase *stmt)
 
bool _Query (char const *sql, MySQLResult **pResult, MySQLField **pFields, uint64 *pRowCount, uint32 *pFieldCount)
 
bool _Query (PreparedStatementBase *stmt, MySQLPreparedStatement **mysqlStmt, MySQLResult **pResult, uint64 *pRowCount, uint32 *pFieldCount)
 
void BeginTransaction ()
 
void RollbackTransaction ()
 
void CommitTransaction ()
 
int ExecuteTransaction (std::shared_ptr< TransactionBase > transaction)
 
size_t EscapeString (char *to, const char *from, size_t length)
 
void Ping ()
 
uint32 GetLastError ()
 

Protected Types

typedef std::vector< std::unique_ptr< MySQLPreparedStatement > > PreparedStatementContainer
 

Protected Member Functions

bool LockIfReady ()
 
void Unlock ()
 Called by parent databasepool. Will let other threads access this connection. More...
 
uint32 GetServerVersion () const
 
MySQLPreparedStatementGetPreparedStatement (uint32 index)
 
void PrepareStatement (uint32 index, std::string_view sql, ConnectionFlags flags)
 
virtual void DoPrepareStatements ()=0
 

Protected Attributes

PreparedStatementContainer m_stmts
 
bool m_reconnecting
 PreparedStatements storage. More...
 
bool m_prepareError
 Are we reconnecting? More...
 

Private Member Functions

bool _HandleMySQLErrno (uint32 errNo, uint8 attempts=5)
 Was there any error while preparing statements? More...
 
 MySQLConnection (MySQLConnection const &right)=delete
 
MySQLConnectionoperator= (MySQLConnection const &right)=delete
 

Private Attributes

ProducerConsumerQueue< SQLOperation * > * m_queue
 
std::unique_ptr< DatabaseWorkerm_worker
 Queue shared with other asynchronous connections. More...
 
MySQLHandlem_Mysql
 Core worker task. More...
 
MySQLConnectionInfom_connectionInfo
 MySQL Handle. More...
 
ConnectionFlags m_connectionFlags
 Connection info (used for logging) More...
 
std::mutex m_Mutex
 Connection flags (for preparing relevant statements) More...
 

Friends

template<class T >
class DatabaseWorkerPool
 
class PingOperation
 

Detailed Description

Definition at line 54 of file MySQLConnection.h.

Member Typedef Documentation

◆ PreparedStatementContainer

typedef std::vector<std::unique_ptr<MySQLPreparedStatement> > MySQLConnection::PreparedStatementContainer
protected

Definition at line 99 of file MySQLConnection.h.

Constructor & Destructor Documentation

◆ MySQLConnection() [1/3]

MySQLConnection::MySQLConnection ( MySQLConnectionInfo connInfo)

Definition at line 50 of file MySQLConnection.cpp.

50 :
51m_reconnecting(false),
52m_prepareError(false),
53m_queue(nullptr),
54m_Mysql(nullptr),
55m_connectionInfo(connInfo),
@ CONNECTION_SYNCH
ProducerConsumerQueue< SQLOperation * > * m_queue
MySQLConnectionInfo & m_connectionInfo
MySQL Handle.
ConnectionFlags m_connectionFlags
Connection info (used for logging)
bool m_prepareError
Are we reconnecting?
MySQLHandle * m_Mysql
Core worker task.
bool m_reconnecting
PreparedStatements storage.

◆ MySQLConnection() [2/3]

MySQLConnection::MySQLConnection ( ProducerConsumerQueue< SQLOperation * > *  queue,
MySQLConnectionInfo connInfo 
)

Constructor for synchronous connections.

Definition at line 58 of file MySQLConnection.cpp.

58 :
59m_reconnecting(false),
60m_prepareError(false),
61m_queue(queue),
62m_Mysql(nullptr),
63m_connectionInfo(connInfo),
65{
66 m_worker = std::make_unique<DatabaseWorker>(m_queue, this);
67}
@ CONNECTION_ASYNC
std::unique_ptr< DatabaseWorker > m_worker
Queue shared with other asynchronous connections.

◆ ~MySQLConnection()

MySQLConnection::~MySQLConnection ( )
virtual

Constructor for asynchronous connections.

Definition at line 69 of file MySQLConnection.cpp.

70{
71 Close();
72}
+ Here is the call graph for this function:

◆ MySQLConnection() [3/3]

MySQLConnection::MySQLConnection ( MySQLConnection const &  right)
privatedelete

Member Function Documentation

◆ _HandleMySQLErrno()

bool MySQLConnection::_HandleMySQLErrno ( uint32  errNo,
uint8  attempts = 5 
)
private

Was there any error while preparing statements?

Definition at line 531 of file MySQLConnection.cpp.

532{
533 switch (errNo)
534 {
535 case CR_SERVER_GONE_ERROR:
536 case CR_SERVER_LOST:
537 case CR_SERVER_LOST_EXTENDED:
538 {
539 if (m_Mysql)
540 {
541 TC_LOG_ERROR("sql.sql", "Lost the connection to the MySQL server!");
542
543 mysql_close(m_Mysql);
544 m_Mysql = nullptr;
545 }
546 [[fallthrough]];
547 }
548 case CR_CONN_HOST_ERROR:
549 {
550 TC_LOG_INFO("sql.sql", "Attempting to reconnect to the MySQL server...");
551
552 m_reconnecting = true;
553
554 uint32 const lErrno = Open();
555 if (!lErrno)
556 {
557 // Don't remove 'this' pointer unless you want to skip loading all prepared statements...
558 if (!this->PrepareStatements())
559 {
560 TC_LOG_FATAL("sql.sql", "Could not re-prepare statements!");
561 std::this_thread::sleep_for(std::chrono::seconds(10));
562 std::abort();
563 }
564
565 TC_LOG_INFO("sql.sql", "Successfully reconnected to {} @{}:{} ({}).",
567 (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");
568
569 m_reconnecting = false;
570 return true;
571 }
572
573 if ((--attempts) == 0)
574 {
575 // Shut down the server when the mysql server isn't
576 // reachable for some time
577 TC_LOG_FATAL("sql.sql", "Failed to reconnect to the MySQL server, "
578 "terminating the server to prevent data corruption!");
579
580 // We could also initiate a shutdown through using std::raise(SIGTERM)
581 std::this_thread::sleep_for(std::chrono::seconds(10));
582 std::abort();
583 }
584 else
585 {
586 // It's possible this attempted reconnect throws 2006 at us.
587 // To prevent crazy recursive calls, sleep here.
588 std::this_thread::sleep_for(std::chrono::seconds(3)); // Sleep 3 seconds
589 return _HandleMySQLErrno(lErrno, attempts); // Call self (recursive)
590 }
591 }
592
593 case ER_LOCK_DEADLOCK:
594 return false; // Implemented in TransactionTask::Execute and DatabaseWorkerPool<T>::DirectCommitTransaction
595 // Query related errors - skip query
596 case ER_WRONG_VALUE_COUNT:
597 case ER_DUP_ENTRY:
598 return false;
599
600 // Outdated table or database structure - terminate core
601 case ER_BAD_FIELD_ERROR:
602 case ER_NO_SUCH_TABLE:
603 TC_LOG_ERROR("sql.sql", "Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders.");
604 std::this_thread::sleep_for(std::chrono::seconds(10));
605 std::abort();
606 return false;
607 case ER_PARSE_ERROR:
608 TC_LOG_ERROR("sql.sql", "Error while parsing SQL. Core fix required.");
609 std::this_thread::sleep_for(std::chrono::seconds(10));
610 std::abort();
611 return false;
612 default:
613 TC_LOG_ERROR("sql.sql", "Unhandled MySQL errno {}. Unexpected behaviour possible.", errNo);
614 return false;
615 }
616}
uint32_t uint32
Definition: Define.h:143
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:159
#define TC_LOG_FATAL(filterType__,...)
Definition: Log.h:168
virtual uint32 Open()
bool _HandleMySQLErrno(uint32 errNo, uint8 attempts=5)
Was there any error while preparing statements?
std::string port_or_socket
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _Query() [1/2]

bool MySQLConnection::_Query ( char const *  sql,
MySQLResult **  pResult,
MySQLField **  pFields,
uint64 pRowCount,
uint32 pFieldCount 
)

Definition at line 333 of file MySQLConnection.cpp.

334{
335 if (!m_Mysql)
336 return false;
337
338 {
339 uint32 _s = getMSTime();
340
341 if (mysql_query(m_Mysql, sql))
342 {
343 uint32 lErrno = mysql_errno(m_Mysql);
344 TC_LOG_INFO("sql.sql", "SQL: {}", sql);
345 TC_LOG_ERROR("sql.sql", "[{}] {}", lErrno, mysql_error(m_Mysql));
346
347 if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection)
348 return _Query(sql, pResult, pFields, pRowCount, pFieldCount); // We try again
349
350 return false;
351 }
352 else
353 TC_LOG_DEBUG("sql.sql", "[{} ms] SQL: {}", getMSTimeDiff(_s, getMSTime()), sql);
354
355 *pResult = reinterpret_cast<MySQLResult*>(mysql_store_result(m_Mysql));
356 *pRowCount = mysql_affected_rows(m_Mysql);
357 *pFieldCount = mysql_field_count(m_Mysql);
358 }
359
360 if (!*pResult )
361 return false;
362
363 if (!*pRowCount)
364 {
365 mysql_free_result(*pResult);
366 return false;
367 }
368
369 *pFields = reinterpret_cast<MySQLField*>(mysql_fetch_fields(*pResult));
370
371 return true;
372}
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
uint32 getMSTime()
Definition: Timer.h:33
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
Definition: Timer.h:40
bool _Query(char const *sql, MySQLResult **pResult, MySQLField **pFields, uint64 *pRowCount, uint32 *pFieldCount)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _Query() [2/2]

bool MySQLConnection::_Query ( PreparedStatementBase stmt,
MySQLPreparedStatement **  mysqlStmt,
MySQLResult **  pResult,
uint64 pRowCount,
uint32 pFieldCount 
)

Definition at line 263 of file MySQLConnection.cpp.

264{
265 if (!m_Mysql)
266 return false;
267
268 uint32 index = stmt->GetIndex();
269
271 ASSERT(m_mStmt); // Can only be null if preparation failed, server side error or bad query
272
273 m_mStmt->BindParameters(stmt);
274 *mysqlStmt = m_mStmt;
275
276 MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT();
277 MYSQL_BIND* msql_BIND = m_mStmt->GetBind();
278
279 uint32 _s = getMSTime();
280
281 if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
282 {
283 uint32 lErrno = mysql_errno(m_Mysql);
284 TC_LOG_ERROR("sql.sql", "SQL(p): {}\n [ERROR]: [{}] {}", m_mStmt->getQueryString(), lErrno, mysql_stmt_error(msql_STMT));
285
286 if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection)
287 return _Query(stmt, mysqlStmt, pResult, pRowCount, pFieldCount); // Try again
288
289 m_mStmt->ClearParameters();
290 return false;
291 }
292
293 if (mysql_stmt_execute(msql_STMT))
294 {
295 uint32 lErrno = mysql_errno(m_Mysql);
296 TC_LOG_ERROR("sql.sql", "SQL(p): {}\n [ERROR]: [{}] {}",
297 m_mStmt->getQueryString(), lErrno, mysql_stmt_error(msql_STMT));
298
299 if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection)
300 return _Query(stmt, mysqlStmt, pResult, pRowCount, pFieldCount); // Try again
301
302 m_mStmt->ClearParameters();
303 return false;
304 }
305
306 TC_LOG_DEBUG("sql.sql", "[{} ms] SQL(p): {}", getMSTimeDiff(_s, getMSTime()), m_mStmt->getQueryString());
307
308 m_mStmt->ClearParameters();
309
310 *pResult = reinterpret_cast<MySQLResult*>(mysql_stmt_result_metadata(msql_STMT));
311 *pRowCount = mysql_stmt_num_rows(msql_STMT);
312 *pFieldCount = mysql_stmt_field_count(msql_STMT);
313
314 return true;
315}
#define ASSERT
Definition: Errors.h:68
MySQLPreparedStatement * GetPreparedStatement(uint32 index)
std::string getQueryString() const
void BindParameters(PreparedStatementBase *stmt)
+ Here is the call graph for this function:

◆ BeginTransaction()

void MySQLConnection::BeginTransaction ( )

Definition at line 374 of file MySQLConnection.cpp.

375{
376 Execute("START TRANSACTION");
377}
bool Execute(char const *sql)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Close()

void MySQLConnection::Close ( )

Definition at line 74 of file MySQLConnection.cpp.

75{
76 // Stop the worker thread before the statements are cleared
77 m_worker.reset();
78
79 m_stmts.clear();
80
81 if (m_Mysql)
82 {
83 mysql_close(m_Mysql);
84 m_Mysql = nullptr;
85 }
86}
PreparedStatementContainer m_stmts
+ Here is the caller graph for this function:

◆ CommitTransaction()

void MySQLConnection::CommitTransaction ( )

Definition at line 384 of file MySQLConnection.cpp.

385{
386 Execute("COMMIT");
387}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ DoPrepareStatements()

virtual void MySQLConnection::DoPrepareStatements ( )
protectedpure virtual

Implemented in CharacterDatabaseConnection, HotfixDatabaseConnection, LoginDatabaseConnection, and WorldDatabaseConnection.

+ Here is the caller graph for this function:

◆ EscapeString()

size_t MySQLConnection::EscapeString ( char *  to,
const char *  from,
size_t  length 
)

Definition at line 440 of file MySQLConnection.cpp.

441{
442 return mysql_real_escape_string(m_Mysql, to, from, length);
443}

◆ Execute() [1/2]

bool MySQLConnection::Execute ( char const *  sql)

Definition at line 189 of file MySQLConnection.cpp.

190{
191 if (!m_Mysql)
192 return false;
193
194 {
195 uint32 _s = getMSTime();
196
197 if (mysql_query(m_Mysql, sql))
198 {
199 uint32 lErrno = mysql_errno(m_Mysql);
200
201 TC_LOG_INFO("sql.sql", "SQL: {}", sql);
202 TC_LOG_ERROR("sql.sql", "[{}] {}", lErrno, mysql_error(m_Mysql));
203
204 if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection)
205 return Execute(sql); // Try again
206
207 return false;
208 }
209 else
210 TC_LOG_DEBUG("sql.sql", "[{} ms] SQL: {}", getMSTimeDiff(_s, getMSTime()), sql);
211 }
212
213 return true;
214}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Execute() [2/2]

bool MySQLConnection::Execute ( PreparedStatementBase stmt)

Definition at line 216 of file MySQLConnection.cpp.

217{
218 if (!m_Mysql)
219 return false;
220
221 uint32 index = stmt->GetIndex();
222
224 ASSERT(m_mStmt); // Can only be null if preparation failed, server side error or bad query
225
226 m_mStmt->BindParameters(stmt);
227
228 MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT();
229 MYSQL_BIND* msql_BIND = m_mStmt->GetBind();
230
231 uint32 _s = getMSTime();
232
233 if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
234 {
235 uint32 lErrno = mysql_errno(m_Mysql);
236 TC_LOG_ERROR("sql.sql", "SQL(p): {}\n [ERROR]: [{}] {}", m_mStmt->getQueryString(), lErrno, mysql_stmt_error(msql_STMT));
237
238 if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection)
239 return Execute(stmt); // Try again
240
241 m_mStmt->ClearParameters();
242 return false;
243 }
244
245 if (mysql_stmt_execute(msql_STMT))
246 {
247 uint32 lErrno = mysql_errno(m_Mysql);
248 TC_LOG_ERROR("sql.sql", "SQL(p): {}\n [ERROR]: [{}] {}", m_mStmt->getQueryString(), lErrno, mysql_stmt_error(msql_STMT));
249
250 if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection)
251 return Execute(stmt); // Try again
252
253 m_mStmt->ClearParameters();
254 return false;
255 }
256
257 TC_LOG_DEBUG("sql.sql", "[{} ms] SQL(p): {}", getMSTimeDiff(_s, getMSTime()), m_mStmt->getQueryString());
258
259 m_mStmt->ClearParameters();
260 return true;
261}
+ Here is the call graph for this function:

◆ ExecuteTransaction()

int MySQLConnection::ExecuteTransaction ( std::shared_ptr< TransactionBase transaction)

Definition at line 389 of file MySQLConnection.cpp.

390{
391 std::vector<SQLElementData> const& queries = transaction->m_queries;
392 if (queries.empty())
393 return -1;
394
396
397 for (auto itr = queries.begin(); itr != queries.end(); ++itr)
398 {
399 SQLElementData const& data = *itr;
400 switch (itr->type)
401 {
403 {
405 ASSERT(stmt);
406 if (!Execute(stmt))
407 {
408 TC_LOG_WARN("sql.sql", "Transaction aborted. {} queries not executed.", (uint32)queries.size());
409 int errorCode = GetLastError();
411 return errorCode;
412 }
413 }
414 break;
415 case SQL_ELEMENT_RAW:
416 {
417 char const* sql = data.element.query;
418 ASSERT(sql);
419 if (!Execute(sql))
420 {
421 TC_LOG_WARN("sql.sql", "Transaction aborted. {} queries not executed.", (uint32)queries.size());
422 int errorCode = GetLastError();
424 return errorCode;
425 }
426 }
427 break;
428 }
429 }
430
431 // we might encounter errors during certain queries, and depending on the kind of error
432 // we might want to restart the transaction. So to prevent data loss, we only clean up when it's all done.
433 // This is done in calling functions DatabaseWorkerPool<T>::DirectCommitTransaction and TransactionTask::Execute,
434 // and not while iterating over every element.
435
437 return 0;
438}
#define TC_LOG_WARN(filterType__,...)
Definition: Log.h:162
@ SQL_ELEMENT_RAW
Definition: SQLOperation.h:34
@ SQL_ELEMENT_PREPARED
Definition: SQLOperation.h:35
SQLElementUnion element
Definition: SQLOperation.h:41
PreparedStatementBase * stmt
Definition: SQLOperation.h:27
char const * query
Definition: SQLOperation.h:28
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetLastError()

uint32 MySQLConnection::GetLastError ( )

Definition at line 450 of file MySQLConnection.cpp.

451{
452 return mysql_errno(m_Mysql);
453}
+ Here is the caller graph for this function:

◆ GetPreparedStatement()

MySQLPreparedStatement * MySQLConnection::GetPreparedStatement ( uint32  index)
protected

Definition at line 470 of file MySQLConnection.cpp.

471{
472 ASSERT(index < m_stmts.size(), "Tried to access invalid prepared statement index %u (max index " SZFMTD ") on database `%s`, connection type: %s",
473 index, m_stmts.size(), m_connectionInfo.database.c_str(), (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");
474 MySQLPreparedStatement* ret = m_stmts[index].get();
475 if (!ret)
476 TC_LOG_ERROR("sql.sql", "Could not fetch prepared statement {} on database `{}`, connection type: {}.",
477 index, m_connectionInfo.database, (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");
478
479 return ret;
480}
#define SZFMTD
Definition: Define.h:133
+ Here is the caller graph for this function:

◆ GetServerVersion()

uint32 MySQLConnection::GetServerVersion ( ) const
protected

Definition at line 465 of file MySQLConnection.cpp.

466{
467 return mysql_get_server_version(m_Mysql);
468}

◆ LockIfReady()

bool MySQLConnection::LockIfReady ( )
protected

Tries to acquire lock. If lock is acquired by another thread the calling parent will just try another connection

Definition at line 455 of file MySQLConnection.cpp.

456{
457 return m_Mutex.try_lock();
458}
std::mutex m_Mutex
Connection flags (for preparing relevant statements)

◆ Open()

uint32 MySQLConnection::Open ( )
virtual

Definition at line 88 of file MySQLConnection.cpp.

89{
90 MYSQL *mysqlInit;
91 mysqlInit = mysql_init(nullptr);
92 if (!mysqlInit)
93 {
94 TC_LOG_ERROR("sql.sql", "Could not initialize Mysql connection to database `{}`", m_connectionInfo.database);
95 return CR_UNKNOWN_ERROR;
96 }
97
98 int port;
99 char const* unix_socket;
100 //unsigned int timeout = 10;
101
102 mysql_options(mysqlInit, MYSQL_SET_CHARSET_NAME, "utf8mb4");
103 //mysql_options(mysqlInit, MYSQL_OPT_READ_TIMEOUT, (char const*)&timeout);
104 #ifdef _WIN32
105 if (m_connectionInfo.host == ".") // named pipe use option (Windows)
106 {
107 unsigned int opt = MYSQL_PROTOCOL_PIPE;
108 mysql_options(mysqlInit, MYSQL_OPT_PROTOCOL, (char const*)&opt);
109 port = 0;
110 unix_socket = nullptr;
111 }
112 else // generic case
113 {
114 port = atoi(m_connectionInfo.port_or_socket.c_str());
115 unix_socket = nullptr;
116 }
117 #else
118 if (m_connectionInfo.host == ".") // socket use option (Unix/Linux)
119 {
120 unsigned int opt = MYSQL_PROTOCOL_SOCKET;
121 mysql_options(mysqlInit, MYSQL_OPT_PROTOCOL, (char const*)&opt);
122 m_connectionInfo.host = "localhost";
123 port = 0;
124 unix_socket = m_connectionInfo.port_or_socket.c_str();
125 }
126 else // generic case
127 {
128 port = atoi(m_connectionInfo.port_or_socket.c_str());
129 unix_socket = nullptr;
130 }
131 #endif
132
133 if (m_connectionInfo.ssl != "")
134 {
135#if !defined(MARIADB_VERSION_ID) && MYSQL_VERSION_ID >= 80000
136 mysql_ssl_mode opt_use_ssl = SSL_MODE_DISABLED;
137 if (m_connectionInfo.ssl == "ssl")
138 {
139 opt_use_ssl = SSL_MODE_REQUIRED;
140 }
141 mysql_options(mysqlInit, MYSQL_OPT_SSL_MODE, (char const*)&opt_use_ssl);
142#else
143 MySQLBool opt_use_ssl = MySQLBool(0);
144 if (m_connectionInfo.ssl == "ssl")
145 {
146 opt_use_ssl = MySQLBool(1);
147 }
148 mysql_options(mysqlInit, MYSQL_OPT_SSL_ENFORCE, (char const*)&opt_use_ssl);
149#endif
150 }
151
152 m_Mysql = reinterpret_cast<MySQLHandle*>(mysql_real_connect(mysqlInit, m_connectionInfo.host.c_str(), m_connectionInfo.user.c_str(),
153 m_connectionInfo.password.c_str(), m_connectionInfo.database.c_str(), port, unix_socket, 0));
154
155 if (m_Mysql)
156 {
157 if (!m_reconnecting)
158 {
159 TC_LOG_INFO("sql.sql", "MySQL client library: {}", mysql_get_client_info());
160 TC_LOG_INFO("sql.sql", "MySQL server ver: {} ", mysql_get_server_info(m_Mysql));
161 // MySQL version above 5.1 IS required in both client and server and there is no known issue with different versions above 5.1
162 // if (mysql_get_server_version(m_Mysql) != mysql_get_client_version())
163 // TC_LOG_INFO("sql.sql", "[WARNING] MySQL client/server version mismatch; may conflict with behaviour of prepared statements.");
164 }
165
166 TC_LOG_INFO("sql.sql", "Connected to MySQL database at {}", m_connectionInfo.host);
167 mysql_autocommit(m_Mysql, 1);
168
169 // set connection properties to UTF8 to properly handle locales for different
170 // server configs - core sends data in UTF8, so MySQL must expect UTF8 too
171 mysql_set_character_set(m_Mysql, "utf8mb4");
172 return 0;
173 }
174 else
175 {
176 TC_LOG_ERROR("sql.sql", "Could not connect to MySQL database at {}: {}", m_connectionInfo.host, mysql_error(mysqlInit));
177 uint32 errorCode = mysql_errno(mysqlInit);
178 mysql_close(mysqlInit);
179 return errorCode;
180 }
181}
std::remove_pointer_t< decltype(std::declval< MYSQL_BIND >().is_null)> MySQLBool
Definition: MySQLHacks.h:32
+ Here is the caller graph for this function:

◆ operator=()

MySQLConnection & MySQLConnection::operator= ( MySQLConnection const &  right)
privatedelete

◆ Ping()

void MySQLConnection::Ping ( )

Definition at line 445 of file MySQLConnection.cpp.

446{
447 mysql_ping(m_Mysql);
448}
+ Here is the caller graph for this function:

◆ PrepareStatement()

void MySQLConnection::PrepareStatement ( uint32  index,
std::string_view  sql,
ConnectionFlags  flags 
)
protected

Definition at line 482 of file MySQLConnection.cpp.

483{
484 // Check if specified query should be prepared on this connection
485 // i.e. don't prepare async statements on synchronous connections
486 // to save memory that will not be used.
487 if (!(m_connectionFlags & flags))
488 {
489 m_stmts[index].reset();
490 return;
491 }
492
493 MYSQL_STMT* stmt = mysql_stmt_init(m_Mysql);
494 if (!stmt)
495 {
496 TC_LOG_ERROR("sql.sql", "In mysql_stmt_init() id: {}, sql: \"{}\"", index, sql);
497 TC_LOG_ERROR("sql.sql", "{}", mysql_error(m_Mysql));
498 m_prepareError = true;
499 }
500 else
501 {
502 if (mysql_stmt_prepare(stmt, sql.data(), static_cast<unsigned long>(sql.size())))
503 {
504 TC_LOG_ERROR("sql.sql", "In mysql_stmt_prepare() id: {}, sql: \"{}\"", index, sql);
505 TC_LOG_ERROR("sql.sql", "{}", mysql_stmt_error(stmt));
506 mysql_stmt_close(stmt);
507 m_prepareError = true;
508 }
509 else
510 m_stmts[index] = std::make_unique<MySQLPreparedStatement>(reinterpret_cast<MySQLStmt*>(stmt), std::string(sql));
511 }
512}
uint16 flags
Definition: DisableMgr.cpp:49
+ Here is the caller graph for this function:

◆ PrepareStatements()

bool MySQLConnection::PrepareStatements ( )

Definition at line 183 of file MySQLConnection.cpp.

184{
186 return !m_prepareError;
187}
virtual void DoPrepareStatements()=0
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Query() [1/2]

ResultSet * MySQLConnection::Query ( char const *  sql)

Definition at line 317 of file MySQLConnection.cpp.

318{
319 if (!sql)
320 return nullptr;
321
322 MySQLResult* result = nullptr;
323 MySQLField* fields = nullptr;
324 uint64 rowCount = 0;
325 uint32 fieldCount = 0;
326
327 if (!_Query(sql, &result, &fields, &rowCount, &fieldCount))
328 return nullptr;
329
330 return new ResultSet(result, fields, rowCount, fieldCount);
331}
uint64_t uint64
Definition: Define.h:142
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Query() [2/2]

PreparedResultSet * MySQLConnection::Query ( PreparedStatementBase stmt)

Definition at line 514 of file MySQLConnection.cpp.

515{
516 MySQLPreparedStatement* mysqlStmt = nullptr;
517 MySQLResult* result = nullptr;
518 uint64 rowCount = 0;
519 uint32 fieldCount = 0;
520
521 if (!_Query(stmt, &mysqlStmt, &result, &rowCount, &fieldCount))
522 return nullptr;
523
524 if (mysql_more_results(m_Mysql))
525 {
526 mysql_next_result(m_Mysql);
527 }
528 return new PreparedResultSet(mysqlStmt->GetSTMT(), result, rowCount, fieldCount);
529}
+ Here is the call graph for this function:

◆ RollbackTransaction()

void MySQLConnection::RollbackTransaction ( )

Definition at line 379 of file MySQLConnection.cpp.

380{
381 Execute("ROLLBACK");
382}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Unlock()

void MySQLConnection::Unlock ( )
protected

Called by parent databasepool. Will let other threads access this connection.

Definition at line 460 of file MySQLConnection.cpp.

461{
462 m_Mutex.unlock();
463}

Friends And Related Function Documentation

◆ DatabaseWorkerPool

template<class T >
friend class DatabaseWorkerPool
friend

Definition at line 56 of file MySQLConnection.h.

◆ PingOperation

friend class PingOperation
friend

Definition at line 57 of file MySQLConnection.h.

Member Data Documentation

◆ m_connectionFlags

ConnectionFlags MySQLConnection::m_connectionFlags
private

Connection info (used for logging)

Definition at line 112 of file MySQLConnection.h.

◆ m_connectionInfo

MySQLConnectionInfo& MySQLConnection::m_connectionInfo
private

MySQL Handle.

Definition at line 111 of file MySQLConnection.h.

◆ m_Mutex

std::mutex MySQLConnection::m_Mutex
private

Connection flags (for preparing relevant statements)

Definition at line 113 of file MySQLConnection.h.

◆ m_Mysql

MySQLHandle* MySQLConnection::m_Mysql
private

Core worker task.

Definition at line 110 of file MySQLConnection.h.

◆ m_prepareError

bool MySQLConnection::m_prepareError
protected

Are we reconnecting?

Definition at line 103 of file MySQLConnection.h.

◆ m_queue

ProducerConsumerQueue<SQLOperation*>* MySQLConnection::m_queue
private

Definition at line 108 of file MySQLConnection.h.

◆ m_reconnecting

bool MySQLConnection::m_reconnecting
protected

PreparedStatements storage.

Definition at line 102 of file MySQLConnection.h.

◆ m_stmts

PreparedStatementContainer MySQLConnection::m_stmts
protected

Definition at line 101 of file MySQLConnection.h.

◆ m_worker

std::unique_ptr<DatabaseWorker> MySQLConnection::m_worker
private

Queue shared with other asynchronous connections.

Definition at line 109 of file MySQLConnection.h.


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