redis 1.0.7 → 2.0.0.rc1

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.
@@ -2,6 +2,14 @@
2
2
 
3
3
  A Ruby client library for the [Redis](http://code.google.com/p/redis) key-value store.
4
4
 
5
+ ## A note about versions
6
+
7
+ Versions *1.0.x* target all versions of Redis. You have to use this one if you are using Redis < 1.2.
8
+
9
+ Version *2.0* is a big refactoring of the previous version and makes little effort to be
10
+ backwards-compatible when it shouldn't. It does not support Redis' original protocol, favoring the
11
+ new, binary-safe one. You should be using this version if you're running Redis 1.2+.
12
+
5
13
  ## Information about Redis
6
14
 
7
15
  Redis is a key-value store with some interesting features:
@@ -1,15 +1,479 @@
1
1
  require 'socket'
2
2
 
3
3
  class Redis
4
- VERSION = "1.0.7"
4
+ VERSION = "2.0.0.rc1"
5
5
 
6
- def self.new(*attrs)
7
- Client.new(*attrs)
6
+ class ProtocolError < RuntimeError
7
+ def initialize(reply_type)
8
+ super("Protocol error, got '#{reply_type}' as initial reply byte")
9
+ end
8
10
  end
9
11
 
10
12
  def self.deprecate(message, trace = caller[0])
11
13
  $stderr.puts "\n#{message} (in #{trace})"
12
14
  end
15
+
16
+ attr :client
17
+
18
+ def self.connect(options = {})
19
+ require "uri"
20
+
21
+ url = URI(options.delete(:url) || ENV["REDIS_URL"] || "redis://127.0.0.1:6379/0")
22
+
23
+ options[:host] = url.host
24
+ options[:port] = url.port
25
+ options[:password] = url.password
26
+ options[:db] = url.path[1..-1].to_i
27
+
28
+ new(options)
29
+ end
30
+
31
+ def initialize(options = {})
32
+ @client = Client.new(options)
33
+ end
34
+
35
+ def select(db)
36
+ @client.db = db
37
+ @client.call(:select, db)
38
+ end
39
+
40
+ def info
41
+ Hash[*@client.call(:info).split(/:|\r\n/)]
42
+ end
43
+
44
+ def flushdb
45
+ @client.call(:flushdb)
46
+ end
47
+
48
+ def save
49
+ @client.call(:save)
50
+ end
51
+
52
+ def bgsave
53
+ @client.call(:bgsave)
54
+ end
55
+
56
+ def get(key)
57
+ @client.call(:get, key)
58
+ end
59
+
60
+ def getset(key, value)
61
+ @client.call(:getset, key, value)
62
+ end
63
+
64
+ def mget(*keys)
65
+ @client.call(:mget, *keys)
66
+ end
67
+
68
+ def hgetall(key)
69
+ Hash[*@client.call(:hgetall, key)]
70
+ end
71
+
72
+ def hget(key, field)
73
+ @client.call(:hget, key, field)
74
+ end
75
+
76
+ def hdel(key, field)
77
+ @client.call(:hdel, key, field)
78
+ end
79
+
80
+ def hkeys(key)
81
+ @client.call(:hkeys, key)
82
+ end
83
+
84
+ def keys(pattern = "*")
85
+ @client.call(:keys, pattern)
86
+ end
87
+
88
+ def randomkey
89
+ @client.call(:randomkey)
90
+ end
91
+
92
+ def echo(value)
93
+ @client.call(:echo, value)
94
+ end
95
+
96
+ def ping
97
+ @client.call(:ping)
98
+ end
99
+
100
+ def lastsave
101
+ @client.call(:lastsave)
102
+ end
103
+
104
+ def dbsize
105
+ @client.call(:dbsize)
106
+ end
107
+
108
+ def exists(key)
109
+ _bool @client.call(:exists, key)
110
+ end
111
+
112
+ def llen(key)
113
+ @client.call(:llen, key)
114
+ end
115
+
116
+ def lrange(key, start, stop)
117
+ @client.call(:lrange, key, start, stop)
118
+ end
119
+
120
+ def ltrim(key, start, stop)
121
+ @client.call(:ltrim, key, start, stop)
122
+ end
123
+
124
+ def lindex(key, index)
125
+ @client.call(:lindex, key, index)
126
+ end
127
+
128
+ def lset(key, index, value)
129
+ @client.call(:lset, key, index, value)
130
+ end
131
+
132
+ def lrem(key, count, value)
133
+ @client.call(:lrem, key, count, value)
134
+ end
135
+
136
+ def rpush(key, value)
137
+ @client.call(:rpush, key, value)
138
+ end
139
+
140
+ def lpush(key, value)
141
+ @client.call(:lpush, key, value)
142
+ end
143
+
144
+ def rpop(key)
145
+ @client.call(:rpop, key)
146
+ end
147
+
148
+ def blpop(key, timeout)
149
+ @client.call_blocking(:blpop, key, timeout)
150
+ end
151
+
152
+ def brpop(key, timeout)
153
+ @client.call_blocking(:brpop, key, timeout)
154
+ end
155
+
156
+ def rpoplpush(source, destination)
157
+ @client.call(:rpoplpush, source, destination)
158
+ end
159
+
160
+ def lpop(key)
161
+ @client.call(:lpop, key)
162
+ end
163
+
164
+ def smembers(key)
165
+ @client.call(:smembers, key)
166
+ end
167
+
168
+ def sismember(key, member)
169
+ _bool @client.call(:sismember, key, member)
170
+ end
171
+
172
+ def sadd(key, value)
173
+ _bool @client.call(:sadd, key, value)
174
+ end
175
+
176
+ def srem(key, value)
177
+ _bool @client.call(:srem, key, value)
178
+ end
179
+
180
+ def smove(source, destination, member)
181
+ _bool @client.call(:smove, source, destination, member)
182
+ end
183
+
184
+ def spop(key)
185
+ @client.call(:spop, key)
186
+ end
187
+
188
+ def scard(key)
189
+ @client.call(:scard, key)
190
+ end
191
+
192
+ def sinter(*keys)
193
+ @client.call(:sinter, *keys)
194
+ end
195
+
196
+ def sinterstore(destination, *keys)
197
+ @client.call(:sinterstore, destination, *keys)
198
+ end
199
+
200
+ def sunion(*keys)
201
+ @client.call(:sunion, *keys)
202
+ end
203
+
204
+ def sunionstore(destination, *keys)
205
+ @client.call(:sunionstore, destination, *keys)
206
+ end
207
+
208
+ def sdiff(*keys)
209
+ @client.call(:sdiff, *keys)
210
+ end
211
+
212
+ def sdiffstore(destination, *keys)
213
+ @client.call(:sdiffstore, destination, *keys)
214
+ end
215
+
216
+ def srandmember(key)
217
+ @client.call(:srandmember, key)
218
+ end
219
+
220
+ def zadd(key, score, member)
221
+ _bool @client.call(:zadd, key, score, member)
222
+ end
223
+
224
+ def zincrby(key, increment, member)
225
+ @client.call(:zincrby, key, increment, member)
226
+ end
227
+
228
+ def zcard(key)
229
+ @client.call(:zcard, key)
230
+ end
231
+
232
+ def zrange(key, start, stop, with_scores = false)
233
+ if with_scores
234
+ @client.call(:zrange, key, start, stop, "WITHSCORES")
235
+ else
236
+ @client.call(:zrange, key, start, stop)
237
+ end
238
+ end
239
+
240
+ def zrangebyscore(key, min, max)
241
+ @client.call(:zrangebyscore, key, min, max)
242
+ end
243
+
244
+ def zrevrange(key, start, stop, with_scores = false)
245
+ if with_scores
246
+ @client.call(:zrevrange, key, start, stop, "WITHSCORES")
247
+ else
248
+ @client.call(:zrevrange, key, start, stop)
249
+ end
250
+ end
251
+
252
+ def zscore(key, member)
253
+ @client.call(:zscore, key, member)
254
+ end
255
+
256
+ def zrem(key, member)
257
+ _bool @client.call(:zrem, key, member)
258
+ end
259
+
260
+ def move(key, db)
261
+ _bool @client.call(:move, key, db)
262
+ end
263
+
264
+ def setnx(key, value)
265
+ _bool @client.call(:setnx, key, value)
266
+ end
267
+
268
+ def del(*keys)
269
+ _bool @client.call(:del, *keys)
270
+ end
271
+
272
+ def rename(old_name, new_name)
273
+ @client.call(:rename, old_name, new_name)
274
+ end
275
+
276
+ def renamenx(old_name, new_name)
277
+ _bool @client.call(:renamenx, old_name, new_name)
278
+ end
279
+
280
+ def expire(key, seconds)
281
+ _bool @client.call(:expire, key, seconds)
282
+ end
283
+
284
+ def ttl(key)
285
+ @client.call(:ttl, key)
286
+ end
287
+
288
+ def expireat(key, unix_time)
289
+ _bool @client.call(:expireat, key, unix_time)
290
+ end
291
+
292
+ def hset(key, field, value)
293
+ _bool @client.call(:hset, key, field, value)
294
+ end
295
+
296
+ def hmset(key, *attrs)
297
+ @client.call(:hmset, key, *attrs)
298
+ end
299
+
300
+ def hlen(key)
301
+ @client.call(:hlen, key)
302
+ end
303
+
304
+ def hvals(key)
305
+ @client.call(:hvals, key)
306
+ end
307
+
308
+ def discard
309
+ @client.call(:discard)
310
+ end
311
+
312
+ def hexists(key, field)
313
+ _bool @client.call(:hexists, key, field)
314
+ end
315
+
316
+ def monitor
317
+ raise NotImplementedError
318
+ end
319
+
320
+ def [](key)
321
+ get(key)
322
+ end
323
+
324
+ def []=(key,value)
325
+ set(key, value)
326
+ end
327
+
328
+ def set(key, value)
329
+ @client.call(:set, key, value)
330
+ end
331
+
332
+ def setex(key, ttl, value)
333
+ @client.call(:setex, key, ttl, value)
334
+ end
335
+
336
+ def mset(*args)
337
+ @client.call(:mset, *args)
338
+ end
339
+
340
+ def mapped_mset(hash)
341
+ mset(*hash.to_a.flatten)
342
+ end
343
+
344
+ def msetnx(*args)
345
+ @client.call(:msetnx, *args)
346
+ end
347
+
348
+ def mapped_msetnx(hash)
349
+ msetnx(*hash.to_a.flatten)
350
+ end
351
+
352
+ def mapped_mget(*keys)
353
+ result = {}
354
+ mget(*keys).each do |value|
355
+ key = keys.shift
356
+ result.merge!(key => value) unless value.nil?
357
+ end
358
+ result
359
+ end
360
+
361
+ def sort(key, options = {})
362
+ cmd = []
363
+ cmd << "SORT"
364
+ cmd << key
365
+ cmd += ["BY", options[:by]] if options[:by]
366
+
367
+ Array(options[:get]).each do |k|
368
+ cmd += ["GET", k]
369
+ end if options[:get]
370
+
371
+ cmd += options[:order].split(" ") if options[:order]
372
+ cmd += ["LIMIT", *options[:limit]] if options[:limit]
373
+ cmd += ["STORE", options[:store]] if options[:store]
374
+
375
+ @client.call(*cmd)
376
+ end
377
+
378
+ def incr(key)
379
+ @client.call(:incr, key)
380
+ end
381
+
382
+ def incrby(key, increment)
383
+ @client.call(:incrby, key, increment)
384
+ end
385
+
386
+ def decr(key)
387
+ @client.call(:decr, key)
388
+ end
389
+
390
+ def decrby(key, decrement)
391
+ @client.call(:decrby, key, decrement)
392
+ end
393
+
394
+ def type(key)
395
+ @client.call(:type, key)
396
+ end
397
+
398
+ def quit
399
+ @client.call(:quit)
400
+ rescue Errno::ECONNRESET
401
+ end
402
+
403
+ def pipelined
404
+ original, @client = @client, Pipeline.new
405
+ yield
406
+ original.call_pipelined(@client.commands) unless @client.commands.empty?
407
+ ensure
408
+ @client = original
409
+ end
410
+
411
+ def exec
412
+ @client.call(:exec)
413
+ end
414
+
415
+ def multi(&block)
416
+ result = @client.call :multi
417
+
418
+ return result unless block_given?
419
+
420
+ begin
421
+ yield(self)
422
+ exec
423
+ rescue Exception => e
424
+ discard
425
+ raise e
426
+ end
427
+ end
428
+
429
+ def publish(channel, message)
430
+ @client.call(:publish, channel, message)
431
+ end
432
+
433
+ def unsubscribe(*channels)
434
+ if @client.kind_of?(SubscribedClient)
435
+ @client = @client.unsubscribe(*channels)
436
+ else
437
+ @client.call(:unsubscribe, *channels)
438
+ end
439
+ end
440
+
441
+ def subscribe(*channels, &block)
442
+ if @client.kind_of?(SubscribedClient)
443
+ @client.call(:subscribe, *channels)
444
+ else
445
+ begin
446
+ original, @client = @client, SubscribedClient.new(@client)
447
+ @client.subscribe(*channels, &block)
448
+ ensure
449
+ @client = original
450
+ end
451
+ end
452
+ end
453
+
454
+ def psubscribe(*channels, &block)
455
+ if @client.kind_of?(SubscribedClient)
456
+ @client.call(:psubscribe, *channels)
457
+ else
458
+ begin
459
+ original, @client = @client, SubscribedClient.new(@client)
460
+ @client.psubscribe(*channels, &block)
461
+ ensure
462
+ @client = original
463
+ end
464
+ end
465
+ end
466
+
467
+ def method_missing(command, *args)
468
+ @client.call(command, *args)
469
+ end
470
+
471
+ private
472
+
473
+ def _bool(value)
474
+ value == 1
475
+ end
476
+
13
477
  end
14
478
 
15
479
  begin