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
data/lib/redis/commands/lists.rb
CHANGED
|
@@ -30,6 +30,84 @@ class Redis
|
|
|
30
30
|
send_command([:lmove, source, destination, where_source, where_destination])
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
# Remove multiple elements from the head/tail of a list, append/prepend
|
|
34
|
+
# them to another list and return them.
|
|
35
|
+
#
|
|
36
|
+
# @example Move a single element (still an array reply)
|
|
37
|
+
# redis.lmovem("foo", "bar", "LEFT", "LEFT")
|
|
38
|
+
# # => ["s1"]
|
|
39
|
+
# @example Move up to 3 elements, pushed one-by-one (block order reversed)
|
|
40
|
+
# redis.lmovem("foo", "bar", "LEFT", "LEFT", count: 3, order: "OBO")
|
|
41
|
+
# # => ["s3", "s2", "s1"]
|
|
42
|
+
# @example Move exactly 2 elements, preserving their relative order
|
|
43
|
+
# redis.lmovem("foo", "bar", "LEFT", "RIGHT", exactly: 2, order: "BULK")
|
|
44
|
+
# # => ["s1", "s2"]
|
|
45
|
+
#
|
|
46
|
+
# @param [String] source source key
|
|
47
|
+
# @param [String] destination destination key
|
|
48
|
+
# @param [String, Symbol] where_source from where to remove elements from the source list
|
|
49
|
+
# e.g. 'LEFT' - from head, 'RIGHT' - from tail
|
|
50
|
+
# @param [String, Symbol] where_destination where to push elements to the destination list
|
|
51
|
+
# e.g. 'LEFT' - to head, 'RIGHT' - to tail
|
|
52
|
+
# @param [Integer] count move up to `count` elements, fewer when the source holds fewer
|
|
53
|
+
# @param [Integer] exactly move exactly `exactly` elements; when the source holds fewer,
|
|
54
|
+
# nothing is moved
|
|
55
|
+
# @param [String, Symbol] order ordering at the destination, required together with
|
|
56
|
+
# `count` or `exactly`:
|
|
57
|
+
# - when `'OBO'` - push each element as popped, so the moved block order is reversed
|
|
58
|
+
# - when `'BULK'` - preserve the original relative order of the moved elements
|
|
59
|
+
#
|
|
60
|
+
# @return [nil, Array<String>] the moved elements in destination order, or nil when
|
|
61
|
+
# nothing was moved
|
|
62
|
+
def lmovem(source, destination, where_source, where_destination, count: nil, exactly: nil, order: nil)
|
|
63
|
+
where_source, where_destination = _normalize_move_wheres(where_source, where_destination)
|
|
64
|
+
|
|
65
|
+
args = [:lmovem, source, destination, where_source, where_destination]
|
|
66
|
+
args.concat(_movem_amount_args(count, exactly, order))
|
|
67
|
+
|
|
68
|
+
send_command(args)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Remove multiple elements from the head/tail of a list, append/prepend
|
|
72
|
+
# them to another list and return them; or block until the request can
|
|
73
|
+
# be satisfied or the timeout expires.
|
|
74
|
+
#
|
|
75
|
+
# @example Move up to 3 elements as soon as any are available
|
|
76
|
+
# redis.blmovem("foo", "bar", "LEFT", "LEFT", timeout: 1, count: 3, order: "BULK")
|
|
77
|
+
# # => ["s1", "s2", "s3"]
|
|
78
|
+
# @example Block until the source holds at least 2 elements
|
|
79
|
+
# redis.blmovem("foo", "bar", "LEFT", "RIGHT", timeout: 1, exactly: 2, order: "OBO")
|
|
80
|
+
# # => nil on timeout
|
|
81
|
+
#
|
|
82
|
+
# @param [String] source source key
|
|
83
|
+
# @param [String] destination destination key
|
|
84
|
+
# @param [String, Symbol] where_source from where to remove elements from the source list
|
|
85
|
+
# e.g. 'LEFT' - from head, 'RIGHT' - from tail
|
|
86
|
+
# @param [String, Symbol] where_destination where to push elements to the destination list
|
|
87
|
+
# e.g. 'LEFT' - to head, 'RIGHT' - to tail
|
|
88
|
+
# @param [Float, Integer] timeout seconds to block, 0 blocks indefinitely
|
|
89
|
+
# @param [Integer] count move up to `count` elements as soon as at least one is available
|
|
90
|
+
# @param [Integer] exactly move exactly `exactly` elements, blocking until the source
|
|
91
|
+
# holds that many
|
|
92
|
+
# @param [String, Symbol] order ordering at the destination, required together with
|
|
93
|
+
# `count` or `exactly`:
|
|
94
|
+
# - when `'OBO'` - push each element as popped, so the moved block order is reversed
|
|
95
|
+
# - when `'BULK'` - preserve the original relative order of the moved elements
|
|
96
|
+
#
|
|
97
|
+
# @return [nil, Array<String>] the moved elements in destination order, or nil when the
|
|
98
|
+
# timeout expired and nothing was moved
|
|
99
|
+
#
|
|
100
|
+
# @see #lmovem
|
|
101
|
+
def blmovem(source, destination, where_source, where_destination, timeout: 0, count: nil, exactly: nil,
|
|
102
|
+
order: nil)
|
|
103
|
+
where_source, where_destination = _normalize_move_wheres(where_source, where_destination)
|
|
104
|
+
|
|
105
|
+
command = [:blmovem, source, destination, where_source, where_destination, timeout]
|
|
106
|
+
command.concat(_movem_amount_args(count, exactly, order))
|
|
107
|
+
|
|
108
|
+
send_blocking_command(command, timeout)
|
|
109
|
+
end
|
|
110
|
+
|
|
33
111
|
# Remove the first/last element in a list and append/prepend it
|
|
34
112
|
# to another list and return it, or block until one is available.
|
|
35
113
|
#
|
|
@@ -48,7 +126,7 @@ class Redis
|
|
|
48
126
|
# @param [String, Symbol] where_destination where to push the element to the source list
|
|
49
127
|
# e.g. 'LEFT' - to head, 'RIGHT' - to tail
|
|
50
128
|
# @param [Hash] options
|
|
51
|
-
# - `:timeout =>
|
|
129
|
+
# - `:timeout => [Float, Integer]`: timeout in seconds, defaults to no timeout
|
|
52
130
|
#
|
|
53
131
|
# @return [nil, String] the element, or nil when the source key does not exist or the timeout expired
|
|
54
132
|
#
|
|
@@ -99,10 +177,10 @@ class Redis
|
|
|
99
177
|
#
|
|
100
178
|
# @param [String] key
|
|
101
179
|
# @param [Integer] count number of elements to remove
|
|
102
|
-
# @return [String, Array<String>] the values of the first elements
|
|
180
|
+
# @return [nil, String, Array<String>] the values of the first elements
|
|
103
181
|
def lpop(key, count = nil)
|
|
104
182
|
command = [:lpop, key]
|
|
105
|
-
command << count if count
|
|
183
|
+
command << Integer(count) if count
|
|
106
184
|
send_command(command)
|
|
107
185
|
end
|
|
108
186
|
|
|
@@ -110,10 +188,10 @@ class Redis
|
|
|
110
188
|
#
|
|
111
189
|
# @param [String] key
|
|
112
190
|
# @param [Integer] count number of elements to remove
|
|
113
|
-
# @return [String, Array<String>] the values of the last elements
|
|
191
|
+
# @return [nil, String, Array<String>] the values of the last elements
|
|
114
192
|
def rpop(key, count = nil)
|
|
115
193
|
command = [:rpop, key]
|
|
116
|
-
command << count if count
|
|
194
|
+
command << Integer(count) if count
|
|
117
195
|
send_command(command)
|
|
118
196
|
end
|
|
119
197
|
|
|
@@ -142,7 +220,7 @@ class Redis
|
|
|
142
220
|
# @param [String, Array<String>] keys one or more keys to perform the
|
|
143
221
|
# blocking pop on
|
|
144
222
|
# @param [Hash] options
|
|
145
|
-
# - `:timeout => Integer`: timeout in seconds, defaults to no timeout
|
|
223
|
+
# - `:timeout => [Float, Integer]`: timeout in seconds, defaults to no timeout
|
|
146
224
|
#
|
|
147
225
|
# @return [nil, [String, String]]
|
|
148
226
|
# - `nil` when the operation timed out
|
|
@@ -156,7 +234,7 @@ class Redis
|
|
|
156
234
|
# @param [String, Array<String>] keys one or more keys to perform the
|
|
157
235
|
# blocking pop on
|
|
158
236
|
# @param [Hash] options
|
|
159
|
-
# - `:timeout => Integer`: timeout in seconds, defaults to no timeout
|
|
237
|
+
# - `:timeout => [Float, Integer]`: timeout in seconds, defaults to no timeout
|
|
160
238
|
#
|
|
161
239
|
# @return [nil, [String, String]]
|
|
162
240
|
# - `nil` when the operation timed out
|
|
@@ -173,23 +251,77 @@ class Redis
|
|
|
173
251
|
# @param [String] source source key
|
|
174
252
|
# @param [String] destination destination key
|
|
175
253
|
# @param [Hash] options
|
|
176
|
-
# - `:timeout => Integer`: timeout in seconds, defaults to no timeout
|
|
254
|
+
# - `:timeout => [Float, Integer]`: timeout in seconds, defaults to no timeout
|
|
177
255
|
#
|
|
178
256
|
# @return [nil, String]
|
|
179
257
|
# - `nil` when the operation timed out
|
|
180
258
|
# - the element was popped and pushed otherwise
|
|
181
|
-
def brpoplpush(source, destination,
|
|
259
|
+
def brpoplpush(source, destination, timeout: 0)
|
|
182
260
|
command = [:brpoplpush, source, destination, timeout]
|
|
183
261
|
send_blocking_command(command, timeout)
|
|
184
262
|
end
|
|
185
263
|
|
|
264
|
+
# Pops one or more elements from the first non-empty list key from the list
|
|
265
|
+
# of provided key names. If lists are empty, blocks until timeout has passed.
|
|
266
|
+
#
|
|
267
|
+
# @example Popping a element
|
|
268
|
+
# redis.blmpop(1.0, 'list')
|
|
269
|
+
# #=> ['list', ['a']]
|
|
270
|
+
# @example With count option
|
|
271
|
+
# redis.blmpop(1.0, 'list', count: 2)
|
|
272
|
+
# #=> ['list', ['a', 'b']]
|
|
273
|
+
#
|
|
274
|
+
# @params timeout [Float] a float value specifying the maximum number of seconds to block) elapses.
|
|
275
|
+
# A timeout of zero can be used to block indefinitely.
|
|
276
|
+
# @params key [String, Array<String>] one or more keys with lists
|
|
277
|
+
# @params modifier [String]
|
|
278
|
+
# - when `"LEFT"` - the elements popped are those from the left of the list
|
|
279
|
+
# - when `"RIGHT"` - the elements popped are those from the right of the list
|
|
280
|
+
# @params count [Integer] a number of elements to pop
|
|
281
|
+
#
|
|
282
|
+
# @return [Array<String, Array<String, Float>>] list of popped elements or nil
|
|
283
|
+
def blmpop(timeout, *keys, modifier: "LEFT", count: nil)
|
|
284
|
+
raise ArgumentError, "Pick either LEFT or RIGHT" unless modifier == "LEFT" || modifier == "RIGHT"
|
|
285
|
+
|
|
286
|
+
args = [:blmpop, timeout, keys.size, *keys, modifier]
|
|
287
|
+
args << "COUNT" << Integer(count) if count
|
|
288
|
+
|
|
289
|
+
send_blocking_command(args, timeout)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# Pops one or more elements from the first non-empty list key from the list
|
|
293
|
+
# of provided key names.
|
|
294
|
+
#
|
|
295
|
+
# @example Popping a element
|
|
296
|
+
# redis.lmpop('list')
|
|
297
|
+
# #=> ['list', ['a']]
|
|
298
|
+
# @example With count option
|
|
299
|
+
# redis.lmpop('list', count: 2)
|
|
300
|
+
# #=> ['list', ['a', 'b']]
|
|
301
|
+
#
|
|
302
|
+
# @params key [String, Array<String>] one or more keys with lists
|
|
303
|
+
# @params modifier [String]
|
|
304
|
+
# - when `"LEFT"` - the elements popped are those from the left of the list
|
|
305
|
+
# - when `"RIGHT"` - the elements popped are those from the right of the list
|
|
306
|
+
# @params count [Integer] a number of elements to pop
|
|
307
|
+
#
|
|
308
|
+
# @return [Array<String, Array<String, Float>>] list of popped elements or nil
|
|
309
|
+
def lmpop(*keys, modifier: "LEFT", count: nil)
|
|
310
|
+
raise ArgumentError, "Pick either LEFT or RIGHT" unless modifier == "LEFT" || modifier == "RIGHT"
|
|
311
|
+
|
|
312
|
+
args = [:lmpop, keys.size, *keys, modifier]
|
|
313
|
+
args << "COUNT" << Integer(count) if count
|
|
314
|
+
|
|
315
|
+
send_command(args)
|
|
316
|
+
end
|
|
317
|
+
|
|
186
318
|
# Get an element from a list by its index.
|
|
187
319
|
#
|
|
188
320
|
# @param [String] key
|
|
189
321
|
# @param [Integer] index
|
|
190
322
|
# @return [String]
|
|
191
323
|
def lindex(key, index)
|
|
192
|
-
send_command([:lindex, key, index])
|
|
324
|
+
send_command([:lindex, key, Integer(index)])
|
|
193
325
|
end
|
|
194
326
|
|
|
195
327
|
# Insert an element before or after another element in a list.
|
|
@@ -211,7 +343,7 @@ class Redis
|
|
|
211
343
|
# @param [Integer] stop stop index
|
|
212
344
|
# @return [Array<String>]
|
|
213
345
|
def lrange(key, start, stop)
|
|
214
|
-
send_command([:lrange, key, start, stop])
|
|
346
|
+
send_command([:lrange, key, Integer(start), Integer(stop)])
|
|
215
347
|
end
|
|
216
348
|
|
|
217
349
|
# Remove elements from a list.
|
|
@@ -224,7 +356,7 @@ class Redis
|
|
|
224
356
|
# @param [String] value
|
|
225
357
|
# @return [Integer] the number of removed elements
|
|
226
358
|
def lrem(key, count, value)
|
|
227
|
-
send_command([:lrem, key, count, value])
|
|
359
|
+
send_command([:lrem, key, Integer(count), value])
|
|
228
360
|
end
|
|
229
361
|
|
|
230
362
|
# Set the value of an element in a list by its index.
|
|
@@ -234,7 +366,7 @@ class Redis
|
|
|
234
366
|
# @param [String] value
|
|
235
367
|
# @return [String] `OK`
|
|
236
368
|
def lset(key, index, value)
|
|
237
|
-
send_command([:lset, key, index, value])
|
|
369
|
+
send_command([:lset, key, Integer(index), value])
|
|
238
370
|
end
|
|
239
371
|
|
|
240
372
|
# Trim a list to the specified range.
|
|
@@ -244,7 +376,7 @@ class Redis
|
|
|
244
376
|
# @param [Integer] stop stop index
|
|
245
377
|
# @return [String] `OK`
|
|
246
378
|
def ltrim(key, start, stop)
|
|
247
|
-
send_command([:ltrim, key, start, stop])
|
|
379
|
+
send_command([:ltrim, key, Integer(start), Integer(stop)])
|
|
248
380
|
end
|
|
249
381
|
|
|
250
382
|
private
|
|
@@ -253,24 +385,34 @@ class Redis
|
|
|
253
385
|
timeout = if args.last.is_a?(Hash)
|
|
254
386
|
options = args.pop
|
|
255
387
|
options[:timeout]
|
|
256
|
-
elsif args.last.respond_to?(:to_int)
|
|
257
|
-
last_arg = args.pop
|
|
258
|
-
::Redis.deprecate!(
|
|
259
|
-
"Passing the timeout as a positional argument is deprecated, it should be passed as a keyword argument:\n" \
|
|
260
|
-
" redis.#{cmd}(#{args.map(&:inspect).join(', ')}, timeout: #{last_arg.to_int})" \
|
|
261
|
-
"(called from: #{caller(2, 1).first})"
|
|
262
|
-
)
|
|
263
|
-
last_arg.to_int
|
|
264
388
|
end
|
|
265
389
|
|
|
266
390
|
timeout ||= 0
|
|
391
|
+
unless timeout.is_a?(Integer) || timeout.is_a?(Float)
|
|
392
|
+
raise ArgumentError, "timeout must be an Integer or Float, got: #{timeout.class}"
|
|
393
|
+
end
|
|
267
394
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
command
|
|
395
|
+
args.flatten!(1)
|
|
396
|
+
command = [cmd].concat(args)
|
|
397
|
+
command << timeout
|
|
271
398
|
send_blocking_command(command, timeout, &blk)
|
|
272
399
|
end
|
|
273
400
|
|
|
401
|
+
def _movem_amount_args(count, exactly, order)
|
|
402
|
+
raise ArgumentError, "Pick either count or exactly, not both" if count && exactly
|
|
403
|
+
|
|
404
|
+
if count || exactly
|
|
405
|
+
order = order.to_s.upcase
|
|
406
|
+
raise ArgumentError, "order must be 'OBO' or 'BULK'" if order != "OBO" && order != "BULK"
|
|
407
|
+
|
|
408
|
+
[count ? "COUNT" : "EXACTLY", Integer(count || exactly), order]
|
|
409
|
+
elsif order
|
|
410
|
+
raise ArgumentError, "order requires count or exactly"
|
|
411
|
+
else
|
|
412
|
+
[]
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
274
416
|
def _normalize_move_wheres(where_source, where_destination)
|
|
275
417
|
where_source = where_source.to_s.upcase
|
|
276
418
|
where_destination = where_destination.to_s.upcase
|