1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* 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 _MYSQLCONNECTION_H
#define _MYSQLCONNECTION_H
#include "Define.h"
#include "DatabaseEnvFwd.h"
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
template <typename T>
class ProducerConsumerQueue;
class DatabaseWorker;
class MySQLPreparedStatement;
class SQLOperation;
enum ConnectionFlags
{
CONNECTION_ASYNC = 0x1,
CONNECTION_SYNCH = 0x2,
CONNECTION_BOTH = CONNECTION_ASYNC | CONNECTION_SYNCH
};
struct TC_DATABASE_API MySQLConnectionInfo
{
explicit MySQLConnectionInfo(std::string const& infoString);
std::string user;
std::string password;
std::string database;
std::string host;
std::string port_or_socket;
};
class TC_DATABASE_API MySQLConnection
{
template <class T> friend class DatabaseWorkerPool;
friend class PingOperation;
public:
MySQLConnection(MySQLConnectionInfo& connInfo); //! Constructor for synchronous connections.
MySQLConnection(ProducerConsumerQueue<SQLOperation*>* queue, MySQLConnectionInfo& connInfo); //! Constructor for asynchronous connections.
virtual ~MySQLConnection();
virtual uint32 Open();
void Close();
bool PrepareStatements();
bool Execute(char const* sql);
bool Execute(PreparedStatementBase* stmt);
ResultSet* Query(char const* sql);
PreparedResultSet* Query(PreparedStatementBase* stmt);
bool _Query(char const* sql, MySQLResult** pResult, MySQLField** pFields, uint64* pRowCount, uint32* pFieldCount);
bool _Query(PreparedStatementBase* stmt, 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:
/// Tries to acquire lock. If lock is acquired by another thread
/// the calling parent will just try another connection
bool LockIfReady();
/// Called by parent databasepool. Will let other threads access this connection
void Unlock();
uint32 GetServerVersion() const;
MySQLPreparedStatement* GetPreparedStatement(uint32 index);
void PrepareStatement(uint32 index, std::string const& sql, ConnectionFlags flags);
virtual void DoPrepareStatements() = 0;
typedef std::vector<std::unique_ptr<MySQLPreparedStatement>> PreparedStatementContainer;
PreparedStatementContainer m_stmts; //! PreparedStatements storage
bool m_reconnecting; //! Are we reconnecting?
bool m_prepareError; //! Was there any error while preparing statements?
private:
bool _HandleMySQLErrno(uint32 errNo, uint8 attempts = 5);
ProducerConsumerQueue<SQLOperation*>* m_queue; //! Queue shared with other asynchronous connections.
std::unique_ptr<DatabaseWorker> m_worker; //! Core worker task.
MySQLHandle* m_Mysql; //! MySQL Handle.
MySQLConnectionInfo& m_connectionInfo; //! Connection info (used for logging)
ConnectionFlags m_connectionFlags; //! Connection flags (for preparing relevant statements)
std::mutex m_Mutex;
MySQLConnection(MySQLConnection const& right) = delete;
MySQLConnection& operator=(MySQLConnection const& right) = delete;
};
#endif
|