diff --git a/README.md b/README.md index e5057d64..5402d737 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,7 @@ Linux/OSX | Windows | Coverage -----------|---------|---------- -[![Build Status](https://travis-ci.com/anarthal/mysql-asio.png?branch=master)](https://github.com/anarthal/mysql-asio) | -[![Build status](https://ci.appveyor.com/api/projects/status/slqnb8mt91v33p1y/branch/master?svg=true)](https://ci.appveyor.com/project/anarthal/mysql-asio/branch/master) | -[![codecov](https://img.shields.io/codecov/c/github/anarthal/mysql-asio/master.svg)](https://codecov.io/gh/anarthal/mysql-asio/branch/master) +[![Build Status](https://travis-ci.com/anarthal/mysql-asio.png?branch=master)](https://github.com/anarthal/mysql-asio) | [![Build status](https://ci.appveyor.com/api/projects/status/slqnb8mt91v33p1y/branch/master?svg=true)](https://ci.appveyor.com/project/anarthal/mysql-asio/branch/master) | [![codecov](https://img.shields.io/codecov/c/github/anarthal/mysql-asio/master.svg)](https://codecov.io/gh/anarthal/mysql-asio/branch/master) Boost.MySQL (former MySQL.Asio) is a C++17 client for the MySQL database server, based on Boost.Asio. This library is in the process of being proposed for Boost. diff --git a/TODO.txt b/TODO.txt index 38cb2576..760e9895 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,6 +1,13 @@ Sanitize Test zero dates Connection quit + Serialization test for quit message + Connection close + Integ test for close + Make integ tests do quit/close when possible + Quit docs + Close docs + clear_errors() function to clear error_info and error_code at once Better docs Breaking up the tutorial in pieces Explaining the different overloads and async methods available @@ -42,7 +49,6 @@ Technical debt Review convention in test names Review named_param Take fetch_many() algorithm out into network_algorithms (e.g. read_many_rows) - clear_errors() function to clear error_info and error_code at once Concept checking for StreamType Review async initiations See if async_initiate is applicable diff --git a/include/boost/mysql/connection.hpp b/include/boost/mysql/connection.hpp index b722eede..b493d97c 100644 --- a/include/boost/mysql/connection.hpp +++ b/include/boost/mysql/connection.hpp @@ -163,6 +163,15 @@ public: template BOOST_MYSQL_INITFN_RESULT_TYPE(CompletionToken, prepare_statement_signature) async_prepare_statement(std::string_view statement, CompletionToken&& token, error_info* info=nullptr); + + void quit(error_code&, error_info&); + void quit(); + + using quit_signature = void(error_code); + + template + BOOST_MYSQL_INITFN_RESULT_TYPE(CompletionToken, quit_signature) + async_quit(CompletionToken&& token, error_info* info=nullptr); }; /** diff --git a/include/boost/mysql/detail/network_algorithms/quit_connection.hpp b/include/boost/mysql/detail/network_algorithms/quit_connection.hpp new file mode 100644 index 00000000..1447b1b0 --- /dev/null +++ b/include/boost/mysql/detail/network_algorithms/quit_connection.hpp @@ -0,0 +1,60 @@ +// +// Copyright (c) 2019-2020 Ruben Perez Hidalgo (rubenperez038 at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_QUIT_CONNECTION_HPP_ +#define INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_QUIT_CONNECTION_HPP_ + +#include "boost/mysql/detail/network_algorithms/common.hpp" + +namespace boost { +namespace mysql { +namespace detail { + +template +void compose_quit( + channel& chan +) +{ + serialize_message( + quit_packet(), + chan.current_capabilities(), + chan.shared_buffer() + ); + chan.reset_sequence_number(); +} + +template +void quit_connection( + channel& chan, + error_code& code, + error_info& +) +{ + compose_quit(chan); + chan.write(boost::asio::buffer(chan.shared_buffer()), code); +} + +using quit_connection_signature = empty_signature; + +template +BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, quit_connection_signature) +async_quit_connection( + channel& chan, + CompletionToken&& token, + error_info* +) +{ + compose_quit(chan); + return chan.async_write(boost::asio::buffer(chan.shared_buffer()), std::forward(token)); +} + +} // detail +} // mysql +} // boost + + +#endif /* INCLUDE_BOOST_MYSQL_DETAIL_NETWORK_ALGORITHMS_QUIT_CONNECTION_HPP_ */ diff --git a/include/boost/mysql/detail/protocol/channel.hpp b/include/boost/mysql/detail/protocol/channel.hpp index 720ef590..c1f31de2 100644 --- a/include/boost/mysql/detail/protocol/channel.hpp +++ b/include/boost/mysql/detail/protocol/channel.hpp @@ -102,8 +102,6 @@ public: bytestring& shared_buffer() noexcept { return shared_buff_; } }; -template -using channel_stream_type = typename ChannelType::stream_type; } // detail } // mysql diff --git a/include/boost/mysql/detail/protocol/common_messages.hpp b/include/boost/mysql/detail/protocol/common_messages.hpp index 1aae337c..f2428eb4 100644 --- a/include/boost/mysql/detail/protocol/common_messages.hpp +++ b/include/boost/mysql/detail/protocol/common_messages.hpp @@ -126,6 +126,18 @@ struct serialization_traits +struct get_struct_fields +{ + static constexpr auto value = std::make_tuple(); +}; + // aux inline error_code process_error_packet(deserialization_context& ctx, error_info& info); diff --git a/include/boost/mysql/impl/connection.hpp b/include/boost/mysql/impl/connection.hpp index ce59cdac..5471016c 100644 --- a/include/boost/mysql/impl/connection.hpp +++ b/include/boost/mysql/impl/connection.hpp @@ -11,6 +11,7 @@ #include "boost/mysql/detail/network_algorithms/handshake.hpp" #include "boost/mysql/detail/network_algorithms/execute_query.hpp" #include "boost/mysql/detail/network_algorithms/prepare_statement.hpp" +#include "boost/mysql/detail/network_algorithms/quit_connection.hpp" #include "boost/mysql/detail/auxiliar/check_completion_token.hpp" #include @@ -40,7 +41,7 @@ void boost::mysql::connection::handshake( template template -BOOST_ASIO_INITFN_RESULT_TYPE( +BOOST_MYSQL_INITFN_RESULT_TYPE( CompletionToken, typename boost::mysql::connection::handshake_signature ) @@ -90,7 +91,7 @@ boost::mysql::resultset boost::mysql::connection::query( template template -BOOST_ASIO_INITFN_RESULT_TYPE( +BOOST_MYSQL_INITFN_RESULT_TYPE( CompletionToken, typename boost::mysql::connection::query_signature ) @@ -139,7 +140,7 @@ boost::mysql::prepared_statement boost::mysql::connection::prepa template template -BOOST_ASIO_INITFN_RESULT_TYPE( +BOOST_MYSQL_INITFN_RESULT_TYPE( CompletionToken, typename boost::mysql::connection::prepare_statement_signature ) @@ -159,5 +160,44 @@ boost::mysql::connection::async_prepare_statement( ); } +template +void boost::mysql::connection::quit( + error_code& err, + error_info& info +) +{ + err.clear(); + info.clear(); + detail::quit_connection(channel_, err, info); +} + +template +void boost::mysql::connection::quit() +{ + error_code err; + error_info info; + detail::quit_connection(channel_, err, info); + detail::check_error_code(err, info); +} + +template +template +BOOST_MYSQL_INITFN_RESULT_TYPE( + CompletionToken, + typename boost::mysql::connection::quit_signature +) +boost::mysql::connection::async_quit( + CompletionToken&& token, + error_info* info +) +{ + detail::conditional_clear(info); + return detail::async_quit_connection( + channel_, + std::forward(token), + info + ); +} + #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6aea5064..17484648 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -88,6 +88,7 @@ add_executable( integration/resultset.cpp integration/prepared_statement_lifecycle.cpp integration/database_types.cpp + integration/quit_connection.cpp ) target_link_libraries( mysql_integrationtests diff --git a/test/integration/network_functions.cpp b/test/integration/network_functions.cpp index f42c490d..e04658e7 100644 --- a/test/integration/network_functions.cpp +++ b/test/integration/network_functions.cpp @@ -133,6 +133,15 @@ public: return r.fetch_all(code, info); }); } + network_result quit( + connection_type& conn + ) override + { + return impl([&](error_code& code, error_info& info) { + conn.quit(code, info); + return no_result(); + }); + } }; template @@ -240,6 +249,15 @@ public: return r.fetch_all(); }); } + network_result quit( + connection_type& conn + ) override + { + return impl([&] { + conn.quit(); + return no_result(); + }); + } }; template @@ -381,6 +399,14 @@ public: return r.async_fetch_all(std::forward(token), info); }); } + network_result quit( + connection_type& conn + ) override + { + return impl([&](auto&& token, error_info* info) { + return conn.async_quit(std::forward(token), info); + }); + } }; template @@ -505,6 +531,15 @@ public: return r.async_fetch_all(yield, info); }); } + network_result quit( + connection_type& conn + ) override + { + return impl(conn, [&](yield_context yield, error_info* info) { + conn.async_quit(yield, info); + return no_result(); + }); + } }; template @@ -629,6 +664,14 @@ public: return r.async_fetch_all(use_future); }); } + network_result quit( + connection_type& conn + ) override + { + return impl_no_result([&] { + return conn.async_quit(use_future); + }); + } }; } diff --git a/test/integration/network_functions.hpp b/test/integration/network_functions.hpp index 158b4121..f3d2da6a 100644 --- a/test/integration/network_functions.hpp +++ b/test/integration/network_functions.hpp @@ -116,6 +116,7 @@ public: virtual network_result fetch_one(resultset_type&) = 0; virtual network_result> fetch_many(resultset_type&, std::size_t count) = 0; virtual network_result> fetch_all(resultset_type&) = 0; + virtual network_result quit(connection_type&) = 0; }; template diff --git a/test/integration/quit_connection.cpp b/test/integration/quit_connection.cpp new file mode 100644 index 00000000..54f2904b --- /dev/null +++ b/test/integration/quit_connection.cpp @@ -0,0 +1,38 @@ +// +// Copyright (c) 2019-2020 Ruben Perez Hidalgo (rubenperez038 at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include "integration_test_common.hpp" + +using namespace boost::mysql::test; +using boost::mysql::error_code; + +namespace +{ + +template +struct QuitConnectionTest : public NetworkTest +{ + void ActiveConnection_ClosesIt() + { + network_functions* net = this->GetParam().net; + + // Quit + auto result = net->quit(this->conn); + result.validate_no_error(); + + // We are no longer able to query + auto query_result = net->query(this->conn, "SELECT 1"); + EXPECT_NE(query_result.err, error_code()); + } +}; + +BOOST_MYSQL_NETWORK_TEST_SUITE(QuitConnectionTest) + +BOOST_MYSQL_NETWORK_TEST(QuitConnectionTest, ActiveConnection_ClosesIt) + +} // anon namespace +