File indexing completed on 2025-12-28 09:28:32
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_MYSQL_DETAIL_EXECUTION_PROCESSOR_RESULTS_IMPL_HPP
0009 #define BOOST_MYSQL_DETAIL_EXECUTION_PROCESSOR_RESULTS_IMPL_HPP
0010
0011 #include <boost/mysql/diagnostics.hpp>
0012 #include <boost/mysql/error_code.hpp>
0013 #include <boost/mysql/field_view.hpp>
0014 #include <boost/mysql/metadata.hpp>
0015 #include <boost/mysql/metadata_collection_view.hpp>
0016 #include <boost/mysql/rows_view.hpp>
0017 #include <boost/mysql/string_view.hpp>
0018
0019 #include <boost/mysql/detail/config.hpp>
0020 #include <boost/mysql/detail/execution_processor/execution_processor.hpp>
0021 #include <boost/mysql/detail/row_impl.hpp>
0022
0023 #include <boost/assert.hpp>
0024
0025 namespace boost {
0026 namespace mysql {
0027 namespace detail {
0028
0029 struct per_resultset_data
0030 {
0031 std::size_t num_columns{};
0032 std::size_t meta_offset{};
0033 std::size_t field_offset;
0034 std::size_t num_rows{};
0035 std::uint64_t affected_rows{};
0036 std::uint64_t last_insert_id{};
0037 std::uint16_t warnings{};
0038 std::size_t info_offset{};
0039 std::size_t info_size{};
0040 bool has_ok_packet_data{false};
0041 bool is_out_params{false};
0042 };
0043
0044
0045 class resultset_container
0046 {
0047 bool first_has_data_{false};
0048 per_resultset_data first_;
0049 std::vector<per_resultset_data> rest_;
0050
0051 public:
0052 resultset_container() = default;
0053 std::size_t size() const noexcept { return !first_has_data_ ? 0 : rest_.size() + 1; }
0054 bool empty() const noexcept { return !first_has_data_; }
0055 void clear() noexcept
0056 {
0057 first_has_data_ = false;
0058 rest_.clear();
0059 }
0060 per_resultset_data& operator[](std::size_t i) noexcept
0061 {
0062 return const_cast<per_resultset_data&>(const_cast<const resultset_container&>(*this)[i]);
0063 }
0064 const per_resultset_data& operator[](std::size_t i) const noexcept
0065 {
0066 BOOST_ASSERT(i < size());
0067 return i == 0 ? first_ : rest_[i - 1];
0068 }
0069 per_resultset_data& back() noexcept
0070 {
0071 return const_cast<per_resultset_data&>(const_cast<const resultset_container&>(*this).back());
0072 }
0073 const per_resultset_data& back() const noexcept
0074 {
0075 BOOST_ASSERT(first_has_data_);
0076 return rest_.empty() ? first_ : rest_.back();
0077 }
0078 BOOST_MYSQL_DECL per_resultset_data& emplace_back();
0079 };
0080
0081
0082
0083
0084
0085
0086
0087
0088 class results_impl final : public execution_processor
0089 {
0090 public:
0091 results_impl() = default;
0092
0093 BOOST_MYSQL_DECL
0094 row_view get_out_params() const noexcept;
0095
0096 std::size_t num_resultsets() const noexcept { return per_result_.size(); }
0097
0098 rows_view get_rows(std::size_t index) const noexcept
0099 {
0100 const auto& resultset_data = per_result_[index];
0101 return access::construct<rows_view>(
0102 rows_.fields().data() + resultset_data.field_offset,
0103 resultset_data.num_rows * resultset_data.num_columns,
0104 resultset_data.num_columns
0105 );
0106 }
0107
0108 metadata_collection_view get_meta(std::size_t index) const noexcept
0109 {
0110 const auto& resultset_data = get_resultset(index);
0111 return metadata_collection_view(
0112 meta_.data() + resultset_data.meta_offset,
0113 resultset_data.num_columns
0114 );
0115 }
0116
0117 std::uint64_t get_affected_rows(std::size_t index) const noexcept
0118 {
0119 return get_resultset(index).affected_rows;
0120 }
0121
0122 std::uint64_t get_last_insert_id(std::size_t index) const noexcept
0123 {
0124 return get_resultset(index).last_insert_id;
0125 }
0126
0127 unsigned get_warning_count(std::size_t index) const noexcept { return get_resultset(index).warnings; }
0128
0129 string_view get_info(std::size_t index) const noexcept
0130 {
0131 const auto& resultset_data = get_resultset(index);
0132 return string_view(info_.data() + resultset_data.info_offset, resultset_data.info_size);
0133 }
0134
0135 bool get_is_out_params(std::size_t index) const noexcept { return get_resultset(index).is_out_params; }
0136
0137 results_impl& get_interface() noexcept { return *this; }
0138
0139 private:
0140
0141 BOOST_MYSQL_DECL
0142 void reset_impl() noexcept override final;
0143
0144 BOOST_MYSQL_DECL
0145 void on_num_meta_impl(std::size_t num_columns) override final;
0146
0147 BOOST_MYSQL_DECL
0148 error_code on_head_ok_packet_impl(const ok_view& pack, diagnostics&) override final;
0149
0150 BOOST_MYSQL_DECL
0151 error_code on_meta_impl(const coldef_view&, bool, diagnostics&) override final;
0152
0153 BOOST_MYSQL_DECL
0154 error_code on_row_impl(span<const std::uint8_t> msg, const output_ref&, std::vector<field_view>&)
0155 override final;
0156
0157 BOOST_MYSQL_DECL
0158 error_code on_row_ok_packet_impl(const ok_view& pack) override final;
0159
0160 BOOST_MYSQL_DECL
0161 void on_row_batch_start_impl() override final;
0162
0163 BOOST_MYSQL_DECL
0164 void on_row_batch_finish_impl() override final;
0165
0166
0167 std::vector<metadata> meta_;
0168 resultset_container per_result_;
0169 std::vector<char> info_;
0170 row_impl rows_;
0171 std::size_t num_fields_at_batch_start_{no_batch};
0172
0173
0174 static BOOST_INLINE_CONSTEXPR std::size_t no_batch = std::size_t(-1);
0175
0176 bool has_active_batch() const noexcept { return num_fields_at_batch_start_ != no_batch; }
0177
0178 BOOST_MYSQL_DECL
0179 void finish_batch();
0180
0181 per_resultset_data& current_resultset() noexcept
0182 {
0183 BOOST_ASSERT(!per_result_.empty());
0184 return per_result_.back();
0185 }
0186
0187 const per_resultset_data& current_resultset() const noexcept
0188 {
0189 BOOST_ASSERT(!per_result_.empty());
0190 return per_result_.back();
0191 }
0192
0193 BOOST_MYSQL_DECL
0194 per_resultset_data& add_resultset();
0195
0196 BOOST_MYSQL_DECL
0197 void on_ok_packet_impl(const ok_view& pack);
0198
0199 const per_resultset_data& get_resultset(std::size_t index) const noexcept
0200 {
0201 BOOST_ASSERT(index < per_result_.size());
0202 return per_result_[index];
0203 }
0204
0205 metadata_collection_view current_resultset_meta() const noexcept
0206 {
0207 return get_meta(per_result_.size() - 1);
0208 }
0209 };
0210
0211 }
0212 }
0213 }
0214
0215 #ifdef BOOST_MYSQL_HEADER_ONLY
0216 #include <boost/mysql/impl/results_impl.ipp>
0217 #endif
0218
0219 #endif