123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- /*
- * Copyright (c) 2017, 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_COMMON_SETTINGS_H
- #define MYSQLX_COMMON_SETTINGS_H
- /*
- Classes and code handling session settings. They are used to process session
- creation options, check their consistency and present the settings in the
- form expected by CDK.
- Known session options and their values are defined
- in mysql_common_constants.h header as SESSION_OPTION_LIST() and accompanying
- macros.
- */
- #include "../common_constants.h"
- #include "value.h"
- #include <vector>
- #include <map>
- #include <bitset>
- #include <sstream>
- namespace cdk {
- namespace ds {
- class Multi_source;
- }}
- namespace mysqlx {
- namespace common {
- /*
- Class for storing session configuration settings.
- */
- class PUBLIC_API Settings_impl
- {
- public:
- /*
- Enumerations with available session options and their values.
- */
- #define SETTINGS_OPT_ENUM_str(X,N) X = N,
- #define SETTINGS_OPT_ENUM_num(X,N) X = N,
- #define SETTINGS_OPT_ENUM_any(X,N) X = N,
- enum class Option_impl {
- SESSION_OPTION_LIST(SETTINGS_OPT_ENUM)
- LAST
- };
- /*
- Enumerations with available client options and their values.
- */
- #define CLIENT_OPT_ENUM_str(X,N) X = N,
- #define CLIENT_OPT_ENUM_bool(X,N) X = N,
- #define CLIENT_OPT_ENUM_num(X,N) X = N,
- #define CLIENT_OPT_ENUM_any(X,N) X = N,
- #define CLIENT_OPT_ENUM_end(X,N) X = N,
- enum class Client_option_impl {
- CLIENT_OPTION_LIST(CLIENT_OPT_ENUM)
- };
- static const char* option_name(Option_impl opt);
- static const char* option_name(Client_option_impl opt);
- #define SETTINGS_VAL_ENUM(X,N) X = N,
- enum class SSL_mode {
- SSL_MODE_LIST(SETTINGS_VAL_ENUM)
- LAST
- };
- static const char* ssl_mode_name(SSL_mode mode);
- enum class Auth_method {
- AUTH_METHOD_LIST(SETTINGS_VAL_ENUM)
- LAST
- };
- static const char* auth_method_name(Auth_method method);
- protected:
- using Value = common::Value;
- using opt_val_t = std::pair<Option_impl, Value>;
- // TODO: use multimap instead?
- using option_list_t = std::vector<opt_val_t>;
- using iterator = option_list_t::const_iterator;
- using client_option_list_t = std::map<Client_option_impl, Value>;
- using client_iterator = option_list_t::const_iterator;
- public:
- /*
- Examine settings stored in this object.
- */
- bool has_option(Option_impl) const;
- const Value& get(Option_impl) const;
- bool has_option(Client_option_impl) const;
- const Value& get(Client_option_impl) const;
- // Iterating over options stored in this object.
- iterator begin() const
- {
- return m_data.m_options.cbegin();
- }
- iterator end() const
- {
- return m_data.m_options.cend();
- }
- /*
- Clear individual or all settings.
- */
- void clear();
- void erase(Option_impl);
- void erase(Client_option_impl);
- /*
- Session options include connection options that specify data source
- (one or many) for which given session is created. This method initializes
- CDK Multi_source object to describe the data source(s) based on the
- connection options.
- */
- void get_data_source(cdk::ds::Multi_source&);
- // Set options based on URI
- void set_from_uri(const std::string &);
- // Set Client options based on JSON object
- void set_client_opts(const std::string &);
- // Set Client options from othe Settings object
- void set_client_opts(const Settings_impl &);
- /*
- Public API has no methods to directly set individual options. Instead,
- to change session settings implementation should create a Setter object
- and use its methods to do the changes. A Settings_impl::Setter object
- provides "transactional" semantics for changing session options -- only
- consistent option changes modify the original Settings_impl object.
- Note: This Setter class is defined in "implementation" header
- common/settings.h. The public API leaves it undefined.
- */
- class Setter;
- protected:
- struct PUBLIC_API Data
- {
- DLL_WARNINGS_PUSH
- option_list_t m_options;
- client_option_list_t m_client_options;
- DLL_WARNINGS_POP
- unsigned m_host_cnt = 0;
- bool m_user_priorities = false;
- bool m_ssl_ca = false;
- SSL_mode m_ssl_mode = SSL_mode::LAST;
- bool m_tcpip = false; // set to true if TCPIP connection was specified
- bool m_sock = false; // set to true if socket connection was specified
- void erase(Option_impl);
- void erase(Client_option_impl);
- };
- Data m_data;
- };
- #define SETTINGS_OPT_NAME_str(X,N) case N: return #X;
- #define SETTINGS_OPT_NAME_num(X,N) case N: return #X;
- #define SETTINGS_OPT_NAME_any(X,N) case N: return #X;
- inline
- const char* Settings_impl::option_name(Option_impl opt)
- {
- switch (unsigned(opt))
- {
- SESSION_OPTION_LIST(SETTINGS_OPT_NAME)
- default:
- return nullptr;
- }
- }
- #define CLIENT_OPT_NAME_str(X,N) case N: return #X;
- #define CLIENT_OPT_NAME_bool(X,N) case N: return #X;
- #define CLIENT_OPT_NAME_num(X,N) case N: return #X;
- #define CLIENT_OPT_NAME_any(X,N) case N: return #X;
- #define CLIENT_OPT_NAME_end(X,N) case N: throw_error("Unexpected Option"); return #X;
- inline
- const char* Settings_impl::option_name(Client_option_impl opt)
- {
- switch (unsigned(opt))
- {
- CLIENT_OPTION_LIST(CLIENT_OPT_NAME)
- default:
- return nullptr;
- }
- }
- #define SETTINGS_VAL_NAME(X,N) case N: return #X;
- inline
- const char* Settings_impl::ssl_mode_name(SSL_mode mode)
- {
- switch (unsigned(mode))
- {
- SSL_MODE_LIST(SETTINGS_VAL_NAME)
- default:
- return nullptr;
- }
- }
- inline
- const char* Settings_impl::auth_method_name(Auth_method method)
- {
- switch (unsigned(method))
- {
- SSL_MODE_LIST(SETTINGS_VAL_NAME)
- default:
- return nullptr;
- }
- }
- /*
- Note: For options that can repeat, returns the last value.
- */
- inline
- const common::Value& Settings_impl::get(Option_impl opt) const
- {
- using std::find_if;
- auto it = find_if(m_data.m_options.crbegin(), m_data.m_options.crend(),
- [opt](opt_val_t el) -> bool { return el.first == opt; }
- );
- static Value null_value;
- if (it == m_data.m_options.crend())
- return null_value;
- return it->second;
- }
- inline
- const common::Value& Settings_impl::get(Client_option_impl opt) const
- {
- static Value null_value;
- auto it = m_data.m_client_options.find(opt);
- if (it == m_data.m_client_options.cend())
- return null_value;
- return it->second;
- }
- inline
- bool Settings_impl::has_option(Option_impl opt) const
- {
- return m_data.m_options.cend() !=
- find_if(m_data.m_options.cbegin(), m_data.m_options.cend(),
- [opt](opt_val_t el) -> bool { return el.first == opt; }
- );
- }
- inline
- bool Settings_impl::has_option(Client_option_impl opt) const
- {
- return m_data.m_client_options.find(opt) != m_data.m_client_options.cend();
- }
- inline
- void Settings_impl::erase(Option_impl opt)
- {
- m_data.erase(opt);
- }
- inline
- void Settings_impl::erase(Client_option_impl opt)
- {
- m_data.erase(opt);
- }
- /*
- Note: Removes all occurrences of the given option. Also updates the context
- used for checking option consistency.
- */
- inline
- void Settings_impl::Data::erase(Option_impl opt)
- {
- remove_from(m_options,
- [opt](opt_val_t el) -> bool
- {
- return el.first == opt;
- }
- );
- /*
- TODO: removing HOST from multi-host settings can leave "orphaned"
- PORT/PRIORITY settings. Do we correctly detect that?
- */
- switch (opt)
- {
- case Option_impl::HOST:
- m_host_cnt = 0;
- FALLTHROUGH;
- case Option_impl::PORT:
- if (0 == m_host_cnt)
- m_tcpip = false;
- break;
- case Option_impl::SOCKET:
- m_sock = false;
- break;
- case Option_impl::PRIORITY:
- m_user_priorities = false;
- break;
- case Option_impl::SSL_CA:
- m_ssl_ca = false;
- break;
- case Option_impl::SSL_MODE:
- m_ssl_mode = SSL_mode::LAST;
- break;
- default:
- break;
- }
- }
- inline
- void Settings_impl::Data::erase(Client_option_impl opt)
- {
- m_client_options.erase(opt);
- }
- } // common namespace
- } // mysqlx namespace
- #endif
|