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