statement.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //
  2. // Copyright (c) 2019-2025 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_IMPL_STATEMENT_HPP
  8. #define BOOST_MYSQL_IMPL_STATEMENT_HPP
  9. #pragma once
  10. #include <boost/mysql/field_view.hpp>
  11. #include <boost/mysql/statement.hpp>
  12. #include <boost/mysql/detail/access.hpp>
  13. #include <boost/mysql/detail/any_execution_request.hpp>
  14. #include <boost/mysql/detail/writable_field_traits.hpp>
  15. #include <boost/assert.hpp>
  16. #include <boost/core/ignore_unused.hpp>
  17. #include <tuple>
  18. #include <vector>
  19. template <BOOST_MYSQL_WRITABLE_FIELD_TUPLE WritableFieldTuple>
  20. class boost::mysql::bound_statement_tuple
  21. {
  22. friend class statement;
  23. friend struct detail::access;
  24. struct impl
  25. {
  26. statement stmt;
  27. WritableFieldTuple params;
  28. } impl_;
  29. template <typename TupleType>
  30. bound_statement_tuple(const statement& stmt, TupleType&& t) : impl_{stmt, std::forward<TupleType>(t)}
  31. {
  32. }
  33. };
  34. template <BOOST_MYSQL_FIELD_VIEW_FORWARD_ITERATOR FieldViewFwdIterator>
  35. class boost::mysql::bound_statement_iterator_range
  36. {
  37. friend class statement;
  38. friend struct detail::access;
  39. struct impl
  40. {
  41. statement stmt;
  42. FieldViewFwdIterator first;
  43. FieldViewFwdIterator last;
  44. } impl_;
  45. bound_statement_iterator_range(
  46. const statement& stmt,
  47. FieldViewFwdIterator first,
  48. FieldViewFwdIterator last
  49. )
  50. : impl_{stmt, first, last}
  51. {
  52. }
  53. };
  54. template <BOOST_MYSQL_WRITABLE_FIELD_TUPLE WritableFieldTuple, typename EnableIf>
  55. boost::mysql::bound_statement_tuple<typename std::decay<WritableFieldTuple>::type> boost::mysql::statement::
  56. bind(WritableFieldTuple&& args) const
  57. {
  58. BOOST_ASSERT(valid());
  59. return bound_statement_tuple<typename std::decay<WritableFieldTuple>::type>(
  60. *this,
  61. std::forward<WritableFieldTuple>(args)
  62. );
  63. }
  64. template <BOOST_MYSQL_FIELD_VIEW_FORWARD_ITERATOR FieldViewFwdIterator, typename EnableIf>
  65. boost::mysql::bound_statement_iterator_range<FieldViewFwdIterator> boost::mysql::statement::bind(
  66. FieldViewFwdIterator first,
  67. FieldViewFwdIterator last
  68. ) const
  69. {
  70. BOOST_ASSERT(valid());
  71. return bound_statement_iterator_range<FieldViewFwdIterator>(*this, first, last);
  72. }
  73. // Execution request traits
  74. namespace boost {
  75. namespace mysql {
  76. namespace detail {
  77. // Tuple
  78. template <std::size_t N>
  79. struct stmt_tuple_request_proxy
  80. {
  81. statement stmt;
  82. std::array<field_view, N> params;
  83. operator any_execution_request() const
  84. {
  85. return any_execution_request({stmt.id(), static_cast<std::uint16_t>(stmt.num_params()), params});
  86. }
  87. };
  88. template <class... T>
  89. struct execution_request_traits<bound_statement_tuple<std::tuple<T...>>>
  90. {
  91. template <std::size_t... I>
  92. static std::array<field_view, sizeof...(T)> tuple_to_array(const std::tuple<T...>& t, mp11::index_sequence<I...>)
  93. {
  94. boost::ignore_unused(t); // MSVC gets confused if sizeof...(T) == 0
  95. return {{to_field(std::get<I>(t))...}};
  96. }
  97. static stmt_tuple_request_proxy<sizeof...(T)> make_request(const bound_statement_tuple<std::tuple<T...>>& input, std::vector<field_view>&)
  98. {
  99. auto& impl = access::get_impl(input);
  100. return {impl.stmt, tuple_to_array(impl.params, mp11::make_index_sequence<sizeof...(T)>())};
  101. }
  102. };
  103. // Iterator range
  104. template <class FieldViewFwdIterator>
  105. struct execution_request_traits<bound_statement_iterator_range<FieldViewFwdIterator>>
  106. {
  107. static any_execution_request make_request(
  108. const bound_statement_iterator_range<FieldViewFwdIterator>& input,
  109. std::vector<field_view>& shared_fields
  110. )
  111. {
  112. auto& impl = access::get_impl(input);
  113. shared_fields.assign(impl.first, impl.last);
  114. return any_execution_request(
  115. {impl.stmt.id(), static_cast<std::uint16_t>(impl.stmt.num_params()), shared_fields}
  116. );
  117. }
  118. };
  119. } // namespace detail
  120. } // namespace mysql
  121. } // namespace boost
  122. #endif