forked from pocoproject/poco
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSessionImpl.h
More file actions
294 lines (222 loc) · 7.63 KB
/
SessionImpl.h
File metadata and controls
294 lines (222 loc) · 7.63 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
//
// SessionImpl.h
//
// Library: Data/MySQL
// Package: MySQL
// Module: SessionImpl
//
// Definition of the SessionImpl class.
//
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_MySQL_SessionImpl_INCLUDED
#define Data_MySQL_SessionImpl_INCLUDED
#include "Poco/Data/MySQL/MySQL.h"
#include "Poco/Data/AbstractSessionImpl.h"
#include "Poco/Data/MySQL/SessionHandle.h"
#include "Poco/Data/MySQL/StatementExecutor.h"
#include "Poco/Data/MySQL/ResultMetadata.h"
#include "Poco/SharedPtr.h"
#include "Poco/Mutex.h"
namespace Poco {
namespace Data {
namespace MySQL {
class MySQL_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
/// Implements SessionImpl interface
{
public:
static const std::string MYSQL_READ_UNCOMMITTED;
static const std::string MYSQL_READ_COMMITTED;
static const std::string MYSQL_REPEATABLE_READ;
static const std::string MYSQL_SERIALIZABLE;
SessionImpl(const std::string& connectionString, std::size_t loginTimeout = LOGIN_TIMEOUT_DEFAULT);
/// Creates the SessionImpl. Opens a connection to the database.
///
/// Connection string format:
/// <str> == <assignment> | <assignment> ';' <str>
/// <assignment> == <name> '=' <value>
/// <name> == 'host' | 'port' | 'user' | 'password' | 'db' | 'compress' | 'auto-reconnect' | 'reset' | 'fail-readonly'
/// <value> == [~;]*
///
/// The following settings are supported:
/// - host: MySQL server hostname or IP address (default: localhost)
/// - port: MySQL server port number (default: 3306)
/// - user: MySQL user name
/// - password: MySQL password
/// - compress: enable compression (true/false; default: false)
/// - auto-reconnect: enable automatic reconnect (true/false; default: false)
/// - secure-auth: use secure authentication (true/false; default: false)
/// - character-set: connection character set (default: utf8)
/// - reset: reset connection when returned to SessionPool by calling
/// mysql_reset_connection().
/// - fail-readonly: if set to true, the session will fail
/// if the database becomes read-only. This corresponds to
/// setFailIfInnoReadOnly(true).
///
/// Warning: Due to a bug in MySQL, resetting the connection with mysql_reset_connection()
/// could change the character encoding used for the connection. Therefore the
/// reset option should be used with caution.
~SessionImpl();
/// Destroys the SessionImpl.
Poco::SharedPtr<Poco::Data::StatementImpl> createStatementImpl();
/// Returns an MySQL StatementImpl
void open(const std::string& connection = "");
/// Opens a connection to the database.
void close();
/// Closes the connection.
void reset();
/// Reset connection with dababase and clears session state, but without disconnecting
bool isConnected() const;
/// Returns true if connected, false otherwise.
bool isGood() const;
/// Returns true iff the database session is good.
/// For the session to be considered good:
/// - it must be connected
/// - and it's last error code must be 0,
/// or mysql_ping() must be okay.
///
/// Furthermore, if the "failIfInnoReadOnly" property
/// has been set to true, the innodb_read_only setting
/// must be false. The flag is only checked if the
/// session has a non-zero error code.
void setConnectionTimeout(std::size_t timeout);
/// Sets the session connection timeout value.
std::size_t getConnectionTimeout() const;
/// Returns the session connection timeout value.
void begin();
/// Starts a transaction
void commit();
/// Commits and ends a transaction
void rollback();
/// Aborts a transaction
bool canTransact() const;
/// Returns true if session has transaction capabilities.
bool isTransaction() const;
/// Returns true iff a transaction is a transaction is in progress, false otherwise.
void setTransactionIsolation(Poco::UInt32 ti);
/// Sets the transaction isolation level.
Poco::UInt32 getTransactionIsolation() const;
/// Returns the transaction isolation level.
bool hasTransactionIsolation(Poco::UInt32 ti) const;
/// Returns true iff the transaction isolation level corresponding
/// to the supplied bitmask is supported.
bool isTransactionIsolation(Poco::UInt32 ti) const;
/// Returns true iff the transaction isolation level corresponds
/// to the supplied bitmask.
void autoCommit(const std::string&, bool val);
/// Sets autocommit property for the session.
bool isAutoCommit(const std::string& name="") const;
/// Returns autocommit property value.
void setInsertId(const std::string&, const Poco::Any&);
/// Try to set insert id - do nothing.
Poco::Any getInsertId(const std::string&) const;
/// Get insert id
void setFailIfInnoReadOnly(const std::string&, bool value);
/// Sets the "failIfInnoReadOnly" feature. If set, isGood() will
/// return false if the database is in read-only mode.
bool getFailIfInnoReadOnly(const std::string&) const;
/// Returns the state of the "failIfInnoReadOnly" feature.
void setLastError(int err);
/// Sets an error code. If a non-zero error code is set, the session
/// is considered bad.
int getLastError() const;
/// Returns the last set error code.
SessionHandle& handle();
// Get handle
const std::string& connectorName() const;
/// Returns the name of the connector.
private:
template <typename T>
static inline T& getValue(MYSQL_BIND* pResult, T& val)
{
return val = *((T*) pResult->buffer);
}
template <typename T>
T& getSetting(const std::string& name, T& val) const
/// Returns required setting.
/// Limited to one setting at a time.
{
StatementExecutor ex(_handle);
ResultMetadata metadata;
metadata.reset();
ex.prepare(Poco::format("SELECT @@%s", name));
metadata.init(ex);
if (metadata.columnsReturned() > 0)
ex.bindResult(metadata.row());
else
throw InvalidArgumentException("No data returned.");
ex.execute(); ex.fetch();
MYSQL_BIND* pResult = metadata.row();
return getValue<T>(pResult, val);
}
std::string _connector;
mutable SessionHandle _handle;
bool _reset;
bool _connected;
bool _inTransaction;
bool _failIfInnoReadOnly;
std::size_t _timeout;
mutable int _lastError;
Poco::FastMutex _mutex;
};
//
// inlines
//
inline bool SessionImpl::canTransact() const
{
return true;
}
inline void SessionImpl::setInsertId(const std::string&, const Poco::Any&)
{
}
inline Poco::Any SessionImpl::getInsertId(const std::string&) const
{
return Poco::Any(Poco::UInt64(mysql_insert_id(_handle)));
}
inline void SessionImpl::setFailIfInnoReadOnly(const std::string&, bool value)
{
_failIfInnoReadOnly = value;
}
inline bool SessionImpl::getFailIfInnoReadOnly(const std::string&) const
{
return _failIfInnoReadOnly;
}
inline void SessionImpl::setLastError(int err)
{
_lastError = err;
}
inline int SessionImpl::getLastError() const
{
return _lastError;
}
inline SessionHandle& SessionImpl::handle()
{
return _handle;
}
inline const std::string& SessionImpl::connectorName() const
{
return _connector;
}
inline bool SessionImpl::isTransaction() const
{
return _inTransaction;
}
inline bool SessionImpl::isTransactionIsolation(Poco::UInt32 ti) const
{
return getTransactionIsolation() == ti;
}
inline std::size_t SessionImpl::getConnectionTimeout() const
{
return _timeout;
}
template <>
inline std::string& SessionImpl::getValue(MYSQL_BIND* pResult, std::string& val)
{
val.assign((char*) pResult->buffer, pResult->buffer_length);
return val;
}
} } } // namespace Poco::Data::MySQL
#endif // Data_MySQL_SessionImpl_INCLUDED