row.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * Copyright (c) 2015, 2019, 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_ROW_H
  31. #define MYSQLX_ROW_H
  32. /**
  33. @file
  34. TODO
  35. */
  36. #include "common.h"
  37. #include "document.h"
  38. #include "detail/row.h"
  39. #include <memory>
  40. namespace mysqlx {
  41. MYSQLX_ABI_BEGIN(2,0)
  42. /**
  43. Represents a single row from a result that contains rows.
  44. Such a row consists of a number of fields, each storing single
  45. value. The number of fields and types of values stored in each
  46. field are described by `RowResult` instance that produced this
  47. row.
  48. Values of fields can be accessed with `get()` method or using
  49. `row[pos]` expression. Fields are identified by 0-based position.
  50. It is also possible to get raw bytes representing value of a
  51. given field with `getBytes()` method.
  52. @sa `Value` class.
  53. @todo Support for iterating over row fields with range-for loop.
  54. @ingroup devapi_res
  55. */
  56. class Row
  57. : private internal::Row_detail
  58. {
  59. Row(internal::Row_detail &&other)
  60. try
  61. : Row_detail(std::move(other))
  62. {}
  63. CATCH_AND_WRAP
  64. public:
  65. Row() {}
  66. template<typename T, typename... Types>
  67. explicit Row(T val, Types... vals)
  68. {
  69. try {
  70. Row_detail::set_values(0, val, vals...);
  71. }
  72. CATCH_AND_WRAP
  73. }
  74. col_count_t colCount() const
  75. {
  76. try {
  77. return Row_detail::col_count();
  78. }
  79. CATCH_AND_WRAP
  80. }
  81. /**
  82. Get raw bytes representing value of row field at position `pos`.
  83. The raw bytes are as received from the server. In genral the value
  84. is represented using x-protocol encoding that corresponds to the
  85. type and other meta-data of the given column. This meta-data can
  86. be accessed via `Column` object returned by `RowResult#getColumn()`
  87. method.
  88. The x-protocol represenation of different value types is documented
  89. [here]
  90. (https://dev.mysql.com/doc/dev/mysql-server/latest/structMysqlx_1_1Resultset_1_1ColumnMetaData.html).
  91. Most types reported by `Column#getType()` method correspond to an x-protocol
  92. value type of the same name.
  93. All integer types use the x-protocol UINT or SINT encoding, which is
  94. the protobuf variant encoding together with zig-zag encoding for the
  95. signed case
  96. (see <https://developers.google.com/protocol-buffers/docs/encoding>)
  97. STRING values are encoded using the character set encoding as reported
  98. by `Column#getCharacterSet()` method of the corresponding `Column` object
  99. (usually `utf8mb4`).
  100. JSON data is represented as a JSON string. ENUM values are represented
  101. as strings with enum constant names. Values of type DATE and TIMESTAMP
  102. use the same representation as DATETIME, with time part empty in case
  103. of DATE values. GEOMETRY values use the internal geometry storage
  104. format described
  105. [here]
  106. (https://dev.mysql.com/doc/refman/8.0/en/gis-data-formats.html).
  107. Note that raw representation of BYTES and STRING values has an extra
  108. 0x00 byte added at the end, which is not part of the originial data.
  109. It is used to distinguish null values from empty byte sequences.
  110. @returns null bytes range if given field is NULL.
  111. @throws out_of_range if given row was not fetched from server.
  112. */
  113. bytes getBytes(col_count_t pos) const
  114. {
  115. try {
  116. return Row_detail::get_bytes(pos);
  117. }
  118. CATCH_AND_WRAP
  119. }
  120. /**
  121. Get reference to row field at position `pos`.
  122. @throws out_of_range if given field does not exist in the row.
  123. */
  124. Value& get(col_count_t pos)
  125. {
  126. try {
  127. return Row_detail::get_val(pos);
  128. }
  129. CATCH_AND_WRAP
  130. }
  131. /**
  132. Set value of row field at position `pos`.
  133. Creates new field if it does not exist.
  134. @returns Reference to the field that was set.
  135. */
  136. Value& set(col_count_t pos, const Value &val)
  137. {
  138. try {
  139. Row_detail::set_values(pos, val);
  140. return Row_detail::get_val(pos);
  141. }
  142. CATCH_AND_WRAP
  143. }
  144. /**
  145. Get const reference to row field at position `pos`.
  146. This is const version of method `get()`.
  147. @throws out_of_range if given field does not exist in the row.
  148. */
  149. const Value& operator[](col_count_t pos) const
  150. {
  151. return const_cast<Row*>(this)->get(pos);
  152. }
  153. /**
  154. Get modifiable reference to row field at position `pos`.
  155. The field is created if it does not exist. In this case
  156. the initial value of the field is NULL.
  157. */
  158. Value& operator[](col_count_t pos)
  159. {
  160. ensure_impl();
  161. try {
  162. return get(pos);
  163. }
  164. catch (const out_of_range&)
  165. {
  166. return set(pos, Value());
  167. }
  168. }
  169. /// Check if this row contains fields or is null.
  170. bool isNull() const { return NULL == m_impl; }
  171. operator bool() const { return !isNull(); }
  172. void clear()
  173. {
  174. try {
  175. Row_detail::clear();
  176. }
  177. CATCH_AND_WRAP
  178. }
  179. private:
  180. using internal::Row_detail::m_impl;
  181. /// @cond IGNORED
  182. friend internal::Row_result_detail<Columns>;
  183. friend internal::Table_insert_detail;
  184. /// @endcond
  185. };
  186. MYSQLX_ABI_END(2,0)
  187. } // mysqlx
  188. #endif