diff --git a/example/metadata.cpp b/example/metadata.cpp index cb895d69..62563c4a 100644 --- a/example/metadata.cpp +++ b/example/metadata.cpp @@ -63,7 +63,7 @@ void main_impl(int argc, char** argv) */ ASSERT(result.fields().size() == 2); - const boost::mysql::field_metadata& company_name = result.fields()[0]; + const boost::mysql::metadata& company_name = result.fields()[0]; ASSERT(company_name.database() == "boost_mysql_examples"); // database name ASSERT(company_name.table() == "comp"); // the alias we assigned to the table in the query ASSERT(company_name.original_table() == "company"); // the original table name @@ -74,7 +74,7 @@ void main_impl(int argc, char** argv) ASSERT(!company_name.is_auto_increment()); // field is not AUTO_INCREMENT ASSERT(company_name.is_not_null()); // field may not be NULL - const boost::mysql::field_metadata& employee_id = result.fields()[1]; + const boost::mysql::metadata& employee_id = result.fields()[1]; ASSERT(employee_id.database() == "boost_mysql_examples"); // database name ASSERT(employee_id.table() == "emp"); // the alias we assigned to the table in the query ASSERT(employee_id.original_table() == "employee"); // the original table name diff --git a/example/query_async_callbacks.cpp b/example/query_async_callbacks.cpp index 5d19edeb..3d59c004 100644 --- a/example/query_async_callbacks.cpp +++ b/example/query_async_callbacks.cpp @@ -32,9 +32,9 @@ using boost::mysql::row; void print_employee(const boost::mysql::row& employee) { std::cout << "Employee '" - << employee.values()[0] << " " // first_name (type boost::string_view) - << employee.values()[1] << "' earns " // last_name (type boost::string_view) - << employee.values()[2] << " dollars yearly\n"; // salary (type double) + << employee.fields()[0] << " " // first_name (type boost::string_view) + << employee.fields()[1] << "' earns " // last_name (type boost::string_view) + << employee.fields()[2] << " dollars yearly\n"; // salary (type double) } void die_on_error( @@ -131,7 +131,7 @@ public: resultset.async_read_all(additional_info, [this](error_code err, const std::vector& rows) { die_on_error(err, additional_info); ASSERT(rows.size() == 1); - auto salary = rows[0].values()[0].get(); + auto salary = rows[0].fields()[0].get(); ASSERT(salary == 15000); close(); }); diff --git a/example/query_async_coroutines.cpp b/example/query_async_coroutines.cpp index eaf95cb3..ae54d819 100644 --- a/example/query_async_coroutines.cpp +++ b/example/query_async_coroutines.cpp @@ -21,9 +21,9 @@ using boost::mysql::error_info; void print_employee(const boost::mysql::row& employee) { std::cout << "Employee '" - << employee.values()[0] << " " // first_name (type boost::string_view) - << employee.values()[1] << "' earns " // last_name (type boost::string_view) - << employee.values()[2] << " dollars yearly\n"; // salary (type double) + << employee.fields()[0] << " " // first_name (type boost::string_view) + << employee.fields()[1] << "' earns " // last_name (type boost::string_view) + << employee.fields()[2] << " dollars yearly\n"; // salary (type double) } // Throws an exception if an operation failed diff --git a/example/query_async_futures.cpp b/example/query_async_futures.cpp index 22e8b670..4e67eca5 100644 --- a/example/query_async_futures.cpp +++ b/example/query_async_futures.cpp @@ -21,9 +21,9 @@ using boost::asio::use_future; void print_employee(const boost::mysql::row& employee) { std::cout << "Employee '" - << employee.values()[0] << " " // first_name (type boost::string_view) - << employee.values()[1] << "' earns " // last_name (type boost::string_view) - << employee.values()[2] << " dollars yearly\n"; // salary (type double) + << employee.fields()[0] << " " // first_name (type boost::string_view) + << employee.fields()[1] << "' earns " // last_name (type boost::string_view) + << employee.fields()[2] << " dollars yearly\n"; // salary (type double) } /** diff --git a/example/query_sync.cpp b/example/query_sync.cpp index 599474d5..63578b4d 100644 --- a/example/query_sync.cpp +++ b/example/query_sync.cpp @@ -33,9 +33,9 @@ void print_employee(const boost::mysql::row& employee) { std::cout << "Employee '" - << employee.values()[0] << " " // first_name (type boost::string_view) - << employee.values()[1] << "' earns " // last_name (type boost::string_view) - << employee.values()[2] << " dollars yearly\n"; // salary (type double) + << employee.fields()[0] << " " // first_name (type boost::string_view) + << employee.fields()[1] << "' earns " // last_name (type boost::string_view) + << employee.fields()[2] << " dollars yearly\n"; // salary (type double) } void main_impl(int argc, char** argv) diff --git a/example/ssl.cpp b/example/ssl.cpp index 69719928..4de123d9 100644 --- a/example/ssl.cpp +++ b/example/ssl.cpp @@ -48,9 +48,9 @@ OzBrmpfHEhF6NDU= void print_employee(const boost::mysql::row& employee) { std::cout << "Employee '" - << employee.values()[0] << " " // first_name (type boost::string_view) - << employee.values()[1] << "' earns " // last_name (type boost::string_view) - << employee.values()[2] << " dollars yearly\n"; // salary (type double) + << employee.fields()[0] << " " // first_name (type boost::string_view) + << employee.fields()[1] << "' earns " // last_name (type boost::string_view) + << employee.fields()[2] << " dollars yearly\n"; // salary (type double) } void main_impl(int argc, char** argv) diff --git a/example/tutorial.cpp b/example/tutorial.cpp index 7d10dd64..97db9b14 100644 --- a/example/tutorial.cpp +++ b/example/tutorial.cpp @@ -69,7 +69,7 @@ void main_impl(int argc, char** argv) //[tutorial_values const boost::mysql::row& first_row = employees.at(0); - boost::mysql::value first_value = first_row.values().at(0); + boost::mysql::field_view first_value = first_row.values().at(0); std::cout << first_value << std::endl; //] diff --git a/example/unix_socket.cpp b/example/unix_socket.cpp index 241aabc4..e9e7803c 100644 --- a/example/unix_socket.cpp +++ b/example/unix_socket.cpp @@ -16,9 +16,9 @@ void print_employee(const boost::mysql::row& employee) { std::cout << "Employee '" - << employee.values()[0] << " " // first_name (type boost::string_view) - << employee.values()[1] << "' earns " // last_name (type boost::string_view) - << employee.values()[2] << " dollars yearly\n"; // salary (type double) + << employee.fields()[0] << " " // first_name (type boost::string_view) + << employee.fields()[1] << "' earns " // last_name (type boost::string_view) + << employee.fields()[2] << " dollars yearly\n"; // salary (type double) } #define ASSERT(expr) \ diff --git a/example/value.cpp b/example/value.cpp index a75d9719..553c784d 100644 --- a/example/value.cpp +++ b/example/value.cpp @@ -5,7 +5,7 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include +#include #include #define ASSERT(expr) \ @@ -18,14 +18,14 @@ void example_get() { //[value_example_get - boost::mysql::value v ("hello"); // v contains type boost::string_view + boost::mysql::field_view v ("hello"); // v contains type boost::string_view boost::string_view typed_val = v.get(); // retrieves the underlying string ASSERT(typed_val == "hello"); try { v.get(); // wrong type! throws boost::mysql::bad_value_access } - catch (const boost::mysql::bad_value_access&) + catch (const boost::mysql::bad_field_access&) { } //] @@ -34,7 +34,7 @@ void example_get() void example_get_optional() { //[value_example_get_optional - boost::mysql::value v (3.14); // v contains type double + boost::mysql::field_view v (3.14); // v contains type double boost::optional typed_val = v.get_optional(); ASSERT(typed_val.has_value()); // the optional is not empty ASSERT(*typed_val == 3.14); // and contains the right value @@ -49,7 +49,7 @@ void example_get_optional() void example_get_std_optional() { //[value_example_get_std_optional - boost::mysql::value v (3.14); // v contains type double + boost::mysql::field_view v (3.14); // v contains type double std::optional typed_val = v.get_std_optional(); ASSERT(typed_val.has_value()); // the optional is not empty ASSERT(*typed_val == 3.14); // and contains the right value @@ -64,7 +64,7 @@ void example_get_std_optional() void example_get_conversions() { //[value_example_get_conversions - boost::mysql::value v (std::uint64_t(42)); // v contains type std::uint64_t + boost::mysql::field_view v (std::uint64_t(42)); // v contains type std::uint64_t ASSERT(v.get() == 42u); // exact type match ASSERT(v.get() == 42); // converts from std::uint64_t -> std::int64_t //] @@ -74,7 +74,7 @@ void example_inefficient() { //[value_example_inefficient // WARNING!! Inefficient, do NOT do - boost::mysql::value v (3.14); // get the value e.g. using query + boost::mysql::field_view v (3.14); // get the value e.g. using query if (v.is_convertible_to()) // it should be double, but we are not use { double val = v.get(); @@ -91,7 +91,7 @@ void example_inefficient() void example_inefficient_ok() { //[value_example_inefficient_ok - boost::mysql::value v (3.14); // get the value e.g. using query + boost::mysql::field_view v (3.14); // get the value e.g. using query boost::optional val = v.get_optional(); // it should be double, but we are not use if (val) @@ -109,7 +109,7 @@ void example_inefficient_ok() void example_is() { //[value_example_is - boost::mysql::value v (std::uint64_t(42)); // v contains type std::uint64_t + boost::mysql::field_view v (std::uint64_t(42)); // v contains type std::uint64_t ASSERT(v.is()); // exact type match ASSERT(!v.is()); // does not consider conversions ASSERT(v.is_convertible_to()); // exact type match diff --git a/include/boost/mysql/connection.hpp b/include/boost/mysql/connection.hpp index cb0db41f..c3ce7c31 100644 --- a/include/boost/mysql/connection.hpp +++ b/include/boost/mysql/connection.hpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -469,16 +468,16 @@ public: /** * \brief Executes a statement (collection, sync with error code version). * \details - * ValueCollection should meet the [reflink ValueCollection] requirements. + * FieldViewCollection should meet the [reflink FieldViewCollection] requirements. * * After this function has returned, you should read the entire resultset * before calling any function that involves communication with the server over this * connection. Otherwise, the results are undefined. */ - template > + template > void execute_statement( const prepared_statement& statement, - const ValueCollection& params, + const FieldViewCollection& params, resultset& result, error_code& err, error_info& info @@ -490,16 +489,16 @@ public: /** * \brief Executes a statement (collection, sync with exceptions version). * \details - * ValueCollection should meet the [reflink ValueCollection] requirements. + * FieldViewCollection should meet the [reflink FieldViewCollection] requirements. * * After this function has returned, you should read the entire resultset * before calling any function that involves communication with the server over this * connection. Otherwise, the results are undefined. */ - template > + template > void execute_statement( const prepared_statement& statement, - const ValueCollection& params, + const FieldViewCollection& params, resultset& result ) { @@ -510,7 +509,7 @@ public: * \brief Executes a statement (collection, * async without [reflink error_info] version). * \details - * ValueCollection should meet the [reflink ValueCollection] requirements. + * FieldViewCollection should meet the [reflink FieldViewCollection] requirements. * * After this operation completes, you should read the entire resultset * before calling any function that involves communication with the server over this @@ -522,16 +521,16 @@ public: * `void(boost::mysql::error_code, boost::mysql::resultset)`. */ template< - class ValueCollection, + class FieldViewCollection, BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type), - class EnableIf = detail::enable_if_value_collection + class EnableIf = detail::enable_if_field_view_collection > BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code)) async_execute_statement( const prepared_statement& statement, - const ValueCollection& params, + const FieldViewCollection& params, resultset& result, CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type) ) @@ -547,7 +546,7 @@ public: * \brief Executes a statement (collection, * async with [reflink error_info] version). * \details - * ValueCollection should meet the [reflink ValueCollection] requirements. + * FieldViewCollection should meet the [reflink FieldViewCollection] requirements. * * After this operation completes, you should read the entire resultset * before calling any function that involves communication with the server over this @@ -559,16 +558,16 @@ public: * `void(boost::mysql::error_code, boost::mysql::resultset)`. */ template < - class ValueCollection, + class FieldViewCollection, BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type), - class EnableIf = detail::enable_if_value_collection + class EnableIf = detail::enable_if_field_view_collection > BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code)) async_execute_statement( const prepared_statement& statement, - const ValueCollection& params, + const FieldViewCollection& params, resultset& result, error_info& output_info, CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type) @@ -586,7 +585,7 @@ public: /** * \brief Executes a statement (`execute_params`, sync with error code version). * \details - * ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements. + * FieldViewFwdIterator should meet the [reflink FieldViewFwdIterator] requirements. * The range \\[`params.first()`, `params.last()`) will be used as parameters for * statement execution. They should be a valid iterator range. * @@ -594,9 +593,9 @@ public: * before calling any function that involves communication with the server over this * connection. Otherwise, the results are undefined. */ - template + template void execute_statement( - const execute_params& params, + const execute_params& params, resultset& result, error_code& ec, error_info& info @@ -605,7 +604,7 @@ public: /** * \brief Executes a statement (`execute_params`, sync with exceptions version). * \details - * ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements. + * FieldViewFwdIterator should meet the [reflink FieldViewFwdIterator] requirements. * The range \\[`params.first()`, `params.last()`) will be used as parameters for * statement execution. They should be a valid iterator range. * @@ -613,9 +612,9 @@ public: * before calling any function that involves communication with the server over this * connection. Otherwise, the results are undefined. */ - template + template void execute_statement( - const execute_params& params, + const execute_params& params, resultset& result ); @@ -623,7 +622,7 @@ public: * \brief Executes a statement (`execute_params`, * async without [reflink error_info] version). * \details - * ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements. + * FieldViewFwdIterator should meet the [reflink FieldViewFwdIterator] requirements. * The range \\[`params.first()`, `params.last()`) will be used as parameters for * statement execution. They should be a valid iterator range. * @@ -639,14 +638,14 @@ public: * `void(boost::mysql::error_code, boost::mysql::resultset)`. */ template < - class ValueForwardIterator, + class FieldViewFwdIterator, BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type) > BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code)) async_execute_statement( - const execute_params& params, + const execute_params& params, resultset& result, CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type) ) @@ -658,7 +657,7 @@ public: * \brief Executes a statement (`execute_params`, * async with [reflink error_info] version). * \details - * ValueForwardIterator should meet the [reflink ValueForwardIterator] requirements. + * FieldViewFwdIterator should meet the [reflink FieldViewFwdIterator] requirements. * The range \\[`params.first()`, `params.last()`) will be used as parameters for * statement execution. They should be a valid iterator range. * @@ -674,14 +673,14 @@ public: * `void(boost::mysql::error_code, boost::mysql::resultset)`. */ template < - class ValueForwardIterator, + class FieldViewFwdIterator, BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type) > BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code)) async_execute_statement( - const execute_params& params, + const execute_params& params, resultset& result, error_info& output_info, CompletionToken&& token BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type) diff --git a/include/boost/mysql/detail/auxiliar/value_type_traits.hpp b/include/boost/mysql/detail/auxiliar/field_type_traits.hpp similarity index 65% rename from include/boost/mysql/detail/auxiliar/value_type_traits.hpp rename to include/boost/mysql/detail/auxiliar/field_type_traits.hpp index 317c334f..428c4d02 100644 --- a/include/boost/mysql/detail/auxiliar/value_type_traits.hpp +++ b/include/boost/mysql/detail/auxiliar/field_type_traits.hpp @@ -8,7 +8,7 @@ #ifndef BOOST_MYSQL_DETAIL_AUXILIAR_VALUE_TYPE_TRAITS_HPP #define BOOST_MYSQL_DETAIL_AUXILIAR_VALUE_TYPE_TRAITS_HPP -#include +#include #include #include #include @@ -19,10 +19,10 @@ namespace mysql { namespace detail { template -struct is_value_forward_iterator : std::false_type { }; +struct is_field_view_forward_iterator : std::false_type { }; template -struct is_value_forward_iterator::value_type >::type >::type, - ::boost::mysql::value + ::boost::mysql::field_view >::value >::type, typename std::enable_if< @@ -42,25 +42,25 @@ struct is_value_forward_iterator> : std::true_type { }; template -struct is_value_collection : std::false_type {}; +struct is_field_view_collection : std::false_type {}; template -struct is_value_collection()))>::value + is_field_view_forward_iterator()))>::value >::type, typename std::enable_if< - is_value_forward_iterator()))>::value + is_field_view_forward_iterator()))>::value >::type >> : std::true_type {}; // Helpers template -using enable_if_value_forward_iterator = typename std::enable_if::value>::type; +using enable_if_field_view_forward_iterator = typename std::enable_if::value>::type; template -using enable_if_value_collection = typename std::enable_if::value>::type; +using enable_if_field_view_collection = typename std::enable_if::value>::type; } diff --git a/include/boost/mysql/detail/channel/channel.hpp b/include/boost/mysql/detail/channel/channel.hpp index c1eff12c..9c3cbcef 100644 --- a/include/boost/mysql/detail/channel/channel.hpp +++ b/include/boost/mysql/detail/channel/channel.hpp @@ -8,8 +8,9 @@ #ifndef BOOST_MYSQL_DETAIL_CHANNEL_CHANNEL_HPP #define BOOST_MYSQL_DETAIL_CHANNEL_CHANNEL_HPP -#include "boost/mysql/error.hpp" #include +#include +#include #include #include #include @@ -34,7 +35,7 @@ class channel std::uint8_t shared_sequence_number_ {}; // for async ops bytestring shared_buff_; // for async ops error_info shared_info_; // for async ops - std::vector shared_values_; // for read_some ops + std::vector shared_fields_; // for read_some ops void process_header_write(std::uint32_t size_to_write, std::uint8_t seqnum); // writes to header_buffer_ @@ -129,8 +130,8 @@ public: bytestring& shared_buffer() noexcept { return shared_buff_; } error_info& shared_info() noexcept { return shared_info_; } std::uint8_t& shared_sequence_number() noexcept { return shared_sequence_number_; } - std::vector& shared_values() noexcept { return shared_values_; } - const std::vector& shared_values() const noexcept { return shared_values_; } + std::vector& shared_fields() noexcept { return shared_fields_; } + const std::vector& shared_fields() const noexcept { return shared_fields_; } }; } // detail diff --git a/include/boost/mysql/detail/channel/message_reader.hpp b/include/boost/mysql/detail/channel/message_reader.hpp index ebf6abea..19a26d35 100644 --- a/include/boost/mysql/detail/channel/message_reader.hpp +++ b/include/boost/mysql/detail/channel/message_reader.hpp @@ -8,8 +8,6 @@ #ifndef BOOST_MYSQL_DETAIL_CHANNEL_MESSAGE_READER_HPP #define BOOST_MYSQL_DETAIL_CHANNEL_MESSAGE_READER_HPP -#include "boost/mysql/detail/protocol/common_messages.hpp" -#include "boost/mysql/detail/protocol/constants.hpp" #include #include #include @@ -18,6 +16,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/include/boost/mysql/detail/network_algorithms/execute_statement.hpp b/include/boost/mysql/detail/network_algorithms/execute_statement.hpp index 5d881372..768aa6a6 100644 --- a/include/boost/mysql/detail/network_algorithms/execute_statement.hpp +++ b/include/boost/mysql/detail/network_algorithms/execute_statement.hpp @@ -17,20 +17,20 @@ namespace boost { namespace mysql { namespace detail { -template +template void execute_statement( channel& channel, - const execute_params& params, + const execute_params& params, resultset& output, error_code& err, error_info& info ); -template +template BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void(error_code)) async_execute_statement( channel& chan, - const execute_params& params, + const execute_params& params, resultset& output, error_info& info, CompletionToken&& token diff --git a/include/boost/mysql/detail/network_algorithms/impl/execute_statement.hpp b/include/boost/mysql/detail/network_algorithms/impl/execute_statement.hpp index c0f506b3..7ecb6f9f 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/execute_statement.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/execute_statement.hpp @@ -21,12 +21,12 @@ namespace boost { namespace mysql { namespace detail { -template -com_stmt_execute_packet make_stmt_execute_packet( - const execute_params& params +template +com_stmt_execute_packet make_stmt_execute_packet( + const execute_params& params ) { - return com_stmt_execute_packet { + return com_stmt_execute_packet { params.statement_id(), std::uint8_t(0), // flags std::uint32_t(1), // iteration count @@ -41,10 +41,10 @@ com_stmt_execute_packet make_stmt_execute_packet( } // mysql } // boost -template +template void boost::mysql::detail::execute_statement( channel& chan, - const execute_params& params, + const execute_params& params, resultset& output, error_code& err, error_info& info @@ -60,14 +60,14 @@ void boost::mysql::detail::execute_statement( ); } -template +template BOOST_ASIO_INITFN_AUTO_RESULT_TYPE( CompletionToken, void(boost::mysql::error_code) ) boost::mysql::detail::async_execute_statement( channel& chan, - const execute_params& params, + const execute_params& params, resultset& output, error_info& info, CompletionToken&& token diff --git a/include/boost/mysql/detail/network_algorithms/impl/read_all_rows.hpp b/include/boost/mysql/detail/network_algorithms/impl/read_all_rows.hpp index ad4cdd6c..c06054b1 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/read_all_rows.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/read_all_rows.hpp @@ -33,8 +33,8 @@ inline void process_rows( error_info& info ) { - // The number of values we already have, required to copy strings - std::size_t old_value_size = output.values().size(); + // The number of fields we already have, required to copy strings + std::size_t old_field_size = output.fields().size(); // Process all read messages until they run out, an error happens // or an EOF is received @@ -51,7 +51,7 @@ inline void process_rows( message, channel.current_capabilities(), resultset, - output.values(), + output.fields(), err, info ); @@ -65,7 +65,7 @@ inline void process_rows( } // Copy strings - output.copy_strings(old_value_size); + output.copy_strings(old_field_size); } diff --git a/include/boost/mysql/detail/network_algorithms/impl/read_some_rows.hpp b/include/boost/mysql/detail/network_algorithms/impl/read_some_rows.hpp index 9d16c05e..ef4bb1a9 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/read_some_rows.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/read_some_rows.hpp @@ -36,7 +36,7 @@ inline void process_rows( // Process all read messages until they run out, an error happens // or an EOF is received std::size_t num_rows = 0; - channel.shared_values().clear(); + channel.shared_fields().clear(); while (channel.num_read_messages()) { // Get the row message @@ -49,7 +49,7 @@ inline void process_rows( message, channel.current_capabilities(), resultset, - channel.shared_values(), + channel.shared_fields(), err, info ); @@ -66,7 +66,7 @@ inline void process_rows( } output = rows_view( - channel.shared_values().data(), + channel.shared_fields().data(), num_rows * resultset.fields().size(), resultset.fields().size() ); diff --git a/include/boost/mysql/detail/protocol/binary_deserialization.hpp b/include/boost/mysql/detail/protocol/binary_deserialization.hpp index 3ffa02fe..22d206ac 100644 --- a/include/boost/mysql/detail/protocol/binary_deserialization.hpp +++ b/include/boost/mysql/detail/protocol/binary_deserialization.hpp @@ -10,24 +10,24 @@ #include #include -#include -#include +#include +#include #include namespace boost { namespace mysql { namespace detail { -inline errc deserialize_binary_value( +inline errc deserialize_binary_field( deserialization_context& ctx, - const field_metadata& meta, - value& output + const metadata& meta, + field_view& output ); inline error_code deserialize_binary_row( deserialization_context& ctx, - const std::vector& meta, - std::vector& output + const std::vector& meta, + std::vector& output ); } // detail diff --git a/include/boost/mysql/detail/protocol/binary_serialization.hpp b/include/boost/mysql/detail/protocol/binary_serialization.hpp index ea9f229f..830f0e4d 100644 --- a/include/boost/mysql/detail/protocol/binary_serialization.hpp +++ b/include/boost/mysql/detail/protocol/binary_serialization.hpp @@ -8,7 +8,7 @@ #ifndef BOOST_MYSQL_DETAIL_PROTOCOL_BINARY_SERIALIZATION_HPP #define BOOST_MYSQL_DETAIL_PROTOCOL_BINARY_SERIALIZATION_HPP -#include +#include #include namespace boost { @@ -16,13 +16,13 @@ namespace mysql { namespace detail { template <> -struct serialization_traits : - noop_deserialize +struct serialization_traits : + noop_deserialize { static inline std::size_t get_size_(const serialization_context& ctx, - const value& input) noexcept; + const field_view& input) noexcept; static inline void serialize_(serialization_context& ctx, - const value& input) noexcept; + const field_view& input) noexcept; }; diff --git a/include/boost/mysql/detail/protocol/bit_deserialization.hpp b/include/boost/mysql/detail/protocol/bit_deserialization.hpp index cb923bce..512ca712 100644 --- a/include/boost/mysql/detail/protocol/bit_deserialization.hpp +++ b/include/boost/mysql/detail/protocol/bit_deserialization.hpp @@ -9,8 +9,10 @@ #define BOOST_MYSQL_DETAIL_PROTOCOL_BIT_DESERIALIZATION_HPP #include +#include #include #include +#include namespace boost { namespace mysql { @@ -23,7 +25,7 @@ namespace detail { // a 2 byte value; BIT(54) will send a 7 byte one). Values are sent as big-endian. inline errc deserialize_bit( boost::string_view from, - value& to + field_view& to ) noexcept { std::size_t num_bytes = from.size(); @@ -34,7 +36,7 @@ inline errc deserialize_bit( unsigned char temp [8] {}; unsigned char* dest = temp + sizeof(temp) - num_bytes; std::memcpy(dest, from.data(), num_bytes); - to = value(boost::endian::load_big_u64(temp)); + to = field_view(boost::endian::load_big_u64(temp)); return errc::ok; } diff --git a/include/boost/mysql/detail/protocol/deserialize_row.hpp b/include/boost/mysql/detail/protocol/deserialize_row.hpp index 4ce96402..89a273d8 100644 --- a/include/boost/mysql/detail/protocol/deserialize_row.hpp +++ b/include/boost/mysql/detail/protocol/deserialize_row.hpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include @@ -28,7 +28,7 @@ inline bool deserialize_row( boost::asio::const_buffer read_message, capabilities current_capabilities, resultset& resultset, - std::vector& output, + std::vector& output, error_code& err, error_info& info ) diff --git a/include/boost/mysql/detail/protocol/impl/binary_deserialization.ipp b/include/boost/mysql/detail/protocol/impl/binary_deserialization.ipp index 32f90e54..4718db45 100644 --- a/include/boost/mysql/detail/protocol/impl/binary_deserialization.ipp +++ b/include/boost/mysql/detail/protocol/impl/binary_deserialization.ipp @@ -23,31 +23,31 @@ namespace mysql { namespace detail { // strings -inline errc deserialize_binary_value_string( +inline errc deserialize_binary_field_string( deserialization_context& ctx, - value& output + field_view& output ) noexcept { string_lenenc deser; auto err = deserialize(ctx, deser); if (err != errc::ok) return err; - output = value(deser.value); + output = field_view(deser.value); return errc::ok; } // ints template -errc deserialize_binary_value_int_impl( +errc deserialize_binary_field_int_impl( deserialization_context& ctx, - value& output + field_view& output ) noexcept { DeserializableType deser; auto err = deserialize(ctx, deser); if (err != errc::ok) return err; - output = value(static_cast(deser)); + output = field_view(static_cast(deser)); return errc::ok; } @@ -55,24 +55,24 @@ template < class DeserializableTypeUnsigned, class DeserializableTypeSigned > -errc deserialize_binary_value_int( - const field_metadata& meta, +errc deserialize_binary_field_int( + const metadata& meta, deserialization_context& ctx, - value& output + field_view& output ) noexcept { return meta.is_unsigned() ? - deserialize_binary_value_int_impl< + deserialize_binary_field_int_impl< std::uint64_t, DeserializableTypeUnsigned>(ctx, output) : - deserialize_binary_value_int_impl< + deserialize_binary_field_int_impl< std::int64_t, DeserializableTypeSigned>(ctx, output); } // Bits. These come as a binary value between 1 and 8 bytes, // packed in a string -inline errc deserialize_binary_value_bit( +inline errc deserialize_binary_field_bit( deserialization_context& ctx, - value& output + field_view& output ) noexcept { string_lenenc buffer; @@ -83,9 +83,9 @@ inline errc deserialize_binary_value_bit( // Floats template -errc deserialize_binary_value_float( +errc deserialize_binary_field_float( deserialization_context& ctx, - value& output + field_view& output ) noexcept { // Size check @@ -102,7 +102,7 @@ errc deserialize_binary_value_float( // Done ctx.advance(sizeof(T)); - output = value(v); + output = field_view(v); return errc::ok; } @@ -134,9 +134,9 @@ inline errc deserialize_binary_ymd( return errc::ok; } -inline errc deserialize_binary_value_date( +inline errc deserialize_binary_field_date( deserialization_context& ctx, - value& output + field_view& output ) noexcept { // Deserialize length @@ -148,7 +148,7 @@ inline errc deserialize_binary_value_date( // Check for zero dates, represented in C++ as a NULL if (length < binc::date_sz) { - output = value(nullptr); + output = field_view(nullptr); return errc::ok; } @@ -161,18 +161,18 @@ inline errc deserialize_binary_value_date( // Check for invalid dates, represented as NULL in C++ if (!is_valid(ymd)) { - output = value(nullptr); + output = field_view(nullptr); return errc::ok; } // Convert to value - output = value(date(days(ymd_to_days(ymd)))); + output = field_view(date(days(ymd_to_days(ymd)))); return errc::ok; } -inline errc deserialize_binary_value_datetime( +inline errc deserialize_binary_field_datetime( deserialization_context& ctx, - value& output + field_view& output ) noexcept { using namespace binc; @@ -231,7 +231,7 @@ inline errc deserialize_binary_value_datetime( // associated to this datetime if (!is_valid(ymd)) { - output = value(nullptr); + output = field_view(nullptr); return errc::ok; } @@ -242,13 +242,13 @@ inline errc deserialize_binary_value_datetime( std::chrono::minutes(minutes) + std::chrono::seconds(seconds) + std::chrono::microseconds(micros); - output = value(d + time_of_day); + output = field_view(d + time_of_day); return errc::ok; } -inline errc deserialize_binary_value_time( +inline errc deserialize_binary_field_time( deserialization_context& ctx, - value& output + field_view& output ) noexcept { using namespace binc; @@ -301,7 +301,7 @@ inline errc deserialize_binary_value_time( } // Compose the final time - output = value(time((is_negative ? -1 : 1) * ( + output = field_view(time((is_negative ? -1 : 1) * ( days(num_days) + std::chrono::hours(hours) + std::chrono::minutes(minutes) + @@ -316,37 +316,37 @@ inline errc deserialize_binary_value_time( } // mysql } // boost -inline boost::mysql::errc boost::mysql::detail::deserialize_binary_value( +inline boost::mysql::errc boost::mysql::detail::deserialize_binary_field( deserialization_context& ctx, - const field_metadata& meta, - value& output + const metadata& meta, + field_view& output ) { switch (meta.protocol_type()) { case protocol_field_type::tiny: - return deserialize_binary_value_int(meta, ctx, output); + return deserialize_binary_field_int(meta, ctx, output); case protocol_field_type::short_: case protocol_field_type::year: - return deserialize_binary_value_int(meta, ctx, output); + return deserialize_binary_field_int(meta, ctx, output); case protocol_field_type::int24: case protocol_field_type::long_: - return deserialize_binary_value_int(meta, ctx, output); + return deserialize_binary_field_int(meta, ctx, output); case protocol_field_type::longlong: - return deserialize_binary_value_int(meta, ctx, output); + return deserialize_binary_field_int(meta, ctx, output); case protocol_field_type::bit: - return deserialize_binary_value_bit(ctx, output); + return deserialize_binary_field_bit(ctx, output); case protocol_field_type::float_: - return deserialize_binary_value_float(ctx, output); + return deserialize_binary_field_float(ctx, output); case protocol_field_type::double_: - return deserialize_binary_value_float(ctx, output); + return deserialize_binary_field_float(ctx, output); case protocol_field_type::timestamp: case protocol_field_type::datetime: - return deserialize_binary_value_datetime(ctx, output); + return deserialize_binary_field_datetime(ctx, output); case protocol_field_type::date: - return deserialize_binary_value_date(ctx, output); + return deserialize_binary_field_date(ctx, output); case protocol_field_type::time: - return deserialize_binary_value_time(ctx, output); + return deserialize_binary_field_time(ctx, output); // True string types case protocol_field_type::varchar: case protocol_field_type::var_string: @@ -362,14 +362,14 @@ inline boost::mysql::errc boost::mysql::detail::deserialize_binary_value( case protocol_field_type::newdecimal: case protocol_field_type::geometry: default: - return deserialize_binary_value_string(ctx, output); + return deserialize_binary_field_string(ctx, output); } } inline boost::mysql::error_code boost::mysql::detail::deserialize_binary_row( deserialization_context& ctx, - const std::vector& meta, - std::vector& output + const std::vector& meta, + std::vector& output ) { std::size_t old_size = output.size(); @@ -392,15 +392,15 @@ inline boost::mysql::error_code boost::mysql::detail::deserialize_binary_row( ctx.advance(null_bitmap.byte_count()); // Actual values - for (std::vector::size_type i = 0; i < output.size(); ++i) + for (std::vector::size_type i = 0; i < output.size(); ++i) { if (null_bitmap.is_null(null_bitmap_begin, i)) { - output[old_size + i] = value(nullptr); + output[old_size + i] = field_view(nullptr); } else { - auto err = deserialize_binary_value(ctx, meta[i], output[old_size + i]); + auto err = deserialize_binary_field(ctx, meta[i], output[old_size + i]); if (err != errc::ok) return make_error_code(err); } diff --git a/include/boost/mysql/detail/protocol/impl/binary_serialization.ipp b/include/boost/mysql/detail/protocol/impl/binary_serialization.ipp index 4e12a222..3988fe2d 100644 --- a/include/boost/mysql/detail/protocol/impl/binary_serialization.ipp +++ b/include/boost/mysql/detail/protocol/impl/binary_serialization.ipp @@ -20,8 +20,7 @@ namespace detail { // Floating point types template -typename std::enable_if::value>::type -serialize_binary_value_impl( +void serialize_binary_float( serialization_context& ctx, T input ) @@ -48,7 +47,7 @@ inline void serialize_binary_ymd( ); } -inline void serialize_binary_value_impl( +inline void serialize_binary_date( serialization_context& ctx, const date& input ) @@ -60,7 +59,7 @@ inline void serialize_binary_value_impl( serialize_binary_ymd(ctx, ymd); } -inline void serialize_binary_value_impl( +inline void serialize_binary_datetime( serialization_context& ctx, const datetime& input ) @@ -88,7 +87,7 @@ inline void serialize_binary_value_impl( ); } -inline void serialize_binary_value_impl( +inline void serialize_binary_time( serialization_context& ctx, const time& input ) @@ -116,66 +115,54 @@ inline void serialize_binary_value_impl( } -struct size_visitor -{ - const serialization_context& ctx; - - size_visitor(const serialization_context& ctx) noexcept: ctx(ctx) {} - - // ints and floats - template - std::size_t operator()(T) noexcept { return sizeof(T); } - - std::size_t operator()(boost::string_view v) noexcept { return get_size(ctx, string_lenenc(v)); } - std::size_t operator()(const date&) noexcept { return binc::date_sz + binc::length_sz; } - std::size_t operator()(const datetime&) noexcept { return binc::datetime_dhmsu_sz + binc::length_sz; } - std::size_t operator()(const time&) noexcept { return binc::time_dhmsu_sz + binc::length_sz; } - std::size_t operator()(null_t) noexcept { return 0; } -}; - -struct serialize_visitor -{ - serialization_context& ctx; - - serialize_visitor(serialization_context& ctx) noexcept: ctx(ctx) {} - - template - void operator()(const T& v) noexcept { serialize_binary_value_impl(ctx, v); } - - void operator()(std::int64_t v) noexcept { serialize(ctx, v); } - void operator()(std::uint64_t v) noexcept { serialize(ctx, v); } - void operator()(boost::string_view v) noexcept { serialize(ctx, string_lenenc(v)); } - void operator()(null_t) noexcept {} -}; - } // detail } // mysql } // boost inline std::size_t boost::mysql::detail::serialization_traits< - boost::mysql::value, + boost::mysql::field_view, boost::mysql::detail::serialization_tag::none >::get_size_( const serialization_context& ctx, - const value& input + const field_view& input ) noexcept { - return boost::variant2::visit(size_visitor(ctx), input.to_variant()); + switch (input.kind()) + { + case field_kind::null: return 0; + case field_kind::int64: return 8; + case field_kind::uint64: return 8; + case field_kind::string: return get_size(ctx, string_lenenc(input.get_string())); + case field_kind::float_: return 4; + case field_kind::double_: return 8; + case field_kind::date: return binc::date_sz + binc::length_sz; + case field_kind::datetime: return binc::datetime_dhmsu_sz + binc::length_sz; + case field_kind::time: return binc::time_dhmsu_sz + binc::length_sz; + } } inline void boost::mysql::detail::serialization_traits< - boost::mysql::value, + boost::mysql::field_view, boost::mysql::detail::serialization_tag::none >::serialize_( serialization_context& ctx, - const value& input + const field_view& input ) noexcept { - boost::variant2::visit(serialize_visitor(ctx), input.to_variant()); + switch (input.kind()) + { + case field_kind::null: break; + case field_kind::int64: serialize(ctx, input.get_int64()); break; + case field_kind::uint64: serialize(ctx, input.get_uint64()); break; + case field_kind::string: serialize(ctx, string_lenenc(input.get_string())); break; + case field_kind::float_: serialize_binary_float(ctx, input.get_float()); break; + case field_kind::double_: serialize_binary_float(ctx, input.get_double()); break; + case field_kind::date: serialize_binary_date(ctx, input.get_date()); break; + case field_kind::datetime: serialize_binary_datetime(ctx, input.get_datetime()); break; + case field_kind::time: serialize_binary_time(ctx, input.get_time()); break; + } } - - #endif diff --git a/include/boost/mysql/detail/protocol/impl/prepared_statement_messages.hpp b/include/boost/mysql/detail/protocol/impl/prepared_statement_messages.hpp index eb1eece0..9fe738d9 100644 --- a/include/boost/mysql/detail/protocol/impl/prepared_statement_messages.hpp +++ b/include/boost/mysql/detail/protocol/impl/prepared_statement_messages.hpp @@ -20,31 +20,30 @@ namespace detail { // Maps from an actual value to a protocol_field_type. Only value's type is used inline protocol_field_type get_protocol_field_type( - const value& input + const field_view& input ) noexcept { - struct visitor + switch (input.kind()) { - protocol_field_type operator()(std::int64_t) const noexcept { return protocol_field_type::longlong; } - protocol_field_type operator()(std::uint64_t) const noexcept { return protocol_field_type::longlong; } - protocol_field_type operator()(boost::string_view) const noexcept { return protocol_field_type::varchar; } - protocol_field_type operator()(float) const noexcept { return protocol_field_type::float_; } - protocol_field_type operator()(double) const noexcept { return protocol_field_type::double_; } - protocol_field_type operator()(date) const noexcept { return protocol_field_type::date; } - protocol_field_type operator()(datetime) const noexcept { return protocol_field_type::datetime; } - protocol_field_type operator()(time) const noexcept { return protocol_field_type::time; } - protocol_field_type operator()(null_t) const noexcept { return protocol_field_type::null; } - }; - return boost::variant2::visit(visitor(), input.to_variant()); + case field_kind::null: return protocol_field_type::null; + case field_kind::int64: return protocol_field_type::longlong; + case field_kind::uint64: return protocol_field_type::longlong; + case field_kind::string: return protocol_field_type::varchar; + case field_kind::float_: return protocol_field_type::float_; + case field_kind::double_: return protocol_field_type::double_; + case field_kind::date: return protocol_field_type::date; + case field_kind::datetime: return protocol_field_type::datetime; + case field_kind::time: return protocol_field_type::time; + } } // Whether to include the unsigned flag in the statement execute message // for a given value or not. Only value's type is used inline bool is_unsigned( - const value& input + const field_view& input ) noexcept { - return input.is(); + return input.is_uint64(); } } // detail @@ -71,14 +70,14 @@ boost::mysql::detail::serialization_traits< ); } -template +template inline std::size_t boost::mysql::detail::serialization_traits< - boost::mysql::detail::com_stmt_execute_packet, + boost::mysql::detail::com_stmt_execute_packet, boost::mysql::detail::serialization_tag::struct_with_fields >::get_size_( const serialization_context& ctx, - const com_stmt_execute_packet& value + const com_stmt_execute_packet& value ) noexcept { std::size_t res = 1 + // command ID @@ -95,17 +94,17 @@ boost::mysql::detail::serialization_traits< return res; } -template +template inline void boost::mysql::detail::serialization_traits< - boost::mysql::detail::com_stmt_execute_packet, + boost::mysql::detail::com_stmt_execute_packet, boost::mysql::detail::serialization_tag::struct_with_fields >::serialize_( serialization_context& ctx, - const com_stmt_execute_packet& input + const com_stmt_execute_packet& input ) noexcept { - constexpr std::uint8_t command_id = com_stmt_execute_packet::command_id; + constexpr std::uint8_t command_id = com_stmt_execute_packet::command_id; serialize( ctx, command_id, diff --git a/include/boost/mysql/detail/protocol/impl/text_deserialization.ipp b/include/boost/mysql/detail/protocol/impl/text_deserialization.ipp index 82e22216..bf88cf21 100644 --- a/include/boost/mysql/detail/protocol/impl/text_deserialization.ipp +++ b/include/boost/mysql/detail/protocol/impl/text_deserialization.ipp @@ -34,21 +34,21 @@ namespace detail { template errc deserialize_text_value_int_impl( boost::string_view from, - value& to + field_view& to ) noexcept { T v; bool ok = boost::conversion::try_lexical_convert(from.data(), from.size(), v); if (!ok) return errc::protocol_value_error; - to = value(v); + to = field_view(v); return errc::ok; } inline errc deserialize_text_value_int( boost::string_view from, - value& to, - const field_metadata& meta + field_view& to, + const metadata& meta ) noexcept { return meta.is_unsigned() ? @@ -60,24 +60,24 @@ inline errc deserialize_text_value_int( template errc deserialize_text_value_float( boost::string_view from, - value& to + field_view& to ) noexcept { T val; bool ok = boost::conversion::try_lexical_convert(from.data(), from.size(), val); if (!ok || std::isnan(val) || std::isinf(val)) // SQL std forbids these values return errc::protocol_value_error; - to = value(val); + to = field_view(val); return errc::ok; } // Strings inline errc deserialize_text_value_string( boost::string_view from, - value& to + field_view& to ) noexcept { - to = value(from); + to = field_view(from); return errc::ok; } @@ -126,7 +126,7 @@ inline errc deserialize_text_ymd( inline errc deserialize_text_value_date( boost::string_view from, - value& to + field_view& to ) noexcept { // Deserialize ymd @@ -139,19 +139,19 @@ inline errc deserialize_text_value_date( // we represent in C++ as NULL if (!is_valid(ymd)) { - to = value(nullptr); + to = field_view(nullptr); return errc::ok; } // Done - to = value(date(days(ymd_to_days(ymd)))); + to = field_view(date(days(ymd_to_days(ymd)))); return errc::ok; } inline errc deserialize_text_value_datetime( boost::string_view from, - value& to, - const field_metadata& meta + field_view& to, + const metadata& meta ) noexcept { using namespace textc; @@ -210,7 +210,7 @@ inline errc deserialize_text_value_datetime( // we represent here as NULL if (!is_valid(ymd)) { - to = value(nullptr); + to = field_view(nullptr); return errc::ok; } @@ -221,14 +221,14 @@ inline errc deserialize_text_value_datetime( std::chrono::minutes(minutes) + std::chrono::seconds(seconds) + std::chrono::microseconds(micros); - to = value(d + time_of_day); + to = field_view(d + time_of_day); return errc::ok; } inline errc deserialize_text_value_time( boost::string_view from, - value& to, - const field_metadata& meta + field_view& to, + const metadata& meta ) noexcept { using namespace textc; @@ -290,7 +290,7 @@ inline errc deserialize_text_value_time( } // Done - to = value(res); + to = field_view(res); return errc::ok; } @@ -309,8 +309,8 @@ inline bool is_next_field_null( inline boost::mysql::errc boost::mysql::detail::deserialize_text_value( boost::string_view from, - const field_metadata& meta, - value& output + const metadata& meta, + field_view& output ) { switch (meta.protocol_type()) @@ -358,17 +358,17 @@ inline boost::mysql::errc boost::mysql::detail::deserialize_text_value( boost::mysql::error_code boost::mysql::detail::deserialize_text_row( deserialization_context& ctx, const std::vector& fields, - std::vector& output + std::vector& output ) { std::size_t old_size = output.size(); output.resize(old_size + fields.size()); - for (std::vector::size_type i = 0; i < fields.size(); ++i) + for (std::vector::size_type i = 0; i < fields.size(); ++i) { if (is_next_field_null(ctx)) { ctx.advance(1); - output[old_size + i] = value(nullptr); + output[old_size + i] = field_view(nullptr); } else { diff --git a/include/boost/mysql/detail/protocol/prepared_statement_messages.hpp b/include/boost/mysql/detail/protocol/prepared_statement_messages.hpp index 92601e44..6340444a 100644 --- a/include/boost/mysql/detail/protocol/prepared_statement_messages.hpp +++ b/include/boost/mysql/detail/protocol/prepared_statement_messages.hpp @@ -10,7 +10,7 @@ #include #include -#include +#include namespace boost { namespace mysql { @@ -64,7 +64,7 @@ struct serialization_traits +template struct com_stmt_execute_packet { std::uint32_t statement_id; @@ -72,8 +72,8 @@ struct com_stmt_execute_packet std::uint32_t iteration_count; // if num_params > 0: NULL bitmap std::uint8_t new_params_bind_flag; - ValueForwardIterator params_begin; - ValueForwardIterator params_end; + FieldViewFwdIterator params_begin; + FieldViewFwdIterator params_end; static constexpr std::uint8_t command_id = 0x17; @@ -89,16 +89,16 @@ struct com_stmt_execute_packet } }; -template +template struct serialization_traits< - com_stmt_execute_packet, + com_stmt_execute_packet, serialization_tag::struct_with_fields -> : noop_deserialize> +> : noop_deserialize> { static inline std::size_t get_size_(const serialization_context& ctx, - const com_stmt_execute_packet& value) noexcept; + const com_stmt_execute_packet& value) noexcept; static inline void serialize_(serialization_context& ctx, - const com_stmt_execute_packet& input) noexcept; + const com_stmt_execute_packet& input) noexcept; }; struct com_stmt_execute_param_meta_packet diff --git a/include/boost/mysql/detail/protocol/serialization.hpp b/include/boost/mysql/detail/protocol/serialization.hpp index 32b46e38..7936c4ee 100644 --- a/include/boost/mysql/detail/protocol/serialization.hpp +++ b/include/boost/mysql/detail/protocol/serialization.hpp @@ -15,7 +15,6 @@ #include #include #include -#include #include namespace boost { diff --git a/include/boost/mysql/detail/protocol/text_deserialization.hpp b/include/boost/mysql/detail/protocol/text_deserialization.hpp index 98a339aa..5ea7a6f2 100644 --- a/include/boost/mysql/detail/protocol/text_deserialization.hpp +++ b/include/boost/mysql/detail/protocol/text_deserialization.hpp @@ -10,8 +10,8 @@ #include #include -#include -#include +#include +#include #include namespace boost { @@ -20,14 +20,14 @@ namespace detail { inline errc deserialize_text_value( boost::string_view from, - const field_metadata& meta, - value& output + const metadata& meta, + field_view& output ); inline error_code deserialize_text_row( deserialization_context& ctx, - const std::vector& meta, - std::vector& output + const std::vector& meta, + std::vector& output ); } // detail diff --git a/include/boost/mysql/execute_params.hpp b/include/boost/mysql/execute_params.hpp index 79d36466..651dd142 100644 --- a/include/boost/mysql/execute_params.hpp +++ b/include/boost/mysql/execute_params.hpp @@ -9,7 +9,7 @@ #define BOOST_MYSQL_EXECUTE_PARAMS_HPP #include -#include +#include #include #include @@ -20,7 +20,7 @@ namespace mysql { * \brief Represents the parameters required to execute a [reflink prepared_statement]. * \details In essence, this class contains an iterator range \\[first, last), pointing * to a sequence of [reflink value]s that will be used as parameters to execute a - * [reflink prepared_statement]. ValueForwardIterator must meet the [reflink ValueForwardIterator] + * [reflink prepared_statement]. FieldViewFwdIterator must meet the [reflink FieldViewFwdIterator] * type requirements. * * In the future, this class may define extra members providing finer control @@ -29,52 +29,52 @@ namespace mysql { * The \ref make_execute_params helper functions make it easier to create * instances of this class. */ -template +template class execute_params { std::uint32_t statement_id_; - ValueForwardIterator first_; - ValueForwardIterator last_; - static_assert(detail::is_value_forward_iterator::value, - "ValueForwardIterator requirements not met"); + FieldViewFwdIterator first_; + FieldViewFwdIterator last_; + static_assert(detail::is_field_view_forward_iterator::value, + "FieldViewFwdIterator requirements not met"); public: /// Constructor. execute_params( const prepared_statement& stmt, - ValueForwardIterator first, - ValueForwardIterator last + FieldViewFwdIterator first, + FieldViewFwdIterator last ); constexpr std::uint32_t statement_id() const noexcept { return statement_id_; } /// Retrieves the parameter value range's begin. - constexpr ValueForwardIterator first() const { return first_; } + constexpr FieldViewFwdIterator first() const { return first_; } /// Retrieves the parameter value range's end. - constexpr ValueForwardIterator last() const { return last_; } + constexpr FieldViewFwdIterator last() const { return last_; } }; template < - class ValueForwardIterator, - class EnableIf = detail::enable_if_value_forward_iterator + class FieldViewFwdIterator, + class EnableIf = detail::enable_if_field_view_forward_iterator > -constexpr execute_params +constexpr execute_params make_execute_params( const prepared_statement& stmt, - ValueForwardIterator first, - ValueForwardIterator last + FieldViewFwdIterator first, + FieldViewFwdIterator last ) { - return execute_params(stmt, first, last); + return execute_params(stmt, first, last); } template < - class ValueCollection, - class EnableIf = detail::enable_if_value_collection + class FieldViewCollection, + class EnableIf = detail::enable_if_field_view_collection > constexpr auto make_execute_params( const prepared_statement& stmt, - const ValueCollection& col + const FieldViewCollection& col ) -> execute_params { return make_execute_params(stmt, std::begin(col), std::end(col)); diff --git a/include/boost/mysql/field_view.hpp b/include/boost/mysql/field_view.hpp new file mode 100644 index 00000000..f7564949 --- /dev/null +++ b/include/boost/mysql/field_view.hpp @@ -0,0 +1,228 @@ +// +// Copyright (c) 2019-2022 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 BOOST_MYSQL_VALUE_HPP +#define BOOST_MYSQL_VALUE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { +namespace mysql { + +/** + * \brief Duration representing a day (24 hours). + * \details Suitable to represent the range of dates MySQL offers. + * May differ in representation from `std::chrono::days` in C++20. + */ +using days = std::chrono::duration>; + +/// Type representing MySQL `__DATE__` data type. +using date = std::chrono::time_point; + +/// Type representing MySQL `__DATETIME__` and `__TIMESTAMP__` data types. +using datetime = std::chrono::time_point; + +/// Type representing MySQL `__TIME__` data type. +using time = std::chrono::microseconds; + +/// Monostate type representing a NULL value. +using null_t = boost::variant2::monostate; + +/// Exception type thrown when trying to access a [reflink value] with an incorrect type. +class bad_field_access : public std::exception +{ +public: + const char* what() const noexcept override { return "bad_value_access"; } +}; + +enum class field_kind +{ + // Order here is important + null = 0, + int64, + uint64, + string, + float_, + double_, + date, + datetime, + time +}; + +/** + * \brief Represents a value in the database of any of the allowed types. + * See [link mysql.values this section] for more info. + * \details + * + * A [reflink value] is a variant-like class. At a given time, + * it always holds a value of one of the type alternatives. + * See [link mysql.values this section] for information + * on how to use this class. + * + * This is a lightweight, cheap-to-copy class. Strings + * are represented as string_views, not as owning strings. + * This implies that if a value is a string, it will point + * to a [*externally owned] piece of memory. See + * [link mysql.values.strings this section] for more info. + */ +class field_view +{ +public: + /// Constructs a NULL value. + BOOST_CXX14_CONSTEXPR field_view() = default; + + /** + * \brief Constructs a NULL value. + * \details + * Caution: `value(NULL)` will __NOT__ match this overload. It will try to construct + * a `boost::string_view` from a NULL C string, causing undefined behavior. + */ + BOOST_CXX14_CONSTEXPR field_view(std::nullptr_t) noexcept : repr_(null_t()) {} + + BOOST_CXX14_CONSTEXPR field_view(signed char v) noexcept : repr_(std::int64_t(v)) {} + BOOST_CXX14_CONSTEXPR field_view(short v) noexcept : repr_(std::int64_t(v)) {} + BOOST_CXX14_CONSTEXPR field_view(int v) noexcept : repr_(std::int64_t(v)) {} + BOOST_CXX14_CONSTEXPR field_view(long v) noexcept : repr_(std::int64_t(v)) {} + BOOST_CXX14_CONSTEXPR field_view(long long v) noexcept : repr_(std::int64_t(v)) {} + + BOOST_CXX14_CONSTEXPR field_view(unsigned char v) noexcept : repr_(std::uint64_t(v)) {} + BOOST_CXX14_CONSTEXPR field_view(unsigned short v) noexcept : repr_(std::uint64_t(v)) {} + BOOST_CXX14_CONSTEXPR field_view(unsigned int v) noexcept : repr_(std::uint64_t(v)) {} + BOOST_CXX14_CONSTEXPR field_view(unsigned long v) noexcept : repr_(std::uint64_t(v)) {} + BOOST_CXX14_CONSTEXPR field_view(unsigned long long v) noexcept : repr_(std::uint64_t(v)) {} + + BOOST_CXX14_CONSTEXPR field_view(boost::string_view v) noexcept : repr_(v) {} + BOOST_CXX14_CONSTEXPR field_view(float v) noexcept : repr_(v) {} + BOOST_CXX14_CONSTEXPR field_view(double v) noexcept : repr_(v) {} + BOOST_CXX14_CONSTEXPR field_view(const date& v) noexcept : repr_(v) {} + BOOST_CXX14_CONSTEXPR field_view(const datetime& v) noexcept : repr_(v) {} + BOOST_CXX14_CONSTEXPR field_view(const time& v) noexcept : repr_(v) {} + + BOOST_CXX14_CONSTEXPR field_kind kind() const noexcept { return static_cast(repr_.index()); } + + BOOST_CXX14_CONSTEXPR bool is_null() const noexcept { return kind() == field_kind::null; } + BOOST_CXX14_CONSTEXPR bool is_int64() const noexcept { return kind() == field_kind::int64; } + BOOST_CXX14_CONSTEXPR bool is_uint64() const noexcept { return kind() == field_kind::uint64; } + BOOST_CXX14_CONSTEXPR bool is_string() const noexcept { return kind() == field_kind::string; } + BOOST_CXX14_CONSTEXPR bool is_float() const noexcept { return kind() == field_kind::float_; } + BOOST_CXX14_CONSTEXPR bool is_double() const noexcept { return kind() == field_kind::double_; } + BOOST_CXX14_CONSTEXPR bool is_date() const noexcept { return kind() == field_kind::date; } + BOOST_CXX14_CONSTEXPR bool is_datetime() const noexcept { return kind() == field_kind::datetime; } + BOOST_CXX14_CONSTEXPR bool is_time() const noexcept { return kind() == field_kind::time; } + + BOOST_CXX14_CONSTEXPR const std::int64_t* if_int64() const noexcept { return boost::variant2::get_if(&repr_); } + BOOST_CXX14_CONSTEXPR const std::uint64_t* if_uint64() const noexcept { return boost::variant2::get_if(&repr_); } + BOOST_CXX14_CONSTEXPR const boost::string_view* if_string() const noexcept { return boost::variant2::get_if(&repr_); } + BOOST_CXX14_CONSTEXPR const float* if_float() const noexcept { return boost::variant2::get_if(&repr_); } + BOOST_CXX14_CONSTEXPR const double* if_double() const noexcept { return boost::variant2::get_if(&repr_); } + BOOST_CXX14_CONSTEXPR const date* if_date() const noexcept { return boost::variant2::get_if(&repr_); } + BOOST_CXX14_CONSTEXPR const datetime* if_datetime() const noexcept { return boost::variant2::get_if(&repr_); } + BOOST_CXX14_CONSTEXPR const time* if_time() const noexcept { return boost::variant2::get_if