Skip to content

Commit

Permalink
CAS command supports EXAT and PXAT options (#1650)
Browse files Browse the repository at this point in the history
  • Loading branch information
enjoy-binbin authored Aug 7, 2023
1 parent 60bcc3f commit 052234b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 5 deletions.
6 changes: 2 additions & 4 deletions src/commands/cmd_string.cc
Original file line number Diff line number Diff line change
Expand Up @@ -559,10 +559,8 @@ class CommandCAS : public Commander {
CommandParser parser(args, 4);
std::string_view flag;
while (parser.Good()) {
if (parser.EatEqICaseFlag("EX", flag)) {
ttl_ = GET_OR_RET(parser.TakeInt<int64_t>(TTL_RANGE<int64_t>)) * 1000;
} else if (parser.EatEqICaseFlag("PX", flag)) {
ttl_ = GET_OR_RET(parser.TakeInt<int64_t>(TTL_RANGE<int64_t>));
if (auto v = GET_OR_RET(ParseTTL(parser, flag))) {
ttl_ = *v;
} else {
return parser.InvalidSyntax();
}
Expand Down
49 changes: 48 additions & 1 deletion tests/gocase/unit/type/strings/strings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -718,26 +718,73 @@ func TestString(t *testing.T) {
require.Equal(t, "", rdb.Get(ctx, "cas_key").Val())
})

t.Run("CAS expire EX option", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "cas_key").Err())
require.NoError(t, rdb.Set(ctx, "cas_key", "123", 0).Err())
require.EqualValues(t, 1, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "ex", 10).Val())
util.BetweenValues(t, rdb.TTL(ctx, "cas_key").Val(), 5*time.Second, 10*time.Second)
})

t.Run("CAS expire Duplicate EX option", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "cas_key").Err())
require.NoError(t, rdb.Set(ctx, "cas_key", "123", 0).Err())
require.EqualValues(t, 1, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "ex", 100, "ex", 10).Val())
util.BetweenValues(t, rdb.TTL(ctx, "cas_key").Val(), 5*time.Second, 10*time.Second)
})

t.Run("CAS expire PX option", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "cas_key").Err())
require.NoError(t, rdb.Set(ctx, "cas_key", "123", 0).Err())
require.EqualValues(t, 1, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "px", 10000).Val())
util.BetweenValues(t, rdb.TTL(ctx, "cas_key").Val(), 5*time.Second, 10*time.Second)
})

t.Run("CAS expire Duplicate PX option", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "cas_key").Err())
require.NoError(t, rdb.Set(ctx, "cas_key", "123", 0).Err())
require.EqualValues(t, 1, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "px", 1000, "px", 10000).Val())
util.BetweenValues(t, rdb.TTL(ctx, "cas_key").Val(), 5*time.Second, 10*time.Second)
})

t.Run("CAS expire PX option and EX option exist at the same time", func(t *testing.T) {
t.Run("CAS expire EXAT option", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "cas_key").Err())
require.NoError(t, rdb.Set(ctx, "cas_key", "123", 0).Err())
require.NoError(t, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "exat", time.Now().Add(10*time.Second).Unix()).Err())
util.BetweenValues(t, rdb.TTL(ctx, "cas_key").Val(), 5*time.Second, 10*time.Second)
})

t.Run("CAS Duplicate EXAT option", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "cas_key").Err())
require.NoError(t, rdb.Set(ctx, "cas_key", "123", 0).Err())
require.NoError(t, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "exat", time.Now().Add(100*time.Second).Unix(), "exat", time.Now().Add(10*time.Second).Unix()).Err())
util.BetweenValues(t, rdb.TTL(ctx, "cas_key").Val(), 5*time.Second, 10*time.Second)
})

t.Run("CAS expire PXAT option", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "cas_key").Err())
require.NoError(t, rdb.Set(ctx, "cas_key", "123", 0).Err())
require.NoError(t, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "pxat", time.Now().Add(10*time.Second).UnixMilli()).Err())
util.BetweenValues(t, rdb.TTL(ctx, "cas_key").Val(), 5*time.Second, 10*time.Second)
})

t.Run("CAS Duplicate PXAT option", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "cas_key").Err())
require.NoError(t, rdb.Set(ctx, "cas_key", "123", 0).Err())
require.NoError(t, rdb.Do(ctx, "cas", "cas_key", "123", "234", "pxat", time.Now().Add(100*time.Second).UnixMilli(), "pxat", time.Now().Add(10*time.Second).UnixMilli()).Err())
util.BetweenValues(t, rdb.TTL(ctx, "cas_key").Val(), 5*time.Second, 10*time.Second)
})

t.Run("CAS expire mutually exclusive options exist at the same time", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "cas_key").Err())
require.NoError(t, rdb.Set(ctx, "cas_key", "123", 0).Err())
require.ErrorContains(t, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "ex", 100, "px", 100000).Err(), "syntax error")
require.ErrorContains(t, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "ex", 100, "ex", 10, "px", 10000).Err(), "syntax error")
require.ErrorContains(t, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "px", 10000, "ex", 100, "ex", 10, "px", 10000).Err(), "syntax error")
require.ErrorContains(t, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "ex", 100, "exat", 100000).Err(), "syntax error")
require.ErrorContains(t, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "ex", 100, "pxat", 100000).Err(), "syntax error")
require.ErrorContains(t, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "px", 100, "exat", 100000).Err(), "syntax error")
require.ErrorContains(t, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "px", 100, "pxat", 100000).Err(), "syntax error")
require.ErrorContains(t, rdb.Do(ctx, "CAS", "cas_key", "123", "234", "exat", 100, "pxat", 100000).Err(), "syntax error")
})

t.Run("CAD normal case", func(t *testing.T) {
Expand Down

0 comments on commit 052234b

Please sign in to comment.