redis 4.1.2 → 4.2.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 +28 -1
- data/README.md +14 -5
- data/lib/redis/client.rb +66 -69
- data/lib/redis/cluster/node.rb +3 -0
- data/lib/redis/cluster/node_key.rb +3 -7
- data/lib/redis/cluster/option.rb +27 -14
- data/lib/redis/cluster/slot.rb +30 -13
- data/lib/redis/cluster/slot_loader.rb +4 -4
- data/lib/redis/cluster.rb +13 -4
- data/lib/redis/connection/command_helper.rb +3 -2
- data/lib/redis/connection/hiredis.rb +4 -3
- data/lib/redis/connection/registry.rb +2 -1
- data/lib/redis/connection/ruby.rb +47 -58
- data/lib/redis/connection/synchrony.rb +9 -4
- data/lib/redis/connection.rb +2 -0
- data/lib/redis/distributed.rb +81 -55
- data/lib/redis/errors.rb +2 -0
- data/lib/redis/hash_ring.rb +15 -14
- data/lib/redis/pipeline.rb +16 -3
- data/lib/redis/subscribe.rb +11 -12
- data/lib/redis/version.rb +3 -1
- data/lib/redis.rb +361 -342
- metadata +5 -5
data/lib/redis.rb
CHANGED
@@ -4,32 +4,36 @@ require "monitor"
|
|
4
4
|
require_relative "redis/errors"
|
5
5
|
|
6
6
|
class Redis
|
7
|
+
class << self
|
8
|
+
attr_accessor :exists_returns_integer
|
9
|
+
attr_writer :current
|
10
|
+
end
|
7
11
|
|
8
12
|
def self.current
|
9
13
|
@current ||= Redis.new
|
10
14
|
end
|
11
15
|
|
12
|
-
def self.current=(redis)
|
13
|
-
@current = redis
|
14
|
-
end
|
15
|
-
|
16
16
|
include MonitorMixin
|
17
17
|
|
18
18
|
# Create a new client instance
|
19
19
|
#
|
20
20
|
# @param [Hash] options
|
21
|
-
# @option options [String] :url (value of the environment variable REDIS_URL) a Redis URL, for a TCP connection:
|
21
|
+
# @option options [String] :url (value of the environment variable REDIS_URL) a Redis URL, for a TCP connection:
|
22
|
+
# `redis://:[password]@[hostname]:[port]/[db]` (password, port and database are optional), for a unix socket
|
23
|
+
# connection: `unix://[path to Redis socket]`. This overrides all other options.
|
22
24
|
# @option options [String] :host ("127.0.0.1") server hostname
|
23
|
-
# @option options [
|
25
|
+
# @option options [Integer] :port (6379) server port
|
24
26
|
# @option options [String] :path path to server socket (overrides host and port)
|
25
27
|
# @option options [Float] :timeout (5.0) timeout in seconds
|
26
28
|
# @option options [Float] :connect_timeout (same as timeout) timeout for initial connect in seconds
|
27
29
|
# @option options [String] :password Password to authenticate against server
|
28
|
-
# @option options [
|
30
|
+
# @option options [Integer] :db (0) Database to select after initial connect
|
29
31
|
# @option options [Symbol] :driver Driver to use, currently supported: `:ruby`, `:hiredis`, `:synchrony`
|
30
|
-
# @option options [String] :id ID for the client connection, assigns name to current connection by sending
|
31
|
-
#
|
32
|
-
# @option options [
|
32
|
+
# @option options [String] :id ID for the client connection, assigns name to current connection by sending
|
33
|
+
# `CLIENT SETNAME`
|
34
|
+
# @option options [Hash, Integer] :tcp_keepalive Keepalive values, if Integer `intvl` and `probe` are calculated
|
35
|
+
# based on the value, if Hash `time`, `intvl` and `probes` can be specified as a Integer
|
36
|
+
# @option options [Integer] :reconnect_attempts Number of attempts trying to connect
|
33
37
|
# @option options [Boolean] :inherit_socket (false) Whether to use socket in forked process or not
|
34
38
|
# @option options [Array] :sentinels List of sentinels to contact
|
35
39
|
# @option options [Symbol] :role (:master) Role to fetch via Sentinel, either `:master` or `:slave`
|
@@ -53,7 +57,7 @@ class Redis
|
|
53
57
|
end
|
54
58
|
|
55
59
|
# Run code with the client reconnecting
|
56
|
-
def with_reconnect(val=true, &blk)
|
60
|
+
def with_reconnect(val = true, &blk)
|
57
61
|
synchronize do |client|
|
58
62
|
client.with_reconnect(val, &blk)
|
59
63
|
end
|
@@ -96,7 +100,9 @@ class Redis
|
|
96
100
|
# See http://redis.io/topics/pipelining for more details.
|
97
101
|
#
|
98
102
|
def queue(*command)
|
99
|
-
|
103
|
+
synchronize do
|
104
|
+
@queue[Thread.current.object_id] << command
|
105
|
+
end
|
100
106
|
end
|
101
107
|
|
102
108
|
# Sends all commands in the queue.
|
@@ -135,7 +141,7 @@ class Redis
|
|
135
141
|
|
136
142
|
# Change the selected database for the current connection.
|
137
143
|
#
|
138
|
-
# @param [
|
144
|
+
# @param [Integer] db zero-based index of the DB to use (0 to 15)
|
139
145
|
# @return [String] `OK`
|
140
146
|
def select(db)
|
141
147
|
synchronize do |client|
|
@@ -204,7 +210,7 @@ class Redis
|
|
204
210
|
def config(action, *args)
|
205
211
|
synchronize do |client|
|
206
212
|
client.call([:config, action] + args) do |reply|
|
207
|
-
if reply.
|
213
|
+
if reply.is_a?(Array) && action == :get
|
208
214
|
Hashify.call(reply)
|
209
215
|
else
|
210
216
|
reply
|
@@ -234,7 +240,7 @@ class Redis
|
|
234
240
|
|
235
241
|
# Return the number of keys in the selected database.
|
236
242
|
#
|
237
|
-
# @return [
|
243
|
+
# @return [Integer]
|
238
244
|
def dbsize
|
239
245
|
synchronize do |client|
|
240
246
|
client.call([:dbsize])
|
@@ -255,7 +261,7 @@ class Redis
|
|
255
261
|
def flushall(options = nil)
|
256
262
|
synchronize do |client|
|
257
263
|
if options && options[:async]
|
258
|
-
client.call([
|
264
|
+
client.call(%i[flushall async])
|
259
265
|
else
|
260
266
|
client.call([:flushall])
|
261
267
|
end
|
@@ -270,7 +276,7 @@ class Redis
|
|
270
276
|
def flushdb(options = nil)
|
271
277
|
synchronize do |client|
|
272
278
|
if options && options[:async]
|
273
|
-
client.call([
|
279
|
+
client.call(%i[flushdb async])
|
274
280
|
else
|
275
281
|
client.call([:flushdb])
|
276
282
|
end
|
@@ -284,7 +290,7 @@ class Redis
|
|
284
290
|
def info(cmd = nil)
|
285
291
|
synchronize do |client|
|
286
292
|
client.call([:info, cmd].compact) do |reply|
|
287
|
-
if reply.
|
293
|
+
if reply.is_a?(String)
|
288
294
|
reply = HashifyInfo.call(reply)
|
289
295
|
|
290
296
|
if cmd && cmd.to_s == "commandstats"
|
@@ -303,7 +309,7 @@ class Redis
|
|
303
309
|
|
304
310
|
# Get the UNIX time stamp of the last successful save to disk.
|
305
311
|
#
|
306
|
-
# @return [
|
312
|
+
# @return [Integer]
|
307
313
|
def lastsave
|
308
314
|
synchronize do |client|
|
309
315
|
client.call([:lastsave])
|
@@ -355,9 +361,9 @@ class Redis
|
|
355
361
|
# Interact with the slowlog (get, len, reset)
|
356
362
|
#
|
357
363
|
# @param [String] subcommand e.g. `get`, `len`, `reset`
|
358
|
-
# @param [
|
359
|
-
# @return [Array<String>,
|
360
|
-
def slowlog(subcommand, length=nil)
|
364
|
+
# @param [Integer] length maximum number of entries to return
|
365
|
+
# @return [Array<String>, Integer, String] depends on subcommand
|
366
|
+
def slowlog(subcommand, length = nil)
|
361
367
|
synchronize do |client|
|
362
368
|
args = [:slowlog, subcommand]
|
363
369
|
args << length if length
|
@@ -377,12 +383,12 @@ class Redis
|
|
377
383
|
# @example
|
378
384
|
# r.time # => [ 1333093196, 606806 ]
|
379
385
|
#
|
380
|
-
# @return [Array<
|
386
|
+
# @return [Array<Integer>] tuple of seconds since UNIX epoch and
|
381
387
|
# microseconds in the current second
|
382
388
|
def time
|
383
389
|
synchronize do |client|
|
384
390
|
client.call([:time]) do |reply|
|
385
|
-
reply
|
391
|
+
reply&.map(&:to_i)
|
386
392
|
end
|
387
393
|
end
|
388
394
|
end
|
@@ -400,7 +406,7 @@ class Redis
|
|
400
406
|
# Set a key's time to live in seconds.
|
401
407
|
#
|
402
408
|
# @param [String] key
|
403
|
-
# @param [
|
409
|
+
# @param [Integer] seconds time to live
|
404
410
|
# @return [Boolean] whether the timeout was set or not
|
405
411
|
def expire(key, seconds)
|
406
412
|
synchronize do |client|
|
@@ -411,7 +417,7 @@ class Redis
|
|
411
417
|
# Set the expiration for a key as a UNIX timestamp.
|
412
418
|
#
|
413
419
|
# @param [String] key
|
414
|
-
# @param [
|
420
|
+
# @param [Integer] unix_time expiry time specified as a UNIX timestamp
|
415
421
|
# @return [Boolean] whether the timeout was set or not
|
416
422
|
def expireat(key, unix_time)
|
417
423
|
synchronize do |client|
|
@@ -422,7 +428,7 @@ class Redis
|
|
422
428
|
# Get the time to live (in seconds) for a key.
|
423
429
|
#
|
424
430
|
# @param [String] key
|
425
|
-
# @return [
|
431
|
+
# @return [Integer] remaining time to live in seconds.
|
426
432
|
#
|
427
433
|
# In Redis 2.6 or older the command returns -1 if the key does not exist or if
|
428
434
|
# the key exist but has no associated expire.
|
@@ -440,7 +446,7 @@ class Redis
|
|
440
446
|
# Set a key's time to live in milliseconds.
|
441
447
|
#
|
442
448
|
# @param [String] key
|
443
|
-
# @param [
|
449
|
+
# @param [Integer] milliseconds time to live
|
444
450
|
# @return [Boolean] whether the timeout was set or not
|
445
451
|
def pexpire(key, milliseconds)
|
446
452
|
synchronize do |client|
|
@@ -451,7 +457,7 @@ class Redis
|
|
451
457
|
# Set the expiration for a key as number of milliseconds from UNIX Epoch.
|
452
458
|
#
|
453
459
|
# @param [String] key
|
454
|
-
# @param [
|
460
|
+
# @param [Integer] ms_unix_time expiry time specified as number of milliseconds from UNIX Epoch.
|
455
461
|
# @return [Boolean] whether the timeout was set or not
|
456
462
|
def pexpireat(key, ms_unix_time)
|
457
463
|
synchronize do |client|
|
@@ -462,7 +468,7 @@ class Redis
|
|
462
468
|
# Get the time to live (in milliseconds) for a key.
|
463
469
|
#
|
464
470
|
# @param [String] key
|
465
|
-
# @return [
|
471
|
+
# @return [Integer] remaining time to live in milliseconds
|
466
472
|
# In Redis 2.6 or older the command returns -1 if the key does not exist or if
|
467
473
|
# the key exist but has no associated expire.
|
468
474
|
#
|
@@ -495,9 +501,9 @@ class Redis
|
|
495
501
|
# - `:replace => Boolean`: if false, raises an error if key already exists
|
496
502
|
# @raise [Redis::CommandError]
|
497
503
|
# @return [String] `"OK"`
|
498
|
-
def restore(key, ttl, serialized_value,
|
504
|
+
def restore(key, ttl, serialized_value, replace: nil)
|
499
505
|
args = [:restore, key, ttl, serialized_value]
|
500
|
-
args << 'REPLACE' if
|
506
|
+
args << 'REPLACE' if replace
|
501
507
|
|
502
508
|
synchronize do |client|
|
503
509
|
client.call(args)
|
@@ -532,7 +538,7 @@ class Redis
|
|
532
538
|
# Delete one or more keys.
|
533
539
|
#
|
534
540
|
# @param [String, Array<String>] keys
|
535
|
-
# @return [
|
541
|
+
# @return [Integer] number of keys that were deleted
|
536
542
|
def del(*keys)
|
537
543
|
synchronize do |client|
|
538
544
|
client.call([:del] + keys)
|
@@ -542,20 +548,43 @@ class Redis
|
|
542
548
|
# Unlink one or more keys.
|
543
549
|
#
|
544
550
|
# @param [String, Array<String>] keys
|
545
|
-
# @return [
|
551
|
+
# @return [Integer] number of keys that were unlinked
|
546
552
|
def unlink(*keys)
|
547
553
|
synchronize do |client|
|
548
554
|
client.call([:unlink] + keys)
|
549
555
|
end
|
550
556
|
end
|
551
557
|
|
552
|
-
# Determine
|
558
|
+
# Determine how many of the keys exists.
|
553
559
|
#
|
554
|
-
# @param [String]
|
560
|
+
# @param [String, Array<String>] keys
|
561
|
+
# @return [Integer]
|
562
|
+
def exists(*keys)
|
563
|
+
if !Redis.exists_returns_integer && keys.size == 1
|
564
|
+
message = "`Redis#exists(key)` will return an Integer in redis-rb 4.3, if you want to keep the old behavior, " \
|
565
|
+
"use `exists?` instead. To opt-in to the new behavior now you can set Redis.exists_returns_integer = true. " \
|
566
|
+
"(#{::Kernel.caller(1, 1).first})\n"
|
567
|
+
|
568
|
+
::Kernel.warn(message)
|
569
|
+
exists?(*keys)
|
570
|
+
else
|
571
|
+
_exists(*keys)
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
def _exists(*keys)
|
576
|
+
synchronize do |client|
|
577
|
+
client.call([:exists, *keys])
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
# Determine if any of the keys exists.
|
582
|
+
#
|
583
|
+
# @param [String, Array<String>] keys
|
555
584
|
# @return [Boolean]
|
556
|
-
def exists(
|
585
|
+
def exists?(*keys)
|
557
586
|
synchronize do |client|
|
558
|
-
client.call([:exists,
|
587
|
+
client.call([:exists, *keys], &Boolify)
|
559
588
|
end
|
560
589
|
end
|
561
590
|
|
@@ -566,7 +595,7 @@ class Redis
|
|
566
595
|
def keys(pattern = "*")
|
567
596
|
synchronize do |client|
|
568
597
|
client.call([:keys, pattern]) do |reply|
|
569
|
-
if reply.
|
598
|
+
if reply.is_a?(String)
|
570
599
|
reply.split(" ")
|
571
600
|
else
|
572
601
|
reply
|
@@ -592,7 +621,7 @@ class Redis
|
|
592
621
|
# # => "bar"
|
593
622
|
#
|
594
623
|
# @param [String] key
|
595
|
-
# @param [
|
624
|
+
# @param [Integer] db
|
596
625
|
# @return [Boolean] whether the key was moved or not
|
597
626
|
def move(key, db)
|
598
627
|
synchronize do |client|
|
@@ -656,36 +685,33 @@ class Redis
|
|
656
685
|
# - `:order => String`: combination of `ASC`, `DESC` and optionally `ALPHA`
|
657
686
|
# - `:store => String`: key to store the result at
|
658
687
|
#
|
659
|
-
# @return [Array<String>, Array<Array<String>>,
|
688
|
+
# @return [Array<String>, Array<Array<String>>, Integer]
|
660
689
|
# - when `:get` is not specified, or holds a single element, an array of elements
|
661
690
|
# - when `:get` is specified, and holds more than one element, an array of
|
662
691
|
# elements where every element is an array with the result for every
|
663
692
|
# element specified in `:get`
|
664
693
|
# - when `:store` is specified, the number of elements in the stored result
|
665
|
-
def sort(key,
|
666
|
-
args = []
|
694
|
+
def sort(key, by: nil, limit: nil, get: nil, order: nil, store: nil)
|
695
|
+
args = [:sort, key]
|
696
|
+
args << "BY" << by if by
|
667
697
|
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
args.concat(["LIMIT"] + limit) if limit
|
698
|
+
if limit
|
699
|
+
args << "LIMIT"
|
700
|
+
args.concat(limit)
|
701
|
+
end
|
673
702
|
|
674
|
-
get = Array(
|
675
|
-
|
703
|
+
get = Array(get)
|
704
|
+
get.each do |item|
|
705
|
+
args << "GET" << item
|
706
|
+
end
|
676
707
|
|
677
|
-
order = options[:order]
|
678
708
|
args.concat(order.split(" ")) if order
|
679
|
-
|
680
|
-
store = options[:store]
|
681
|
-
args.concat(["STORE", store]) if store
|
709
|
+
args << "STORE" << store if store
|
682
710
|
|
683
711
|
synchronize do |client|
|
684
|
-
client.call(
|
712
|
+
client.call(args) do |reply|
|
685
713
|
if get.size > 1 && !store
|
686
|
-
if reply
|
687
|
-
reply.each_slice(get.size).to_a
|
688
|
-
end
|
714
|
+
reply.each_slice(get.size).to_a if reply
|
689
715
|
else
|
690
716
|
reply
|
691
717
|
end
|
@@ -710,7 +736,7 @@ class Redis
|
|
710
736
|
# # => 4
|
711
737
|
#
|
712
738
|
# @param [String] key
|
713
|
-
# @return [
|
739
|
+
# @return [Integer] value after decrementing it
|
714
740
|
def decr(key)
|
715
741
|
synchronize do |client|
|
716
742
|
client.call([:decr, key])
|
@@ -724,8 +750,8 @@ class Redis
|
|
724
750
|
# # => 0
|
725
751
|
#
|
726
752
|
# @param [String] key
|
727
|
-
# @param [
|
728
|
-
# @return [
|
753
|
+
# @param [Integer] decrement
|
754
|
+
# @return [Integer] value after decrementing it
|
729
755
|
def decrby(key, decrement)
|
730
756
|
synchronize do |client|
|
731
757
|
client.call([:decrby, key, decrement])
|
@@ -739,7 +765,7 @@ class Redis
|
|
739
765
|
# # => 6
|
740
766
|
#
|
741
767
|
# @param [String] key
|
742
|
-
# @return [
|
768
|
+
# @return [Integer] value after incrementing it
|
743
769
|
def incr(key)
|
744
770
|
synchronize do |client|
|
745
771
|
client.call([:incr, key])
|
@@ -753,8 +779,8 @@ class Redis
|
|
753
779
|
# # => 10
|
754
780
|
#
|
755
781
|
# @param [String] key
|
756
|
-
# @param [
|
757
|
-
# @return [
|
782
|
+
# @param [Integer] increment
|
783
|
+
# @return [Integer] value after incrementing it
|
758
784
|
def incrby(key, increment)
|
759
785
|
synchronize do |client|
|
760
786
|
client.call([:incrby, key, increment])
|
@@ -781,31 +807,25 @@ class Redis
|
|
781
807
|
# @param [String] key
|
782
808
|
# @param [String] value
|
783
809
|
# @param [Hash] options
|
784
|
-
# - `:ex =>
|
785
|
-
# - `:px =>
|
810
|
+
# - `:ex => Integer`: Set the specified expire time, in seconds.
|
811
|
+
# - `:px => Integer`: Set the specified expire time, in milliseconds.
|
786
812
|
# - `:nx => true`: Only set the key if it does not already exist.
|
787
813
|
# - `:xx => true`: Only set the key if it already exist.
|
814
|
+
# - `:keepttl => true`: Retain the time to live associated with the key.
|
788
815
|
# @return [String, Boolean] `"OK"` or true, false if `:nx => true` or `:xx => true`
|
789
|
-
def set(key, value,
|
790
|
-
args = []
|
791
|
-
|
792
|
-
|
793
|
-
args
|
794
|
-
|
795
|
-
|
796
|
-
args.concat(["PX", px]) if px
|
797
|
-
|
798
|
-
nx = options[:nx]
|
799
|
-
args.concat(["NX"]) if nx
|
800
|
-
|
801
|
-
xx = options[:xx]
|
802
|
-
args.concat(["XX"]) if xx
|
816
|
+
def set(key, value, ex: nil, px: nil, nx: nil, xx: nil, keepttl: nil)
|
817
|
+
args = [:set, key, value.to_s]
|
818
|
+
args << "EX" << ex if ex
|
819
|
+
args << "PX" << px if px
|
820
|
+
args << "NX" if nx
|
821
|
+
args << "XX" if xx
|
822
|
+
args << "KEEPTTL" if keepttl
|
803
823
|
|
804
824
|
synchronize do |client|
|
805
825
|
if nx || xx
|
806
|
-
client.call(
|
826
|
+
client.call(args, &BoolifySet)
|
807
827
|
else
|
808
|
-
client.call(
|
828
|
+
client.call(args)
|
809
829
|
end
|
810
830
|
end
|
811
831
|
end
|
@@ -813,7 +833,7 @@ class Redis
|
|
813
833
|
# Set the time to live in seconds of a key.
|
814
834
|
#
|
815
835
|
# @param [String] key
|
816
|
-
# @param [
|
836
|
+
# @param [Integer] ttl
|
817
837
|
# @param [String] value
|
818
838
|
# @return [String] `"OK"`
|
819
839
|
def setex(key, ttl, value)
|
@@ -825,7 +845,7 @@ class Redis
|
|
825
845
|
# Set the time to live in milliseconds of a key.
|
826
846
|
#
|
827
847
|
# @param [String] key
|
828
|
-
# @param [
|
848
|
+
# @param [Integer] ttl
|
829
849
|
# @param [String] value
|
830
850
|
# @return [String] `"OK"`
|
831
851
|
def psetex(key, ttl, value)
|
@@ -887,7 +907,7 @@ class Redis
|
|
887
907
|
# @see #mapped_msetnx
|
888
908
|
def msetnx(*args)
|
889
909
|
synchronize do |client|
|
890
|
-
client.call([:msetnx
|
910
|
+
client.call([:msetnx, *args], &Boolify)
|
891
911
|
end
|
892
912
|
end
|
893
913
|
|
@@ -918,7 +938,7 @@ class Redis
|
|
918
938
|
# Get the values of all the given keys.
|
919
939
|
#
|
920
940
|
# @example
|
921
|
-
# redis.mget("key1", "
|
941
|
+
# redis.mget("key1", "key2")
|
922
942
|
# # => ["v1", "v2"]
|
923
943
|
#
|
924
944
|
# @param [Array<String>] keys
|
@@ -927,7 +947,7 @@ class Redis
|
|
927
947
|
# @see #mapped_mget
|
928
948
|
def mget(*keys, &blk)
|
929
949
|
synchronize do |client|
|
930
|
-
client.call([:mget
|
950
|
+
client.call([:mget, *keys], &blk)
|
931
951
|
end
|
932
952
|
end
|
933
953
|
|
@@ -943,7 +963,7 @@ class Redis
|
|
943
963
|
# @see #mget
|
944
964
|
def mapped_mget(*keys)
|
945
965
|
mget(*keys) do |reply|
|
946
|
-
if reply.
|
966
|
+
if reply.is_a?(Array)
|
947
967
|
Hash[keys.zip(reply)]
|
948
968
|
else
|
949
969
|
reply
|
@@ -954,9 +974,9 @@ class Redis
|
|
954
974
|
# Overwrite part of a string at key starting at the specified offset.
|
955
975
|
#
|
956
976
|
# @param [String] key
|
957
|
-
# @param [
|
977
|
+
# @param [Integer] offset byte offset
|
958
978
|
# @param [String] value
|
959
|
-
# @return [
|
979
|
+
# @return [Integer] length of the string after it was modified
|
960
980
|
def setrange(key, offset, value)
|
961
981
|
synchronize do |client|
|
962
982
|
client.call([:setrange, key, offset, value.to_s])
|
@@ -966,10 +986,10 @@ class Redis
|
|
966
986
|
# Get a substring of the string stored at a key.
|
967
987
|
#
|
968
988
|
# @param [String] key
|
969
|
-
# @param [
|
970
|
-
# @param [
|
989
|
+
# @param [Integer] start zero-based start offset
|
990
|
+
# @param [Integer] stop zero-based end offset. Use -1 for representing
|
971
991
|
# the end of the string
|
972
|
-
# @return [
|
992
|
+
# @return [Integer] `0` or `1`
|
973
993
|
def getrange(key, start, stop)
|
974
994
|
synchronize do |client|
|
975
995
|
client.call([:getrange, key, start, stop])
|
@@ -979,9 +999,9 @@ class Redis
|
|
979
999
|
# Sets or clears the bit at offset in the string value stored at key.
|
980
1000
|
#
|
981
1001
|
# @param [String] key
|
982
|
-
# @param [
|
983
|
-
# @param [
|
984
|
-
# @return [
|
1002
|
+
# @param [Integer] offset bit offset
|
1003
|
+
# @param [Integer] value bit value `0` or `1`
|
1004
|
+
# @return [Integer] the original bit value stored at `offset`
|
985
1005
|
def setbit(key, offset, value)
|
986
1006
|
synchronize do |client|
|
987
1007
|
client.call([:setbit, key, offset, value])
|
@@ -991,8 +1011,8 @@ class Redis
|
|
991
1011
|
# Returns the bit value at offset in the string value stored at key.
|
992
1012
|
#
|
993
1013
|
# @param [String] key
|
994
|
-
# @param [
|
995
|
-
# @return [
|
1014
|
+
# @param [Integer] offset bit offset
|
1015
|
+
# @return [Integer] `0` or `1`
|
996
1016
|
def getbit(key, offset)
|
997
1017
|
synchronize do |client|
|
998
1018
|
client.call([:getbit, key, offset])
|
@@ -1003,7 +1023,7 @@ class Redis
|
|
1003
1023
|
#
|
1004
1024
|
# @param [String] key
|
1005
1025
|
# @param [String] value value to append
|
1006
|
-
# @return [
|
1026
|
+
# @return [Integer] length of the string after appending
|
1007
1027
|
def append(key, value)
|
1008
1028
|
synchronize do |client|
|
1009
1029
|
client.call([:append, key, value])
|
@@ -1013,9 +1033,9 @@ class Redis
|
|
1013
1033
|
# Count the number of set bits in a range of the string value stored at key.
|
1014
1034
|
#
|
1015
1035
|
# @param [String] key
|
1016
|
-
# @param [
|
1017
|
-
# @param [
|
1018
|
-
# @return [
|
1036
|
+
# @param [Integer] start start index
|
1037
|
+
# @param [Integer] stop stop index
|
1038
|
+
# @return [Integer] the number of bits set to 1
|
1019
1039
|
def bitcount(key, start = 0, stop = -1)
|
1020
1040
|
synchronize do |client|
|
1021
1041
|
client.call([:bitcount, key, start, stop])
|
@@ -1027,25 +1047,23 @@ class Redis
|
|
1027
1047
|
# @param [String] operation e.g. `and`, `or`, `xor`, `not`
|
1028
1048
|
# @param [String] destkey destination key
|
1029
1049
|
# @param [String, Array<String>] keys one or more source keys to perform `operation`
|
1030
|
-
# @return [
|
1050
|
+
# @return [Integer] the length of the string stored in `destkey`
|
1031
1051
|
def bitop(operation, destkey, *keys)
|
1032
1052
|
synchronize do |client|
|
1033
|
-
client.call([:bitop, operation, destkey
|
1053
|
+
client.call([:bitop, operation, destkey, *keys])
|
1034
1054
|
end
|
1035
1055
|
end
|
1036
1056
|
|
1037
1057
|
# Return the position of the first bit set to 1 or 0 in a string.
|
1038
1058
|
#
|
1039
1059
|
# @param [String] key
|
1040
|
-
# @param [
|
1041
|
-
# @param [
|
1042
|
-
# @param [
|
1043
|
-
# @return [
|
1060
|
+
# @param [Integer] bit whether to look for the first 1 or 0 bit
|
1061
|
+
# @param [Integer] start start index
|
1062
|
+
# @param [Integer] stop stop index
|
1063
|
+
# @return [Integer] the position of the first 1/0 bit.
|
1044
1064
|
# -1 if looking for 1 and it is not found or start and stop are given.
|
1045
|
-
def bitpos(key, bit, start=nil, stop=nil)
|
1046
|
-
|
1047
|
-
raise(ArgumentError, 'stop parameter specified without start parameter')
|
1048
|
-
end
|
1065
|
+
def bitpos(key, bit, start = nil, stop = nil)
|
1066
|
+
raise(ArgumentError, 'stop parameter specified without start parameter') if stop && !start
|
1049
1067
|
|
1050
1068
|
synchronize do |client|
|
1051
1069
|
command = [:bitpos, key, bit]
|
@@ -1070,7 +1088,7 @@ class Redis
|
|
1070
1088
|
# Get the length of the value stored in a key.
|
1071
1089
|
#
|
1072
1090
|
# @param [String] key
|
1073
|
-
# @return [
|
1091
|
+
# @return [Integer] the length of the value stored in the key, or 0
|
1074
1092
|
# if the key does not exist
|
1075
1093
|
def strlen(key)
|
1076
1094
|
synchronize do |client|
|
@@ -1081,7 +1099,7 @@ class Redis
|
|
1081
1099
|
# Get the length of a list.
|
1082
1100
|
#
|
1083
1101
|
# @param [String] key
|
1084
|
-
# @return [
|
1102
|
+
# @return [Integer]
|
1085
1103
|
def llen(key)
|
1086
1104
|
synchronize do |client|
|
1087
1105
|
client.call([:llen, key])
|
@@ -1092,7 +1110,7 @@ class Redis
|
|
1092
1110
|
#
|
1093
1111
|
# @param [String] key
|
1094
1112
|
# @param [String, Array<String>] value string value, or array of string values to push
|
1095
|
-
# @return [
|
1113
|
+
# @return [Integer] the length of the list after the push operation
|
1096
1114
|
def lpush(key, value)
|
1097
1115
|
synchronize do |client|
|
1098
1116
|
client.call([:lpush, key, value])
|
@@ -1103,7 +1121,7 @@ class Redis
|
|
1103
1121
|
#
|
1104
1122
|
# @param [String] key
|
1105
1123
|
# @param [String] value
|
1106
|
-
# @return [
|
1124
|
+
# @return [Integer] the length of the list after the push operation
|
1107
1125
|
def lpushx(key, value)
|
1108
1126
|
synchronize do |client|
|
1109
1127
|
client.call([:lpushx, key, value])
|
@@ -1114,7 +1132,7 @@ class Redis
|
|
1114
1132
|
#
|
1115
1133
|
# @param [String] key
|
1116
1134
|
# @param [String, Array<String>] value string value, or array of string values to push
|
1117
|
-
# @return [
|
1135
|
+
# @return [Integer] the length of the list after the push operation
|
1118
1136
|
def rpush(key, value)
|
1119
1137
|
synchronize do |client|
|
1120
1138
|
client.call([:rpush, key, value])
|
@@ -1125,7 +1143,7 @@ class Redis
|
|
1125
1143
|
#
|
1126
1144
|
# @param [String] key
|
1127
1145
|
# @param [String] value
|
1128
|
-
# @return [
|
1146
|
+
# @return [Integer] the length of the list after the push operation
|
1129
1147
|
def rpushx(key, value)
|
1130
1148
|
synchronize do |client|
|
1131
1149
|
client.call([:rpushx, key, value])
|
@@ -1164,21 +1182,21 @@ class Redis
|
|
1164
1182
|
end
|
1165
1183
|
|
1166
1184
|
def _bpop(cmd, args, &blk)
|
1167
|
-
|
1168
|
-
|
1169
|
-
if args.last.is_a?(Hash)
|
1185
|
+
timeout = if args.last.is_a?(Hash)
|
1170
1186
|
options = args.pop
|
1187
|
+
options[:timeout]
|
1171
1188
|
elsif args.last.respond_to?(:to_int)
|
1172
1189
|
# Issue deprecation notice in obnoxious mode...
|
1173
|
-
|
1190
|
+
args.pop.to_int
|
1174
1191
|
end
|
1175
1192
|
|
1193
|
+
timeout ||= 0
|
1194
|
+
|
1176
1195
|
if args.size > 1
|
1177
1196
|
# Issue deprecation notice in obnoxious mode...
|
1178
1197
|
end
|
1179
1198
|
|
1180
1199
|
keys = args.flatten
|
1181
|
-
timeout = options[:timeout] || 0
|
1182
1200
|
|
1183
1201
|
synchronize do |client|
|
1184
1202
|
command = [cmd, keys, timeout]
|
@@ -1203,7 +1221,7 @@ class Redis
|
|
1203
1221
|
# @param [String, Array<String>] keys one or more keys to perform the
|
1204
1222
|
# blocking pop on
|
1205
1223
|
# @param [Hash] options
|
1206
|
-
# - `:timeout =>
|
1224
|
+
# - `:timeout => Integer`: timeout in seconds, defaults to no timeout
|
1207
1225
|
#
|
1208
1226
|
# @return [nil, [String, String]]
|
1209
1227
|
# - `nil` when the operation timed out
|
@@ -1217,7 +1235,7 @@ class Redis
|
|
1217
1235
|
# @param [String, Array<String>] keys one or more keys to perform the
|
1218
1236
|
# blocking pop on
|
1219
1237
|
# @param [Hash] options
|
1220
|
-
# - `:timeout =>
|
1238
|
+
# - `:timeout => Integer`: timeout in seconds, defaults to no timeout
|
1221
1239
|
#
|
1222
1240
|
# @return [nil, [String, String]]
|
1223
1241
|
# - `nil` when the operation timed out
|
@@ -1234,20 +1252,12 @@ class Redis
|
|
1234
1252
|
# @param [String] source source key
|
1235
1253
|
# @param [String] destination destination key
|
1236
1254
|
# @param [Hash] options
|
1237
|
-
# - `:timeout =>
|
1255
|
+
# - `:timeout => Integer`: timeout in seconds, defaults to no timeout
|
1238
1256
|
#
|
1239
1257
|
# @return [nil, String]
|
1240
1258
|
# - `nil` when the operation timed out
|
1241
1259
|
# - the element was popped and pushed otherwise
|
1242
|
-
def brpoplpush(source, destination,
|
1243
|
-
case options
|
1244
|
-
when Integer
|
1245
|
-
# Issue deprecation notice in obnoxious mode...
|
1246
|
-
options = { :timeout => options }
|
1247
|
-
end
|
1248
|
-
|
1249
|
-
timeout = options[:timeout] || 0
|
1250
|
-
|
1260
|
+
def brpoplpush(source, destination, deprecated_timeout = 0, timeout: deprecated_timeout)
|
1251
1261
|
synchronize do |client|
|
1252
1262
|
command = [:brpoplpush, source, destination, timeout]
|
1253
1263
|
timeout += client.timeout if timeout > 0
|
@@ -1258,7 +1268,7 @@ class Redis
|
|
1258
1268
|
# Get an element from a list by its index.
|
1259
1269
|
#
|
1260
1270
|
# @param [String] key
|
1261
|
-
# @param [
|
1271
|
+
# @param [Integer] index
|
1262
1272
|
# @return [String]
|
1263
1273
|
def lindex(key, index)
|
1264
1274
|
synchronize do |client|
|
@@ -1272,7 +1282,7 @@ class Redis
|
|
1272
1282
|
# @param [String, Symbol] where `BEFORE` or `AFTER`
|
1273
1283
|
# @param [String] pivot reference element
|
1274
1284
|
# @param [String] value
|
1275
|
-
# @return [
|
1285
|
+
# @return [Integer] length of the list after the insert operation, or `-1`
|
1276
1286
|
# when the element `pivot` was not found
|
1277
1287
|
def linsert(key, where, pivot, value)
|
1278
1288
|
synchronize do |client|
|
@@ -1283,8 +1293,8 @@ class Redis
|
|
1283
1293
|
# Get a range of elements from a list.
|
1284
1294
|
#
|
1285
1295
|
# @param [String] key
|
1286
|
-
# @param [
|
1287
|
-
# @param [
|
1296
|
+
# @param [Integer] start start index
|
1297
|
+
# @param [Integer] stop stop index
|
1288
1298
|
# @return [Array<String>]
|
1289
1299
|
def lrange(key, start, stop)
|
1290
1300
|
synchronize do |client|
|
@@ -1295,12 +1305,12 @@ class Redis
|
|
1295
1305
|
# Remove elements from a list.
|
1296
1306
|
#
|
1297
1307
|
# @param [String] key
|
1298
|
-
# @param [
|
1308
|
+
# @param [Integer] count number of elements to remove. Use a positive
|
1299
1309
|
# value to remove the first `count` occurrences of `value`. A negative
|
1300
1310
|
# value to remove the last `count` occurrences of `value`. Or zero, to
|
1301
1311
|
# remove all occurrences of `value` from the list.
|
1302
1312
|
# @param [String] value
|
1303
|
-
# @return [
|
1313
|
+
# @return [Integer] the number of removed elements
|
1304
1314
|
def lrem(key, count, value)
|
1305
1315
|
synchronize do |client|
|
1306
1316
|
client.call([:lrem, key, count, value])
|
@@ -1310,7 +1320,7 @@ class Redis
|
|
1310
1320
|
# Set the value of an element in a list by its index.
|
1311
1321
|
#
|
1312
1322
|
# @param [String] key
|
1313
|
-
# @param [
|
1323
|
+
# @param [Integer] index
|
1314
1324
|
# @param [String] value
|
1315
1325
|
# @return [String] `OK`
|
1316
1326
|
def lset(key, index, value)
|
@@ -1322,8 +1332,8 @@ class Redis
|
|
1322
1332
|
# Trim a list to the specified range.
|
1323
1333
|
#
|
1324
1334
|
# @param [String] key
|
1325
|
-
# @param [
|
1326
|
-
# @param [
|
1335
|
+
# @param [Integer] start start index
|
1336
|
+
# @param [Integer] stop stop index
|
1327
1337
|
# @return [String] `OK`
|
1328
1338
|
def ltrim(key, start, stop)
|
1329
1339
|
synchronize do |client|
|
@@ -1334,7 +1344,7 @@ class Redis
|
|
1334
1344
|
# Get the number of members in a set.
|
1335
1345
|
#
|
1336
1346
|
# @param [String] key
|
1337
|
-
# @return [
|
1347
|
+
# @return [Integer]
|
1338
1348
|
def scard(key)
|
1339
1349
|
synchronize do |client|
|
1340
1350
|
client.call([:scard, key])
|
@@ -1345,8 +1355,8 @@ class Redis
|
|
1345
1355
|
#
|
1346
1356
|
# @param [String] key
|
1347
1357
|
# @param [String, Array<String>] member one member, or array of members
|
1348
|
-
# @return [Boolean,
|
1349
|
-
# holding whether or not adding the member succeeded, or `
|
1358
|
+
# @return [Boolean, Integer] `Boolean` when a single member is specified,
|
1359
|
+
# holding whether or not adding the member succeeded, or `Integer` when an
|
1350
1360
|
# array of members is specified, holding the number of members that were
|
1351
1361
|
# successfully added
|
1352
1362
|
def sadd(key, member)
|
@@ -1367,8 +1377,8 @@ class Redis
|
|
1367
1377
|
#
|
1368
1378
|
# @param [String] key
|
1369
1379
|
# @param [String, Array<String>] member one member, or array of members
|
1370
|
-
# @return [Boolean,
|
1371
|
-
# holding whether or not removing the member succeeded, or `
|
1380
|
+
# @return [Boolean, Integer] `Boolean` when a single member is specified,
|
1381
|
+
# holding whether or not removing the member succeeded, or `Integer` when an
|
1372
1382
|
# array of members is specified, holding the number of members that were
|
1373
1383
|
# successfully removed
|
1374
1384
|
def srem(key, member)
|
@@ -1389,7 +1399,7 @@ class Redis
|
|
1389
1399
|
#
|
1390
1400
|
# @param [String] key
|
1391
1401
|
# @return [String]
|
1392
|
-
# @param [
|
1402
|
+
# @param [Integer] count
|
1393
1403
|
def spop(key, count = nil)
|
1394
1404
|
synchronize do |client|
|
1395
1405
|
if count.nil?
|
@@ -1403,7 +1413,7 @@ class Redis
|
|
1403
1413
|
# Get one or more random members from a set.
|
1404
1414
|
#
|
1405
1415
|
# @param [String] key
|
1406
|
-
# @param [
|
1416
|
+
# @param [Integer] count
|
1407
1417
|
# @return [String]
|
1408
1418
|
def srandmember(key, count = nil)
|
1409
1419
|
synchronize do |client|
|
@@ -1454,7 +1464,7 @@ class Redis
|
|
1454
1464
|
# @return [Array<String>] members in the difference
|
1455
1465
|
def sdiff(*keys)
|
1456
1466
|
synchronize do |client|
|
1457
|
-
client.call([:sdiff
|
1467
|
+
client.call([:sdiff, *keys])
|
1458
1468
|
end
|
1459
1469
|
end
|
1460
1470
|
|
@@ -1462,10 +1472,10 @@ class Redis
|
|
1462
1472
|
#
|
1463
1473
|
# @param [String] destination destination key
|
1464
1474
|
# @param [String, Array<String>] keys keys pointing to sets to subtract
|
1465
|
-
# @return [
|
1475
|
+
# @return [Integer] number of elements in the resulting set
|
1466
1476
|
def sdiffstore(destination, *keys)
|
1467
1477
|
synchronize do |client|
|
1468
|
-
client.call([:sdiffstore, destination
|
1478
|
+
client.call([:sdiffstore, destination, *keys])
|
1469
1479
|
end
|
1470
1480
|
end
|
1471
1481
|
|
@@ -1475,7 +1485,7 @@ class Redis
|
|
1475
1485
|
# @return [Array<String>] members in the intersection
|
1476
1486
|
def sinter(*keys)
|
1477
1487
|
synchronize do |client|
|
1478
|
-
client.call([:sinter
|
1488
|
+
client.call([:sinter, *keys])
|
1479
1489
|
end
|
1480
1490
|
end
|
1481
1491
|
|
@@ -1483,10 +1493,10 @@ class Redis
|
|
1483
1493
|
#
|
1484
1494
|
# @param [String] destination destination key
|
1485
1495
|
# @param [String, Array<String>] keys keys pointing to sets to intersect
|
1486
|
-
# @return [
|
1496
|
+
# @return [Integer] number of elements in the resulting set
|
1487
1497
|
def sinterstore(destination, *keys)
|
1488
1498
|
synchronize do |client|
|
1489
|
-
client.call([:sinterstore, destination
|
1499
|
+
client.call([:sinterstore, destination, *keys])
|
1490
1500
|
end
|
1491
1501
|
end
|
1492
1502
|
|
@@ -1496,7 +1506,7 @@ class Redis
|
|
1496
1506
|
# @return [Array<String>] members in the union
|
1497
1507
|
def sunion(*keys)
|
1498
1508
|
synchronize do |client|
|
1499
|
-
client.call([:sunion
|
1509
|
+
client.call([:sunion, *keys])
|
1500
1510
|
end
|
1501
1511
|
end
|
1502
1512
|
|
@@ -1504,10 +1514,10 @@ class Redis
|
|
1504
1514
|
#
|
1505
1515
|
# @param [String] destination destination key
|
1506
1516
|
# @param [String, Array<String>] keys keys pointing to sets to unify
|
1507
|
-
# @return [
|
1517
|
+
# @return [Integer] number of elements in the resulting set
|
1508
1518
|
def sunionstore(destination, *keys)
|
1509
1519
|
synchronize do |client|
|
1510
|
-
client.call([:sunionstore, destination
|
1520
|
+
client.call([:sunionstore, destination, *keys])
|
1511
1521
|
end
|
1512
1522
|
end
|
1513
1523
|
|
@@ -1518,7 +1528,7 @@ class Redis
|
|
1518
1528
|
# # => 4
|
1519
1529
|
#
|
1520
1530
|
# @param [String] key
|
1521
|
-
# @return [
|
1531
|
+
# @return [Integer]
|
1522
1532
|
def zcard(key)
|
1523
1533
|
synchronize do |client|
|
1524
1534
|
client.call([:zcard, key])
|
@@ -1549,38 +1559,27 @@ class Redis
|
|
1549
1559
|
# - `:incr => true`: When this option is specified ZADD acts like
|
1550
1560
|
# ZINCRBY; only one score-element pair can be specified in this mode
|
1551
1561
|
#
|
1552
|
-
# @return [Boolean,
|
1562
|
+
# @return [Boolean, Integer, Float]
|
1553
1563
|
# - `Boolean` when a single pair is specified, holding whether or not it was
|
1554
1564
|
# **added** to the sorted set.
|
1555
|
-
# - `
|
1565
|
+
# - `Integer` when an array of pairs is specified, holding the number of
|
1556
1566
|
# pairs that were **added** to the sorted set.
|
1557
1567
|
# - `Float` when option :incr is specified, holding the score of the member
|
1558
1568
|
# after incrementing it.
|
1559
|
-
def zadd(key, *args
|
1560
|
-
|
1561
|
-
if
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
zadd_options << "NX" if nx
|
1566
|
-
|
1567
|
-
xx = options[:xx]
|
1568
|
-
zadd_options << "XX" if xx
|
1569
|
-
|
1570
|
-
ch = options[:ch]
|
1571
|
-
zadd_options << "CH" if ch
|
1572
|
-
|
1573
|
-
incr = options[:incr]
|
1574
|
-
zadd_options << "INCR" if incr
|
1575
|
-
end
|
1569
|
+
def zadd(key, *args, nx: nil, xx: nil, ch: nil, incr: nil)
|
1570
|
+
command = [:zadd, key]
|
1571
|
+
command << "NX" if nx
|
1572
|
+
command << "XX" if xx
|
1573
|
+
command << "CH" if ch
|
1574
|
+
command << "INCR" if incr
|
1576
1575
|
|
1577
1576
|
synchronize do |client|
|
1578
1577
|
if args.size == 1 && args[0].is_a?(Array)
|
1579
1578
|
# Variadic: return float if INCR, integer if !INCR
|
1580
|
-
client.call(
|
1579
|
+
client.call(command + args[0], &(incr ? Floatify : nil))
|
1581
1580
|
elsif args.size == 2
|
1582
1581
|
# Single pair: return float if INCR, boolean if !INCR
|
1583
|
-
client.call(
|
1582
|
+
client.call(command + args, &(incr ? Floatify : Boolify))
|
1584
1583
|
else
|
1585
1584
|
raise ArgumentError, "wrong number of arguments"
|
1586
1585
|
end
|
@@ -1615,10 +1614,10 @@ class Redis
|
|
1615
1614
|
# - a single member
|
1616
1615
|
# - an array of members
|
1617
1616
|
#
|
1618
|
-
# @return [Boolean,
|
1617
|
+
# @return [Boolean, Integer]
|
1619
1618
|
# - `Boolean` when a single member is specified, holding whether or not it
|
1620
1619
|
# was removed from the sorted set
|
1621
|
-
# - `
|
1620
|
+
# - `Integer` when an array of pairs is specified, holding the number of
|
1622
1621
|
# members that were removed to the sorted set
|
1623
1622
|
def zrem(key, member)
|
1624
1623
|
synchronize do |client|
|
@@ -1743,18 +1742,16 @@ class Redis
|
|
1743
1742
|
# # => [["a", 32.0], ["b", 64.0]]
|
1744
1743
|
#
|
1745
1744
|
# @param [String] key
|
1746
|
-
# @param [
|
1747
|
-
# @param [
|
1745
|
+
# @param [Integer] start start index
|
1746
|
+
# @param [Integer] stop stop index
|
1748
1747
|
# @param [Hash] options
|
1749
1748
|
# - `:with_scores => true`: include scores in output
|
1750
1749
|
#
|
1751
1750
|
# @return [Array<String>, Array<[String, Float]>]
|
1752
1751
|
# - when `:with_scores` is not specified, an array of members
|
1753
1752
|
# - when `:with_scores` is specified, an array with `[member, score]` pairs
|
1754
|
-
def zrange(key, start, stop,
|
1755
|
-
args = []
|
1756
|
-
|
1757
|
-
with_scores = options[:with_scores] || options[:withscores]
|
1753
|
+
def zrange(key, start, stop, withscores: false, with_scores: withscores)
|
1754
|
+
args = [:zrange, key, start, stop]
|
1758
1755
|
|
1759
1756
|
if with_scores
|
1760
1757
|
args << "WITHSCORES"
|
@@ -1762,7 +1759,7 @@ class Redis
|
|
1762
1759
|
end
|
1763
1760
|
|
1764
1761
|
synchronize do |client|
|
1765
|
-
client.call(
|
1762
|
+
client.call(args, &block)
|
1766
1763
|
end
|
1767
1764
|
end
|
1768
1765
|
|
@@ -1777,10 +1774,8 @@ class Redis
|
|
1777
1774
|
# # => [["b", 64.0], ["a", 32.0]]
|
1778
1775
|
#
|
1779
1776
|
# @see #zrange
|
1780
|
-
def zrevrange(key, start, stop,
|
1781
|
-
args = []
|
1782
|
-
|
1783
|
-
with_scores = options[:with_scores] || options[:withscores]
|
1777
|
+
def zrevrange(key, start, stop, withscores: false, with_scores: withscores)
|
1778
|
+
args = [:zrevrange, key, start, stop]
|
1784
1779
|
|
1785
1780
|
if with_scores
|
1786
1781
|
args << "WITHSCORES"
|
@@ -1788,7 +1783,7 @@ class Redis
|
|
1788
1783
|
end
|
1789
1784
|
|
1790
1785
|
synchronize do |client|
|
1791
|
-
client.call(
|
1786
|
+
client.call(args, &block)
|
1792
1787
|
end
|
1793
1788
|
end
|
1794
1789
|
|
@@ -1796,7 +1791,7 @@ class Redis
|
|
1796
1791
|
#
|
1797
1792
|
# @param [String] key
|
1798
1793
|
# @param [String] member
|
1799
|
-
# @return [
|
1794
|
+
# @return [Integer]
|
1800
1795
|
def zrank(key, member)
|
1801
1796
|
synchronize do |client|
|
1802
1797
|
client.call([:zrank, key, member])
|
@@ -1808,7 +1803,7 @@ class Redis
|
|
1808
1803
|
#
|
1809
1804
|
# @param [String] key
|
1810
1805
|
# @param [String] member
|
1811
|
-
# @return [
|
1806
|
+
# @return [Integer]
|
1812
1807
|
def zrevrank(key, member)
|
1813
1808
|
synchronize do |client|
|
1814
1809
|
client.call([:zrevrank, key, member])
|
@@ -1825,9 +1820,9 @@ class Redis
|
|
1825
1820
|
# # => 5
|
1826
1821
|
#
|
1827
1822
|
# @param [String] key
|
1828
|
-
# @param [
|
1829
|
-
# @param [
|
1830
|
-
# @return [
|
1823
|
+
# @param [Integer] start start index
|
1824
|
+
# @param [Integer] stop stop index
|
1825
|
+
# @return [Integer] number of members that were removed
|
1831
1826
|
def zremrangebyrank(key, start, stop)
|
1832
1827
|
synchronize do |client|
|
1833
1828
|
client.call([:zremrangebyrank, key, start, stop])
|
@@ -1851,7 +1846,7 @@ class Redis
|
|
1851
1846
|
# - inclusive maximum is specified by prefixing `(`
|
1852
1847
|
# - exclusive maximum is specified by prefixing `[`
|
1853
1848
|
#
|
1854
|
-
# @return [
|
1849
|
+
# @return [Integer] number of members within the specified lexicographical range
|
1855
1850
|
def zlexcount(key, min, max)
|
1856
1851
|
synchronize do |client|
|
1857
1852
|
client.call([:zlexcount, key, min, max])
|
@@ -1879,14 +1874,16 @@ class Redis
|
|
1879
1874
|
# `count` members
|
1880
1875
|
#
|
1881
1876
|
# @return [Array<String>, Array<[String, Float]>]
|
1882
|
-
def zrangebylex(key, min, max,
|
1883
|
-
args = []
|
1877
|
+
def zrangebylex(key, min, max, limit: nil)
|
1878
|
+
args = [:zrangebylex, key, min, max]
|
1884
1879
|
|
1885
|
-
|
1886
|
-
|
1880
|
+
if limit
|
1881
|
+
args << "LIMIT"
|
1882
|
+
args.concat(limit)
|
1883
|
+
end
|
1887
1884
|
|
1888
1885
|
synchronize do |client|
|
1889
|
-
client.call(
|
1886
|
+
client.call(args)
|
1890
1887
|
end
|
1891
1888
|
end
|
1892
1889
|
|
@@ -1901,14 +1898,16 @@ class Redis
|
|
1901
1898
|
# # => ["abbygail", "abby"]
|
1902
1899
|
#
|
1903
1900
|
# @see #zrangebylex
|
1904
|
-
def zrevrangebylex(key, max, min,
|
1905
|
-
args = []
|
1901
|
+
def zrevrangebylex(key, max, min, limit: nil)
|
1902
|
+
args = [:zrevrangebylex, key, max, min]
|
1906
1903
|
|
1907
|
-
|
1908
|
-
|
1904
|
+
if limit
|
1905
|
+
args << "LIMIT"
|
1906
|
+
args.concat(limit)
|
1907
|
+
end
|
1909
1908
|
|
1910
1909
|
synchronize do |client|
|
1911
|
-
client.call(
|
1910
|
+
client.call(args)
|
1912
1911
|
end
|
1913
1912
|
end
|
1914
1913
|
|
@@ -1939,21 +1938,21 @@ class Redis
|
|
1939
1938
|
# @return [Array<String>, Array<[String, Float]>]
|
1940
1939
|
# - when `:with_scores` is not specified, an array of members
|
1941
1940
|
# - when `:with_scores` is specified, an array with `[member, score]` pairs
|
1942
|
-
def zrangebyscore(key, min, max,
|
1943
|
-
args = []
|
1944
|
-
|
1945
|
-
with_scores = options[:with_scores] || options[:withscores]
|
1941
|
+
def zrangebyscore(key, min, max, withscores: false, with_scores: withscores, limit: nil)
|
1942
|
+
args = [:zrangebyscore, key, min, max]
|
1946
1943
|
|
1947
1944
|
if with_scores
|
1948
1945
|
args << "WITHSCORES"
|
1949
1946
|
block = FloatifyPairs
|
1950
1947
|
end
|
1951
1948
|
|
1952
|
-
|
1953
|
-
|
1949
|
+
if limit
|
1950
|
+
args << "LIMIT"
|
1951
|
+
args.concat(limit)
|
1952
|
+
end
|
1954
1953
|
|
1955
1954
|
synchronize do |client|
|
1956
|
-
client.call(
|
1955
|
+
client.call(args, &block)
|
1957
1956
|
end
|
1958
1957
|
end
|
1959
1958
|
|
@@ -1971,21 +1970,21 @@ class Redis
|
|
1971
1970
|
# # => [["b", 64.0], ["a", 32.0]]
|
1972
1971
|
#
|
1973
1972
|
# @see #zrangebyscore
|
1974
|
-
def zrevrangebyscore(key, max, min,
|
1975
|
-
args = []
|
1976
|
-
|
1977
|
-
with_scores = options[:with_scores] || options[:withscores]
|
1973
|
+
def zrevrangebyscore(key, max, min, withscores: false, with_scores: withscores, limit: nil)
|
1974
|
+
args = [:zrevrangebyscore, key, max, min]
|
1978
1975
|
|
1979
1976
|
if with_scores
|
1980
|
-
args <<
|
1977
|
+
args << "WITHSCORES"
|
1981
1978
|
block = FloatifyPairs
|
1982
1979
|
end
|
1983
1980
|
|
1984
|
-
|
1985
|
-
|
1981
|
+
if limit
|
1982
|
+
args << "LIMIT"
|
1983
|
+
args.concat(limit)
|
1984
|
+
end
|
1986
1985
|
|
1987
1986
|
synchronize do |client|
|
1988
|
-
client.call(
|
1987
|
+
client.call(args, &block)
|
1989
1988
|
end
|
1990
1989
|
end
|
1991
1990
|
|
@@ -2005,7 +2004,7 @@ class Redis
|
|
2005
2004
|
# @param [String] max
|
2006
2005
|
# - inclusive maximum score is specified verbatim
|
2007
2006
|
# - exclusive maximum score is specified by prefixing `(`
|
2008
|
-
# @return [
|
2007
|
+
# @return [Integer] number of members that were removed
|
2009
2008
|
def zremrangebyscore(key, min, max)
|
2010
2009
|
synchronize do |client|
|
2011
2010
|
client.call([:zremrangebyscore, key, min, max])
|
@@ -2028,7 +2027,7 @@ class Redis
|
|
2028
2027
|
# @param [String] max
|
2029
2028
|
# - inclusive maximum score is specified verbatim
|
2030
2029
|
# - exclusive maximum score is specified by prefixing `(`
|
2031
|
-
# @return [
|
2030
|
+
# @return [Integer] number of members in within the specified range
|
2032
2031
|
def zcount(key, min, max)
|
2033
2032
|
synchronize do |client|
|
2034
2033
|
client.call([:zcount, key, min, max])
|
@@ -2048,18 +2047,19 @@ class Redis
|
|
2048
2047
|
# - `:weights => [Float, Float, ...]`: weights to associate with source
|
2049
2048
|
# sorted sets
|
2050
2049
|
# - `:aggregate => String`: aggregate function to use (sum, min, max, ...)
|
2051
|
-
# @return [
|
2052
|
-
def zinterstore(destination, keys,
|
2053
|
-
args = []
|
2050
|
+
# @return [Integer] number of elements in the resulting sorted set
|
2051
|
+
def zinterstore(destination, keys, weights: nil, aggregate: nil)
|
2052
|
+
args = [:zinterstore, destination, keys.size, *keys]
|
2054
2053
|
|
2055
|
-
|
2056
|
-
|
2054
|
+
if weights
|
2055
|
+
args << "WEIGHTS"
|
2056
|
+
args.concat(weights)
|
2057
|
+
end
|
2057
2058
|
|
2058
|
-
aggregate
|
2059
|
-
args.concat(["AGGREGATE", aggregate]) if aggregate
|
2059
|
+
args << "AGGREGATE" << aggregate if aggregate
|
2060
2060
|
|
2061
2061
|
synchronize do |client|
|
2062
|
-
client.call(
|
2062
|
+
client.call(args)
|
2063
2063
|
end
|
2064
2064
|
end
|
2065
2065
|
|
@@ -2075,40 +2075,46 @@ class Redis
|
|
2075
2075
|
# - `:weights => [Float, Float, ...]`: weights to associate with source
|
2076
2076
|
# sorted sets
|
2077
2077
|
# - `:aggregate => String`: aggregate function to use (sum, min, max, ...)
|
2078
|
-
# @return [
|
2079
|
-
def zunionstore(destination, keys,
|
2080
|
-
args = []
|
2078
|
+
# @return [Integer] number of elements in the resulting sorted set
|
2079
|
+
def zunionstore(destination, keys, weights: nil, aggregate: nil)
|
2080
|
+
args = [:zunionstore, destination, keys.size, *keys]
|
2081
2081
|
|
2082
|
-
|
2083
|
-
|
2082
|
+
if weights
|
2083
|
+
args << "WEIGHTS"
|
2084
|
+
args.concat(weights)
|
2085
|
+
end
|
2084
2086
|
|
2085
|
-
aggregate
|
2086
|
-
args.concat(["AGGREGATE", aggregate]) if aggregate
|
2087
|
+
args << "AGGREGATE" << aggregate if aggregate
|
2087
2088
|
|
2088
2089
|
synchronize do |client|
|
2089
|
-
client.call(
|
2090
|
+
client.call(args)
|
2090
2091
|
end
|
2091
2092
|
end
|
2092
2093
|
|
2093
2094
|
# Get the number of fields in a hash.
|
2094
2095
|
#
|
2095
2096
|
# @param [String] key
|
2096
|
-
# @return [
|
2097
|
+
# @return [Integer] number of fields in the hash
|
2097
2098
|
def hlen(key)
|
2098
2099
|
synchronize do |client|
|
2099
2100
|
client.call([:hlen, key])
|
2100
2101
|
end
|
2101
2102
|
end
|
2102
2103
|
|
2103
|
-
# Set
|
2104
|
+
# Set one or more hash values.
|
2105
|
+
#
|
2106
|
+
# @example
|
2107
|
+
# redis.hset("hash", "f1", "v1", "f2", "v2") # => 2
|
2108
|
+
# redis.hset("hash", { "f1" => "v1", "f2" => "v2" }) # => 2
|
2104
2109
|
#
|
2105
2110
|
# @param [String] key
|
2106
|
-
# @param [String]
|
2107
|
-
# @
|
2108
|
-
|
2109
|
-
|
2111
|
+
# @param [Array<String> | Hash<String, String>] attrs array or hash of fields and values
|
2112
|
+
# @return [Integer] The number of fields that were added to the hash
|
2113
|
+
def hset(key, *attrs)
|
2114
|
+
attrs = attrs.first.flatten if attrs.size == 1 && attrs.first.is_a?(Hash)
|
2115
|
+
|
2110
2116
|
synchronize do |client|
|
2111
|
-
client.call([:hset, key,
|
2117
|
+
client.call([:hset, key, *attrs])
|
2112
2118
|
end
|
2113
2119
|
end
|
2114
2120
|
|
@@ -2197,7 +2203,7 @@ class Redis
|
|
2197
2203
|
# @see #hmget
|
2198
2204
|
def mapped_hmget(key, *fields)
|
2199
2205
|
hmget(key, *fields) do |reply|
|
2200
|
-
if reply.
|
2206
|
+
if reply.is_a?(Array)
|
2201
2207
|
Hash[fields.zip(reply)]
|
2202
2208
|
else
|
2203
2209
|
reply
|
@@ -2209,7 +2215,7 @@ class Redis
|
|
2209
2215
|
#
|
2210
2216
|
# @param [String] key
|
2211
2217
|
# @param [String, Array<String>] field
|
2212
|
-
# @return [
|
2218
|
+
# @return [Integer] the number of fields that were removed from the hash
|
2213
2219
|
def hdel(key, *fields)
|
2214
2220
|
synchronize do |client|
|
2215
2221
|
client.call([:hdel, key, *fields])
|
@@ -2231,8 +2237,8 @@ class Redis
|
|
2231
2237
|
#
|
2232
2238
|
# @param [String] key
|
2233
2239
|
# @param [String] field
|
2234
|
-
# @param [
|
2235
|
-
# @return [
|
2240
|
+
# @param [Integer] increment
|
2241
|
+
# @return [Integer] value of the field after incrementing it
|
2236
2242
|
def hincrby(key, field, increment)
|
2237
2243
|
synchronize do |client|
|
2238
2244
|
client.call([:hincrby, key, field, increment])
|
@@ -2290,20 +2296,21 @@ class Redis
|
|
2290
2296
|
|
2291
2297
|
def subscribed?
|
2292
2298
|
synchronize do |client|
|
2293
|
-
client.
|
2299
|
+
client.is_a? SubscribedClient
|
2294
2300
|
end
|
2295
2301
|
end
|
2296
2302
|
|
2297
2303
|
# Listen for messages published to the given channels.
|
2298
2304
|
def subscribe(*channels, &block)
|
2299
|
-
synchronize do |
|
2305
|
+
synchronize do |_client|
|
2300
2306
|
_subscription(:subscribe, 0, channels, block)
|
2301
2307
|
end
|
2302
2308
|
end
|
2303
2309
|
|
2304
|
-
# Listen for messages published to the given channels. Throw a timeout error
|
2310
|
+
# Listen for messages published to the given channels. Throw a timeout error
|
2311
|
+
# if there is no messages for a timeout period.
|
2305
2312
|
def subscribe_with_timeout(timeout, *channels, &block)
|
2306
|
-
synchronize do |
|
2313
|
+
synchronize do |_client|
|
2307
2314
|
_subscription(:subscribe_with_timeout, timeout, channels, block)
|
2308
2315
|
end
|
2309
2316
|
end
|
@@ -2311,21 +2318,23 @@ class Redis
|
|
2311
2318
|
# Stop listening for messages posted to the given channels.
|
2312
2319
|
def unsubscribe(*channels)
|
2313
2320
|
synchronize do |client|
|
2314
|
-
raise
|
2321
|
+
raise "Can't unsubscribe if not subscribed." unless subscribed?
|
2322
|
+
|
2315
2323
|
client.unsubscribe(*channels)
|
2316
2324
|
end
|
2317
2325
|
end
|
2318
2326
|
|
2319
2327
|
# Listen for messages published to channels matching the given patterns.
|
2320
2328
|
def psubscribe(*channels, &block)
|
2321
|
-
synchronize do |
|
2329
|
+
synchronize do |_client|
|
2322
2330
|
_subscription(:psubscribe, 0, channels, block)
|
2323
2331
|
end
|
2324
2332
|
end
|
2325
2333
|
|
2326
|
-
# Listen for messages published to channels matching the given patterns.
|
2334
|
+
# Listen for messages published to channels matching the given patterns.
|
2335
|
+
# Throw a timeout error if there is no messages for a timeout period.
|
2327
2336
|
def psubscribe_with_timeout(timeout, *channels, &block)
|
2328
|
-
synchronize do |
|
2337
|
+
synchronize do |_client|
|
2329
2338
|
_subscription(:psubscribe_with_timeout, timeout, channels, block)
|
2330
2339
|
end
|
2331
2340
|
end
|
@@ -2333,7 +2342,8 @@ class Redis
|
|
2333
2342
|
# Stop listening for messages posted to channels matching the given patterns.
|
2334
2343
|
def punsubscribe(*channels)
|
2335
2344
|
synchronize do |client|
|
2336
|
-
raise
|
2345
|
+
raise "Can't unsubscribe if not subscribed." unless subscribed?
|
2346
|
+
|
2337
2347
|
client.punsubscribe(*channels)
|
2338
2348
|
end
|
2339
2349
|
end
|
@@ -2378,7 +2388,7 @@ class Redis
|
|
2378
2388
|
# @see #multi
|
2379
2389
|
def watch(*keys)
|
2380
2390
|
synchronize do |client|
|
2381
|
-
res = client.call([:watch
|
2391
|
+
res = client.call([:watch, *keys])
|
2382
2392
|
|
2383
2393
|
if block_given?
|
2384
2394
|
begin
|
@@ -2408,7 +2418,7 @@ class Redis
|
|
2408
2418
|
end
|
2409
2419
|
|
2410
2420
|
def pipelined
|
2411
|
-
synchronize do |
|
2421
|
+
synchronize do |_client|
|
2412
2422
|
begin
|
2413
2423
|
pipeline = Pipeline.new(@client)
|
2414
2424
|
original, @client = @client, pipeline
|
@@ -2608,18 +2618,12 @@ class Redis
|
|
2608
2618
|
_eval(:evalsha, args)
|
2609
2619
|
end
|
2610
2620
|
|
2611
|
-
def _scan(command, cursor, args,
|
2621
|
+
def _scan(command, cursor, args, match: nil, count: nil, &block)
|
2612
2622
|
# SSCAN/ZSCAN/HSCAN already prepend the key to +args+.
|
2613
2623
|
|
2614
2624
|
args << cursor
|
2615
|
-
|
2616
|
-
|
2617
|
-
args.concat(["MATCH", match])
|
2618
|
-
end
|
2619
|
-
|
2620
|
-
if count = options[:count]
|
2621
|
-
args.concat(["COUNT", count])
|
2622
|
-
end
|
2625
|
+
args << "MATCH" << match if match
|
2626
|
+
args << "COUNT" << count if count
|
2623
2627
|
|
2624
2628
|
synchronize do |client|
|
2625
2629
|
client.call([command] + args, &block)
|
@@ -2641,8 +2645,8 @@ class Redis
|
|
2641
2645
|
# - `:count => Integer`: return count keys at most per iteration
|
2642
2646
|
#
|
2643
2647
|
# @return [String, Array<String>] the next cursor and all found keys
|
2644
|
-
def scan(cursor, options
|
2645
|
-
_scan(:scan, cursor, [], options)
|
2648
|
+
def scan(cursor, **options)
|
2649
|
+
_scan(:scan, cursor, [], **options)
|
2646
2650
|
end
|
2647
2651
|
|
2648
2652
|
# Scan the keyspace
|
@@ -2660,11 +2664,12 @@ class Redis
|
|
2660
2664
|
# - `:count => Integer`: return count keys at most per iteration
|
2661
2665
|
#
|
2662
2666
|
# @return [Enumerator] an enumerator for all found keys
|
2663
|
-
def scan_each(options
|
2664
|
-
return to_enum(:scan_each, options) unless block_given?
|
2667
|
+
def scan_each(**options, &block)
|
2668
|
+
return to_enum(:scan_each, **options) unless block_given?
|
2669
|
+
|
2665
2670
|
cursor = 0
|
2666
2671
|
loop do
|
2667
|
-
cursor, keys = scan(cursor, options)
|
2672
|
+
cursor, keys = scan(cursor, **options)
|
2668
2673
|
keys.each(&block)
|
2669
2674
|
break if cursor == "0"
|
2670
2675
|
end
|
@@ -2681,8 +2686,8 @@ class Redis
|
|
2681
2686
|
# - `:count => Integer`: return count keys at most per iteration
|
2682
2687
|
#
|
2683
2688
|
# @return [String, Array<[String, String]>] the next cursor and all found keys
|
2684
|
-
def hscan(key, cursor, options
|
2685
|
-
_scan(:hscan, cursor, [key], options) do |reply|
|
2689
|
+
def hscan(key, cursor, **options)
|
2690
|
+
_scan(:hscan, cursor, [key], **options) do |reply|
|
2686
2691
|
[reply[0], reply[1].each_slice(2).to_a]
|
2687
2692
|
end
|
2688
2693
|
end
|
@@ -2698,11 +2703,12 @@ class Redis
|
|
2698
2703
|
# - `:count => Integer`: return count keys at most per iteration
|
2699
2704
|
#
|
2700
2705
|
# @return [Enumerator] an enumerator for all found keys
|
2701
|
-
def hscan_each(key, options
|
2702
|
-
return to_enum(:hscan_each, key, options) unless block_given?
|
2706
|
+
def hscan_each(key, **options, &block)
|
2707
|
+
return to_enum(:hscan_each, key, **options) unless block_given?
|
2708
|
+
|
2703
2709
|
cursor = 0
|
2704
2710
|
loop do
|
2705
|
-
cursor, values = hscan(key, cursor, options)
|
2711
|
+
cursor, values = hscan(key, cursor, **options)
|
2706
2712
|
values.each(&block)
|
2707
2713
|
break if cursor == "0"
|
2708
2714
|
end
|
@@ -2720,8 +2726,8 @@ class Redis
|
|
2720
2726
|
#
|
2721
2727
|
# @return [String, Array<[String, Float]>] the next cursor and all found
|
2722
2728
|
# members and scores
|
2723
|
-
def zscan(key, cursor, options
|
2724
|
-
_scan(:zscan, cursor, [key], options) do |reply|
|
2729
|
+
def zscan(key, cursor, **options)
|
2730
|
+
_scan(:zscan, cursor, [key], **options) do |reply|
|
2725
2731
|
[reply[0], FloatifyPairs.call(reply[1])]
|
2726
2732
|
end
|
2727
2733
|
end
|
@@ -2737,11 +2743,12 @@ class Redis
|
|
2737
2743
|
# - `:count => Integer`: return count keys at most per iteration
|
2738
2744
|
#
|
2739
2745
|
# @return [Enumerator] an enumerator for all found scores and members
|
2740
|
-
def zscan_each(key, options
|
2741
|
-
return to_enum(:zscan_each, key, options) unless block_given?
|
2746
|
+
def zscan_each(key, **options, &block)
|
2747
|
+
return to_enum(:zscan_each, key, **options) unless block_given?
|
2748
|
+
|
2742
2749
|
cursor = 0
|
2743
2750
|
loop do
|
2744
|
-
cursor, values = zscan(key, cursor, options)
|
2751
|
+
cursor, values = zscan(key, cursor, **options)
|
2745
2752
|
values.each(&block)
|
2746
2753
|
break if cursor == "0"
|
2747
2754
|
end
|
@@ -2758,8 +2765,8 @@ class Redis
|
|
2758
2765
|
# - `:count => Integer`: return count keys at most per iteration
|
2759
2766
|
#
|
2760
2767
|
# @return [String, Array<String>] the next cursor and all found members
|
2761
|
-
def sscan(key, cursor, options
|
2762
|
-
_scan(:sscan, cursor, [key], options)
|
2768
|
+
def sscan(key, cursor, **options)
|
2769
|
+
_scan(:sscan, cursor, [key], **options)
|
2763
2770
|
end
|
2764
2771
|
|
2765
2772
|
# Scan a set
|
@@ -2773,11 +2780,12 @@ class Redis
|
|
2773
2780
|
# - `:count => Integer`: return count keys at most per iteration
|
2774
2781
|
#
|
2775
2782
|
# @return [Enumerator] an enumerator for all keys in the set
|
2776
|
-
def sscan_each(key, options
|
2777
|
-
return to_enum(:sscan_each, key, options) unless block_given?
|
2783
|
+
def sscan_each(key, **options, &block)
|
2784
|
+
return to_enum(:sscan_each, key, **options) unless block_given?
|
2785
|
+
|
2778
2786
|
cursor = 0
|
2779
2787
|
loop do
|
2780
|
-
cursor, keys = sscan(key, cursor, options)
|
2788
|
+
cursor, keys = sscan(key, cursor, **options)
|
2781
2789
|
keys.each(&block)
|
2782
2790
|
break if cursor == "0"
|
2783
2791
|
end
|
@@ -2800,7 +2808,7 @@ class Redis
|
|
2800
2808
|
# union of the HyperLogLogs contained in the keys.
|
2801
2809
|
#
|
2802
2810
|
# @param [String, Array<String>] keys
|
2803
|
-
# @return [
|
2811
|
+
# @return [Integer]
|
2804
2812
|
def pfcount(*keys)
|
2805
2813
|
synchronize do |client|
|
2806
2814
|
client.call([:pfcount] + keys)
|
@@ -2841,12 +2849,12 @@ class Redis
|
|
2841
2849
|
end
|
2842
2850
|
end
|
2843
2851
|
|
2844
|
-
|
2845
2852
|
# Query a sorted set representing a geospatial index to fetch members matching a
|
2846
2853
|
# given maximum distance from a point
|
2847
2854
|
#
|
2848
2855
|
# @param [Array] args key, longitude, latitude, radius, unit(m|km|ft|mi)
|
2849
|
-
# @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest
|
2856
|
+
# @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest
|
2857
|
+
# or the farthest to the nearest relative to the center
|
2850
2858
|
# @param [Integer] count limit the results to the first N matching items
|
2851
2859
|
# @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information
|
2852
2860
|
# @return [Array<String>] may be changed with `options`
|
@@ -2863,7 +2871,8 @@ class Redis
|
|
2863
2871
|
# given maximum distance from an already existing member
|
2864
2872
|
#
|
2865
2873
|
# @param [Array] args key, member, radius, unit(m|km|ft|mi)
|
2866
|
-
# @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest
|
2874
|
+
# @param ['asc', 'desc'] sort sort returned items from the nearest to the farthest or the farthest
|
2875
|
+
# to the nearest relative to the center
|
2867
2876
|
# @param [Integer] count limit the results to the first N matching items
|
2868
2877
|
# @param ['WITHDIST', 'WITHCOORD', 'WITHHASH'] options to return additional information
|
2869
2878
|
# @return [Array<String>] may be changed with `options`
|
@@ -2880,7 +2889,8 @@ class Redis
|
|
2880
2889
|
#
|
2881
2890
|
# @param [String] key
|
2882
2891
|
# @param [String, Array<String>] member one member or array of members
|
2883
|
-
# @return [Array<Array<String>, nil>] returns array of elements, where each
|
2892
|
+
# @return [Array<Array<String>, nil>] returns array of elements, where each
|
2893
|
+
# element is either array of longitude and latitude or nil
|
2884
2894
|
def geopos(key, member)
|
2885
2895
|
synchronize do |client|
|
2886
2896
|
client.call([:geopos, key, member])
|
@@ -2944,10 +2954,14 @@ class Redis
|
|
2944
2954
|
# @option opts [Boolean] :approximate whether to add `~` modifier of maxlen or not
|
2945
2955
|
#
|
2946
2956
|
# @return [String] the entry id
|
2947
|
-
def xadd(key, entry,
|
2957
|
+
def xadd(key, entry, approximate: nil, maxlen: nil, id: '*')
|
2948
2958
|
args = [:xadd, key]
|
2949
|
-
|
2950
|
-
|
2959
|
+
if maxlen
|
2960
|
+
args << "MAXLEN"
|
2961
|
+
args << "~" if approximate
|
2962
|
+
args << maxlen
|
2963
|
+
end
|
2964
|
+
args << id
|
2951
2965
|
args.concat(entry.to_a.flatten)
|
2952
2966
|
synchronize { |client| client.call(args) }
|
2953
2967
|
end
|
@@ -3002,8 +3016,8 @@ class Redis
|
|
3002
3016
|
# @param count [Integer] the number of entries as limit
|
3003
3017
|
#
|
3004
3018
|
# @return [Array<Array<String, Hash>>] the ids and entries pairs
|
3005
|
-
def xrange(key, start = '-',
|
3006
|
-
args = [:xrange, key, start,
|
3019
|
+
def xrange(key, start = '-', range_end = '+', count: nil)
|
3020
|
+
args = [:xrange, key, start, range_end]
|
3007
3021
|
args.concat(['COUNT', count]) if count
|
3008
3022
|
synchronize { |client| client.call(args, &HashifyStreamEntries) }
|
3009
3023
|
end
|
@@ -3025,8 +3039,8 @@ class Redis
|
|
3025
3039
|
# @params count [Integer] the number of entries as limit
|
3026
3040
|
#
|
3027
3041
|
# @return [Array<Array<String, Hash>>] the ids and entries pairs
|
3028
|
-
def xrevrange(key,
|
3029
|
-
args = [:xrevrange, key,
|
3042
|
+
def xrevrange(key, range_end = '+', start = '-', count: nil)
|
3043
|
+
args = [:xrevrange, key, range_end, start]
|
3030
3044
|
args.concat(['COUNT', count]) if count
|
3031
3045
|
synchronize { |client| client.call(args, &HashifyStreamEntries) }
|
3032
3046
|
end
|
@@ -3118,12 +3132,12 @@ class Redis
|
|
3118
3132
|
# @option opts [Boolean] :noack whether message loss is acceptable or not
|
3119
3133
|
#
|
3120
3134
|
# @return [Hash{String => Hash{String => Hash}}] the entries
|
3121
|
-
def xreadgroup(group, consumer, keys, ids,
|
3135
|
+
def xreadgroup(group, consumer, keys, ids, count: nil, block: nil, noack: nil)
|
3122
3136
|
args = [:xreadgroup, 'GROUP', group, consumer]
|
3123
|
-
args << 'COUNT' <<
|
3124
|
-
args << 'BLOCK' <<
|
3125
|
-
args << 'NOACK' if
|
3126
|
-
_xread(args, keys, ids,
|
3137
|
+
args << 'COUNT' << count if count
|
3138
|
+
args << 'BLOCK' << block.to_i if block
|
3139
|
+
args << 'NOACK' if noack
|
3140
|
+
_xread(args, keys, ids, block)
|
3127
3141
|
end
|
3128
3142
|
|
3129
3143
|
# Removes one or multiple entries from the pending entries list of a stream consumer group.
|
@@ -3233,8 +3247,8 @@ class Redis
|
|
3233
3247
|
when "get-master-addr-by-name"
|
3234
3248
|
reply
|
3235
3249
|
else
|
3236
|
-
if reply.
|
3237
|
-
if reply[0].
|
3250
|
+
if reply.is_a?(Array)
|
3251
|
+
if reply[0].is_a?(Array)
|
3238
3252
|
reply.map(&Hashify)
|
3239
3253
|
else
|
3240
3254
|
Hashify.call(reply)
|
@@ -3258,12 +3272,17 @@ class Redis
|
|
3258
3272
|
def cluster(subcommand, *args)
|
3259
3273
|
subcommand = subcommand.to_s.downcase
|
3260
3274
|
block = case subcommand
|
3261
|
-
|
3262
|
-
|
3263
|
-
|
3264
|
-
|
3265
|
-
|
3266
|
-
|
3275
|
+
when 'slots'
|
3276
|
+
HashifyClusterSlots
|
3277
|
+
when 'nodes'
|
3278
|
+
HashifyClusterNodes
|
3279
|
+
when 'slaves'
|
3280
|
+
HashifyClusterSlaves
|
3281
|
+
when 'info'
|
3282
|
+
HashifyInfo
|
3283
|
+
else
|
3284
|
+
Noop
|
3285
|
+
end
|
3267
3286
|
|
3268
3287
|
# @see https://github.com/antirez/redis/blob/unstable/src/redis-trib.rb#L127 raw reply expected
|
3269
3288
|
block = Noop unless @cluster_mode
|
@@ -3298,21 +3317,21 @@ class Redis
|
|
3298
3317
|
return @original_client.connection_info if @cluster_mode
|
3299
3318
|
|
3300
3319
|
{
|
3301
|
-
host:
|
3302
|
-
port:
|
3303
|
-
db:
|
3304
|
-
id:
|
3320
|
+
host: @original_client.host,
|
3321
|
+
port: @original_client.port,
|
3322
|
+
db: @original_client.db,
|
3323
|
+
id: @original_client.id,
|
3305
3324
|
location: @original_client.location
|
3306
3325
|
}
|
3307
3326
|
end
|
3308
3327
|
|
3309
|
-
def method_missing(command, *args)
|
3328
|
+
def method_missing(command, *args) # rubocop:disable Style/MissingRespondToMissing
|
3310
3329
|
synchronize do |client|
|
3311
3330
|
client.call([command] + args)
|
3312
3331
|
end
|
3313
3332
|
end
|
3314
3333
|
|
3315
|
-
private
|
3334
|
+
private
|
3316
3335
|
|
3317
3336
|
# Commands returning 1 for true and 0 for false may be executed in a pipeline
|
3318
3337
|
# where the method call will return nil. Propagate the nil instead of falsely
|
@@ -3392,10 +3411,10 @@ private
|
|
3392
3411
|
|
3393
3412
|
HashifyStreamPendings = lambda { |reply|
|
3394
3413
|
{
|
3395
|
-
'size'
|
3414
|
+
'size' => reply[0],
|
3396
3415
|
'min_entry_id' => reply[1],
|
3397
3416
|
'max_entry_id' => reply[2],
|
3398
|
-
'consumers'
|
3417
|
+
'consumers' => reply[3].nil? ? {} : reply[3].to_h
|
3399
3418
|
}
|
3400
3419
|
}
|
3401
3420
|
|
@@ -3404,8 +3423,8 @@ private
|
|
3404
3423
|
{
|
3405
3424
|
'entry_id' => arr[0],
|
3406
3425
|
'consumer' => arr[1],
|
3407
|
-
'elapsed'
|
3408
|
-
'count'
|
3426
|
+
'elapsed' => arr[2],
|
3427
|
+
'count' => arr[3]
|
3409
3428
|
}
|
3410
3429
|
end
|
3411
3430
|
}
|
@@ -3413,15 +3432,15 @@ private
|
|
3413
3432
|
HashifyClusterNodeInfo = lambda { |str|
|
3414
3433
|
arr = str.split(' ')
|
3415
3434
|
{
|
3416
|
-
'node_id'
|
3417
|
-
'ip_port'
|
3418
|
-
'flags'
|
3435
|
+
'node_id' => arr[0],
|
3436
|
+
'ip_port' => arr[1],
|
3437
|
+
'flags' => arr[2].split(','),
|
3419
3438
|
'master_node_id' => arr[3],
|
3420
|
-
'ping_sent'
|
3421
|
-
'pong_recv'
|
3422
|
-
'config_epoch'
|
3423
|
-
'link_state'
|
3424
|
-
'slots'
|
3439
|
+
'ping_sent' => arr[4],
|
3440
|
+
'pong_recv' => arr[5],
|
3441
|
+
'config_epoch' => arr[6],
|
3442
|
+
'link_state' => arr[7],
|
3443
|
+
'slots' => arr[8].nil? ? nil : Range.new(*arr[8].split('-'))
|
3425
3444
|
}
|
3426
3445
|
}
|
3427
3446
|
|
@@ -3432,9 +3451,9 @@ private
|
|
3432
3451
|
replicas = arr[3..-1].map { |r| { 'ip' => r[0], 'port' => r[1], 'node_id' => r[2] } }
|
3433
3452
|
{
|
3434
3453
|
'start_slot' => first_slot,
|
3435
|
-
'end_slot'
|
3436
|
-
'master'
|
3437
|
-
'replicas'
|
3454
|
+
'end_slot' => last_slot,
|
3455
|
+
'master' => master,
|
3456
|
+
'replicas' => replicas
|
3438
3457
|
}
|
3439
3458
|
end
|
3440
3459
|
}
|