redis 4.8.0 → 5.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +64 -1
- data/README.md +101 -161
- data/lib/redis/client.rb +82 -625
- data/lib/redis/commands/bitmaps.rb +4 -1
- data/lib/redis/commands/cluster.rb +1 -18
- data/lib/redis/commands/connection.rb +5 -10
- data/lib/redis/commands/geo.rb +3 -3
- data/lib/redis/commands/hashes.rb +9 -6
- data/lib/redis/commands/hyper_log_log.rb +1 -1
- data/lib/redis/commands/keys.rb +5 -23
- data/lib/redis/commands/lists.rb +74 -25
- data/lib/redis/commands/pubsub.rb +28 -25
- data/lib/redis/commands/server.rb +15 -15
- data/lib/redis/commands/sets.rb +31 -40
- data/lib/redis/commands/sorted_sets.rb +84 -12
- data/lib/redis/commands/streams.rb +39 -19
- data/lib/redis/commands/strings.rb +18 -17
- data/lib/redis/commands/transactions.rb +7 -31
- data/lib/redis/commands.rb +4 -7
- data/lib/redis/distributed.rb +114 -64
- data/lib/redis/errors.rb +15 -50
- data/lib/redis/hash_ring.rb +26 -26
- data/lib/redis/pipeline.rb +43 -222
- data/lib/redis/subscribe.rb +50 -14
- data/lib/redis/version.rb +1 -1
- data/lib/redis.rb +76 -184
- metadata +10 -54
- data/lib/redis/cluster/command.rb +0 -79
- data/lib/redis/cluster/command_loader.rb +0 -33
- data/lib/redis/cluster/key_slot_converter.rb +0 -72
- data/lib/redis/cluster/node.rb +0 -120
- data/lib/redis/cluster/node_key.rb +0 -31
- data/lib/redis/cluster/node_loader.rb +0 -34
- data/lib/redis/cluster/option.rb +0 -100
- data/lib/redis/cluster/slot.rb +0 -86
- data/lib/redis/cluster/slot_loader.rb +0 -46
- data/lib/redis/cluster.rb +0 -315
- data/lib/redis/connection/command_helper.rb +0 -41
- data/lib/redis/connection/hiredis.rb +0 -68
- data/lib/redis/connection/registry.rb +0 -13
- data/lib/redis/connection/ruby.rb +0 -437
- data/lib/redis/connection/synchrony.rb +0 -148
- data/lib/redis/connection.rb +0 -11
data/lib/redis/commands/sets.rb
CHANGED
@@ -15,56 +15,40 @@ class Redis
|
|
15
15
|
#
|
16
16
|
# @param [String] key
|
17
17
|
# @param [String, Array<String>] member one member, or array of members
|
18
|
-
# @return [
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def sadd(key, member)
|
23
|
-
block = if Redis.sadd_returns_boolean && !member.is_a?(Array)
|
24
|
-
::Redis.deprecate!(
|
25
|
-
"Redis#sadd will always return an Integer in Redis 5.0.0. Use Redis#sadd? instead." \
|
26
|
-
"(called from: #{caller(1, 1).first})"
|
27
|
-
)
|
28
|
-
Boolify
|
29
|
-
end
|
30
|
-
send_command([:sadd, key, member], &block)
|
18
|
+
# @return [Integer] The number of members that were successfully added
|
19
|
+
def sadd(key, *members)
|
20
|
+
members.flatten!(1)
|
21
|
+
send_command([:sadd, key].concat(members))
|
31
22
|
end
|
32
23
|
|
33
24
|
# Add one or more members to a set.
|
34
25
|
#
|
35
26
|
# @param [String] key
|
36
27
|
# @param [String, Array<String>] member one member, or array of members
|
37
|
-
# @return [Boolean]
|
38
|
-
def sadd?(key,
|
39
|
-
|
28
|
+
# @return [Boolean] Wether at least one member was successfully added.
|
29
|
+
def sadd?(key, *members)
|
30
|
+
members.flatten!(1)
|
31
|
+
send_command([:sadd, key].concat(members), &Boolify)
|
40
32
|
end
|
41
33
|
|
42
34
|
# Remove one or more members from a set.
|
43
35
|
#
|
44
36
|
# @param [String] key
|
45
37
|
# @param [String, Array<String>] member one member, or array of members
|
46
|
-
# @return [
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
def srem(key, member)
|
51
|
-
block = if Redis.sadd_returns_boolean && !member.is_a?(Array)
|
52
|
-
::Redis.deprecate!(
|
53
|
-
"Redis#sadd will always return an Integer in Redis 5.0.0. Use Redis#sadd? instead." \
|
54
|
-
"(called from: #{caller(1, 1).first})"
|
55
|
-
)
|
56
|
-
Boolify
|
57
|
-
end
|
58
|
-
send_command([:srem, key, member], &block)
|
38
|
+
# @return [Integer] The number of members that were successfully removed
|
39
|
+
def srem(key, *members)
|
40
|
+
members.flatten!(1)
|
41
|
+
send_command([:srem, key].concat(members))
|
59
42
|
end
|
60
43
|
|
61
44
|
# Remove one or more members from a set.
|
62
45
|
#
|
63
46
|
# @param [String] key
|
64
47
|
# @param [String, Array<String>] member one member, or array of members
|
65
|
-
# @return [Boolean]
|
66
|
-
def srem?(key,
|
67
|
-
|
48
|
+
# @return [Boolean] Wether at least one member was successfully removed.
|
49
|
+
def srem?(key, *members)
|
50
|
+
members.flatten!(1)
|
51
|
+
send_command([:srem, key].concat(members), &Boolify)
|
68
52
|
end
|
69
53
|
|
70
54
|
# Remove and return one or more random member from a set.
|
@@ -76,7 +60,7 @@ class Redis
|
|
76
60
|
if count.nil?
|
77
61
|
send_command([:spop, key])
|
78
62
|
else
|
79
|
-
send_command([:spop, key, count])
|
63
|
+
send_command([:spop, key, Integer(count)])
|
80
64
|
end
|
81
65
|
end
|
82
66
|
|
@@ -118,7 +102,8 @@ class Redis
|
|
118
102
|
# @param [String, Array<String>] members
|
119
103
|
# @return [Array<Boolean>]
|
120
104
|
def smismember(key, *members)
|
121
|
-
|
105
|
+
members.flatten!(1)
|
106
|
+
send_command([:smismember, key].concat(members)) do |reply|
|
122
107
|
reply.map(&Boolify)
|
123
108
|
end
|
124
109
|
end
|
@@ -136,7 +121,8 @@ class Redis
|
|
136
121
|
# @param [String, Array<String>] keys keys pointing to sets to subtract
|
137
122
|
# @return [Array<String>] members in the difference
|
138
123
|
def sdiff(*keys)
|
139
|
-
|
124
|
+
keys.flatten!(1)
|
125
|
+
send_command([:sdiff].concat(keys))
|
140
126
|
end
|
141
127
|
|
142
128
|
# Subtract multiple sets and store the resulting set in a key.
|
@@ -145,7 +131,8 @@ class Redis
|
|
145
131
|
# @param [String, Array<String>] keys keys pointing to sets to subtract
|
146
132
|
# @return [Integer] number of elements in the resulting set
|
147
133
|
def sdiffstore(destination, *keys)
|
148
|
-
|
134
|
+
keys.flatten!(1)
|
135
|
+
send_command([:sdiffstore, destination].concat(keys))
|
149
136
|
end
|
150
137
|
|
151
138
|
# Intersect multiple sets.
|
@@ -153,7 +140,8 @@ class Redis
|
|
153
140
|
# @param [String, Array<String>] keys keys pointing to sets to intersect
|
154
141
|
# @return [Array<String>] members in the intersection
|
155
142
|
def sinter(*keys)
|
156
|
-
|
143
|
+
keys.flatten!(1)
|
144
|
+
send_command([:sinter].concat(keys))
|
157
145
|
end
|
158
146
|
|
159
147
|
# Intersect multiple sets and store the resulting set in a key.
|
@@ -162,7 +150,8 @@ class Redis
|
|
162
150
|
# @param [String, Array<String>] keys keys pointing to sets to intersect
|
163
151
|
# @return [Integer] number of elements in the resulting set
|
164
152
|
def sinterstore(destination, *keys)
|
165
|
-
|
153
|
+
keys.flatten!(1)
|
154
|
+
send_command([:sinterstore, destination].concat(keys))
|
166
155
|
end
|
167
156
|
|
168
157
|
# Add multiple sets.
|
@@ -170,7 +159,8 @@ class Redis
|
|
170
159
|
# @param [String, Array<String>] keys keys pointing to sets to unify
|
171
160
|
# @return [Array<String>] members in the union
|
172
161
|
def sunion(*keys)
|
173
|
-
|
162
|
+
keys.flatten!(1)
|
163
|
+
send_command([:sunion].concat(keys))
|
174
164
|
end
|
175
165
|
|
176
166
|
# Add multiple sets and store the resulting set in a key.
|
@@ -179,7 +169,8 @@ class Redis
|
|
179
169
|
# @param [String, Array<String>] keys keys pointing to sets to unify
|
180
170
|
# @return [Integer] number of elements in the resulting set
|
181
171
|
def sunionstore(destination, *keys)
|
182
|
-
|
172
|
+
keys.flatten!(1)
|
173
|
+
send_command([:sunionstore, destination].concat(keys))
|
183
174
|
end
|
184
175
|
|
185
176
|
# Scan a set
|
@@ -136,7 +136,9 @@ class Redis
|
|
136
136
|
# @return [Array<String, Float>] element and score pair if count is not specified
|
137
137
|
# @return [Array<Array<String, Float>>] list of popped elements and scores
|
138
138
|
def zpopmax(key, count = nil)
|
139
|
-
|
139
|
+
command = [:zpopmax, key]
|
140
|
+
command << Integer(count) if count
|
141
|
+
send_command(command) do |members|
|
140
142
|
members = FloatifyPairs.call(members)
|
141
143
|
count.to_i > 1 ? members : members.first
|
142
144
|
end
|
@@ -157,12 +159,80 @@ class Redis
|
|
157
159
|
# @return [Array<String, Float>] element and score pair if count is not specified
|
158
160
|
# @return [Array<Array<String, Float>>] list of popped elements and scores
|
159
161
|
def zpopmin(key, count = nil)
|
160
|
-
|
162
|
+
command = [:zpopmin, key]
|
163
|
+
command << Integer(count) if count
|
164
|
+
send_command(command) do |members|
|
161
165
|
members = FloatifyPairs.call(members)
|
162
166
|
count.to_i > 1 ? members : members.first
|
163
167
|
end
|
164
168
|
end
|
165
169
|
|
170
|
+
# Removes and returns up to count members with scores in the sorted set stored at key.
|
171
|
+
#
|
172
|
+
# @example Popping a member
|
173
|
+
# redis.bzmpop('zset')
|
174
|
+
# #=> ['zset', ['a', 1.0]]
|
175
|
+
# @example With count option
|
176
|
+
# redis.bzmpop('zset', count: 2)
|
177
|
+
# #=> ['zset', [['a', 1.0], ['b', 2.0]]
|
178
|
+
#
|
179
|
+
# @params timeout [Float] a float value specifying the maximum number of seconds to block) elapses.
|
180
|
+
# A timeout of zero can be used to block indefinitely.
|
181
|
+
# @params key [String, Array<String>] one or more keys with sorted sets
|
182
|
+
# @params modifier [String]
|
183
|
+
# - when `"MIN"` - the elements popped are those with lowest scores
|
184
|
+
# - when `"MAX"` - the elements popped are those with the highest scores
|
185
|
+
# @params count [Integer] a number of members to pop
|
186
|
+
#
|
187
|
+
# @return [Array<String, Array<String, Float>>] list of popped elements and scores
|
188
|
+
def bzmpop(timeout, *keys, modifier: "MIN", count: nil)
|
189
|
+
raise ArgumentError, "Pick either MIN or MAX" unless modifier == "MIN" || modifier == "MAX"
|
190
|
+
|
191
|
+
args = [:bzmpop, timeout, keys.size, *keys, modifier]
|
192
|
+
args << "COUNT" << Integer(count) if count
|
193
|
+
|
194
|
+
send_blocking_command(args, timeout) do |response|
|
195
|
+
response&.map do |entry|
|
196
|
+
case entry
|
197
|
+
when String then entry
|
198
|
+
when Array then entry.map { |pair| FloatifyPairs.call(pair) }.flatten(1)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# Removes and returns up to count members with scores in the sorted set stored at key.
|
205
|
+
#
|
206
|
+
# @example Popping a member
|
207
|
+
# redis.zmpop('zset')
|
208
|
+
# #=> ['zset', ['a', 1.0]]
|
209
|
+
# @example With count option
|
210
|
+
# redis.zmpop('zset', count: 2)
|
211
|
+
# #=> ['zset', [['a', 1.0], ['b', 2.0]]
|
212
|
+
#
|
213
|
+
# @params key [String, Array<String>] one or more keys with sorted sets
|
214
|
+
# @params modifier [String]
|
215
|
+
# - when `"MIN"` - the elements popped are those with lowest scores
|
216
|
+
# - when `"MAX"` - the elements popped are those with the highest scores
|
217
|
+
# @params count [Integer] a number of members to pop
|
218
|
+
#
|
219
|
+
# @return [Array<String, Array<String, Float>>] list of popped elements and scores
|
220
|
+
def zmpop(*keys, modifier: "MIN", count: nil)
|
221
|
+
raise ArgumentError, "Pick either MIN or MAX" unless modifier == "MIN" || modifier == "MAX"
|
222
|
+
|
223
|
+
args = [:zmpop, keys.size, *keys, modifier]
|
224
|
+
args << "COUNT" << Integer(count) if count
|
225
|
+
|
226
|
+
send_command(args) do |response|
|
227
|
+
response&.map do |entry|
|
228
|
+
case entry
|
229
|
+
when String then entry
|
230
|
+
when Array then entry.map { |pair| FloatifyPairs.call(pair) }.flatten(1)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
166
236
|
# Removes and returns up to count members with the highest scores in the sorted set stored at keys,
|
167
237
|
# or block until one is available.
|
168
238
|
#
|
@@ -261,7 +331,7 @@ class Redis
|
|
261
331
|
end
|
262
332
|
|
263
333
|
args = [:zrandmember, key]
|
264
|
-
args << count if count
|
334
|
+
args << Integer(count) if count
|
265
335
|
|
266
336
|
if with_scores
|
267
337
|
args << "WITHSCORES"
|
@@ -313,7 +383,7 @@ class Redis
|
|
313
383
|
|
314
384
|
if limit
|
315
385
|
args << "LIMIT"
|
316
|
-
args.concat(limit)
|
386
|
+
args.concat(limit.map { |l| Integer(l) })
|
317
387
|
end
|
318
388
|
|
319
389
|
if with_scores
|
@@ -354,7 +424,7 @@ class Redis
|
|
354
424
|
|
355
425
|
if limit
|
356
426
|
args << "LIMIT"
|
357
|
-
args.concat(limit)
|
427
|
+
args.concat(limit.map { |l| Integer(l) })
|
358
428
|
end
|
359
429
|
|
360
430
|
send_command(args)
|
@@ -372,7 +442,7 @@ class Redis
|
|
372
442
|
#
|
373
443
|
# @see #zrange
|
374
444
|
def zrevrange(key, start, stop, withscores: false, with_scores: withscores)
|
375
|
-
args = [:zrevrange, key, start, stop]
|
445
|
+
args = [:zrevrange, key, Integer(start), Integer(stop)]
|
376
446
|
|
377
447
|
if with_scores
|
378
448
|
args << "WITHSCORES"
|
@@ -466,7 +536,7 @@ class Redis
|
|
466
536
|
|
467
537
|
if limit
|
468
538
|
args << "LIMIT"
|
469
|
-
args.concat(limit)
|
539
|
+
args.concat(limit.map { |l| Integer(l) })
|
470
540
|
end
|
471
541
|
|
472
542
|
send_command(args)
|
@@ -488,7 +558,7 @@ class Redis
|
|
488
558
|
|
489
559
|
if limit
|
490
560
|
args << "LIMIT"
|
491
|
-
args.concat(limit)
|
561
|
+
args.concat(limit.map { |l| Integer(l) })
|
492
562
|
end
|
493
563
|
|
494
564
|
send_command(args)
|
@@ -531,7 +601,7 @@ class Redis
|
|
531
601
|
|
532
602
|
if limit
|
533
603
|
args << "LIMIT"
|
534
|
-
args.concat(limit)
|
604
|
+
args.concat(limit.map { |l| Integer(l) })
|
535
605
|
end
|
536
606
|
|
537
607
|
send_command(args, &block)
|
@@ -561,7 +631,7 @@ class Redis
|
|
561
631
|
|
562
632
|
if limit
|
563
633
|
args << "LIMIT"
|
564
|
-
args.concat(limit)
|
634
|
+
args.concat(limit.map { |l| Integer(l) })
|
565
635
|
end
|
566
636
|
|
567
637
|
send_command(args, &block)
|
@@ -778,7 +848,8 @@ class Redis
|
|
778
848
|
private
|
779
849
|
|
780
850
|
def _zsets_operation(cmd, *keys, weights: nil, aggregate: nil, with_scores: false)
|
781
|
-
|
851
|
+
keys.flatten!(1)
|
852
|
+
command = [cmd, keys.size].concat(keys)
|
782
853
|
|
783
854
|
if weights
|
784
855
|
command << "WEIGHTS"
|
@@ -796,7 +867,8 @@ class Redis
|
|
796
867
|
end
|
797
868
|
|
798
869
|
def _zsets_operation_store(cmd, destination, keys, weights: nil, aggregate: nil)
|
799
|
-
|
870
|
+
keys.flatten!(1)
|
871
|
+
command = [cmd, destination, keys.size].concat(keys)
|
800
872
|
|
801
873
|
if weights
|
802
874
|
command << "WEIGHTS"
|
@@ -21,15 +21,12 @@ class Redis
|
|
21
21
|
# @return [Array<Hash>] information of the consumers if subcommand is `consumers`
|
22
22
|
def xinfo(subcommand, key, group = nil)
|
23
23
|
args = [:xinfo, subcommand, key, group].compact
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
when 'stream' then Hashify.call(reply)
|
28
|
-
when 'groups', 'consumers' then reply.map { |arr| Hashify.call(arr) }
|
29
|
-
else reply
|
30
|
-
end
|
31
|
-
end
|
24
|
+
block = case subcommand.to_s.downcase
|
25
|
+
when 'stream' then Hashify
|
26
|
+
when 'groups', 'consumers' then proc { |r| r.map(&Hashify) }
|
32
27
|
end
|
28
|
+
|
29
|
+
send_command(args, &block)
|
33
30
|
end
|
34
31
|
|
35
32
|
# Add new entry to the stream.
|
@@ -37,7 +34,7 @@ class Redis
|
|
37
34
|
# @example Without options
|
38
35
|
# redis.xadd('mystream', f1: 'v1', f2: 'v2')
|
39
36
|
# @example With options
|
40
|
-
# redis.xadd('mystream', { f1: 'v1', f2: 'v2' }, id: '0-0', maxlen: 1000, approximate: true)
|
37
|
+
# redis.xadd('mystream', { f1: 'v1', f2: 'v2' }, id: '0-0', maxlen: 1000, approximate: true, nomkstream: true)
|
41
38
|
#
|
42
39
|
# @param key [String] the stream key
|
43
40
|
# @param entry [Hash] one or multiple field-value pairs
|
@@ -46,17 +43,19 @@ class Redis
|
|
46
43
|
# @option opts [String] :id the entry id, default value is `*`, it means auto generation
|
47
44
|
# @option opts [Integer] :maxlen max length of entries
|
48
45
|
# @option opts [Boolean] :approximate whether to add `~` modifier of maxlen or not
|
46
|
+
# @option opts [Boolean] :nomkstream whether to add NOMKSTREAM, default is not to add
|
49
47
|
#
|
50
48
|
# @return [String] the entry id
|
51
|
-
def xadd(key, entry, approximate: nil, maxlen: nil, id: '*')
|
49
|
+
def xadd(key, entry, approximate: nil, maxlen: nil, nomkstream: nil, id: '*')
|
52
50
|
args = [:xadd, key]
|
51
|
+
args << 'NOMKSTREAM' if nomkstream
|
53
52
|
if maxlen
|
54
53
|
args << "MAXLEN"
|
55
54
|
args << "~" if approximate
|
56
55
|
args << maxlen
|
57
56
|
end
|
58
57
|
args << id
|
59
|
-
args.concat(entry.
|
58
|
+
args.concat(entry.flatten)
|
60
59
|
send_command(args)
|
61
60
|
end
|
62
61
|
|
@@ -66,14 +65,30 @@ class Redis
|
|
66
65
|
# redis.xtrim('mystream', 1000)
|
67
66
|
# @example With options
|
68
67
|
# redis.xtrim('mystream', 1000, approximate: true)
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
# @
|
68
|
+
# @example With strategy
|
69
|
+
# redis.xtrim('mystream', '1-0', strategy: 'MINID')
|
70
|
+
#
|
71
|
+
# @overload xtrim(key, maxlen, strategy: 'MAXLEN', approximate: true)
|
72
|
+
# @param key [String] the stream key
|
73
|
+
# @param maxlen [Integer] max length of entries
|
74
|
+
# @param strategy [String] the limit strategy, must be MAXLEN
|
75
|
+
# @param approximate [Boolean] whether to add `~` modifier of maxlen or not
|
76
|
+
# @param limit [Integer] maximum count of entries to be evicted
|
77
|
+
# @overload xtrim(key, minid, strategy: 'MINID', approximate: true)
|
78
|
+
# @param key [String] the stream key
|
79
|
+
# @param minid [String] minimum id of entries
|
80
|
+
# @param strategy [String] the limit strategy, must be MINID
|
81
|
+
# @param approximate [Boolean] whether to add `~` modifier of minid or not
|
82
|
+
# @param limit [Integer] maximum count of entries to be evicted
|
73
83
|
#
|
74
84
|
# @return [Integer] the number of entries actually deleted
|
75
|
-
def xtrim(key,
|
76
|
-
|
85
|
+
def xtrim(key, len_or_id, strategy: 'MAXLEN', approximate: false, limit: nil)
|
86
|
+
strategy = strategy.to_s.upcase
|
87
|
+
|
88
|
+
args = [:xtrim, key, strategy]
|
89
|
+
args << '~' if approximate
|
90
|
+
args << len_or_id
|
91
|
+
args.concat(['LIMIT', limit]) if limit
|
77
92
|
send_command(args)
|
78
93
|
end
|
79
94
|
|
@@ -113,7 +128,7 @@ class Redis
|
|
113
128
|
def xrange(key, start = '-', range_end = '+', count: nil)
|
114
129
|
args = [:xrange, key, start, range_end]
|
115
130
|
args.concat(['COUNT', count]) if count
|
116
|
-
|
131
|
+
send_command(args, &HashifyStreamEntries)
|
117
132
|
end
|
118
133
|
|
119
134
|
# Fetches entries of the stream in descending order.
|
@@ -334,6 +349,8 @@ class Redis
|
|
334
349
|
# redis.xpending('mystream', 'mygroup')
|
335
350
|
# @example With range options
|
336
351
|
# redis.xpending('mystream', 'mygroup', '-', '+', 10)
|
352
|
+
# @example With range and idle time options
|
353
|
+
# redis.xpending('mystream', 'mygroup', '-', '+', 10, idle: 9000)
|
337
354
|
# @example With range and consumer options
|
338
355
|
# redis.xpending('mystream', 'mygroup', '-', '+', 10, 'consumer1')
|
339
356
|
#
|
@@ -344,10 +361,13 @@ class Redis
|
|
344
361
|
# @param count [Integer] count the number of entries as limit
|
345
362
|
# @param consumer [String] the consumer name
|
346
363
|
#
|
364
|
+
# @option opts [Integer] :idle pending message minimum idle time in milliseconds
|
365
|
+
#
|
347
366
|
# @return [Hash] the summary of pending entries
|
348
367
|
# @return [Array<Hash>] the pending entries details if options were specified
|
349
|
-
def xpending(key, group, *args)
|
368
|
+
def xpending(key, group, *args, idle: nil)
|
350
369
|
command_args = [:xpending, key, group]
|
370
|
+
command_args << 'IDLE' << Integer(idle) if idle
|
351
371
|
case args.size
|
352
372
|
when 0, 3, 4
|
353
373
|
command_args.concat(args)
|
@@ -25,7 +25,7 @@ class Redis
|
|
25
25
|
# @param [Integer] decrement
|
26
26
|
# @return [Integer] value after decrementing it
|
27
27
|
def decrby(key, decrement)
|
28
|
-
send_command([:decrby, key, decrement])
|
28
|
+
send_command([:decrby, key, Integer(decrement)])
|
29
29
|
end
|
30
30
|
|
31
31
|
# Increment the integer value of a key by one.
|
@@ -50,7 +50,7 @@ class Redis
|
|
50
50
|
# @param [Integer] increment
|
51
51
|
# @return [Integer] value after incrementing it
|
52
52
|
def incrby(key, increment)
|
53
|
-
send_command([:incrby, key, increment])
|
53
|
+
send_command([:incrby, key, Integer(increment)])
|
54
54
|
end
|
55
55
|
|
56
56
|
# Increment the numeric value of a key by the given float number.
|
@@ -63,7 +63,7 @@ class Redis
|
|
63
63
|
# @param [Float] increment
|
64
64
|
# @return [Float] value after incrementing it
|
65
65
|
def incrbyfloat(key, increment)
|
66
|
-
send_command([:incrbyfloat, key, increment], &Floatify)
|
66
|
+
send_command([:incrbyfloat, key, Float(increment)], &Floatify)
|
67
67
|
end
|
68
68
|
|
69
69
|
# Set the string value of a key.
|
@@ -82,10 +82,10 @@ class Redis
|
|
82
82
|
# @return [String, Boolean] `"OK"` or true, false if `:nx => true` or `:xx => true`
|
83
83
|
def set(key, value, ex: nil, px: nil, exat: nil, pxat: nil, nx: nil, xx: nil, keepttl: nil, get: nil)
|
84
84
|
args = [:set, key, value.to_s]
|
85
|
-
args << "EX" << ex if ex
|
86
|
-
args << "PX" << px if px
|
87
|
-
args << "EXAT" << exat if exat
|
88
|
-
args << "PXAT" << pxat if pxat
|
85
|
+
args << "EX" << Integer(ex) if ex
|
86
|
+
args << "PX" << Integer(px) if px
|
87
|
+
args << "EXAT" << Integer(exat) if exat
|
88
|
+
args << "PXAT" << Integer(pxat) if pxat
|
89
89
|
args << "NX" if nx
|
90
90
|
args << "XX" if xx
|
91
91
|
args << "KEEPTTL" if keepttl
|
@@ -105,7 +105,7 @@ class Redis
|
|
105
105
|
# @param [String] value
|
106
106
|
# @return [String] `"OK"`
|
107
107
|
def setex(key, ttl, value)
|
108
|
-
send_command([:setex, key, ttl, value.to_s])
|
108
|
+
send_command([:setex, key, Integer(ttl), value.to_s])
|
109
109
|
end
|
110
110
|
|
111
111
|
# Set the time to live in milliseconds of a key.
|
@@ -115,7 +115,7 @@ class Redis
|
|
115
115
|
# @param [String] value
|
116
116
|
# @return [String] `"OK"`
|
117
117
|
def psetex(key, ttl, value)
|
118
|
-
send_command([:psetex, key, ttl, value.to_s])
|
118
|
+
send_command([:psetex, key, Integer(ttl), value.to_s])
|
119
119
|
end
|
120
120
|
|
121
121
|
# Set the value of a key, only if the key does not exist.
|
@@ -152,7 +152,7 @@ class Redis
|
|
152
152
|
#
|
153
153
|
# @see #mset
|
154
154
|
def mapped_mset(hash)
|
155
|
-
mset(hash.
|
155
|
+
mset(hash.flatten)
|
156
156
|
end
|
157
157
|
|
158
158
|
# Set one or more values, only if none of the keys exist.
|
@@ -180,7 +180,7 @@ class Redis
|
|
180
180
|
#
|
181
181
|
# @see #msetnx
|
182
182
|
def mapped_msetnx(hash)
|
183
|
-
msetnx(hash.
|
183
|
+
msetnx(hash.flatten)
|
184
184
|
end
|
185
185
|
|
186
186
|
# Get the value of a key.
|
@@ -202,6 +202,7 @@ class Redis
|
|
202
202
|
#
|
203
203
|
# @see #mapped_mget
|
204
204
|
def mget(*keys, &blk)
|
205
|
+
keys.flatten!(1)
|
205
206
|
send_command([:mget, *keys], &blk)
|
206
207
|
end
|
207
208
|
|
@@ -232,7 +233,7 @@ class Redis
|
|
232
233
|
# @param [String] value
|
233
234
|
# @return [Integer] length of the string after it was modified
|
234
235
|
def setrange(key, offset, value)
|
235
|
-
send_command([:setrange, key, offset, value.to_s])
|
236
|
+
send_command([:setrange, key, Integer(offset), value.to_s])
|
236
237
|
end
|
237
238
|
|
238
239
|
# Get a substring of the string stored at a key.
|
@@ -243,7 +244,7 @@ class Redis
|
|
243
244
|
# the end of the string
|
244
245
|
# @return [Integer] `0` or `1`
|
245
246
|
def getrange(key, start, stop)
|
246
|
-
send_command([:getrange, key, start, stop])
|
247
|
+
send_command([:getrange, key, Integer(start), Integer(stop)])
|
247
248
|
end
|
248
249
|
|
249
250
|
# Append a value to a key.
|
@@ -291,10 +292,10 @@ class Redis
|
|
291
292
|
# @return [String] The value of key, or nil when key does not exist.
|
292
293
|
def getex(key, ex: nil, px: nil, exat: nil, pxat: nil, persist: false)
|
293
294
|
args = [:getex, key]
|
294
|
-
args << "EX" << ex if ex
|
295
|
-
args << "PX" << px if px
|
296
|
-
args << "EXAT" << exat if exat
|
297
|
-
args << "PXAT" << pxat if pxat
|
295
|
+
args << "EX" << Integer(ex) if ex
|
296
|
+
args << "PX" << Integer(px) if px
|
297
|
+
args << "EXAT" << Integer(exat) if exat
|
298
|
+
args << "PXAT" << Integer(pxat) if pxat
|
298
299
|
args << "PERSIST" if persist
|
299
300
|
|
300
301
|
send_command(args)
|
@@ -5,48 +5,26 @@ class Redis
|
|
5
5
|
module Transactions
|
6
6
|
# Mark the start of a transaction block.
|
7
7
|
#
|
8
|
-
# Passing a block is optional.
|
9
|
-
#
|
10
8
|
# @example With a block
|
11
9
|
# redis.multi do |multi|
|
12
10
|
# multi.set("key", "value")
|
13
11
|
# multi.incr("counter")
|
14
12
|
# end # => ["OK", 6]
|
15
13
|
#
|
16
|
-
# @example Without a block
|
17
|
-
# redis.multi
|
18
|
-
# # => "OK"
|
19
|
-
# redis.set("key", "value")
|
20
|
-
# # => "QUEUED"
|
21
|
-
# redis.incr("counter")
|
22
|
-
# # => "QUEUED"
|
23
|
-
# redis.exec
|
24
|
-
# # => ["OK", 6]
|
25
|
-
#
|
26
14
|
# @yield [multi] the commands that are called inside this block are cached
|
27
15
|
# and written to the server upon returning from it
|
28
16
|
# @yieldparam [Redis] multi `self`
|
29
17
|
#
|
30
|
-
# @return [
|
31
|
-
# -
|
32
|
-
# - when a block is given, an array with replies
|
18
|
+
# @return [Array<...>]
|
19
|
+
# - an array with replies
|
33
20
|
#
|
34
21
|
# @see #watch
|
35
22
|
# @see #unwatch
|
36
|
-
def multi
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
synchronize do |prior_client|
|
43
|
-
pipeline = Pipeline::Multi.new(prior_client)
|
44
|
-
pipelined_connection = PipelinedConnection.new(pipeline)
|
45
|
-
yield pipelined_connection
|
46
|
-
prior_client.call_pipeline(pipeline)
|
23
|
+
def multi
|
24
|
+
synchronize do |client|
|
25
|
+
client.multi do |raw_transaction|
|
26
|
+
yield MultiConnection.new(raw_transaction)
|
47
27
|
end
|
48
|
-
else
|
49
|
-
send_command([:multi])
|
50
28
|
end
|
51
29
|
end
|
52
30
|
|
@@ -82,7 +60,7 @@ class Redis
|
|
82
60
|
# @see #multi
|
83
61
|
def watch(*keys)
|
84
62
|
synchronize do |client|
|
85
|
-
res = client.
|
63
|
+
res = client.call_v([:watch] + keys)
|
86
64
|
|
87
65
|
if block_given?
|
88
66
|
begin
|
@@ -125,8 +103,6 @@ class Redis
|
|
125
103
|
|
126
104
|
# Discard all commands issued after MULTI.
|
127
105
|
#
|
128
|
-
# Only call this method when `#multi` was called **without** a block.
|
129
|
-
#
|
130
106
|
# @return [String] `"OK"`
|
131
107
|
#
|
132
108
|
# @see #multi
|
data/lib/redis/commands.rb
CHANGED
@@ -40,12 +40,7 @@ class Redis
|
|
40
40
|
# where the method call will return nil. Propagate the nil instead of falsely
|
41
41
|
# returning false.
|
42
42
|
Boolify = lambda { |value|
|
43
|
-
|
44
|
-
when Integer
|
45
|
-
value > 0
|
46
|
-
else
|
47
|
-
value
|
48
|
-
end
|
43
|
+
value != 0 unless value.nil?
|
49
44
|
}
|
50
45
|
|
51
46
|
BoolifySet = lambda { |value|
|
@@ -124,7 +119,9 @@ class Redis
|
|
124
119
|
HashifyStreamAutoclaim = lambda { |reply|
|
125
120
|
{
|
126
121
|
'next' => reply[0],
|
127
|
-
'entries' => reply[1].map
|
122
|
+
'entries' => reply[1].compact.map do |entry, values|
|
123
|
+
[entry, values.each_slice(2)&.to_h]
|
124
|
+
end
|
128
125
|
}
|
129
126
|
}
|
130
127
|
|