MySQL Connector/C++
MySQL connector library for C and C++ applications
result.h
Go to the documentation of this file.
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_DETAIL_RESULT_H
32#define MYSQLX_DETAIL_RESULT_H
33
40#include "../common.h"
41#include "../error.h"
42#include "../document.h"
43#include "../row.h"
44#include "../collations.h"
45
46#include <deque>
47
48
49namespace mysqlx {
50MYSQLX_ABI_BEGIN(2,0)
51
52class RowResult;
53class Column;
54class Columns;
55class Session;
56
57namespace common {
58
59class Result_init;
60class Column_info;
61class Result_impl;
62
63} // common
64
65
66namespace internal {
67
68
69struct Session_detail;
70
71
72class PUBLIC_API Result_detail
73{
74 // Disable copy semantics for result classes.
75
76 Result_detail(const Result_detail&) = delete;
77 Result_detail& operator=(const Result_detail&) = delete;
78
79public:
80
81 using Impl = common::Result_impl;
82
83protected:
84
85 Result_detail(common::Result_init&);
86
87 // Note: move semantics is implemented by move assignment operator.
88
89 Result_detail(Result_detail &&other)
90 {
91 operator=(std::move(other));
92 }
93
94 Result_detail& operator=(Result_detail&&);
95
96 Result_detail() = default;
97 virtual ~Result_detail();
98
99 Impl& get_impl();
100
101 const Impl& get_impl() const
102 {
103 return const_cast<Result_detail*>(this)->get_impl();
104 }
105
106 void check_result() const;
107
108 uint64_t get_affected_rows() const;
109 uint64_t get_auto_increment() const;
110
111 using DocIdList = internal::List_initializer<const std::vector<std::string>&>;
112
113 DocIdList get_generated_ids() const;
114
115 // Handling multi-results
116
117 bool has_data() const;
118
119 // Note: needs to be called before accessing the first result set.
120 bool next_result();
121
122protected:
123
124 Impl *m_impl = nullptr;
125 bool m_owns_impl = false;
126
127 /*
128 Source for WarningList initializer.
129 */
130
131 struct Warning_src
132 {
133 using Value = Warning;
134
135 Result_detail &m_res;
136
137 Warning_src(Result_detail &res)
138 : m_res(res)
139 {}
140
141 size_t size() const
142 {
143 return m_res.get_warning_count();
144 }
145
146 Warning operator[](size_t pos)
147 {
148 return m_res.get_warning(pos);
149 }
150 };
151
152public:
153
154 using WarningList = internal::List_initializer<Array_source<Warning_src>>;
155
156protected:
157
158 unsigned get_warning_count() const;
159 Warning get_warning(size_t pos);
160
161 WarningList get_warnings()
162 {
163 get_warning_count();
164 return { *this };
165 }
166
167public:
168
169 friend Session_detail;
170 friend List_initializer<Result_detail>;
171};
172
173
174/*
175 This class keeps a reference to column information stored in a
176 common::Column_info<> instance. The meta-data is exposed in format expected
177 by X DevAPI meta-data access methods. In particualr the CDK type and encoding
178 format information is translated to X DevAPI type information. For example,
179 a CDK column of type FLOAT can be reported as DevAPI type FLOAT, DOUBLE
180 or DECIMAL, depending on the encoding format that was reported by CDK. This
181 translation happens in Column::getType() method.
182
183 Additional encoding information is exposed via other methods such as
184 is_signed().
185*/
186
187class PUBLIC_API Column_detail
188 : virtual common::Printable
189{
190protected:
191
192 using Impl = common::Column_info;
193
194 const Impl *m_impl = nullptr;
195
196 Column_detail(const Impl *impl)
197 : m_impl(impl)
198 {}
199
200 const Impl& get_impl() const
201 {
202 assert(m_impl);
203 return *m_impl;
204 }
205
206 string get_name() const;
207 string get_label() const;
208 string get_schema_name() const;
209 string get_table_name() const;
210 string get_table_label() const;
211
212 // Note: should return values of mysqlx::Type enum constants
213
214 unsigned get_type() const;
215
216 CharacterSet get_charset() const;
217 const CollationInfo& get_collation() const;
218
219 unsigned long get_length() const;
220 unsigned short get_decimals() const;
221
222 bool is_signed() const;
223 bool is_padded() const;
224
225 void print(std::ostream&) const override;
226
227protected:
228
229 Column_detail() = default;
230 Column_detail(const Column_detail&) = default;
231 Column_detail(Column_detail&&) = default;
232
233 Column_detail& operator=(const Column_detail&) = default;
234
235public:
236
237 friend Impl;
238 friend Result_detail;
239 friend RowResult;
240
241 struct INTERNAL Access;
242 friend Access;
243};
244
245
246/*
247 A wrapper around column meta-data class COL that adds copy semantics
248 and default ctor. This is required by Columns_detail class which uses
249 an STL container to store data for several columns.
250*/
251
252template <class COL>
253struct Column_storage
254 : public COL
255{
256 Column_storage(const typename COL::Impl *impl)
257 : COL(impl)
258 {}
259
260 // Note: these members are needed to use it with std::deque<>
261
262 Column_storage() = default;
263 Column_storage(const Column_storage&) = default;
264 Column_storage& operator=(const Column_storage&) = default;
265};
266
267
268template <class COLS> class Row_result_detail;
269
270
271/*
272 Class holding meta-data information for all columns in a result.
273
274 Template parameter COL is a class used to store information about a single
275 column. It is made into template parameter because full definition of
276 the actuall mysqlx::Column class is not available in this header.
277
278 Note: Because this class is implemented using std::deque<>, we wrap COL
279 class with the Column_storage<> wrapper to provide copy semantics and default
280 ctor required by this STL container.
281*/
282
283template <class COL>
284class Columns_detail
285 : public std::deque<Column_storage<COL>>
286{
287 Columns_detail(const Columns_detail&) = delete;
288
289protected:
290
291 Columns_detail() = default;
292 Columns_detail(Columns_detail&&) = default;
293 Columns_detail& operator=(Columns_detail&&) = default;
294
295 void init(const internal::Result_detail::Impl&);
296
298 friend internal::Row_result_detail<Columns>;
300};
301
302
303/*
304 COLS is a class used to store information about result columns. It is made
305 into template parameter because the actual mysqlx::Columns class, with
306 the public API for accessing column information, is defined in the top-level
307 header devapi/result.h.
308
309 The COLS class should have move semantics to enable move-semantics for result
310 objects.
311*/
312
313template <class COLS>
314class Row_result_detail
315 : public Result_detail
316{
317public:
318
319 using iterator = Iterator<Row_result_detail, Row>;
320 using RowList = List_initializer<Row_result_detail&>;
321 using Columns = COLS;
322
323 iterator begin()
324 {
325 return iterator(*this);
326 }
327
328 iterator end() const
329 {
330 return iterator();
331 }
332
333private:
334
335 // Row iterator implementation
336
337 Row m_row;
338
339 using Value = Row;
340
341 void iterator_start() {}
342
343 bool iterator_next();
344
345 Value iterator_get()
346 {
347 return m_row;
348 }
349
350
351protected:
352
353 Row_result_detail() = default;
354 Row_result_detail(common::Result_init&);
355
356 Row_result_detail(Row_result_detail&&) = default;
357 Row_result_detail& operator=(Row_result_detail&&) = default;
358
359 RowList get_rows()
360 {
361 /*
362 Construct RowList instance passing reference to this Row_result_detail
363 object which acts as a source for the list initializer.
364 */
365 return *this;
366 }
367
368 row_count_t row_count();
369
370 Row get_row()
371 {
372 if (!iterator_next())
373 return Row();
374 return iterator_get();
375 }
376
377private:
378
379 // Storage for result column information.
380
381 Columns m_cols;
382
383protected:
384
385 col_count_t col_count() const;
386 const Column& get_column(col_count_t) const;
387 const Columns& get_columns() const;
388
389 bool next_result()
390 {
391 bool rc = Result_detail::next_result();
392 if (rc)
393 m_cols.init(get_impl());
394 return rc;
395 }
396
397 friend iterator;
398 friend RowResult;
399 friend Columns;
400};
401
402
403// Document based results
404// ----------------------
405
406class PUBLIC_API Doc_result_detail
407 : public Result_detail
408{
409public:
410
411 using iterator = Iterator<Doc_result_detail, DbDoc>;
412 using DocList = List_initializer<Doc_result_detail&>;
413
414 iterator begin()
415 {
416 return iterator(*this);
417 }
418
419 iterator end() const
420 {
421 return iterator();
422 }
423
424private:
425
426 // iterator implementation
427
428 DbDoc m_cur_doc;
429
430 void iterator_start() {}
431
432 bool iterator_next();
433
434 DbDoc iterator_get()
435 {
436 return m_cur_doc;
437 }
438
439protected:
440
441 Doc_result_detail() = default;
442
443 Doc_result_detail(common::Result_init &init)
444 : Result_detail(init)
445 {}
446
447 DbDoc get_doc()
448 {
449 if (!iterator_next())
450 return DbDoc();
451 return iterator_get();
452 }
453
454 uint64_t count();
455
456 DocList get_docs()
457 {
458 return *this;
459 }
460
461 friend Impl;
462 friend iterator;
463};
464
465
466} // internal namespace
467MYSQLX_ABI_END(2,0)
468} // mysqlx
469
470#endif