diff --git a/redis/command_factory.cc b/redis/command_factory.cc index 47c42e88b5..098f26ff01 100644 --- a/redis/command_factory.cc +++ b/redis/command_factory.cc @@ -36,6 +36,7 @@ shared_ptr command_factory::create(service::storage_proxy& pro { "select", [] (service::storage_proxy& proxy, request&& req) { return commands::select::prepare(proxy, std::move(req)); } }, { "get", [] (service::storage_proxy& proxy, request&& req) { return commands::get::prepare(proxy, std::move(req)); } }, { "exists", [] (service::storage_proxy& proxy, request&& req) { return commands::exists::prepare(proxy, std::move(req)); } }, + { "ttl", [] (service::storage_proxy& proxy, request&& req) { return commands::ttl::prepare(proxy, std::move(req)); } }, { "set", [] (service::storage_proxy& proxy, request&& req) { return commands::set::prepare(proxy, std::move(req)); } }, { "setex", [] (service::storage_proxy& proxy, request&& req) { return commands::setex::prepare(proxy, std::move(req)); } }, { "del", [] (service::storage_proxy& proxy, request&& req) { return commands::del::prepare(proxy, std::move(req)); } }, diff --git a/redis/commands.cc b/redis/commands.cc index 9a0f486a9d..1cb4d6654a 100644 --- a/redis/commands.cc +++ b/redis/commands.cc @@ -74,6 +74,26 @@ future exists::execute(service::storage_proxy& proxy, redis::redi }); } +shared_ptr ttl::prepare(service::storage_proxy& proxy, request&& req) { + if (req.arguments_size() != 1) { + throw wrong_arguments_exception(1, req.arguments_size(), req._command); + } + return seastar::make_shared (std::move(req._command), std::move(req._args[0])); +} + +future ttl::execute(service::storage_proxy& proxy, redis::redis_options& options, service_permit permit) { + return redis::read_strings(proxy, options, _key, permit).then([] (auto result) { + if (result->has_result()) { + if (result->has_ttl()) { + return redis_message::number(result->ttl().count()); + }else{ + return redis_message::number(-1); + } + } + return redis_message::number(-2); + }); +} + shared_ptr set::prepare(service::storage_proxy& proxy, request&& req) { if (req.arguments_size() != 2) { throw wrong_arguments_exception(2, req.arguments_size(), req._command); diff --git a/redis/commands.hh b/redis/commands.hh index 6b6600e7d9..9f7bdda432 100644 --- a/redis/commands.hh +++ b/redis/commands.hh @@ -48,6 +48,17 @@ public: virtual future execute(service::storage_proxy&, redis_options&, service_permit) override; }; +class ttl : public abstract_command { + bytes _key; +public: + static shared_ptr prepare(service::storage_proxy& proxy, request&& req); + ttl(bytes&& name, bytes&& key) + : abstract_command(std::move(name)) + , _key(std::move(key)) { + } + virtual future execute(service::storage_proxy&, redis_options&, service_permit) override; +}; + class set : public abstract_command { bytes _key; bytes _data; diff --git a/redis/query_utils.cc b/redis/query_utils.cc index c2ce727c4b..37179dfeb5 100644 --- a/redis/query_utils.cc +++ b/redis/query_utils.cc @@ -41,10 +41,13 @@ private: void add_cell(const column_definition& col, const std::optional& cell) { if (cell) { - cell->value().with_linearized([this, &col] (bytes_view cell_view) { + cell->value().with_linearized([this, &col, &cell] (bytes_view cell_view) { auto&& dv = col.type->deserialize_value(cell_view); auto&& d = dv.serialize_nonnull(); _data->_result = std::move(d); + if (cell->expiry().has_value()) { + _data->_ttl = cell->expiry().value() - gc_clock::now(); + } _data->_has_result = true; }); } diff --git a/redis/query_utils.hh b/redis/query_utils.hh index ac62b8ffce..80ef41ecc4 100644 --- a/redis/query_utils.hh +++ b/redis/query_utils.hh @@ -24,6 +24,7 @@ #include "seastar/core/shared_ptr.hh" #include "seastar/core/future.hh" #include "bytes.hh" +#include "gc_clock.hh" using namespace seastar; @@ -41,8 +42,11 @@ class redis_options; struct strings_result { bytes _result; bool _has_result; + ttl_opt _ttl; bytes& result() { return _result; } bool has_result() const { return _has_result; } + gc_clock::duration ttl() { return _ttl.value(); } + bool has_ttl() { return _ttl.has_value(); } }; future> read_strings(service::storage_proxy&, const redis_options&, const bytes&, service_permit);