MySQL 9.1.0
Source Code Documentation
mysql_session.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2016, 2024, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef _ROUTER_MYSQL_SESSION_H_
27#define _ROUTER_MYSQL_SESSION_H_
28
31
32#include <functional>
33#include <memory>
34#include <stdexcept>
35#include <string>
36#include <vector>
37
38#include <mysql.h> // enum mysql_ssl_mode
39
42
43namespace mysqlrouter {
44
46 public:
47 MysqlError() = default;
48 MysqlError(unsigned int code, std::string message, std::string sql_state)
49 : code_{code},
50 message_{std::move(message)},
51 sql_state_{std::move(sql_state)} {}
52
53 operator bool() { return code_ != 0; }
54
55 std::string message() const { return message_; }
56 std::string sql_state() const { return sql_state_; }
57 unsigned int value() const { return code_; }
58
59 private:
60 unsigned int code_{0};
61 std::string message_;
62 std::string sql_state_;
63};
64
65namespace impl {
66/**
67 * gettable, settable option for mysql_option's.
68 *
69 * adapts scalar types like int/bool/... mysql_option's to
70 * mysql_options()/mysql_get_option().
71 *
72 * - mysql_options() expects a '&int'
73 * - mysql_get_option() expects a '&int'
74 */
75template <mysql_option Opt, class ValueType>
76class Option {
77 public:
78 using value_type = ValueType;
79
80 constexpr Option() = default;
81 constexpr explicit Option(value_type v) : v_{std::move(v)} {}
82
83 // get the option id
84 constexpr mysql_option option() const noexcept { return Opt; }
85
86 // get address of the storage.
87 constexpr const void *data() const { return std::addressof(v_); }
88
89 // get address of the storage.
90 constexpr void *data() { return std::addressof(v_); }
91
92 // set the value of the option
93 constexpr void value(value_type v) { v_ = v; }
94
95 // get the value of the option
96 constexpr value_type value() const { return v_; }
97
98 private:
100};
101
102/**
103 * gettable, settable option for 'const char *' based mysql_option's.
104 *
105 * adapts 'const char *' based mysql_option to
106 * mysql_options()/mysql_get_option().
107 *
108 * - mysql_options() expects a 'const char *'
109 * - mysql_get_option() expects a '&(const char *)'
110 */
111template <mysql_option Opt>
112class Option<Opt, const char *> {
113 public:
114 using value_type = const char *;
115
116 Option() = default;
117 constexpr explicit Option(value_type v) : v_{std::move(v)} {}
118
119 constexpr mysql_option option() const noexcept { return Opt; }
120
121 constexpr const void *data() const { return v_; }
122
123 constexpr void *data() { return std::addressof(v_); }
124
125 constexpr void value(value_type v) { v_ = v; }
126
127 constexpr value_type value() const { return v_; }
128
129 private:
131};
132
133template <mysql_option Opt>
134class Option<Opt, std::nullptr_t> {
135 public:
136 using value_type = std::nullptr_t;
137
138 Option() = default;
139 // accept a void *, but ignore it.
140 constexpr explicit Option(value_type) {}
141
142 constexpr mysql_option option() const noexcept { return Opt; }
143
144 constexpr const void *data() const { return nullptr; }
145
146 constexpr void *data() { return nullptr; }
147
148 constexpr value_type value() const { return nullptr; }
149};
150} // namespace impl
151
152// mysql_options() may be used with MYSQL * == nullptr to get global values.
153
155 public:
156 static constexpr int kDefaultConnectTimeout = 5;
157 static constexpr int kDefaultReadTimeout = 30;
158 typedef std::vector<const char *> Row;
159 typedef std::function<bool(const Row &)> RowProcessor;
160 typedef std::function<void(unsigned, MYSQL_FIELD *)> FieldValidator;
161
162 // text representations of SSL modes
163 static const char kSslModeDisabled[];
164 static const char kSslModePreferred[];
165 static const char kSslModeRequired[];
166 static const char kSslModeVerifyCa[];
167 static const char kSslModeVerifyIdentity[];
168 //
169 // mysql_option's
170 //
171 // (sorted by appearance in documentation)
172
173 // type for mysql_option's which set/get a 'bool'
174 template <mysql_option Opt>
176
177 // type for mysql_option's which set/get a 'unsigned int'
178 template <mysql_option Opt>
180
181 // type for mysql_option's which set/get a 'unsigned long'
182 template <mysql_option Opt>
184
185 // type for mysql_option's which set/get a 'const char *'
186 template <mysql_option Opt>
188
209 // TCP/UnixSocket/...
226
235
237 public:
238 Transaction(MySQLSession *session) : session_(session) {
239 session_->execute("START TRANSACTION");
240 }
241
243 if (session_) {
244 try {
245 session_->execute("ROLLBACK");
246 } catch (...) {
247 // ignore errors during rollback on d-tor
248 }
249 }
250 }
251
252 void commit() {
253 session_->execute("COMMIT");
254 session_ = nullptr;
255 }
256
257 void rollback() {
258 session_->execute("ROLLBACK");
259 session_ = nullptr;
260 }
261
262 private:
264 };
265
266 class Error : public std::runtime_error {
267 public:
268 // NOTE Not all calls to constructors provide the 3rd argument. To save
269 // time, only the code where it was needed atm was upgraded from 2 to
270 // 3 args; upgrade elsewhere if needed
271
272 Error(const char *error, unsigned int code,
273 const std::string message = "<not set>")
274 : std::runtime_error(error), code_(code), message_(message) {}
275
276 Error(const std::string &error, unsigned int code,
277 const std::string &message = "<not set>")
278 : std::runtime_error(error), code_(code), message_(message) {}
279
280 unsigned int code() const { return code_; }
281 std::string message() const { return message_; }
282
283 private:
284 const unsigned int code_;
285 const std::string message_;
286 };
287
288 class ResultRow {
289 public:
290 ResultRow(Row row) : row_{std::move(row)} {}
291 virtual ~ResultRow() = default;
292 size_t size() const { return row_.size(); }
293 const char *&operator[](size_t i) { return row_[i]; }
294
295 private:
297 };
298
299 MySQLSession();
300 virtual ~MySQLSession();
301
302 static mysql_ssl_mode parse_ssl_mode(
303 std::string ssl_mode); // throws std::logic_error
304 static const char *ssl_mode_to_string(mysql_ssl_mode ssl_mode) noexcept;
305
306 // throws Error, std::invalid_argument
307 virtual void set_ssl_options(mysql_ssl_mode ssl_mode,
308 const std::string &tls_version,
309 const std::string &ssl_cipher,
310 const std::string &ca, const std::string &capath,
311 const std::string &crl,
312 const std::string &crlpath);
313
314 mysql_ssl_mode ssl_mode() const;
315 std::string tls_version() const;
316 std::string ssl_cipher() const;
317 std::string ssl_ca() const;
318 std::string ssl_capath() const;
319 std::string ssl_crl() const;
320 std::string ssl_crlpath() const;
321
322 std::string ssl_cert() const;
323 std::string ssl_key() const;
324
325 int connect_timeout() const;
326 int read_timeout() const;
327
328 // throws Error
329 virtual void set_ssl_cert(const std::string &cert, const std::string &key);
330
331 /**
332 * set a mysql option.
333 *
334 * @code
335 * auto res = set_option(ConnectTimeout(10));
336 * @endcode
337 *
338 * @note on error the MysqlError may not always contain the right error-code.
339 *
340 * @param [in] opt option to set.
341 * @returns a MysqlError on error
342 * @retval true on success
343 */
344 template <class SettableMysqlOption>
345 stdx::expected<void, MysqlError> set_option(const SettableMysqlOption &opt) {
346 if (0 != mysql_options(connection_, opt.option(), opt.data())) {
347 return stdx::unexpected(MysqlError(mysql_errno(connection_),
348 mysql_error(connection_),
349 mysql_sqlstate(connection_)));
350 }
351
352 return {};
353 }
354
355 /**
356 * get a mysql option.
357 *
358 * @code
359 * ConnectTimeout opt_connect_timeout;
360 * auto res = get_option(opt_connect_timeout);
361 * if (res) {
362 * std::cerr << opt_connect_timeout.value() << std::endl;
363 * }
364 * @endcode
365 *
366 * @param [in,out] opt option to query.
367 * @retval true on success.
368 * @retval false if option is not known.
369 */
370 template <class GettableMysqlOption>
371 bool get_option(GettableMysqlOption &opt) const {
372 if (0 != mysql_get_option(connection_, opt.option(), opt.data())) {
373 return false;
374 }
375
376 return true;
377 }
378
379 virtual void connect(const std::string &host, unsigned int port,
380 const std::string &username, const std::string &password,
381 const std::string &unix_socket,
382 const std::string &default_schema,
384 int read_timeout = kDefaultReadTimeout); // throws Error
385 virtual void disconnect();
386
387 /**
388 * Connect using the same settings and parameters that were used for the last
389 * other.connect() using provided credentials.
390 */
391 virtual void connect(const MySQLSession &other, const std::string &username,
392 const std::string &password);
393
394 virtual void execute(
395 const std::string &query); // throws Error, std::logic_error
396 virtual void query(
397 const std::string &query, const RowProcessor &processor,
398 const FieldValidator &validator); // throws Error, std::logic_error
399 virtual std::unique_ptr<MySQLSession::ResultRow> query_one(
400 const std::string &query,
401 const FieldValidator &validator); // throws Error
402 //
403 void query(const std::string &stmt, const RowProcessor &processor) {
404 return query(stmt, processor, [](unsigned, MYSQL_FIELD *) {});
405 }
406
407 std::unique_ptr<MySQLSession::ResultRow> query_one(const std::string &stmt) {
408 return query_one(stmt, [](unsigned, MYSQL_FIELD *) {});
409 }
410
411 virtual uint64_t last_insert_id() noexcept;
412
413 virtual unsigned warning_count() noexcept;
414
415 virtual std::string quote(const std::string &s, char qchar = '\'') const;
416
417 virtual bool is_connected() noexcept { return connection_ && connected_; }
418 const std::string &get_address() noexcept { return connection_address_; }
419
420 virtual const char *last_error();
421 virtual unsigned int last_errno();
422
423 virtual const char *ssl_cipher();
424
425 virtual bool is_ssl_session_reused();
426
427 virtual unsigned long server_version();
428
429 private:
430 // stores selected parameters that were passed to the last successful call to
431 // connect()
432 struct {
433 std::string host;
434 unsigned int port{};
435 std::string unix_socket;
436 std::string default_schema;
437 } connect_params_;
438
443
445 public:
447 };
448
449 using mysql_result_type = std::unique_ptr<MYSQL_RES, MYSQL_RES_Deleter>;
450
451 /**
452 * run query.
453 *
454 * There are 3 cases:
455 *
456 * 1. query returns a resultset
457 * 3. query returns no resultset
458 * 2. query fails with an error
459 *
460 * @param q stmt to execute
461 *
462 * @returns resultset on success, MysqlError on error
463 */
465 const std::string &q);
466
467 /**
468 * log query before running it.
469 */
471 const std::string &q);
472
473 // if query be timed and sent to the sql-log.
475};
476
477} // namespace mysqlrouter
478
479#endif
Definition: mysql_session.h:266
Error(const char *error, unsigned int code, const std::string message="<not set>")
Definition: mysql_session.h:272
std::string message() const
Definition: mysql_session.h:281
unsigned int code() const
Definition: mysql_session.h:280
const std::string message_
Definition: mysql_session.h:285
Error(const std::string &error, unsigned int code, const std::string &message="<not set>")
Definition: mysql_session.h:276
const unsigned int code_
Definition: mysql_session.h:284
Definition: mysql_session.h:444
void operator()(MYSQL_RES *res)
Definition: mysql_session.h:446
Definition: mysql_session.h:288
ResultRow(Row row)
Definition: mysql_session.h:290
size_t size() const
Definition: mysql_session.h:292
Row row_
Definition: mysql_session.h:296
const char *& operator[](size_t i)
Definition: mysql_session.h:293
Definition: mysql_session.h:236
void commit()
Definition: mysql_session.h:252
Transaction(MySQLSession *session)
Definition: mysql_session.h:238
void rollback()
Definition: mysql_session.h:257
~Transaction()
Definition: mysql_session.h:242
MySQLSession * session_
Definition: mysql_session.h:263
Definition: mysql_session.h:154
std::function< void(unsigned, MYSQL_FIELD *)> FieldValidator
Definition: mysql_session.h:160
std::string connection_address_
Definition: mysql_session.h:441
bool get_option(GettableMysqlOption &opt) const
get a mysql option.
Definition: mysql_session.h:371
MYSQL * connection_
Definition: mysql_session.h:439
std::unique_ptr< MySQLSession::ResultRow > query_one(const std::string &stmt)
Definition: mysql_session.h:407
std::unique_ptr< MYSQL_RES, MYSQL_RES_Deleter > mysql_result_type
Definition: mysql_session.h:449
std::function< bool(const Row &)> RowProcessor
Definition: mysql_session.h:159
stdx::expected< void, MysqlError > set_option(const SettableMysqlOption &opt)
set a mysql option.
Definition: mysql_session.h:345
void query(const std::string &stmt, const RowProcessor &processor)
Definition: mysql_session.h:403
std::string default_schema
Definition: mysql_session.h:436
SQLLogFilter log_filter_
Definition: mysql_session.h:442
const std::string & get_address() noexcept
Definition: mysql_session.h:418
bool connected_
Definition: mysql_session.h:440
std::string host
Definition: mysql_session.h:433
std::string unix_socket
Definition: mysql_session.h:435
std::vector< const char * > Row
Definition: mysql_session.h:158
Definition: mysql_session.h:45
MysqlError(unsigned int code, std::string message, std::string sql_state)
Definition: mysql_session.h:48
unsigned int value() const
Definition: mysql_session.h:57
std::string message() const
Definition: mysql_session.h:55
std::string sql_state() const
Definition: mysql_session.h:56
std::string sql_state_
Definition: mysql_session.h:62
unsigned int code_
Definition: mysql_session.h:60
std::string message_
Definition: mysql_session.h:61
A SQLLogFilter allows to replace substrings defined by a set of hardcoded regular expressions with '*...
Definition: log_filter.h:77
gettable, settable option for 'const char *' based mysql_option's.
Definition: mysql_session.h:112
constexpr const void * data() const
Definition: mysql_session.h:121
const char * value_type
Definition: mysql_session.h:114
constexpr void * data()
Definition: mysql_session.h:123
constexpr Option(value_type v)
Definition: mysql_session.h:117
constexpr value_type value() const
Definition: mysql_session.h:127
constexpr mysql_option option() const noexcept
Definition: mysql_session.h:119
constexpr void value(value_type v)
Definition: mysql_session.h:125
constexpr mysql_option option() const noexcept
Definition: mysql_session.h:142
constexpr value_type value() const
Definition: mysql_session.h:148
constexpr void * data()
Definition: mysql_session.h:146
std::nullptr_t value_type
Definition: mysql_session.h:136
constexpr Option(value_type)
Definition: mysql_session.h:140
constexpr const void * data() const
Definition: mysql_session.h:144
gettable, settable option for mysql_option's.
Definition: mysql_session.h:76
constexpr Option()=default
constexpr Option(value_type v)
Definition: mysql_session.h:81
constexpr const void * data() const
Definition: mysql_session.h:87
ValueType value_type
Definition: mysql_session.h:78
constexpr void * data()
Definition: mysql_session.h:90
value_type v_
Definition: mysql_session.h:99
constexpr mysql_option option() const noexcept
Definition: mysql_session.h:84
constexpr value_type value() const
Definition: mysql_session.h:96
constexpr void value(value_type v)
Definition: mysql_session.h:93
Definition: expected.h:286
static bool execute(MYSQL_STMT *stmt, char *packet, ulong length, bool send_param_count)
Auxiliary function to send COM_STMT_EXECUTE packet to server and read reply.
Definition: libmysql.cc:1805
static char * query
Definition: myisam_ftdump.cc:47
static char * server_version
Definition: mysql.cc:118
This file defines the client API to MySQL and also the ABI of the dynamically linked libmysqlclient.
const char *STDCALL mysql_sqlstate(MYSQL *mysql)
Definition: client.cc:9536
unsigned int STDCALL mysql_errno(MYSQL *mysql)
Definition: client.cc:9194
mysql_option
Definition: mysql.h:170
int STDCALL mysql_get_option(MYSQL *mysql, enum mysql_option option, const void *arg)
Return the current values for the options settable through mysql_options()
Definition: client.cc:8893
const char *STDCALL mysql_error(MYSQL *mysql)
Definition: client.cc:9198
void STDCALL mysql_free_result(MYSQL_RES *result)
Definition: client.cc:1955
int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option, const void *arg)
Definition: client.cc:8554
mysql_ssl_mode
Definition: mysql.h:272
static char * password
Definition: mysql_secure_installation.cc:58
const char * host
Definition: mysqladmin.cc:65
void error(const char *format,...)
ulong connect_timeout
Definition: mysqld.cc:1347
void disconnect(Connection &c)
Definition: server.cc:48
Definition: http_server_component.cc:34
constexpr const unsigned int kDefaultConnectTimeout
Definition: metadata_cache.h:64
constexpr const unsigned int kDefaultReadTimeout
Definition: metadata_cache.h:66
Definition: base64.h:43
int last_error()
get last socket error.
Definition: socket_error.h:82
stdx::expected< void, error_type > connect(native_handle_type native_handle, const struct sockaddr *addr, size_t addr_len)
wrap connect() in a portable way.
Definition: socket.h:353
Definition: gcs_xcom_synode.h:64
unexpected(E) -> unexpected< E >
static int is_connected(connection_descriptor *con)
Definition: node_connection.h:94
required string key
Definition: replication_asynchronous_connection_failover.proto:60
required uint64 port
Definition: replication_asynchronous_connection_failover.proto:33
#define ROUTER_MYSQL_EXPORT
Definition: router_mysql_export.h:15
constexpr const char * ssl_mode_to_string(SslMode mode)
Definition: ssl_mode.h:44
Definition: mysql.h:121
Definition: mysql.h:340
Definition: mysql.h:300
synode_no q[FIFO_SIZE]
Definition: xcom_base.cc:4086