results_impl.ipp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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_RESULTS_IMPL_IPP
  8. #define BOOST_MYSQL_IMPL_RESULTS_IMPL_IPP
  9. #pragma once
  10. #include <boost/mysql/detail/execution_processor/results_impl.hpp>
  11. #include <boost/mysql/impl/internal/protocol/deserialization.hpp>
  12. boost::mysql::detail::per_resultset_data& boost::mysql::detail::resultset_container::emplace_back()
  13. {
  14. if (!first_has_data_)
  15. {
  16. first_ = per_resultset_data();
  17. first_has_data_ = true;
  18. return first_;
  19. }
  20. else
  21. {
  22. rest_.emplace_back();
  23. return rest_.back();
  24. }
  25. }
  26. boost::mysql::row_view boost::mysql::detail::results_impl::get_out_params() const noexcept
  27. {
  28. BOOST_ASSERT(is_complete());
  29. for (std::size_t i = 0; i < per_result_.size(); ++i)
  30. {
  31. if (per_result_[i].is_out_params)
  32. {
  33. auto res = get_rows(i);
  34. return res.empty() ? row_view() : res[0];
  35. }
  36. }
  37. return row_view();
  38. }
  39. void boost::mysql::detail::results_impl::reset_impl() noexcept
  40. {
  41. meta_.clear();
  42. per_result_.clear();
  43. info_.clear();
  44. rows_.clear();
  45. num_fields_at_batch_start_ = no_batch;
  46. }
  47. void boost::mysql::detail::results_impl::on_num_meta_impl(std::size_t num_columns)
  48. {
  49. auto& resultset_data = add_resultset();
  50. meta_.reserve(meta_.size() + num_columns);
  51. resultset_data.num_columns = num_columns;
  52. }
  53. boost::mysql::error_code boost::mysql::detail::results_impl::
  54. on_head_ok_packet_impl(const ok_view& pack, diagnostics&)
  55. {
  56. add_resultset();
  57. on_ok_packet_impl(pack);
  58. return error_code();
  59. }
  60. boost::mysql::error_code boost::mysql::detail::results_impl::
  61. on_meta_impl(const coldef_view& coldef, bool, diagnostics&)
  62. {
  63. meta_.push_back(create_meta(coldef));
  64. return error_code();
  65. }
  66. boost::mysql::error_code boost::mysql::detail::results_impl::
  67. on_row_impl(span<const std::uint8_t> msg, const output_ref&, std::vector<field_view>&)
  68. {
  69. BOOST_ASSERT(has_active_batch());
  70. // add row storage
  71. std::size_t num_fields = current_resultset().num_columns;
  72. span<field_view> storage = rows_.add_fields(num_fields);
  73. ++current_resultset().num_rows;
  74. // deserialize the row
  75. auto err = deserialize_row(encoding(), msg, current_resultset_meta(), storage);
  76. if (err)
  77. return err;
  78. return error_code();
  79. }
  80. boost::mysql::error_code boost::mysql::detail::results_impl::on_row_ok_packet_impl(const ok_view& pack)
  81. {
  82. on_ok_packet_impl(pack);
  83. return error_code();
  84. }
  85. void boost::mysql::detail::results_impl::on_row_batch_start_impl()
  86. {
  87. BOOST_ASSERT(!has_active_batch());
  88. num_fields_at_batch_start_ = rows_.fields().size();
  89. }
  90. void boost::mysql::detail::results_impl::on_row_batch_finish_impl() { finish_batch(); }
  91. void boost::mysql::detail::results_impl::finish_batch()
  92. {
  93. if (has_active_batch())
  94. {
  95. rows_.copy_strings_as_offsets(
  96. num_fields_at_batch_start_,
  97. rows_.fields().size() - num_fields_at_batch_start_
  98. );
  99. num_fields_at_batch_start_ = no_batch;
  100. }
  101. }
  102. boost::mysql::detail::per_resultset_data& boost::mysql::detail::results_impl::add_resultset()
  103. {
  104. // Allocate a new per-resultset object
  105. auto& resultset_data = per_result_.emplace_back();
  106. resultset_data.meta_offset = meta_.size();
  107. resultset_data.field_offset = rows_.fields().size();
  108. resultset_data.info_offset = info_.size();
  109. return resultset_data;
  110. }
  111. void boost::mysql::detail::results_impl::on_ok_packet_impl(const ok_view& pack)
  112. {
  113. auto& resultset_data = current_resultset();
  114. resultset_data.affected_rows = pack.affected_rows;
  115. resultset_data.last_insert_id = pack.last_insert_id;
  116. resultset_data.warnings = pack.warnings;
  117. resultset_data.info_size = pack.info.size();
  118. resultset_data.has_ok_packet_data = true;
  119. resultset_data.is_out_params = pack.is_out_params();
  120. info_.insert(info_.end(), pack.info.begin(), pack.info.end());
  121. if (!pack.more_results())
  122. {
  123. finish_batch();
  124. rows_.offsets_to_string_views();
  125. }
  126. }
  127. #endif