static_results.hpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. //
  2. // Copyright (c) 2019-2024 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef BOOST_MYSQL_STATIC_RESULTS_HPP
  8. #define BOOST_MYSQL_STATIC_RESULTS_HPP
  9. #include <boost/mysql/detail/config.hpp>
  10. #ifdef BOOST_MYSQL_CXX14
  11. #include <boost/mysql/metadata_collection_view.hpp>
  12. #include <boost/mysql/string_view.hpp>
  13. #include <boost/mysql/detail/access.hpp>
  14. #include <boost/mysql/detail/execution_processor/static_results_impl.hpp>
  15. #include <boost/assert.hpp>
  16. namespace boost {
  17. namespace mysql {
  18. /**
  19. * \brief Holds the results of a SQL query (static interface).
  20. * \details
  21. * This object can store the results of single and multi resultset queries
  22. * in a type-safe manner.
  23. *
  24. * \tparam StaticRow The row or row types that will be returned by the server.
  25. * There must be one for every resultset returned by the query, and always at least one.
  26. * All the passed types must fulfill the `StaticRow` concept.
  27. *
  28. * \par Thread safety
  29. * Distinct objects: safe. \n
  30. * Shared objects: unsafe. \n
  31. */
  32. template <class... StaticRow>
  33. class static_results
  34. {
  35. public:
  36. /**
  37. * \brief Default constructor.
  38. * \details Constructs an empty results object, with `this->has_value() == false`.
  39. *
  40. * \par Exception safety
  41. * No-throw guarantee.
  42. */
  43. static_results() = default;
  44. /**
  45. * \brief Copy constructor.
  46. * \par Exception safety
  47. * Strong guarantee. Internal allocations may throw.
  48. */
  49. static_results(const static_results& other) = default;
  50. /**
  51. * \brief Move constructor.
  52. * \par Exception safety
  53. * No-throw guarantee.
  54. *
  55. * \par Object lifetimes
  56. * View objects obtained from `other` remain valid.
  57. */
  58. static_results(static_results&& other) = default;
  59. /**
  60. * \brief Copy assignment.
  61. * \par Exception safety
  62. * Basic guarantee. Internal allocations may throw.
  63. *
  64. * \par Object lifetimes
  65. * Views referencing `*this` are invalidated.
  66. */
  67. static_results& operator=(const static_results& other) = default;
  68. /**
  69. * \brief Move assignment.
  70. * \par Exception safety
  71. * Basic guarantee. Internal allocations may throw.
  72. *
  73. * \par Object lifetimes
  74. * View objects obtained from `other` remain valid.
  75. * Views and referencing `*this` are invalidated.
  76. */
  77. static_results& operator=(static_results&& other) = default;
  78. /// Destructor
  79. ~static_results() = default;
  80. /**
  81. * \brief Returns whether the object holds a valid result.
  82. * \details Having `this->has_value()` is a precondition to call all data accessors.
  83. * Objects populated by \ref connection::execute and \ref connection::async_execute
  84. * are guaranteed to have `this->has_value() == true`.
  85. *
  86. * \par Exception safety
  87. * No-throw guarantee.
  88. *
  89. * \par Complexity
  90. * Constant.
  91. */
  92. bool has_value() const noexcept { return impl_.get_interface().is_complete(); }
  93. /**
  94. * \brief Returns the rows retrieved by the SQL query.
  95. * \details
  96. *
  97. * \tparam I Resultset index. For operations returning more than one resultset, you can explicitly
  98. * specify this parameter to obtain the rows contained in the i-th resultset. If left unspecified,
  99. * rows for the first resultset are returned.
  100. *
  101. * \return Returns a read-only span of the `I`-th row type.
  102. *
  103. * \par Preconditions
  104. * `this->has_value() == true`
  105. *
  106. * \par Exception safety
  107. * No-throw guarantee.
  108. *
  109. * \par Object lifetimes
  110. * This function returns a view object, with reference semantics. The returned view points into
  111. * memory owned by `*this`, and will be valid as long as `*this` or an object move-constructed
  112. * from `*this` are alive.
  113. *
  114. * \par Complexity
  115. * Constant.
  116. */
  117. template <std::size_t I = 0>
  118. #ifdef BOOST_MYSQL_DOXYGEN
  119. boost::span<const StaticRow... [I]>
  120. #else
  121. boost::span<const typename std::tuple_element<I, std::tuple<StaticRow...> >::type>
  122. #endif
  123. rows() const noexcept {
  124. static_assert(I < sizeof...(StaticRow), "Index I out of range");
  125. BOOST_ASSERT(has_value());
  126. return impl_.template get_rows<I>();
  127. }
  128. /**
  129. * \brief Returns metadata about the columns in the query.
  130. * \details
  131. * The returned collection will have as many \ref metadata objects as columns retrieved by
  132. * the SQL query, and in the same order. Note that this may not be the same order as in the `StaticRow`
  133. * type, since columns may be mapped by name or discarded. This function returns the representation that
  134. * was retrieved from the database.
  135. *
  136. * \tparam I Resultset index. For operations returning more than one resultset, you can explicitly
  137. * specify this parameter to obtain metadata for the i-th resultset. If left unspecified,
  138. * metadata for the first resultset is returned.
  139. *
  140. * \par Preconditions
  141. * `this->has_value() == true`
  142. *
  143. * \par Exception safety
  144. * No-throw guarantee.
  145. *
  146. * \par Object lifetimes
  147. * This function returns a view object, with reference semantics. The returned view points into
  148. * memory owned by `*this`, and will be valid as long as `*this` or an object move-constructed
  149. * from `*this` are alive.
  150. *
  151. * \par Complexity
  152. * Constant.
  153. */
  154. template <std::size_t I = 0>
  155. metadata_collection_view meta() const noexcept
  156. {
  157. static_assert(I < sizeof...(StaticRow), "Index I out of range");
  158. BOOST_ASSERT(has_value());
  159. return impl_.get_interface().get_meta(I);
  160. }
  161. /**
  162. * \brief Returns the number of rows affected by the executed SQL statement.
  163. * \details
  164. * \tparam I Resultset index. For operations returning more than one resultset, you can explicitly
  165. * specify this parameter to obtain the number of affected rows by the i-th resultset. If left
  166. * unspecified, the number of affected rows by the first resultset is returned.
  167. *
  168. * \par Preconditions
  169. * `this->has_value() == true`
  170. *
  171. * \par Exception safety
  172. * No-throw guarantee.
  173. *
  174. * \par Complexity
  175. * Constant.
  176. */
  177. template <std::size_t I = 0>
  178. std::uint64_t affected_rows() const noexcept
  179. {
  180. static_assert(I < sizeof...(StaticRow), "Index I out of range");
  181. BOOST_ASSERT(has_value());
  182. return impl_.get_interface().get_affected_rows(I);
  183. }
  184. /**
  185. * \brief Returns the last insert ID produced by the executed SQL statement.
  186. * \details
  187. * \tparam I Resultset index. For operations returning more than one resultset, you can explicitly
  188. * specify this parameter to obtain the last insert ID for the i-th resultset. If left unspecified,
  189. * the last insert ID for the first resultset is returned.
  190. *
  191. * \par Preconditions
  192. * `this->has_value() == true`
  193. *
  194. * \par Exception safety
  195. * No-throw guarantee.
  196. *
  197. * \par Complexity
  198. * Constant.
  199. */
  200. template <std::size_t I = 0>
  201. std::uint64_t last_insert_id() const noexcept
  202. {
  203. static_assert(I < sizeof...(StaticRow), "I index out of range");
  204. BOOST_ASSERT(has_value());
  205. return impl_.get_interface().get_last_insert_id(I);
  206. }
  207. /**
  208. * \brief Returns the number of warnings produced by the executed SQL statement.
  209. * \details
  210. * \tparam I Resultset index. For operations returning more than one resultset, you can explicitly
  211. * specify this parameter to obtain the warning count for the i-th resultset. If left unspecified,
  212. * the warning count for the first resultset is returned.
  213. *
  214. * \par Preconditions
  215. * `this->has_value() == true`
  216. *
  217. * \par Exception safety
  218. * No-throw guarantee.
  219. *
  220. * \par Complexity
  221. * Constant.
  222. */
  223. template <std::size_t I = 0>
  224. unsigned warning_count() const noexcept
  225. {
  226. static_assert(I < sizeof...(StaticRow), "I index out of range");
  227. BOOST_ASSERT(has_value());
  228. return impl_.get_interface().get_warning_count(I);
  229. }
  230. /**
  231. * \brief Returns additional text information about the execution of the SQL statement.
  232. * \details
  233. * The format of this information is documented by MySQL <a
  234. * href="https://dev.mysql.com/doc/c-api/8.0/en/mysql-info.html">here</a>.
  235. * \n
  236. * The returned string always uses ASCII encoding, regardless of the connection's character set.
  237. *
  238. * \tparam I Resultset index. For operations returning more than one resultset, you can explicitly
  239. * specify this parameter to obtain the value for the i-th resultset. If left unspecified,
  240. * the value for the first resultset is returned.
  241. *
  242. * \par Preconditions
  243. * `this->has_value() == true`
  244. *
  245. * \par Exception safety
  246. * No-throw guarantee.
  247. *
  248. * \par Object lifetimes
  249. * This function returns a view object, with reference semantics. The returned view points into
  250. * memory owned by `*this`, and will be valid as long as `*this` or an object move-constructed
  251. * from `*this` are alive.
  252. *
  253. * \par Complexity
  254. * Constant.
  255. */
  256. template <std::size_t I = 0>
  257. string_view info() const noexcept
  258. {
  259. static_assert(I < sizeof...(StaticRow), "I index out of range");
  260. BOOST_ASSERT(has_value());
  261. return impl_.get_interface().get_info(I);
  262. }
  263. private:
  264. detail::static_results_impl<StaticRow...> impl_;
  265. #ifndef BOOST_MYSQL_DOXYGEN
  266. friend struct detail::access;
  267. #endif
  268. };
  269. } // namespace mysql
  270. } // namespace boost
  271. #endif // BOOST_MYSQL_CXX14
  272. #endif