MySQL 8.3.0
Source Code Documentation
mysql_session.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2016, 2023, 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
41namespace mysqlrouter {
42
44 public:
45 MysqlError() = default;
46 MysqlError(unsigned int code, std::string message, std::string sql_state)
47 : code_{code},
48 message_{std::move(message)},
49 sql_state_{std::move(sql_state)} {}
50
51 operator bool() { return code_ != 0; }
52
53 std::string message() const { return message_; }
54 std::string sql_state() const { return sql_state_; }
55 unsigned int value() const { return code_; }
56
57 private:
58 unsigned int code_{0};
59 std::string message_;
60 std::string sql_state_;
61};
62
63namespace impl {
64/**
65 * gettable, settable option for mysql_option's.
66 *
67 * adapts scalar types like int/bool/... mysql_option's to
68 * mysql_options()/mysql_get_option().
69 *
70 * - mysql_options() expects a '&int'
71 * - mysql_get_option() expects a '&int'
72 */
73template <mysql_option Opt, class ValueType>
74class Option {
75 public:
76 using value_type = ValueType;
77
78 constexpr Option() = default;
79 constexpr explicit Option(value_type v) : v_{std::move(v)} {}
80
81 // get the option id
82 constexpr mysql_option option() const noexcept { return Opt; }
83
84 // get address of the storage.
85 constexpr const void *data() const { return std::addressof(v_); }
86
87 // get address of the storage.
88 constexpr void *data() { return std::addressof(v_); }
89
90 // set the value of the option
91 constexpr void value(value_type v) { v_ = v; }
92
93 // get the value of the option
94 constexpr value_type value() const { return v_; }
95
96 private:
98};
99
100/**
101 * gettable, settable option for 'const char *' based mysql_option's.
102 *
103 * adapts 'const char *' based mysql_option to
104 * mysql_options()/mysql_get_option().
105 *
106 * - mysql_options() expects a 'const char *'
107 * - mysql_get_option() expects a '&(const char *)'
108 */
109template <mysql_option Opt>
110class Option<Opt, const char *> {
111 public:
112 using value_type = const char *;
113
114 Option() = default;
115 constexpr explicit Option(value_type v) : v_{std::move(v)} {}
116
117 constexpr mysql_option option() const noexcept { return Opt; }
118
119 constexpr const void *data() const { return v_; }
120
121 constexpr void *data() { return std::addressof(v_); }
122
123 constexpr void value(value_type v) { v_ = v; }
124
125 constexpr value_type value() const { return v_; }
126
127 private:
129};
130
131template <mysql_option Opt>
132class Option<Opt, std::nullptr_t> {
133 public:
134 using value_type = std::nullptr_t;
135
136 Option() = default;
137 // accept a void *, but ignore it.
138 constexpr explicit Option(value_type) {}
139
140 constexpr mysql_option option() const noexcept { return Opt; }
141
142 constexpr const void *data() const { return nullptr; }
143
144 constexpr void *data() { return nullptr; }
145
146 constexpr value_type value() const { return nullptr; }
147};
148} // namespace impl
149
150// mysql_options() may be used with MYSQL * == nullptr to get global values.
151
153 public:
154 static constexpr int kDefaultConnectTimeout = 5;
155 static constexpr int kDefaultReadTimeout = 30;
156 typedef std::vector<const char *> Row;
157 typedef std::function<bool(const Row &)> RowProcessor;
158 typedef std::function<void(unsigned, MYSQL_FIELD *)> FieldValidator;
159
160 // text representations of SSL modes
161 static const char kSslModeDisabled[];
162 static const char kSslModePreferred[];
163 static const char kSslModeRequired[];
164 static const char kSslModeVerifyCa[];
165 static const char kSslModeVerifyIdentity[];
166 //
167 // mysql_option's
168 //
169 // (sorted by appearance in documentation)
170
171 // type for mysql_option's which set/get a 'bool'
172 template <mysql_option Opt>
174
175 // type for mysql_option's which set/get a 'unsigned int'
176 template <mysql_option Opt>
178
179 // type for mysql_option's which set/get a 'unsigned long'
180 template <mysql_option Opt>
182
183 // type for mysql_option's which set/get a 'const char *'
184 template <mysql_option Opt>
186
207 // 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::make_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:152
std::function< void(unsigned, MYSQL_FIELD *)> FieldValidator
Definition: mysql_session.h:158
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:157
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:156
Definition: mysql_session.h:43
MysqlError(unsigned int code, std::string message, std::string sql_state)
Definition: mysql_session.h:46
unsigned int value() const
Definition: mysql_session.h:55
std::string message() const
Definition: mysql_session.h:53
std::string sql_state() const
Definition: mysql_session.h:54
std::string sql_state_
Definition: mysql_session.h:60
unsigned int code_
Definition: mysql_session.h:58
std::string message_
Definition: mysql_session.h:59
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:110
constexpr const void * data() const
Definition: mysql_session.h:119
const char * value_type
Definition: mysql_session.h:112
constexpr void * data()
Definition: mysql_session.h:121
constexpr Option(value_type v)
Definition: mysql_session.h:115
constexpr value_type value() const
Definition: mysql_session.h:125
constexpr mysql_option option() const noexcept
Definition: mysql_session.h:117
constexpr void value(value_type v)
Definition: mysql_session.h:123
constexpr mysql_option option() const noexcept
Definition: mysql_session.h:140
constexpr value_type value() const
Definition: mysql_session.h:146
constexpr void * data()
Definition: mysql_session.h:144
std::nullptr_t value_type
Definition: mysql_session.h:134
constexpr Option(value_type)
Definition: mysql_session.h:138
constexpr const void * data() const
Definition: mysql_session.h:142
gettable, settable option for mysql_option's.
Definition: mysql_session.h:74
constexpr Option()=default
constexpr Option(value_type v)
Definition: mysql_session.h:79
constexpr const void * data() const
Definition: mysql_session.h:85
ValueType value_type
Definition: mysql_session.h:76
constexpr void * data()
Definition: mysql_session.h:88
value_type v_
Definition: mysql_session.h:97
constexpr mysql_option option() const noexcept
Definition: mysql_session.h:82
constexpr value_type value() const
Definition: mysql_session.h:94
constexpr void value(value_type v)
Definition: mysql_session.h:91
Definition: expected.h:943
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:1612
static char * query
Definition: myisam_ftdump.cc:46
static char * server_version
Definition: mysql.cc:119
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:9450
unsigned int STDCALL mysql_errno(MYSQL *mysql)
Definition: client.cc:9108
mysql_option
Definition: mysql.h:167
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:8807
const char *STDCALL mysql_error(MYSQL *mysql)
Definition: client.cc:9112
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:8468
mysql_ssl_mode
Definition: mysql.h:269
static char * password
Definition: mysql_secure_installation.cc:57
const char * host
Definition: mysqladmin.cc:63
ulong connect_timeout
Definition: mysqld.cc:1342
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:352
Definition: varlen_sort.h:174
constexpr auto make_unexpected(E &&e) -> unexpected< std::decay_t< E > >
Definition: expected.h:124
static int is_connected(connection_descriptor *con)
Definition: node_connection.h:93
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:337
Definition: mysql.h:297
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:4085