diff --git a/TODO.txt b/TODO.txt index 97217f79..b961d52d 100644 --- a/TODO.txt +++ b/TODO.txt @@ -3,8 +3,6 @@ Sanitize Connection connect Close/quit to channel Integration test for network errors (e.g. host unreachable) - Change read_row_result async signature to use error_info* - Replace yields by asio macros Better docs Wandbox Breaking up the tutorial in pieces diff --git a/include/boost/mysql/detail/network_algorithms/impl/close_connection.hpp b/include/boost/mysql/detail/network_algorithms/impl/close_connection.hpp index ba8c4972..a10a7283 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/close_connection.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/close_connection.hpp @@ -9,7 +9,6 @@ #define INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_CLOSE_CONNECTION_HPP_ #include "boost/mysql/detail/network_algorithms/quit_connection.hpp" -#include namespace boost { namespace mysql { @@ -69,17 +68,17 @@ boost::mysql::detail::async_close_connection( ) { error_code close_err; - reenter(*this) + BOOST_ASIO_CORO_REENTER(*this) { if (!this->get_channel().next_layer().is_open()) { this->complete(cont, error_code()); - yield break; + BOOST_ASIO_CORO_YIELD break; } // We call close regardless of the quit outcome // There are no async versions of shutdown or close - yield async_quit_connection( + BOOST_ASIO_CORO_YIELD async_quit_connection( this->get_channel(), std::move(*this), this->get_output_info() @@ -93,7 +92,5 @@ boost::mysql::detail::async_close_connection( return op::initiate(std::forward(token), chan, info); } -#include - #endif /* INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_CLOSE_CONNECTION_HPP_ */ diff --git a/include/boost/mysql/detail/network_algorithms/impl/execute_generic.hpp b/include/boost/mysql/detail/network_algorithms/impl/execute_generic.hpp index a0d63788..4b7dc8b9 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/execute_generic.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/execute_generic.hpp @@ -8,7 +8,6 @@ #ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_EXECUTE_GENERIC_HPP #define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_EXECUTE_GENERIC_HPP -#include #include namespace boost { @@ -232,13 +231,13 @@ boost::mysql::detail::async_execute_generic( // Non-error path error_info info; - reenter(*this) + BOOST_ASIO_CORO_REENTER(*this) { // The request message has already been composed in the ctor. Send it - yield this->async_write(processor_->get_buffer()); + BOOST_ASIO_CORO_YIELD this->async_write(processor_->get_buffer()); // Read the response - yield this->async_read(processor_->get_buffer()); + BOOST_ASIO_CORO_YIELD this->async_read(processor_->get_buffer()); // Response may be: ok_packet, err_packet, local infile request (not implemented), or response with fields processor_->process_response(err, info); @@ -246,7 +245,7 @@ boost::mysql::detail::async_execute_generic( { conditional_assign(this->get_output_info(), std::move(info)); this->complete(cont, err, resultset_type()); - yield break; + BOOST_ASIO_CORO_YIELD break; } remaining_fields_ = processor_->field_count(); @@ -254,14 +253,14 @@ boost::mysql::detail::async_execute_generic( while (remaining_fields_ > 0) { // Read the field definition packet - yield this->async_read(processor_->get_buffer()); + BOOST_ASIO_CORO_YIELD this->async_read(processor_->get_buffer()); // Process the message err = processor_->process_field_definition(); if (err) { this->complete(cont, err, resultset_type()); - yield break; + BOOST_ASIO_CORO_YIELD break; } remaining_fields_--; @@ -281,6 +280,5 @@ boost::mysql::detail::async_execute_generic( chan, info, deserializer, request); } -#include #endif /* INCLUDE_MYSQL_IMPL_NETWORK_ALGORITHMS_READ_RESULTSET_HEAD_IPP_ */ diff --git a/include/boost/mysql/detail/network_algorithms/impl/execute_query.hpp b/include/boost/mysql/detail/network_algorithms/impl/execute_query.hpp index f2f99b8c..cd7df7f3 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/execute_query.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/execute_query.hpp @@ -54,7 +54,5 @@ boost::mysql::detail::async_execute_query( ); } -#include - #endif /* INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_EXECUTE_QUERY_HPP_ */ diff --git a/include/boost/mysql/detail/network_algorithms/impl/handshake.hpp b/include/boost/mysql/detail/network_algorithms/impl/handshake.hpp index 0f31a731..c53498fb 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/handshake.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/handshake.hpp @@ -12,7 +12,6 @@ #include "boost/mysql/detail/protocol/capabilities.hpp" #include "boost/mysql/detail/protocol/handshake_messages.hpp" #include "boost/mysql/detail/auth/auth_calculator.hpp" -#include namespace boost { namespace mysql { @@ -345,17 +344,17 @@ boost::mysql::detail::async_handshake( // Non-error path error_info info; - reenter(*this) + BOOST_ASIO_CORO_REENTER(*this) { // Read server greeting - yield this->async_read(); + BOOST_ASIO_CORO_YIELD this->async_read(); // Process server greeting err = processor_.process_handshake(this->get_channel().shared_buffer(), info); if (err) { complete(cont, err, std::move(info)); - yield break; + BOOST_ASIO_CORO_YIELD break; } // SSL @@ -363,20 +362,20 @@ boost::mysql::detail::async_handshake( { // Send SSL request processor_.compose_ssl_request(this->get_channel().shared_buffer()); - yield this->async_write(); + BOOST_ASIO_CORO_YIELD this->async_write(); // SSL handshake - yield this->get_channel().async_ssl_handshake(std::move(*this)); + BOOST_ASIO_CORO_YIELD this->get_channel().async_ssl_handshake(std::move(*this)); } // Compose and send handshake response processor_.compose_handshake_response(this->get_channel().shared_buffer()); - yield this->async_write(); + BOOST_ASIO_CORO_YIELD this->async_write(); while (auth_state_ != auth_result::complete) { // Receive response - yield this->async_read(); + BOOST_ASIO_CORO_YIELD this->async_read(); // Process it err = processor_.process_handshake_server_response( @@ -387,13 +386,13 @@ boost::mysql::detail::async_handshake( if (err) { complete(cont, err, std::move(info)); - yield break; + BOOST_ASIO_CORO_YIELD break; } if (auth_state_ == auth_result::send_more_data) { // We received an auth switch response and we have the response ready to be sent - yield this->async_write(); + BOOST_ASIO_CORO_YIELD this->async_write(); } } @@ -405,7 +404,5 @@ boost::mysql::detail::async_handshake( return op::initiate(std::forward(token), chan, info, params); } -#include - #endif diff --git a/include/boost/mysql/detail/network_algorithms/impl/prepare_statement.hpp b/include/boost/mysql/detail/network_algorithms/impl/prepare_statement.hpp index 0d0d1faa..83a10daa 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/prepare_statement.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/prepare_statement.hpp @@ -8,8 +8,6 @@ #ifndef BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_PREPARE_STATEMENT_HPP #define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_PREPARE_STATEMENT_HPP -#include - namespace boost { namespace mysql { namespace detail { @@ -148,13 +146,13 @@ boost::mysql::detail::async_prepare_statement( // Regular coroutine body; if there has been an error, we don't get here error_info info; - reenter(*this) + BOOST_ASIO_CORO_REENTER(*this) { // Write message (already serialized at this point) - yield this->async_write(processor_.get_buffer()); + BOOST_ASIO_CORO_YIELD this->async_write(processor_.get_buffer()); // Read response - yield this->async_read(processor_.get_buffer()); + BOOST_ASIO_CORO_YIELD this->async_read(processor_.get_buffer()); // Process response processor_.process_response(err, info); @@ -162,7 +160,7 @@ boost::mysql::detail::async_prepare_statement( { detail::conditional_assign(this->get_output_info(), std::move(info)); this->complete(cont, err, stmt_type()); - yield break; + BOOST_ASIO_CORO_YIELD break; } // Server sends now one packet per parameter and field. @@ -170,7 +168,7 @@ boost::mysql::detail::async_prepare_statement( remaining_meta_ = processor_.get_num_metadata_packets(); for (; remaining_meta_ > 0; --remaining_meta_) { - yield this->async_read(processor_.get_buffer()); + BOOST_ASIO_CORO_YIELD this->async_read(processor_.get_buffer()); } // Compose response @@ -186,6 +184,4 @@ boost::mysql::detail::async_prepare_statement( return op::initiate(std::forward(token), chan, info, statement); } -#include - #endif /* INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_PREPARE_STATEMENT_HPP_ */ diff --git a/include/boost/mysql/detail/network_algorithms/impl/read_row.hpp b/include/boost/mysql/detail/network_algorithms/impl/read_row.hpp index 2c74dd55..9a5a5529 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/read_row.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/read_row.hpp @@ -9,7 +9,6 @@ #define BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_IMPL_READ_ROW_HPP #include "boost/mysql/detail/protocol/text_deserialization.hpp" -#include namespace boost { namespace mysql { @@ -102,7 +101,8 @@ boost::mysql::detail::async_read_row( bytestring& buffer, std::vector& output_values, ok_packet& output_ok_packet, - CompletionToken&& token + CompletionToken&& token, + error_info* output_info ) { struct op : async_op @@ -143,15 +143,15 @@ boost::mysql::detail::async_read_row( // Error checking if (err) { - this->complete(cont, err, info, result); + this->complete(cont, err, result); return; } // Normal path - reenter(*this) + BOOST_ASIO_CORO_REENTER(*this) { // Read the message - yield this->async_read(buffer_); + BOOST_ASIO_CORO_YIELD this->async_read(buffer_); // Process it result = process_read_message( @@ -164,7 +164,8 @@ boost::mysql::detail::async_read_row( err, info ); - this->complete(cont, err, std::move(info), result); + detail::conditional_assign(this->get_output_info(), std::move(info)); + this->complete(cont, err, result); } } }; @@ -172,7 +173,7 @@ boost::mysql::detail::async_read_row( return op::initiate( std::forward(token), chan, - nullptr, // no output error_info* + output_info, deserializer, meta, buffer, @@ -181,6 +182,4 @@ boost::mysql::detail::async_read_row( ); } -#include - #endif /* INCLUDE_MYSQL_IMPL_NETWORK_ALGORITHMS_READ_TEXT_ROW_IPP_ */ diff --git a/include/boost/mysql/detail/network_algorithms/read_row.hpp b/include/boost/mysql/detail/network_algorithms/read_row.hpp index be2572a4..38bf3897 100644 --- a/include/boost/mysql/detail/network_algorithms/read_row.hpp +++ b/include/boost/mysql/detail/network_algorithms/read_row.hpp @@ -36,7 +36,7 @@ read_row_result read_row( error_info& info ); -using read_row_signature = void(error_code, error_info, read_row_result); +using read_row_signature = void(error_code, read_row_result); template BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, read_row_signature) @@ -47,7 +47,8 @@ async_read_row( bytestring& buffer, std::vector& output_values, ok_packet& output_ok_packet, - CompletionToken&& token + CompletionToken&& token, + error_info* output_info ); diff --git a/include/boost/mysql/detail/protocol/impl/channel.hpp b/include/boost/mysql/detail/protocol/impl/channel.hpp index a0aff661..1c35cd44 100644 --- a/include/boost/mysql/detail/protocol/impl/channel.hpp +++ b/include/boost/mysql/detail/protocol/impl/channel.hpp @@ -14,7 +14,6 @@ #include "boost/mysql/detail/protocol/common_messages.hpp" #include "boost/mysql/detail/protocol/constants.hpp" #include "boost/mysql/detail/auxiliar/valgrind.hpp" -#include namespace boost { namespace mysql { @@ -270,11 +269,11 @@ boost::mysql::detail::channel::async_read( // Non-error path std::uint32_t size_to_read = 0; channel& chan = this->get_channel(); - reenter(*this) + BOOST_ASIO_CORO_REENTER(*this) { do { - yield chan.async_read_impl( + BOOST_ASIO_CORO_YIELD chan.async_read_impl( boost::asio::buffer(chan.header_buffer_), std::move(*this) ); @@ -284,12 +283,12 @@ boost::mysql::detail::channel::async_read( if (code) { this->complete(cont, code); - yield break; + BOOST_ASIO_CORO_YIELD break; } buffer_.resize(buffer_.size() + size_to_read); - yield chan.async_read_impl( + BOOST_ASIO_CORO_YIELD chan.async_read_impl( boost::asio::buffer(buffer_.data() + total_transferred_size_, size_to_read), std::move(*this) ); @@ -352,7 +351,7 @@ boost::mysql::detail::channel::async_write( // Non-error path std::uint32_t size_to_write; channel& chan = this->get_channel(); - reenter(*this) + BOOST_ASIO_CORO_REENTER(*this) { // Force write the packet header on an empty packet, at least. do @@ -360,7 +359,7 @@ boost::mysql::detail::channel::async_write( size_to_write = compute_size_to_write(buffer_.size(), total_transferred_size_); chan.process_header_write(size_to_write); - yield chan.async_write_impl( + BOOST_ASIO_CORO_YIELD chan.async_write_impl( std::array { boost::asio::buffer(chan.header_buffer_), boost::asio::buffer(buffer_ + total_transferred_size_, size_to_write) @@ -408,7 +407,4 @@ boost::mysql::detail::channel::async_ssl_handshake( } -#include - - #endif diff --git a/include/boost/mysql/impl/resultset.hpp b/include/boost/mysql/impl/resultset.hpp index e266e8b9..5916bc0b 100644 --- a/include/boost/mysql/impl/resultset.hpp +++ b/include/boost/mysql/impl/resultset.hpp @@ -13,7 +13,6 @@ #include #include #include -#include template const boost::mysql::row* boost::mysql::resultset::fetch_one( @@ -134,10 +133,6 @@ boost::mysql::resultset::async_fetch_one( error_info* info ) { - assert(valid()); - detail::conditional_clear(info); - detail::check_completion_token(); - struct op: detail::async_op { resultset& resultset_; @@ -155,29 +150,28 @@ boost::mysql::resultset::async_fetch_one( void operator()( error_code err, - error_info info={}, detail::read_row_result result=detail::read_row_result::error, bool cont=true ) { - reenter(*this) + BOOST_ASIO_CORO_REENTER(*this) { if (resultset_.complete()) { this->complete(cont, error_code(), nullptr); - yield break; + BOOST_ASIO_CORO_YIELD break; } - yield detail::async_read_row( + BOOST_ASIO_CORO_YIELD detail::async_read_row( resultset_.deserializer_, *resultset_.channel_, resultset_.meta_.fields(), resultset_.buffer_, resultset_.current_row_.values(), resultset_.ok_packet_, - std::move(*this) + std::move(*this), + this->get_output_info() ); resultset_.eof_received_ = result == detail::read_row_result::eof; - detail::conditional_assign(this->get_output_info(), std::move(info)); this->complete( cont, err, @@ -187,6 +181,9 @@ boost::mysql::resultset::async_fetch_one( } }; + assert(valid()); + detail::conditional_clear(info); + detail::check_completion_token(); return op::initiate(std::forward(token), *channel_, info, *this); } @@ -202,10 +199,6 @@ boost::mysql::resultset::async_fetch_many( error_info* info ) { - assert(valid()); - detail::conditional_clear(info); - detail::check_completion_token(); - struct op_impl { resultset& parent_resultset; @@ -248,29 +241,28 @@ boost::mysql::resultset::async_fetch_many( void operator()( error_code err, - error_info info={}, detail::read_row_result result=detail::read_row_result::error, bool cont=true ) { - reenter(*this) + BOOST_ASIO_CORO_REENTER(*this) { while (!impl_->parent_resultset.complete() && impl_->remaining > 0) { - yield detail::async_read_row( + BOOST_ASIO_CORO_YIELD detail::async_read_row( impl_->parent_resultset.deserializer_, this->get_channel(), impl_->parent_resultset.meta_.fields(), impl_->buffer, impl_->values, impl_->parent_resultset.ok_packet_, - std::move(*this) + std::move(*this), + this->get_output_info() ); if (result == detail::read_row_result::error) { - detail::conditional_assign(this->get_output_info(), std::move(info)); this->complete(cont, err, std::move(impl_->rows)); - yield break; + BOOST_ASIO_CORO_YIELD break; } else if (result == detail::read_row_result::eof) { @@ -286,6 +278,9 @@ boost::mysql::resultset::async_fetch_many( } }; + assert(valid()); + detail::conditional_clear(info); + detail::check_completion_token(); return op::initiate(std::forward(token), *channel_, info, *this, count); } @@ -308,7 +303,4 @@ boost::mysql::resultset::async_fetch_all( } -#include - - #endif