MySQL Connector/C++ 9.3.0
MySQL connector library for C and C++ applications
All Classes Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
value.h
1/*
2 * Copyright (c) 2015, 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_COMMON_VALUE_H
32#define MYSQLX_COMMON_VALUE_H
33
34
35#include "api.h"
36#include "error.h"
37#include "util.h"
38
39PUSH_SYS_WARNINGS
40#include <string>
41POP_SYS_WARNINGS
42
43
44namespace mysqlx {
45MYSQLX_ABI_BEGIN(2,0)
46
47namespace common {
48
49class Value_conv;
50
51/*
52 Class representing a polymorphic value of one of the supported types.
53
54 TODO: Extend it with array and document types (currently these are implemented
55 in derived mysqlx::Value class of DevAPI).
56
57 TODO: When storing raw bytes, currently they are copied inside the Value
58 object. Consider if this can be avoided.
59*/
60
61class PUBLIC_API Value
62 : public virtual Printable
63{
64public:
65
66 enum Type
67 {
68 VNULL,
69 UINT64,
70 INT64,
71 FLOAT,
72 DOUBLE,
73 BOOL,
74 STRING,
75 USTRING,
76 RAW,
77 EXPR,
78 JSON,
79 };
80
81 using string = std::string;
82
83protected:
84
85 Type m_type;
86
87 // TODO: Use std::variant to save space
88
89 DLL_WARNINGS_PUSH
90
91 std::string m_str;
92 std::u16string m_ustr;
93
94 DLL_WARNINGS_POP
95
96 union {
97 double v_double = 0.0;
98 float v_float;
99 int64_t v_sint;
100 uint64_t v_uint;
101 bool v_bool;
102 } m_val;
103
104 void print(std::ostream&) const override;
105
106 template <typename T>
107 Value(Type type, T &&init)
108 : Value(std::forward<T>(init))
109 {
110 m_type = type;
111 }
112
113public:
114
115 // Construct a NULL item
116 Value() : m_type(VNULL)
117 {}
118
119
120 // Construct an item from a string
121 Value(const std::string& str) : m_type(STRING), m_str(str)
122 {
123 m_val.v_bool = false;
124 }
125
126 Value(const std::u16string &str)
127 : m_type(USTRING), m_ustr(str)
128 {
129 m_val.v_bool = false;
130 }
131
132
133 // Construct an item from a signed 64-bit integer
134 Value(int64_t v) : m_type(INT64)
135 { m_val.v_sint = v; }
136
137 // Construct an item from an unsigned 64-bit integer
138 Value(uint64_t v) : m_type(UINT64)
139 { m_val.v_uint = v; }
140
141 // Construct an item from a float
142 Value(float v) : m_type(FLOAT)
143 { m_val.v_float = v; }
144
145 // Construct an item from a double
146 Value(double v) : m_type(DOUBLE)
147 { m_val.v_double = v; }
148
149
150 // Construct an item from a bool
151 Value(bool v) : m_type(BOOL)
152 { m_val.v_bool = v; }
153
154 // Construct an item from bytes
155 Value(const byte *ptr, size_t len) : m_type(RAW)
156 {
157 // Note: bytes are copied to m_str member.
158 m_str.assign((const char*)ptr, len);
159 }
160
161 // Other numeric conversions
162
163 template <
164 typename T,
165 typename std::enable_if<std::is_unsigned<T>::value>::type* = nullptr
166 >
167 Value(T val)
168 : Value(uint64_t(val))
169 {}
170
171 template <
172 typename T,
173 typename std::enable_if<!std::is_unsigned<T>::value>::type* = nullptr,
174 typename std::enable_if<std::is_integral<T>::value>::type* = nullptr
175 >
176 Value(T val)
177 : Value(int64_t(val))
178 {}
179
180
181 bool is_null() const
182 {
183 return VNULL == m_type;
184 }
185
186 bool get_bool() const
187 {
188 switch (m_type)
189 {
190 case BOOL: return m_val.v_bool;
191 case UINT64: return 0 != m_val.v_uint;
192 case INT64: return 0 != m_val.v_sint;
193 default:
194 throw Error("Can not convert to Boolean value");
195 }
196 }
197
198 uint64_t get_uint() const
199 {
200 if (UINT64 != m_type && INT64 != m_type && BOOL != m_type)
201 throw Error("Can not convert to integer value");
202
203 if (BOOL == m_type)
204 return m_val.v_bool ? 1 : 0;
205
206 if (INT64 == m_type && 0 > m_val.v_sint)
207 throw Error("Converting negative integer to unsigned value");
208
209 uint64_t val = (UINT64 == m_type ? m_val.v_uint : (uint64_t)m_val.v_sint);
210
211 return val;
212 }
213
214 int64_t get_sint() const
215 {
216 if (INT64 == m_type)
217 return m_val.v_sint;
218
219 uint64_t val = get_uint();
220
221 if (!check_num_limits<int64_t>(val))
222 throw Error("Value cannot be converted to signed integer number");
223
224 return val;
225 }
226
227 float get_float() const
228 {
229 switch (m_type)
230 {
231 case INT64: return 1.0F*m_val.v_sint;
232 case UINT64: return 1.0F*m_val.v_uint;
233 case FLOAT: return m_val.v_float;
234 default:
235 throw Error("Value cannot be converted to float number");
236 }
237 }
238
239 double get_double() const
240 {
241 switch (m_type)
242 {
243 case INT64: return 1.0*m_val.v_sint;
244 case UINT64: return 1.0*m_val.v_uint;
245 case FLOAT: return m_val.v_float;
246 case DOUBLE: return m_val.v_double;
247 default:
248 throw Error("Value can not be converted to double number");
249 }
250 }
251
252 /*
253 Note: In general this method returns raw value representation as obtained
254 from the server, which is stored in m_str member. If a non-string value was
255 not obtained from the server, there is no raw representation for it and
256 error is thrown. String values always have raw representation which is
257 either utf8 or utf16 encoding. Strings obtained from the server use utf8 as
258 raw representation. For strings created by user code this might be either
259 utf8 or utf16, depending on how string was created.
260 */
261
262 const byte* get_bytes(size_t *size) const
263 {
264 switch (m_type)
265 {
266 case USTRING:
267 if (!m_ustr.empty())
268 {
269 if (size)
270 *size = m_ustr.size() * sizeof(char16_t);
271 return (const byte*)m_ustr.data();
272 }
273 FALLTHROUGH;
274
275 default:
276 if (m_str.empty())
277 throw Error("Value cannot be converted to raw bytes");
278 FALLTHROUGH;
279
280 case RAW:
281 case STRING:
282 if (size)
283 *size = m_str.length();
284 return (const byte*)m_str.data();
285
286 }
287 }
288
289 // Note: these methods perform utf8 conversions as necessary.
290
291 const std::string& get_string() const;
292 const std::u16string& get_ustring() const;
293
294 Type get_type() const
295 {
296 return m_type;
297 }
298
299private:
300
301 /*
302 Note: Avoid implicit conversion from pointer types to bool.
303 Without this declaration, Value(bool) constructor is invoked
304 for pointer types. Here we declare and hide an explicit constructor
305 for pointer types which prevents compiler to pick Value(bool).
306 */
307
308 template <typename T>
309 Value(const T*);
310
311public:
312
313 friend Value_conv;
314
315 struct Access;
316 friend Access;
317};
318
319} // common
320MYSQLX_ABI_END(2,0)
321} // mysqlx
322
323#endif
Classes used to access query and command execution results.
Type
Types that can be reported in result meta-data.
Definition: result.h:241