123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919 |
- /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.0, as
- * published by the Free Software Foundation.
- *
- * This program is also distributed with certain software (including
- * but not limited to OpenSSL) that is licensed under separate terms,
- * as designated in a particular file or component or in included license
- * documentation. The authors of MySQL hereby grant you an
- * additional permission to link the program and your derivative works
- * with the separately licensed software that they have included with
- * MySQL.
- *
- * Without limiting anything contained in the foregoing, this file,
- * which is part of MySQL Connector/C++, is also subject to the
- * Universal FOSS Exception, version 1.0, a copy of which can be found at
- * http://oss.oracle.com/licenses/universal-foss-exception.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License, version 2.0, for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #ifndef MYSQLX_DEVAPI_SETTINGS_H
- #define MYSQLX_DEVAPI_SETTINGS_H
- /**
- @file
- TODO
- */
- #include "common.h"
- #include "detail/settings.h"
- namespace mysqlx {
- /**
- Client creation options
- */
- enum_class ClientOption
- {
- #define CLIENT_OPT_ENUM_any(X,N) X = N,
- #define CLIENT_OPT_ENUM_num(X,N) X = N,
- #define CLIENT_OPT_ENUM_str(X,N) X = N,
- #define CLIENT_OPT_ENUM_end(X,N) X = N,
- CLIENT_OPTION_LIST(CLIENT_OPT_ENUM)
- };
- /// @cond DISABLED
- // Note: Doxygen gets confused here and renders docs incorrectly.
- inline
- std::string ClientOptionName(ClientOption opt)
- {
- #define CLT_OPT_NAME_any(X,N) case ClientOption::X: return #X;
- #define CLT_OPT_NAME_bool(X,N) CLT_OPT_NAME_any(X,N)
- #define CLT_OPT_NAME_num(X,N) CLT_OPT_NAME_any(X,N)
- #define CLT_OPT_NAME_str(X,N) CLT_OPT_NAME_any(X,N)
- #define CLT_OPT_NAME_end(X,N) // let it use the default
- switch(opt)
- {
- CLIENT_OPTION_LIST(CLT_OPT_NAME)
- default:
- {
- std::ostringstream buf;
- buf << "<UKNOWN (" << unsigned(opt) << ")>" << std::ends;
- return buf.str();
- }
- };
- }
- /// @endcond
- /*
- TODO: Cross-references to session options inside Doxygen docs do not work.
- */
- /**
- Session creation options
- @note `PRIORITY` should be defined after a `HOST` (`PORT`) to which
- it applies.
- @note Specifying `SSL_CA` option requires `SSL_MODE` value of `VERIFY_CA`
- or `VERIFY_IDENTITY`. If `SSL_MODE` is not explicitly given then
- setting `SSL_CA` implies `VERIFY_CA`.
- */
- enum_class SessionOption
- {
- #define SESS_OPT_ENUM_any(X,N) X = N,
- #define SESS_OPT_ENUM_num(X,N) X = N,
- #define SESS_OPT_ENUM_str(X,N) X = N,
- SESSION_OPTION_LIST(SESS_OPT_ENUM)
- LAST
- };
- /// @cond DISABLED
- // Note: Doxygen gets confused here and renders docs incorrectly.
- inline
- std::string SessionOptionName(SessionOption opt)
- {
- #define SESS_OPT_NAME_any(X,N) case SessionOption::X: return #X;
- #define SESS_OPT_NAME_num(X,N) SESS_OPT_NAME_any(X,N)
- #define SESS_OPT_NAME_str(X,N) SESS_OPT_NAME_any(X,N)
- switch(opt)
- {
- SESSION_OPTION_LIST(SESS_OPT_NAME)
- default:
- {
- std::ostringstream buf;
- buf << "<UKNOWN (" << unsigned(opt) << ")>" << std::ends;
- return buf.str();
- }
- };
- }
- /// @endcond
- /**
- Modes to be used with `SSL_MODE` option
- */
- enum_class SSLMode
- {
- #define SSL_ENUM(X,N) X = N,
- SSL_MODE_LIST(SSL_ENUM)
- };
- /// @cond DISABLED
- inline
- std::string SSLModeName(SSLMode m)
- {
- #define MODE_NAME(X,N) case SSLMode::X: return #X;
- switch(m)
- {
- SSL_MODE_LIST(MODE_NAME)
- default:
- {
- std::ostringstream buf;
- buf << "<UKNOWN (" << unsigned(m) << ")>" << std::ends;
- return buf.str();
- }
- };
- }
- /// @endcond
- /**
- Authentication methods to be used with `AUTH` option.
- */
- enum_class AuthMethod
- {
- #define AUTH_ENUM(X,N) X=N,
- AUTH_METHOD_LIST(AUTH_ENUM)
- };
- /// @cond DISABLED
- inline
- std::string AuthMethodName(AuthMethod m)
- {
- #define AUTH_NAME(X,N) case AuthMethod::X: return #X;
- switch(m)
- {
- AUTH_METHOD_LIST(AUTH_NAME)
- default:
- {
- std::ostringstream buf;
- buf << "<UKNOWN (" << unsigned(m) << ")>" << std::ends;
- return buf.str();
- }
- };
- }
- /// @endcond
- namespace internal {
- /*
- Encapsulate public enumerations in the Settings_traits class to be used
- by Settings_detail<> template.
- */
- struct Settings_traits
- {
- using Options = mysqlx::SessionOption;
- using CliOptions = mysqlx::ClientOption;
- using SSLMode = mysqlx::SSLMode;
- using AuthMethod = mysqlx::AuthMethod;
- static std::string get_mode_name(SSLMode mode)
- {
- return SSLModeName(mode);
- }
- static std::string get_option_name(Options opt)
- {
- return SessionOptionName(opt);
- }
- static std::string get_auth_name(AuthMethod m)
- {
- return AuthMethodName(m);
- }
- };
- template<>
- PUBLIC_API
- void
- internal::Settings_detail<internal::Settings_traits>::
- do_set(session_opt_list_t &&opts);
- } // internal namespace
- class Client;
- class Session;
- /**
- Represents session options to be passed at session creation time.
- SessionSettings can be constructed using a connection string, common
- connect options (host, port, user, password, database) or with a list
- of `SessionOption` constants, each followed by the option value.
- Examples:
- ~~~~~~
- SessionSettings from_url("mysqlx://user:pwd@host:port/db?ssl-mode=required");
- SessionSettings from_options("host", port, "user", "pwd", "db");
- SessionSettings from_option_list(
- SessionOption::USER, "user",
- SessionOption::PWD, "pwd",
- SessionOption::HOST, "host",
- SessionOption::PORT, port,
- SessionOption::DB, "db",
- SessionOption::SSL_MODE, SSLMode::REQUIRED
- );
- ~~~~~~
- The HOST, PORT and SOCKET settings can be repeated to build a list of hosts
- to be used by the connection fail-over logic when creating a session (see
- description of `Session` class). In that case each host can be assigned
- a priority by setting the `PRIORITY` option. If priorities are not explicitly
- assigned, hosts are tried in the order in which they are specified in session
- settings. If priorities are used, they must be assigned to all hosts
- specified in the settings.
- @ingroup devapi
- */
- class SessionSettings
- : private internal::Settings_detail<internal::Settings_traits>
- {
- using Value = mysqlx::Value;
- public:
- /**
- Create session settings from a connection string.
- Connection sting has the form
- "user:pass@connection-data/db?option&option"
- with optional `mysqlx://` prefix.
- The `connetction-data` part is either a single host address or a coma
- separated list of hosts in square brackets: `[host1, host2, ..., hostN]`.
- In the latter case the connection fail-over logic will be used when
- creating the session.
- A single host address is either a DNS host name, an IPv4 address of
- the form "nn.nn.nn.nn" or an IPv6 address of the form "[nn:nn:nn:...]".
- On Unix systems a host can be specified as a path to a Unix domain
- socket - this path must start with `/` or `.`.
- Characters like `/` in the connection data, which otherwise have a special
- meaning inside a connection string, must be represented using percent
- encoding (e.g., `%2F` for `/`). Another option is to enclose a host name or
- a socket path in round braces. For example, one can write
- "mysqlx://(./path/to/socket)/db"
- instead of
- "mysqlx://.%2Fpath%2Fto%2Fsocket/db"
- To specify priorities for hosts in a multi-host settings, use list of pairs
- of the form `(address=host,priority=N)`. If priorities are specified, they
- must be given to all hosts in the list.
- The optional `db` part of the connection string defines the default schema
- of the session.
- Possible connection options are:
- - `ssl-mode` : define `SSLMode` option to be used
- - `ssl-ca=`path : path to a PEM file specifying trusted root certificates
- */
- SessionSettings(const string &uri)
- {
- try {
- Settings_detail::set_from_uri(uri);
- }
- CATCH_AND_WRAP
- }
- /**
- Explicitly specify basic connection settings.
- @note Session settings constructed this way request an SSL connection
- by default.
- */
- SessionSettings(const std::string &host, unsigned port,
- const string &user,
- const char *pwd = NULL,
- const string &db = string())
- {
- set(
- SessionOption::HOST, host,
- SessionOption::PORT, port,
- SessionOption::USER, user
- );
- if (pwd)
- set(SessionOption::PWD, std::string(pwd));
- if (!db.empty())
- set(SessionOption::DB, db);
- }
- SessionSettings(const std::string &host, unsigned port,
- const string &user,
- const std::string &pwd,
- const string &db = string())
- : SessionSettings(host, port, user, pwd.c_str(), db)
- {}
- /**
- Basic settings with the default port
- @note Session settings constructed this way request an SSL connection
- by default.
- */
- SessionSettings(const std::string &host,
- const string &user,
- const char *pwd = NULL,
- const string &db = string())
- : SessionSettings(host, DEFAULT_MYSQLX_PORT, user, pwd, db)
- {}
- SessionSettings(const std::string &host,
- const string &user,
- const std::string &pwd,
- const string &db = string())
- : SessionSettings(host, DEFAULT_MYSQLX_PORT, user, pwd, db)
- {}
- /**
- Basic settings for a session on the localhost.
- @note Session settings constructed this way request an SSL connection
- by default.
- */
- SessionSettings(unsigned port,
- const string &user,
- const char *pwd = NULL,
- const string &db = string())
- : SessionSettings("localhost", port, user, pwd, db)
- {}
- SessionSettings(unsigned port,
- const string &user,
- const std::string &pwd,
- const string &db = string())
- : SessionSettings("localhost", port, user, pwd.c_str(), db)
- {}
- /*
- Templates below are here to take care of the optional password
- parameter of type const char* (which can be either 3-rd or 4-th in
- the parameter list). Without these templates passing
- NULL as password is ambiguous because NULL is defined as 0,
- which has type int, and then it could be treated as port value.
- */
- template <
- typename HOST,
- typename PORT,
- typename USER,
- typename... T,
- typename std::enable_if<
- std::is_constructible<SessionSettings, HOST, PORT, USER, const char*, T...>::value
- >::type* = nullptr
- >
- SessionSettings(HOST h, PORT p, USER u ,long , T... args)
- : SessionSettings(h, p, u, nullptr, args...)
- {}
- template <
- typename PORT,
- typename USER,
- typename... T,
- typename std::enable_if<
- std::is_constructible<SessionSettings, PORT, USER, const char*, T...>::value
- >::type* = nullptr
- >
- SessionSettings(PORT p, USER u ,long , T... args)
- : SessionSettings(p, u, nullptr, args...)
- {}
- /**
- Specify settings as a list of session options.
- The list of options consist of a SessionOption constant,
- identifying the option to set, followed by the value of the option.
- Example:
- ~~~~~~
- SessionSettings from_option_list(
- SessionOption::USER, "user",
- SessionOption::PWD, "pwd",
- SessionOption::HOST, "host",
- SessionOption::PORT, port,
- SessionOption::DB, "db",
- SessionOption::SSL_MODE, SessionSettings::SSLMode::REQUIRED
- );
- ~~~~~~
- */
- template <typename... R>
- SessionSettings(SessionOption opt, R&&...rest)
- {
- try {
- // set<true> means that only SessionOption can be used
- Settings_detail::set<true>(opt, std::forward<R>(rest)...);
- }
- CATCH_AND_WRAP
- }
- /*
- Return an iterator pointing to the first element of the SessionSettings.
- */
- using Settings_detail::iterator;
- iterator begin()
- {
- try {
- return Settings_detail::begin();
- }
- CATCH_AND_WRAP
- }
- /*
- Return an iterator pointing to the last element of the SessionSettings.
- */
- iterator end()
- {
- try {
- return Settings_detail::end();
- }
- CATCH_AND_WRAP
- }
- /**
- Find the specified option @p opt and returns its Value.
- Returns NULL Value if not found.
- @note For option such as `HOST`, which can repeat several times in
- the settings, only the last value is reported.
- */
- Value find(SessionOption opt)
- {
- try {
- return Settings_detail::get(opt);
- }
- CATCH_AND_WRAP
- }
- /**
- Set session options.
- Accepts a list of one or more `SessionOption` constants, each followed by
- the option value. Options specified here are added to the current settings.
- Repeated `HOST`, `PORT`, `SOCKET` and `PRIORITY` options build a list of
- hosts to be used by the fail-over logic. For other options, if they are set
- again, the new value overrides the previous setting.
- @note
- When using `HOST`, `PORT` and `PRIORITY` options to specify a single
- host, all have to be specified in the same `set()` call.
- */
- template<typename... R>
- void set(SessionOption opt, R&&... rest)
- {
- try {
- // set<true> means that only SessionOption can be used
- Settings_detail::set<true>(opt, std::forward<R>(rest)...);
- }
- CATCH_AND_WRAP
- }
- /**
- Clear all settings specified so far.
- */
- void clear()
- {
- try {
- Settings_detail::clear();
- }
- CATCH_AND_WRAP
- }
- /**
- Remove all settings for the given option @p opt.
- @note For option such as `HOST`, which can repeat several times in
- the settings, all occurrences are erased.
- */
- void erase(SessionOption opt)
- {
- try {
- Settings_detail::erase(opt);
- }
- CATCH_AND_WRAP
- }
- /**
- Check if option @p opt was defined.
- */
- bool has_option(SessionOption opt)
- {
- try {
- return Settings_detail::has_option(opt);
- }
- CATCH_AND_WRAP
- }
- private:
- friend Client;
- friend Session;
- };
- /**
- ClientSettings are used to construct Client objects.
- It can be constructed using a connection string plus a JSON with client
- options, or by setting each ClientOption and SessionOption with its
- correspondant value.
- @ingroup devapi
- */
- class ClientSettings
- : private internal::Settings_detail<internal::Settings_traits>
- {
- public:
- using Value = mysqlx::Value;
- /**
- Create client settings from a connection string.
- @see SessionSettings
- */
- ClientSettings(const string &uri)
- {
- try {
- Settings_detail::set_from_uri(uri);
- }
- CATCH_AND_WRAP
- }
- /**
- Create client settings from a connection string and a ClientSettings object
- @see SessionSettings
- */
- ClientSettings(const string &uri, ClientSettings &opts)
- {
- try {
- Settings_detail::set_from_uri(uri);
- Settings_detail::set_client_opts(opts);
- }
- CATCH_AND_WRAP
- }
- /**
- Create client settings from a connection string and. Client options are
- expressed in JSON format. Here is an example:
- ~~~~~~
- { "pooling": {
- "enabled": true,
- "maxSize": 25,
- "queueTimeout": 1000,
- "maxIdleTime": 5000}
- }
- ~~~~~~
- All options are defined under a document with key vale "pooling". Inside the
- document, the available options are these:
- - `enabled` : boolean value that enable or disable connection pooling. If
- disabled, session created from pool are the same as created
- directly without client handle.
- Enabled by default.
- - `mazSize` : integer that defines the max pooling sessions possible. If
- uses tries to get session from pool when maximum sessions are
- used, it will wait for an available session untill
- `queueTimeout`.
- Defaults to 25.
- - `queueTimeout` : integer value that defines the time, in milliseconds,
- that client will wait to get an available session.
- By default it doesn't timeouts.
- - `maxIdleTime` : integer value that defines the time, in milliseconds, that
- an available session will wait in the pool before it is
- removed.
- By default it doesn't cleans sessions.
- */
- ClientSettings(const string &uri, const DbDoc &options)
- {
- try {
- Settings_detail::set_from_uri(uri);
- std::stringstream str_opts;
- str_opts << options;
- Settings_detail::set_client_opts(str_opts.str());
- }
- CATCH_AND_WRAP
- }
- /**
- Create client settings from a connection string and. Client options are
- expressed in JSON format. Here is an example:
- ~~~~~~
- { "pooling": {
- "enabled": true,
- "maxSize": 25,
- "queueTimeout": 1000,
- "maxIdleTime": 5000}
- }
- ~~~~~~
- All options are defined under a document with key vale "pooling". Inside the
- document, the available options are these:
- - `enabled` : boolean value that enable or disable connection pooling. If
- disabled, session created from pool are the same as created
- directly without client handle.
- Enabled by default.
- - `mazSize` : integer that defines the max pooling sessions possible. If
- uses tries to get session from pool when maximum sessions are
- used, it will wait for an available session untill
- `queueTimeout`.
- Defaults to 25.
- - `queueTimeout` : integer value that defines the time, in milliseconds,
- that client will wait to get an available session.
- By default it doesn't timeouts.
- - `maxIdleTime` : integer value that defines the time, in milliseconds, that
- an available session will wait in the pool before it is
- removed.
- By default it doesn't cleans sessions.
- */
- ClientSettings(const string &uri, const char *options)
- {
- try {
- Settings_detail::set_from_uri(uri);
- Settings_detail::set_client_opts(options);
- }
- CATCH_AND_WRAP
- }
- /**
- Create client settings from a connection string and client settings as a
- list of client options.
- The list of options consist of a ClientOption constant,
- identifying the option to set, followed by the value of the option.
- Example:
- ~~~~~~
- ClientSettings from_option_list( "mysqlx://root@localhost",
- ClientOption::POOLING, true,
- ClientOption::POOL_MAX_SIZE, max_connections,
- ClientOption::POOL_QUEUE_TIMEOUT, std::chrono::seconds(100),
- ClientOption::POOL_MAX_IDLE_TIME, std::chrono::microseconds(1)
- );
- ~~~~~~
- ClientOption::POOL_QUEUE_TIMEOUT and ClientOption::POOL_MAX_IDLE_TIME can
- be specified using std::chrono::duration objects, or by integer values, with
- the latest to be specified in milliseconds.
- @see SessionSettings
- */
- template<typename...R>
- ClientSettings(const string &uri, mysqlx::ClientOption opt, R... rest)
- try
- : ClientSettings(uri)
- {
- // set<false> means that both SessionOption and ClientOption can be used
- Settings_detail::set<false>(opt, std::forward<R>(rest)...);
- }
- CATCH_AND_WRAP
- template <typename... R>
- ClientSettings(mysqlx::SessionOption opt, R&&...rest)
- {
- try {
- // set<false> means that both SessionOption and ClientOption can be used
- Settings_detail::set<false>(opt, std::forward<R>(rest)...);
- }
- CATCH_AND_WRAP
- }
- template <typename... R>
- ClientSettings(mysqlx::ClientOption opt, R&&...rest)
- {
- try {
- // set<false> means that both SessionOption and ClientOption can be used
- Settings_detail::set<false>(opt, std::forward<R>(rest)...);
- }
- CATCH_AND_WRAP
- }
- /**
- Find the specified option @p opt and returns its Value.
- Returns NULL Value if not found.
- */
- Value find(mysqlx::ClientOption opt)
- {
- try {
- return Settings_detail::get(opt);
- }
- CATCH_AND_WRAP
- }
- /**
- Find the specified option @p opt and returns its Value.
- Returns NULL Value if not found.
- @note For option such as `HOST`, which can repeat several times in
- the settings, only the last value is reported.
- */
- Value find(mysqlx::SessionOption opt)
- {
- try {
- return Settings_detail::get(opt);
- }
- CATCH_AND_WRAP
- }
- /**
- Set client and session options.
- Accepts a list of one or more `ClientOption` or `SessionOption` constants,
- each followed by the option value. Options specified here are added to the
- current settings.
- Repeated `HOST`, `PORT`, `SOCKET` and `PRIORITY` options build a list of
- hosts to be used by the fail-over logic. For other options, if they are set
- again, the new value overrides the previous setting.
- @note
- When using `HOST`, `PORT` and `PRIORITY` options to specify a single
- host, all have to be specified in the same `set()` call.
- */
- template<typename OPT,typename... R>
- void set(OPT opt, R&&... rest)
- {
- try {
- // set<false> means that both SessionOption and ClientOption can be used
- Settings_detail::set<false>(opt, std::forward<R>(rest)...);
- }
- CATCH_AND_WRAP
- }
- /**
- Clear all settings specified so far.
- */
- void clear()
- {
- try {
- Settings_detail::clear();
- }
- CATCH_AND_WRAP
- }
- /**
- Remove the given option @p opt.
- */
- void erase(mysqlx::ClientOption opt)
- {
- try {
- Settings_detail::erase(opt);
- }
- CATCH_AND_WRAP
- }
- /**
- Remove all settings for the given option @p opt.
- @note For option such as `HOST`, which can repeat several times in
- the settings, all occurrences are erased.
- */
- void erase(mysqlx::SessionOption opt)
- {
- try {
- Settings_detail::erase(opt);
- }
- CATCH_AND_WRAP
- }
- /**
- Check if option @p opt was defined.
- */
- bool has_option(mysqlx::ClientOption opt)
- {
- try {
- return Settings_detail::has_option(opt);
- }
- CATCH_AND_WRAP
- }
- /**
- Check if option @p opt was defined.
- */
- bool has_option(SessionOption opt)
- {
- try {
- return Settings_detail::has_option(opt);
- }
- CATCH_AND_WRAP
- }
- private:
- friend Client;
- friend Session;
- };
- } // mysqlx
- #endif
|