run_algo.ipp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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_IMPL_RUN_ALGO_IPP
  8. #define BOOST_MYSQL_IMPL_RUN_ALGO_IPP
  9. #pragma once
  10. #include <boost/mysql/detail/algo_params.hpp>
  11. #include <boost/mysql/detail/config.hpp>
  12. #include <boost/mysql/detail/run_algo.hpp>
  13. #include <boost/mysql/impl/internal/network_algorithms/run_algo_impl.hpp>
  14. #include <boost/mysql/impl/internal/sansio/connection_state.hpp>
  15. #include <boost/asio/any_completion_handler.hpp>
  16. namespace boost {
  17. namespace mysql {
  18. namespace detail {
  19. template <class AlgoParams>
  20. class generic_algo_handler
  21. {
  22. public:
  23. static_assert(!has_void_result<AlgoParams>(), "AlgoParams::result_type should be non-void");
  24. using result_t = typename AlgoParams::result_type;
  25. using final_handler_t = asio::any_completion_handler<void(error_code, result_t)>;
  26. generic_algo_handler(final_handler_t&& h, connection_state& st) : final_handler_(std::move(h)), st_(&st)
  27. {
  28. }
  29. using allocator_type = typename final_handler_t::allocator_type;
  30. using cancellation_slot_type = typename final_handler_t::cancellation_slot_type;
  31. allocator_type get_allocator() const noexcept { return final_handler_.get_allocator(); }
  32. cancellation_slot_type get_cancellation_slot() const noexcept
  33. {
  34. return final_handler_.get_cancellation_slot();
  35. }
  36. const final_handler_t& handler() const noexcept { return final_handler_; }
  37. void operator()(error_code ec)
  38. {
  39. std::move(final_handler_)(ec, ec ? result_t{} : st_->result<AlgoParams>());
  40. }
  41. private:
  42. final_handler_t final_handler_;
  43. connection_state* st_;
  44. };
  45. template <class OpParam>
  46. asio::any_completion_handler<void(error_code)> make_handler(
  47. completion_handler_t<OpParam>&& final_handler,
  48. connection_state& st,
  49. typename std::enable_if<!has_void_result<OpParam>()>::type* = nullptr
  50. )
  51. {
  52. return generic_algo_handler<OpParam>(std::move(final_handler), st);
  53. }
  54. template <class OpParam>
  55. asio::any_completion_handler<void(error_code)> make_handler(
  56. asio::any_completion_handler<void(error_code)>&& final_handler,
  57. connection_state&,
  58. typename std::enable_if<has_void_result<OpParam>()>::type* = nullptr
  59. )
  60. {
  61. return std::move(final_handler);
  62. }
  63. } // namespace detail
  64. } // namespace mysql
  65. } // namespace boost
  66. namespace boost {
  67. namespace asio {
  68. template <class OpParam, class Candidate>
  69. struct associated_executor<mysql::detail::generic_algo_handler<OpParam>, Candidate>
  70. {
  71. using type = any_completion_executor;
  72. static type get(
  73. const mysql::detail::generic_algo_handler<OpParam>& handler,
  74. const Candidate& candidate = Candidate()
  75. ) noexcept
  76. {
  77. return asio::get_associated_executor(handler.handler(), candidate);
  78. }
  79. };
  80. template <class OpParam, class Candidate>
  81. struct associated_immediate_executor<mysql::detail::generic_algo_handler<OpParam>, Candidate>
  82. {
  83. using type = any_completion_executor;
  84. static type get(
  85. const mysql::detail::generic_algo_handler<OpParam>& handler,
  86. const Candidate& candidate = Candidate()
  87. ) BOOST_ASIO_NOEXCEPT
  88. {
  89. return asio::get_associated_immediate_executor(handler.handler(), candidate);
  90. }
  91. };
  92. } // namespace asio
  93. } // namespace boost
  94. template <class AlgoParams>
  95. typename AlgoParams::result_type boost::mysql::detail::run_algo(
  96. any_stream& stream,
  97. connection_state& st,
  98. AlgoParams params,
  99. error_code& ec
  100. )
  101. {
  102. auto algo = st.setup(params);
  103. run_algo_impl(stream, algo, ec);
  104. return st.result<AlgoParams>();
  105. }
  106. template <class AlgoParams>
  107. void boost::mysql::detail::async_run_algo(
  108. any_stream& stream,
  109. connection_state& st,
  110. AlgoParams params,
  111. completion_handler_t<AlgoParams> final_handler
  112. )
  113. {
  114. auto handler = make_handler<AlgoParams>(std::move(final_handler), st);
  115. auto algo = st.setup(params);
  116. async_run_algo_impl(stream, algo, std::move(handler));
  117. }
  118. #ifdef BOOST_MYSQL_SEPARATE_COMPILATION
  119. #define BOOST_MYSQL_INSTANTIATE_ALGO(op_params_type) \
  120. template op_params_type::result_type \
  121. run_algo<op_params_type>(any_stream&, connection_state&, op_params_type, error_code&); \
  122. template void async_run_algo< \
  123. op_params_type>(any_stream&, connection_state&, op_params_type, completion_handler_t<op_params_type>);
  124. namespace boost {
  125. namespace mysql {
  126. namespace detail {
  127. BOOST_MYSQL_INSTANTIATE_ALGO(connect_algo_params)
  128. BOOST_MYSQL_INSTANTIATE_ALGO(handshake_algo_params)
  129. BOOST_MYSQL_INSTANTIATE_ALGO(execute_algo_params)
  130. BOOST_MYSQL_INSTANTIATE_ALGO(start_execution_algo_params)
  131. BOOST_MYSQL_INSTANTIATE_ALGO(read_resultset_head_algo_params)
  132. BOOST_MYSQL_INSTANTIATE_ALGO(read_some_rows_algo_params)
  133. BOOST_MYSQL_INSTANTIATE_ALGO(read_some_rows_dynamic_algo_params)
  134. BOOST_MYSQL_INSTANTIATE_ALGO(prepare_statement_algo_params)
  135. BOOST_MYSQL_INSTANTIATE_ALGO(close_statement_algo_params)
  136. BOOST_MYSQL_INSTANTIATE_ALGO(set_character_set_algo_params)
  137. BOOST_MYSQL_INSTANTIATE_ALGO(ping_algo_params)
  138. BOOST_MYSQL_INSTANTIATE_ALGO(reset_connection_algo_params)
  139. BOOST_MYSQL_INSTANTIATE_ALGO(quit_connection_algo_params)
  140. BOOST_MYSQL_INSTANTIATE_ALGO(close_connection_algo_params)
  141. } // namespace detail
  142. } // namespace mysql
  143. } // namespace boost
  144. #endif
  145. #endif