MySQL 8.0.30
Source Code Documentation
mysql_session.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2016, 2022, 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 also distributed 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 included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23*/
24
25#ifndef _ROUTER_MYSQL_SESSION_H_
26#define _ROUTER_MYSQL_SESSION_H_
27
29
30#include <functional>
31#include <memory>
32#include <stdexcept>
33#include <string>
34#include <vector>
35
36#include <mysql.h> // enum mysql_ssl_mode
37
40#ifdef FRIEND_TEST
41class MockMySQLSession;
42#endif
43
44namespace mysqlrouter {
45
47 public:
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_;
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 // this struct contains all parameters which would be needed if you wanted to
170 // create a new connection with same parameters (server address, options,
171 // etc)
173 struct SslOptions {
175 std::string tls_version;
176 std::string ssl_cipher;
177 std::string ca;
178 std::string capath;
179 std::string crl;
180 std::string crlpath;
181 } ssl_opts;
182 struct SslCert {
183 std::string cert;
184 std::string key;
185 } ssl_cert;
186 struct ConnOptions {
187 std::string host;
188 unsigned int port;
189 std::string username;
190 std::string password;
191 std::string unix_socket;
192 std::string default_schema;
195 } conn_opts;
196 };
197
198 //
199 // mysql_option's
200 //
201 // (sorted by appearance in documentation)
202
203 // type for mysql_option's which set/get a 'bool'
204 template <mysql_option Opt>
206
207 // type for mysql_option's which set/get a 'unsigned int'
208 template <mysql_option Opt>
210
211 // type for mysql_option's which set/get a 'unsigned long'
212 template <mysql_option Opt>
214
215 // type for mysql_option's which set/get a 'const char *'
216 template <mysql_option Opt>
218
239 // TCP/UnixSocket/...
257
266
268 public:
269 Transaction(MySQLSession *session) : session_(session) {
270 session_->execute("START TRANSACTION");
271 }
272
274 if (session_) {
275 try {
276 session_->execute("ROLLBACK");
277 } catch (...) {
278 // ignore errors during rollback on d-tor
279 }
280 }
281 }
282
283 void commit() {
284 session_->execute("COMMIT");
285 session_ = nullptr;
286 }
287
288 void rollback() {
289 session_->execute("ROLLBACK");
290 session_ = nullptr;
291 }
292
293 private:
295 };
296
297 class Error : public std::runtime_error {
298 public:
299 // NOTE Not all calls to constructors provide the 3rd argument. To save
300 // time, only the code where it was needed atm was upgraded from 2 to
301 // 3 args; upgrade elsewhere if needed
302
303 Error(const char *error, unsigned int code,
304 const std::string message = "<not set>")
305 : std::runtime_error(error), code_(code), message_(message) {}
306
307 Error(const std::string &error, unsigned int code,
308 const std::string &message = "<not set>")
309 : std::runtime_error(error), code_(code), message_(message) {}
310
311 unsigned int code() const { return code_; }
312 std::string message() const { return message_; }
313
314 private:
315 const unsigned int code_;
316 const std::string message_;
317 };
318
319 class ResultRow {
320 public:
321 ResultRow(Row row) : row_{std::move(row)} {}
322 virtual ~ResultRow() = default;
323 size_t size() const { return row_.size(); }
324 const char *&operator[](size_t i) { return row_[i]; }
325
326 private:
328 };
329
331 virtual void log(const std::string &msg) = 0;
332 virtual ~LoggingStrategy() = default;
333 };
334
336 virtual void log(const std::string & /*msg*/) override {}
337 };
338
340 virtual void log(const std::string &msg) override;
341 };
342
343 MySQLSession(std::unique_ptr<LoggingStrategy> logging_strategy =
344 std::make_unique<LoggingStrategyNone>());
345 virtual ~MySQLSession();
346
347 static mysql_ssl_mode parse_ssl_mode(
348 std::string ssl_mode); // throws std::logic_error
349 static const char *ssl_mode_to_string(mysql_ssl_mode ssl_mode) noexcept;
350
351 // throws Error, std::invalid_argument
352 virtual void set_ssl_options(mysql_ssl_mode ssl_mode,
353 const std::string &tls_version,
354 const std::string &ssl_cipher,
355 const std::string &ca, const std::string &capath,
356 const std::string &crl,
357 const std::string &crlpath);
358
359 // throws Error
360 virtual void set_ssl_cert(const std::string &cert, const std::string &key);
361
362 /**
363 * set a mysql option.
364 *
365 * @code
366 * auto res = set_option(ConnectTimeout(10));
367 * @endcode
368 *
369 * @note on error the MysqlError may not always contain the right error-code.
370 *
371 * @param [in] opt option to set.
372 * @returns a MysqlError on error
373 * @retval true on success
374 */
375 template <class SettableMysqlOption>
376 stdx::expected<void, MysqlError> set_option(const SettableMysqlOption &opt) {
377 if (0 != mysql_options(connection_, opt.option(), opt.data())) {
378 return stdx::make_unexpected(MysqlError(mysql_errno(connection_),
379 mysql_error(connection_),
380 mysql_sqlstate(connection_)));
381 }
382
383 return {};
384 }
385
386 /**
387 * get a mysql option.
388 *
389 * @code
390 * ConnectTimeout opt_connect_timeout;
391 * auto res = get_option(opt_connect_timeout);
392 * if (res) {
393 * std::cerr << opt_connect_timeout.value() << std::endl;
394 * }
395 * @endcode
396 *
397 * @param [in,out] opt option to query.
398 * @retval true on success.
399 * @retval false if option is not known.
400 */
401 template <class GettableMysqlOption>
402 bool get_option(GettableMysqlOption &opt) {
403 if (0 != mysql_get_option(connection_, opt.option(), opt.data())) {
404 return false;
405 }
406
407 return true;
408 }
409
410 virtual void connect(const std::string &host, unsigned int port,
411 const std::string &username, const std::string &password,
412 const std::string &unix_socket,
413 const std::string &default_schema,
415 int read_timeout = kDefaultReadTimeout); // throws Error
416 virtual void disconnect();
417
418 /**
419 * This is an alternative way to initialise a new connection. It calls
420 * connect() and several other methods under the hood. Along with its
421 * counterpart `get_connection_parameters()`, it's useful for spawning
422 * new connections using an existing connection as a template.
423 *
424 * @param conn_params Connection parameters
425 *
426 * @see get_connection_parameters()
427 */
428 virtual void connect_and_set_opts(const ConnectionParameters &conn_params);
429
430 /**
431 * Returns connection parameters which could be used as a template for
432 * spawning new connections.
433 *
434 * @see connect_and_set_opts()
435 *
436 * @returns parameters used to create current connection
437 */
439 return conn_params_;
440 }
441
442 virtual void execute(
443 const std::string &query); // throws Error, std::logic_error
444 virtual void query(
445 const std::string &query, const RowProcessor &processor,
446 const FieldValidator &validator =
447 null_field_validator); // throws Error, std::logic_error
448 virtual std::unique_ptr<MySQLSession::ResultRow> query_one(
449 const std::string &query,
450 const FieldValidator &validator = null_field_validator); // throws Error
451
452 virtual uint64_t last_insert_id() noexcept;
453
454 virtual unsigned warning_count() noexcept;
455
456 virtual std::string quote(const std::string &s, char qchar = '\'') const;
457
458 virtual bool is_connected() noexcept { return connection_ && connected_; }
459 const std::string &get_address() noexcept { return connection_address_; }
460
461 virtual const char *last_error();
462 virtual unsigned int last_errno();
463
464 virtual const char *ssl_cipher();
465
466 protected:
467 static const std::function<void(unsigned, MYSQL_FIELD *)>
469 std::unique_ptr<LoggingStrategy> logging_strategy_;
470
471 private:
473
478
479 virtual MYSQL *raw_mysql() noexcept { return connection_; }
480
481#ifdef FRIEND_TEST
482 friend class ::MockMySQLSession;
483#endif
484
486 public:
488 };
489
490 using mysql_result_type = std::unique_ptr<MYSQL_RES, MYSQL_RES_Deleter>;
491
492 /**
493 * run query.
494 *
495 * There are 3 cases:
496 *
497 * 1. query returns a resultset
498 * 3. query returns no resultset
499 * 2. query fails with an error
500 *
501 * @param q stmt to execute
502 *
503 * @returns resultset on sucess, MysqlError on error
504 */
506 const std::string &q);
507
508 /**
509 * log query before running it.
510 */
512 const std::string &q);
513};
514
515} // namespace mysqlrouter
516
517#endif
Definition: mysql_session.h:297
Error(const char *error, unsigned int code, const std::string message="<not set>")
Definition: mysql_session.h:303
std::string message() const
Definition: mysql_session.h:312
unsigned int code() const
Definition: mysql_session.h:311
const std::string message_
Definition: mysql_session.h:316
Error(const std::string &error, unsigned int code, const std::string &message="<not set>")
Definition: mysql_session.h:307
const unsigned int code_
Definition: mysql_session.h:315
Definition: mysql_session.h:485
void operator()(MYSQL_RES *res)
Definition: mysql_session.h:487
Definition: mysql_session.h:319
ResultRow(Row row)
Definition: mysql_session.h:321
size_t size() const
Definition: mysql_session.h:323
Row row_
Definition: mysql_session.h:327
const char *& operator[](size_t i)
Definition: mysql_session.h:324
Definition: mysql_session.h:267
void commit()
Definition: mysql_session.h:283
Transaction(MySQLSession *session)
Definition: mysql_session.h:269
void rollback()
Definition: mysql_session.h:288
~Transaction()
Definition: mysql_session.h:273
MySQLSession * session_
Definition: mysql_session.h:294
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:476
ConnectionParameters conn_params_
Definition: mysql_session.h:472
virtual MYSQL * raw_mysql() noexcept
Definition: mysql_session.h:479
MYSQL * connection_
Definition: mysql_session.h:474
std::unique_ptr< MYSQL_RES, MYSQL_RES_Deleter > mysql_result_type
Definition: mysql_session.h:490
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:376
static const std::function< void(unsigned, MYSQL_FIELD *)> null_field_validator
Definition: mysql_session.h:468
SQLLogFilter log_filter_
Definition: mysql_session.h:477
const std::string & get_address() noexcept
Definition: mysql_session.h:459
bool connected_
Definition: mysql_session.h:475
std::unique_ptr< LoggingStrategy > logging_strategy_
Definition: mysql_session.h:469
bool get_option(GettableMysqlOption &opt)
get a mysql option.
Definition: mysql_session.h:402
std::vector< const char * > Row
Definition: mysql_session.h:158
virtual ConnectionParameters get_connection_parameters()
Returns connection parameters which could be used as a template for spawning new connections.
Definition: mysql_session.h:438
Definition: mysql_session.h:46
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:76
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:936
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:1742
static char * query
Definition: myisam_ftdump.cc:44
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: libmysql.cc:935
unsigned int STDCALL mysql_errno(MYSQL *mysql)
Definition: client.cc:8990
mysql_option
Definition: mysql.h:169
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:8696
const char *STDCALL mysql_error(MYSQL *mysql)
Definition: client.cc:8994
void STDCALL mysql_free_result(MYSQL_RES *result)
Definition: client.cc:1939
int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option, const void *arg)
Definition: client.cc:8368
mysql_ssl_mode
Definition: mysql.h:270
static char * password
Definition: mysql_secure_installation.cc:55
Log error(cerr, "ERROR")
const char * host
Definition: mysqladmin.cc:58
ulong connect_timeout
Definition: mysqld.cc:1313
Definition: authentication.cc:35
constexpr const unsigned int kDefaultConnectTimeout
Definition: metadata_cache.h:64
constexpr const unsigned int kDefaultReadTimeout
Definition: metadata_cache.h:66
Definition: dim.h:357
int last_error()
get last socket error.
Definition: socket_error.h:81
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:346
Definition: varlen_sort.h:183
constexpr auto make_unexpected(E &&e) -> unexpected< std::decay_t< E > >
Definition: expected.h:117
static int is_connected(connection_descriptor *con)
Definition: node_connection.h:77
required string key
Definition: replication_asynchronous_connection_failover.proto:59
required uint64 port
Definition: replication_asynchronous_connection_failover.proto:32
#define ROUTER_LIB_EXPORT
Definition: router_export.h:15
constexpr const char * ssl_mode_to_string(SslMode mode)
Definition: ssl_mode.h:43
Definition: mysql.h:120
Definition: mysql.h:338
Definition: mysql.h:298
std::string username
Definition: mysql_session.h:189
std::string default_schema
Definition: mysql_session.h:192
std::string password
Definition: mysql_session.h:190
std::string unix_socket
Definition: mysql_session.h:191
unsigned int port
Definition: mysql_session.h:188
std::string host
Definition: mysql_session.h:187
std::string cert
Definition: mysql_session.h:183
std::string key
Definition: mysql_session.h:184
std::string tls_version
Definition: mysql_session.h:175
std::string crlpath
Definition: mysql_session.h:180
std::string crl
Definition: mysql_session.h:179
mysql_ssl_mode ssl_mode
Definition: mysql_session.h:174
std::string ca
Definition: mysql_session.h:177
std::string ssl_cipher
Definition: mysql_session.h:176
std::string capath
Definition: mysql_session.h:178
Definition: mysql_session.h:335
virtual void log(const std::string &) override
Definition: mysql_session.h:336
Definition: mysql_session.h:330
virtual void log(const std::string &msg)=0
synode_no q[FIFO_SIZE]
Definition: xcom_base.cc:4055