MySQL 8.4.3
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 bool log_will_be_ignored() const = 0;
310
311 virtual void log(const std::string &msg) = 0;
312 };
313
315 // nothing will be logged.
316 bool log_will_be_ignored() const override { return true; }
317
318 void log(const std::string & /*msg*/) override {}
319 };
320
322 : public LoggingStrategy {
323 bool log_will_be_ignored() const override;
324
325 void log(const std::string &msg) override;
326 };
327
328 MySQLSession(std::unique_ptr<LoggingStrategy> logging_strategy =
329 std::make_unique<LoggingStrategyNone>());
330 virtual ~MySQLSession();
331
332 static mysql_ssl_mode parse_ssl_mode(
333 std::string ssl_mode); // throws std::logic_error
334 static const char *ssl_mode_to_string(mysql_ssl_mode ssl_mode) noexcept;
335
336 // throws Error, std::invalid_argument
337 virtual void set_ssl_options(mysql_ssl_mode ssl_mode,
338 const std::string &tls_version,
339 const std::string &ssl_cipher,
340 const std::string &ca, const std::string &capath,
341 const std::string &crl,
342 const std::string &crlpath);
343
344 mysql_ssl_mode ssl_mode() const;
345 std::string tls_version() const;
346 std::string ssl_cipher() const;
347 std::string ssl_ca() const;
348 std::string ssl_capath() const;
349 std::string ssl_crl() const;
350 std::string ssl_crlpath() const;
351
352 std::string ssl_cert() const;
353 std::string ssl_key() const;
354
355 int connect_timeout() const;
356 int read_timeout() const;
357
358 // throws Error
359 virtual void set_ssl_cert(const std::string &cert, const std::string &key);
360
361 /**
362 * set a mysql option.
363 *
364 * @code
365 * auto res = set_option(ConnectTimeout(10));
366 * @endcode
367 *
368 * @note on error the MysqlError may not always contain the right error-code.
369 *
370 * @param [in] opt option to set.
371 * @returns a MysqlError on error
372 * @retval true on success
373 */
374 template <class SettableMysqlOption>
375 stdx::expected<void, MysqlError> set_option(const SettableMysqlOption &opt) {
376 if (0 != mysql_options(connection_, opt.option(), opt.data())) {
377 return stdx::unexpected(MysqlError(mysql_errno(connection_),
378 mysql_error(connection_),
379 mysql_sqlstate(connection_)));
380 }
381
382 return {};
383 }
384
385 /**
386 * get a mysql option.
387 *
388 * @code
389 * ConnectTimeout opt_connect_timeout;
390 * auto res = get_option(opt_connect_timeout);
391 * if (res) {
392 * std::cerr << opt_connect_timeout.value() << std::endl;
393 * }
394 * @endcode
395 *
396 * @param [in,out] opt option to query.
397 * @retval true on success.
398 * @retval false if option is not known.
399 */
400 template <class GettableMysqlOption>
401 bool get_option(GettableMysqlOption &opt) const {
402 if (0 != mysql_get_option(connection_, opt.option(), opt.data())) {
403 return false;
404 }
405
406 return true;
407 }
408
409 virtual void connect(const std::string &host, unsigned int port,
410 const std::string &username, const std::string &password,
411 const std::string &unix_socket,
412 const std::string &default_schema,
414 int read_timeout = kDefaultReadTimeout); // throws Error
415 virtual void disconnect();
416
417 /**
418 * Connect using the same settings and parameters that were used for the last
419 * other.connect() using provided credentials.
420 */
421 virtual void connect(const MySQLSession &other, const std::string &username,
422 const std::string &password);
423
424 virtual void execute(
425 const std::string &query); // throws Error, std::logic_error
426 virtual void query(
427 const std::string &query, const RowProcessor &processor,
428 const FieldValidator &validator); // throws Error, std::logic_error
429 virtual std::unique_ptr<MySQLSession::ResultRow> query_one(
430 const std::string &query,
431 const FieldValidator &validator); // throws Error
432 //
433 void query(const std::string &stmt, const RowProcessor &processor) {
434 return query(stmt, processor, [](unsigned, MYSQL_FIELD *) {});
435 }
436
437 std::unique_ptr<MySQLSession::ResultRow> query_one(const std::string &stmt) {
438 return query_one(stmt, [](unsigned, MYSQL_FIELD *) {});
439 }
440
441 virtual uint64_t last_insert_id() noexcept;
442
443 virtual unsigned warning_count() noexcept;
444
445 virtual std::string quote(const std::string &s, char qchar = '\'') const;
446
447 virtual bool is_connected() noexcept { return connection_ && connected_; }
448 const std::string &get_address() noexcept { return connection_address_; }
449
450 virtual const char *last_error();
451 virtual unsigned int last_errno();
452
453 virtual const char *ssl_cipher();
454
455 virtual bool is_ssl_session_reused();
456
457 virtual unsigned long server_version();
458
459 protected:
460 std::unique_ptr<LoggingStrategy> logging_strategy_;
461
462 private:
463 // stores selected parameters that were passed to the last successful call to
464 // connect()
465 struct {
466 std::string host;
467 unsigned int port{};
468 std::string unix_socket;
469 std::string default_schema;
470 } connect_params_;
471
476
478 public:
480 };
481
482 using mysql_result_type = std::unique_ptr<MYSQL_RES, MYSQL_RES_Deleter>;
483
484 /**
485 * run query.
486 *
487 * There are 3 cases:
488 *
489 * 1. query returns a resultset
490 * 3. query returns no resultset
491 * 2. query fails with an error
492 *
493 * @param q stmt to execute
494 *
495 * @returns resultset on success, MysqlError on error
496 */
498 const std::string &q);
499
500 /**
501 * log query before running it.
502 */
504 const std::string &q);
505};
506
507} // namespace mysqlrouter
508
509#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:477
void operator()(MYSQL_RES *res)
Definition: mysql_session.h:479
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:474
bool get_option(GettableMysqlOption &opt) const
get a mysql option.
Definition: mysql_session.h:401
MYSQL * connection_
Definition: mysql_session.h:472
std::unique_ptr< MySQLSession::ResultRow > query_one(const std::string &stmt)
Definition: mysql_session.h:437
std::unique_ptr< MYSQL_RES, MYSQL_RES_Deleter > mysql_result_type
Definition: mysql_session.h:482
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:375
void query(const std::string &stmt, const RowProcessor &processor)
Definition: mysql_session.h:433
std::string default_schema
Definition: mysql_session.h:469
SQLLogFilter log_filter_
Definition: mysql_session.h:475
const std::string & get_address() noexcept
Definition: mysql_session.h:448
bool connected_
Definition: mysql_session.h:473
std::string host
Definition: mysql_session.h:466
std::unique_ptr< LoggingStrategy > logging_strategy_
Definition: mysql_session.h:460
std::string unix_socket
Definition: mysql_session.h:468
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: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: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:9516
unsigned int STDCALL mysql_errno(MYSQL *mysql)
Definition: client.cc:9174
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:8873
const char *STDCALL mysql_error(MYSQL *mysql)
Definition: client.cc:9178
void STDCALL mysql_free_result(MYSQL_RES *result)
Definition: client.cc:1956
int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option, const void *arg)
Definition: client.cc:8534
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:1340
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
Definition: mysql_session.h:314
bool log_will_be_ignored() const override
Definition: mysql_session.h:316
void log(const std::string &) override
Definition: mysql_session.h:318
Definition: mysql_session.h:298
LoggingStrategy(const LoggingStrategy &)=default
LoggingStrategy & operator=(const LoggingStrategy &)=default
virtual bool log_will_be_ignored() const =0
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