MySQL 8.0.39
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/...
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
300 LoggingStrategy() = default;
301
304
307
308 virtual ~LoggingStrategy() = default;
309
310 virtual void log(const std::string &msg) = 0;
311 };
312
314 virtual void log(const std::string & /*msg*/) override {}
315 };
316
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::make_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 protected:
449 std::unique_ptr<LoggingStrategy> logging_strategy_;
450
451 private:
452 // stores selected parameters that were passed to the last successful call to
453 // connect()
454 struct {
455 std::string host;
456 unsigned int port{};
457 std::string unix_socket;
458 std::string default_schema;
459 } connect_params_;
460
465
466 virtual MYSQL *raw_mysql() noexcept { return connection_; }
467
469 public:
471 };
472
473 using mysql_result_type = std::unique_ptr<MYSQL_RES, MYSQL_RES_Deleter>;
474
475 /**
476 * run query.
477 *
478 * There are 3 cases:
479 *
480 * 1. query returns a resultset
481 * 3. query returns no resultset
482 * 2. query fails with an error
483 *
484 * @param q stmt to execute
485 *
486 * @returns resultset on success, MysqlError on error
487 */
489 const std::string &q);
490
491 /**
492 * log query before running it.
493 */
495 const std::string &q);
496};
497
498} // namespace mysqlrouter
499
500#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:468
void operator()(MYSQL_RES *res)
Definition: mysql_session.h:470
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:153
std::function< void(unsigned, MYSQL_FIELD *)> FieldValidator
Definition: mysql_session.h:159
std::string connection_address_
Definition: mysql_session.h:463
virtual MYSQL * raw_mysql() noexcept
Definition: mysql_session.h:466
bool get_option(GettableMysqlOption &opt) const
get a mysql option.
Definition: mysql_session.h:394
MYSQL * connection_
Definition: mysql_session.h:461
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:473
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:458
SQLLogFilter log_filter_
Definition: mysql_session.h:464
const std::string & get_address() noexcept
Definition: mysql_session.h:441
bool connected_
Definition: mysql_session.h:462
std::string host
Definition: mysql_session.h:455
std::unique_ptr< LoggingStrategy > logging_strategy_
Definition: mysql_session.h:449
std::string unix_socket
Definition: mysql_session.h:457
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:944
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:1718
static char * query
Definition: myisam_ftdump.cc:45
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:9409
unsigned int STDCALL mysql_errno(MYSQL *mysql)
Definition: client.cc:9086
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:8789
const char *STDCALL mysql_error(MYSQL *mysql)
Definition: client.cc:9090
void STDCALL mysql_free_result(MYSQL_RES *result)
Definition: client.cc:1948
int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option, const void *arg)
Definition: client.cc:8455
mysql_ssl_mode
Definition: mysql.h:271
static char * password
Definition: mysql_secure_installation.cc:56
Log error(cerr, "ERROR")
const char * host
Definition: mysqladmin.cc:59
ulong connect_timeout
Definition: mysqld.cc:1329
Definition: authentication.cc:36
constexpr const unsigned int kDefaultConnectTimeout
Definition: metadata_cache.h:65
constexpr const unsigned int kDefaultReadTimeout
Definition: metadata_cache.h:67
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
constexpr auto make_unexpected(E &&e) -> unexpected< std::decay_t< E > >
Definition: expected.h:125
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:339
Definition: mysql.h:299
Definition: mysql_session.h:313
virtual void log(const std::string &) override
Definition: mysql_session.h:314
Definition: mysql_session.h:299
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:4059