mirror of
https://github.com/boostorg/redis.git
synced 2026-01-19 04:42:09 +00:00
Fixup Adds generic_flat_response typedef
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2018-2022 Marcelo Zimbres Silva (mzimbres@gmail.com)
|
/* Copyright (c) 2018-2025 Marcelo Zimbres Silva (mzimbres@gmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0. (See
|
* Distributed under the Boost Software License, Version 1.0. (See
|
||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
@@ -32,7 +32,7 @@ using boost::asio::dynamic_buffer;
|
|||||||
using boost::asio::redirect_error;
|
using boost::asio::redirect_error;
|
||||||
using boost::redis::config;
|
using boost::redis::config;
|
||||||
using boost::redis::connection;
|
using boost::redis::connection;
|
||||||
using boost::redis::resp3::flat_tree;
|
using boost::redis::generic_flat_response;
|
||||||
using boost::redis::request;
|
using boost::redis::request;
|
||||||
using boost::system::error_code;
|
using boost::system::error_code;
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
@@ -45,7 +45,7 @@ auto receiver(std::shared_ptr<connection> conn) -> awaitable<void>
|
|||||||
request req;
|
request req;
|
||||||
req.push("SUBSCRIBE", "channel");
|
req.push("SUBSCRIBE", "channel");
|
||||||
|
|
||||||
flat_tree resp;
|
generic_flat_response resp;
|
||||||
conn->set_receive_response(resp);
|
conn->set_receive_response(resp);
|
||||||
|
|
||||||
while (conn->will_reconnect()) {
|
while (conn->will_reconnect()) {
|
||||||
@@ -58,12 +58,12 @@ auto receiver(std::shared_ptr<connection> conn) -> awaitable<void>
|
|||||||
if (ec)
|
if (ec)
|
||||||
break; // Connection lost, break so we can reconnect to channels.
|
break; // Connection lost, break so we can reconnect to channels.
|
||||||
|
|
||||||
for (auto const& elem: resp.get_view())
|
for (auto const& elem: resp.value().get_view())
|
||||||
std::cout << elem.value << "\n";
|
std::cout << elem.value << "\n";
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
resp.clear();
|
resp.value().clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
namespace asio = boost::asio;
|
namespace asio = boost::asio;
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
using boost::redis::request;
|
using boost::redis::request;
|
||||||
using boost::redis::resp3::flat_tree;
|
using boost::redis::generic_flat_response;
|
||||||
using boost::redis::config;
|
using boost::redis::config;
|
||||||
using boost::system::error_code;
|
using boost::system::error_code;
|
||||||
using boost::redis::connection;
|
using boost::redis::connection;
|
||||||
@@ -49,7 +49,7 @@ auto receiver(std::shared_ptr<connection> conn) -> asio::awaitable<void>
|
|||||||
request req;
|
request req;
|
||||||
req.push("SUBSCRIBE", "channel");
|
req.push("SUBSCRIBE", "channel");
|
||||||
|
|
||||||
flat_tree resp;
|
generic_flat_response resp;
|
||||||
conn->set_receive_response(resp);
|
conn->set_receive_response(resp);
|
||||||
|
|
||||||
// Loop while reconnection is enabled
|
// Loop while reconnection is enabled
|
||||||
@@ -66,12 +66,12 @@ auto receiver(std::shared_ptr<connection> conn) -> asio::awaitable<void>
|
|||||||
|
|
||||||
// The response must be consumed without suspending the
|
// The response must be consumed without suspending the
|
||||||
// coroutine i.e. without the use of async operations.
|
// coroutine i.e. without the use of async operations.
|
||||||
for (auto const& elem: resp.get_view())
|
for (auto const& elem: resp.value().get_view())
|
||||||
std::cout << elem.value << "\n";
|
std::cout << elem.value << "\n";
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
resp.clear();
|
resp.value().clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <boost/redis/resp3/serialization.hpp>
|
#include <boost/redis/resp3/serialization.hpp>
|
||||||
#include <boost/redis/resp3/type.hpp>
|
#include <boost/redis/resp3/type.hpp>
|
||||||
#include <boost/redis/resp3/flat_tree.hpp>
|
#include <boost/redis/resp3/flat_tree.hpp>
|
||||||
|
#include <boost/redis/response.hpp>
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
@@ -205,6 +206,45 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class general_aggregate<generic_flat_response> {
|
||||||
|
private:
|
||||||
|
generic_flat_response* tree_ = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit general_aggregate(generic_flat_response* c = nullptr)
|
||||||
|
: tree_(c)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void on_init() { }
|
||||||
|
void on_done()
|
||||||
|
{
|
||||||
|
BOOST_ASSERT_MSG(!!tree_, "Unexpected null pointer");
|
||||||
|
if (tree_->has_value()) {
|
||||||
|
tree_->value().notify_done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class String>
|
||||||
|
void on_node(resp3::basic_node<String> const& nd, system::error_code&)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT_MSG(!!tree_, "Unexpected null pointer");
|
||||||
|
switch (nd.data_type) {
|
||||||
|
case resp3::type::blob_error:
|
||||||
|
case resp3::type::simple_error:
|
||||||
|
*tree_ = error{
|
||||||
|
nd.data_type,
|
||||||
|
std::string{std::cbegin(nd.value), std::cend(nd.value)}
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (tree_->has_value()) {
|
||||||
|
(**tree_).push(nd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class general_aggregate<resp3::flat_tree> {
|
class general_aggregate<resp3::flat_tree> {
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -115,6 +115,14 @@ struct response_traits<resp3::flat_tree> {
|
|||||||
static auto adapt(response_type& v) noexcept { return adapter_type{&v}; }
|
static auto adapt(response_type& v) noexcept { return adapter_type{&v}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct response_traits<generic_flat_response> {
|
||||||
|
using response_type = generic_flat_response;
|
||||||
|
using adapter_type = general_aggregate<response_type>;
|
||||||
|
|
||||||
|
static auto adapt(response_type& v) noexcept { return adapter_type{&v}; }
|
||||||
|
};
|
||||||
|
|
||||||
template <class... Ts>
|
template <class... Ts>
|
||||||
struct response_traits<response<Ts...>> {
|
struct response_traits<response<Ts...>> {
|
||||||
using response_type = response<Ts...>;
|
using response_type = response<Ts...>;
|
||||||
|
|||||||
@@ -71,6 +71,13 @@ struct result_traits<resp3::basic_tree<String>> {
|
|||||||
static auto adapt(response_type& v) noexcept { return adapter_type{&v}; }
|
static auto adapt(response_type& v) noexcept { return adapter_type{&v}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct result_traits<generic_flat_response> {
|
||||||
|
using response_type = generic_flat_response;
|
||||||
|
using adapter_type = general_aggregate<response_type>;
|
||||||
|
static auto adapt(response_type& v) noexcept { return adapter_type{&v}; }
|
||||||
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct result_traits<resp3::flat_tree> {
|
struct result_traits<resp3::flat_tree> {
|
||||||
using response_type = resp3::flat_tree;
|
using response_type = resp3::flat_tree;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <boost/redis/adapter/result.hpp>
|
#include <boost/redis/adapter/result.hpp>
|
||||||
#include <boost/redis/resp3/node.hpp>
|
#include <boost/redis/resp3/node.hpp>
|
||||||
#include <boost/redis/resp3/tree.hpp>
|
#include <boost/redis/resp3/tree.hpp>
|
||||||
|
#include <boost/redis/resp3/flat_tree.hpp>
|
||||||
|
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
|
|
||||||
@@ -32,6 +33,9 @@ using response = std::tuple<adapter::result<Ts>...>;
|
|||||||
*/
|
*/
|
||||||
using generic_response = adapter::result<resp3::tree>;
|
using generic_response = adapter::result<resp3::tree>;
|
||||||
|
|
||||||
|
/// Similar to @ref boost::redis::generic_response but stores data contiguously.
|
||||||
|
using generic_flat_response = adapter::result<resp3::flat_tree>;
|
||||||
|
|
||||||
/** @brief (Deprecated) Consume on response from a generic response
|
/** @brief (Deprecated) Consume on response from a generic response
|
||||||
*
|
*
|
||||||
* This function rotates the elements so that the start of the next
|
* This function rotates the elements so that the start of the next
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ using boost::redis::adapter::adapt2;
|
|||||||
using boost::redis::adapter::result;
|
using boost::redis::adapter::result;
|
||||||
using boost::redis::resp3::tree;
|
using boost::redis::resp3::tree;
|
||||||
using boost::redis::resp3::flat_tree;
|
using boost::redis::resp3::flat_tree;
|
||||||
|
using boost::redis::generic_flat_response;
|
||||||
using boost::redis::ignore_t;
|
using boost::redis::ignore_t;
|
||||||
using boost::redis::resp3::detail::deserialize;
|
using boost::redis::resp3::detail::deserialize;
|
||||||
using boost::redis::resp3::node;
|
using boost::redis::resp3::node;
|
||||||
@@ -375,25 +376,45 @@ tree from_flat(flat_tree const& resp)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tree from_flat(generic_flat_response const& resp)
|
||||||
|
{
|
||||||
|
tree ret;
|
||||||
|
for (auto const& e: resp.value().get_view())
|
||||||
|
ret.push_back(from_node_view(e));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Parses the same data into a tree and a
|
// Parses the same data into a tree and a
|
||||||
// flat_tree, they should be equal to each other.
|
// flat_tree, they should be equal to each other.
|
||||||
BOOST_AUTO_TEST_CASE(flat_tree_views_are_set)
|
BOOST_AUTO_TEST_CASE(flat_tree_views_are_set)
|
||||||
{
|
{
|
||||||
tree resp1;
|
tree resp1;
|
||||||
flat_tree fresp;
|
flat_tree resp2;
|
||||||
|
generic_flat_response resp3;
|
||||||
|
|
||||||
error_code ec;
|
error_code ec;
|
||||||
deserialize(resp3_set, adapt2(resp1), ec);
|
deserialize(resp3_set, adapt2(resp1), ec);
|
||||||
BOOST_CHECK_EQUAL(ec, error_code{});
|
BOOST_CHECK_EQUAL(ec, error_code{});
|
||||||
|
|
||||||
deserialize(resp3_set, adapt2(fresp), ec);
|
deserialize(resp3_set, adapt2(resp2), ec);
|
||||||
BOOST_CHECK_EQUAL(ec, error_code{});
|
BOOST_CHECK_EQUAL(ec, error_code{});
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(fresp.get_reallocs(), 1u);
|
deserialize(resp3_set, adapt2(resp3), ec);
|
||||||
BOOST_CHECK_EQUAL(fresp.get_total_msgs(), 1u);
|
BOOST_CHECK_EQUAL(ec, error_code{});
|
||||||
|
|
||||||
auto const resp2 = from_flat(fresp);
|
BOOST_CHECK_EQUAL(resp2.get_reallocs(), 1u);
|
||||||
BOOST_CHECK_EQUAL(resp1, resp2);
|
BOOST_CHECK_EQUAL(resp2.get_total_msgs(), 1u);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(resp3.value().get_reallocs(), 1u);
|
||||||
|
BOOST_CHECK_EQUAL(resp3.value().get_total_msgs(), 1u);
|
||||||
|
|
||||||
|
auto const tmp2 = from_flat(resp2);
|
||||||
|
BOOST_CHECK_EQUAL(resp1, tmp2);
|
||||||
|
|
||||||
|
auto const tmp3 = from_flat(resp3);
|
||||||
|
BOOST_CHECK_EQUAL(resp1, tmp3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The response should be reusable.
|
// The response should be reusable.
|
||||||
@@ -446,3 +467,39 @@ BOOST_AUTO_TEST_CASE(flat_tree_copy_assign)
|
|||||||
BOOST_TEST((copy2 == resp));
|
BOOST_TEST((copy2 == resp));
|
||||||
BOOST_TEST((copy3 == resp));
|
BOOST_TEST((copy3 == resp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(generic_flat_response_simple_error)
|
||||||
|
{
|
||||||
|
generic_flat_response resp;
|
||||||
|
|
||||||
|
char const* wire = "-Error\r\n";
|
||||||
|
|
||||||
|
error_code ec;
|
||||||
|
deserialize(wire, adapt2(resp), ec);
|
||||||
|
BOOST_CHECK_EQUAL(ec, error_code{});
|
||||||
|
|
||||||
|
BOOST_TEST(!resp.has_value());
|
||||||
|
BOOST_TEST(resp.has_error());
|
||||||
|
auto const error = resp.error();
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(error.data_type, boost::redis::resp3::type::simple_error);
|
||||||
|
BOOST_CHECK_EQUAL(error.diagnostic, std::string{"Error"});
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(generic_flat_response_blob_error)
|
||||||
|
{
|
||||||
|
generic_flat_response resp;
|
||||||
|
|
||||||
|
char const* wire = "!5\r\nError\r\n";
|
||||||
|
|
||||||
|
error_code ec;
|
||||||
|
deserialize(wire, adapt2(resp), ec);
|
||||||
|
BOOST_CHECK_EQUAL(ec, error_code{});
|
||||||
|
|
||||||
|
BOOST_TEST(!resp.has_value());
|
||||||
|
BOOST_TEST(resp.has_error());
|
||||||
|
auto const error = resp.error();
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(error.data_type, boost::redis::resp3::type::blob_error);
|
||||||
|
BOOST_CHECK_EQUAL(error.diagnostic, std::string{"Error"});
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user