winescout-redis-rb 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,462 @@
1
+ require 'socket'
2
+ require 'set'
3
+ require File.join(File.dirname(__FILE__),'server')
4
+
5
+
6
+ class RedisError < StandardError
7
+ end
8
+ class RedisRenameError < StandardError
9
+ end
10
+ class Redis
11
+ ERR = "-".freeze
12
+ OK = 'OK'.freeze
13
+ SINGLE = '+'.freeze
14
+ BULK = '$'.freeze
15
+ MULTI = '*'.freeze
16
+ INT = ':'.freeze
17
+
18
+ attr_reader :server
19
+
20
+
21
+ def initialize(opts={})
22
+ @opts = {:host => 'localhost', :port => '6379'}.merge(opts)
23
+ $debug = @opts[:debug]
24
+ @server = Server.new(@opts[:host], @opts[:port])
25
+ end
26
+
27
+ def to_s
28
+ "#{host}:#{port}"
29
+ end
30
+
31
+ def port
32
+ @opts[:port]
33
+ end
34
+
35
+ def host
36
+ @opts[:host]
37
+ end
38
+
39
+ def with_socket_management(server, &block)
40
+ begin
41
+ block.call(server.socket)
42
+ #Timeout or server down
43
+ rescue Errno::ECONNRESET, Errno::EPIPE, Errno::ECONNREFUSED => e
44
+ server.close
45
+ puts "Client (#{server.inspect}) disconnected from server: #{e.inspect}\n" if $debug
46
+ retry
47
+ #Server down
48
+ rescue NoMethodError => e
49
+ puts "Client (#{server.inspect}) tryin server that is down: #{e.inspect}\n Dying!" if $debug
50
+ raise Errno::ECONNREFUSED
51
+ #exit
52
+ end
53
+ end
54
+
55
+ def monitor
56
+ ensure_retry do
57
+ with_socket_management(@server) do |socket|
58
+ trap("INT") { puts "\nGot ^C! Dying!"; exit }
59
+ write "MONITOR\r\n"
60
+ puts "Now Monitoring..."
61
+ socket.read(12)
62
+ loop do
63
+ x = socket.gets
64
+ puts x unless x.nil?
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ def quit
71
+ write "QUIT\r\n"
72
+ end
73
+
74
+ def select_db(index)
75
+ write "SELECT #{index}\r\n"
76
+ get_response
77
+ end
78
+
79
+ def flush_db
80
+ write "FLUSHDB\r\n"
81
+ get_response == OK
82
+ end
83
+
84
+ def last_save
85
+ write "LASTSAVE\r\n"
86
+ get_response.to_i
87
+ end
88
+
89
+ def bgsave
90
+ write "BGSAVE\r\n"
91
+ get_response == OK
92
+ end
93
+
94
+ def info
95
+ info = {}
96
+ write("INFO\r\n")
97
+ x = get_response
98
+ x.each do |kv|
99
+ k,v = kv.split(':', 2)
100
+ k,v = k.chomp, v = v.chomp
101
+ info[k.to_sym] = v
102
+ end
103
+ info
104
+ end
105
+
106
+
107
+ def bulk_reply
108
+ begin
109
+ x = read.chomp
110
+ puts "bulk_reply read value is #{x.inspect}" if $debug
111
+ return x
112
+ rescue => e
113
+ puts "error in bulk_reply #{e}" if $debug
114
+ nil
115
+ end
116
+ end
117
+
118
+ def write(data)
119
+ with_socket_management(@server) do |socket|
120
+ puts "writing: #{data}" if $debug
121
+ socket.write(data)
122
+ end
123
+ end
124
+
125
+ def fetch(len)
126
+ with_socket_management(@server) do |socket|
127
+ len = [0, len.to_i].max
128
+ res = socket.read(len + 2)
129
+ res = res.chomp if res
130
+ res
131
+ end
132
+ end
133
+
134
+ def read(length = read_proto)
135
+ with_socket_management(@server) do |socket|
136
+ res = socket.read(length)
137
+ puts "read is #{res.inspect}" if $debug
138
+ res
139
+ end
140
+ end
141
+
142
+ def keys(glob)
143
+ write "KEYS #{glob}\r\n"
144
+ get_response.split(' ')
145
+ end
146
+
147
+ def rename!(oldkey, newkey)
148
+ write "RENAME #{oldkey} #{newkey}\r\n"
149
+ get_response
150
+ end
151
+
152
+ def rename(oldkey, newkey)
153
+ write "RENAMENX #{oldkey} #{newkey}\r\n"
154
+ case get_response
155
+ when -1
156
+ raise RedisRenameError, "source key: #{oldkey} does not exist"
157
+ when 0
158
+ raise RedisRenameError, "target key: #{oldkey} already exists"
159
+ when -3
160
+ raise RedisRenameError, "source and destination keys are the same"
161
+ when 1
162
+ true
163
+ end
164
+ end
165
+
166
+ def key?(key)
167
+ write "EXISTS #{key}\r\n"
168
+ get_response == 1
169
+ end
170
+
171
+ def delete(key)
172
+ write "DEL #{key}\r\n"
173
+ get_response == 1
174
+ end
175
+
176
+ def [](key)
177
+ get(key)
178
+ end
179
+
180
+ def get(key)
181
+ write "GET #{key}\r\n"
182
+ get_response
183
+ end
184
+
185
+ def mget(*keys)
186
+ write "MGET #{keys.join(' ')}\r\n"
187
+ get_response
188
+ end
189
+
190
+ def incr(key, increment=nil)
191
+ if increment
192
+ write "INCRBY #{key} #{increment}\r\n"
193
+ else
194
+ write "INCR #{key}\r\n"
195
+ end
196
+ get_response
197
+ end
198
+
199
+ def decr(key, decrement=nil)
200
+ if decrement
201
+ write "DECRRBY #{key} #{decrement}\r\n"
202
+ else
203
+ write "DECR #{key}\r\n"
204
+ end
205
+ get_response
206
+ end
207
+
208
+ def randkey
209
+ write "RANDOMKEY\r\n"
210
+ get_response
211
+ end
212
+
213
+ def list_length(key)
214
+ write "LLEN #{key}\r\n"
215
+ case i = get_response
216
+ when -2
217
+ raise RedisError, "key: #{key} does not hold a list value"
218
+ else
219
+ i
220
+ end
221
+ end
222
+
223
+ def type?(key)
224
+ write "TYPE #{key}\r\n"
225
+ get_response
226
+ end
227
+
228
+ def push_tail(key, string)
229
+ write "RPUSH #{key} #{string.to_s.size}\r\n#{string.to_s}\r\n"
230
+ get_response
231
+ end
232
+
233
+ def push_head(key, string)
234
+ write "LPUSH #{key} #{string.to_s.size}\r\n#{string.to_s}\r\n"
235
+ get_response
236
+ end
237
+
238
+ def pop_head(key)
239
+ write "LPOP #{key}\r\n"
240
+ get_response
241
+ end
242
+
243
+ def pop_tail(key)
244
+ write "RPOP #{key}\r\n"
245
+ get_response
246
+ end
247
+
248
+ def list_set(key, index, val)
249
+ write "LSET #{key} #{index} #{val.to_s.size}\r\n#{val}\r\n"
250
+ get_response == OK
251
+ end
252
+
253
+ def list_length(key)
254
+ write "LLEN #{key}\r\n"
255
+ case i = get_response
256
+ when -2
257
+ raise RedisError, "key: #{key} does not hold a list value"
258
+ else
259
+ i
260
+ end
261
+ end
262
+
263
+ def list_range(key, start, ending)
264
+ write "LRANGE #{key} #{start} #{ending}\r\n"
265
+ get_response
266
+ end
267
+
268
+ def list_trim(key, start, ending)
269
+ write "LTRIM #{key} #{start} #{ending}\r\n"
270
+ get_response
271
+ end
272
+
273
+ def list_index(key, index)
274
+ write "LINDEX #{key} #{index}\r\n"
275
+ get_response
276
+ end
277
+
278
+ def list_rm(key, count, value)
279
+ write "LREM #{key} #{count} #{value.to_s.size}\r\n#{value}\r\n"
280
+ case num = get_response
281
+ when -1
282
+ raise RedisError, "key: #{key} does not exist"
283
+ when -2
284
+ raise RedisError, "key: #{key} does not hold a list value"
285
+ else
286
+ num
287
+ end
288
+ end
289
+
290
+ def set_add(key, member)
291
+ write "SADD #{key} #{member.to_s.size}\r\n#{member}\r\n"
292
+ case get_response
293
+ when 1
294
+ true
295
+ when 0
296
+ false
297
+ when -2
298
+ raise RedisError, "key: #{key} contains a non set value"
299
+ end
300
+ end
301
+
302
+ def set_delete(key, member)
303
+ write "SREM #{key} #{member.to_s.size}\r\n#{member}\r\n"
304
+ case get_response
305
+ when 1
306
+ true
307
+ when 0
308
+ false
309
+ when -2
310
+ raise RedisError, "key: #{key} contains a non set value"
311
+ end
312
+ end
313
+
314
+ def set_count(key)
315
+ write "SCARD #{key}\r\n"
316
+ case i = get_response
317
+ when -2
318
+ raise RedisError, "key: #{key} contains a non set value"
319
+ else
320
+ i
321
+ end
322
+ end
323
+
324
+ def set_member?(key, member)
325
+ write "SISMEMBER #{key} #{member.to_s.size}\r\n#{member}\r\n"
326
+ case get_response
327
+ when 1
328
+ true
329
+ when 0
330
+ false
331
+ when -2
332
+ raise RedisError, "key: #{key} contains a non set value"
333
+ end
334
+ end
335
+
336
+ def set_members(key)
337
+ write "SMEMBERS #{key}\r\n"
338
+ Set.new(get_response)
339
+ end
340
+
341
+ def set_intersect(*keys)
342
+ write "SINTER #{keys.join(' ')}\r\n"
343
+ Set.new(get_response)
344
+ end
345
+
346
+ def set_inter_store(destkey, *keys)
347
+ write "SINTERSTORE #{destkey} #{keys.join(' ')}\r\n"
348
+ get_response
349
+ end
350
+
351
+ def sort(key, opts={})
352
+ cmd = "SORT #{key}"
353
+ cmd << " BY #{opts[:by]}" if opts[:by]
354
+ cmd << " GET #{opts[:get]}" if opts[:get]
355
+ cmd << " INCR #{opts[:incr]}" if opts[:incr]
356
+ cmd << " DEL #{opts[:del]}" if opts[:del]
357
+ cmd << " DECR #{opts[:decr]}" if opts[:decr]
358
+ cmd << " #{opts[:order]}" if opts[:order]
359
+ cmd << " LIMIT #{opts[:limit].join(' ')}" if opts[:limit]
360
+ cmd << "\r\n"
361
+ write(cmd)
362
+ get_response
363
+ end
364
+
365
+ def multi_bulk
366
+ res = read_proto
367
+ puts "mb res is #{res.inspect}" if $debug
368
+ list = []
369
+ Integer(res).times do
370
+ vf = get_response
371
+ puts "curren vf is #{vf.inspect}" if $debug
372
+ list << vf
373
+ puts "current list is #{list.inspect}" if $debug
374
+ end
375
+ list
376
+ end
377
+
378
+ def get_reply
379
+ begin
380
+ r = read(1)
381
+ raise RedisError if (r == "\r" || r == "\n")
382
+ rescue RedisError
383
+ retry
384
+ end
385
+ r
386
+ end
387
+
388
+ def []=(key, val)
389
+ set(key,val)
390
+ end
391
+
392
+
393
+ def set(key, val, expiry=nil)
394
+ write("SET #{key} #{val.to_s.size}\r\n#{val}\r\n")
395
+ get_response == OK
396
+ end
397
+
398
+ def set_unless_exists(key, val)
399
+ write "SETNX #{key} #{val.to_s.size}\r\n#{val}\r\n"
400
+ get_response == 1
401
+ end
402
+
403
+ def status_code_reply
404
+ begin
405
+ res = read_proto
406
+ if res.index('-') == 0
407
+ raise RedisError, res
408
+ else
409
+ true
410
+ end
411
+ rescue RedisError
412
+ raise RedisError
413
+ end
414
+ end
415
+
416
+ def get_response
417
+ begin
418
+ rtype = get_reply
419
+ rescue => e
420
+ raise RedisError, e.inspect
421
+ end
422
+ puts "reply_type is #{rtype.inspect}" if $debug
423
+ case rtype
424
+ when SINGLE
425
+ single_line
426
+ when BULK
427
+ bulk_reply
428
+ when MULTI
429
+ multi_bulk
430
+ when INT
431
+ integer_reply
432
+ when ERR
433
+ raise RedisError, single_line
434
+ else
435
+ raise RedisError, "Unknown response.."
436
+ end
437
+ end
438
+
439
+ def integer_reply
440
+ Integer(read_proto)
441
+ end
442
+
443
+ def single_line
444
+ buff = ""
445
+ while buff[-2..-1] != "\r\n"
446
+ buff << read(1)
447
+ end
448
+ puts "single_line value is #{buff[0..-3].inspect}" if $debug
449
+ buff[0..-3]
450
+ end
451
+
452
+ def read_proto
453
+ with_socket_management(@server) do |socket|
454
+ if res = socket.gets
455
+ x = res.chomp
456
+ puts "read_proto is #{x.inspect}\n\n" if $debug
457
+ x.to_i
458
+ end
459
+ end
460
+ end
461
+
462
+ end