From 8ae6014ad18f65b1c986b2d4d2282ddb6ef98d81 Mon Sep 17 00:00:00 2001 From: jyf111 Date: Sat, 6 Jan 2024 15:30:12 +0800 Subject: [PATCH] Add support of BITFIELD_RO --- src/commands/cmd_bit.cc | 10 +++++++++- tests/gocase/unit/type/bitmap/bitmap_test.go | 14 +++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/commands/cmd_bit.cc b/src/commands/cmd_bit.cc index 88341c843a8..6e9fe5ba33f 100644 --- a/src/commands/cmd_bit.cc +++ b/src/commands/cmd_bit.cc @@ -242,6 +242,7 @@ class CommandBitOp : public Commander { BitOpFlags op_flag_; }; +template class CommandBitfield : public Commander { public: Status Parse(const std::vector &args) override { @@ -314,6 +315,12 @@ class CommandBitfield : public Commander { cmds_.push_back(cmd); } + if constexpr (ReadOnly) { + if (!read_only_) { + return {Status::RedisParseErr, "BITFIELD_RO only supports the GET subcommand"}; + } + } + return Commander::Parse(args); } @@ -394,6 +401,7 @@ REDIS_REGISTER_COMMANDS(MakeCmdAttr("getbit", 3, "read-only", 1, MakeCmdAttr("bitcount", -2, "read-only", 1, 1, 1), MakeCmdAttr("bitpos", -3, "read-only", 1, 1, 1), MakeCmdAttr("bitop", -4, "write", 2, -1, 1), - MakeCmdAttr("bitfield", -2, "write", 1, 1, 1), ) + MakeCmdAttr>("bitfield", -2, "write", 1, 1, 1), + MakeCmdAttr>("bitfield_ro", -2, "read-only", 1, 1, 1), ) } // namespace redis diff --git a/tests/gocase/unit/type/bitmap/bitmap_test.go b/tests/gocase/unit/type/bitmap/bitmap_test.go index eb778622b7f..a8ee50d048d 100644 --- a/tests/gocase/unit/type/bitmap/bitmap_test.go +++ b/tests/gocase/unit/type/bitmap/bitmap_test.go @@ -303,13 +303,25 @@ func TestBitmap(t *testing.T) { require.EqualValues(t, 32, rdb.BitOpOr(ctx, "x", "a", "b").Val()) }) - t.Run("BITFIELD on string type", func(t *testing.T) { + t.Run("BITFIELD and BITFIELD_RO on string type", func(t *testing.T) { str := "zhe ge ren hen lan, shen me dou mei you liu xia." require.NoError(t, rdb.Set(ctx, "str", str, 0).Err()) + for _, command := range []string{"BITFIELD", "BITFIELD_RO"} { + res := rdb.Do(ctx, command, "str", "GET", "u8", "32", "GET", "u8", "40") + require.NoError(t, res.Err()) + require.EqualValues(t, []interface{}{int64(str[4]), int64(str[5])}, res.Val()) + } + res := rdb.BitField(ctx, "str", "GET", "u8", "32", "SET", "u8", "32", 'r', "GET", "u8", "32") require.NoError(t, res.Err()) require.EqualValues(t, str[4], res.Val()[0]) require.EqualValues(t, str[4], res.Val()[1]) require.EqualValues(t, 'r', res.Val()[2]) + require.ErrorContains(t, rdb.Do(ctx, "BITFIELD_RO", "str", "GET", "u8", "32", "SET", "u8", "32", 'r', "GET", "u8", "32").Err(), "BITFIELD_RO only supports the GET subcommand") + + res = rdb.BitField(ctx, "str", "INCRBY", "u8", "32", 2) + require.NoError(t, res.Err()) + require.EqualValues(t, 't', res.Val()[0]) + require.ErrorContains(t, rdb.Do(ctx, "BITFIELD_RO", "str", "INCRBY", "u8", "32", 2).Err(), "BITFIELD_RO only supports the GET subcommand") }) }