redis 3.0.0.rc2 → 3.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.
- data/.order +169 -0
- data/CHANGELOG.md +79 -9
- data/README.md +7 -0
- data/Rakefile +167 -0
- data/lib/redis.rb +1265 -1148
- data/lib/redis/client.rb +11 -18
- data/lib/redis/distributed.rb +337 -280
- data/lib/redis/pipeline.rb +12 -4
- data/lib/redis/version.rb +1 -1
- data/redis.gemspec +1 -1
- data/test/commands_on_lists_test.rb +0 -30
- data/test/commands_on_strings_test.rb +0 -6
- data/test/distributed_scripting_test.rb +102 -0
- data/test/internals_test.rb +33 -35
- data/test/lint/lists.rb +42 -12
- data/test/lint/strings.rb +6 -0
- data/test/lint/value_types.rb +10 -6
- data/test/scripting_test.rb +78 -0
- metadata +12 -8
data/lib/redis.rb
CHANGED
@@ -36,13 +36,18 @@ class Redis
|
|
36
36
|
mon_synchronize { yield(@client) }
|
37
37
|
end
|
38
38
|
|
39
|
-
# Run code
|
40
|
-
def
|
39
|
+
# Run code with the client reconnecting
|
40
|
+
def with_reconnect(val=true, &blk)
|
41
41
|
synchronize do |client|
|
42
|
-
client.
|
42
|
+
client.with_reconnect(val, &blk)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
# Run code without the client reconnecting
|
47
|
+
def without_reconnect(&blk)
|
48
|
+
with_reconnect(false, &blk)
|
49
|
+
end
|
50
|
+
|
46
51
|
# Authenticate to the server.
|
47
52
|
#
|
48
53
|
# @param [String] password must match the password specified in the
|
@@ -65,31 +70,57 @@ class Redis
|
|
65
70
|
end
|
66
71
|
end
|
67
72
|
|
68
|
-
#
|
73
|
+
# Ping the server.
|
69
74
|
#
|
70
|
-
# @
|
71
|
-
|
72
|
-
def info(cmd = nil)
|
75
|
+
# @return [String] `PONG`
|
76
|
+
def ping
|
73
77
|
synchronize do |client|
|
74
|
-
client.call [:
|
75
|
-
|
76
|
-
|
77
|
-
line.split(":", 2) unless line =~ /^(#|$)/
|
78
|
-
end]
|
78
|
+
client.call [:ping]
|
79
|
+
end
|
80
|
+
end
|
79
81
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
82
|
+
# Echo the given string.
|
83
|
+
#
|
84
|
+
# @param [String] value
|
85
|
+
# @return [String]
|
86
|
+
def echo(value)
|
87
|
+
synchronize do |client|
|
88
|
+
client.call [:echo, value]
|
89
|
+
end
|
90
|
+
end
|
87
91
|
|
88
|
-
|
92
|
+
# Close the connection.
|
93
|
+
#
|
94
|
+
# @return [String] `OK`
|
95
|
+
def quit
|
96
|
+
synchronize do |client|
|
97
|
+
begin
|
98
|
+
client.call [:quit]
|
99
|
+
rescue ConnectionError
|
100
|
+
ensure
|
101
|
+
client.disconnect
|
89
102
|
end
|
90
103
|
end
|
91
104
|
end
|
92
105
|
|
106
|
+
# Asynchronously rewrite the append-only file.
|
107
|
+
#
|
108
|
+
# @return [String] `OK`
|
109
|
+
def bgrewriteaof
|
110
|
+
synchronize do |client|
|
111
|
+
client.call [:bgrewriteaof]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Asynchronously save the dataset to disk.
|
116
|
+
#
|
117
|
+
# @return [String] `OK`
|
118
|
+
def bgsave
|
119
|
+
synchronize do |client|
|
120
|
+
client.call [:bgsave]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
93
124
|
# Get or set server configuration parameters.
|
94
125
|
#
|
95
126
|
# @param [String] action e.g. `get`, `set`, `resetstat`
|
@@ -107,12 +138,18 @@ class Redis
|
|
107
138
|
end
|
108
139
|
end
|
109
140
|
|
110
|
-
#
|
141
|
+
# Return the number of keys in the selected database.
|
111
142
|
#
|
112
|
-
# @return [
|
113
|
-
def
|
143
|
+
# @return [Fixnum]
|
144
|
+
def dbsize
|
114
145
|
synchronize do |client|
|
115
|
-
client.call [:
|
146
|
+
client.call [:dbsize]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def debug(*args)
|
151
|
+
synchronize do |client|
|
152
|
+
client.call [:debug, *args]
|
116
153
|
end
|
117
154
|
end
|
118
155
|
|
@@ -125,158 +162,219 @@ class Redis
|
|
125
162
|
end
|
126
163
|
end
|
127
164
|
|
128
|
-
#
|
165
|
+
# Remove all keys from the current database.
|
129
166
|
#
|
130
|
-
# @return [String]
|
131
|
-
def
|
167
|
+
# @return [String] `OK`
|
168
|
+
def flushdb
|
132
169
|
synchronize do |client|
|
133
|
-
client.call [:
|
170
|
+
client.call [:flushdb]
|
134
171
|
end
|
135
172
|
end
|
136
173
|
|
137
|
-
#
|
174
|
+
# Get information and statistics about the server.
|
138
175
|
#
|
139
|
-
# @
|
140
|
-
|
176
|
+
# @param [String, Symbol] cmd e.g. "commandstats"
|
177
|
+
# @return [Hash<String, String>]
|
178
|
+
def info(cmd = nil)
|
141
179
|
synchronize do |client|
|
142
|
-
client.call [:
|
180
|
+
client.call [:info, cmd].compact do |reply|
|
181
|
+
if reply.kind_of?(String)
|
182
|
+
reply = Hash[reply.split("\r\n").map do |line|
|
183
|
+
line.split(":", 2) unless line =~ /^(#|$)/
|
184
|
+
end]
|
185
|
+
|
186
|
+
if cmd && cmd.to_s == "commandstats"
|
187
|
+
# Extract nested hashes for INFO COMMANDSTATS
|
188
|
+
reply = Hash[reply.map do |k, v|
|
189
|
+
[k[/^cmdstat_(.*)$/, 1], Hash[*v.split(/,|=/)]]
|
190
|
+
end]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
reply
|
195
|
+
end
|
143
196
|
end
|
144
197
|
end
|
145
198
|
|
146
|
-
#
|
199
|
+
# Get the UNIX time stamp of the last successful save to disk.
|
147
200
|
#
|
148
|
-
# @return [
|
149
|
-
def
|
201
|
+
# @return [Fixnum]
|
202
|
+
def lastsave
|
150
203
|
synchronize do |client|
|
151
|
-
client.call [:
|
204
|
+
client.call [:lastsave]
|
152
205
|
end
|
153
206
|
end
|
154
207
|
|
155
|
-
#
|
208
|
+
# Listen for all requests received by the server in real time.
|
209
|
+
#
|
210
|
+
# There is no way to interrupt this command.
|
211
|
+
#
|
212
|
+
# @yield a block to be called for every line of output
|
213
|
+
# @yieldparam [String] line timestamp and command that was executed
|
214
|
+
def monitor(&block)
|
215
|
+
synchronize do |client|
|
216
|
+
client.call_loop([:monitor], &block)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# Synchronously save the dataset to disk.
|
156
221
|
#
|
157
|
-
# @param [String] key
|
158
222
|
# @return [String]
|
159
|
-
def
|
223
|
+
def save
|
160
224
|
synchronize do |client|
|
161
|
-
client.call [:
|
225
|
+
client.call [:save]
|
162
226
|
end
|
163
227
|
end
|
164
228
|
|
165
|
-
|
229
|
+
# Synchronously save the dataset to disk and then shut down the server.
|
230
|
+
def shutdown
|
231
|
+
synchronize do |client|
|
232
|
+
client.with_reconnect(false) do
|
233
|
+
begin
|
234
|
+
client.call [:shutdown]
|
235
|
+
rescue ConnectionError
|
236
|
+
# This means Redis has probably exited.
|
237
|
+
nil
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
166
242
|
|
167
|
-
#
|
168
|
-
|
169
|
-
# @param [String] key
|
170
|
-
# @param [Fixnum] offset bit offset
|
171
|
-
# @return [Fixnum] `0` or `1`
|
172
|
-
def getbit(key, offset)
|
243
|
+
# Make the server a slave of another instance, or promote it as master.
|
244
|
+
def slaveof(host, port)
|
173
245
|
synchronize do |client|
|
174
|
-
client.call [:
|
246
|
+
client.call [:slaveof, host, port]
|
175
247
|
end
|
176
248
|
end
|
177
249
|
|
178
|
-
#
|
250
|
+
# Interact with the slowlog (get, len, reset)
|
179
251
|
#
|
180
|
-
# @param [String]
|
181
|
-
# @param [Fixnum]
|
182
|
-
# @
|
183
|
-
|
184
|
-
# @return [Fixnum] `0` or `1`
|
185
|
-
def getrange(key, start, stop)
|
252
|
+
# @param [String] subcommand e.g. `get`, `len`, `reset`
|
253
|
+
# @param [Fixnum] length maximum number of entries to return
|
254
|
+
# @return [Array<String>, Fixnum, String] depends on subcommand
|
255
|
+
def slowlog(subcommand, length=nil)
|
186
256
|
synchronize do |client|
|
187
|
-
|
257
|
+
args = [:slowlog, subcommand]
|
258
|
+
args << length if length
|
259
|
+
client.call args
|
188
260
|
end
|
189
261
|
end
|
190
262
|
|
191
|
-
#
|
192
|
-
|
193
|
-
# @param [String] key
|
194
|
-
# @param [String] value value to replace the current value with
|
195
|
-
# @return [String] the old value stored in the key, or `nil` if the key
|
196
|
-
# did not exist
|
197
|
-
def getset(key, value)
|
263
|
+
# Internal command used for replication.
|
264
|
+
def sync
|
198
265
|
synchronize do |client|
|
199
|
-
client.call [:
|
266
|
+
client.call [:sync]
|
200
267
|
end
|
201
268
|
end
|
202
269
|
|
203
|
-
#
|
270
|
+
# Return the server time.
|
204
271
|
#
|
205
272
|
# @example
|
206
|
-
#
|
207
|
-
# # => ["v1", "v2"]
|
208
|
-
#
|
209
|
-
# @param [Array<String>] keys
|
210
|
-
# @return [Array<String>] an array of values for the specified keys
|
273
|
+
# r.time # => [ 1333093196, 606806 ]
|
211
274
|
#
|
212
|
-
# @
|
213
|
-
|
275
|
+
# @return [Array<Fixnum>] tuple of seconds since UNIX epoch and
|
276
|
+
# microseconds in the current second
|
277
|
+
def time
|
214
278
|
synchronize do |client|
|
215
|
-
client.call [:
|
279
|
+
client.call [:time] do |reply|
|
280
|
+
reply.map(&:to_i) if reply
|
281
|
+
end
|
216
282
|
end
|
217
283
|
end
|
218
284
|
|
219
|
-
#
|
285
|
+
# Remove the expiration from a key.
|
220
286
|
#
|
221
287
|
# @param [String] key
|
222
|
-
# @
|
223
|
-
|
224
|
-
def append(key, value)
|
288
|
+
# @return [Boolean] whether the timeout was removed or not
|
289
|
+
def persist(key)
|
225
290
|
synchronize do |client|
|
226
|
-
client.call [:
|
291
|
+
client.call [:persist, key], &_boolify
|
227
292
|
end
|
228
293
|
end
|
229
294
|
|
230
|
-
#
|
295
|
+
# Set a key's time to live in seconds.
|
231
296
|
#
|
232
297
|
# @param [String] key
|
233
|
-
# @
|
234
|
-
#
|
235
|
-
def
|
298
|
+
# @param [Fixnum] seconds time to live
|
299
|
+
# @return [Boolean] whether the timeout was set or not
|
300
|
+
def expire(key, seconds)
|
236
301
|
synchronize do |client|
|
237
|
-
client.call [:
|
302
|
+
client.call [:expire, key, seconds], &_boolify
|
238
303
|
end
|
239
304
|
end
|
240
305
|
|
241
|
-
#
|
306
|
+
# Set the expiration for a key as a UNIX timestamp.
|
242
307
|
#
|
243
308
|
# @param [String] key
|
244
|
-
# @
|
245
|
-
|
309
|
+
# @param [Fixnum] unix_time expiry time specified as a UNIX timestamp
|
310
|
+
# @return [Boolean] whether the timeout was set or not
|
311
|
+
def expireat(key, unix_time)
|
246
312
|
synchronize do |client|
|
247
|
-
client.call [:
|
313
|
+
client.call [:expireat, key, unix_time], &_boolify
|
248
314
|
end
|
249
315
|
end
|
250
316
|
|
251
|
-
# Get the
|
317
|
+
# Get the time to live (in seconds) for a key.
|
252
318
|
#
|
253
319
|
# @param [String] key
|
254
|
-
# @
|
255
|
-
#
|
256
|
-
def
|
320
|
+
# @return [Fixnum] remaining time to live in seconds, or -1 if the
|
321
|
+
# key does not exist or does not have a timeout
|
322
|
+
def ttl(key)
|
257
323
|
synchronize do |client|
|
258
|
-
client.call [:
|
324
|
+
client.call [:ttl, key]
|
259
325
|
end
|
260
326
|
end
|
261
327
|
|
262
|
-
#
|
328
|
+
# Set a key's time to live in milliseconds.
|
263
329
|
#
|
264
330
|
# @param [String] key
|
265
|
-
# @param [
|
266
|
-
# @return [
|
267
|
-
def
|
331
|
+
# @param [Fixnum] milliseconds time to live
|
332
|
+
# @return [Boolean] whether the timeout was set or not
|
333
|
+
def pexpire(key, milliseconds)
|
268
334
|
synchronize do |client|
|
269
|
-
client.call [:
|
335
|
+
client.call [:pexpire, key, milliseconds], &_boolify
|
270
336
|
end
|
271
337
|
end
|
272
338
|
|
273
|
-
#
|
339
|
+
# Set the expiration for a key as number of milliseconds from UNIX Epoch.
|
274
340
|
#
|
275
341
|
# @param [String] key
|
276
|
-
# @
|
277
|
-
|
342
|
+
# @param [Fixnum] ms_unix_time expiry time specified as number of milliseconds from UNIX Epoch.
|
343
|
+
# @return [Boolean] whether the timeout was set or not
|
344
|
+
def pexpireat(key, ms_unix_time)
|
278
345
|
synchronize do |client|
|
279
|
-
client.call [:
|
346
|
+
client.call [:pexpireat, key, ms_unix_time], &_boolify
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
# Get the time to live (in milliseconds) for a key.
|
351
|
+
#
|
352
|
+
# @param [String] key
|
353
|
+
# @return [Fixnum] remaining time to live in milliseconds, or -1 if the
|
354
|
+
# key does not exist or does not have a timeout
|
355
|
+
def pttl(key)
|
356
|
+
synchronize do |client|
|
357
|
+
client.call [:pttl, key]
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
# Delete one or more keys.
|
362
|
+
#
|
363
|
+
# @param [String, Array<String>] keys
|
364
|
+
# @return [Fixnum] number of keys that were deleted
|
365
|
+
def del(*keys)
|
366
|
+
synchronize do |client|
|
367
|
+
client.call [:del, *keys]
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
# Determine if a key exists.
|
372
|
+
#
|
373
|
+
# @param [String] key
|
374
|
+
# @return [Boolean]
|
375
|
+
def exists(key)
|
376
|
+
synchronize do |client|
|
377
|
+
client.call [:exists, key], &_boolify
|
280
378
|
end
|
281
379
|
end
|
282
380
|
|
@@ -296,1390 +394,1396 @@ class Redis
|
|
296
394
|
end
|
297
395
|
end
|
298
396
|
|
299
|
-
#
|
397
|
+
# Move a key to another database.
|
300
398
|
#
|
301
|
-
# @
|
302
|
-
|
399
|
+
# @example Move a key to another database
|
400
|
+
# redis.set "foo", "bar"
|
401
|
+
# # => "OK"
|
402
|
+
# redis.move "foo", 2
|
403
|
+
# # => true
|
404
|
+
# redis.exists "foo"
|
405
|
+
# # => false
|
406
|
+
# redis.select 2
|
407
|
+
# # => "OK"
|
408
|
+
# redis.exists "foo"
|
409
|
+
# # => true
|
410
|
+
# resis.get "foo"
|
411
|
+
# # => "bar"
|
412
|
+
#
|
413
|
+
# @param [String] key
|
414
|
+
# @param [Fixnum] db
|
415
|
+
# @return [Boolean] whether the key was moved or not
|
416
|
+
def move(key, db)
|
303
417
|
synchronize do |client|
|
304
|
-
client.call [:
|
418
|
+
client.call [:move, key, db], &_boolify
|
305
419
|
end
|
306
420
|
end
|
307
421
|
|
308
|
-
|
422
|
+
def object(*args)
|
423
|
+
synchronize do |client|
|
424
|
+
client.call [:object, *args]
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
# Return a random key from the keyspace.
|
309
429
|
#
|
310
|
-
# @param [String] value
|
311
430
|
# @return [String]
|
312
|
-
def
|
431
|
+
def randomkey
|
313
432
|
synchronize do |client|
|
314
|
-
client.call [:
|
433
|
+
client.call [:randomkey]
|
315
434
|
end
|
316
435
|
end
|
317
436
|
|
318
|
-
#
|
319
|
-
#
|
320
|
-
# @example
|
321
|
-
# r.time # => [ 1333093196, 606806 ]
|
437
|
+
# Rename a key. If the new key already exists it is overwritten.
|
322
438
|
#
|
323
|
-
# @
|
324
|
-
#
|
325
|
-
|
439
|
+
# @param [String] old_name
|
440
|
+
# @param [String] new_name
|
441
|
+
# @return [String] `OK`
|
442
|
+
def rename(old_name, new_name)
|
326
443
|
synchronize do |client|
|
327
|
-
client.call [:
|
328
|
-
reply.map(&:to_i) if reply
|
329
|
-
end
|
444
|
+
client.call [:rename, old_name, new_name]
|
330
445
|
end
|
331
446
|
end
|
332
447
|
|
333
|
-
#
|
448
|
+
# Rename a key, only if the new key does not exist.
|
334
449
|
#
|
335
|
-
# @
|
336
|
-
|
450
|
+
# @param [String] old_name
|
451
|
+
# @param [String] new_name
|
452
|
+
# @return [Boolean] whether the key was renamed or not
|
453
|
+
def renamenx(old_name, new_name)
|
337
454
|
synchronize do |client|
|
338
|
-
client.call [:
|
455
|
+
client.call [:renamenx, old_name, new_name], &_boolify
|
339
456
|
end
|
340
457
|
end
|
341
458
|
|
342
|
-
#
|
459
|
+
# Sort the elements in a list, set or sorted set.
|
343
460
|
#
|
344
|
-
# @
|
345
|
-
|
461
|
+
# @example Retrieve the first 2 elements from an alphabetically sorted "list"
|
462
|
+
# redis.sort("list", :order => "alpha", :limit => [0, 2])
|
463
|
+
# # => ["a", "b"]
|
464
|
+
# @example Store an alphabetically descending list in "target"
|
465
|
+
# redis.sort("list", :order => "desc alpha", :store => "target")
|
466
|
+
# # => 26
|
467
|
+
#
|
468
|
+
# @param [String] key
|
469
|
+
# @param [Hash] options
|
470
|
+
# - `:by => String`: use external key to sort elements by
|
471
|
+
# - `:limit => [offset, count]`: skip `offset` elements, return a maximum
|
472
|
+
# of `count` elements
|
473
|
+
# - `:get => [String, Array<String>]`: single key or array of keys to
|
474
|
+
# retrieve per element in the result
|
475
|
+
# - `:order => String`: combination of `ASC`, `DESC` and optionally `ALPHA`
|
476
|
+
# - `:store => String`: key to store the result at
|
477
|
+
#
|
478
|
+
# @return [Array<String>, Array<Array<String>>, Fixnum]
|
479
|
+
# - when `:get` is not specified, or holds a single element, an array of elements
|
480
|
+
# - when `:get` is specified, and holds more than one element, an array of
|
481
|
+
# elements where every element is an array with the result for every
|
482
|
+
# element specified in `:get`
|
483
|
+
# - when `:store` is specified, the number of elements in the stored result
|
484
|
+
def sort(key, options = {})
|
485
|
+
args = []
|
486
|
+
|
487
|
+
by = options[:by]
|
488
|
+
args.concat ["BY", by] if by
|
489
|
+
|
490
|
+
limit = options[:limit]
|
491
|
+
args.concat ["LIMIT", *limit] if limit
|
492
|
+
|
493
|
+
get = Array(options[:get])
|
494
|
+
args.concat ["GET"].product(get).flatten unless get.empty?
|
495
|
+
|
496
|
+
order = options[:order]
|
497
|
+
args.concat order.split(" ") if order
|
498
|
+
|
499
|
+
store = options[:store]
|
500
|
+
args.concat ["STORE", store] if store
|
501
|
+
|
346
502
|
synchronize do |client|
|
347
|
-
client.call [:
|
503
|
+
client.call [:sort, key, *args] do |reply|
|
504
|
+
if get.size > 1
|
505
|
+
if reply
|
506
|
+
reply.each_slice(get.size).to_a
|
507
|
+
end
|
508
|
+
else
|
509
|
+
reply
|
510
|
+
end
|
511
|
+
end
|
348
512
|
end
|
349
513
|
end
|
350
514
|
|
351
|
-
#
|
515
|
+
# Determine the type stored at key.
|
352
516
|
#
|
353
|
-
# @
|
354
|
-
|
517
|
+
# @param [String] key
|
518
|
+
# @return [String] `string`, `list`, `set`, `zset`, `hash` or `none`
|
519
|
+
def type(key)
|
355
520
|
synchronize do |client|
|
356
|
-
client.call [:
|
521
|
+
client.call [:type, key]
|
357
522
|
end
|
358
523
|
end
|
359
524
|
|
360
|
-
#
|
525
|
+
# Decrement the integer value of a key by one.
|
526
|
+
#
|
527
|
+
# @example
|
528
|
+
# redis.decr("value")
|
529
|
+
# # => 4
|
361
530
|
#
|
362
531
|
# @param [String] key
|
363
|
-
# @return [
|
364
|
-
def
|
532
|
+
# @return [Fixnum] value after decrementing it
|
533
|
+
def decr(key)
|
365
534
|
synchronize do |client|
|
366
|
-
client.call [:
|
535
|
+
client.call [:decr, key]
|
367
536
|
end
|
368
537
|
end
|
369
538
|
|
370
|
-
#
|
539
|
+
# Decrement the integer value of a key by the given number.
|
540
|
+
#
|
541
|
+
# @example
|
542
|
+
# redis.decrby("value", 5)
|
543
|
+
# # => 0
|
371
544
|
#
|
372
545
|
# @param [String] key
|
373
|
-
# @
|
374
|
-
|
546
|
+
# @param [Fixnum] decrement
|
547
|
+
# @return [Fixnum] value after decrementing it
|
548
|
+
def decrby(key, decrement)
|
375
549
|
synchronize do |client|
|
376
|
-
client.call [:
|
550
|
+
client.call [:decrby, key, decrement]
|
377
551
|
end
|
378
552
|
end
|
379
553
|
|
380
|
-
#
|
554
|
+
# Increment the integer value of a key by one.
|
555
|
+
#
|
556
|
+
# @example
|
557
|
+
# redis.incr("value")
|
558
|
+
# # => 6
|
381
559
|
#
|
382
560
|
# @param [String] key
|
383
|
-
# @
|
384
|
-
|
385
|
-
# @return [Array<String>]
|
386
|
-
def lrange(key, start, stop)
|
561
|
+
# @return [Fixnum] value after incrementing it
|
562
|
+
def incr(key)
|
387
563
|
synchronize do |client|
|
388
|
-
client.call [:
|
564
|
+
client.call [:incr, key]
|
389
565
|
end
|
390
566
|
end
|
391
567
|
|
392
|
-
#
|
568
|
+
# Increment the integer value of a key by the given integer number.
|
569
|
+
#
|
570
|
+
# @example
|
571
|
+
# redis.incrby("value", 5)
|
572
|
+
# # => 10
|
393
573
|
#
|
394
574
|
# @param [String] key
|
395
|
-
# @param [Fixnum]
|
396
|
-
# @
|
397
|
-
|
398
|
-
def ltrim(key, start, stop)
|
575
|
+
# @param [Fixnum] increment
|
576
|
+
# @return [Fixnum] value after incrementing it
|
577
|
+
def incrby(key, increment)
|
399
578
|
synchronize do |client|
|
400
|
-
client.call [:
|
579
|
+
client.call [:incrby, key, increment]
|
401
580
|
end
|
402
581
|
end
|
403
582
|
|
404
|
-
#
|
583
|
+
# Increment the numeric value of a key by the given float number.
|
584
|
+
#
|
585
|
+
# @example
|
586
|
+
# redis.incrbyfloat("value", 1.23)
|
587
|
+
# # => 1.23
|
405
588
|
#
|
406
589
|
# @param [String] key
|
407
|
-
# @param [
|
408
|
-
# @return [
|
409
|
-
def
|
590
|
+
# @param [Float] increment
|
591
|
+
# @return [Float] value after incrementing it
|
592
|
+
def incrbyfloat(key, increment)
|
410
593
|
synchronize do |client|
|
411
|
-
client.call [:
|
594
|
+
client.call [:incrbyfloat, key, increment] do |reply|
|
595
|
+
Float(reply) if reply
|
596
|
+
end
|
412
597
|
end
|
413
598
|
end
|
414
599
|
|
415
|
-
#
|
600
|
+
# Set the string value of a key.
|
416
601
|
#
|
417
602
|
# @param [String] key
|
418
|
-
# @param [String, Symbol] where `BEFORE` or `AFTER`
|
419
|
-
# @param [String] pivot reference element
|
420
603
|
# @param [String] value
|
421
|
-
# @return
|
422
|
-
|
423
|
-
def linsert(key, where, pivot, value)
|
604
|
+
# @return `"OK"`
|
605
|
+
def set(key, value)
|
424
606
|
synchronize do |client|
|
425
|
-
client.call [:
|
607
|
+
client.call [:set, key, value]
|
426
608
|
end
|
427
609
|
end
|
428
610
|
|
429
|
-
|
611
|
+
alias :[]= :set
|
612
|
+
|
613
|
+
# Set the time to live in seconds of a key.
|
430
614
|
#
|
431
615
|
# @param [String] key
|
432
|
-
# @param [Fixnum]
|
616
|
+
# @param [Fixnum] ttl
|
433
617
|
# @param [String] value
|
434
|
-
# @return
|
435
|
-
def
|
618
|
+
# @return `"OK"`
|
619
|
+
def setex(key, ttl, value)
|
436
620
|
synchronize do |client|
|
437
|
-
client.call [:
|
621
|
+
client.call [:setex, key, ttl, value]
|
438
622
|
end
|
439
623
|
end
|
440
624
|
|
441
|
-
#
|
625
|
+
# Set the time to live in milliseconds of a key.
|
442
626
|
#
|
443
627
|
# @param [String] key
|
444
|
-
# @param [Fixnum]
|
445
|
-
# value to remove the first `count` occurrences of `value`. A negative
|
446
|
-
# value to remove the last `count` occurrences of `value`. Or zero, to
|
447
|
-
# remove all occurrences of `value` from the list.
|
628
|
+
# @param [Fixnum] ttl
|
448
629
|
# @param [String] value
|
449
|
-
# @return
|
450
|
-
def
|
630
|
+
# @return `"OK"`
|
631
|
+
def psetex(key, ttl, value)
|
451
632
|
synchronize do |client|
|
452
|
-
client.call [:
|
633
|
+
client.call [:psetex, key, ttl, value]
|
453
634
|
end
|
454
635
|
end
|
455
636
|
|
456
|
-
#
|
637
|
+
# Set the value of a key, only if the key does not exist.
|
457
638
|
#
|
458
639
|
# @param [String] key
|
459
640
|
# @param [String] value
|
460
|
-
# @return [
|
461
|
-
def
|
641
|
+
# @return [Boolean] whether the key was set or not
|
642
|
+
def setnx(key, value)
|
462
643
|
synchronize do |client|
|
463
|
-
client.call [:
|
644
|
+
client.call [:setnx, key, value], &_boolify
|
464
645
|
end
|
465
646
|
end
|
466
647
|
|
467
|
-
#
|
648
|
+
# Set one or more values.
|
468
649
|
#
|
469
|
-
# @
|
470
|
-
#
|
471
|
-
#
|
472
|
-
|
650
|
+
# @example
|
651
|
+
# redis.mset("key1", "v1", "key2", "v2")
|
652
|
+
# # => "OK"
|
653
|
+
#
|
654
|
+
# @param [Array<String>] args array of keys and values
|
655
|
+
# @return `"OK"`
|
656
|
+
#
|
657
|
+
# @see #mapped_mset
|
658
|
+
def mset(*args)
|
473
659
|
synchronize do |client|
|
474
|
-
client.call [:
|
660
|
+
client.call [:mset, *args]
|
475
661
|
end
|
476
662
|
end
|
477
663
|
|
478
|
-
#
|
664
|
+
# Set one or more values.
|
479
665
|
#
|
480
|
-
# @
|
481
|
-
#
|
482
|
-
#
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
666
|
+
# @example
|
667
|
+
# redis.mapped_mset({ "f1" => "v1", "f2" => "v2" })
|
668
|
+
# # => "OK"
|
669
|
+
#
|
670
|
+
# @param [Hash] hash keys mapping to values
|
671
|
+
# @return `"OK"`
|
672
|
+
#
|
673
|
+
# @see #mset
|
674
|
+
def mapped_mset(hash)
|
675
|
+
mset(*hash.to_a.flatten)
|
487
676
|
end
|
488
677
|
|
489
|
-
#
|
678
|
+
# Set one or more values, only if none of the keys exist.
|
490
679
|
#
|
491
|
-
# @
|
492
|
-
#
|
493
|
-
#
|
494
|
-
|
680
|
+
# @example
|
681
|
+
# redis.msetnx("key1", "v1", "key2", "v2")
|
682
|
+
# # => true
|
683
|
+
#
|
684
|
+
# @param [Array<String>] args array of keys and values
|
685
|
+
# @return [Boolean] whether or not all values were set
|
686
|
+
#
|
687
|
+
# @see #mapped_msetnx
|
688
|
+
def msetnx(*args)
|
495
689
|
synchronize do |client|
|
496
|
-
client.call [:
|
690
|
+
client.call [:msetnx, *args], &_boolify
|
497
691
|
end
|
498
692
|
end
|
499
693
|
|
500
|
-
#
|
694
|
+
# Set one or more values, only if none of the keys exist.
|
695
|
+
#
|
696
|
+
# @example
|
697
|
+
# redis.msetnx({ "key1" => "v1", "key2" => "v2" })
|
698
|
+
# # => true
|
699
|
+
#
|
700
|
+
# @param [Hash] hash keys mapping to values
|
701
|
+
# @return [Boolean] whether or not all values were set
|
702
|
+
#
|
703
|
+
# @see #msetnx
|
704
|
+
def mapped_msetnx(hash)
|
705
|
+
msetnx(*hash.to_a.flatten)
|
706
|
+
end
|
707
|
+
|
708
|
+
# Get the value of a key.
|
501
709
|
#
|
502
710
|
# @param [String] key
|
503
711
|
# @return [String]
|
504
|
-
def
|
712
|
+
def get(key)
|
505
713
|
synchronize do |client|
|
506
|
-
client.call [:
|
714
|
+
client.call [:get, key]
|
507
715
|
end
|
508
716
|
end
|
509
717
|
|
510
|
-
|
511
|
-
options = {}
|
512
|
-
|
513
|
-
case args.last
|
514
|
-
when Hash
|
515
|
-
options = args.pop
|
516
|
-
when Integer
|
517
|
-
# Issue deprecation notice in obnoxious mode...
|
518
|
-
options[:timeout] = args.pop
|
519
|
-
end
|
520
|
-
|
521
|
-
if args.size > 1
|
522
|
-
# Issue deprecation notice in obnoxious mode...
|
523
|
-
end
|
524
|
-
|
525
|
-
keys = args.flatten
|
526
|
-
timeout = options[:timeout] || 0
|
527
|
-
|
528
|
-
synchronize do |client|
|
529
|
-
client.call_without_timeout [cmd, keys, timeout]
|
530
|
-
end
|
531
|
-
end
|
718
|
+
alias :[] :get
|
532
719
|
|
533
|
-
#
|
720
|
+
# Get the values of all the given keys.
|
534
721
|
#
|
535
|
-
# @example
|
536
|
-
#
|
537
|
-
# # =>
|
538
|
-
# # => ["list", "element"] on success
|
539
|
-
# @example Without timeout
|
540
|
-
# list, element = redis.blpop("list")
|
541
|
-
# # => ["list", "element"]
|
542
|
-
# @example Blocking pop on multiple lists
|
543
|
-
# list, element = redis.blpop(["list", "another_list"])
|
544
|
-
# # => ["list", "element"]
|
722
|
+
# @example
|
723
|
+
# redis.mget("key1", "key1")
|
724
|
+
# # => ["v1", "v2"]
|
545
725
|
#
|
546
|
-
# @param [
|
547
|
-
#
|
548
|
-
# @param [Hash] options
|
549
|
-
# - `:timeout => Fixnum`: timeout in seconds, defaults to no timeout
|
726
|
+
# @param [Array<String>] keys
|
727
|
+
# @return [Array<String>] an array of values for the specified keys
|
550
728
|
#
|
551
|
-
# @
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
729
|
+
# @see #mapped_mget
|
730
|
+
def mget(*keys, &blk)
|
731
|
+
synchronize do |client|
|
732
|
+
client.call [:mget, *keys], &blk
|
733
|
+
end
|
556
734
|
end
|
557
735
|
|
558
|
-
#
|
736
|
+
# Get the values of all the given keys.
|
559
737
|
#
|
560
|
-
# @
|
561
|
-
#
|
562
|
-
#
|
563
|
-
# - `:timeout => Fixnum`: timeout in seconds, defaults to no timeout
|
738
|
+
# @example
|
739
|
+
# redis.mapped_mget("key1", "key1")
|
740
|
+
# # => { "key1" => "v1", "key2" => "v2" }
|
564
741
|
#
|
565
|
-
# @
|
566
|
-
#
|
567
|
-
# - tuple of the list that was popped from and element was popped otherwise
|
742
|
+
# @param [Array<String>] keys array of keys
|
743
|
+
# @return [Hash] a hash mapping the specified keys to their values
|
568
744
|
#
|
569
|
-
# @see #
|
570
|
-
def
|
571
|
-
|
745
|
+
# @see #mget
|
746
|
+
def mapped_mget(*keys)
|
747
|
+
mget(*keys) do |reply|
|
748
|
+
if reply.kind_of?(Array)
|
749
|
+
hash = Hash.new
|
750
|
+
keys.zip(reply).each do |field, value|
|
751
|
+
hash[field] = value
|
752
|
+
end
|
753
|
+
hash
|
754
|
+
else
|
755
|
+
reply
|
756
|
+
end
|
757
|
+
end
|
572
758
|
end
|
573
759
|
|
574
|
-
#
|
575
|
-
# until one is available.
|
576
|
-
#
|
577
|
-
# @param [String] source source key
|
578
|
-
# @param [String] destination destination key
|
579
|
-
# @param [Hash] options
|
580
|
-
# - `:timeout => Fixnum`: timeout in seconds, defaults to no timeout
|
760
|
+
# Overwrite part of a string at key starting at the specified offset.
|
581
761
|
#
|
582
|
-
# @
|
583
|
-
#
|
584
|
-
#
|
585
|
-
|
586
|
-
|
587
|
-
when Integer
|
588
|
-
# Issue deprecation notice in obnoxious mode...
|
589
|
-
options = { :timeout => options }
|
590
|
-
end
|
591
|
-
|
592
|
-
timeout = options[:timeout] || 0
|
593
|
-
|
762
|
+
# @param [String] key
|
763
|
+
# @param [Fixnum] offset byte offset
|
764
|
+
# @param [String] value
|
765
|
+
# @return [Fixnum] length of the string after it was modified
|
766
|
+
def setrange(key, offset, value)
|
594
767
|
synchronize do |client|
|
595
|
-
client.
|
768
|
+
client.call [:setrange, key, offset, value]
|
596
769
|
end
|
597
770
|
end
|
598
771
|
|
599
|
-
#
|
772
|
+
# Get a substring of the string stored at a key.
|
600
773
|
#
|
601
|
-
# @param [String]
|
602
|
-
# @param [
|
603
|
-
# @
|
604
|
-
|
774
|
+
# @param [String] key
|
775
|
+
# @param [Fixnum] start zero-based start offset
|
776
|
+
# @param [Fixnum] stop zero-based end offset. Use -1 for representing
|
777
|
+
# the end of the string
|
778
|
+
# @return [Fixnum] `0` or `1`
|
779
|
+
def getrange(key, start, stop)
|
605
780
|
synchronize do |client|
|
606
|
-
client.call [:
|
781
|
+
client.call [:getrange, key, start, stop]
|
607
782
|
end
|
608
783
|
end
|
609
784
|
|
610
|
-
#
|
785
|
+
# Sets or clears the bit at offset in the string value stored at key.
|
611
786
|
#
|
612
787
|
# @param [String] key
|
613
|
-
# @
|
614
|
-
|
788
|
+
# @param [Fixnum] offset bit offset
|
789
|
+
# @param [Fixnum] value bit value `0` or `1`
|
790
|
+
# @return [Fixnum] the original bit value stored at `offset`
|
791
|
+
def setbit(key, offset, value)
|
615
792
|
synchronize do |client|
|
616
|
-
client.call [:
|
793
|
+
client.call [:setbit, key, offset, value]
|
617
794
|
end
|
618
795
|
end
|
619
796
|
|
620
|
-
#
|
797
|
+
# Returns the bit value at offset in the string value stored at key.
|
621
798
|
#
|
622
|
-
# @param [String]
|
623
|
-
# @param [Fixnum]
|
624
|
-
# @return [
|
625
|
-
def
|
799
|
+
# @param [String] key
|
800
|
+
# @param [Fixnum] offset bit offset
|
801
|
+
# @return [Fixnum] `0` or `1`
|
802
|
+
def getbit(key, offset)
|
626
803
|
synchronize do |client|
|
627
|
-
|
628
|
-
args << length if length
|
629
|
-
client.call args
|
804
|
+
client.call [:getbit, key, offset]
|
630
805
|
end
|
631
806
|
end
|
632
807
|
|
633
|
-
#
|
808
|
+
# Append a value to a key.
|
634
809
|
#
|
635
810
|
# @param [String] key
|
636
|
-
# @
|
637
|
-
|
811
|
+
# @param [String] value value to append
|
812
|
+
# @return [Fixnum] length of the string after appending
|
813
|
+
def append(key, value)
|
638
814
|
synchronize do |client|
|
639
|
-
client.call [:
|
815
|
+
client.call [:append, key, value]
|
640
816
|
end
|
641
817
|
end
|
642
818
|
|
643
|
-
#
|
819
|
+
# Set the string value of a key and return its old value.
|
644
820
|
#
|
645
821
|
# @param [String] key
|
646
|
-
# @param [String]
|
647
|
-
# @return [
|
648
|
-
|
822
|
+
# @param [String] value value to replace the current value with
|
823
|
+
# @return [String] the old value stored in the key, or `nil` if the key
|
824
|
+
# did not exist
|
825
|
+
def getset(key, value)
|
649
826
|
synchronize do |client|
|
650
|
-
client.call [:
|
827
|
+
client.call [:getset, key, value]
|
651
828
|
end
|
652
829
|
end
|
653
830
|
|
654
|
-
#
|
831
|
+
# Get the length of the value stored in a key.
|
655
832
|
#
|
656
833
|
# @param [String] key
|
657
|
-
# @
|
658
|
-
#
|
659
|
-
|
660
|
-
# array of members is specified, holding the number of members that were
|
661
|
-
# successfully added
|
662
|
-
def sadd(key, member)
|
834
|
+
# @return [Fixnum] the length of the value stored in the key, or 0
|
835
|
+
# if the key does not exist
|
836
|
+
def strlen(key)
|
663
837
|
synchronize do |client|
|
664
|
-
client.call [:
|
665
|
-
if member.is_a? Array
|
666
|
-
# Variadic: return integer
|
667
|
-
reply
|
668
|
-
else
|
669
|
-
# Single argument: return boolean
|
670
|
-
_boolify.call(reply)
|
671
|
-
end
|
672
|
-
end
|
838
|
+
client.call [:strlen, key]
|
673
839
|
end
|
674
840
|
end
|
675
841
|
|
676
|
-
#
|
842
|
+
# Get the length of a list.
|
677
843
|
#
|
678
844
|
# @param [String] key
|
679
|
-
# @
|
680
|
-
|
681
|
-
# holding whether or not removing the member succeeded, or `Fixnum` when an
|
682
|
-
# array of members is specified, holding the number of members that were
|
683
|
-
# successfully removed
|
684
|
-
def srem(key, member)
|
845
|
+
# @return [Fixnum]
|
846
|
+
def llen(key)
|
685
847
|
synchronize do |client|
|
686
|
-
client.call [:
|
687
|
-
if member.is_a? Array
|
688
|
-
# Variadic: return integer
|
689
|
-
reply
|
690
|
-
else
|
691
|
-
# Single argument: return boolean
|
692
|
-
_boolify.call(reply)
|
693
|
-
end
|
694
|
-
end
|
848
|
+
client.call [:llen, key]
|
695
849
|
end
|
696
850
|
end
|
697
851
|
|
698
|
-
#
|
852
|
+
# Prepend one or more values to a list, creating the list if it doesn't exist
|
699
853
|
#
|
700
|
-
# @param [String]
|
701
|
-
# @param [String]
|
702
|
-
# @
|
703
|
-
|
704
|
-
def smove(source, destination, member)
|
854
|
+
# @param [String] key
|
855
|
+
# @param [String] value
|
856
|
+
# @return [Fixnum] the length of the list after the push operation
|
857
|
+
def lpush(key, value)
|
705
858
|
synchronize do |client|
|
706
|
-
client.call [:
|
859
|
+
client.call [:lpush, key, value]
|
707
860
|
end
|
708
861
|
end
|
709
862
|
|
710
|
-
#
|
863
|
+
# Prepend a value to a list, only if the list exists.
|
711
864
|
#
|
712
865
|
# @param [String] key
|
713
|
-
# @
|
714
|
-
|
866
|
+
# @param [String] value
|
867
|
+
# @return [Fixnum] the length of the list after the push operation
|
868
|
+
def lpushx(key, value)
|
715
869
|
synchronize do |client|
|
716
|
-
client.call [:
|
870
|
+
client.call [:lpushx, key, value]
|
717
871
|
end
|
718
872
|
end
|
719
873
|
|
720
|
-
#
|
874
|
+
# Append one or more values to a list, creating the list if it doesn't exist
|
721
875
|
#
|
722
876
|
# @param [String] key
|
723
|
-
# @
|
724
|
-
|
877
|
+
# @param [String] value
|
878
|
+
# @return [Fixnum] the length of the list after the push operation
|
879
|
+
def rpush(key, value)
|
725
880
|
synchronize do |client|
|
726
|
-
client.call [:
|
881
|
+
client.call [:rpush, key, value]
|
727
882
|
end
|
728
883
|
end
|
729
884
|
|
730
|
-
#
|
885
|
+
# Append a value to a list, only if the list exists.
|
731
886
|
#
|
732
|
-
# @param [String
|
733
|
-
# @
|
734
|
-
|
887
|
+
# @param [String] key
|
888
|
+
# @param [String] value
|
889
|
+
# @return [Fixnum] the length of the list after the push operation
|
890
|
+
def rpushx(key, value)
|
735
891
|
synchronize do |client|
|
736
|
-
client.call [:
|
892
|
+
client.call [:rpushx, key, value]
|
737
893
|
end
|
738
894
|
end
|
739
895
|
|
740
|
-
#
|
896
|
+
# Remove and get the first element in a list.
|
741
897
|
#
|
742
|
-
# @param [String]
|
743
|
-
# @
|
744
|
-
|
745
|
-
def sinterstore(destination, *keys)
|
898
|
+
# @param [String] key
|
899
|
+
# @return [String]
|
900
|
+
def lpop(key)
|
746
901
|
synchronize do |client|
|
747
|
-
client.call [:
|
902
|
+
client.call [:lpop, key]
|
748
903
|
end
|
749
904
|
end
|
750
905
|
|
751
|
-
#
|
906
|
+
# Remove and get the last element in a list.
|
752
907
|
#
|
753
|
-
# @param [String
|
754
|
-
# @return [
|
755
|
-
def
|
908
|
+
# @param [String] key
|
909
|
+
# @return [String]
|
910
|
+
def rpop(key)
|
756
911
|
synchronize do |client|
|
757
|
-
client.call [:
|
912
|
+
client.call [:rpop, key]
|
758
913
|
end
|
759
914
|
end
|
760
915
|
|
761
|
-
#
|
916
|
+
# Remove the last element in a list, append it to another list and return it.
|
762
917
|
#
|
918
|
+
# @param [String] source source key
|
763
919
|
# @param [String] destination destination key
|
764
|
-
# @
|
765
|
-
|
766
|
-
def sunionstore(destination, *keys)
|
920
|
+
# @return [nil, String] the element, or nil when the source key does not exist
|
921
|
+
def rpoplpush(source, destination)
|
767
922
|
synchronize do |client|
|
768
|
-
client.call [:
|
923
|
+
client.call [:rpoplpush, source, destination]
|
769
924
|
end
|
770
925
|
end
|
771
926
|
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
927
|
+
def _bpop(cmd, args)
|
928
|
+
options = {}
|
929
|
+
|
930
|
+
case args.last
|
931
|
+
when Hash
|
932
|
+
options = args.pop
|
933
|
+
when Integer
|
934
|
+
# Issue deprecation notice in obnoxious mode...
|
935
|
+
options[:timeout] = args.pop
|
936
|
+
end
|
937
|
+
|
938
|
+
if args.size > 1
|
939
|
+
# Issue deprecation notice in obnoxious mode...
|
940
|
+
end
|
941
|
+
|
942
|
+
keys = args.flatten
|
943
|
+
timeout = options[:timeout] || 0
|
944
|
+
|
777
945
|
synchronize do |client|
|
778
|
-
client.
|
946
|
+
client.call_without_timeout [cmd, keys, timeout]
|
779
947
|
end
|
780
948
|
end
|
781
949
|
|
782
|
-
#
|
950
|
+
# Remove and get the first element in a list, or block until one is available.
|
951
|
+
#
|
952
|
+
# @example With timeout
|
953
|
+
# list, element = redis.blpop("list", :timeout => 5)
|
954
|
+
# # => nil on timeout
|
955
|
+
# # => ["list", "element"] on success
|
956
|
+
# @example Without timeout
|
957
|
+
# list, element = redis.blpop("list")
|
958
|
+
# # => ["list", "element"]
|
959
|
+
# @example Blocking pop on multiple lists
|
960
|
+
# list, element = redis.blpop(["list", "another_list"])
|
961
|
+
# # => ["list", "element"]
|
962
|
+
#
|
963
|
+
# @param [String, Array<String>] keys one or more keys to perform the
|
964
|
+
# blocking pop on
|
965
|
+
# @param [Hash] options
|
966
|
+
# - `:timeout => Fixnum`: timeout in seconds, defaults to no timeout
|
967
|
+
#
|
968
|
+
# @return [nil, [String, String]]
|
969
|
+
# - `nil` when the operation timed out
|
970
|
+
# - tuple of the list that was popped from and element was popped otherwise
|
971
|
+
def blpop(*args)
|
972
|
+
_bpop(:blpop, args)
|
973
|
+
end
|
974
|
+
|
975
|
+
# Remove and get the last element in a list, or block until one is available.
|
976
|
+
#
|
977
|
+
# @param [String, Array<String>] keys one or more keys to perform the
|
978
|
+
# blocking pop on
|
979
|
+
# @param [Hash] options
|
980
|
+
# - `:timeout => Fixnum`: timeout in seconds, defaults to no timeout
|
981
|
+
#
|
982
|
+
# @return [nil, [String, String]]
|
983
|
+
# - `nil` when the operation timed out
|
984
|
+
# - tuple of the list that was popped from and element was popped otherwise
|
985
|
+
#
|
986
|
+
# @see #blpop
|
987
|
+
def brpop(*args)
|
988
|
+
_bpop(:brpop, args)
|
989
|
+
end
|
990
|
+
|
991
|
+
# Pop a value from a list, push it to another list and return it; or block
|
992
|
+
# until one is available.
|
783
993
|
#
|
994
|
+
# @param [String] source source key
|
784
995
|
# @param [String] destination destination key
|
785
|
-
# @param [
|
786
|
-
#
|
787
|
-
|
996
|
+
# @param [Hash] options
|
997
|
+
# - `:timeout => Fixnum`: timeout in seconds, defaults to no timeout
|
998
|
+
#
|
999
|
+
# @return [nil, String]
|
1000
|
+
# - `nil` when the operation timed out
|
1001
|
+
# - the element was popped and pushed otherwise
|
1002
|
+
def brpoplpush(source, destination, options = {})
|
1003
|
+
case options
|
1004
|
+
when Integer
|
1005
|
+
# Issue deprecation notice in obnoxious mode...
|
1006
|
+
options = { :timeout => options }
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
timeout = options[:timeout] || 0
|
1010
|
+
|
788
1011
|
synchronize do |client|
|
789
|
-
client.
|
1012
|
+
client.call_without_timeout [:brpoplpush, source, destination, timeout]
|
790
1013
|
end
|
791
1014
|
end
|
792
1015
|
|
793
|
-
# Get
|
1016
|
+
# Get an element from a list by its index.
|
794
1017
|
#
|
795
1018
|
# @param [String] key
|
1019
|
+
# @param [Fixnum] index
|
796
1020
|
# @return [String]
|
797
|
-
def
|
1021
|
+
def lindex(key, index)
|
798
1022
|
synchronize do |client|
|
799
|
-
client.call [:
|
1023
|
+
client.call [:lindex, key, index]
|
800
1024
|
end
|
801
1025
|
end
|
802
1026
|
|
803
|
-
#
|
804
|
-
# that already exist.
|
805
|
-
#
|
806
|
-
# @example Add a single `[score, member]` pair to a sorted set
|
807
|
-
# redis.zadd("zset", 32.0, "member")
|
808
|
-
# @example Add an array of `[score, member]` pairs to a sorted set
|
809
|
-
# redis.zadd("zset", [[32.0, "a"], [64.0, "b"]])
|
1027
|
+
# Insert an element before or after another element in a list.
|
810
1028
|
#
|
811
1029
|
# @param [String] key
|
812
|
-
# @param [
|
813
|
-
#
|
814
|
-
#
|
815
|
-
#
|
816
|
-
#
|
817
|
-
|
818
|
-
# **added** to the sorted set
|
819
|
-
# - `Fixnum` when an array of pairs is specified, holding the number of
|
820
|
-
# pairs that were **added** to the sorted set
|
821
|
-
def zadd(key, *args)
|
1030
|
+
# @param [String, Symbol] where `BEFORE` or `AFTER`
|
1031
|
+
# @param [String] pivot reference element
|
1032
|
+
# @param [String] value
|
1033
|
+
# @return [Fixnum] length of the list after the insert operation, or `-1`
|
1034
|
+
# when the element `pivot` was not found
|
1035
|
+
def linsert(key, where, pivot, value)
|
822
1036
|
synchronize do |client|
|
823
|
-
|
824
|
-
# Variadic: return integer
|
825
|
-
client.call [:zadd, key] + args[0]
|
826
|
-
elsif args.size == 2
|
827
|
-
# Single pair: return boolean
|
828
|
-
client.call [:zadd, key, args[0], args[1]], &_boolify
|
829
|
-
else
|
830
|
-
raise ArgumentError, "wrong number of arguments"
|
831
|
-
end
|
1037
|
+
client.call [:linsert, key, where, pivot, value]
|
832
1038
|
end
|
833
1039
|
end
|
834
1040
|
|
835
|
-
#
|
836
|
-
#
|
837
|
-
# @example Remove a single member from a sorted set
|
838
|
-
# redis.zrem("zset", "a")
|
839
|
-
# @example Remove an array of members from a sorted set
|
840
|
-
# redis.zrem("zset", ["a", "b"])
|
1041
|
+
# Get a range of elements from a list.
|
841
1042
|
#
|
842
1043
|
# @param [String] key
|
843
|
-
# @param [
|
844
|
-
#
|
845
|
-
#
|
846
|
-
|
847
|
-
# @return [Boolean, Fixnum]
|
848
|
-
# - `Boolean` when a single member is specified, holding whether or not it
|
849
|
-
# was removed from the sorted set
|
850
|
-
# - `Fixnum` when an array of pairs is specified, holding the number of
|
851
|
-
# members that were removed to the sorted set
|
852
|
-
def zrem(key, member)
|
1044
|
+
# @param [Fixnum] start start index
|
1045
|
+
# @param [Fixnum] stop stop index
|
1046
|
+
# @return [Array<String>]
|
1047
|
+
def lrange(key, start, stop)
|
853
1048
|
synchronize do |client|
|
854
|
-
client.call [:
|
855
|
-
if member.is_a? Array
|
856
|
-
# Variadic: return integer
|
857
|
-
reply
|
858
|
-
else
|
859
|
-
# Single argument: return boolean
|
860
|
-
_boolify.call(reply)
|
861
|
-
end
|
862
|
-
end
|
1049
|
+
client.call [:lrange, key, start, stop]
|
863
1050
|
end
|
864
1051
|
end
|
865
1052
|
|
866
|
-
#
|
1053
|
+
# Remove elements from a list.
|
867
1054
|
#
|
868
1055
|
# @param [String] key
|
869
|
-
# @param [
|
870
|
-
#
|
871
|
-
|
1056
|
+
# @param [Fixnum] count number of elements to remove. Use a positive
|
1057
|
+
# value to remove the first `count` occurrences of `value`. A negative
|
1058
|
+
# value to remove the last `count` occurrences of `value`. Or zero, to
|
1059
|
+
# remove all occurrences of `value` from the list.
|
1060
|
+
# @param [String] value
|
1061
|
+
# @return [Fixnum] the number of removed elements
|
1062
|
+
def lrem(key, count, value)
|
872
1063
|
synchronize do |client|
|
873
|
-
client.call [:
|
1064
|
+
client.call [:lrem, key, count, value]
|
874
1065
|
end
|
875
1066
|
end
|
876
1067
|
|
877
|
-
#
|
878
|
-
# high to low.
|
1068
|
+
# Set the value of an element in a list by its index.
|
879
1069
|
#
|
880
1070
|
# @param [String] key
|
881
|
-
# @param [
|
882
|
-
# @
|
883
|
-
|
1071
|
+
# @param [Fixnum] index
|
1072
|
+
# @param [String] value
|
1073
|
+
# @return [String] `OK`
|
1074
|
+
def lset(key, index, value)
|
884
1075
|
synchronize do |client|
|
885
|
-
client.call [:
|
1076
|
+
client.call [:lset, key, index, value]
|
886
1077
|
end
|
887
1078
|
end
|
888
1079
|
|
889
|
-
#
|
890
|
-
#
|
891
|
-
# @example
|
892
|
-
# redis.zincrby("zset", 32.0, "a")
|
893
|
-
# # => 64.0
|
1080
|
+
# Trim a list to the specified range.
|
894
1081
|
#
|
895
1082
|
# @param [String] key
|
896
|
-
# @param [
|
897
|
-
# @param [
|
898
|
-
# @return [
|
899
|
-
def
|
1083
|
+
# @param [Fixnum] start start index
|
1084
|
+
# @param [Fixnum] stop stop index
|
1085
|
+
# @return [String] `OK`
|
1086
|
+
def ltrim(key, start, stop)
|
900
1087
|
synchronize do |client|
|
901
|
-
client.call [:
|
902
|
-
Float(reply) if reply
|
903
|
-
end
|
1088
|
+
client.call [:ltrim, key, start, stop]
|
904
1089
|
end
|
905
1090
|
end
|
906
1091
|
|
907
|
-
# Get the number of members in a
|
908
|
-
#
|
909
|
-
# @example
|
910
|
-
# redis.zcard("zset")
|
911
|
-
# # => 4
|
1092
|
+
# Get the number of members in a set.
|
912
1093
|
#
|
913
1094
|
# @param [String] key
|
914
1095
|
# @return [Fixnum]
|
915
|
-
def
|
1096
|
+
def scard(key)
|
916
1097
|
synchronize do |client|
|
917
|
-
client.call [:
|
1098
|
+
client.call [:scard, key]
|
918
1099
|
end
|
919
1100
|
end
|
920
1101
|
|
921
|
-
#
|
922
|
-
#
|
923
|
-
# @example Retrieve all members from a sorted set
|
924
|
-
# redis.zrange("zset", 0, -1)
|
925
|
-
# # => ["a", "b"]
|
926
|
-
# @example Retrieve all members and their scores from a sorted set
|
927
|
-
# redis.zrange("zset", 0, -1, :with_scores => true)
|
928
|
-
# # => [["a", 32.0], ["b", 64.0]]
|
1102
|
+
# Add one or more members to a set.
|
929
1103
|
#
|
930
1104
|
# @param [String] key
|
931
|
-
# @param [
|
932
|
-
# @
|
933
|
-
#
|
934
|
-
#
|
935
|
-
#
|
936
|
-
|
937
|
-
# - when `:with_scores` is not specified, an array of members
|
938
|
-
# - when `:with_scores` is specified, an array with `[member, score]` pairs
|
939
|
-
def zrange(key, start, stop, options = {})
|
940
|
-
args = []
|
941
|
-
|
942
|
-
with_scores = options[:with_scores] || options[:withscores]
|
943
|
-
args << "WITHSCORES" if with_scores
|
944
|
-
|
1105
|
+
# @param [String, Array<String>] member one member, or array of members
|
1106
|
+
# @return [Boolean, Fixnum] `Boolean` when a single member is specified,
|
1107
|
+
# holding whether or not adding the member succeeded, or `Fixnum` when an
|
1108
|
+
# array of members is specified, holding the number of members that were
|
1109
|
+
# successfully added
|
1110
|
+
def sadd(key, member)
|
945
1111
|
synchronize do |client|
|
946
|
-
client.call [:
|
947
|
-
if
|
948
|
-
|
949
|
-
reply.each_slice(2).map do |member, score|
|
950
|
-
[member, Float(score)]
|
951
|
-
end
|
952
|
-
end
|
953
|
-
else
|
1112
|
+
client.call [:sadd, key, member] do |reply|
|
1113
|
+
if member.is_a? Array
|
1114
|
+
# Variadic: return integer
|
954
1115
|
reply
|
1116
|
+
else
|
1117
|
+
# Single argument: return boolean
|
1118
|
+
_boolify.call(reply)
|
955
1119
|
end
|
956
1120
|
end
|
957
1121
|
end
|
958
1122
|
end
|
959
1123
|
|
960
|
-
#
|
961
|
-
# from high to low.
|
962
|
-
#
|
963
|
-
# @example Retrieve all members from a sorted set
|
964
|
-
# redis.zrevrange("zset", 0, -1)
|
965
|
-
# # => ["b", "a"]
|
966
|
-
# @example Retrieve all members and their scores from a sorted set
|
967
|
-
# redis.zrevrange("zset", 0, -1, :with_scores => true)
|
968
|
-
# # => [["b", 64.0], ["a", 32.0]]
|
1124
|
+
# Remove one or more members from a set.
|
969
1125
|
#
|
970
|
-
# @
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
1126
|
+
# @param [String] key
|
1127
|
+
# @param [String, Array<String>] member one member, or array of members
|
1128
|
+
# @return [Boolean, Fixnum] `Boolean` when a single member is specified,
|
1129
|
+
# holding whether or not removing the member succeeded, or `Fixnum` when an
|
1130
|
+
# array of members is specified, holding the number of members that were
|
1131
|
+
# successfully removed
|
1132
|
+
def srem(key, member)
|
977
1133
|
synchronize do |client|
|
978
|
-
client.call [:
|
979
|
-
if
|
980
|
-
|
981
|
-
reply.each_slice(2).map do |member, score|
|
982
|
-
[member, Float(score)]
|
983
|
-
end
|
984
|
-
end
|
985
|
-
else
|
1134
|
+
client.call [:srem, key, member] do |reply|
|
1135
|
+
if member.is_a? Array
|
1136
|
+
# Variadic: return integer
|
986
1137
|
reply
|
1138
|
+
else
|
1139
|
+
# Single argument: return boolean
|
1140
|
+
_boolify.call(reply)
|
987
1141
|
end
|
988
1142
|
end
|
989
1143
|
end
|
990
1144
|
end
|
991
1145
|
|
992
|
-
#
|
993
|
-
#
|
994
|
-
# @example Retrieve members with score `>= 5` and `< 100`
|
995
|
-
# redis.zrangebyscore("zset", "5", "(100")
|
996
|
-
# # => ["a", "b"]
|
997
|
-
# @example Retrieve the first 2 members with score `>= 0`
|
998
|
-
# redis.zrangebyscore("zset", "0", "+inf", :limit => [0, 2])
|
999
|
-
# # => ["a", "b"]
|
1000
|
-
# @example Retrieve members and their scores with scores `> 5`
|
1001
|
-
# redis.zrangebyscore("zset", "(5", "+inf", :with_scores => true)
|
1002
|
-
# # => [["a", 32.0], ["b", 64.0]]
|
1146
|
+
# Remove and return a random member from a set.
|
1003
1147
|
#
|
1004
1148
|
# @param [String] key
|
1005
|
-
# @
|
1006
|
-
|
1007
|
-
# - exclusive minimum score is specified by prefixing `(`
|
1008
|
-
# @param [String] max
|
1009
|
-
# - inclusive maximum score is specified verbatim
|
1010
|
-
# - exclusive maximum score is specified by prefixing `(`
|
1011
|
-
# @param [Hash] options
|
1012
|
-
# - `:with_scores => true`: include scores in output
|
1013
|
-
# - `:limit => [offset, count]`: skip `offset` members, return a maximum of
|
1014
|
-
# `count` members
|
1015
|
-
#
|
1016
|
-
# @return [Array<String>, Array<[String, Float]>]
|
1017
|
-
# - when `:with_scores` is not specified, an array of members
|
1018
|
-
# - when `:with_scores` is specified, an array with `[member, score]` pairs
|
1019
|
-
def zrangebyscore(key, min, max, options = {})
|
1020
|
-
args = []
|
1021
|
-
|
1022
|
-
with_scores = options[:with_scores] || options[:withscores]
|
1023
|
-
args.concat ["WITHSCORES"] if with_scores
|
1024
|
-
|
1025
|
-
limit = options[:limit]
|
1026
|
-
args.concat ["LIMIT", *limit] if limit
|
1027
|
-
|
1149
|
+
# @return [String]
|
1150
|
+
def spop(key)
|
1028
1151
|
synchronize do |client|
|
1029
|
-
client.call [:
|
1030
|
-
if with_scores
|
1031
|
-
if reply
|
1032
|
-
reply.each_slice(2).map do |member, score|
|
1033
|
-
[member, Float(score)]
|
1034
|
-
end
|
1035
|
-
end
|
1036
|
-
else
|
1037
|
-
reply
|
1038
|
-
end
|
1039
|
-
end
|
1152
|
+
client.call [:spop, key]
|
1040
1153
|
end
|
1041
1154
|
end
|
1042
1155
|
|
1043
|
-
#
|
1044
|
-
# from high to low.
|
1045
|
-
#
|
1046
|
-
# @example Retrieve members with score `< 100` and `>= 5`
|
1047
|
-
# redis.zrevrangebyscore("zset", "(100", "5")
|
1048
|
-
# # => ["b", "a"]
|
1049
|
-
# @example Retrieve the first 2 members with score `<= 0`
|
1050
|
-
# redis.zrevrangebyscore("zset", "0", "-inf", :limit => [0, 2])
|
1051
|
-
# # => ["b", "a"]
|
1052
|
-
# @example Retrieve members and their scores with scores `> 5`
|
1053
|
-
# redis.zrevrangebyscore("zset", "+inf", "(5", :with_scores => true)
|
1054
|
-
# # => [["b", 64.0], ["a", 32.0]]
|
1156
|
+
# Get a random member from a set.
|
1055
1157
|
#
|
1056
|
-
# @
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
with_scores = options[:with_scores] || options[:withscores]
|
1061
|
-
args.concat ["WITHSCORES"] if with_scores
|
1062
|
-
|
1063
|
-
limit = options[:limit]
|
1064
|
-
args.concat ["LIMIT", *limit] if limit
|
1065
|
-
|
1158
|
+
# @param [String] key
|
1159
|
+
# @return [String]
|
1160
|
+
def srandmember(key)
|
1066
1161
|
synchronize do |client|
|
1067
|
-
client.call [:
|
1068
|
-
if with_scores
|
1069
|
-
if reply
|
1070
|
-
reply.each_slice(2).map do |member, score|
|
1071
|
-
[member, Float(score)]
|
1072
|
-
end
|
1073
|
-
end
|
1074
|
-
else
|
1075
|
-
reply
|
1076
|
-
end
|
1077
|
-
end
|
1162
|
+
client.call [:srandmember, key]
|
1078
1163
|
end
|
1079
1164
|
end
|
1080
1165
|
|
1081
|
-
#
|
1166
|
+
# Move a member from one set to another.
|
1082
1167
|
#
|
1083
|
-
# @
|
1084
|
-
#
|
1085
|
-
#
|
1086
|
-
# @
|
1087
|
-
|
1088
|
-
# # => 2
|
1089
|
-
#
|
1090
|
-
# @param [String] key
|
1091
|
-
# @param [String] min
|
1092
|
-
# - inclusive minimum score is specified verbatim
|
1093
|
-
# - exclusive minimum score is specified by prefixing `(`
|
1094
|
-
# @param [String] max
|
1095
|
-
# - inclusive maximum score is specified verbatim
|
1096
|
-
# - exclusive maximum score is specified by prefixing `(`
|
1097
|
-
# @return [Fixnum] number of members in within the specified range
|
1098
|
-
def zcount(key, min, max)
|
1168
|
+
# @param [String] source source key
|
1169
|
+
# @param [String] destination destination key
|
1170
|
+
# @param [String] member member to move from `source` to `destination`
|
1171
|
+
# @return [Boolean]
|
1172
|
+
def smove(source, destination, member)
|
1099
1173
|
synchronize do |client|
|
1100
|
-
client.call [:
|
1174
|
+
client.call [:smove, source, destination, member], &_boolify
|
1101
1175
|
end
|
1102
1176
|
end
|
1103
1177
|
|
1104
|
-
#
|
1105
|
-
#
|
1106
|
-
# @example Remove members with score `>= 5` and `< 100`
|
1107
|
-
# redis.zremrangebyscore("zset", "5", "(100")
|
1108
|
-
# # => 2
|
1109
|
-
# @example Remove members with scores `> 5`
|
1110
|
-
# redis.zremrangebyscore("zset", "(5", "+inf")
|
1111
|
-
# # => 2
|
1178
|
+
# Determine if a given value is a member of a set.
|
1112
1179
|
#
|
1113
1180
|
# @param [String] key
|
1114
|
-
# @param [String]
|
1115
|
-
#
|
1116
|
-
|
1117
|
-
# @param [String] max
|
1118
|
-
# - inclusive maximum score is specified verbatim
|
1119
|
-
# - exclusive maximum score is specified by prefixing `(`
|
1120
|
-
# @return [Fixnum] number of members that were removed
|
1121
|
-
def zremrangebyscore(key, min, max)
|
1181
|
+
# @param [String] member
|
1182
|
+
# @return [Boolean]
|
1183
|
+
def sismember(key, member)
|
1122
1184
|
synchronize do |client|
|
1123
|
-
client.call [:
|
1185
|
+
client.call [:sismember, key, member], &_boolify
|
1124
1186
|
end
|
1125
1187
|
end
|
1126
1188
|
|
1127
|
-
#
|
1128
|
-
#
|
1129
|
-
# @example Remove first 5 members
|
1130
|
-
# redis.zremrangebyrank("zset", 0, 4)
|
1131
|
-
# # => 5
|
1132
|
-
# @example Remove last 5 members
|
1133
|
-
# redis.zremrangebyrank("zset", -5, -1)
|
1134
|
-
# # => 5
|
1189
|
+
# Get all the members in a set.
|
1135
1190
|
#
|
1136
1191
|
# @param [String] key
|
1137
|
-
# @
|
1138
|
-
|
1139
|
-
# @return [Fixnum] number of members that were removed
|
1140
|
-
def zremrangebyrank(key, start, stop)
|
1192
|
+
# @return [Array<String>]
|
1193
|
+
def smembers(key)
|
1141
1194
|
synchronize do |client|
|
1142
|
-
client.call [:
|
1195
|
+
client.call [:smembers, key]
|
1143
1196
|
end
|
1144
1197
|
end
|
1145
1198
|
|
1146
|
-
#
|
1147
|
-
#
|
1148
|
-
# @example Get the score for member "a"
|
1149
|
-
# redis.zscore("zset", "a")
|
1150
|
-
# # => 32.0
|
1199
|
+
# Subtract multiple sets.
|
1151
1200
|
#
|
1152
|
-
# @param [String]
|
1153
|
-
# @
|
1154
|
-
|
1155
|
-
def zscore(key, member)
|
1201
|
+
# @param [String, Array<String>] keys keys pointing to sets to subtract
|
1202
|
+
# @return [Array<String>] members in the difference
|
1203
|
+
def sdiff(*keys)
|
1156
1204
|
synchronize do |client|
|
1157
|
-
client.call [:
|
1158
|
-
Float(reply) if reply
|
1159
|
-
end
|
1205
|
+
client.call [:sdiff, *keys]
|
1160
1206
|
end
|
1161
1207
|
end
|
1162
1208
|
|
1163
|
-
#
|
1164
|
-
# key.
|
1165
|
-
#
|
1166
|
-
# @example Compute the intersection of `2*zsetA` with `1*zsetB`, summing their scores
|
1167
|
-
# redis.zinterstore("zsetC", ["zsetA", "zsetB"], :weights => [2.0, 1.0], :aggregate => "sum")
|
1168
|
-
# # => 4
|
1209
|
+
# Subtract multiple sets and store the resulting set in a key.
|
1169
1210
|
#
|
1170
1211
|
# @param [String] destination destination key
|
1171
|
-
# @param [Array<String>] keys
|
1172
|
-
# @
|
1173
|
-
|
1174
|
-
# sorted sets
|
1175
|
-
# - `:aggregate => String`: aggregate function to use (sum, min, max, ...)
|
1176
|
-
# @return [Fixnum] number of elements in the resulting sorted set
|
1177
|
-
def zinterstore(destination, keys, options = {})
|
1178
|
-
args = []
|
1179
|
-
|
1180
|
-
weights = options[:weights]
|
1181
|
-
args.concat ["WEIGHTS", *weights] if weights
|
1182
|
-
|
1183
|
-
aggregate = options[:aggregate]
|
1184
|
-
args.concat ["AGGREGATE", aggregate] if aggregate
|
1185
|
-
|
1212
|
+
# @param [String, Array<String>] keys keys pointing to sets to subtract
|
1213
|
+
# @return [Fixnum] number of elements in the resulting set
|
1214
|
+
def sdiffstore(destination, *keys)
|
1186
1215
|
synchronize do |client|
|
1187
|
-
client.call [:
|
1216
|
+
client.call [:sdiffstore, destination, *keys]
|
1188
1217
|
end
|
1189
1218
|
end
|
1190
1219
|
|
1191
|
-
#
|
1192
|
-
#
|
1193
|
-
# @example Compute the union of `2*zsetA` with `1*zsetB`, summing their scores
|
1194
|
-
# redis.zunionstore("zsetC", ["zsetA", "zsetB"], :weights => [2.0, 1.0], :aggregate => "sum")
|
1195
|
-
# # => 8
|
1220
|
+
# Intersect multiple sets.
|
1196
1221
|
#
|
1197
|
-
# @param [String]
|
1198
|
-
# @
|
1199
|
-
|
1200
|
-
# - `:weights => [Float, Float, ...]`: weights to associate with source
|
1201
|
-
# sorted sets
|
1202
|
-
# - `:aggregate => String`: aggregate function to use (sum, min, max, ...)
|
1203
|
-
# @return [Fixnum] number of elements in the resulting sorted set
|
1204
|
-
def zunionstore(destination, keys, options = {})
|
1205
|
-
args = []
|
1206
|
-
|
1207
|
-
weights = options[:weights]
|
1208
|
-
args.concat ["WEIGHTS", *weights] if weights
|
1209
|
-
|
1210
|
-
aggregate = options[:aggregate]
|
1211
|
-
args.concat ["AGGREGATE", aggregate] if aggregate
|
1212
|
-
|
1222
|
+
# @param [String, Array<String>] keys keys pointing to sets to intersect
|
1223
|
+
# @return [Array<String>] members in the intersection
|
1224
|
+
def sinter(*keys)
|
1213
1225
|
synchronize do |client|
|
1214
|
-
client.call [:
|
1226
|
+
client.call [:sinter, *keys]
|
1215
1227
|
end
|
1216
1228
|
end
|
1217
1229
|
|
1218
|
-
#
|
1219
|
-
#
|
1220
|
-
# @example Move a key to another database
|
1221
|
-
# redis.set "foo", "bar"
|
1222
|
-
# # => "OK"
|
1223
|
-
# redis.move "foo", 2
|
1224
|
-
# # => true
|
1225
|
-
# redis.exists "foo"
|
1226
|
-
# # => false
|
1227
|
-
# redis.select 2
|
1228
|
-
# # => "OK"
|
1229
|
-
# redis.exists "foo"
|
1230
|
-
# # => true
|
1231
|
-
# resis.get "foo"
|
1232
|
-
# # => "bar"
|
1230
|
+
# Intersect multiple sets and store the resulting set in a key.
|
1233
1231
|
#
|
1234
|
-
# @param [String] key
|
1235
|
-
# @param [
|
1236
|
-
# @return [
|
1237
|
-
def
|
1232
|
+
# @param [String] destination destination key
|
1233
|
+
# @param [String, Array<String>] keys keys pointing to sets to intersect
|
1234
|
+
# @return [Fixnum] number of elements in the resulting set
|
1235
|
+
def sinterstore(destination, *keys)
|
1238
1236
|
synchronize do |client|
|
1239
|
-
client.call [:
|
1237
|
+
client.call [:sinterstore, destination, *keys]
|
1240
1238
|
end
|
1241
1239
|
end
|
1242
1240
|
|
1243
|
-
#
|
1241
|
+
# Add multiple sets.
|
1244
1242
|
#
|
1245
|
-
# @param [String]
|
1246
|
-
# @
|
1247
|
-
|
1248
|
-
def setnx(key, value)
|
1243
|
+
# @param [String, Array<String>] keys keys pointing to sets to unify
|
1244
|
+
# @return [Array<String>] members in the union
|
1245
|
+
def sunion(*keys)
|
1249
1246
|
synchronize do |client|
|
1250
|
-
client.call [:
|
1247
|
+
client.call [:sunion, *keys]
|
1251
1248
|
end
|
1252
1249
|
end
|
1253
1250
|
|
1254
|
-
#
|
1251
|
+
# Add multiple sets and store the resulting set in a key.
|
1255
1252
|
#
|
1256
|
-
# @param [String
|
1257
|
-
# @
|
1258
|
-
|
1253
|
+
# @param [String] destination destination key
|
1254
|
+
# @param [String, Array<String>] keys keys pointing to sets to unify
|
1255
|
+
# @return [Fixnum] number of elements in the resulting set
|
1256
|
+
def sunionstore(destination, *keys)
|
1259
1257
|
synchronize do |client|
|
1260
|
-
client.call [:
|
1258
|
+
client.call [:sunionstore, destination, *keys]
|
1261
1259
|
end
|
1262
1260
|
end
|
1263
1261
|
|
1264
|
-
#
|
1262
|
+
# Get the number of members in a sorted set.
|
1265
1263
|
#
|
1266
|
-
# @
|
1267
|
-
#
|
1268
|
-
#
|
1269
|
-
def rename(old_name, new_name)
|
1270
|
-
synchronize do |client|
|
1271
|
-
client.call [:rename, old_name, new_name]
|
1272
|
-
end
|
1273
|
-
end
|
1274
|
-
|
1275
|
-
# Rename a key, only if the new key does not exist.
|
1264
|
+
# @example
|
1265
|
+
# redis.zcard("zset")
|
1266
|
+
# # => 4
|
1276
1267
|
#
|
1277
|
-
# @param [String]
|
1278
|
-
# @
|
1279
|
-
|
1280
|
-
def renamenx(old_name, new_name)
|
1268
|
+
# @param [String] key
|
1269
|
+
# @return [Fixnum]
|
1270
|
+
def zcard(key)
|
1281
1271
|
synchronize do |client|
|
1282
|
-
client.call [:
|
1272
|
+
client.call [:zcard, key]
|
1283
1273
|
end
|
1284
1274
|
end
|
1285
1275
|
|
1286
|
-
#
|
1276
|
+
# Add one or more members to a sorted set, or update the score for members
|
1277
|
+
# that already exist.
|
1278
|
+
#
|
1279
|
+
# @example Add a single `[score, member]` pair to a sorted set
|
1280
|
+
# redis.zadd("zset", 32.0, "member")
|
1281
|
+
# @example Add an array of `[score, member]` pairs to a sorted set
|
1282
|
+
# redis.zadd("zset", [[32.0, "a"], [64.0, "b"]])
|
1287
1283
|
#
|
1288
1284
|
# @param [String] key
|
1289
|
-
# @param [
|
1290
|
-
#
|
1291
|
-
|
1285
|
+
# @param [[Float, String], Array<[Float, String]>] args
|
1286
|
+
# - a single `[score, member]` pair
|
1287
|
+
# - an array of `[score, member]` pairs
|
1288
|
+
#
|
1289
|
+
# @return [Boolean, Fixnum]
|
1290
|
+
# - `Boolean` when a single pair is specified, holding whether or not it was
|
1291
|
+
# **added** to the sorted set
|
1292
|
+
# - `Fixnum` when an array of pairs is specified, holding the number of
|
1293
|
+
# pairs that were **added** to the sorted set
|
1294
|
+
def zadd(key, *args)
|
1292
1295
|
synchronize do |client|
|
1293
|
-
|
1296
|
+
if args.size == 1 && args[0].is_a?(Array)
|
1297
|
+
# Variadic: return integer
|
1298
|
+
client.call [:zadd, key] + args[0]
|
1299
|
+
elsif args.size == 2
|
1300
|
+
# Single pair: return boolean
|
1301
|
+
client.call [:zadd, key, args[0], args[1]], &_boolify
|
1302
|
+
else
|
1303
|
+
raise ArgumentError, "wrong number of arguments"
|
1304
|
+
end
|
1294
1305
|
end
|
1295
1306
|
end
|
1296
1307
|
|
1297
|
-
#
|
1308
|
+
# Increment the score of a member in a sorted set.
|
1309
|
+
#
|
1310
|
+
# @example
|
1311
|
+
# redis.zincrby("zset", 32.0, "a")
|
1312
|
+
# # => 64.0
|
1298
1313
|
#
|
1299
1314
|
# @param [String] key
|
1300
|
-
# @param [
|
1301
|
-
# @
|
1302
|
-
|
1315
|
+
# @param [Float] increment
|
1316
|
+
# @param [String] member
|
1317
|
+
# @return [Float] score of the member after incrementing it
|
1318
|
+
def zincrby(key, increment, member)
|
1303
1319
|
synchronize do |client|
|
1304
|
-
client.call [:
|
1320
|
+
client.call [:zincrby, key, increment, member] do |reply|
|
1321
|
+
Float(reply) if reply
|
1322
|
+
end
|
1305
1323
|
end
|
1306
1324
|
end
|
1307
1325
|
|
1308
|
-
# Remove
|
1326
|
+
# Remove one or more members from a sorted set.
|
1327
|
+
#
|
1328
|
+
# @example Remove a single member from a sorted set
|
1329
|
+
# redis.zrem("zset", "a")
|
1330
|
+
# @example Remove an array of members from a sorted set
|
1331
|
+
# redis.zrem("zset", ["a", "b"])
|
1309
1332
|
#
|
1310
1333
|
# @param [String] key
|
1311
|
-
# @
|
1312
|
-
|
1313
|
-
|
1314
|
-
client.call [:persist, key], &_boolify
|
1315
|
-
end
|
1316
|
-
end
|
1317
|
-
|
1318
|
-
# Get the time to live (in seconds) for a key.
|
1334
|
+
# @param [String, Array<String>] member
|
1335
|
+
# - a single member
|
1336
|
+
# - an array of members
|
1319
1337
|
#
|
1320
|
-
# @
|
1321
|
-
#
|
1322
|
-
#
|
1323
|
-
|
1338
|
+
# @return [Boolean, Fixnum]
|
1339
|
+
# - `Boolean` when a single member is specified, holding whether or not it
|
1340
|
+
# was removed from the sorted set
|
1341
|
+
# - `Fixnum` when an array of pairs is specified, holding the number of
|
1342
|
+
# members that were removed to the sorted set
|
1343
|
+
def zrem(key, member)
|
1324
1344
|
synchronize do |client|
|
1325
|
-
client.call [:
|
1345
|
+
client.call [:zrem, key, member] do |reply|
|
1346
|
+
if member.is_a? Array
|
1347
|
+
# Variadic: return integer
|
1348
|
+
reply
|
1349
|
+
else
|
1350
|
+
# Single argument: return boolean
|
1351
|
+
_boolify.call(reply)
|
1352
|
+
end
|
1353
|
+
end
|
1326
1354
|
end
|
1327
1355
|
end
|
1328
1356
|
|
1329
|
-
# Get the
|
1357
|
+
# Get the score associated with the given member in a sorted set.
|
1358
|
+
#
|
1359
|
+
# @example Get the score for member "a"
|
1360
|
+
# redis.zscore("zset", "a")
|
1361
|
+
# # => 32.0
|
1330
1362
|
#
|
1331
1363
|
# @param [String] key
|
1332
|
-
# @
|
1333
|
-
#
|
1334
|
-
def
|
1364
|
+
# @param [String] member
|
1365
|
+
# @return [Float] score of the member
|
1366
|
+
def zscore(key, member)
|
1335
1367
|
synchronize do |client|
|
1336
|
-
client.call [:
|
1368
|
+
client.call [:zscore, key, member] do |reply|
|
1369
|
+
Float(reply) if reply
|
1370
|
+
end
|
1337
1371
|
end
|
1338
1372
|
end
|
1339
1373
|
|
1340
|
-
#
|
1374
|
+
# Return a range of members in a sorted set, by index.
|
1375
|
+
#
|
1376
|
+
# @example Retrieve all members from a sorted set
|
1377
|
+
# redis.zrange("zset", 0, -1)
|
1378
|
+
# # => ["a", "b"]
|
1379
|
+
# @example Retrieve all members and their scores from a sorted set
|
1380
|
+
# redis.zrange("zset", 0, -1, :with_scores => true)
|
1381
|
+
# # => [["a", 32.0], ["b", 64.0]]
|
1341
1382
|
#
|
1342
1383
|
# @param [String] key
|
1343
|
-
# @param [Fixnum]
|
1344
|
-
# @
|
1345
|
-
|
1384
|
+
# @param [Fixnum] start start index
|
1385
|
+
# @param [Fixnum] stop stop index
|
1386
|
+
# @param [Hash] options
|
1387
|
+
# - `:with_scores => true`: include scores in output
|
1388
|
+
#
|
1389
|
+
# @return [Array<String>, Array<[String, Float]>]
|
1390
|
+
# - when `:with_scores` is not specified, an array of members
|
1391
|
+
# - when `:with_scores` is specified, an array with `[member, score]` pairs
|
1392
|
+
def zrange(key, start, stop, options = {})
|
1393
|
+
args = []
|
1394
|
+
|
1395
|
+
with_scores = options[:with_scores] || options[:withscores]
|
1396
|
+
args << "WITHSCORES" if with_scores
|
1397
|
+
|
1346
1398
|
synchronize do |client|
|
1347
|
-
client.call [:
|
1399
|
+
client.call [:zrange, key, start, stop, *args] do |reply|
|
1400
|
+
if with_scores
|
1401
|
+
if reply
|
1402
|
+
reply.each_slice(2).map do |member, score|
|
1403
|
+
[member, Float(score)]
|
1404
|
+
end
|
1405
|
+
end
|
1406
|
+
else
|
1407
|
+
reply
|
1408
|
+
end
|
1409
|
+
end
|
1348
1410
|
end
|
1349
1411
|
end
|
1350
1412
|
|
1351
|
-
#
|
1413
|
+
# Return a range of members in a sorted set, by index, with scores ordered
|
1414
|
+
# from high to low.
|
1352
1415
|
#
|
1353
|
-
# @
|
1354
|
-
#
|
1355
|
-
#
|
1356
|
-
|
1416
|
+
# @example Retrieve all members from a sorted set
|
1417
|
+
# redis.zrevrange("zset", 0, -1)
|
1418
|
+
# # => ["b", "a"]
|
1419
|
+
# @example Retrieve all members and their scores from a sorted set
|
1420
|
+
# redis.zrevrange("zset", 0, -1, :with_scores => true)
|
1421
|
+
# # => [["b", 64.0], ["a", 32.0]]
|
1422
|
+
#
|
1423
|
+
# @see #zrange
|
1424
|
+
def zrevrange(key, start, stop, options = {})
|
1425
|
+
args = []
|
1426
|
+
|
1427
|
+
with_scores = options[:with_scores] || options[:withscores]
|
1428
|
+
args << "WITHSCORES" if with_scores
|
1429
|
+
|
1357
1430
|
synchronize do |client|
|
1358
|
-
client.call [:
|
1431
|
+
client.call [:zrevrange, key, start, stop, *args] do |reply|
|
1432
|
+
if with_scores
|
1433
|
+
if reply
|
1434
|
+
reply.each_slice(2).map do |member, score|
|
1435
|
+
[member, Float(score)]
|
1436
|
+
end
|
1437
|
+
end
|
1438
|
+
else
|
1439
|
+
reply
|
1440
|
+
end
|
1441
|
+
end
|
1359
1442
|
end
|
1360
1443
|
end
|
1361
|
-
|
1444
|
+
|
1445
|
+
# Determine the index of a member in a sorted set.
|
1362
1446
|
#
|
1363
1447
|
# @param [String] key
|
1364
|
-
# @param [String]
|
1365
|
-
# @
|
1366
|
-
|
1367
|
-
def hset(key, field, value)
|
1448
|
+
# @param [String] member
|
1449
|
+
# @return [Fixnum]
|
1450
|
+
def zrank(key, member)
|
1368
1451
|
synchronize do |client|
|
1369
|
-
client.call [:
|
1452
|
+
client.call [:zrank, key, member]
|
1370
1453
|
end
|
1371
1454
|
end
|
1372
1455
|
|
1373
|
-
#
|
1456
|
+
# Determine the index of a member in a sorted set, with scores ordered from
|
1457
|
+
# high to low.
|
1374
1458
|
#
|
1375
1459
|
# @param [String] key
|
1376
|
-
# @param [String]
|
1377
|
-
# @
|
1378
|
-
|
1379
|
-
def hsetnx(key, field, value)
|
1460
|
+
# @param [String] member
|
1461
|
+
# @return [Fixnum]
|
1462
|
+
def zrevrank(key, member)
|
1380
1463
|
synchronize do |client|
|
1381
|
-
client.call [:
|
1464
|
+
client.call [:zrevrank, key, member]
|
1382
1465
|
end
|
1383
1466
|
end
|
1384
1467
|
|
1385
|
-
#
|
1468
|
+
# Remove all members in a sorted set within the given indexes.
|
1386
1469
|
#
|
1387
|
-
# @example
|
1388
|
-
# redis.
|
1389
|
-
# # =>
|
1470
|
+
# @example Remove first 5 members
|
1471
|
+
# redis.zremrangebyrank("zset", 0, 4)
|
1472
|
+
# # => 5
|
1473
|
+
# @example Remove last 5 members
|
1474
|
+
# redis.zremrangebyrank("zset", -5, -1)
|
1475
|
+
# # => 5
|
1390
1476
|
#
|
1391
1477
|
# @param [String] key
|
1392
|
-
# @param [
|
1393
|
-
# @
|
1394
|
-
#
|
1395
|
-
|
1396
|
-
def hmset(key, *attrs)
|
1478
|
+
# @param [Fixnum] start start index
|
1479
|
+
# @param [Fixnum] stop stop index
|
1480
|
+
# @return [Fixnum] number of members that were removed
|
1481
|
+
def zremrangebyrank(key, start, stop)
|
1397
1482
|
synchronize do |client|
|
1398
|
-
client.call [:
|
1483
|
+
client.call [:zremrangebyrank, key, start, stop]
|
1399
1484
|
end
|
1400
1485
|
end
|
1401
1486
|
|
1402
|
-
#
|
1487
|
+
# Return a range of members in a sorted set, by score.
|
1403
1488
|
#
|
1404
|
-
# @example
|
1405
|
-
# redis.
|
1406
|
-
# # => "
|
1489
|
+
# @example Retrieve members with score `>= 5` and `< 100`
|
1490
|
+
# redis.zrangebyscore("zset", "5", "(100")
|
1491
|
+
# # => ["a", "b"]
|
1492
|
+
# @example Retrieve the first 2 members with score `>= 0`
|
1493
|
+
# redis.zrangebyscore("zset", "0", "+inf", :limit => [0, 2])
|
1494
|
+
# # => ["a", "b"]
|
1495
|
+
# @example Retrieve members and their scores with scores `> 5`
|
1496
|
+
# redis.zrangebyscore("zset", "(5", "+inf", :with_scores => true)
|
1497
|
+
# # => [["a", 32.0], ["b", 64.0]]
|
1407
1498
|
#
|
1408
1499
|
# @param [String] key
|
1409
|
-
# @param [
|
1410
|
-
#
|
1500
|
+
# @param [String] min
|
1501
|
+
# - inclusive minimum score is specified verbatim
|
1502
|
+
# - exclusive minimum score is specified by prefixing `(`
|
1503
|
+
# @param [String] max
|
1504
|
+
# - inclusive maximum score is specified verbatim
|
1505
|
+
# - exclusive maximum score is specified by prefixing `(`
|
1506
|
+
# @param [Hash] options
|
1507
|
+
# - `:with_scores => true`: include scores in output
|
1508
|
+
# - `:limit => [offset, count]`: skip `offset` members, return a maximum of
|
1509
|
+
# `count` members
|
1411
1510
|
#
|
1412
|
-
# @
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1511
|
+
# @return [Array<String>, Array<[String, Float]>]
|
1512
|
+
# - when `:with_scores` is not specified, an array of members
|
1513
|
+
# - when `:with_scores` is specified, an array with `[member, score]` pairs
|
1514
|
+
def zrangebyscore(key, min, max, options = {})
|
1515
|
+
args = []
|
1516
|
+
|
1517
|
+
with_scores = options[:with_scores] || options[:withscores]
|
1518
|
+
args.concat ["WITHSCORES"] if with_scores
|
1519
|
+
|
1520
|
+
limit = options[:limit]
|
1521
|
+
args.concat ["LIMIT", *limit] if limit
|
1416
1522
|
|
1417
|
-
# Get the values of all the given hash fields.
|
1418
|
-
#
|
1419
|
-
# @example
|
1420
|
-
# redis.hmget("hash", "f1", "f2")
|
1421
|
-
# # => ["v1", "v2"]
|
1422
|
-
#
|
1423
|
-
# @param [String] key
|
1424
|
-
# @param [Array<String>] fields array of fields
|
1425
|
-
# @return [Array<String>] an array of values for the specified fields
|
1426
|
-
#
|
1427
|
-
# @see #mapped_hmget
|
1428
|
-
def hmget(key, *fields, &blk)
|
1429
1523
|
synchronize do |client|
|
1430
|
-
client.call [:
|
1524
|
+
client.call [:zrangebyscore, key, min, max, *args] do |reply|
|
1525
|
+
if with_scores
|
1526
|
+
if reply
|
1527
|
+
reply.each_slice(2).map do |member, score|
|
1528
|
+
[member, Float(score)]
|
1529
|
+
end
|
1530
|
+
end
|
1531
|
+
else
|
1532
|
+
reply
|
1533
|
+
end
|
1534
|
+
end
|
1431
1535
|
end
|
1432
1536
|
end
|
1433
1537
|
|
1434
|
-
#
|
1435
|
-
#
|
1436
|
-
# @example
|
1437
|
-
# redis.hmget("hash", "f1", "f2")
|
1438
|
-
# # => { "f1" => "v1", "f2" => "v2" }
|
1538
|
+
# Return a range of members in a sorted set, by score, with scores ordered
|
1539
|
+
# from high to low.
|
1439
1540
|
#
|
1440
|
-
# @
|
1441
|
-
#
|
1442
|
-
#
|
1541
|
+
# @example Retrieve members with score `< 100` and `>= 5`
|
1542
|
+
# redis.zrevrangebyscore("zset", "(100", "5")
|
1543
|
+
# # => ["b", "a"]
|
1544
|
+
# @example Retrieve the first 2 members with score `<= 0`
|
1545
|
+
# redis.zrevrangebyscore("zset", "0", "-inf", :limit => [0, 2])
|
1546
|
+
# # => ["b", "a"]
|
1547
|
+
# @example Retrieve members and their scores with scores `> 5`
|
1548
|
+
# redis.zrevrangebyscore("zset", "+inf", "(5", :with_scores => true)
|
1549
|
+
# # => [["b", 64.0], ["a", 32.0]]
|
1443
1550
|
#
|
1444
|
-
# @see #
|
1445
|
-
def
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1551
|
+
# @see #zrangebyscore
|
1552
|
+
def zrevrangebyscore(key, max, min, options = {})
|
1553
|
+
args = []
|
1554
|
+
|
1555
|
+
with_scores = options[:with_scores] || options[:withscores]
|
1556
|
+
args.concat ["WITHSCORES"] if with_scores
|
1557
|
+
|
1558
|
+
limit = options[:limit]
|
1559
|
+
args.concat ["LIMIT", *limit] if limit
|
1560
|
+
|
1561
|
+
synchronize do |client|
|
1562
|
+
client.call [:zrevrangebyscore, key, max, min, *args] do |reply|
|
1563
|
+
if with_scores
|
1564
|
+
if reply
|
1565
|
+
reply.each_slice(2).map do |member, score|
|
1566
|
+
[member, Float(score)]
|
1567
|
+
end
|
1568
|
+
end
|
1569
|
+
else
|
1570
|
+
reply
|
1451
1571
|
end
|
1452
|
-
hash
|
1453
|
-
else
|
1454
|
-
reply
|
1455
1572
|
end
|
1456
1573
|
end
|
1457
1574
|
end
|
1458
1575
|
|
1459
|
-
#
|
1460
|
-
#
|
1461
|
-
# @param [String] key
|
1462
|
-
# @return [Fixnum] number of fields in the hash
|
1463
|
-
def hlen(key)
|
1464
|
-
synchronize do |client|
|
1465
|
-
client.call [:hlen, key]
|
1466
|
-
end
|
1467
|
-
end
|
1468
|
-
|
1469
|
-
# Get all the values in a hash.
|
1576
|
+
# Remove all members in a sorted set within the given scores.
|
1470
1577
|
#
|
1471
|
-
# @
|
1472
|
-
#
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
end
|
1478
|
-
|
1479
|
-
# Increment the integer value of a hash field by the given integer number.
|
1578
|
+
# @example Remove members with score `>= 5` and `< 100`
|
1579
|
+
# redis.zremrangebyscore("zset", "5", "(100")
|
1580
|
+
# # => 2
|
1581
|
+
# @example Remove members with scores `> 5`
|
1582
|
+
# redis.zremrangebyscore("zset", "(5", "+inf")
|
1583
|
+
# # => 2
|
1480
1584
|
#
|
1481
1585
|
# @param [String] key
|
1482
|
-
# @param [String]
|
1483
|
-
#
|
1484
|
-
#
|
1485
|
-
|
1586
|
+
# @param [String] min
|
1587
|
+
# - inclusive minimum score is specified verbatim
|
1588
|
+
# - exclusive minimum score is specified by prefixing `(`
|
1589
|
+
# @param [String] max
|
1590
|
+
# - inclusive maximum score is specified verbatim
|
1591
|
+
# - exclusive maximum score is specified by prefixing `(`
|
1592
|
+
# @return [Fixnum] number of members that were removed
|
1593
|
+
def zremrangebyscore(key, min, max)
|
1486
1594
|
synchronize do |client|
|
1487
|
-
client.call [:
|
1595
|
+
client.call [:zremrangebyscore, key, min, max]
|
1488
1596
|
end
|
1489
1597
|
end
|
1490
1598
|
|
1491
|
-
#
|
1599
|
+
# Count the members in a sorted set with scores within the given values.
|
1492
1600
|
#
|
1493
|
-
# @
|
1494
|
-
#
|
1495
|
-
#
|
1496
|
-
# @
|
1497
|
-
|
1498
|
-
|
1499
|
-
client.call [:hincrbyfloat, key, field, increment] do |reply|
|
1500
|
-
Float(reply) if reply
|
1501
|
-
end
|
1502
|
-
end
|
1503
|
-
end
|
1504
|
-
|
1505
|
-
# Determine if a hash field exists.
|
1601
|
+
# @example Count members with score `>= 5` and `< 100`
|
1602
|
+
# redis.zcount("zset", "5", "(100")
|
1603
|
+
# # => 2
|
1604
|
+
# @example Count members with scores `> 5`
|
1605
|
+
# redis.zcount("zset", "(5", "+inf")
|
1606
|
+
# # => 2
|
1506
1607
|
#
|
1507
1608
|
# @param [String] key
|
1508
|
-
# @param [String]
|
1509
|
-
#
|
1510
|
-
|
1609
|
+
# @param [String] min
|
1610
|
+
# - inclusive minimum score is specified verbatim
|
1611
|
+
# - exclusive minimum score is specified by prefixing `(`
|
1612
|
+
# @param [String] max
|
1613
|
+
# - inclusive maximum score is specified verbatim
|
1614
|
+
# - exclusive maximum score is specified by prefixing `(`
|
1615
|
+
# @return [Fixnum] number of members in within the specified range
|
1616
|
+
def zcount(key, min, max)
|
1511
1617
|
synchronize do |client|
|
1512
|
-
client.call [:
|
1618
|
+
client.call [:zcount, key, min, max]
|
1513
1619
|
end
|
1514
1620
|
end
|
1515
1621
|
|
1516
|
-
#
|
1622
|
+
# Intersect multiple sorted sets and store the resulting sorted set in a new
|
1623
|
+
# key.
|
1517
1624
|
#
|
1518
|
-
#
|
1625
|
+
# @example Compute the intersection of `2*zsetA` with `1*zsetB`, summing their scores
|
1626
|
+
# redis.zinterstore("zsetC", ["zsetA", "zsetB"], :weights => [2.0, 1.0], :aggregate => "sum")
|
1627
|
+
# # => 4
|
1519
1628
|
#
|
1520
|
-
# @
|
1521
|
-
# @
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1629
|
+
# @param [String] destination destination key
|
1630
|
+
# @param [Array<String>] keys source keys
|
1631
|
+
# @param [Hash] options
|
1632
|
+
# - `:weights => [Float, Float, ...]`: weights to associate with source
|
1633
|
+
# sorted sets
|
1634
|
+
# - `:aggregate => String`: aggregate function to use (sum, min, max, ...)
|
1635
|
+
# @return [Fixnum] number of elements in the resulting sorted set
|
1636
|
+
def zinterstore(destination, keys, options = {})
|
1637
|
+
args = []
|
1527
1638
|
|
1528
|
-
|
1529
|
-
|
1530
|
-
client.call [:debug, *args]
|
1531
|
-
end
|
1532
|
-
end
|
1639
|
+
weights = options[:weights]
|
1640
|
+
args.concat ["WEIGHTS", *weights] if weights
|
1533
1641
|
|
1534
|
-
|
1535
|
-
|
1536
|
-
client.call [:object, *args]
|
1537
|
-
end
|
1538
|
-
end
|
1642
|
+
aggregate = options[:aggregate]
|
1643
|
+
args.concat ["AGGREGATE", aggregate] if aggregate
|
1539
1644
|
|
1540
|
-
# Internal command used for replication.
|
1541
|
-
def sync
|
1542
1645
|
synchronize do |client|
|
1543
|
-
client.call [:
|
1646
|
+
client.call [:zinterstore, destination, keys.size, *(keys + args)]
|
1544
1647
|
end
|
1545
1648
|
end
|
1546
1649
|
|
1547
|
-
#
|
1650
|
+
# Add multiple sorted sets and store the resulting sorted set in a new key.
|
1548
1651
|
#
|
1549
|
-
# @
|
1550
|
-
#
|
1551
|
-
#
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1652
|
+
# @example Compute the union of `2*zsetA` with `1*zsetB`, summing their scores
|
1653
|
+
# redis.zunionstore("zsetC", ["zsetA", "zsetB"], :weights => [2.0, 1.0], :aggregate => "sum")
|
1654
|
+
# # => 8
|
1655
|
+
#
|
1656
|
+
# @param [String] destination destination key
|
1657
|
+
# @param [Array<String>] keys source keys
|
1658
|
+
# @param [Hash] options
|
1659
|
+
# - `:weights => [Float, Float, ...]`: weights to associate with source
|
1660
|
+
# sorted sets
|
1661
|
+
# - `:aggregate => String`: aggregate function to use (sum, min, max, ...)
|
1662
|
+
# @return [Fixnum] number of elements in the resulting sorted set
|
1663
|
+
def zunionstore(destination, keys, options = {})
|
1664
|
+
args = []
|
1557
1665
|
|
1558
|
-
|
1666
|
+
weights = options[:weights]
|
1667
|
+
args.concat ["WEIGHTS", *weights] if weights
|
1668
|
+
|
1669
|
+
aggregate = options[:aggregate]
|
1670
|
+
args.concat ["AGGREGATE", aggregate] if aggregate
|
1559
1671
|
|
1560
|
-
# Sets or clears the bit at offset in the string value stored at key.
|
1561
|
-
#
|
1562
|
-
# @param [String] key
|
1563
|
-
# @param [Fixnum] offset bit offset
|
1564
|
-
# @param [Fixnum] value bit value `0` or `1`
|
1565
|
-
# @return [Fixnum] the original bit value stored at `offset`
|
1566
|
-
def setbit(key, offset, value)
|
1567
1672
|
synchronize do |client|
|
1568
|
-
client.call [:
|
1673
|
+
client.call [:zunionstore, destination, keys.size, *(keys + args)]
|
1569
1674
|
end
|
1570
1675
|
end
|
1571
1676
|
|
1572
|
-
#
|
1677
|
+
# Get the number of fields in a hash.
|
1573
1678
|
#
|
1574
1679
|
# @param [String] key
|
1575
|
-
# @
|
1576
|
-
|
1577
|
-
# @return `"OK"`
|
1578
|
-
def setex(key, ttl, value)
|
1680
|
+
# @return [Fixnum] number of fields in the hash
|
1681
|
+
def hlen(key)
|
1579
1682
|
synchronize do |client|
|
1580
|
-
client.call [:
|
1683
|
+
client.call [:hlen, key]
|
1581
1684
|
end
|
1582
1685
|
end
|
1583
1686
|
|
1584
|
-
# Set the
|
1687
|
+
# Set the string value of a hash field.
|
1585
1688
|
#
|
1586
1689
|
# @param [String] key
|
1587
|
-
# @param [
|
1690
|
+
# @param [String] field
|
1588
1691
|
# @param [String] value
|
1589
|
-
# @return
|
1590
|
-
def
|
1692
|
+
# @return [Boolean] whether or not the field was **added** to the hash
|
1693
|
+
def hset(key, field, value)
|
1591
1694
|
synchronize do |client|
|
1592
|
-
client.call [:
|
1695
|
+
client.call [:hset, key, field, value], &_boolify
|
1593
1696
|
end
|
1594
1697
|
end
|
1595
1698
|
|
1596
|
-
#
|
1699
|
+
# Set the value of a hash field, only if the field does not exist.
|
1597
1700
|
#
|
1598
1701
|
# @param [String] key
|
1599
|
-
# @param [
|
1702
|
+
# @param [String] field
|
1600
1703
|
# @param [String] value
|
1601
|
-
# @return [
|
1602
|
-
def
|
1704
|
+
# @return [Boolean] whether or not the field was **added** to the hash
|
1705
|
+
def hsetnx(key, field, value)
|
1603
1706
|
synchronize do |client|
|
1604
|
-
client.call [:
|
1707
|
+
client.call [:hsetnx, key, field, value], &_boolify
|
1605
1708
|
end
|
1606
1709
|
end
|
1607
1710
|
|
1608
|
-
# Set one or more values.
|
1711
|
+
# Set one or more hash values.
|
1609
1712
|
#
|
1610
1713
|
# @example
|
1611
|
-
# redis.
|
1714
|
+
# redis.hmset("hash", "f1", "v1", "f2", "v2")
|
1612
1715
|
# # => "OK"
|
1613
1716
|
#
|
1614
|
-
# @param [
|
1717
|
+
# @param [String] key
|
1718
|
+
# @param [Array<String>] attrs array of fields and values
|
1615
1719
|
# @return `"OK"`
|
1616
1720
|
#
|
1617
|
-
# @see #
|
1618
|
-
def
|
1721
|
+
# @see #mapped_hmset
|
1722
|
+
def hmset(key, *attrs)
|
1619
1723
|
synchronize do |client|
|
1620
|
-
client.call [:
|
1724
|
+
client.call [:hmset, key, *attrs]
|
1621
1725
|
end
|
1622
1726
|
end
|
1623
1727
|
|
1624
|
-
# Set one or more values.
|
1728
|
+
# Set one or more hash values.
|
1625
1729
|
#
|
1626
1730
|
# @example
|
1627
|
-
# redis.
|
1731
|
+
# redis.hmset("hash", { "f1" => "v1", "f2" => "v2" })
|
1628
1732
|
# # => "OK"
|
1629
1733
|
#
|
1630
|
-
# @param [
|
1734
|
+
# @param [String] key
|
1735
|
+
# @param [Hash] hash fields mapping to values
|
1631
1736
|
# @return `"OK"`
|
1632
1737
|
#
|
1633
|
-
# @see #
|
1634
|
-
def
|
1635
|
-
|
1738
|
+
# @see #hmset
|
1739
|
+
def mapped_hmset(key, hash)
|
1740
|
+
hmset(key, *hash.to_a.flatten)
|
1636
1741
|
end
|
1637
1742
|
|
1638
|
-
#
|
1639
|
-
#
|
1640
|
-
# @example
|
1641
|
-
# redis.msetnx("key1", "v1", "key2", "v2")
|
1642
|
-
# # => true
|
1643
|
-
#
|
1644
|
-
# @param [Array<String>] args array of keys and values
|
1645
|
-
# @return [Boolean] whether or not all values were set
|
1743
|
+
# Get the value of a hash field.
|
1646
1744
|
#
|
1647
|
-
# @
|
1648
|
-
|
1745
|
+
# @param [String] key
|
1746
|
+
# @param [String] field
|
1747
|
+
# @return [String]
|
1748
|
+
def hget(key, field)
|
1649
1749
|
synchronize do |client|
|
1650
|
-
client.call [:
|
1750
|
+
client.call [:hget, key, field]
|
1651
1751
|
end
|
1652
1752
|
end
|
1653
1753
|
|
1654
|
-
#
|
1754
|
+
# Get the values of all the given hash fields.
|
1655
1755
|
#
|
1656
1756
|
# @example
|
1657
|
-
# redis.
|
1658
|
-
# # =>
|
1757
|
+
# redis.hmget("hash", "f1", "f2")
|
1758
|
+
# # => ["v1", "v2"]
|
1659
1759
|
#
|
1660
|
-
# @param [
|
1661
|
-
# @
|
1760
|
+
# @param [String] key
|
1761
|
+
# @param [Array<String>] fields array of fields
|
1762
|
+
# @return [Array<String>] an array of values for the specified fields
|
1662
1763
|
#
|
1663
|
-
# @see #
|
1664
|
-
def
|
1665
|
-
|
1764
|
+
# @see #mapped_hmget
|
1765
|
+
def hmget(key, *fields, &blk)
|
1766
|
+
synchronize do |client|
|
1767
|
+
client.call [:hmget, key, *fields], &blk
|
1768
|
+
end
|
1666
1769
|
end
|
1667
1770
|
|
1668
|
-
# Get the values of all the given
|
1771
|
+
# Get the values of all the given hash fields.
|
1669
1772
|
#
|
1670
1773
|
# @example
|
1671
|
-
# redis.
|
1672
|
-
# # => { "
|
1774
|
+
# redis.hmget("hash", "f1", "f2")
|
1775
|
+
# # => { "f1" => "v1", "f2" => "v2" }
|
1673
1776
|
#
|
1674
|
-
# @param [
|
1675
|
-
# @
|
1777
|
+
# @param [String] key
|
1778
|
+
# @param [Array<String>] fields array of fields
|
1779
|
+
# @return [Hash] a hash mapping the specified fields to their values
|
1676
1780
|
#
|
1677
|
-
# @see #
|
1678
|
-
def
|
1679
|
-
|
1781
|
+
# @see #hmget
|
1782
|
+
def mapped_hmget(key, *fields)
|
1783
|
+
hmget(key, *fields) do |reply|
|
1680
1784
|
if reply.kind_of?(Array)
|
1681
1785
|
hash = Hash.new
|
1682
|
-
|
1786
|
+
fields.zip(reply).each do |field, value|
|
1683
1787
|
hash[field] = value
|
1684
1788
|
end
|
1685
1789
|
hash
|
@@ -1689,191 +1793,124 @@ class Redis
|
|
1689
1793
|
end
|
1690
1794
|
end
|
1691
1795
|
|
1692
|
-
#
|
1693
|
-
#
|
1694
|
-
# @example Retrieve the first 2 elements from an alphabetically sorted "list"
|
1695
|
-
# redis.sort("list", :order => "alpha", :limit => [0, 2])
|
1696
|
-
# # => ["a", "b"]
|
1697
|
-
# @example Store an alphabetically descending list in "target"
|
1698
|
-
# redis.sort("list", :order => "desc alpha", :store => "target")
|
1699
|
-
# # => 26
|
1796
|
+
# Delete one or more hash fields.
|
1700
1797
|
#
|
1701
1798
|
# @param [String] key
|
1702
|
-
# @param [
|
1703
|
-
#
|
1704
|
-
|
1705
|
-
# of `count` elements
|
1706
|
-
# - `:get => [String, Array<String>]`: single key or array of keys to
|
1707
|
-
# retrieve per element in the result
|
1708
|
-
# - `:order => String`: combination of `ASC`, `DESC` and optionally `ALPHA`
|
1709
|
-
# - `:store => String`: key to store the result at
|
1710
|
-
#
|
1711
|
-
# @return [Array<String>, Array<Array<String>>, Fixnum]
|
1712
|
-
# - when `:get` is not specified, or holds a single element, an array of elements
|
1713
|
-
# - when `:get` is specified, and holds more than one element, an array of
|
1714
|
-
# elements where every element is an array with the result for every
|
1715
|
-
# element specified in `:get`
|
1716
|
-
# - when `:store` is specified, the number of elements in the stored result
|
1717
|
-
def sort(key, options = {})
|
1718
|
-
args = []
|
1719
|
-
|
1720
|
-
by = options[:by]
|
1721
|
-
args.concat ["BY", by] if by
|
1722
|
-
|
1723
|
-
limit = options[:limit]
|
1724
|
-
args.concat ["LIMIT", *limit] if limit
|
1725
|
-
|
1726
|
-
get = Array(options[:get])
|
1727
|
-
args.concat ["GET"].product(get).flatten unless get.empty?
|
1728
|
-
|
1729
|
-
order = options[:order]
|
1730
|
-
args.concat order.split(" ") if order
|
1731
|
-
|
1732
|
-
store = options[:store]
|
1733
|
-
args.concat ["STORE", store] if store
|
1734
|
-
|
1799
|
+
# @param [String, Array<String>] field
|
1800
|
+
# @return [Fixnum] the number of fields that were removed from the hash
|
1801
|
+
def hdel(key, field)
|
1735
1802
|
synchronize do |client|
|
1736
|
-
client.call [:
|
1737
|
-
if get.size > 1
|
1738
|
-
if reply
|
1739
|
-
reply.each_slice(get.size).to_a
|
1740
|
-
end
|
1741
|
-
else
|
1742
|
-
reply
|
1743
|
-
end
|
1744
|
-
end
|
1803
|
+
client.call [:hdel, key, field]
|
1745
1804
|
end
|
1746
1805
|
end
|
1747
1806
|
|
1748
|
-
#
|
1749
|
-
#
|
1750
|
-
# @example
|
1751
|
-
# redis.incr("value")
|
1752
|
-
# # => 6
|
1807
|
+
# Determine if a hash field exists.
|
1753
1808
|
#
|
1754
1809
|
# @param [String] key
|
1755
|
-
# @
|
1756
|
-
|
1810
|
+
# @param [String] field
|
1811
|
+
# @return [Boolean] whether or not the field exists in the hash
|
1812
|
+
def hexists(key, field)
|
1757
1813
|
synchronize do |client|
|
1758
|
-
client.call [:
|
1814
|
+
client.call [:hexists, key, field], &_boolify
|
1759
1815
|
end
|
1760
1816
|
end
|
1761
1817
|
|
1762
|
-
# Increment the integer value of a
|
1763
|
-
#
|
1764
|
-
# @example
|
1765
|
-
# redis.incrby("value", 5)
|
1766
|
-
# # => 10
|
1818
|
+
# Increment the integer value of a hash field by the given integer number.
|
1767
1819
|
#
|
1768
1820
|
# @param [String] key
|
1821
|
+
# @param [String] field
|
1769
1822
|
# @param [Fixnum] increment
|
1770
|
-
# @return [Fixnum] value after incrementing it
|
1771
|
-
def
|
1823
|
+
# @return [Fixnum] value of the field after incrementing it
|
1824
|
+
def hincrby(key, field, increment)
|
1772
1825
|
synchronize do |client|
|
1773
|
-
client.call [:
|
1826
|
+
client.call [:hincrby, key, field, increment]
|
1774
1827
|
end
|
1775
1828
|
end
|
1776
1829
|
|
1777
|
-
# Increment the numeric value of a
|
1778
|
-
#
|
1779
|
-
# @example
|
1780
|
-
# redis.incrbyfloat("value", 1.23)
|
1781
|
-
# # => 1.23
|
1830
|
+
# Increment the numeric value of a hash field by the given float number.
|
1782
1831
|
#
|
1783
1832
|
# @param [String] key
|
1833
|
+
# @param [String] field
|
1784
1834
|
# @param [Float] increment
|
1785
|
-
# @return [Float] value after incrementing it
|
1786
|
-
def
|
1835
|
+
# @return [Float] value of the field after incrementing it
|
1836
|
+
def hincrbyfloat(key, field, increment)
|
1787
1837
|
synchronize do |client|
|
1788
|
-
client.call [:
|
1838
|
+
client.call [:hincrbyfloat, key, field, increment] do |reply|
|
1789
1839
|
Float(reply) if reply
|
1790
1840
|
end
|
1791
1841
|
end
|
1792
1842
|
end
|
1793
1843
|
|
1794
|
-
#
|
1795
|
-
#
|
1796
|
-
# @example
|
1797
|
-
# redis.decr("value")
|
1798
|
-
# # => 4
|
1844
|
+
# Get all the fields in a hash.
|
1799
1845
|
#
|
1800
1846
|
# @param [String] key
|
1801
|
-
# @return [
|
1802
|
-
def
|
1847
|
+
# @return [Array<String>]
|
1848
|
+
def hkeys(key)
|
1803
1849
|
synchronize do |client|
|
1804
|
-
client.call [:
|
1850
|
+
client.call [:hkeys, key]
|
1805
1851
|
end
|
1806
1852
|
end
|
1807
1853
|
|
1808
|
-
#
|
1809
|
-
#
|
1810
|
-
# @example
|
1811
|
-
# redis.decrby("value", 5)
|
1812
|
-
# # => 0
|
1854
|
+
# Get all the values in a hash.
|
1813
1855
|
#
|
1814
1856
|
# @param [String] key
|
1815
|
-
# @
|
1816
|
-
|
1817
|
-
def decrby(key, decrement)
|
1857
|
+
# @return [Array<String>]
|
1858
|
+
def hvals(key)
|
1818
1859
|
synchronize do |client|
|
1819
|
-
client.call [:
|
1860
|
+
client.call [:hvals, key]
|
1820
1861
|
end
|
1821
1862
|
end
|
1822
1863
|
|
1823
|
-
#
|
1864
|
+
# Get all the fields and values in a hash.
|
1824
1865
|
#
|
1825
1866
|
# @param [String] key
|
1826
|
-
# @return [String]
|
1827
|
-
def
|
1867
|
+
# @return [Hash<String, String>]
|
1868
|
+
def hgetall(key)
|
1828
1869
|
synchronize do |client|
|
1829
|
-
client.call [:
|
1870
|
+
client.call [:hgetall, key], &_hashify
|
1830
1871
|
end
|
1831
1872
|
end
|
1832
1873
|
|
1833
|
-
#
|
1834
|
-
|
1835
|
-
# @return [String] `OK`
|
1836
|
-
def quit
|
1874
|
+
# Post a message to a channel.
|
1875
|
+
def publish(channel, message)
|
1837
1876
|
synchronize do |client|
|
1838
|
-
|
1839
|
-
client.call [:quit]
|
1840
|
-
rescue ConnectionError
|
1841
|
-
ensure
|
1842
|
-
client.disconnect
|
1843
|
-
end
|
1877
|
+
client.call [:publish, channel, message]
|
1844
1878
|
end
|
1845
1879
|
end
|
1846
1880
|
|
1847
|
-
|
1848
|
-
def shutdown
|
1881
|
+
def subscribed?
|
1849
1882
|
synchronize do |client|
|
1850
|
-
client.
|
1851
|
-
begin
|
1852
|
-
client.call [:shutdown]
|
1853
|
-
rescue ConnectionError
|
1854
|
-
# This means Redis has probably exited.
|
1855
|
-
nil
|
1856
|
-
end
|
1857
|
-
end
|
1883
|
+
client.kind_of? SubscribedClient
|
1858
1884
|
end
|
1859
1885
|
end
|
1860
1886
|
|
1861
|
-
#
|
1862
|
-
def
|
1887
|
+
# Listen for messages published to the given channels.
|
1888
|
+
def subscribe(*channels, &block)
|
1863
1889
|
synchronize do |client|
|
1864
|
-
|
1890
|
+
_subscription(:subscribe, channels, block)
|
1865
1891
|
end
|
1866
1892
|
end
|
1867
1893
|
|
1868
|
-
|
1894
|
+
# Stop listening for messages posted to the given channels.
|
1895
|
+
def unsubscribe(*channels)
|
1869
1896
|
synchronize do |client|
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1897
|
+
raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed?
|
1898
|
+
client.unsubscribe(*channels)
|
1899
|
+
end
|
1900
|
+
end
|
1901
|
+
|
1902
|
+
# Listen for messages published to channels matching the given patterns.
|
1903
|
+
def psubscribe(*channels, &block)
|
1904
|
+
synchronize do |client|
|
1905
|
+
_subscription(:psubscribe, channels, block)
|
1906
|
+
end
|
1907
|
+
end
|
1908
|
+
|
1909
|
+
# Stop listening for messages posted to channels matching the given patterns.
|
1910
|
+
def punsubscribe(*channels)
|
1911
|
+
synchronize do |client|
|
1912
|
+
raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed?
|
1913
|
+
client.punsubscribe(*channels)
|
1877
1914
|
end
|
1878
1915
|
end
|
1879
1916
|
|
@@ -1936,6 +1973,18 @@ class Redis
|
|
1936
1973
|
end
|
1937
1974
|
end
|
1938
1975
|
|
1976
|
+
def pipelined
|
1977
|
+
synchronize do |client|
|
1978
|
+
begin
|
1979
|
+
original, @client = @client, Pipeline.new
|
1980
|
+
yield(self)
|
1981
|
+
original.call_pipeline(@client)
|
1982
|
+
ensure
|
1983
|
+
@client = original
|
1984
|
+
end
|
1985
|
+
end
|
1986
|
+
end
|
1987
|
+
|
1939
1988
|
# Mark the start of a transaction block.
|
1940
1989
|
#
|
1941
1990
|
# Passing a block is optional.
|
@@ -2013,47 +2062,115 @@ class Redis
|
|
2013
2062
|
end
|
2014
2063
|
end
|
2015
2064
|
|
2016
|
-
#
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2021
|
-
|
2065
|
+
# Control remote script registry.
|
2066
|
+
#
|
2067
|
+
# @example Load a script
|
2068
|
+
# sha = redis.script(:load, "return 1")
|
2069
|
+
# # => <sha of this script>
|
2070
|
+
# @example Check if a script exists
|
2071
|
+
# redis.script(:exists, sha)
|
2072
|
+
# # => true
|
2073
|
+
# @example Check if multiple scripts exist
|
2074
|
+
# redis.script(:exists, [sha, other_sha])
|
2075
|
+
# # => [true, false]
|
2076
|
+
# @example Flush the script registry
|
2077
|
+
# redis.script(:flush)
|
2078
|
+
# # => "OK"
|
2079
|
+
# @example Kill a running script
|
2080
|
+
# redis.script(:kill)
|
2081
|
+
# # => "OK"
|
2082
|
+
#
|
2083
|
+
# @param [String] subcommand e.g. `exists`, `flush`, `load`, `kill`
|
2084
|
+
# @param [Array<String>] args depends on subcommand
|
2085
|
+
# @return [String, Boolean, Array<Boolean>, ...] depends on subcommand
|
2086
|
+
#
|
2087
|
+
# @see #eval
|
2088
|
+
# @see #evalsha
|
2089
|
+
def script(subcommand, *args)
|
2090
|
+
subcommand = subcommand.to_s.downcase
|
2022
2091
|
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
end
|
2027
|
-
end
|
2092
|
+
if subcommand == "exists"
|
2093
|
+
synchronize do |client|
|
2094
|
+
arg = args.first
|
2028
2095
|
|
2029
|
-
|
2030
|
-
|
2031
|
-
synchronize do |client|
|
2032
|
-
raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed?
|
2033
|
-
client.unsubscribe(*channels)
|
2034
|
-
end
|
2035
|
-
end
|
2096
|
+
client.call [:script, :exists, arg] do |reply|
|
2097
|
+
reply = reply.map { |r| _boolify.call(r) }
|
2036
2098
|
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2099
|
+
if arg.is_a?(Array)
|
2100
|
+
reply
|
2101
|
+
else
|
2102
|
+
reply.first
|
2103
|
+
end
|
2104
|
+
end
|
2105
|
+
end
|
2106
|
+
else
|
2107
|
+
synchronize do |client|
|
2108
|
+
client.call [:script, subcommand] + args
|
2109
|
+
end
|
2042
2110
|
end
|
2043
2111
|
end
|
2044
2112
|
|
2045
|
-
|
2046
|
-
|
2113
|
+
def _eval(cmd, args)
|
2114
|
+
script = args.shift
|
2115
|
+
options = args.pop if args.last.is_a?(Hash)
|
2116
|
+
options ||= {}
|
2117
|
+
|
2118
|
+
keys = args.shift || options[:keys] || []
|
2119
|
+
argv = args.shift || options[:argv] || []
|
2120
|
+
|
2047
2121
|
synchronize do |client|
|
2048
|
-
|
2122
|
+
client.call [cmd, script, keys.length] + keys + argv
|
2049
2123
|
end
|
2050
2124
|
end
|
2051
2125
|
|
2052
|
-
#
|
2053
|
-
|
2054
|
-
|
2055
|
-
|
2056
|
-
|
2126
|
+
# Evaluate Lua script.
|
2127
|
+
#
|
2128
|
+
# @example EVAL without KEYS nor ARGV
|
2129
|
+
# redis.eval("return 1")
|
2130
|
+
# # => 1
|
2131
|
+
# @example EVAL with KEYS and ARGV as array arguments
|
2132
|
+
# redis.eval("return { KEYS, ARGV }", ["k1", "k2"], ["a1", "a2"])
|
2133
|
+
# # => [["k1", "k2"], ["a1", "a2"]]
|
2134
|
+
# @example EVAL with KEYS and ARGV in a hash argument
|
2135
|
+
# redis.eval("return { KEYS, ARGV }", :keys => ["k1", "k2"], :argv => ["a1", "a2"])
|
2136
|
+
# # => [["k1", "k2"], ["a1", "a2"]]
|
2137
|
+
#
|
2138
|
+
# @param [Array<String>] keys optional array with keys to pass to the script
|
2139
|
+
# @param [Array<String>] argv optional array with arguments to pass to the script
|
2140
|
+
# @param [Hash] options
|
2141
|
+
# - `:keys => Array<String>`: optional array with keys to pass to the script
|
2142
|
+
# - `:argv => Array<String>`: optional array with arguments to pass to the script
|
2143
|
+
# @return depends on the script
|
2144
|
+
#
|
2145
|
+
# @see #script
|
2146
|
+
# @see #evalsha
|
2147
|
+
def eval(*args)
|
2148
|
+
_eval(:eval, args)
|
2149
|
+
end
|
2150
|
+
|
2151
|
+
# Evaluate Lua script by its SHA.
|
2152
|
+
#
|
2153
|
+
# @example EVALSHA without KEYS nor ARGV
|
2154
|
+
# redis.evalsha(sha)
|
2155
|
+
# # => <depends on script>
|
2156
|
+
# @example EVALSHA with KEYS and ARGV as array arguments
|
2157
|
+
# redis.evalsha(sha, ["k1", "k2"], ["a1", "a2"])
|
2158
|
+
# # => <depends on script>
|
2159
|
+
# @example EVALSHA with KEYS and ARGV in a hash argument
|
2160
|
+
# redis.evalsha(sha, :keys => ["k1", "k2"], :argv => ["a1", "a2"])
|
2161
|
+
# # => <depends on script>
|
2162
|
+
#
|
2163
|
+
# @param [Array<String>] keys optional array with keys to pass to the script
|
2164
|
+
# @param [Array<String>] argv optional array with arguments to pass to the script
|
2165
|
+
# @param [Hash] options
|
2166
|
+
# - `:keys => Array<String>`: optional array with keys to pass to the script
|
2167
|
+
# - `:argv => Array<String>`: optional array with arguments to pass to the script
|
2168
|
+
# @return depends on the script
|
2169
|
+
#
|
2170
|
+
# @see #script
|
2171
|
+
# @see #eval
|
2172
|
+
def evalsha(*args)
|
2173
|
+
_eval(:evalsha, args)
|
2057
2174
|
end
|
2058
2175
|
|
2059
2176
|
def id
|