Skip to content

Commit

Permalink
feat redis: add support for GT and LT flags in ZADD
Browse files Browse the repository at this point in the history
Support for `GT` and `LT` flags in `ZADD` and tests.
P.S: I didn't find which version it started, so I use 6.2.0. In 6.0 it does not work
Tests: протестировано CI

Pull Request resolved: #777
commit_hash:9acec1b79bb1bb4a476fda9a95ea2fd49250dad7
  • Loading branch information
Greenvi4 authored and apolukhin committed Dec 23, 2024
1 parent 1410cb1 commit e680053
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 5 deletions.
38 changes: 33 additions & 5 deletions redis/include/userver/storages/redis/command_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,51 @@ struct GeosearchOptions {

struct ZaddOptions {
enum class Exist { kAddAlways, kAddIfNotExist, kAddIfExist };
enum class Compare { kNone, kGreaterThan, kLessThan };
enum class ReturnValue { kAddedCount, kChangedCount };

ZaddOptions() = default;
constexpr ZaddOptions(Exist exist, ReturnValue return_value = ReturnValue::kAddedCount)
: exist(exist), return_value(return_value) {}
constexpr ZaddOptions(ReturnValue return_value, Exist exist = Exist::kAddAlways)
: exist(exist), return_value(return_value) {}
constexpr ZaddOptions(
Exist exist,
ReturnValue return_value = ReturnValue::kAddedCount,
Compare compare = Compare::kNone
)
: exist(exist), compare(compare), return_value(return_value) {}
constexpr ZaddOptions(Exist exist, Compare compare, ReturnValue return_value = ReturnValue::kAddedCount)
: exist(exist), compare(compare), return_value(return_value) {}

constexpr ZaddOptions(ReturnValue return_value, Exist exist = Exist::kAddAlways, Compare compare = Compare::kNone)
: exist(exist), compare(compare), return_value(return_value) {}
constexpr ZaddOptions(ReturnValue return_value, Compare compare, Exist exist = Exist::kAddAlways)
: exist(exist), compare(compare), return_value(return_value) {}

constexpr ZaddOptions(
Compare compare,
Exist exist = Exist::kAddAlways,
ReturnValue return_value = ReturnValue::kAddedCount
)
: exist(exist), compare(compare), return_value(return_value) {}
constexpr ZaddOptions(Compare compare, ReturnValue return_value, Exist exist = Exist::kAddAlways)
: exist(exist), compare(compare), return_value(return_value) {}

Exist exist = Exist::kAddAlways;
Compare compare = Compare::kNone;
ReturnValue return_value = ReturnValue::kAddedCount;
};

constexpr ZaddOptions operator|(ZaddOptions::Exist exist, ZaddOptions::ReturnValue return_value) {
return {exist, return_value};
}
constexpr ZaddOptions operator|(ZaddOptions::Exist exist, ZaddOptions::Compare compare) { return {exist, compare}; }
constexpr ZaddOptions operator|(ZaddOptions::Compare compare, ZaddOptions::Exist exist) { return {compare, exist}; }
constexpr ZaddOptions operator|(ZaddOptions::Compare compare, ZaddOptions::ReturnValue return_value) {
return {compare, return_value};
}
constexpr ZaddOptions operator|(ZaddOptions::ReturnValue return_value, ZaddOptions::Exist exist) {
return {exist, return_value};
return {return_value, exist};
}
constexpr ZaddOptions operator|(ZaddOptions::ReturnValue return_value, ZaddOptions::Compare compare) {
return {return_value, compare};
}

class ScanOptionsBase {
Expand Down
34 changes: 34 additions & 0 deletions redis/src/storages/redis/client_redistest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,40 @@ UTEST_F(RedisClientTest, Zadd) {
EXPECT_FALSE(client->ZaddIncrExisting("zset", 1.1, "five", {}).Get().has_value());
}

UTEST_F(RedisClientTest, ZaddGtLt) {
Version since{6, 2, 0};
if (!CheckVersion(since)) GTEST_SKIP() << SkipMsgByVersion("Zadd gt/lt", since);

auto client = GetClient();

storages::redis::ZaddOptions options;
options.compare = storages::redis::ZaddOptions::Compare::kGreaterThan;
EXPECT_EQ(client->Zadd("zset_gt_lt", {{1., "one"}, {3., "two"}}, options, {}).Get(), 2);
EXPECT_EQ(client->Zscore("zset_gt_lt", "one", {}).Get(), 1);
EXPECT_EQ(client->Zscore("zset_gt_lt", "two", {}).Get(), 3);

EXPECT_EQ(client->Zadd("zset_gt_lt", {{3., "one"}, {1., "two"}}, options, {}).Get(), 0);
EXPECT_EQ(client->Zscore("zset_gt_lt", "one", {}).Get(), 3);
EXPECT_EQ(client->Zscore("zset_gt_lt", "two", {}).Get(), 3);

EXPECT_EQ(client->Zadd("zset_gt_lt", {{4., "one"}, {4., "two"}}, options, {}).Get(), 0);
EXPECT_EQ(client->Zscore("zset_gt_lt", "one", {}).Get(), 4);
EXPECT_EQ(client->Zscore("zset_gt_lt", "two", {}).Get(), 4);

options.compare = storages::redis::ZaddOptions::Compare::kLessThan;
EXPECT_EQ(client->Zadd("zset_gt_lt", {{3., "one"}, {5., "two"}}, options, {}).Get(), 0);
EXPECT_EQ(client->Zscore("zset_gt_lt", "one", {}).Get(), 3);
EXPECT_EQ(client->Zscore("zset_gt_lt", "two", {}).Get(), 4);

EXPECT_EQ(client->Zadd("zset_gt_lt", {{5., "one"}, {3., "two"}}, options, {}).Get(), 0);
EXPECT_EQ(client->Zscore("zset_gt_lt", "one", {}).Get(), 3);
EXPECT_EQ(client->Zscore("zset_gt_lt", "two", {}).Get(), 3);

EXPECT_EQ(client->Zadd("zset_gt_lt", {{1., "one"}, {1., "two"}}, options, {}).Get(), 0);
EXPECT_EQ(client->Zscore("zset_gt_lt", "one", {}).Get(), 1);
EXPECT_EQ(client->Zscore("zset_gt_lt", "two", {}).Get(), 1);
}

UTEST_F(RedisClientTest, Zcard) {
auto client = GetClient();

Expand Down
5 changes: 5 additions & 0 deletions redis/src/storages/redis/impl/cmd_args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ void PutArg(CmdArgs::CmdArgsArray& args_, const ZaddOptions& arg) {
else if (arg.exist == ZaddOptions::Exist::kAddIfExist)
args_.emplace_back("XX");

if (arg.compare == ZaddOptions::Compare::kGreaterThan)
args_.emplace_back("GT");
else if (arg.compare == ZaddOptions::Compare::kLessThan)
args_.emplace_back("LT");

if (arg.return_value == ZaddOptions::ReturnValue::kChangedCount) args_.emplace_back("CH");
}

Expand Down

0 comments on commit e680053

Please sign in to comment.