File indexing completed on 2025-11-08 09:50:32
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_MYSQL_IMPL_INTERNAL_SANSIO_READ_RESULTSET_HEAD_HPP
0009 #define BOOST_MYSQL_IMPL_INTERNAL_SANSIO_READ_RESULTSET_HEAD_HPP
0010
0011 #include <boost/mysql/diagnostics.hpp>
0012 #include <boost/mysql/error_code.hpp>
0013
0014 #include <boost/mysql/detail/algo_params.hpp>
0015 #include <boost/mysql/detail/execution_processor/execution_processor.hpp>
0016 #include <boost/mysql/detail/next_action.hpp>
0017
0018 #include <boost/mysql/impl/internal/coroutine.hpp>
0019 #include <boost/mysql/impl/internal/sansio/connection_state_data.hpp>
0020
0021 namespace boost {
0022 namespace mysql {
0023 namespace detail {
0024
0025 inline error_code process_execution_response(
0026 connection_state_data& st,
0027 execution_processor& proc,
0028 span<const std::uint8_t> msg,
0029 diagnostics& diag
0030 )
0031 {
0032 auto response = deserialize_execute_response(msg, st.flavor, diag);
0033 error_code err;
0034 switch (response.type)
0035 {
0036 case execute_response::type_t::error: err = response.data.err; break;
0037 case execute_response::type_t::ok_packet:
0038 st.backslash_escapes = response.data.ok_pack.backslash_escapes();
0039 err = proc.on_head_ok_packet(response.data.ok_pack, diag);
0040 break;
0041 case execute_response::type_t::num_fields: proc.on_num_meta(response.data.num_fields); break;
0042 }
0043 return err;
0044 }
0045
0046 inline error_code process_field_definition(
0047 execution_processor& proc,
0048 span<const std::uint8_t> msg,
0049 diagnostics& diag
0050 )
0051 {
0052
0053 coldef_view coldef{};
0054 auto err = deserialize_column_definition(msg, coldef);
0055 if (err)
0056 return err;
0057
0058
0059 return proc.on_meta(coldef, diag);
0060 }
0061
0062 class read_resultset_head_algo
0063 {
0064 execution_processor* proc_;
0065 bool is_top_level_;
0066
0067 struct state_t
0068 {
0069 int resume_point{0};
0070 } state_;
0071
0072
0073
0074 void maybe_set_status_ready(connection_state_data& st) const
0075 {
0076 if (is_top_level_)
0077 st.status = connection_status::ready;
0078 }
0079
0080 public:
0081 read_resultset_head_algo(read_resultset_head_algo_params params, bool is_top_level = true) noexcept
0082 : proc_(params.proc), is_top_level_(is_top_level)
0083 {
0084 }
0085
0086 void reset() { state_ = state_t{}; }
0087
0088 execution_processor& processor() { return *proc_; }
0089
0090 next_action resume(connection_state_data& st, diagnostics& diag, error_code ec)
0091 {
0092 switch (state_.resume_point)
0093 {
0094 case 0:
0095
0096
0097 if (!proc_->is_reading_head())
0098 return next_action();
0099
0100
0101 if (is_top_level_)
0102 {
0103 ec = st.check_status_multi_function();
0104 if (ec)
0105 return ec;
0106 }
0107
0108
0109 BOOST_MYSQL_YIELD(state_.resume_point, 1, st.read(proc_->sequence_number()))
0110 if (ec)
0111 {
0112 maybe_set_status_ready(st);
0113 return ec;
0114 }
0115
0116
0117
0118 ec = process_execution_response(st, *proc_, st.reader.message(), diag);
0119 if (ec)
0120 {
0121 maybe_set_status_ready(st);
0122 return ec;
0123 }
0124
0125
0126 while (proc_->is_reading_meta())
0127 {
0128
0129 BOOST_MYSQL_YIELD(state_.resume_point, 2, st.read(proc_->sequence_number()))
0130 if (ec)
0131 {
0132 maybe_set_status_ready(st);
0133 return ec;
0134 }
0135
0136
0137 ec = process_field_definition(*proc_, st.reader.message(), diag);
0138 if (ec)
0139 {
0140 maybe_set_status_ready(st);
0141 return ec;
0142 }
0143 }
0144
0145
0146
0147
0148 if (proc_->is_complete() && is_top_level_)
0149 st.status = connection_status::ready;
0150 }
0151
0152 return next_action();
0153 }
0154 };
0155
0156 }
0157 }
0158 }
0159
0160 #endif