1 package redis
2
3 import (
4 "context"
5 "errors"
6 )
7
8 type BitMapCmdable interface {
9 GetBit(ctx context.Context, key string, offset int64) *IntCmd
10 SetBit(ctx context.Context, key string, offset int64, value int) *IntCmd
11 BitCount(ctx context.Context, key string, bitCount *BitCount) *IntCmd
12 BitOpAnd(ctx context.Context, destKey string, keys ...string) *IntCmd
13 BitOpOr(ctx context.Context, destKey string, keys ...string) *IntCmd
14 BitOpXor(ctx context.Context, destKey string, keys ...string) *IntCmd
15 BitOpDiff(ctx context.Context, destKey string, keys ...string) *IntCmd
16 BitOpDiff1(ctx context.Context, destKey string, keys ...string) *IntCmd
17 BitOpAndOr(ctx context.Context, destKey string, keys ...string) *IntCmd
18 BitOpOne(ctx context.Context, destKey string, keys ...string) *IntCmd
19 BitOpNot(ctx context.Context, destKey string, key string) *IntCmd
20 BitPos(ctx context.Context, key string, bit int64, pos ...int64) *IntCmd
21 BitPosSpan(ctx context.Context, key string, bit int8, start, end int64, span string) *IntCmd
22 BitField(ctx context.Context, key string, values ...interface{}) *IntSliceCmd
23 BitFieldRO(ctx context.Context, key string, values ...interface{}) *IntSliceCmd
24 }
25
26 func (c cmdable) GetBit(ctx context.Context, key string, offset int64) *IntCmd {
27 cmd := NewIntCmd(ctx, "getbit", key, offset)
28 _ = c(ctx, cmd)
29 return cmd
30 }
31
32 func (c cmdable) SetBit(ctx context.Context, key string, offset int64, value int) *IntCmd {
33 cmd := NewIntCmd(
34 ctx,
35 "setbit",
36 key,
37 offset,
38 value,
39 )
40 _ = c(ctx, cmd)
41 return cmd
42 }
43
44 type BitCount struct {
45 Start, End int64
46 Unit string
47 }
48
49 const BitCountIndexByte string = "BYTE"
50 const BitCountIndexBit string = "BIT"
51
52 func (c cmdable) BitCount(ctx context.Context, key string, bitCount *BitCount) *IntCmd {
53 args := make([]any, 2, 5)
54 args[0] = "bitcount"
55 args[1] = key
56 if bitCount != nil {
57 args = append(args, bitCount.Start, bitCount.End)
58 if bitCount.Unit != "" {
59 if bitCount.Unit != BitCountIndexByte && bitCount.Unit != BitCountIndexBit {
60 cmd := NewIntCmd(ctx)
61 cmd.SetErr(errors.New("redis: invalid bitcount index"))
62 return cmd
63 }
64 args = append(args, bitCount.Unit)
65 }
66 }
67 cmd := NewIntCmd(ctx, args...)
68 _ = c(ctx, cmd)
69 return cmd
70 }
71
72 func (c cmdable) bitOp(ctx context.Context, op, destKey string, keys ...string) *IntCmd {
73 args := make([]interface{}, 3+len(keys))
74 args[0] = "bitop"
75 args[1] = op
76 args[2] = destKey
77 for i, key := range keys {
78 args[3+i] = key
79 }
80 cmd := NewIntCmd(ctx, args...)
81 _ = c(ctx, cmd)
82 return cmd
83 }
84
85
86 func (c cmdable) BitOpAnd(ctx context.Context, destKey string, keys ...string) *IntCmd {
87 return c.bitOp(ctx, "and", destKey, keys...)
88 }
89
90
91 func (c cmdable) BitOpOr(ctx context.Context, destKey string, keys ...string) *IntCmd {
92 return c.bitOp(ctx, "or", destKey, keys...)
93 }
94
95
96 func (c cmdable) BitOpXor(ctx context.Context, destKey string, keys ...string) *IntCmd {
97 return c.bitOp(ctx, "xor", destKey, keys...)
98 }
99
100
101 func (c cmdable) BitOpNot(ctx context.Context, destKey string, key string) *IntCmd {
102 return c.bitOp(ctx, "not", destKey, key)
103 }
104
105
106
107 func (c cmdable) BitOpDiff(ctx context.Context, destKey string, keys ...string) *IntCmd {
108 return c.bitOp(ctx, "diff", destKey, keys...)
109 }
110
111
112
113 func (c cmdable) BitOpDiff1(ctx context.Context, destKey string, keys ...string) *IntCmd {
114 return c.bitOp(ctx, "diff1", destKey, keys...)
115 }
116
117
118
119 func (c cmdable) BitOpAndOr(ctx context.Context, destKey string, keys ...string) *IntCmd {
120 return c.bitOp(ctx, "andor", destKey, keys...)
121 }
122
123
124
125 func (c cmdable) BitOpOne(ctx context.Context, destKey string, keys ...string) *IntCmd {
126 return c.bitOp(ctx, "one", destKey, keys...)
127 }
128
129
130
131 func (c cmdable) BitPos(ctx context.Context, key string, bit int64, pos ...int64) *IntCmd {
132 args := make([]interface{}, 3+len(pos))
133 args[0] = "bitpos"
134 args[1] = key
135 args[2] = bit
136 switch len(pos) {
137 case 0:
138 case 1:
139 args[3] = pos[0]
140 case 2:
141 args[3] = pos[0]
142 args[4] = pos[1]
143 default:
144 panic("too many arguments")
145 }
146 cmd := NewIntCmd(ctx, args...)
147 _ = c(ctx, cmd)
148 return cmd
149 }
150
151
152
153
154
155
156
157 func (c cmdable) BitPosSpan(ctx context.Context, key string, bit int8, start, end int64, span string) *IntCmd {
158 cmd := NewIntCmd(ctx, "bitpos", key, bit, start, end, span)
159 _ = c(ctx, cmd)
160 return cmd
161 }
162
163
164
165
166
167 func (c cmdable) BitField(ctx context.Context, key string, values ...interface{}) *IntSliceCmd {
168 args := make([]interface{}, 2, 2+len(values))
169 args[0] = "bitfield"
170 args[1] = key
171 args = appendArgs(args, values)
172 cmd := NewIntSliceCmd(ctx, args...)
173 _ = c(ctx, cmd)
174 return cmd
175 }
176
177
178
179
180 func (c cmdable) BitFieldRO(ctx context.Context, key string, values ...interface{}) *IntSliceCmd {
181 args := make([]interface{}, 2, 2+len(values))
182 args[0] = "BITFIELD_RO"
183 args[1] = key
184 if len(values)%2 != 0 {
185 panic("BitFieldRO: invalid number of arguments, must be even")
186 }
187 for i := 0; i < len(values); i += 2 {
188 args = append(args, "GET", values[i], values[i+1])
189 }
190 cmd := NewIntSliceCmd(ctx, args...)
191 _ = c(ctx, cmd)
192 return cmd
193 }
194
View as plain text