redis 4.8.1 → 5.4.0
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 +82 -0
- data/README.md +125 -162
- data/lib/redis/client.rb +82 -616
- data/lib/redis/commands/bitmaps.rb +14 -4
- 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 +13 -6
- data/lib/redis/commands/hyper_log_log.rb +1 -1
- data/lib/redis/commands/keys.rb +27 -23
- data/lib/redis/commands/lists.rb +74 -25
- data/lib/redis/commands/pubsub.rb +34 -25
- data/lib/redis/commands/server.rb +15 -15
- data/lib/redis/commands/sets.rb +35 -40
- data/lib/redis/commands/sorted_sets.rb +128 -18
- data/lib/redis/commands/streams.rb +48 -21
- data/lib/redis/commands/strings.rb +18 -17
- data/lib/redis/commands/transactions.rb +7 -31
- data/lib/redis/commands.rb +11 -12
- data/lib/redis/distributed.rb +136 -72
- data/lib/redis/errors.rb +15 -50
- data/lib/redis/hash_ring.rb +26 -26
- data/lib/redis/pipeline.rb +47 -222
- data/lib/redis/subscribe.rb +50 -14
- data/lib/redis/version.rb +1 -1
- data/lib/redis.rb +77 -184
- metadata +10 -57
- 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
@@ -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|
|
@@ -88,12 +83,14 @@ class Redis
|
|
88
83
|
end
|
89
84
|
}
|
90
85
|
|
86
|
+
FloatifyPair = lambda { |(first, score)|
|
87
|
+
[first, Floatify.call(score)]
|
88
|
+
}
|
89
|
+
|
91
90
|
FloatifyPairs = lambda { |value|
|
92
91
|
return value unless value.respond_to?(:each_slice)
|
93
92
|
|
94
|
-
value.each_slice(2).map
|
95
|
-
[member, Floatify.call(score)]
|
96
|
-
end
|
93
|
+
value.each_slice(2).map(&FloatifyPair)
|
97
94
|
}
|
98
95
|
|
99
96
|
HashifyInfo = lambda { |reply|
|
@@ -124,7 +121,9 @@ class Redis
|
|
124
121
|
HashifyStreamAutoclaim = lambda { |reply|
|
125
122
|
{
|
126
123
|
'next' => reply[0],
|
127
|
-
'entries' => reply[1].map
|
124
|
+
'entries' => reply[1].compact.map do |entry, values|
|
125
|
+
[entry, values.each_slice(2)&.to_h]
|
126
|
+
end
|
128
127
|
}
|
129
128
|
}
|
130
129
|
|
@@ -202,8 +201,8 @@ class Redis
|
|
202
201
|
# hash, are up to consumers.
|
203
202
|
#
|
204
203
|
# Redis error replies are raised as Ruby exceptions.
|
205
|
-
def call(*command)
|
206
|
-
send_command(command)
|
204
|
+
def call(*command, &block)
|
205
|
+
send_command(command, &block)
|
207
206
|
end
|
208
207
|
|
209
208
|
# Interact with the sentinel command (masters, master, slaves, failover)
|
data/lib/redis/distributed.rb
CHANGED
@@ -20,7 +20,7 @@ class Redis
|
|
20
20
|
def initialize(node_configs, options = {})
|
21
21
|
@tag = options[:tag] || /^\{(.+?)\}/
|
22
22
|
@ring = options[:ring] || HashRing.new
|
23
|
-
@node_configs = node_configs.dup
|
23
|
+
@node_configs = node_configs.map(&:dup)
|
24
24
|
@default_options = options.dup
|
25
25
|
node_configs.each { |node_config| add_node(node_config) }
|
26
26
|
@subscribed_node = nil
|
@@ -41,6 +41,8 @@ class Redis
|
|
41
41
|
def add_node(options)
|
42
42
|
options = { url: options } if options.is_a?(String)
|
43
43
|
options = @default_options.merge(options)
|
44
|
+
options.delete(:tag)
|
45
|
+
options.delete(:ring)
|
44
46
|
@ring.add_node Redis.new(options)
|
45
47
|
end
|
46
48
|
|
@@ -64,6 +66,10 @@ class Redis
|
|
64
66
|
on_each_node :quit
|
65
67
|
end
|
66
68
|
|
69
|
+
def close
|
70
|
+
on_each_node :close
|
71
|
+
end
|
72
|
+
|
67
73
|
# Asynchronously save the dataset to disk.
|
68
74
|
def bgsave
|
69
75
|
on_each_node :bgsave
|
@@ -124,6 +130,11 @@ class Redis
|
|
124
130
|
node_for(key).expireat(key, unix_time, **kwargs)
|
125
131
|
end
|
126
132
|
|
133
|
+
# Get the expiration for a key as a UNIX timestamp.
|
134
|
+
def expiretime(key)
|
135
|
+
node_for(key).expiretime(key)
|
136
|
+
end
|
137
|
+
|
127
138
|
# Get the time to live (in seconds) for a key.
|
128
139
|
def ttl(key)
|
129
140
|
node_for(key).ttl(key)
|
@@ -139,6 +150,11 @@ class Redis
|
|
139
150
|
node_for(key).pexpireat(key, ms_unix_time, **kwarg)
|
140
151
|
end
|
141
152
|
|
153
|
+
# Get the expiration for a key as number of milliseconds from UNIX Epoch.
|
154
|
+
def pexpiretime(key)
|
155
|
+
node_for(key).pexpiretime(key)
|
156
|
+
end
|
157
|
+
|
142
158
|
# Get the time to live (in milliseconds) for a key.
|
143
159
|
def pttl(key)
|
144
160
|
node_for(key).pttl(key)
|
@@ -161,6 +177,7 @@ class Redis
|
|
161
177
|
|
162
178
|
# Delete a key.
|
163
179
|
def del(*args)
|
180
|
+
args.flatten!(1)
|
164
181
|
keys_per_node = args.group_by { |key| node_for(key) }
|
165
182
|
keys_per_node.inject(0) do |sum, (node, keys)|
|
166
183
|
sum + node.del(*keys)
|
@@ -169,6 +186,7 @@ class Redis
|
|
169
186
|
|
170
187
|
# Unlink keys.
|
171
188
|
def unlink(*args)
|
189
|
+
args.flatten!(1)
|
172
190
|
keys_per_node = args.group_by { |key| node_for(key) }
|
173
191
|
keys_per_node.inject(0) do |sum, (node, keys)|
|
174
192
|
sum + node.unlink(*keys)
|
@@ -177,23 +195,16 @@ class Redis
|
|
177
195
|
|
178
196
|
# Determine if a key exists.
|
179
197
|
def exists(*args)
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
"(#{::Kernel.caller(1, 1).first})\n"
|
185
|
-
)
|
186
|
-
exists?(*args)
|
187
|
-
else
|
188
|
-
keys_per_node = args.group_by { |key| node_for(key) }
|
189
|
-
keys_per_node.inject(0) do |sum, (node, keys)|
|
190
|
-
sum + node._exists(*keys)
|
191
|
-
end
|
198
|
+
args.flatten!(1)
|
199
|
+
keys_per_node = args.group_by { |key| node_for(key) }
|
200
|
+
keys_per_node.inject(0) do |sum, (node, keys)|
|
201
|
+
sum + node.exists(*keys)
|
192
202
|
end
|
193
203
|
end
|
194
204
|
|
195
205
|
# Determine if any of the keys exists.
|
196
206
|
def exists?(*args)
|
207
|
+
args.flatten!(1)
|
197
208
|
keys_per_node = args.group_by { |key| node_for(key) }
|
198
209
|
keys_per_node.each do |node, keys|
|
199
210
|
return true if node.exists?(*keys)
|
@@ -297,7 +308,7 @@ class Redis
|
|
297
308
|
end
|
298
309
|
|
299
310
|
# Set multiple keys to multiple values.
|
300
|
-
def mset(*
|
311
|
+
def mset(*)
|
301
312
|
raise CannotDistribute, :mset
|
302
313
|
end
|
303
314
|
|
@@ -306,7 +317,7 @@ class Redis
|
|
306
317
|
end
|
307
318
|
|
308
319
|
# Set multiple keys to multiple values, only if none of the keys exist.
|
309
|
-
def msetnx(*
|
320
|
+
def msetnx(*)
|
310
321
|
raise CannotDistribute, :msetnx
|
311
322
|
end
|
312
323
|
|
@@ -331,11 +342,13 @@ class Redis
|
|
331
342
|
|
332
343
|
# Get the values of all the given keys as an Array.
|
333
344
|
def mget(*keys)
|
345
|
+
keys.flatten!(1)
|
334
346
|
mapped_mget(*keys).values_at(*keys)
|
335
347
|
end
|
336
348
|
|
337
349
|
# Get the values of all the given keys as a Hash.
|
338
350
|
def mapped_mget(*keys)
|
351
|
+
keys.flatten!(1)
|
339
352
|
keys.group_by { |k| node_for k }.inject({}) do |results, (node, subkeys)|
|
340
353
|
results.merge! node.mapped_mget(*subkeys)
|
341
354
|
end
|
@@ -367,20 +380,21 @@ class Redis
|
|
367
380
|
end
|
368
381
|
|
369
382
|
# Count the number of set bits in a range of the string value stored at key.
|
370
|
-
def bitcount(key, start = 0, stop = -1)
|
371
|
-
node_for(key).bitcount(key, start, stop)
|
383
|
+
def bitcount(key, start = 0, stop = -1, scale: nil)
|
384
|
+
node_for(key).bitcount(key, start, stop, scale: scale)
|
372
385
|
end
|
373
386
|
|
374
387
|
# Perform a bitwise operation between strings and store the resulting string in a key.
|
375
388
|
def bitop(operation, destkey, *keys)
|
389
|
+
keys.flatten!(1)
|
376
390
|
ensure_same_node(:bitop, [destkey] + keys) do |node|
|
377
|
-
node.bitop(operation, destkey,
|
391
|
+
node.bitop(operation, destkey, keys)
|
378
392
|
end
|
379
393
|
end
|
380
394
|
|
381
395
|
# Return the position of the first bit set to 1 or 0 in a string.
|
382
|
-
def bitpos(key, bit, start = nil, stop = nil)
|
383
|
-
node_for(key).bitpos(key, bit, start, stop)
|
396
|
+
def bitpos(key, bit, start = nil, stop = nil, scale: nil)
|
397
|
+
node_for(key).bitpos(key, bit, start, stop, scale: scale)
|
384
398
|
end
|
385
399
|
|
386
400
|
# Set the string value of a key and return its old value.
|
@@ -463,23 +477,15 @@ class Redis
|
|
463
477
|
timeout = if args.last.is_a?(Hash)
|
464
478
|
options = args.pop
|
465
479
|
options[:timeout]
|
466
|
-
elsif args.last.respond_to?(:to_int)
|
467
|
-
last_arg = args.pop
|
468
|
-
::Redis.deprecate!(
|
469
|
-
"Passing the timeout as a positional argument is deprecated, it should be passed as a keyword argument:\n" \
|
470
|
-
" redis.#{cmd}(#{args.map(&:inspect).join(', ')}, timeout: #{last_arg.to_int})" \
|
471
|
-
"(called from: #{caller(2, 1).first})"
|
472
|
-
)
|
473
|
-
last_arg.to_int
|
474
480
|
end
|
475
481
|
|
476
|
-
|
482
|
+
args.flatten!(1)
|
477
483
|
|
478
|
-
ensure_same_node(cmd,
|
484
|
+
ensure_same_node(cmd, args) do |node|
|
479
485
|
if timeout
|
480
|
-
node.__send__(cmd,
|
486
|
+
node.__send__(cmd, args, timeout: timeout)
|
481
487
|
else
|
482
|
-
node.__send__(cmd,
|
488
|
+
node.__send__(cmd, args)
|
483
489
|
end
|
484
490
|
end
|
485
491
|
end
|
@@ -490,6 +496,18 @@ class Redis
|
|
490
496
|
_bpop(:blpop, args)
|
491
497
|
end
|
492
498
|
|
499
|
+
def bzpopmax(*args)
|
500
|
+
_bpop(:bzpopmax, args) do |reply|
|
501
|
+
reply.is_a?(Array) ? [reply[0], reply[1], Floatify.call(reply[2])] : reply
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
def bzpopmin(*args)
|
506
|
+
_bpop(:bzpopmin, args) do |reply|
|
507
|
+
reply.is_a?(Array) ? [reply[0], reply[1], Floatify.call(reply[2])] : reply
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
493
511
|
# Remove and get the last element in a list, or block until one is
|
494
512
|
# available.
|
495
513
|
def brpop(*args)
|
@@ -498,9 +516,9 @@ class Redis
|
|
498
516
|
|
499
517
|
# Pop a value from a list, push it to another list and return it; or block
|
500
518
|
# until one is available.
|
501
|
-
def brpoplpush(source, destination,
|
519
|
+
def brpoplpush(source, destination, **options)
|
502
520
|
ensure_same_node(:brpoplpush, [source, destination]) do |node|
|
503
|
-
node.brpoplpush(source, destination,
|
521
|
+
node.brpoplpush(source, destination, **options)
|
504
522
|
end
|
505
523
|
end
|
506
524
|
|
@@ -534,29 +552,43 @@ class Redis
|
|
534
552
|
node_for(key).ltrim(key, start, stop)
|
535
553
|
end
|
536
554
|
|
555
|
+
# Iterate over keys, blocking and removing elements from the first non empty liist found.
|
556
|
+
def blmpop(timeout, *keys, modifier: "LEFT", count: nil)
|
557
|
+
ensure_same_node(:blmpop, keys) do |node|
|
558
|
+
node.blmpop(timeout, *keys, modifier: modifier, count: count)
|
559
|
+
end
|
560
|
+
end
|
561
|
+
|
562
|
+
# Iterate over keys, removing elements from the first non list found.
|
563
|
+
def lmpop(*keys, modifier: "LEFT", count: nil)
|
564
|
+
ensure_same_node(:lmpop, keys) do |node|
|
565
|
+
node.lmpop(*keys, modifier: modifier, count: count)
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
537
569
|
# Get the number of members in a set.
|
538
570
|
def scard(key)
|
539
571
|
node_for(key).scard(key)
|
540
572
|
end
|
541
573
|
|
542
574
|
# Add one or more members to a set.
|
543
|
-
def sadd(key,
|
544
|
-
node_for(key).sadd(key,
|
575
|
+
def sadd(key, *members)
|
576
|
+
node_for(key).sadd(key, *members)
|
545
577
|
end
|
546
578
|
|
547
579
|
# Add one or more members to a set.
|
548
|
-
def sadd?(key,
|
549
|
-
node_for(key).sadd?(key,
|
580
|
+
def sadd?(key, *members)
|
581
|
+
node_for(key).sadd?(key, *members)
|
550
582
|
end
|
551
583
|
|
552
584
|
# Remove one or more members from a set.
|
553
|
-
def srem(key,
|
554
|
-
node_for(key).srem(key,
|
585
|
+
def srem(key, *members)
|
586
|
+
node_for(key).srem(key, *members)
|
555
587
|
end
|
556
588
|
|
557
589
|
# Remove one or more members from a set.
|
558
|
-
def srem?(key,
|
559
|
-
node_for(key).srem?(key,
|
590
|
+
def srem?(key, *members)
|
591
|
+
node_for(key).srem?(key, *members)
|
560
592
|
end
|
561
593
|
|
562
594
|
# Remove and return a random member from a set.
|
@@ -603,43 +635,49 @@ class Redis
|
|
603
635
|
|
604
636
|
# Subtract multiple sets.
|
605
637
|
def sdiff(*keys)
|
638
|
+
keys.flatten!(1)
|
606
639
|
ensure_same_node(:sdiff, keys) do |node|
|
607
|
-
node.sdiff(
|
640
|
+
node.sdiff(keys)
|
608
641
|
end
|
609
642
|
end
|
610
643
|
|
611
644
|
# Subtract multiple sets and store the resulting set in a key.
|
612
645
|
def sdiffstore(destination, *keys)
|
613
|
-
|
614
|
-
|
646
|
+
keys.flatten!(1)
|
647
|
+
ensure_same_node(:sdiffstore, [destination].concat(keys)) do |node|
|
648
|
+
node.sdiffstore(destination, keys)
|
615
649
|
end
|
616
650
|
end
|
617
651
|
|
618
652
|
# Intersect multiple sets.
|
619
653
|
def sinter(*keys)
|
654
|
+
keys.flatten!(1)
|
620
655
|
ensure_same_node(:sinter, keys) do |node|
|
621
|
-
node.sinter(
|
656
|
+
node.sinter(keys)
|
622
657
|
end
|
623
658
|
end
|
624
659
|
|
625
660
|
# Intersect multiple sets and store the resulting set in a key.
|
626
661
|
def sinterstore(destination, *keys)
|
627
|
-
|
628
|
-
|
662
|
+
keys.flatten!(1)
|
663
|
+
ensure_same_node(:sinterstore, [destination].concat(keys)) do |node|
|
664
|
+
node.sinterstore(destination, keys)
|
629
665
|
end
|
630
666
|
end
|
631
667
|
|
632
668
|
# Add multiple sets.
|
633
669
|
def sunion(*keys)
|
670
|
+
keys.flatten!(1)
|
634
671
|
ensure_same_node(:sunion, keys) do |node|
|
635
|
-
node.sunion(
|
672
|
+
node.sunion(keys)
|
636
673
|
end
|
637
674
|
end
|
638
675
|
|
639
676
|
# Add multiple sets and store the resulting set in a key.
|
640
677
|
def sunionstore(destination, *keys)
|
641
|
-
|
642
|
-
|
678
|
+
keys.flatten!(1)
|
679
|
+
ensure_same_node(:sunionstore, [destination].concat(keys)) do |node|
|
680
|
+
node.sunionstore(destination, keys)
|
643
681
|
end
|
644
682
|
end
|
645
683
|
|
@@ -680,6 +718,20 @@ class Redis
|
|
680
718
|
node_for(key).zmscore(key, *members)
|
681
719
|
end
|
682
720
|
|
721
|
+
# Iterate over keys, blocking and removing members from the first non empty sorted set found.
|
722
|
+
def bzmpop(timeout, *keys, modifier: "MIN", count: nil)
|
723
|
+
ensure_same_node(:bzmpop, keys) do |node|
|
724
|
+
node.bzmpop(timeout, *keys, modifier: modifier, count: count)
|
725
|
+
end
|
726
|
+
end
|
727
|
+
|
728
|
+
# Iterate over keys, removing members from the first non empty sorted set found.
|
729
|
+
def zmpop(*keys, modifier: "MIN", count: nil)
|
730
|
+
ensure_same_node(:zmpop, keys) do |node|
|
731
|
+
node.zmpop(*keys, modifier: modifier, count: count)
|
732
|
+
end
|
733
|
+
end
|
734
|
+
|
683
735
|
# Return a range of members in a sorted set, by index, score or lexicographical ordering.
|
684
736
|
def zrange(key, start, stop, **options)
|
685
737
|
node_for(key).zrange(key, start, stop, **options)
|
@@ -700,14 +752,14 @@ class Redis
|
|
700
752
|
end
|
701
753
|
|
702
754
|
# Determine the index of a member in a sorted set.
|
703
|
-
def zrank(key, member)
|
704
|
-
node_for(key).zrank(key, member)
|
755
|
+
def zrank(key, member, **options)
|
756
|
+
node_for(key).zrank(key, member, **options)
|
705
757
|
end
|
706
758
|
|
707
759
|
# Determine the index of a member in a sorted set, with scores ordered from
|
708
760
|
# high to low.
|
709
|
-
def zrevrank(key, member)
|
710
|
-
node_for(key).zrevrank(key, member)
|
761
|
+
def zrevrank(key, member, **options)
|
762
|
+
node_for(key).zrevrank(key, member, **options)
|
711
763
|
end
|
712
764
|
|
713
765
|
# Remove all members in a sorted set within the given indexes.
|
@@ -738,43 +790,49 @@ class Redis
|
|
738
790
|
|
739
791
|
# Get the intersection of multiple sorted sets
|
740
792
|
def zinter(*keys, **options)
|
793
|
+
keys.flatten!(1)
|
741
794
|
ensure_same_node(:zinter, keys) do |node|
|
742
|
-
node.zinter(
|
795
|
+
node.zinter(keys, **options)
|
743
796
|
end
|
744
797
|
end
|
745
798
|
|
746
799
|
# Intersect multiple sorted sets and store the resulting sorted set in a new
|
747
800
|
# key.
|
748
|
-
def zinterstore(destination, keys, **options)
|
749
|
-
|
801
|
+
def zinterstore(destination, *keys, **options)
|
802
|
+
keys.flatten!(1)
|
803
|
+
ensure_same_node(:zinterstore, [destination].concat(keys)) do |node|
|
750
804
|
node.zinterstore(destination, keys, **options)
|
751
805
|
end
|
752
806
|
end
|
753
807
|
|
754
808
|
# Return the union of multiple sorted sets.
|
755
809
|
def zunion(*keys, **options)
|
810
|
+
keys.flatten!(1)
|
756
811
|
ensure_same_node(:zunion, keys) do |node|
|
757
|
-
node.zunion(
|
812
|
+
node.zunion(keys, **options)
|
758
813
|
end
|
759
814
|
end
|
760
815
|
|
761
816
|
# Add multiple sorted sets and store the resulting sorted set in a new key.
|
762
|
-
def zunionstore(destination, keys, **options)
|
763
|
-
|
817
|
+
def zunionstore(destination, *keys, **options)
|
818
|
+
keys.flatten!(1)
|
819
|
+
ensure_same_node(:zunionstore, [destination].concat(keys)) do |node|
|
764
820
|
node.zunionstore(destination, keys, **options)
|
765
821
|
end
|
766
822
|
end
|
767
823
|
|
768
824
|
# Return the difference between the first and all successive input sorted sets.
|
769
825
|
def zdiff(*keys, **options)
|
826
|
+
keys.flatten!(1)
|
770
827
|
ensure_same_node(:zdiff, keys) do |node|
|
771
|
-
node.zdiff(
|
828
|
+
node.zdiff(keys, **options)
|
772
829
|
end
|
773
830
|
end
|
774
831
|
|
775
832
|
# Compute the difference between the first and all successive input sorted sets
|
776
833
|
# and store the resulting sorted set in a new key.
|
777
|
-
def zdiffstore(destination, keys, **options)
|
834
|
+
def zdiffstore(destination, *keys, **options)
|
835
|
+
keys.flatten!(1)
|
778
836
|
ensure_same_node(:zdiffstore, [destination] + keys) do |node|
|
779
837
|
node.zdiffstore(destination, keys, **options)
|
780
838
|
end
|
@@ -801,7 +859,7 @@ class Redis
|
|
801
859
|
end
|
802
860
|
|
803
861
|
def mapped_hmset(key, hash)
|
804
|
-
node_for(key).hmset(key,
|
862
|
+
node_for(key).hmset(key, hash)
|
805
863
|
end
|
806
864
|
|
807
865
|
# Get the value of a hash field.
|
@@ -811,11 +869,13 @@ class Redis
|
|
811
869
|
|
812
870
|
# Get the values of all the given hash fields.
|
813
871
|
def hmget(key, *fields)
|
814
|
-
|
872
|
+
fields.flatten!(1)
|
873
|
+
node_for(key).hmget(key, fields)
|
815
874
|
end
|
816
875
|
|
817
876
|
def mapped_hmget(key, *fields)
|
818
|
-
|
877
|
+
fields.flatten!(1)
|
878
|
+
node_for(key).mapped_hmget(key, fields)
|
819
879
|
end
|
820
880
|
|
821
881
|
def hrandfield(key, count = nil, **options)
|
@@ -824,7 +884,8 @@ class Redis
|
|
824
884
|
|
825
885
|
# Delete one or more hash fields.
|
826
886
|
def hdel(key, *fields)
|
827
|
-
|
887
|
+
fields.flatten!(1)
|
888
|
+
node_for(key).hdel(key, fields)
|
828
889
|
end
|
829
890
|
|
830
891
|
# Determine if a hash field exists.
|
@@ -881,18 +942,22 @@ class Redis
|
|
881
942
|
|
882
943
|
# Stop listening for messages posted to the given channels.
|
883
944
|
def unsubscribe(*channels)
|
884
|
-
raise "Can't unsubscribe if not subscribed." unless subscribed?
|
945
|
+
raise SubscriptionError, "Can't unsubscribe if not subscribed." unless subscribed?
|
885
946
|
|
886
947
|
@subscribed_node.unsubscribe(*channels)
|
887
948
|
end
|
888
949
|
|
889
950
|
# Listen for messages published to channels matching the given patterns.
|
951
|
+
# See the [Redis Server PSUBSCRIBE documentation](https://redis.io/docs/latest/commands/psubscribe/)
|
952
|
+
# for further details
|
890
953
|
def psubscribe(*channels, &block)
|
891
954
|
raise NotImplementedError
|
892
955
|
end
|
893
956
|
|
894
957
|
# Stop listening for messages posted to channels matching the given
|
895
958
|
# patterns.
|
959
|
+
# See the [Redis Server PUNSUBSCRIBE documentation](https://redis.io/docs/latest/commands/punsubscribe/)
|
960
|
+
# for further details
|
896
961
|
def punsubscribe(*channels)
|
897
962
|
raise NotImplementedError
|
898
963
|
end
|
@@ -928,9 +993,7 @@ class Redis
|
|
928
993
|
def multi(&block)
|
929
994
|
raise CannotDistribute, :multi unless @watch_key
|
930
995
|
|
931
|
-
|
932
|
-
@watch_key = nil if block_given?
|
933
|
-
result
|
996
|
+
node_for(@watch_key).multi(&block)
|
934
997
|
end
|
935
998
|
|
936
999
|
# Execute all commands issued after MULTI.
|
@@ -1020,7 +1083,8 @@ class Redis
|
|
1020
1083
|
end
|
1021
1084
|
|
1022
1085
|
def key_tag(key)
|
1023
|
-
key.to_s
|
1086
|
+
key = key.to_s
|
1087
|
+
key[@tag, 1] if key.match?(@tag)
|
1024
1088
|
end
|
1025
1089
|
|
1026
1090
|
def ensure_same_node(command, keys)
|