MySQL 9.0.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
30
31#include <functional>
32#include <memory>
33#include <stdexcept>
34#include <string>
35#include <vector>
36
37#include <mysql.h> // enum mysql_ssl_mode
38
41
42namespace mysqlrouter {
43
45 public:
46 MysqlError() = default;
47 MysqlError(unsigned int code, std::string message, std::string sql_state)
48 : code_{code},
49 message_{std::move(message)},
50 sql_state_{std::move(sql_state)} {}
51
52 operator bool() { return code_ != 0; }
53
54 std::string message() const { return message_; }
55 std::string sql_state() const { return sql_state_; }
56 unsigned int value() const { return code_; }
57
58 private:
59 unsigned int code_{0};
60 std::string message_;
61 std::string sql_state_;
62};
63
64namespace impl {
65/**
66 * gettable, settable option for mysql_option's.
67 *
68 * adapts scalar types like int/bool/... mysql_option's to
69 * mysql_options()/mysql_get_option().
70 *
71 * - mysql_options() expects a '&int'
72 * - mysql_get_option() expects a '&int'
73 */
74template <mysql_option Opt, class ValueType>
75class Option {
76 public:
77 using value_type = ValueType;
78
79 constexpr Option() = default;
80 constexpr explicit Option(value_type v) : v_{std::move(v)} {}
81
82 // get the option id
83 constexpr mysql_option option() const noexcept { return Opt; }
84
85 // get address of the storage.
86 constexpr const void *data() const { return std::addressof(v_); }
87
88 // get address of the storage.
89 constexpr void *data() { return std::addressof(v_); }
90
91 // set the value of the option
92 constexpr void value(value_type v) { v_ = v; }
93
94 // get the value of the option
95 constexpr value_type value() const { return v_; }
96
97 private:
99};
100
101/**
102 * gettable, settable option for 'const char *' based mysql_option's.
103 *
104 * adapts 'const char *' based mysql_option to
105 * mysql_options()/mysql_get_option().
106 *
107 * - mysql_options() expects a 'const char *'
108 * - mysql_get_option() expects a '&(const char *)'
109 */
110template <mysql_option Opt>
111class Option<Opt, const char *> {
112 public:
113 using value_type = const char *;
114
115 Option() = default;
116 constexpr explicit Option(value_type v) : v_{std::move(v)} {}
117
118 constexpr mysql_option option() const noexcept { return Opt; }
119
120 constexpr const void *data() const { return v_; }
121
122 constexpr void *data() { return std::addressof(v_); }
123
124 constexpr void value(value_type v) { v_ = v; }
125
126 constexpr value_type value() const { return v_; }
127
128 private:
130};
131
132template <mysql_option Opt>
133class Option<Opt, std::nullptr_t> {
134 public:
135 using value_type = std::nullptr_t;
136
137 Option() = default;
138 // accept a void *, but ignore it.
139 constexpr explicit Option(value_type) {}
140
141 constexpr mysql_option option() const noexcept { return Opt; }
142
143 constexpr const void *data() const { return nullptr; }
144
145 constexpr void *data() { return nullptr; }
146
147 constexpr value_type value() const { return nullptr; }
148};
149} // namespace impl
150
151// mysql_options() may be used with MYSQL * == nullptr to get global values.
152
154 public:
155 static constexpr int kDefaultConnectTimeout = 5;
156 static constexpr int kDefaultReadTimeout = 30;
157 typedef std::vector<const char *> Row;
158 typedef std::function<bool(const Row &)> RowProcessor;
159 typedef std::function<void(unsigned, MYSQL_FIELD *)> FieldValidator;
160
161 // text representations of SSL modes
162 static const char kSslModeDisabled[];
163 static const char kSslModePreferred[];
164 static const char kSslModeRequired[];
165 static const char kSslModeVerifyCa[];
166 static const char kSslModeVerifyIdentity[];
167 //
168 // mysql_option's
169 //
170 // (sorted by appearance in documentation)
171
172 // type for mysql_option's which set/get a 'bool'
173 template <mysql_option Opt>
175
176 // type for mysql_option's which set/get a 'unsigned int'
177 template <mysql_option Opt>
179
180 // type for mysql_option's which set/get a 'unsigned long'
181 template <mysql_option Opt>
183
184 // type for mysql_option's which set/get a 'const char *'
185 template <mysql_option Opt>
187
208 // TCP/UnixSocket/...
225
234
236 public:
237 Transaction(MySQLSession *session) : session_(session) {
238 session_->execute("START TRANSACTION");
239 }
240
242 if (session_) {
243 try {
244 session_->execute("ROLLBACK");
245 } catch (...) {
246 // ignore errors during rollback on d-tor
247 }
248 }
249 }
250
251 void commit() {
252 session_->execute("COMMIT");
253 session_ = nullptr;
254 }
255
256 void rollback() {
257 session_->execute("ROLLBACK");
258 session_ = nullptr;
259 }
260
261 private:
263 };
264
265 class Error : public std::runtime_error {
266 public:
267 // NOTE Not all calls to constructors provide the 3rd argument. To save
268 // time, only the code where it was needed atm was upgraded from 2 to
269 // 3 args; upgrade elsewhere if needed
270
271 Error(const char *error, unsigned int code,
272 const std::string message = "<not set>")
273 : std::runtime_error(error), code_(code), message_(message) {}
274
275 Error(const std::string &error, unsigned int code,
276 const std::string &message = "<not set>")
277 : std::runtime_error(error), code_(code), message_(message) {}
278
279 unsigned int code() const { return code_; }
280 std::string message() const { return message_; }
281
282 private:
283 const unsigned int code_;
284 const std::string message_;
285 };
286
287 class ResultRow {
288 public:
289 ResultRow(Row row) : row_{std::move(row)} {}
290 virtual ~ResultRow() = default;
291 size_t size() const { return row_.size(); }
292 const char *&operator[](size_t i) { return row_[i]; }
293
294 private:
296 };
297
299 LoggingStrategy() = default;
300
303
306
307 virtual ~LoggingStrategy() = default;
308
309 virtual void log(const std::string &msg) = 0;
310 };
311
313 virtual void log(const std::string & /*msg*/) override {}
314 };
315
317 : public LoggingStrategy {
318 virtual void log(const std::string &msg) override;
319 };
320
321 MySQLSession(std::unique_ptr<LoggingStrategy> logging_strategy =
322 std::make_unique<LoggingStrategyNone>());
323 virtual ~MySQLSession();
324
325 static mysql_ssl_mode parse_ssl_mode(
326 std::string ssl_mode); // throws std::logic_error
327 static const char *ssl_mode_to_string(mysql_ssl_mode ssl_mode) noexcept;
328
329 // throws Error, std::invalid_argument
330 virtual void set_ssl_options(mysql_ssl_mode ssl_mode,
331 const std::string &tls_version,
332 const std::string &ssl_cipher,
333 const std::string &ca, const std::string &capath,
334 const std::string &crl,
335 const std::string &crlpath);
336
337 mysql_ssl_mode ssl_mode() const;
338 std::string tls_version() const;
339 std::string ssl_cipher() const;
340 std::string ssl_ca() const;
341 std::string ssl_capath() const;
342 std::string ssl_crl() const;
343 std::string ssl_crlpath() const;
344
345 std::string ssl_cert() const;
346 std::string ssl_key() const;
347
348 int connect_timeout() const;
349 int read_timeout() const;
350
351 // throws Error
352 virtual void set_ssl_cert(const std::string &cert, const std::string &key);
353
354 /**
355 * set a mysql option.
356 *
357 * @code
358 * auto res = set_option(ConnectTimeout(10));
359 * @endcode
360 *
361 * @note on error the MysqlError may not always contain the right error-code.
362 *
363 * @param [in] opt option to set.
364 * @returns a MysqlError on error
365 * @retval true on success
366 */
367 template <class SettableMysqlOption>
368 stdx::expected<void, MysqlError> set_option(const SettableMysqlOption &opt) {
369 if (0 != mysql_options(connection_, opt.option(), opt.data())) {
370 return stdx::unexpected(MysqlError(mysql_errno(connection_),
371 mysql_error(connection_),
372 mysql_sqlstate(connection_)));
373 }
374
375 return {};
376 }
377
378 /**
379 * get a mysql option.
380 *
381 * @code
382 * ConnectTimeout opt_connect_timeout;
383 * auto res = get_option(opt_connect_timeout);
384 * if (res) {
385 * std::cerr << opt_connect_timeout.value() << std::endl;
386 * }
387 * @endcode
388 *
389 * @param [in,out] opt option to query.
390 * @retval true on success.
391 * @retval false if option is not known.
392 */
393 template <class GettableMysqlOption>
394 bool get_option(GettableMysqlOption &opt) const {
395 if (0 != mysql_get_option(connection_, opt.option(), opt.data())) {
396 return false;
397 }
398
399 return true;
400 }
401
402 virtual void connect(const std::string &host, unsigned int port,
403 const std::string &username, const std::string &password,
404 const std::string &unix_socket,
405 const std::string &default_schema,
407 int read_timeout = kDefaultReadTimeout); // throws Error
408 virtual void disconnect();
409
410 /**
411 * Connect using the same settings and parameters that were used for the last
412 * other.connect() using provided credentials.
413 */
414 virtual void connect(const MySQLSession &other, const std::string &username,
415 const std::string &password);
416
417 virtual void execute(
418 const std::string &query); // throws Error, std::logic_error
419 virtual void query(
420 const std::string &query, const RowProcessor &processor,
421 const FieldValidator &validator); // throws Error, std::logic_error
422 virtual std::unique_ptr<MySQLSession::ResultRow> query_one(
423 const std::string &query,
424 const FieldValidator &validator); // throws Error
425 //
426 void query(const std::string &stmt, const RowProcessor &processor) {
427 return query(stmt, processor, [](unsigned, MYSQL_FIELD *) {});
428 }
429
430 std::unique_ptr<MySQLSession::ResultRow> query_one(const std::string &stmt) {
431 return query_one(stmt, [](unsigned, MYSQL_FIELD *) {});
432 }
433
434 virtual uint64_t last_insert_id() noexcept;
435
436 virtual unsigned warning_count() noexcept;
437
438 virtual std::string quote(const std::string &s, char qchar = '\'') const;
439
440 virtual bool is_connected() noexcept { return connection_ && connected_; }
441 const std::string &get_address() noexcept { return connection_address_; }
442
443 virtual const char *last_error();
444 virtual unsigned int last_errno();
445
446 virtual const char *ssl_cipher();
447
448 virtual bool is_ssl_session_reused();
449
450 virtual unsigned long server_version();
451
452 protected:
453 std::unique_ptr<LoggingStrategy> logging_strategy_;
454
455 private:
456 // stores selected parameters that were passed to the last successful call to
457 // connect()
458 struct {
459 std::string host;
460 unsigned int port{};
461 std::string unix_socket;
462 std::string default_schema;
463 } connect_params_;
464
469
471 public:
473 };
474
475 using mysql_result_type = std::unique_ptr<MYSQL_RES, MYSQL_RES_Deleter>;
476
477 /**
478 * run query.
479 *
480 * There are 3 cases:
481 *
482 * 1. query returns a resultset
483 * 3. query returns no resultset
484 * 2. query fails with an error
485 *
486 * @param q stmt to execute
487 *
488 * @returns resultset on success, MysqlError on error
489 */
491 const std::string &q);
492
493 /**
494 * log query before running it.
495 */
497 const std::string &q);
498};
499
500} // namespace mysqlrouter
501
502#endif
Definition: mysql_session.h:265
Error(const char *error, unsigned int code, const std::string message="<not set>")
Definition: mysql_session.h:271
std::string message() const
Definition: mysql_session.h:280
unsigned int code() const
Definition: mysql_session.h:279
const std::string message_
Definition: mysql_session.h:284
Error(const std::string &error, unsigned int code, const std::string &message="<not set>")
Definition: mysql_session.h:275
const unsigned int code_
Definition: mysql_session.h:283
Definition: mysql_session.h:470
void operator()(MYSQL_RES *res)
Definition: mysql_session.h:472
Definition: mysql_session.h:287
ResultRow(Row row)
Definition: mysql_session.h:289
size_t size() const
Definition: mysql_session.h:291
Row row_
Definition: mysql_session.h:295
const char *& operator[](size_t i)
Definition: mysql_session.h:292
Definition: mysql_session.h:235
void commit()
Definition: mysql_session.h:251
Transaction(MySQLSession *session)
Definition: mysql_session.h:237
void rollback()
Definition: mysql_session.h:256
~Transaction()
Definition: mysql_session.h:241
MySQLSession * session_
Definition: mysql_session.h:262
Definition: mysql_session.h:153
std::function< void(unsigned, MYSQL_FIELD *)> FieldValidator
Definition: mysql_session.h:159
std::string connection_address_
Definition: mysql_session.h:467
bool get_option(GettableMysqlOption &opt) const
get a mysql option.
Definition: mysql_session.h:394
MYSQL * connection_
Definition: mysql_session.h:465
std::unique_ptr< MySQLSession::ResultRow > query_one(const std::string &stmt)
Definition: mysql_session.h:430
std::unique_ptr< MYSQL_RES, MYSQL_RES_Deleter > mysql_result_type
Definition: mysql_session.h:475
std::function< bool(const Row &)> RowProcessor
Definition: mysql_session.h:158
stdx::expected< void, MysqlError > set_option(const SettableMysqlOption &opt)
set a mysql option.
Definition: mysql_session.h:368
void query(const std::string &stmt, const RowProcessor &processor)
Definition: mysql_session.h:426
std::string default_schema
Definition: mysql_session.h:462
SQLLogFilter log_filter_
Definition: mysql_session.h:468
const std::string & get_address() noexcept
Definition: mysql_session.h:441
bool connected_
Definition: mysql_session.h:466
std::string host
Definition: mysql_session.h:459
std::unique_ptr< LoggingStrategy > logging_strategy_
Definition: mysql_session.h:453
std::string unix_socket
Definition: mysql_session.h:461
std::vector< const char * > Row
Definition: mysql_session.h:157
Definition: mysql_session.h:44
MysqlError(unsigned int code, std::string message, std::string sql_state)
Definition: mysql_session.h:47
unsigned int value() const
Definition: mysql_session.h:56
std::string message() const
Definition: mysql_session.h:54
std::string sql_state() const
Definition: mysql_session.h:55
std::string sql_state_
Definition: mysql_session.h:61
unsigned int code_
Definition: mysql_session.h:59
std::string message_
Definition: mysql_session.h:60
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:111
constexpr const void * data() const
Definition: mysql_session.h:120
const char * value_type
Definition: mysql_session.h:113
constexpr void * data()
Definition: mysql_session.h:122
constexpr Option(value_type v)
Definition: mysql_session.h:116
constexpr value_type value() const
Definition: mysql_session.h:126
constexpr mysql_option option() const noexcept
Definition: mysql_session.h:118
constexpr void value(value_type v)
Definition: mysql_session.h:124
constexpr mysql_option option() const noexcept
Definition: mysql_session.h:141
constexpr value_type value() const
Definition: mysql_session.h:147
constexpr void * data()
Definition: mysql_session.h:145
std::nullptr_t value_type
Definition: mysql_session.h:135
constexpr Option(value_type)
Definition: mysql_session.h:139
constexpr const void * data() const
Definition: mysql_session.h:143
gettable, settable option for mysql_option's.
Definition: mysql_session.h:75
constexpr Option()=default
constexpr Option(value_type v)
Definition: mysql_session.h:80
constexpr const void * data() const
Definition: mysql_session.h:86
ValueType value_type
Definition: mysql_session.h:77
constexpr void * data()
Definition: mysql_session.h:89
value_type v_
Definition: mysql_session.h:98
constexpr mysql_option option() const noexcept
Definition: mysql_session.h:83
constexpr value_type value() const
Definition: mysql_session.h:95
constexpr void value(value_type v)
Definition: mysql_session.h:92
Definition: expected.h:284
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:1734
static char * query
Definition: myisam_ftdump.cc:47
static char * server_version
Definition: mysql.cc:120
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:9534
unsigned int STDCALL mysql_errno(MYSQL *mysql)
Definition: client.cc:9192
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:8891
const char *STDCALL mysql_error(MYSQL *mysql)
Definition: client.cc:9196
void STDCALL mysql_free_result(MYSQL_RES *result)
Definition: client.cc:1954
int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option, const void *arg)
Definition: client.cc:8552
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:1342
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: dim.h:358
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
Definition: mysql_session.h:312
virtual void log(const std::string &) override
Definition: mysql_session.h:313
Definition: mysql_session.h:298
LoggingStrategy(const LoggingStrategy &)=default
LoggingStrategy & operator=(const LoggingStrategy &)=default
LoggingStrategy(LoggingStrategy &&)=default
virtual void log(const std::string &msg)=0
LoggingStrategy & operator=(LoggingStrategy &&)=default
synode_no q[FIFO_SIZE]
Definition: xcom_base.cc:4086