result.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  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_RESULT_H
  31. #define MYSQLX_RESULT_H
  32. /**
  33. @file
  34. Classes used to access query and command execution results.
  35. */
  36. #include "common.h"
  37. #include "document.h"
  38. #include "row.h"
  39. #include "collations.h"
  40. #include "detail/result.h"
  41. namespace mysqlx {
  42. using std::ostream;
  43. class Session;
  44. class Schema;
  45. class Collection;
  46. class Result;
  47. class Row;
  48. class RowResult;
  49. class SqlResult;
  50. class DbDoc;
  51. class DocResult;
  52. template <class Res, class Op> class Executable;
  53. namespace internal {
  54. /*
  55. A wrapper which adds methods common for all result classes.
  56. */
  57. template <class Base>
  58. class Result_common
  59. : protected Base
  60. {
  61. using WarningList = internal::Result_detail::WarningList;
  62. public:
  63. /// Get the number of warnings stored in the result.
  64. unsigned getWarningsCount() const
  65. {
  66. try {
  67. return Base::get_warning_count();
  68. }
  69. CATCH_AND_WRAP
  70. }
  71. /// Get a list of warnings stored in the result.
  72. WarningList getWarnings()
  73. {
  74. try {
  75. return Base::get_warnings();
  76. }
  77. CATCH_AND_WRAP
  78. }
  79. /// Get the warning at the given, 0-based position.
  80. // TODO: Change arg type to size_t?
  81. Warning getWarning(unsigned pos)
  82. {
  83. try {
  84. return Base::get_warning(pos);
  85. }
  86. CATCH_AND_WRAP
  87. }
  88. // TODO: expose this in the API?
  89. //using WarningsIterator = Result_detail::iterator;
  90. /**
  91. Get the count of affected items (rows or doucuments) from manipulation statements.
  92. */
  93. uint64_t getAffectedItemsCount() const
  94. {
  95. try {
  96. return Result_detail::get_affected_rows();
  97. } CATCH_AND_WRAP
  98. }
  99. protected:
  100. // Wrap base ctors/assginment with catch handlers
  101. Result_common()
  102. try
  103. : Base()
  104. {}
  105. CATCH_AND_WRAP
  106. Result_common(Result_common &&other)
  107. try
  108. : Base(std::move(other))
  109. {}
  110. CATCH_AND_WRAP
  111. Result_common& operator=(Result_common &&other)
  112. try
  113. {
  114. Base::operator=(std::move(other));
  115. return *this;
  116. }
  117. CATCH_AND_WRAP
  118. Result_common(common::Result_init &init)
  119. try
  120. : Base(init)
  121. {}
  122. CATCH_AND_WRAP
  123. };
  124. } // internal namespace
  125. /**
  126. Represents a result of an operation that does not return data.
  127. A generic result which can be returned by operations which only
  128. modify data.
  129. A `Result` instance can store the result of executing an operation:
  130. ~~~~~~
  131. Result res = operation.execute();
  132. ~~~~~~
  133. Storing another result in a `Result` instance overwrites
  134. the previous result.
  135. @ingroup devapi_res
  136. */
  137. class Result
  138. : public internal::Result_common<internal::Result_detail>
  139. {
  140. public:
  141. Result() = default;
  142. /**
  143. Get the auto-increment value if one was generated by a table insert
  144. statement.
  145. */
  146. uint64_t getAutoIncrementValue() const
  147. {
  148. try {
  149. return Result_detail::get_auto_increment();
  150. } CATCH_AND_WRAP
  151. }
  152. /**
  153. Return a list of identifiers of multiple documents added to a collection,
  154. generated by the server.
  155. */
  156. DocIdList getGeneratedIds() const
  157. {
  158. try {
  159. return Result_detail::get_generated_ids();
  160. } CATCH_AND_WRAP
  161. }
  162. private:
  163. Result(common::Result_init &init)
  164. : Result_common(init)
  165. {}
  166. template <class Res, class Op>
  167. friend class Executable;
  168. friend Collection;
  169. };
  170. // Row based results
  171. // -----------------
  172. /**
  173. Types that can be reported in result meta-data.
  174. @ingroup devapi_res
  175. */
  176. enum class Type : unsigned short
  177. {
  178. #undef TYPE_ENUM
  179. #define TYPE_ENUM(X,N) X=N,
  180. RESULT_TYPE_LIST(TYPE_ENUM)
  181. };
  182. /**
  183. Return name of a given type.
  184. @ingroup devapi_res
  185. */
  186. inline
  187. const char* typeName(Type t)
  188. {
  189. #define TYPE_NAME(T,X) case Type::T: return #T;
  190. switch (t)
  191. {
  192. RESULT_TYPE_LIST(TYPE_NAME)
  193. default:
  194. THROW("Unknown type");
  195. }
  196. }
  197. inline
  198. std::ostream& operator<<(std::ostream &out, Type t)
  199. {
  200. return out << typeName(t);
  201. }
  202. /**
  203. Provides meta-data for a single result column.
  204. @ingroup devapi_res
  205. */
  206. class Column
  207. : public virtual common::Printable
  208. , private internal::Column_detail
  209. {
  210. public:
  211. string getSchemaName() const ///< TODO
  212. {
  213. try {
  214. return Column_detail::get_schema_name();
  215. }
  216. CATCH_AND_WRAP
  217. }
  218. string getTableName() const ///< TODO
  219. {
  220. try {
  221. return Column_detail::get_table_name();
  222. }
  223. CATCH_AND_WRAP
  224. }
  225. string getTableLabel() const ///< TODO
  226. {
  227. try {
  228. return Column_detail::get_table_label();
  229. }
  230. CATCH_AND_WRAP
  231. }
  232. string getColumnName() const ///< TODO
  233. {
  234. try {
  235. return Column_detail::get_name();
  236. }
  237. CATCH_AND_WRAP
  238. }
  239. string getColumnLabel() const ///< TODO
  240. {
  241. try {
  242. return Column_detail::get_label();
  243. }
  244. CATCH_AND_WRAP
  245. }
  246. Type getType() const ///< TODO
  247. {
  248. try {
  249. return Type(Column_detail::get_type());
  250. }
  251. CATCH_AND_WRAP
  252. }
  253. /**
  254. Get column length
  255. @return The maximum length of data in the column in bytes, as reported
  256. by the server.
  257. @note Because the column length is returned as byte length, it could be
  258. confusing with the multi-byte character sets. For instance, with UTF8MB4
  259. the length of VARCHAR(100) column is reported as 400 because each character
  260. is 4 bytes long.
  261. */
  262. unsigned long getLength() const
  263. {
  264. try {
  265. return Column_detail::get_length();
  266. }
  267. CATCH_AND_WRAP
  268. }
  269. unsigned short getFractionalDigits() const ///< TODO
  270. {
  271. try {
  272. return Column_detail::get_decimals();
  273. }
  274. CATCH_AND_WRAP
  275. }
  276. bool isNumberSigned() const ///< TODO
  277. {
  278. try {
  279. return Column_detail::is_signed();
  280. }
  281. CATCH_AND_WRAP
  282. }
  283. CharacterSet getCharacterSet() const ///< TODO
  284. {
  285. try {
  286. return Column_detail::get_charset();
  287. }
  288. CATCH_AND_WRAP
  289. }
  290. /// TODO
  291. std::string getCharacterSetName() const
  292. {
  293. try {
  294. return characterSetName(getCharacterSet());
  295. }
  296. CATCH_AND_WRAP
  297. }
  298. const CollationInfo& getCollation() const ///< TODO
  299. {
  300. try {
  301. return Column_detail::get_collation();
  302. }
  303. CATCH_AND_WRAP
  304. }
  305. /// TODO
  306. std::string getCollationName() const
  307. {
  308. try {
  309. return getCollation().getName();
  310. }
  311. CATCH_AND_WRAP
  312. }
  313. /// TODO
  314. bool isPadded() const
  315. {
  316. try {
  317. return Column_detail::is_padded();
  318. }
  319. CATCH_AND_WRAP
  320. }
  321. protected:
  322. using Column_detail::Impl;
  323. Column(const Impl &impl)
  324. try
  325. : Column_detail(impl)
  326. {}
  327. CATCH_AND_WRAP
  328. Column() = default;
  329. Column(const Column&) = default;
  330. Column(Column&&) = default;
  331. Column& operator=(const Column&) = default;
  332. void print(std::ostream &out) const
  333. {
  334. // TODO: not sure if this code will be called by operator<<.
  335. try {
  336. Column_detail::print(out);
  337. }
  338. CATCH_AND_WRAP
  339. }
  340. public:
  341. friend RowResult;
  342. struct INTERNAL Access;
  343. friend Access;
  344. };
  345. /*
  346. Extern declarations for Columns_detail<Column> template specialization
  347. elements that are defined in result.cc.
  348. Note: "extern template" works with MSVC but not with GCC.
  349. */
  350. namespace internal {
  351. template<> PUBLIC_API
  352. void Columns_detail<Column>::init(const Result_detail::Impl&);
  353. } // internal
  354. extern template PUBLIC_API
  355. void internal::Columns_detail<Column>::init(
  356. const internal::Result_detail::Impl &impl
  357. );
  358. class Columns
  359. : private internal::Columns_detail<Column>
  360. {
  361. public:
  362. using Columns_detail::operator[];
  363. using Columns_detail::iterator;
  364. using Columns_detail::begin;
  365. using Columns_detail::end;
  366. private:
  367. using Columns_detail::init;
  368. // note: Required by Row_result_detail
  369. Columns() = default;
  370. Columns(Columns&&) = default;
  371. Columns& operator=(Columns&&) = default;
  372. ///@cond IGNORE
  373. friend internal::Row_result_detail<Columns>;
  374. ///@endcond
  375. };
  376. /*
  377. Extern declarations for Row_result_detail<Columns> template specialization
  378. elements that are defined in result.cc.
  379. */
  380. namespace internal {
  381. template<> PUBLIC_API
  382. bool Row_result_detail<Columns>::iterator_next();
  383. template<> PUBLIC_API
  384. col_count_t Row_result_detail<Columns>::col_count() const;
  385. template<> PUBLIC_API
  386. Row_result_detail<Columns>::Row_result_detail(
  387. common::Result_init &init
  388. );
  389. template<> PUBLIC_API
  390. auto Row_result_detail<Columns>::get_column(col_count_t pos) const
  391. -> const Column&;
  392. template<> PUBLIC_API
  393. auto internal::Row_result_detail<Columns>::get_columns() const
  394. -> const Columns&;
  395. template<> PUBLIC_API
  396. row_count_t internal::Row_result_detail<Columns>::row_count();
  397. } // internal
  398. /**
  399. %Result of an operation that returns rows.
  400. A `RowResult` object gives sequential access to the rows contained in
  401. the result. It is possible to get the rows one-by-one, or fetch and store
  402. all of them at once. One can iterate over the rows using range loop:
  403. `for (Row r : result) ...`.
  404. @ingroup devapi_res
  405. */
  406. class RowResult
  407. : public internal::Result_common<internal::Row_result_detail<Columns>>
  408. {
  409. public:
  410. using Columns = mysqlx::Columns;
  411. RowResult() = default;
  412. /// Return the number of fields in each row.
  413. col_count_t getColumnCount() const
  414. {
  415. try {
  416. return Row_result_detail::col_count();
  417. }
  418. CATCH_AND_WRAP
  419. }
  420. /// Return `Column` object describing the given column of the result.
  421. const Column& getColumn(col_count_t pos) const
  422. {
  423. try {
  424. return Row_result_detail::get_column(pos);
  425. }
  426. CATCH_AND_WRAP
  427. }
  428. /**
  429. Return meta-data for all result columns.
  430. TODO: explain ownership
  431. */
  432. const Columns& getColumns() const
  433. {
  434. try {
  435. return Row_result_detail::get_columns();
  436. }
  437. CATCH_AND_WRAP
  438. }
  439. /**
  440. Return the current row and move to the next one in the sequence.
  441. If there are no more rows in this result, returns a null `Row` instance.
  442. */
  443. Row fetchOne()
  444. {
  445. try {
  446. return Row_result_detail::get_row();
  447. }
  448. CATCH_AND_WRAP
  449. }
  450. using iterator = RowList::iterator;
  451. /**
  452. Return all remaining rows
  453. %Result of this method can be stored in a container such as
  454. `std::list<Row>`. Rows that have already been fetched using `fetchOne()` are
  455. not included in the result of `fetchAll()`.
  456. */
  457. RowList fetchAll()
  458. {
  459. try {
  460. return Row_result_detail::get_rows();
  461. }
  462. CATCH_AND_WRAP
  463. }
  464. /**
  465. Returns the number of rows contained in the result.
  466. The method counts only the rows that were not yet fetched and are still
  467. available in the result.
  468. */
  469. row_count_t count()
  470. {
  471. try {
  472. return Row_result_detail::row_count();
  473. }
  474. CATCH_AND_WRAP
  475. }
  476. /*
  477. Iterate over rows (range-for support).
  478. Rows that have been fetched using iterator are not available when
  479. calling fetchOne() or fetchAll()
  480. */
  481. iterator begin()
  482. {
  483. try {
  484. return Row_result_detail::begin();
  485. }
  486. CATCH_AND_WRAP
  487. }
  488. iterator end() const
  489. {
  490. try {
  491. return Row_result_detail::end();
  492. }
  493. CATCH_AND_WRAP
  494. }
  495. private:
  496. RowResult(common::Result_init &init)
  497. : Result_common(init)
  498. {}
  499. public:
  500. template <class Res, class Op> friend class Executable;
  501. friend SqlResult;
  502. friend DocResult;
  503. };
  504. /**
  505. %Result of an SQL query or command.
  506. In general, an SQL query or command can return multiple results (for example,
  507. a call to a stored procedure). Additionally, each or only some of these
  508. results can contain row data. A `SqlResult` object gives a sequential access
  509. to all results of a multi-result. Method `nextResult()` moves to the next
  510. result in the sequence, if present. Methods of `RowResult` are used to access
  511. row data of the current result (if it contains data).
  512. @ingroup devapi_res
  513. */
  514. class SqlResult
  515. : public RowResult
  516. {
  517. public:
  518. SqlResult() = default;
  519. /**
  520. Tell if the current result contains row data.
  521. If this is the case, rows can be accessed using `RowResult` interface.
  522. Otherwise calling `RowResult` methods throws an error.
  523. */
  524. bool hasData() const
  525. {
  526. try {
  527. return Result_detail::has_data();
  528. }
  529. CATCH_AND_WRAP
  530. }
  531. /**
  532. Move to the next result, if there is one.
  533. Returns true if the next result is available, false if there are no more
  534. results in the reply. Calling `nextResult()` discards the current result.
  535. If it has any rows that has not yet been fetched, these rows are also
  536. discarded.
  537. */
  538. bool nextResult()
  539. {
  540. try {
  541. return Row_result_detail::next_result();
  542. }
  543. CATCH_AND_WRAP
  544. }
  545. /**
  546. Get the auto-increment value if one was generated by a table insert
  547. statement.
  548. */
  549. uint64_t getAutoIncrementValue()
  550. {
  551. try {
  552. return Result_detail::get_auto_increment();
  553. }
  554. CATCH_AND_WRAP
  555. }
  556. private:
  557. SqlResult(common::Result_init &init)
  558. : RowResult(init)
  559. {}
  560. template <class Res, class Op>
  561. friend class Executable;
  562. };
  563. // Document based results
  564. // ----------------------
  565. /**
  566. %Result of an operation that returns documents.
  567. A `DocResult` object gives sequential access to the documents contained in
  568. the result. It is possible to get the documents one-by-one, or fetch and store
  569. all of them at once. One can iterate over the documents using range loop:
  570. `for (DbDoc d : result) ...`.
  571. @ingroup devapi_res
  572. */
  573. class DocResult
  574. : public internal::Result_common<internal::Doc_result_detail>
  575. {
  576. public:
  577. DocResult() = default;
  578. /**
  579. Return the current document and move to the next one in the sequence.
  580. If there are no more documents in this result, returns a null document.
  581. */
  582. DbDoc fetchOne()
  583. {
  584. try {
  585. return Doc_result_detail::get_doc();
  586. }
  587. CATCH_AND_WRAP
  588. }
  589. /**
  590. Return all remaining documents.
  591. %Result of this method can be stored in a container such as
  592. `std::list<DbDoc>`. Documents that have already been fetched using
  593. `fetchOne()` are not included in the result of `fetchAll()`.
  594. */
  595. DocList fetchAll()
  596. {
  597. try {
  598. return Doc_result_detail::get_docs();
  599. }
  600. CATCH_AND_WRAP
  601. }
  602. /**
  603. Returns the number of documents contained in the result.
  604. The method counts only the documents that were not yet fetched and are still
  605. available in the result.
  606. */
  607. uint64_t count()
  608. {
  609. try {
  610. return Doc_result_detail::count();
  611. }
  612. CATCH_AND_WRAP
  613. }
  614. /*
  615. Iterate over documents (range-for support).
  616. Documents that have been fetched using iterator are not available when
  617. calling fetchOne() or fetchAll()
  618. */
  619. using iterator = Doc_result_detail::iterator;
  620. iterator begin()
  621. {
  622. try {
  623. return Doc_result_detail::begin();
  624. }
  625. CATCH_AND_WRAP
  626. }
  627. iterator end() const
  628. {
  629. try {
  630. return Doc_result_detail::end();
  631. }
  632. CATCH_AND_WRAP
  633. }
  634. private:
  635. DocResult(common::Result_init &init)
  636. : Result_common(init)
  637. {}
  638. friend DbDoc;
  639. template <class Res,class Op>
  640. friend class Executable;
  641. };
  642. } // mysqlx
  643. #endif