2
0
mirror of https://github.com/boostorg/redis.git synced 2026-01-19 04:42:09 +00:00

Removes command enum.

This commit is contained in:
Marcelo Zimbres
2022-06-27 22:48:47 +02:00
parent 888bb476d7
commit 4f0d9de393
18 changed files with 88 additions and 934 deletions

View File

@@ -16,7 +16,6 @@ check_PROGRAMS += intro_sync
check_PROGRAMS += intro
check_PROGRAMS += containers
check_PROGRAMS += serialization
check_PROGRAMS += adapter
check_PROGRAMS += test_low_level
if HAVE_CXX20
check_PROGRAMS += test_high_level
@@ -24,7 +23,6 @@ endif
EXTRA_PROGRAMS =
EXTRA_PROGRAMS += subscriber
EXTRA_PROGRAMS += commands
if HAVE_CXX20
EXTRA_PROGRAMS += echo_server
EXTRA_PROGRAMS += echo_server_direct
@@ -39,13 +37,11 @@ CLEANFILES += $(EXTRA_PROGRAMS)
all: $(check_PROGRAMS) $(EXTRA_PROGRAMS)
intro_sync_SOURCES = $(top_srcdir)/tests/intro_sync.cpp
commands_SOURCES = $(top_srcdir)/tools/commands.cpp
subscriber_SOURCES = $(top_srcdir)/examples/subscriber.cpp
test_low_level_SOURCES = $(top_srcdir)/tests/low_level.cpp
intro_SOURCES = $(top_srcdir)/examples/intro.cpp
containers_SOURCES = $(top_srcdir)/examples/containers.cpp
serialization_SOURCES = $(top_srcdir)/examples/serialization.cpp
adapter_SOURCES = $(top_srcdir)/examples/adapter.cpp
if HAVE_CXX20
test_high_level_SOURCES = $(top_srcdir)/tests/high_level.cpp
chat_room_SOURCES = $(top_srcdir)/examples/chat_room.cpp

View File

@@ -22,11 +22,9 @@ namespace aedis {
namespace detail {
struct ignore_adapter {
template <class Command>
void
operator()(
std::size_t i,
Command cmd,
resp3::node<boost::string_view> const& nd,
boost::system::error_code& ec)
{
@@ -49,11 +47,9 @@ public:
adapter::detail::assigner<std::tuple_size<Tuple>::value - 1>::assign(adapters_, r);
}
template <class Command>
void
operator()(
std::size_t i,
Command cmd,
resp3::node<boost::string_view> const& nd,
boost::system::error_code& ec)
{
@@ -72,11 +68,9 @@ private:
public:
vector_adapter(Vector& v) : adapter_{adapter::adapt(v)} { }
template <class Command>
void
operator()(
std::size_t i,
Command cmd,
resp3::node<boost::string_view> const& nd,
boost::system::error_code& ec)
{

View File

@@ -7,450 +7,11 @@
#ifndef AEDIS_COMMAND_HPP
#define AEDIS_COMMAND_HPP
#include <ostream>
#include <string>
#include <boost/utility/string_view.hpp>
namespace aedis {
/** \brief Redis commands.
* \ingroup any
*
* The full list of of commands can be found at
* https://redis.io/commands.
*
* \remark This list was created with the help of the \c command
* command.
*/
enum class command {
/// https://redis.io/commands/acl
acl,
/// https://redis.io/commands/append
append,
/// https://redis.io/commands/asking
asking,
/// https://redis.io/commands/auth
auth,
/// https://redis.io/commands/bgrewriteaof
bgrewriteaof,
/// https://redis.io/commands/bgsave
bgsave,
/// https://redis.io/commands/bitcount
bitcount,
/// https://redis.io/commands/bitfield
bitfield,
/// https://redis.io/commands/bitfield_ro
bitfield_ro,
/// https://redis.io/commands/bitop
bitop,
/// https://redis.io/commands/bitpos
bitpos,
/// https://redis.io/commands/blpop
blpop,
/// https://redis.io/commands/brpop
brpop,
/// https://redis.io/commands/brpoplpush
brpoplpush,
/// https://redis.io/commands/bzpopmax
bzpopmax,
/// https://redis.io/commands/bzpopmin
bzpopmin,
/// https://redis.io/commands/client
client,
/// https://redis.io/commands/cluster
cluster,
/// https://redis.io/commands/command
command,
/// https://redis.io/commands/config
config,
/// https://redis.io/commands/dbsize
dbsize,
/// https://redis.io/commands/debug
debug,
/// https://redis.io/commands/decr
decr,
/// https://redis.io/commands/decrby
decrby,
/// https://redis.io/commands/del
del,
/// https://redis.io/commands/discard
discard,
/// https://redis.io/commands/dump
dump,
/// https://redis.io/commands/echo
echo,
/// https://redis.io/commands/eval
eval,
/// https://redis.io/commands/evalsha
evalsha,
/// https://redis.io/commands/exec
exec,
/// https://redis.io/commands/exists
exists,
/// https://redis.io/commands/expire
expire,
/// https://redis.io/commands/expireat
expireat,
/// https://redis.io/commands/flushall
flushall,
/// https://redis.io/commands/flushdb
flushdb,
/// https://redis.io/commands/geoadd
geoadd,
/// https://redis.io/commands/geodist
geodist,
/// https://redis.io/commands/geohash
geohash,
/// https://redis.io/commands/geopos
geopos,
/// https://redis.io/commands/georadius
georadius,
/// https://redis.io/commands/georadius_ro
georadius_ro,
/// https://redis.io/commands/georadiusbymember
georadiusbymember,
/// https://redis.io/commands/georadiusbymember_ro
georadiusbymember_ro,
/// https://redis.io/commands/get
get,
/// https://redis.io/commands/getbit
getbit,
/// https://redis.io/commands/getrange
getrange,
/// https://redis.io/commands/getset
getset,
/// https://redis.io/commands/hdel
hdel,
/// https://redis.io/commands/hello
hello,
/// https://redis.io/commands/hexists
hexists,
/// https://redis.io/commands/hget
hget,
/// https://redis.io/commands/hgetall
hgetall,
/// https://redis.io/commands/hincrby
hincrby,
/// https://redis.io/commands/hincrbyfloat
hincrbyfloat,
/// https://redis.io/commands/hkeys
hkeys,
/// https://redis.io/commands/hlen
hlen,
/// https://redis.io/commands/hmget
hmget,
/// https://redis.io/commands/hmset
hmset,
/// https://redis.io/commands/hscan
hscan,
/// https://redis.io/commands/hset
hset,
/// https://redis.io/commands/hsetnx
hsetnx,
/// https://redis.io/commands/hstrlen
hstrlen,
/// https://redis.io/commands/hvals
hvals,
/// https://redis.io/commands/incr
incr,
/// https://redis.io/commands/incrby
incrby,
/// https://redis.io/commands/incrbyfloat
incrbyfloat,
/// https://redis.io/commands/info
info,
/// https://redis.io/commands/keys
keys,
/// https://redis.io/commands/lastsave
lastsave,
/// https://redis.io/commands/latency
latency,
/// https://redis.io/commands/lindex
lindex,
/// https://redis.io/commands/linsert
linsert,
/// https://redis.io/commands/llen
llen,
/// https://redis.io/commands/lolwut
lolwut,
/// https://redis.io/commands/lpop
lpop,
/// https://redis.io/commands/lpos
lpos,
/// https://redis.io/commands/lpush
lpush,
/// https://redis.io/commands/lpushx
lpushx,
/// https://redis.io/commands/lrange
lrange,
/// https://redis.io/commands/lrem
lrem,
/// https://redis.io/commands/lset
lset,
/// https://redis.io/commands/ltrim
ltrim,
/// https://redis.io/commands/memory
memory,
/// https://redis.io/commands/mget
mget,
/// https://redis.io/commands/migrate
migrate,
/// https://redis.io/commands/module
module,
/// https://redis.io/commands/monitor
monitor,
/// https://redis.io/commands/move
move,
/// https://redis.io/commands/mset
mset,
/// https://redis.io/commands/msetnx
msetnx,
/// https://redis.io/commands/multi
multi,
/// https://redis.io/commands/object
object,
/// https://redis.io/commands/persist
persist,
/// https://redis.io/commands/pexpire
pexpire,
/// https://redis.io/commands/pexpireat
pexpireat,
/// https://redis.io/commands/pfadd
pfadd,
/// https://redis.io/commands/pfcount
pfcount,
/// https://redis.io/commands/pfdebug
pfdebug,
/// https://redis.io/commands/pfmerge
pfmerge,
/// https://redis.io/commands/pfselftest
pfselftest,
/// https://redis.io/commands/ping
ping,
/// https://redis.io/commands/post
post,
/// https://redis.io/commands/psetex
psetex,
/// https://redis.io/commands/psubscribe
psubscribe,
/// https://redis.io/commands/psync
psync,
/// https://redis.io/commands/pttl
pttl,
/// https://redis.io/commands/publish
publish,
/// https://redis.io/commands/pubsub
pubsub,
/// https://redis.io/commands/punsubscribe
punsubscribe,
/// https://redis.io/commands/randomkey
randomkey,
/// https://redis.io/commands/readonly
readonly,
/// https://redis.io/commands/readwrite
readwrite,
/// https://redis.io/commands/rename
rename,
/// https://redis.io/commands/renamenx
renamenx,
/// https://redis.io/commands/replconf
replconf,
/// https://redis.io/commands/replicaof
replicaof,
/// https://redis.io/commands/restore
restore,
/// https://redis.io/commands/role
role,
/// https://redis.io/commands/rpop
rpop,
/// https://redis.io/commands/rpoplpush
rpoplpush,
/// https://redis.io/commands/rpush
rpush,
/// https://redis.io/commands/rpushx
rpushx,
/// https://redis.io/commands/sadd
sadd,
/// https://redis.io/commands/save
save,
/// https://redis.io/commands/scan
scan,
/// https://redis.io/commands/scard
scard,
/// https://redis.io/commands/script
script,
/// https://redis.io/commands/sdiff
sdiff,
/// https://redis.io/commands/sdiffstore
sdiffstore,
/// https://redis.io/commands/select
select,
/// https://redis.io/topics/sentinel
sentinel,
/// https://redis.io/commands/set
set,
/// https://redis.io/commands/setbit
setbit,
/// https://redis.io/commands/setex
setex,
/// https://redis.io/commands/setnx
setnx,
/// https://redis.io/commands/setrange
setrange,
/// https://redis.io/commands/shutdown
shutdown,
/// https://redis.io/commands/sinter
sinter,
/// https://redis.io/commands/sinterstore
sinterstore,
/// https://redis.io/commands/sismember
sismember,
/// https://redis.io/commands/slaveof
slaveof,
/// https://redis.io/commands/slowlog
slowlog,
/// https://redis.io/commands/smembers
smembers,
/// https://redis.io/commands/smove
smove,
/// https://redis.io/commands/sort
sort,
/// https://redis.io/commands/spop
spop,
/// https://redis.io/commands/srandmember
srandmember,
/// https://redis.io/commands/srem
srem,
/// https://redis.io/commands/sscan
sscan,
/// https://redis.io/commands/stralgo
stralgo,
/// https://redis.io/commands/strlen
strlen,
/// https://redis.io/commands/subscribe
subscribe,
/// https://redis.io/commands/substr
substr,
/// https://redis.io/commands/sunion
sunion,
/// https://redis.io/commands/sunionstore
sunionstore,
/// https://redis.io/commands/swapdb
swapdb,
/// https://redis.io/commands/sync
sync,
/// https://redis.io/commands/time
time,
/// https://redis.io/commands/touch
touch,
/// https://redis.io/commands/ttl
ttl,
/// https://redis.io/commands/type
type,
/// https://redis.io/commands/unlink
unlink,
/// https://redis.io/commands/quit
quit,
/// https://redis.io/commands/unsubscribe
unsubscribe,
/// https://redis.io/commands/unwatch
unwatch,
/// https://redis.io/commands/wait
wait,
/// https://redis.io/commands/watch
watch,
/// https://redis.io/commands/xack
xack,
/// https://redis.io/commands/xadd
xadd,
/// https://redis.io/commands/xclaim
xclaim,
/// https://redis.io/commands/xdel
xdel,
/// https://redis.io/commands/xgroup
xgroup,
/// https://redis.io/commands/xinfo
xinfo,
/// https://redis.io/commands/xlen
xlen,
/// https://redis.io/commands/xpending
xpending,
/// https://redis.io/commands/xrange
xrange,
/// https://redis.io/commands/xread
xread,
/// https://redis.io/commands/xreadgroup
xreadgroup,
/// https://redis.io/commands/xrevrange
xrevrange,
/// https://redis.io/commands/xsetid
xsetid,
/// https://redis.io/commands/xtrim
xtrim,
/// https://redis.io/commands/zadd
zadd,
/// https://redis.io/commands/zcard
zcard,
/// https://redis.io/commands/zcount
zcount,
/// https://redis.io/commands/zincrby
zincrby,
/// https://redis.io/commands/zinterstore
zinterstore,
/// https://redis.io/commands/zlexcount
zlexcount,
/// https://redis.io/commands/zpopmax
zpopmax,
/// https://redis.io/commands/zpopmin
zpopmin,
/// https://redis.io/commands/zrange
zrange,
/// https://redis.io/commands/zrangebylex
zrangebylex,
/// https://redis.io/commands/zrangebyscore
zrangebyscore,
/// https://redis.io/commands/zrank
zrank,
/// https://redis.io/commands/zrem
zrem,
/// https://redis.io/commands/zremrangebylex
zremrangebylex,
/// https://redis.io/commands/zremrangebyrank
zremrangebyrank,
/// https://redis.io/commands/zremrangebyscore
zremrangebyscore,
/// https://redis.io/commands/zrevrange
zrevrange,
/// https://redis.io/commands/zrevrangebylex
zrevrangebylex,
/// https://redis.io/commands/zrevrangebyscore
zrevrangebyscore,
/// https://redis.io/commands/zrevrank
zrevrank,
/// https://redis.io/commands/zscan
zscan,
/// https://redis.io/commands/zscore
zscore,
/// https://redis.io/commands/zunionstore
zunionstore,
/// Invalid command.
invalid
};
/** \brief Converts the command to a string.
* \ingroup any
* \param c The command to convert.
*/
char const* to_string(command c);
/** \brief Writes the command string to the stream.
* \ingroup any
* \param os Output stream.
* \param c Redis command
*/
std::ostream& operator<<(std::ostream& os, command c);
// Checks whether a command has push response.
bool has_push_response(command cmd);
bool has_push_response(boost::string_view cmd);
} // aedis

View File

@@ -244,9 +244,9 @@ public:
auto f =
[adapter]
(resp3::node<boost::string_view> const& node, boost::system::error_code& ec) mutable
{
adapter(std::size_t(-1), command::invalid, node, ec);
};
{
adapter(std::size_t(-1), node, ec);
};
return boost::asio::async_compose
< CompletionToken
@@ -310,7 +310,7 @@ private:
reqs_.push_back(make_req_info());
reqs_.back()->timer.expires_at(std::chrono::steady_clock::time_point::max());
reqs_.back()->req = &req;
reqs_.back()->n_cmds = req.commands().size();
reqs_.back()->n_cmds = req.commands();
reqs_.back()->stop = false;
return empty && socket_ != nullptr;
@@ -452,9 +452,7 @@ private:
auto const size = cfg_.coalesce_requests ? reqs_.size() : 1;
for (auto i = 0UL; i < size; ++i) {
payload_ += reqs_.at(i)->req->payload();
for (auto cmd : reqs_.at(i)->req->commands()) {
cmds_.push(cmd.first);
}
cmds_ += reqs_.at(i)->req->commands();
}
}
@@ -475,7 +473,7 @@ private:
std::string read_buffer_;
std::string payload_;
std::queue<command> cmds_;
std::size_t cmds_ = 0;
std::deque<std::shared_ptr<req_info>> reqs_;
std::vector<std::shared_ptr<req_info>> pool_;

View File

@@ -64,7 +64,7 @@ struct hello_op {
{
BOOST_ASSERT(conn->socket_ != nullptr);
conn->req_.clear();
conn->req_.push(command::hello, 3);
conn->req_.push("HELLO", 3);
conn->ping_timer_.expires_after(std::chrono::seconds{2});
yield resp3::async_exec(*conn->socket_, conn->ping_timer_, conn->req_, adapter::adapt(), conn->make_dynamic_buffer(), std::move(self));
self.complete(ec);
@@ -156,7 +156,7 @@ struct exec_read_op {
// Loop reading the responses to this request.
BOOST_ASSERT(!conn->reqs_.empty());
while (conn->reqs_.front()->expects_response()) {
BOOST_ASSERT(!conn->cmds_.empty());
BOOST_ASSERT(conn->cmds_ != 0);
//-----------------------------------
// If we detect a push in the middle of a request we have
@@ -184,7 +184,7 @@ struct exec_read_op {
yield
resp3::async_read(*conn->socket_, conn->make_dynamic_buffer(),
[i = index, adpt = adapter, cmd = conn->cmds_.front()] (resp3::node<boost::string_view> const& nd, boost::system::error_code& ec) mutable { adpt(i, cmd, nd, ec); },
[i = index, adpt = adapter] (resp3::node<boost::string_view> const& nd, boost::system::error_code& ec) mutable { adpt(i, nd, ec); },
std::move(self));
++index;
@@ -199,8 +199,8 @@ struct exec_read_op {
BOOST_ASSERT(conn->reqs_.front()->expects_response());
conn->reqs_.front()->pop();
BOOST_ASSERT(!conn->cmds_.empty());
conn->cmds_.pop();
BOOST_ASSERT(conn->cmds_ != 0);
--conn->cmds_;
}
self.complete({}, read_size);
@@ -275,7 +275,7 @@ struct exec_exit_op {
// 2. There are enqueued commands that will be written, while
// we are writing we have to listen for messages. e.g. server
// pushes.
if (conn->cmds_.empty()) {
if (conn->cmds_ == 0) {
yield conn->read_channel_.async_send({}, 0, std::move(self));
}
@@ -320,7 +320,7 @@ struct exec_op {
}
BOOST_ASSERT(!conn->reqs_.empty());
if (conn->cmds_.empty() && conn->payload_.empty()) {
if (conn->cmds_ == 0 && conn->payload_.empty()) {
yield conn->async_exec_write(std::move(self));
if (ec) {
conn->close();
@@ -370,7 +370,7 @@ struct ping_op {
}
conn->req_.clear();
conn->req_.push(command::ping);
conn->req_.push("PING");
yield conn->async_exec(conn->req_, aedis::adapt(), std::move(self));
if (ec) {
self.complete(ec);
@@ -543,7 +543,7 @@ struct reader_op {
|| (!conn->reqs_.empty() && !conn->reqs_.front()->expects_response())) {
yield async_send_receive(conn->push_channel_, std::move(self));
} else {
BOOST_ASSERT(!conn->cmds_.empty());
BOOST_ASSERT(conn->cmds_ != 0);
BOOST_ASSERT(conn->reqs_.front()->expects_response());
yield async_send_receive(conn->read_channel_, std::move(self));
}

View File

@@ -8,237 +8,12 @@
namespace aedis {
char const* to_string(command c)
bool has_push_response(boost::string_view cmd)
{
static char const* table[] = {
"ACL",
"APPEND",
"ASKING",
"AUTH",
"BGREWRITEAOF",
"BGSAVE",
"BITCOUNT",
"BITFIELD",
"BITFIELD_RO",
"BITOP",
"BITPOS",
"BLPOP",
"BRPOP",
"BRPOPLPUSH",
"BZPOPMAX",
"BZPOPMIN",
"CLIENT",
"CLUSTER",
"COMMAND",
"CONFIG",
"DBSIZE",
"DEBUG",
"DECR",
"DECRBY",
"DEL",
"DISCARD",
"DUMP",
"ECHO",
"EVAL",
"EVALSHA",
"EXEC",
"EXISTS",
"EXPIRE",
"EXPIREAT",
"FLUSHALL",
"FLUSHDB",
"GEOADD",
"GEODIST",
"GEOHASH",
"GEOPOS",
"GEORADIUS",
"GEORADIUS_RO",
"GEORADIUSBYMEMBER",
"GEORADIUSBYMEMBER_RO",
"GET",
"GETBIT",
"GETRANGE",
"GETSET",
"HDEL",
"HELLO",
"HEXISTS",
"HGET",
"HGETALL",
"HINCRBY",
"HINCRBYFLOAT",
"HKEYS",
"HLEN",
"HMGET",
"HMSET",
"HSCAN",
"HSET",
"HSETNX",
"HSTRLEN",
"HVALS",
"INCR",
"INCRBY",
"INCRBYFLOAT",
"INFO",
"KEYS",
"LASTSAVE",
"LATENCY",
"LINDEX",
"LINSERT",
"LLEN",
"LOLWUT",
"LPOP",
"LPOS",
"LPUSH",
"LPUSHX",
"LRANGE",
"LREM",
"LSET",
"LTRIM",
"MEMORY",
"MGET",
"MIGRATE",
"MODULE",
"MONITOR",
"MOVE",
"MSET",
"MSETNX",
"MULTI",
"OBJECT",
"PERSIST",
"PEXPIRE",
"PEXPIREAT",
"PFADD",
"PFCOUNT",
"PFDEBUG",
"PFMERGE",
"PFSELFTEST",
"PING",
"POST",
"PSETEX",
"PSUBSCRIBE",
"PSYNC",
"PTTL",
"PUBLISH",
"PUBSUB",
"PUNSUBSCRIBE",
"RANDOMKEY",
"READONLY",
"READWRITE",
"RENAME",
"RENAMENX",
"REPLCONF",
"REPLICAOF",
"RESTORE",
"ROLE",
"RPOP",
"RPOPLPUSH",
"RPUSH",
"RPUSHX",
"SADD",
"SAVE",
"SCAN",
"SCARD",
"SCRIPT",
"SDIFF",
"SDIFFSTORE",
"SELECT",
"SENTINEL",
"SET",
"SETBIT",
"SETEX",
"SETNX",
"SETRANGE",
"SHUTDOWN",
"SINTER",
"SINTERSTORE",
"SISMEMBER",
"SLAVEOF",
"SLOWLOG",
"SMEMBERS",
"SMOVE",
"SORT",
"SPOP",
"SRANDMEMBER",
"SREM",
"SSCAN",
"STRALGO",
"STRLEN",
"SUBSCRIBE",
"SUBSTR",
"SUNION",
"SUNIONSTORE",
"SWAPDB",
"SYNC",
"TIME",
"TOUCH",
"TTL",
"TYPE",
"UNLINK",
"QUIT",
"UNSUBSCRIBE",
"UNWATCH",
"WAIT",
"WATCH",
"XACK",
"XADD",
"XCLAIM",
"XDEL",
"XGROUP",
"XINFO",
"XLEN",
"XPENDING",
"XRANGE",
"XREAD",
"XREADGROUP",
"XREVRANGE",
"XSETID",
"XTRIM",
"ZADD",
"ZCARD",
"ZCOUNT",
"ZINCRBY",
"ZINTERSTORE",
"ZLEXCOUNT",
"ZPOPMAX",
"ZPOPMIN",
"ZRANGE",
"ZRANGEBYLEX",
"ZRANGEBYSCORE",
"ZRANK",
"ZREM",
"ZREMRANGEBYLEX",
"ZREMRANGEBYRANK",
"ZREMRANGEBYSCORE",
"ZREVRANGE",
"ZREVRANGEBYLEX",
"ZREVRANGEBYSCORE",
"ZREVRANK",
"ZSCAN",
"ZSCORE",
"ZUNIONSTORE",
"INVALID",
};
return table[static_cast<int>(c)];
}
std::ostream& operator<<(std::ostream& os, command c)
{
os << to_string(c);
return os;
}
bool has_push_response(command cmd)
{
switch (cmd) {
case command::subscribe:
case command::unsubscribe:
case command::psubscribe:
return true;
default:
return false;
}
if (cmd == "SUBSCRIBE") return true;
if (cmd == "PSUBSCRIBE") return true;
if (cmd == "UNSUBSCRIBE") return true;
return false;
}
} // aedis

View File

@@ -8,7 +8,6 @@
#define AEDIS_RESP3_REQUEST_HPP
#include <boost/hana.hpp>
#include <aedis/command.hpp>
#include <aedis/resp3/compose.hpp>
// NOTE: Consider detecting tuples in the type in the parameter pack
@@ -31,11 +30,11 @@ namespace resp3 {
*
* @code
* request r;
* r.push(command::hello, 3);
* r.push(command::flushall);
* r.push(command::ping);
* r.push(command::incr, "key");
* r.push(command::quit);
* r.push("HELLO", 3);
* r.push("FLUSHALL");
* r.push("PING");
* r.push("PING", "key");
* r.push("QUIT");
* co_await async_write(socket, buffer(r));
* @endcode
*
@@ -46,12 +45,12 @@ namespace resp3 {
*/
class request {
public:
/** \brief Returns a list of commands contained in this request.
/** \brief Returns the number of commands contained in this request.
*
* \returns A container with the commands contained in the request
* with their sizes: \c std::vector<std::pair<command, std::size_t>>.
* \returns A container with the commands contained in the
* request.
*/
auto const& commands() const noexcept { return commands_;};
std::size_t commands() const noexcept { return commands_;};
/// Returns the request payload.
auto const& payload() const noexcept { return payload_;}
@@ -72,7 +71,7 @@ public:
void clear()
{
payload_.clear();
commands_.clear();
commands_ = 0;
}
/** @brief Appends a new command to the end of the request.
@@ -81,7 +80,7 @@ public:
*
* \code
* request req;
* req.push(command::set, "key", "some string", "EX", "2");
* req.push("SET", "key", "some string", "EX", "2");
* \endcode
*
* will add the \c set command with value "some string" and an
@@ -91,7 +90,7 @@ public:
* \param args Command arguments.
*/
template <class... Ts>
void push(command cmd, Ts const&... args)
void push(boost::string_view cmd, Ts const&... args)
{
using boost::hana::for_each;
using boost::hana::make_tuple;
@@ -100,12 +99,12 @@ public:
auto const before = payload_.size();
auto constexpr pack_size = sizeof...(Ts);
resp3::add_header(payload_, type::array, 1 + pack_size);
resp3::add_bulk(payload_, to_string(cmd));
resp3::add_bulk(payload_, cmd);
resp3::add_bulk(payload_, make_tuple(args...));
auto const after = payload_.size();
if (!has_push_response(cmd))
commands_.push_back(std::make_pair(cmd, after - before));
++commands_;
}
/** @brief Appends a new command to the end of the request.
@@ -121,7 +120,7 @@ public:
* };
*
* request req;
* req.push_range2(command::hset, "key", std::cbegin(map), std::cend(map));
* req.push_range2("HSET", "key", std::cbegin(map), std::cend(map));
* @endcode
*
* \param cmd The command e.g. Redis or Sentinel command.
@@ -130,7 +129,7 @@ public:
* \param end Iterator to the end of the range.
*/
template <class Key, class ForwardIterator>
void push_range2(command cmd, Key const& key, ForwardIterator begin, ForwardIterator end)
void push_range2(boost::string_view cmd, Key const& key, ForwardIterator begin, ForwardIterator end)
{
using value_type = typename std::iterator_traits<ForwardIterator>::value_type;
using resp3::type;
@@ -143,7 +142,7 @@ public:
auto constexpr size = resp3::bulk_counter<value_type>::size;
auto const distance = std::distance(begin, end);
resp3::add_header(payload_, type::array, 2 + size * distance);
resp3::add_bulk(payload_, to_string(cmd));
resp3::add_bulk(payload_, cmd);
resp3::add_bulk(payload_, key);
for (; begin != end; ++begin)
@@ -151,7 +150,7 @@ public:
auto const after = payload_.size();
if (!has_push_response(cmd))
commands_.push_back(std::make_pair(cmd, after - before));
++commands_;
}
/** @brief Appends a new command to the end of the request.
@@ -164,7 +163,7 @@ public:
* { "channel1" , "channel2" , "channel3" }
*
* request req;
* req.push(command::subscribe, std::cbegin(channels), std::cedn(channels));
* req.push("SUBSCRIBE", std::cbegin(channels), std::cedn(channels));
* \endcode
*
* \param cmd The Redis command
@@ -172,7 +171,7 @@ public:
* \param end Iterator to the end of the range.
*/
template <class ForwardIterator>
void push_range2(command cmd, ForwardIterator begin, ForwardIterator end)
void push_range2(boost::string_view cmd, ForwardIterator begin, ForwardIterator end)
{
using value_type = typename std::iterator_traits<ForwardIterator>::value_type;
using resp3::type;
@@ -184,14 +183,14 @@ public:
auto constexpr size = resp3::bulk_counter<value_type>::size;
auto const distance = std::distance(begin, end);
resp3::add_header(payload_, type::array, 1 + size * distance);
resp3::add_bulk(payload_, to_string(cmd));
resp3::add_bulk(payload_, cmd);
for (; begin != end; ++begin)
resp3::add_bulk(payload_, *begin);
auto const after = payload_.size();
if (!has_push_response(cmd))
commands_.push_back(std::make_pair(cmd, before - after));
++commands_;
}
/** @brief Appends a new command to the end of the request.
@@ -199,7 +198,7 @@ public:
* Equivalent to the overload taking a range (i.e. send_range2).
*/
template <class Key, class Range>
void push_range(command cmd, Key const& key, Range const& range)
void push_range(boost::string_view cmd, Key const& key, Range const& range)
{
using std::begin;
using std::end;
@@ -211,7 +210,7 @@ public:
* Equivalent to the overload taking a range (i.e. send_range2).
*/
template <class Range>
void push_range(command cmd, Range const& range)
void push_range(boost::string_view cmd, Range const& range)
{
using std::begin;
using std::end;
@@ -220,7 +219,7 @@ public:
private:
std::string payload_;
std::vector<std::pair<command, std::size_t>> commands_;
std::size_t commands_ = 0;
bool retry_ = false;
};

View File

@@ -1,57 +0,0 @@
/* Copyright (c) 2018-2022 Marcelo Zimbres Silva (mzimbres@gmail.com)
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
*/
#include <map>
#include <set>
#include <vector>
#include <iostream>
#include <boost/asio.hpp>
#include <aedis/aedis.hpp>
#include <aedis/src.hpp>
#include "print.hpp"
namespace net = boost::asio;
namespace adapter = aedis::adapter;
using aedis::command;
using aedis::resp3::request;
using connection = aedis::connection<>;
using node_type = aedis::resp3::node<boost::string_view>;
using error_code = boost::system::error_code;
auto handler =[](auto ec, auto...)
{ std::cout << ec.message() << std::endl; };
int main()
{
request req;
req.push(command::ping);
req.push(command::incr, "some-key");
req.push(command::quit);
std::string r0;
int r1;
auto adapter =
[ a0 = adapter::adapt(r0)
, a1 = adapter::adapt(r1)
](std::size_t, command cmd, node_type const& nd, error_code& ec) mutable
{
switch (cmd) {
case command::ping: a0(nd, ec); break;
case command::incr: a1(nd, ec); break;
default:;
}
};
net::io_context ioc;
connection db{ioc};
db.async_exec("127.0.0.1", "6379", req, adapter, handler);
ioc.run();
std::cout
<< "ping: " << r0 << "\n"
<< "incr: " << r1 << "\n";
}

View File

@@ -15,7 +15,6 @@
namespace net = boost::asio;
using aedis::adapt;
using aedis::command;
using aedis::resp3::request;
using tcp_socket = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::socket>;
using tcp_acceptor = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::acceptor>;
@@ -56,7 +55,7 @@ private:
auto dbuffer = net::dynamic_buffer(msg, 1024);
for (;;) {
auto const n = co_await net::async_read_until(socket_, dbuffer, "\n");
req.push(command::publish, "channel", msg);
req.push("PUBLISH", "channel", msg);
co_await db->async_exec(req);
req.clear();
msg.erase(0, n);
@@ -102,7 +101,7 @@ reader(
std::shared_ptr<sessions_type> sessions)
{
request req;
req.push(command::subscribe, "channel");
req.push("SUBSCRIBE", "channel");
co_await db->async_exec(req);
for (response_type resp;;) {

View File

@@ -14,7 +14,6 @@
namespace net = boost::asio;
using boost::optional;
using aedis::adapt;
using aedis::command;
using aedis::resp3::request;
using connection = aedis::connection<>;
@@ -27,13 +26,13 @@ int main()
{{"key1", 10}, {"key2", 20}, {"key3", 30}};
request req;
req.push_range(command::rpush, "rpush-key", vec);
req.push_range(command::hset, "hset-key", map);
req.push(command::multi);
req.push(command::lrange, "rpush-key", 0, -1);
req.push(command::hgetall, "hset-key");
req.push(command::exec);
req.push(command::quit);
req.push_range("RPUSH", "rpush-key", vec);
req.push_range("HSET", "hset-key", map);
req.push("MULTI");
req.push("LRANGE", "rpush-key", 0, -1);
req.push("HGETALL", "hset-key");
req.push("EXEC");
req.push("QUIT");
std::tuple<
std::string, // rpush

View File

@@ -12,7 +12,6 @@
namespace net = boost::asio;
using aedis::adapt;
using aedis::command;
using aedis::resp3::request;
using tcp_socket = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::socket>;
using tcp_acceptor = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::acceptor>;
@@ -27,7 +26,7 @@ net::awaitable<void> echo_loop(tcp_socket socket, std::shared_ptr<connection> db
for (;;) {
auto n = co_await net::async_read_until(socket, net::dynamic_buffer(buffer, 1024), "\n");
req.push(command::ping, buffer);
req.push("PING", buffer);
co_await db->async_exec(req, adapt(resp));
co_await net::async_write(socket, net::buffer(std::get<0>(resp)));
std::get<0>(resp).clear();

View File

@@ -13,7 +13,6 @@
namespace net = boost::asio;
using aedis::adapt;
using aedis::command;
using aedis::resp3::request;
using connection = aedis::connection<>;
@@ -22,8 +21,9 @@ int main()
net::io_context ioc;
request req;
req.push(command::ping, "Ping example");
req.push(command::quit);
req.push("PING", "Ping example");
req.push("QUIT");
std::tuple<std::string, std::string> resp;
connection db{ioc};

View File

View File

@@ -17,7 +17,6 @@
#include "print.hpp"
namespace net = boost::asio;
using aedis::command;
using aedis::resp3::request;
using connection = aedis::connection<>;
using namespace boost::json;
@@ -92,9 +91,9 @@ int main()
};
request req;
req.push_range(command::sadd, "sadd-key", users);
req.push(command::smembers, "sadd-key");
req.push(command::quit);
req.push_range("SADD", "sadd-key", users);
req.push("SMEMBERS", "sadd-key");
req.push("QUIT");
std::tuple<int, std::set<user>, std::string> resp;

View File

@@ -13,7 +13,6 @@
namespace net = boost::asio;
using aedis::adapt;
using aedis::command;
using aedis::resp3::request;
using aedis::resp3::node;
using tcp_socket = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::socket>;
@@ -56,7 +55,7 @@ int main()
net::io_context ioc;
auto db = std::make_shared<connection>(ioc);
request req;
req.push(command::subscribe, "channel");
req.push("SUBSCRIBE", "channel");
db->async_exec("127.0.0.1", "6379", req, adapt(), handler);
net::co_spawn(ioc, reader(db), net::detached);
ioc.run();

View File

@@ -21,7 +21,6 @@
namespace net = boost::asio;
namespace resp3 = aedis::resp3;
using aedis::command;
using aedis::resp3::request;
using connection = aedis::connection<>;
using error_code = boost::system::error_code;
@@ -67,7 +66,7 @@ void test_quit()
auto db = std::make_shared<connection>(ioc);
request req;
req.push(command::quit);
req.push("QUIT");
db->async_exec(req, aedis::adapt(), [](auto ec, auto r){
expect_no_error(ec, "test_quit");
});
@@ -82,7 +81,7 @@ void test_quit()
void test_quit2()
{
request req;
req.push(command::quit);
req.push("QUIT");
net::io_context ioc;
auto db = std::make_shared<connection>(ioc);
@@ -116,8 +115,8 @@ void test_push1()
auto db = std::make_shared<connection>(ioc);
request req;
req.push(command::subscribe, "channel");
req.push(command::quit);
req.push("SUBSCRIBE", "channel");
req.push("QUIT");
db->async_exec("127.0.0.1", "6379", req, aedis::adapt(), [](auto ec, auto r){
expect_error(ec, net::error::misc_errors::eof, "test_push1");
@@ -133,7 +132,7 @@ net::awaitable<void> run5(std::shared_ptr<connection> db)
{
{
request req;
req.push(command::quit);
req.push("QUIT");
db->async_exec("127.0.0.1", "6379", req, aedis::adapt(), [](auto ec, auto){
// TODO: This should be eof.
expect_error(ec, net::error::basic_errors::operation_aborted, "run5a");
@@ -142,7 +141,7 @@ net::awaitable<void> run5(std::shared_ptr<connection> db)
{
request req;
req.push(command::quit);
req.push("QUIT");
db->async_exec("127.0.0.1", "6379", req, aedis::adapt(), [](auto ec, auto){
expect_error(ec, net::error::misc_errors::eof, "run5b");
});
@@ -170,7 +169,7 @@ void test_no_push_reader1()
auto db = std::make_shared<connection>(ioc, cfg);
request req;
req.push(command::subscribe, "channel");
req.push("SUBSCRIBE", "channel");
db->async_exec("127.0.0.1", "6379", req, aedis::adapt(), [](auto ec, auto r){
expect_error(ec, boost::asio::experimental::channel_errc::channel_cancelled, "test_no_push_reader1");
@@ -188,7 +187,7 @@ void test_no_push_reader2()
request req;
// Wrong command.
req.push(command::subscribe);
req.push("SUBSCRIBE");
db->async_exec("127.0.0.1", "6379", req, aedis::adapt(), [](auto ec, auto r){
expect_error(ec, boost::asio::experimental::channel_errc::channel_cancelled, "test_no_push_reader2");
@@ -206,8 +205,8 @@ void test_no_push_reader3()
request req;
// Wrong command.
req.push(command::ping, "Message");
req.push(command::subscribe);
req.push("PING", "Message");
req.push("SUBSCRIBE");
db->async_exec("127.0.0.1", "6379", req, aedis::adapt(), [](auto ec, auto r){
expect_error(ec, aedis::error::idle_timeout, "test_no_push_reader3");
@@ -227,7 +226,7 @@ void test_idle()
auto db = std::make_shared<connection>(ioc, cfg);
request req;
req.push(command::client, "PAUSE", 5000);
req.push("CLIENT", "PAUSE", 5000);
db->async_exec(req, aedis::adapt(), [](auto ec, auto r){
expect_no_error(ec, "test_idle");
@@ -246,14 +245,14 @@ auto handler =[](auto ec, auto...)
void test_push2()
{
request req1;
req1.push(command::ping, "Message1");
req1.push("PING", "Message1");
request req2;
req2.push(command::subscribe, "channel");
req2.push("SUBSCRIBE", "channel");
request req3;
req3.push(command::ping, "Message2");
req3.push(command::quit);
req3.push("PING", "Message2");
req3.push("QUIT");
std::tuple<std::string, std::string> resp;
@@ -276,13 +275,13 @@ push_consumer3(std::shared_ptr<connection> db)
void test_push3()
{
request req1;
req1.push(command::ping, "Message1");
req1.push("PING", "Message1");
request req2;
req2.push(command::subscribe, "channel");
req2.push("SUBSCRIBE", "channel");
request req3;
req3.push(command::quit);
req3.push("QUIT");
net::io_context ioc;
auto db = std::make_shared<connection>(ioc);
@@ -305,13 +304,13 @@ void test_push3()
void test_exec_while_processing()
{
request req1;
req1.push(command::ping, "Message1");
req1.push("PING", "Message1");
request req2;
req2.push(command::subscribe, "channel");
req2.push("SUBSCRIBE", "channel");
request req3;
req3.push(command::quit);
req3.push("QUIT");
net::io_context ioc;
auto db = std::make_shared<connection>(ioc);

View File

@@ -15,7 +15,6 @@
namespace net = boost::asio;
namespace resp3 = aedis::resp3;
using aedis::command;
using aedis::resp3::request;
using aedis::adapter::adapt;
using net::ip::tcp;
@@ -31,9 +30,9 @@ int main()
// Creates the request and writes to the socket.
request req;
req.push(command::hello, 3);
req.push(command::ping);
req.push(command::quit);
req.push("HELLO", 3);
req.push("PING");
req.push("QUIT");
resp3::write(socket, req);
// Responses

View File

@@ -1,105 +0,0 @@
/* Copyright (c) 2018-2022 Marcelo Zimbres Silva (mzimbres@gmail.com)
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
*/
#include <iostream>
#include <algorithm>
#include <cctype>
#include <boost/asio/connect.hpp>
#include <aedis/aedis.hpp>
#include <aedis/src.hpp>
namespace net = boost::asio;
namespace resp3 = aedis::resp3;
using aedis::command;
using aedis::resp3::request;
using aedis::resp3::node;
using aedis::adapter::adapt;
using net::ip::tcp;
using net::write;
using net::buffer;
using net::dynamic_buffer;
std::string toupper(std::string s)
{
std::transform(std::begin(s), std::end(s), std::begin(s),
[](unsigned char c){ return std::toupper(c); });
return s;
}
std::vector<std::string>
get_cmd_names(std::vector<node<std::string>> const& resp)
{
if (resp.empty()) {
std::cerr << "Response is empty." << std::endl;
return {};
}
std::vector<std::string> ret;
for (auto i = 0ULL; i < resp.size(); ++i) {
if (resp.at(i).depth == 1)
ret.push_back(resp.at(i + 1).value);
}
std::sort(std::begin(ret), std::end(ret));
return ret;
}
void print_cmds_enum(std::vector<std::string> const& cmds)
{
std::cout << "enum class command {\n";
for (auto const& cmd : cmds) {
std::cout
<< " /// https://redis.io/commands/" << cmd << "\n"
<< " " << cmd << ",\n";
}
std::cout << " invalid\n};\n";
}
void print_cmds_strs(std::vector<std::string> const& cmds)
{
std::cout << " static char const* table[] = {\n";
for (auto const& cmd : cmds) {
std::cout << " \"" << toupper(cmd) << "\",\n";
}
std::cout << " };\n";
}
int main()
{
try {
net::io_context ioc;
tcp::resolver resv{ioc};
auto const res = resv.resolve("127.0.0.1", "6379");
tcp::socket socket{ioc};
net::connect(socket, res);
request req;
req.push(command::hello, 3);
req.push(command::command);
req.push(command::quit);
write(socket, buffer(req.payload()));
std::vector<node<std::string>> resp;
std::string buffer;
resp3::read(socket, dynamic_buffer(buffer));
resp3::read(socket, dynamic_buffer(buffer), adapt(resp));
resp3::read(socket, dynamic_buffer(buffer));
auto const cmds = get_cmd_names(resp);
print_cmds_enum(cmds);
std::cout << "\n";
print_cmds_strs(cmds);
} catch (std::exception const& e) {
std::cerr << e.what() << std::endl;
}
}