result.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. /*
  2. * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  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 also distributed with certain software (including
  9. * but not limited to OpenSSL) that is licensed under separate terms,
  10. * as designated in a particular file or component or in included license
  11. * documentation. The authors of MySQL hereby grant you an
  12. * additional permission to link the program and your derivative works
  13. * with the separately licensed software that they have included with
  14. * MySQL.
  15. *
  16. * Without limiting anything contained in the foregoing, this file,
  17. * which is part of MySQL Connector/C++, is also subject to the
  18. * Universal FOSS Exception, version 1.0, a copy of which can be found at
  19. * http://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. #ifndef MYSQLX_DETAIL_RESULT_H
  31. #define MYSQLX_DETAIL_RESULT_H
  32. /**
  33. @file
  34. Details for public API result classes.
  35. */
  36. #include "../common.h"
  37. #include "../error.h"
  38. #include "../document.h"
  39. #include "../row.h"
  40. #include "../collations.h"
  41. #include <deque>
  42. namespace mysqlx {
  43. class RowResult;
  44. class Column;
  45. class Columns;
  46. class Session;
  47. namespace common {
  48. class Result_init;
  49. template <class STR> class Column_info;
  50. } // common
  51. namespace internal {
  52. struct Session_detail;
  53. class PUBLIC_API Result_detail
  54. {
  55. // Disable copy semantics for result classes.
  56. Result_detail(const Result_detail&) = delete;
  57. Result_detail& operator=(const Result_detail&) = delete;
  58. public:
  59. struct INTERNAL Impl;
  60. protected:
  61. Result_detail(common::Result_init&);
  62. // Note: move semantics is implemented by move assignment operator.
  63. Result_detail(Result_detail &&other)
  64. {
  65. operator=(std::move(other));
  66. }
  67. Result_detail& operator=(Result_detail&&);
  68. Result_detail() = default;
  69. virtual ~Result_detail();
  70. Impl& get_impl();
  71. const Impl& get_impl() const
  72. {
  73. return const_cast<Result_detail*>(this)->get_impl();
  74. }
  75. void check_result() const;
  76. uint64_t get_affected_rows() const;
  77. uint64_t get_auto_increment() const;
  78. using DocIdList = internal::List_initializer<const std::vector<std::string>&>;
  79. DocIdList get_generated_ids() const;
  80. // Handling multi-results
  81. bool has_data() const;
  82. bool next_result();
  83. protected:
  84. Impl *m_impl = nullptr;
  85. bool m_owns_impl = false;
  86. /*
  87. Source for WarningList initializer.
  88. */
  89. struct Warning_src
  90. {
  91. using Value = Warning;
  92. Result_detail &m_res;
  93. Warning_src(Result_detail &res)
  94. : m_res(res)
  95. {}
  96. size_t size() const
  97. {
  98. return m_res.get_warning_count();
  99. }
  100. Warning operator[](size_t pos)
  101. {
  102. return m_res.get_warning(pos);
  103. }
  104. };
  105. public:
  106. using WarningList = internal::List_initializer<Array_source<Warning_src>>;
  107. protected:
  108. unsigned get_warning_count() const;
  109. Warning get_warning(size_t pos);
  110. WarningList get_warnings()
  111. {
  112. assert(m_impl);
  113. return { *this };
  114. }
  115. public:
  116. friend Session_detail;
  117. friend List_initializer<Result_detail>;
  118. };
  119. /*
  120. This class keeps a reference to column information stored in a
  121. common::Column_info<> instance. The meta-data is exposed in format expected
  122. by X DevAPI meta-data access methods. In particualr the CDK type and encoding
  123. format information is translated to X DevAPI type information. For example,
  124. a CDK column of type FLOAT can be reported as DevAPI type FLOAT, DOUBLE
  125. or DECIMAL, depending on the encoding format that was reported by CDK. This
  126. translation happens in Column::getType() method.
  127. Additional encoding information is exposed via other methods such as
  128. is_signed().
  129. */
  130. class PUBLIC_API Column_detail
  131. : virtual common::Printable
  132. {
  133. protected:
  134. using Impl = common::Column_info<string>;
  135. const Impl *m_impl = nullptr;
  136. Column_detail(const Impl &impl)
  137. : m_impl(&impl)
  138. {}
  139. const Impl& get_impl() const
  140. {
  141. assert(m_impl);
  142. return *m_impl;
  143. }
  144. string get_name() const;
  145. string get_label() const;
  146. string get_schema_name() const;
  147. string get_table_name() const;
  148. string get_table_label() const;
  149. // Note: should return values of mysqlx::Type enum constants
  150. unsigned get_type() const;
  151. CharacterSet get_charset() const;
  152. const CollationInfo& get_collation() const;
  153. unsigned long get_length() const;
  154. unsigned short get_decimals() const;
  155. bool is_signed() const;
  156. bool is_padded() const;
  157. void print(std::ostream&) const override;
  158. protected:
  159. Column_detail() = default;
  160. Column_detail(const Column_detail&) = default;
  161. Column_detail(Column_detail&&) = default;
  162. Column_detail& operator=(const Column_detail&) = default;
  163. public:
  164. friend Impl;
  165. friend Result_detail;
  166. friend RowResult;
  167. struct INTERNAL Access;
  168. friend Access;
  169. };
  170. /*
  171. A wrapper around column meta-data class COL that adds copy semantics
  172. and default ctor. This is required by Columns_detail class which uses
  173. an STL container to store data for several columns.
  174. */
  175. template <class COL>
  176. struct Column_storage
  177. : public COL
  178. {
  179. Column_storage(const typename COL::Impl &impl)
  180. : COL(impl)
  181. {}
  182. // Note: these members are needed to use it with std::deque<>
  183. Column_storage() = default;
  184. Column_storage(const Column_storage&) = default;
  185. Column_storage& operator=(const Column_storage&) = default;
  186. };
  187. template <class COLS> class Row_result_detail;
  188. /*
  189. Class holding meta-data information for all columns in a result.
  190. Template parameter COL is a class used to store information about a single
  191. column. It is made into template parameter because full definition of
  192. the actuall mysqlx::Column class is not available in this header.
  193. Note: Because this class is implemented using std::deque<>, we wrap COL
  194. class with the Column_storage<> wrapper to provide copy semantics and default
  195. ctor required by this STL container.
  196. */
  197. template <class COL>
  198. class Columns_detail
  199. : public std::deque<Column_storage<COL>>
  200. {
  201. Columns_detail(const Columns_detail&) = delete;
  202. protected:
  203. Columns_detail() = default;
  204. Columns_detail(Columns_detail&&) = default;
  205. Columns_detail& operator=(Columns_detail&&) = default;
  206. void init(const internal::Result_detail::Impl&);
  207. ///@cond IGNORE
  208. friend internal::Row_result_detail<Columns>;
  209. ///@endcond
  210. };
  211. /*
  212. COLS is a class used to store information about result columns. It is made
  213. into template parameter because the actual mysqlx::Columns class, with
  214. the public API for accessing column information, is defined in the top-level
  215. header devapi/result.h.
  216. The COLS class should have move semantics to enable move-semantics for result
  217. objects.
  218. */
  219. template <class COLS>
  220. class Row_result_detail
  221. : public Result_detail
  222. {
  223. public:
  224. using iterator = Iterator<Row_result_detail, Row>;
  225. using RowList = List_initializer<Row_result_detail&>;
  226. using Columns = COLS;
  227. iterator begin()
  228. {
  229. return iterator(*this);
  230. }
  231. iterator end() const
  232. {
  233. return iterator();
  234. }
  235. private:
  236. // Row iterator implementation
  237. Row m_row;
  238. using Value = Row;
  239. void iterator_start() {}
  240. bool iterator_next();
  241. Value iterator_get()
  242. {
  243. return m_row;
  244. }
  245. protected:
  246. Row_result_detail() = default;
  247. Row_result_detail(common::Result_init&);
  248. Row_result_detail(Row_result_detail&&) = default;
  249. Row_result_detail& operator=(Row_result_detail&&) = default;
  250. RowList get_rows()
  251. {
  252. /*
  253. Construct RowList instance passing reference to this Row_result_detail
  254. object which acts as a source for the list initializer.
  255. */
  256. return *this;
  257. }
  258. row_count_t row_count();
  259. Row get_row()
  260. {
  261. if (!iterator_next())
  262. return Row();
  263. return iterator_get();
  264. }
  265. private:
  266. // Storage for result column information.
  267. Columns m_cols;
  268. protected:
  269. col_count_t col_count() const;
  270. const Column& get_column(col_count_t) const;
  271. const Columns& get_columns() const;
  272. bool next_result()
  273. {
  274. bool rc = Result_detail::next_result();
  275. if (rc)
  276. m_cols.init(get_impl());
  277. return rc;
  278. }
  279. friend iterator;
  280. friend RowResult;
  281. friend Columns;
  282. };
  283. // Document based results
  284. // ----------------------
  285. class PUBLIC_API Doc_result_detail
  286. : public Result_detail
  287. {
  288. public:
  289. using iterator = Iterator<Doc_result_detail, DbDoc>;
  290. using DocList = List_initializer<Doc_result_detail&>;
  291. iterator begin()
  292. {
  293. return iterator(*this);
  294. }
  295. iterator end() const
  296. {
  297. return iterator();
  298. }
  299. private:
  300. // iterator implementation
  301. DbDoc m_cur_doc;
  302. void iterator_start() {}
  303. bool iterator_next();
  304. DbDoc iterator_get()
  305. {
  306. return m_cur_doc;
  307. }
  308. protected:
  309. Doc_result_detail() = default;
  310. Doc_result_detail(common::Result_init &init)
  311. : Result_detail(init)
  312. {}
  313. DbDoc get_doc()
  314. {
  315. if (!iterator_next())
  316. return DbDoc();
  317. return iterator_get();
  318. }
  319. uint64_t count();
  320. DocList get_docs()
  321. {
  322. return *this;
  323. }
  324. friend Impl;
  325. friend iterator;
  326. };
  327. } // internal namespace
  328. } // mysqlx
  329. #endif