ruby-redis 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/LICENSE +9 -0
  2. data/README +90 -0
  3. data/bin/ruby-redis +12 -0
  4. data/bin/ruby-redis.compiled.rbc +243 -0
  5. data/lib/redis/bin.rb +74 -0
  6. data/lib/redis/bin.rbc +1325 -0
  7. data/lib/redis/buftok.rbc +2658 -0
  8. data/lib/redis/config.rb +46 -0
  9. data/lib/redis/config.rbc +1009 -0
  10. data/lib/redis/connection.rb +69 -0
  11. data/lib/redis/connection.rbc +1354 -0
  12. data/lib/redis/database.rb +109 -0
  13. data/lib/redis/database.rbc +2275 -0
  14. data/lib/redis/hashes.rb +72 -0
  15. data/lib/redis/hashes.rbc +1843 -0
  16. data/lib/redis/hiredis.rbc +658 -0
  17. data/lib/redis/keys.rb +165 -0
  18. data/lib/redis/keys.rbc +3386 -0
  19. data/lib/redis/lists.rb +227 -0
  20. data/lib/redis/lists.rbc +5241 -0
  21. data/lib/redis/logger.rb +81 -0
  22. data/lib/redis/logger.rbc +2106 -0
  23. data/lib/redis/protocol.rb +170 -0
  24. data/lib/redis/protocol.rbc +3735 -0
  25. data/lib/redis/pubsub.rb +153 -0
  26. data/lib/redis/pubsub.rbc +3447 -0
  27. data/lib/redis/reader.rb +164 -0
  28. data/lib/redis/reader.rbc +2769 -0
  29. data/lib/redis/send.rbc +1268 -0
  30. data/lib/redis/sender.rb +49 -0
  31. data/lib/redis/sender.rbc +1057 -0
  32. data/lib/redis/server.rb +62 -0
  33. data/lib/redis/server.rbc +1177 -0
  34. data/lib/redis/sets.rb +105 -0
  35. data/lib/redis/sets.rbc +2800 -0
  36. data/lib/redis/strict.rb +67 -0
  37. data/lib/redis/strict.rbc +1419 -0
  38. data/lib/redis/strings.rb +144 -0
  39. data/lib/redis/strings.rbc +3338 -0
  40. data/lib/redis/synchrony.rb +58 -0
  41. data/lib/redis/synchrony.rbc +1397 -0
  42. data/lib/redis/version.rb +7 -0
  43. data/lib/redis/version.rbc +180 -0
  44. data/lib/redis/zsets.rb +281 -0
  45. data/lib/redis/zsets.rbc +6596 -0
  46. data/lib/redis.rb +215 -0
  47. data/lib/redis.rbc +4391 -0
  48. metadata +117 -0
data/lib/redis.rb ADDED
@@ -0,0 +1,215 @@
1
+ # for Ruby older than 1.9
2
+ unless Kernel.respond_to?(:require_relative)
3
+ module Kernel
4
+ def require_relative(path)
5
+ require File.join(File.dirname(caller[0]), path.to_str)
6
+ end
7
+ end
8
+ end
9
+
10
+ require 'eventmachine'
11
+ class Redis < EventMachine::Connection ; end
12
+
13
+ require_relative 'redis/version'
14
+ require_relative 'redis/reader'
15
+ require_relative 'redis/sender'
16
+
17
+ class Redis
18
+
19
+ include Sender
20
+
21
+ class Command
22
+ include EventMachine::Deferrable
23
+ def initialize connection
24
+ @connection = connection
25
+ self.errback do |msg|
26
+ # game over on timeout
27
+ @connection.close_connection unless msg
28
+ end
29
+ end
30
+ # EventMachine older than 1.0.0.beta.4 doesn't return self
31
+ test = self.new nil
32
+ unless self === test.callback{}
33
+ def callback; super; self; end
34
+ def errback; super; self; end
35
+ def timeout *args; super; self; end
36
+ end
37
+ end
38
+
39
+ def initialize options={}
40
+ if defined? Hiredis and defined? Hiredis::Reader
41
+ @reader = Hiredis::Reader.new
42
+ else
43
+ @reader = Reader.new
44
+ end
45
+ @queue = []
46
+ @pubsub_callback = proc{}
47
+ end
48
+
49
+ def unbind
50
+ @queue.each { |d| d.fail RuntimeError.new 'connection closed' }
51
+ @queue.clear
52
+ end
53
+
54
+ # Pub/Sub works by sending all orphaned messages to this callback.
55
+ # It is simple and fast but not tolerant to programming errors.
56
+ # Subclass Redis and/or create a defensive layer if you need to.
57
+ def pubsub_callback &block
58
+ @pubsub_callback = block
59
+ end
60
+
61
+ def receive_data data
62
+ @reader.feed data
63
+ until (data = @reader.gets) == false
64
+ deferrable = @queue.shift
65
+ if deferrable
66
+ if Exception === data
67
+ deferrable.fail data
68
+ else
69
+ deferrable.succeed data
70
+ end
71
+ else
72
+ @pubsub_callback.call data
73
+ end
74
+ end
75
+ rescue Exception => e
76
+ @queue.shift.fail e unless @queue.empty?
77
+ close_connection
78
+ end
79
+
80
+ def method_missing method, *args, &block
81
+ deferrable = Command.new self
82
+ if [:subscribe, :psubscribe, :unsubscribe, :punsubscribe].include? method
83
+ deferrable.callback do |data|
84
+ deferrable.succeed nil
85
+ @pubsub_callback.call data
86
+ end
87
+ end
88
+ if transform = self.class.transforms[method]
89
+ deferrable.callback do |data|
90
+ begin
91
+ deferrable.succeed transform.call data
92
+ rescue Exception => e
93
+ deferrable.fail e
94
+ end
95
+ end
96
+ end
97
+ deferrable.callback &block if block
98
+ @queue.push deferrable
99
+ send_redis args.reduce([method]){ |arr, arg|
100
+ if Hash === arg
101
+ arr += arg.to_a.flatten 1
102
+ else
103
+ arr << arg
104
+ end
105
+ }
106
+ deferrable
107
+ end
108
+
109
+ # Yielded by multi_exec to proxy and collect commands
110
+ class Multi < Command
111
+ include Enumerable
112
+ def initialize *args
113
+ super
114
+ @commands = []
115
+ end
116
+ def each
117
+ @commands.each {|x|yield x}
118
+ end
119
+ def size
120
+ @commands.size
121
+ end
122
+ def method_missing method, *args, &block
123
+ command = @connection.send method, *args, &block
124
+ proxy = Command.new @connection
125
+ command.callback do |status|
126
+ @commands << proxy
127
+ end
128
+ command.errback do |err|
129
+ @commands << err
130
+ proxy.fail err
131
+ end
132
+ proxy
133
+ end
134
+ end
135
+
136
+ # Wrap around multi and exec. Leaves the raw calls
137
+ # to multi and exec open for custom implementations.
138
+ def multi_exec
139
+ self.multi.errback do |r|
140
+ # This usually happens in the case of a programming error.
141
+ # Sometimes it is called when the connection breaks.
142
+ self.close_connection
143
+ end
144
+ error = nil
145
+ begin
146
+ yield redis_multi = Multi.new(self)
147
+ rescue Exception => e
148
+ error = e
149
+ end
150
+ redis_exec = self.exec
151
+ if error
152
+ EM.next_tick { redis_exec.fail error }
153
+ end
154
+ redis_exec.callback do |results|
155
+ # Normalized results include syntax errors and original references.
156
+ # Command callbacks are meant to run before exec callbacks.
157
+ if results == nil
158
+ redis_exec.succeed nil
159
+ else
160
+ normalized_results = []
161
+ redis_multi.each do |command|
162
+ if Exception === command
163
+ normalized_results << command
164
+ else
165
+ result = results.shift
166
+ normalized_results << result
167
+ if Exception === result
168
+ command.fail result
169
+ else
170
+ command.succeed result
171
+ end
172
+ end
173
+ end
174
+ redis_exec.succeed normalized_results
175
+ end
176
+ end
177
+ end
178
+
179
+ # Some data is best transformed into a Ruby type. You can set up global
180
+ # transforms here that are automatically attached to command callbacks.
181
+ # Redis.transforms[:mycustom1] = Redis.transforms[:exists] # boolean
182
+ # Redis.transforms[:mycustom2] = proc { |data| MyType.new data }
183
+ def self.transforms
184
+ @@transforms ||= lambda {
185
+ boolean = lambda { |tf| tf[0] == 1 ? true : false }
186
+ hash = lambda { |hash| Hash[*hash] }
187
+ {
188
+ #keys
189
+ :exists => boolean,
190
+ :expire => boolean,
191
+ :expireat => boolean,
192
+ :move => boolean,
193
+ :persist => boolean,
194
+ :renamenx => boolean,
195
+ #strings
196
+ :msetnx => boolean,
197
+ :setnx => boolean,
198
+ #hashes
199
+ :hexists => boolean,
200
+ :hgetall => hash,
201
+ :hset => boolean,
202
+ :hsetnx => boolean,
203
+ #sets
204
+ :sismember => boolean,
205
+ :smove => boolean,
206
+ :srem => boolean,
207
+ #zsets
208
+ :zrem => boolean,
209
+ }
210
+ }.call
211
+ end
212
+
213
+
214
+ end
215
+