redis 4.8.1 → 6.0.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 +138 -1
- data/README.md +285 -169
- data/lib/redis/client.rb +116 -611
- 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 +109 -7
- data/lib/redis/commands/hashes.rb +179 -8
- data/lib/redis/commands/hyper_log_log.rb +1 -1
- data/lib/redis/commands/keys.rb +32 -24
- data/lib/redis/commands/lists.rb +167 -25
- data/lib/redis/commands/modules/json.rb +530 -0
- data/lib/redis/commands/modules/search/aggregation.rb +418 -0
- data/lib/redis/commands/modules/search/dialect.rb +14 -0
- data/lib/redis/commands/modules/search/field.rb +306 -0
- data/lib/redis/commands/modules/search/hybrid.rb +359 -0
- data/lib/redis/commands/modules/search/index.rb +351 -0
- data/lib/redis/commands/modules/search/index_definition.rb +114 -0
- data/lib/redis/commands/modules/search/miscellaneous.rb +607 -0
- data/lib/redis/commands/modules/search/query.rb +738 -0
- data/lib/redis/commands/modules/search/result.rb +488 -0
- data/lib/redis/commands/modules/search/schema.rb +211 -0
- data/lib/redis/commands/modules/search.rb +19 -0
- data/lib/redis/commands/pubsub.rb +34 -25
- data/lib/redis/commands/server.rb +15 -15
- data/lib/redis/commands/sets.rb +76 -40
- data/lib/redis/commands/sorted_sets.rb +128 -19
- data/lib/redis/commands/streams.rb +75 -28
- data/lib/redis/commands/strings.rb +18 -17
- data/lib/redis/commands/transactions.rb +7 -31
- data/lib/redis/commands.rb +39 -20
- data/lib/redis/distributed.rb +407 -73
- data/lib/redis/errors.rb +20 -50
- data/lib/redis/hash_ring.rb +26 -26
- data/lib/redis/lib_identity.rb +105 -0
- data/lib/redis/pipeline.rb +47 -222
- data/lib/redis/subscribe.rb +51 -15
- data/lib/redis/version.rb +1 -1
- data/lib/redis.rb +213 -188
- metadata +25 -59
- 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
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "redis/commands/modules/search/dialect"
|
|
4
|
+
require "redis/commands/modules/search/index_definition"
|
|
5
|
+
require "redis/commands/modules/search/field"
|
|
6
|
+
require "redis/commands/modules/search/schema"
|
|
7
|
+
require "redis/commands/modules/search/query"
|
|
8
|
+
require "redis/commands/modules/search/index"
|
|
9
|
+
require "redis/commands/modules/search/result"
|
|
10
|
+
require "redis/commands/modules/search/miscellaneous"
|
|
11
|
+
require "redis/commands/modules/search/hybrid"
|
|
12
|
+
require "redis/commands/modules/search/aggregation"
|
|
13
|
+
|
|
14
|
+
class Redis
|
|
15
|
+
module Commands
|
|
16
|
+
module Search
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -9,57 +9,45 @@ class Redis
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def subscribed?
|
|
12
|
-
|
|
13
|
-
client.is_a? SubscribedClient
|
|
14
|
-
end
|
|
12
|
+
!@subscription_client.nil?
|
|
15
13
|
end
|
|
16
14
|
|
|
17
15
|
# Listen for messages published to the given channels.
|
|
18
16
|
def subscribe(*channels, &block)
|
|
19
|
-
|
|
20
|
-
_subscription(:subscribe, 0, channels, block)
|
|
21
|
-
end
|
|
17
|
+
_subscription(:subscribe, 0, channels, block)
|
|
22
18
|
end
|
|
23
19
|
|
|
24
20
|
# Listen for messages published to the given channels. Throw a timeout error
|
|
25
21
|
# if there is no messages for a timeout period.
|
|
26
22
|
def subscribe_with_timeout(timeout, *channels, &block)
|
|
27
|
-
|
|
28
|
-
_subscription(:subscribe_with_timeout, timeout, channels, block)
|
|
29
|
-
end
|
|
23
|
+
_subscription(:subscribe_with_timeout, timeout, channels, block)
|
|
30
24
|
end
|
|
31
25
|
|
|
32
26
|
# Stop listening for messages posted to the given channels.
|
|
33
27
|
def unsubscribe(*channels)
|
|
34
|
-
|
|
35
|
-
raise "Can't unsubscribe if not subscribed." unless subscribed?
|
|
36
|
-
|
|
37
|
-
client.unsubscribe(*channels)
|
|
38
|
-
end
|
|
28
|
+
_subscription(:unsubscribe, 0, channels, nil)
|
|
39
29
|
end
|
|
40
30
|
|
|
41
31
|
# Listen for messages published to channels matching the given patterns.
|
|
32
|
+
# See the [Redis Server PSUBSCRIBE documentation](https://redis.io/docs/latest/commands/psubscribe/)
|
|
33
|
+
# for further details
|
|
42
34
|
def psubscribe(*channels, &block)
|
|
43
|
-
|
|
44
|
-
_subscription(:psubscribe, 0, channels, block)
|
|
45
|
-
end
|
|
35
|
+
_subscription(:psubscribe, 0, channels, block)
|
|
46
36
|
end
|
|
47
37
|
|
|
48
38
|
# Listen for messages published to channels matching the given patterns.
|
|
49
39
|
# Throw a timeout error if there is no messages for a timeout period.
|
|
40
|
+
# See the [Redis Server PSUBSCRIBE documentation](https://redis.io/docs/latest/commands/psubscribe/)
|
|
41
|
+
# for further details
|
|
50
42
|
def psubscribe_with_timeout(timeout, *channels, &block)
|
|
51
|
-
|
|
52
|
-
_subscription(:psubscribe_with_timeout, timeout, channels, block)
|
|
53
|
-
end
|
|
43
|
+
_subscription(:psubscribe_with_timeout, timeout, channels, block)
|
|
54
44
|
end
|
|
55
45
|
|
|
56
46
|
# Stop listening for messages posted to channels matching the given patterns.
|
|
47
|
+
# See the [Redis Server PUNSUBSCRIBE documentation](https://redis.io/docs/latest/commands/punsubscribe/)
|
|
48
|
+
# for further details
|
|
57
49
|
def punsubscribe(*channels)
|
|
58
|
-
|
|
59
|
-
raise "Can't unsubscribe if not subscribed." unless subscribed?
|
|
60
|
-
|
|
61
|
-
client.punsubscribe(*channels)
|
|
62
|
-
end
|
|
50
|
+
_subscription(:punsubscribe, 0, channels, nil)
|
|
63
51
|
end
|
|
64
52
|
|
|
65
53
|
# Inspect the state of the Pub/Sub subsystem.
|
|
@@ -67,6 +55,27 @@ class Redis
|
|
|
67
55
|
def pubsub(subcommand, *args)
|
|
68
56
|
send_command([:pubsub, subcommand] + args)
|
|
69
57
|
end
|
|
58
|
+
|
|
59
|
+
# Post a message to a channel in a shard.
|
|
60
|
+
def spublish(channel, message)
|
|
61
|
+
send_command([:spublish, channel, message])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Listen for messages published to the given channels in a shard.
|
|
65
|
+
def ssubscribe(*channels, &block)
|
|
66
|
+
_subscription(:ssubscribe, 0, channels, block)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Listen for messages published to the given channels in a shard.
|
|
70
|
+
# Throw a timeout error if there is no messages for a timeout period.
|
|
71
|
+
def ssubscribe_with_timeout(timeout, *channels, &block)
|
|
72
|
+
_subscription(:ssubscribe_with_timeout, timeout, channels, block)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Stop listening for messages posted to the given channels in a shard.
|
|
76
|
+
def sunsubscribe(*channels)
|
|
77
|
+
_subscription(:sunsubscribe, 0, channels, nil)
|
|
78
|
+
end
|
|
70
79
|
end
|
|
71
80
|
end
|
|
72
81
|
end
|
|
@@ -36,7 +36,7 @@ class Redis
|
|
|
36
36
|
#
|
|
37
37
|
# @param [String, Symbol] subcommand e.g. `kill`, `list`, `getname`, `setname`
|
|
38
38
|
# @return [String, Hash] depends on subcommand
|
|
39
|
-
def client(subcommand
|
|
39
|
+
def client(subcommand, *args)
|
|
40
40
|
send_command([:client, subcommand] + args) do |reply|
|
|
41
41
|
if subcommand.to_s == "list"
|
|
42
42
|
reply.lines.map do |line|
|
|
@@ -117,9 +117,13 @@ class Redis
|
|
|
117
117
|
#
|
|
118
118
|
# @yield a block to be called for every line of output
|
|
119
119
|
# @yieldparam [String] line timestamp and command that was executed
|
|
120
|
-
def monitor
|
|
120
|
+
def monitor
|
|
121
121
|
synchronize do |client|
|
|
122
|
-
client.
|
|
122
|
+
client = client.pubsub
|
|
123
|
+
client.call_v([:monitor])
|
|
124
|
+
loop do
|
|
125
|
+
yield client.next_event
|
|
126
|
+
end
|
|
123
127
|
end
|
|
124
128
|
end
|
|
125
129
|
|
|
@@ -133,13 +137,11 @@ class Redis
|
|
|
133
137
|
# Synchronously save the dataset to disk and then shut down the server.
|
|
134
138
|
def shutdown
|
|
135
139
|
synchronize do |client|
|
|
136
|
-
client.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
nil
|
|
142
|
-
end
|
|
140
|
+
client.disable_reconnection do
|
|
141
|
+
client.call_v([:shutdown])
|
|
142
|
+
rescue ConnectionError
|
|
143
|
+
# This means Redis has probably exited.
|
|
144
|
+
nil
|
|
143
145
|
end
|
|
144
146
|
end
|
|
145
147
|
end
|
|
@@ -155,11 +157,9 @@ class Redis
|
|
|
155
157
|
# @param [Integer] length maximum number of entries to return
|
|
156
158
|
# @return [Array<String>, Integer, String] depends on subcommand
|
|
157
159
|
def slowlog(subcommand, length = nil)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
client.call args
|
|
162
|
-
end
|
|
160
|
+
args = [:slowlog, subcommand]
|
|
161
|
+
args << Integer(length) if length
|
|
162
|
+
send_command(args)
|
|
163
163
|
end
|
|
164
164
|
|
|
165
165
|
# Internal command used for replication.
|
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#srem will always return an Integer in Redis 5.0.0. Use Redis#srem? 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,28 @@ 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))
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Get the number of members in the difference between the first set and
|
|
139
|
+
# all successive sets.
|
|
140
|
+
#
|
|
141
|
+
# @example
|
|
142
|
+
# redis.sadd("foo", ["s1", "s2", "s3"])
|
|
143
|
+
# redis.sadd("bar", "s3")
|
|
144
|
+
# redis.sdiffcard("foo", "bar")
|
|
145
|
+
# # => 2
|
|
146
|
+
#
|
|
147
|
+
# @param [String, Array<String>] keys keys pointing to sets to subtract
|
|
148
|
+
# @param [Integer] limit stop counting once the difference reaches `limit`
|
|
149
|
+
# members (`0` means unlimited)
|
|
150
|
+
# @return [Integer] number of members in the difference
|
|
151
|
+
def sdiffcard(*keys, limit: nil)
|
|
152
|
+
keys.flatten!(1)
|
|
153
|
+
args = [:sdiffcard, keys.size].concat(keys)
|
|
154
|
+
args << "LIMIT" << Integer(limit) if limit
|
|
155
|
+
send_command(args)
|
|
149
156
|
end
|
|
150
157
|
|
|
151
158
|
# Intersect multiple sets.
|
|
@@ -153,7 +160,8 @@ class Redis
|
|
|
153
160
|
# @param [String, Array<String>] keys keys pointing to sets to intersect
|
|
154
161
|
# @return [Array<String>] members in the intersection
|
|
155
162
|
def sinter(*keys)
|
|
156
|
-
|
|
163
|
+
keys.flatten!(1)
|
|
164
|
+
send_command([:sinter].concat(keys))
|
|
157
165
|
end
|
|
158
166
|
|
|
159
167
|
# Intersect multiple sets and store the resulting set in a key.
|
|
@@ -162,7 +170,8 @@ class Redis
|
|
|
162
170
|
# @param [String, Array<String>] keys keys pointing to sets to intersect
|
|
163
171
|
# @return [Integer] number of elements in the resulting set
|
|
164
172
|
def sinterstore(destination, *keys)
|
|
165
|
-
|
|
173
|
+
keys.flatten!(1)
|
|
174
|
+
send_command([:sinterstore, destination].concat(keys))
|
|
166
175
|
end
|
|
167
176
|
|
|
168
177
|
# Add multiple sets.
|
|
@@ -170,7 +179,8 @@ class Redis
|
|
|
170
179
|
# @param [String, Array<String>] keys keys pointing to sets to unify
|
|
171
180
|
# @return [Array<String>] members in the union
|
|
172
181
|
def sunion(*keys)
|
|
173
|
-
|
|
182
|
+
keys.flatten!(1)
|
|
183
|
+
send_command([:sunion].concat(keys))
|
|
174
184
|
end
|
|
175
185
|
|
|
176
186
|
# Add multiple sets and store the resulting set in a key.
|
|
@@ -179,7 +189,29 @@ class Redis
|
|
|
179
189
|
# @param [String, Array<String>] keys keys pointing to sets to unify
|
|
180
190
|
# @return [Integer] number of elements in the resulting set
|
|
181
191
|
def sunionstore(destination, *keys)
|
|
182
|
-
|
|
192
|
+
keys.flatten!(1)
|
|
193
|
+
send_command([:sunionstore, destination].concat(keys))
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Get the number of distinct members in the union of multiple sets.
|
|
197
|
+
#
|
|
198
|
+
# @example
|
|
199
|
+
# redis.sadd("foo", ["s1", "s2", "s3"])
|
|
200
|
+
# redis.sadd("bar", ["s3", "s4"])
|
|
201
|
+
# redis.sunioncard("foo", "bar")
|
|
202
|
+
# # => 4
|
|
203
|
+
#
|
|
204
|
+
# @param [String, Array<String>] keys keys pointing to sets to unify
|
|
205
|
+
# @param [Boolean] approx return an approximate cardinality computed with HyperLogLog
|
|
206
|
+
# @param [Integer] limit stop counting once the union reaches `limit`
|
|
207
|
+
# members (`0` means unlimited)
|
|
208
|
+
# @return [Integer] number of distinct members in the union
|
|
209
|
+
def sunioncard(*keys, approx: false, limit: nil)
|
|
210
|
+
keys.flatten!(1)
|
|
211
|
+
args = [:sunioncard, keys.size].concat(keys)
|
|
212
|
+
args << "APPROX" if approx
|
|
213
|
+
args << "LIMIT" << Integer(limit) if limit
|
|
214
|
+
send_command(args)
|
|
183
215
|
end
|
|
184
216
|
|
|
185
217
|
# Scan a set
|
|
@@ -193,6 +225,8 @@ class Redis
|
|
|
193
225
|
# - `:count => Integer`: return count keys at most per iteration
|
|
194
226
|
#
|
|
195
227
|
# @return [String, Array<String>] the next cursor and all found members
|
|
228
|
+
#
|
|
229
|
+
# See the [Redis Server SSCAN documentation](https://redis.io/docs/latest/commands/sscan/) for further details
|
|
196
230
|
def sscan(key, cursor, **options)
|
|
197
231
|
_scan(:sscan, cursor, [key], **options)
|
|
198
232
|
end
|
|
@@ -208,6 +242,8 @@ class Redis
|
|
|
208
242
|
# - `:count => Integer`: return count keys at most per iteration
|
|
209
243
|
#
|
|
210
244
|
# @return [Enumerator] an enumerator for all keys in the set
|
|
245
|
+
#
|
|
246
|
+
# See the [Redis Server SSCAN documentation](https://redis.io/docs/latest/commands/sscan/) for further details
|
|
211
247
|
def sscan_each(key, **options, &block)
|
|
212
248
|
return to_enum(:sscan_each, key, **options) unless block_given?
|
|
213
249
|
|
|
@@ -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"
|
|
@@ -296,7 +366,6 @@ class Redis
|
|
|
296
366
|
# - when `:with_scores` is specified, an array with `[member, score]` pairs
|
|
297
367
|
def zrange(key, start, stop, byscore: false, by_score: byscore, bylex: false, by_lex: bylex,
|
|
298
368
|
rev: false, limit: nil, withscores: false, with_scores: withscores)
|
|
299
|
-
|
|
300
369
|
if by_score && by_lex
|
|
301
370
|
raise ArgumentError, "only one of :by_score or :by_lex can be specified"
|
|
302
371
|
end
|
|
@@ -313,7 +382,7 @@ class Redis
|
|
|
313
382
|
|
|
314
383
|
if limit
|
|
315
384
|
args << "LIMIT"
|
|
316
|
-
args.concat(limit)
|
|
385
|
+
args.concat(limit.map { |l| Integer(l) })
|
|
317
386
|
end
|
|
318
387
|
|
|
319
388
|
if with_scores
|
|
@@ -354,7 +423,7 @@ class Redis
|
|
|
354
423
|
|
|
355
424
|
if limit
|
|
356
425
|
args << "LIMIT"
|
|
357
|
-
args.concat(limit)
|
|
426
|
+
args.concat(limit.map { |l| Integer(l) })
|
|
358
427
|
end
|
|
359
428
|
|
|
360
429
|
send_command(args)
|
|
@@ -372,7 +441,7 @@ class Redis
|
|
|
372
441
|
#
|
|
373
442
|
# @see #zrange
|
|
374
443
|
def zrevrange(key, start, stop, withscores: false, with_scores: withscores)
|
|
375
|
-
args = [:zrevrange, key, start, stop]
|
|
444
|
+
args = [:zrevrange, key, Integer(start), Integer(stop)]
|
|
376
445
|
|
|
377
446
|
if with_scores
|
|
378
447
|
args << "WITHSCORES"
|
|
@@ -384,21 +453,55 @@ class Redis
|
|
|
384
453
|
|
|
385
454
|
# Determine the index of a member in a sorted set.
|
|
386
455
|
#
|
|
456
|
+
# @example Retrieve member rank
|
|
457
|
+
# redis.zrank("zset", "a")
|
|
458
|
+
# # => 3
|
|
459
|
+
# @example Retrieve member rank with their score
|
|
460
|
+
# redis.zrank("zset", "a", :with_score => true)
|
|
461
|
+
# # => [3, 32.0]
|
|
462
|
+
#
|
|
387
463
|
# @param [String] key
|
|
388
464
|
# @param [String] member
|
|
389
|
-
#
|
|
390
|
-
|
|
391
|
-
|
|
465
|
+
#
|
|
466
|
+
# @return [Integer, [Integer, Float]]
|
|
467
|
+
# - when `:with_score` is not specified, an Integer
|
|
468
|
+
# - when `:with_score` is specified, a `[rank, score]` pair
|
|
469
|
+
def zrank(key, member, withscore: false, with_score: withscore)
|
|
470
|
+
args = [:zrank, key, member]
|
|
471
|
+
|
|
472
|
+
if with_score
|
|
473
|
+
args << "WITHSCORE"
|
|
474
|
+
block = FloatifyPair
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
send_command(args, &block)
|
|
392
478
|
end
|
|
393
479
|
|
|
394
480
|
# Determine the index of a member in a sorted set, with scores ordered from
|
|
395
481
|
# high to low.
|
|
396
482
|
#
|
|
483
|
+
# @example Retrieve member rank
|
|
484
|
+
# redis.zrevrank("zset", "a")
|
|
485
|
+
# # => 3
|
|
486
|
+
# @example Retrieve member rank with their score
|
|
487
|
+
# redis.zrevrank("zset", "a", :with_score => true)
|
|
488
|
+
# # => [3, 32.0]
|
|
489
|
+
#
|
|
397
490
|
# @param [String] key
|
|
398
491
|
# @param [String] member
|
|
399
|
-
#
|
|
400
|
-
|
|
401
|
-
|
|
492
|
+
#
|
|
493
|
+
# @return [Integer, [Integer, Float]]
|
|
494
|
+
# - when `:with_score` is not specified, an Integer
|
|
495
|
+
# - when `:with_score` is specified, a `[rank, score]` pair
|
|
496
|
+
def zrevrank(key, member, withscore: false, with_score: withscore)
|
|
497
|
+
args = [:zrevrank, key, member]
|
|
498
|
+
|
|
499
|
+
if with_score
|
|
500
|
+
args << "WITHSCORE"
|
|
501
|
+
block = FloatifyPair
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
send_command(args, &block)
|
|
402
505
|
end
|
|
403
506
|
|
|
404
507
|
# Remove all members in a sorted set within the given indexes.
|
|
@@ -466,7 +569,7 @@ class Redis
|
|
|
466
569
|
|
|
467
570
|
if limit
|
|
468
571
|
args << "LIMIT"
|
|
469
|
-
args.concat(limit)
|
|
572
|
+
args.concat(limit.map { |l| Integer(l) })
|
|
470
573
|
end
|
|
471
574
|
|
|
472
575
|
send_command(args)
|
|
@@ -488,7 +591,7 @@ class Redis
|
|
|
488
591
|
|
|
489
592
|
if limit
|
|
490
593
|
args << "LIMIT"
|
|
491
|
-
args.concat(limit)
|
|
594
|
+
args.concat(limit.map { |l| Integer(l) })
|
|
492
595
|
end
|
|
493
596
|
|
|
494
597
|
send_command(args)
|
|
@@ -531,7 +634,7 @@ class Redis
|
|
|
531
634
|
|
|
532
635
|
if limit
|
|
533
636
|
args << "LIMIT"
|
|
534
|
-
args.concat(limit)
|
|
637
|
+
args.concat(limit.map { |l| Integer(l) })
|
|
535
638
|
end
|
|
536
639
|
|
|
537
640
|
send_command(args, &block)
|
|
@@ -561,7 +664,7 @@ class Redis
|
|
|
561
664
|
|
|
562
665
|
if limit
|
|
563
666
|
args << "LIMIT"
|
|
564
|
-
args.concat(limit)
|
|
667
|
+
args.concat(limit.map { |l| Integer(l) })
|
|
565
668
|
end
|
|
566
669
|
|
|
567
670
|
send_command(args, &block)
|
|
@@ -747,6 +850,8 @@ class Redis
|
|
|
747
850
|
#
|
|
748
851
|
# @return [String, Array<[String, Float]>] the next cursor and all found
|
|
749
852
|
# members and scores
|
|
853
|
+
#
|
|
854
|
+
# See the [Redis Server ZSCAN documentation](https://redis.io/docs/latest/commands/zscan/) for further details
|
|
750
855
|
def zscan(key, cursor, **options)
|
|
751
856
|
_scan(:zscan, cursor, [key], **options) do |reply|
|
|
752
857
|
[reply[0], FloatifyPairs.call(reply[1])]
|
|
@@ -764,6 +869,8 @@ class Redis
|
|
|
764
869
|
# - `:count => Integer`: return count keys at most per iteration
|
|
765
870
|
#
|
|
766
871
|
# @return [Enumerator] an enumerator for all found scores and members
|
|
872
|
+
#
|
|
873
|
+
# See the [Redis Server ZSCAN documentation](https://redis.io/docs/latest/commands/zscan/) for further details
|
|
767
874
|
def zscan_each(key, **options, &block)
|
|
768
875
|
return to_enum(:zscan_each, key, **options) unless block_given?
|
|
769
876
|
|
|
@@ -778,7 +885,8 @@ class Redis
|
|
|
778
885
|
private
|
|
779
886
|
|
|
780
887
|
def _zsets_operation(cmd, *keys, weights: nil, aggregate: nil, with_scores: false)
|
|
781
|
-
|
|
888
|
+
keys.flatten!(1)
|
|
889
|
+
command = [cmd, keys.size].concat(keys)
|
|
782
890
|
|
|
783
891
|
if weights
|
|
784
892
|
command << "WEIGHTS"
|
|
@@ -796,7 +904,8 @@ class Redis
|
|
|
796
904
|
end
|
|
797
905
|
|
|
798
906
|
def _zsets_operation_store(cmd, destination, keys, weights: nil, aggregate: nil)
|
|
799
|
-
|
|
907
|
+
keys.flatten!(1)
|
|
908
|
+
command = [cmd, destination, keys.size].concat(keys)
|
|
800
909
|
|
|
801
910
|
if weights
|
|
802
911
|
command << "WEIGHTS"
|