MySQL Connector/C++ 9.3.0
MySQL connector library for C and C++ applications
All Classes Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
settings.h
1/*
2 * Copyright (c) 2017, 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, as
6 * 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, as
10 * 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 * Without limiting anything contained in the foregoing, this file,
17 * which is part of Connector/C++, is also subject to the
18 * Universal FOSS Exception, version 1.0, a copy of which can be found at
19 * https://oss.oracle.com/licenses/universal-foss-exception.
20 *
21 * This program is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24 * See the GNU General Public License, version 2.0, for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#ifndef MYSQLX_DETAIL_SETTINGS_H
32#define MYSQLX_DETAIL_SETTINGS_H
33
34#include "../common.h"
35#include "../document.h"
36#include <chrono>
37
38#include <list>
39#include <chrono>
40
41namespace mysqlx {
42MYSQLX_ABI_BEGIN(2,0)
43
44namespace internal {
45
46/*
47 Note: Options and SSLMode enumerations are given by Traits template parameter
48 to allow defining (and documenting) them in the main settings.h header.
49*/
50
51
52template <typename Traits>
53class Settings_detail
54 : public common::Settings_impl
55{
56 using Value = mysqlx::Value;
57 using Option = typename Traits::Options;
58 using COption = typename Traits::COptions;
59 using SSLMode = typename Traits::SSLMode;
60 using AuthMethod = typename Traits::AuthMethod;
61 using CompressionMode = typename Traits::CompressionMode;
62
63public:
64
65 template <bool session_only, typename OPT, typename... Ty>
66 void set(OPT opt, Ty&&... rest)
67 {
68 do_set(get_options<session_only>(opt, std::forward<Ty>(rest)...));
69 }
70
71protected:
72
73 /*
74 Declare options that require specific type of value (mostly enumerations).
75 For such options we do not accept setting them to arbitrary values. Instead
76 an overload of opt_val() with appropriate type will be used to set value
77 of the option.
78 */
79
80#define OPT_VAL_TYPE(X) \
81 X(SSL_MODE,SSLMode) \
82 X(AUTH,AuthMethod)
83
84#define CHECK_OPT(Opt,Type) \
85 if (opt == Session_option_impl::Opt) \
86 throw Error(#Opt "setting requires value of type " #Type);
87
88 /*
89 Store option value in Value object (with basic run-time type checks)
90 TODO: More precise type checking using per-option types.
91 */
92
93 static Value opt_val(int opt, Value &&val)
94 {
95 OPT_VAL_TYPE(CHECK_OPT)
96 return std::move(val);
97 }
98
99 /*
100 For types which are not convertible to Value, but can be converted to string
101 go through string conversion.
102 */
103
104 static Value opt_val(int opt, std::nullptr_t)
105 {
106 return opt_val(opt, Value());
107 }
108
109 template <
110 typename V,
111 typename std::enable_if<std::is_convertible<V, string>::value>::type*
112 = nullptr
113 >
114 static Value opt_val(int opt, V &&val)
115 {
116 return opt_val(opt, Value(string(val)));
117 }
118
119 static Value opt_val(int opt, SSLMode m)
120 {
121 if (opt != Session_option_impl::SSL_MODE)
122 throw Error(
123 "SessionSettings::SSLMode value can only be used on SSL_MODE setting."
124 );
125 return unsigned(m);
126 }
127
128 static Value opt_val(int opt, AuthMethod m)
129 {
130 if (opt != Session_option_impl::AUTH)
131 throw Error(
132 "SessionSettings::AuthMethod value can only be used on AUTH setting."
133 );
134 return unsigned(m);
135 }
136
137 static Value opt_val(int opt, CompressionMode m)
138 {
139 if (opt != Session_option_impl::COMPRESSION)
140 throw Error(
141 "SessionSettings::CompressionMode value can only be used on COMPRESSION setting."
142 );
143 return unsigned(m);
144 }
145
146 // Note: is_range<C> is true for string types, which should not be treated
147 // as arrays of characters, but as single Values.
148
149 template <
150 typename C,
151 typename std::enable_if<is_range<C>::value>::type* = nullptr,
152 typename std::enable_if<!std::is_convertible<C,Value>::value>::type*
153 = nullptr
154 >
155 static Value opt_val(int , const C &container)
156 {
157 return Value(std::begin(container), std::end(container));
158 }
159
160 template<typename _Rep, typename _Period>
161 static Value opt_val(
162 int opt, const std::chrono::duration<_Rep, _Period> &duration
163 )
164 {
165 if (opt != Session_option_impl::CONNECT_TIMEOUT &&
166 opt != Client_option_impl::POOL_QUEUE_TIMEOUT &&
167 opt != Client_option_impl::POOL_MAX_IDLE_TIME)
168 {
169 std::stringstream err_msg;
170 err_msg << "Option " << option_name(opt) << " does not accept time value";
171 throw_error(err_msg.str().c_str());
172 }
173
174 return Value(std::chrono::duration_cast<std::chrono::milliseconds>(duration)
175 .count());
176 }
177
178 // Handle values that are directly convertible to Value.
179
180 template <
181 typename V,
182 typename std::enable_if<std::is_convertible<V,int>::value>::type*
183 = nullptr,
184 typename std::enable_if<std::is_convertible<V,Value>::value>::type*
185 = nullptr
186 >
187 static Value opt_val(int opt, V &&val)
188 {
189 return opt_val(opt, Value(val));
190 }
191
192 using session_opt_val_t = std::pair<int, Value>;
193 using session_opt_list_t = std::list<session_opt_val_t>;
194
195 /*
196 Set list of options with consistency checks.
197
198 This operation is atomic - settings are changed only if all options could
199 be set without error, otherwise settings remain unchanged.
200 */
201
202 void do_set(session_opt_list_t&&);
203
204 // Note: for ABI compatibility
205 void PUBLIC_API do_set(std::list<std::pair<int, common::Value>>&&);
206
207 /*
208 Templates that collect varargs list of options into opt_list_t list
209 that can be passed to do_set().
210 */
211
212 template<bool session_only>
213 static session_opt_list_t get_options()
214 {
215 return {};
216 }
217
218 /*
219 Note: if we ever support options without values, another overload is
220 needed: get_options(Option opt, Option opt1, R&... rest).
221 */
222
223 template <
224 bool session_only, typename V, typename... Ty,
225 typename std::enable_if<session_only, int>::type* = nullptr
226 >
227 static session_opt_list_t get_options(Option opt, V&& val, Ty&&... rest)
228 {
229 int oo(static_cast<int>(opt));
230 session_opt_list_t opts = get_options<session_only>(std::forward<Ty>(rest)...);
231 opts.emplace_front(oo,
232 Settings_detail::opt_val(oo, std::forward<V>(val))
233 );
234 return opts;
235 }
236
237 template <
238 bool session_only, typename V, typename... Ty,
239 typename std::enable_if<!session_only, int>::type* = nullptr
240 >
241 static session_opt_list_t get_options(COption opt, V&& val, Ty&&... rest)
242 {
243 int oo(static_cast<int>(opt));
244 session_opt_list_t opts = get_options<session_only>(std::forward<Ty>(rest)...);
245 opts.emplace_front(
246 oo,
247 Settings_detail::opt_val(oo, std::forward<V>(val))
248 );
249 return opts;
250 }
251
252 /*
253 Note: Methods below rely on the fact that DevAPI SessionOption constants
254 have the same numeric values as common::Settings_impl::Option ones.
255 */
256
257 bool has_option(COption opt) const
258 {
259 return Settings_impl::has_option(opt);
260 }
261
262 Value get(COption opt)
263 {
264 return Settings_impl::get(opt);
265 }
266
267};
268
269
270} // internal namespace
271
272MYSQLX_ABI_END(2,0)
273} // mysqlx namespace
274
275#endif
276
Value object can store value of scalar type, string, array or document.
Definition: document.h:230
CompressionMode
Values to be used with COMPRESSION option .
Definition: settings.h:294
AuthMethod
Authentication methods to be used with AUTH option.
Definition: settings.h:261
SSLMode
Modes to be used with SSL_MODE option .
Definition: settings.h:227