redis 1.0.7 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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