redis_wrapper 0.1.0 → 0.2.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/README.md CHANGED
@@ -0,0 +1,3 @@
1
+ # Redis Wrapper
2
+
3
+ Redis Wrapper is built on top of the [redis-rb](https://github.com/ezmobius/redis-rb) library as a communication method between ruby code and redis. Redis-rb handles all the connection to the database store, while redis_wrapper supplies a more convient interface on which to communicate. All methods available via redis-rb are accessible by the wrapper, but allows objects other than strings to be passed in.
@@ -1,17 +1,170 @@
1
1
  module RedisWrapper
2
2
  class RedisWrapper
3
+ attr_accessor :namespace
4
+ # The following table defines how input parameters and result
5
+ # values should be modified for the namespace along with Object compression.
6
+ # Thanks is due to defunkt and his gem, https://github.com/defunkt/redis-namespace as
7
+ # inspiration on how to solve this problem.
8
+ #
9
+ # COMMANDS is a hash. Each key is the name of a command and each
10
+ # value is a hash itself. The namespace key holds an 2 value array, determining the process of
11
+ # how to merge on the namespace. The options key, holds a hash that is merged onto the other options passed
12
+ # This insures that some commands like AUTH, are enforced to be raw true so Entry doesn't alter the command.
13
+ #
14
+ # The first element in the value array describes how to modify the
15
+ # arguments passed. It can be one of:
16
+ #
17
+ # nil
18
+ # Do nothing.
19
+ # :first
20
+ # Add the namespace to the first argument passed, e.g.
21
+ # GET key => GET namespace:key
22
+ # :all
23
+ # Add the namespace to all arguments passed, e.g.
24
+ # MGET key1 key2 => MGET namespace:key1 namespace:key2
25
+ # :exclude_first
26
+ # Add the namespace to all arguments but the first, e.g.
27
+ # :exclude_last
28
+ # Add the namespace to all arguments but the last, e.g.
29
+ # BLPOP key1 key2 timeout =>
30
+ # BLPOP namespace:key1 namespace:key2 timeout
31
+ # :exclude_options
32
+ # Add the namespace to all arguments, except the last argument,
33
+ # if the last argument is a hash of options.
34
+ # ZUNIONSTORE key1 2 key2 key3 WEIGHTS 2 1 =>
35
+ # ZUNIONSTORE namespace:key1 2 namespace:key2 namespace:key3 WEIGHTS 2 1
36
+ # :alternate
37
+ # Add the namespace to every other argument, e.g.
38
+ # MSET key1 value1 key2 value2 =>
39
+ # MSET namespace:key1 value1 namespace:key2 value2
40
+ #
41
+ # The second element in the value array describes how to modify
42
+ # the return value of the Redis call. It can be one of:
43
+ #
44
+ # nil
45
+ # Do nothing.
46
+ # :all
47
+ # Add the namespace to all elements returned, e.g.
48
+ # key1 key2 => namespace:key1 namespace:key2
49
+ COMMANDS = {
50
+ :auth => {:namespace=>[],:options=>{:raw=>true}},
51
+ :bgrewriteaof => {:namespace=>[], :options=>{}},
52
+ :bgsave => {:namespace=>[], :options=>{}},
53
+ :blpop => {:namespace=>[ :exclude_last, :first ], :options=>{}},
54
+ :brpop => {:namespace=>[ :exclude_last ], :options=>{}},
55
+ :dbsize => {:namespace=>[], :options=>{}},
56
+ :debug => {:namespace=>[ :exclude_first ], :options=>{}},
57
+ :decr => {:namespace=>[ :first ], :options=>{}},
58
+ :decrby => {:namespace=>[ :first ], :options=>{}},
59
+ :del => {:namespace=>[ :all ], :options=>{}},
60
+ :exists => {:namespace=>[ :first ], :options=>{}},
61
+ :expire => {:namespace=>[ :first ], :options=>{}},
62
+ :expireat => {:namespace=>[ :first ], :options=>{}},
63
+ :flushall => {:namespace=>[], :options=>{}},
64
+ :flushdb => {:namespace=>[], :options=>{}},
65
+ :get => {:namespace=>[ :first ], :options=>{}},
66
+ :getset => {:namespace=>[ :first ], :options=>{}},
67
+ :hset => {:namespace=>[ :first ], :options=>{}},
68
+ :hsetnx => {:namespace=>[ :first ], :options=>{}},
69
+ :hget => {:namespace=>[ :first ], :options=>{}},
70
+ :hincrby => {:namespace=>[ :first ], :options=>{}},
71
+ :hmget => {:namespace=>[ :first ], :options=>{}},
72
+ :hmset => {:namespace=>[ :first ], :options=>{}},
73
+ :hdel => {:namespace=>[ :first ], :options=>{}},
74
+ :hexists => {:namespace=>[ :first ], :options=>{}},
75
+ :hlen => {:namespace=>[ :first ], :options=>{}},
76
+ :hkeys => {:namespace=>[ :first ], :options=>{}},
77
+ :hvals => {:namespace=>[ :first ], :options=>{}},
78
+ :hgetall => {:namespace=>[ :first ], :options=>{}},
79
+ :incr => {:namespace=>[ :first ], :options=>{}},
80
+ :incrby => {:namespace=>[ :first ], :options=>{}},
81
+ :info => {:namespace=>[], :options=>{}},
82
+ :keys => {:namespace=>[ :first, :all ], :options=>{}},
83
+ :lastsave => {:namespace=>[], :options=>{}},
84
+ :lindex => {:namespace=>[ :first ], :options=>{}},
85
+ :llen => {:namespace=>[ :first ], :options=>{}},
86
+ :lpop => {:namespace=>[ :first ], :options=>{}},
87
+ :lpush => {:namespace=>[ :first ], :options=>{}},
88
+ :lrange => {:namespace=>[ :first ], :options=>{}},
89
+ :lrem => {:namespace=>[ :first ], :options=>{}},
90
+ :lset => {:namespace=>[ :first ], :options=>{}},
91
+ :ltrim => {:namespace=>[ :first ], :options=>{}},
92
+ :mapped_hmset => {:namespace=>[ :first ], :options=>{}},
93
+ :mapped_mget => {:namespace=>[ :all, :all ], :options=>{}},
94
+ :mget => {:namespace=>[ :all ], :options=>{}},
95
+ #:monitor => {:namespace=>[ :monitor ], :options=>{}},
96
+ :move => {:namespace=>[ :first ], :options=>{}},
97
+ :mset => {:namespace=>[ :alternate ], :options=>{}},
98
+ :msetnx => {:namespace=>[ :alternate ], :options=>{}},
99
+ :psubscribe => {:namespace=>[ :all ], :options=>{}},
100
+ :publish => {:namespace=>[ :first ], :options=>{}},
101
+ :punsubscribe => {:namespace=>[ :all ], :options=>{}},
102
+ :quit => {:namespace=>[], :options=>{}},
103
+ :randomkey => {:namespace=>[], :options=>{}},
104
+ :rename => {:namespace=>[ :all ], :options=>{}},
105
+ :renamenx => {:namespace=>[ :all ], :options=>{}},
106
+ :rpop => {:namespace=>[ :first ], :options=>{}},
107
+ :rpoplpush => {:namespace=>[ :all ], :options=>{}},
108
+ :rpush => {:namespace=>[ :first ], :options=>{}},
109
+ :sadd => {:namespace=>[ :first ], :options=>{}},
110
+ :save => {:namespace=>[], :options=>{}},
111
+ :scard => {:namespace=>[ :first ], :options=>{}},
112
+ :sdiff => {:namespace=>[ :all ], :options=>{}},
113
+ :sdiffstore => {:namespace=>[ :all ], :options=>{}},
114
+ :select => {:namespace=>[], :options=>{}},
115
+ :set => {:namespace=>[ :first ], :options=>{}},
116
+ :setex => {:namespace=>[ :first ], :options=>{}},
117
+ :setnx => {:namespace=>[ :first ], :options=>{}},
118
+ :shutdown => {:namespace=>[], :options=>{}},
119
+ :sinter => {:namespace=>[:all], :options=>{}},
120
+ :sinterstore => {:namespace=>[:all], :options=>{}},
121
+ :sismember => {:namespace=>[:first], :options=>{}},
122
+ :slaveof => {:namespace=>[], :options=>{}},
123
+ :smembers => {:namespace=>[:first], :options=>{}},
124
+ :smove => {:namespace=>[:exclude_last], :options=>{}},
125
+ #:sort => {:namespace=>[:sort], :options=>{}},
126
+ :spop => {:namespace=>[:first], :options=>{}},
127
+ :srandmember => {:namespace=>[:first], :options=>{}},
128
+ :srem => {:namespace=>[:first], :options=>{}},
129
+ :subscribe => {:namespace=>[:all], :options=>{}},
130
+ :sunion => {:namespace=>[:all], :options=>{}},
131
+ :sunionstore => {:namespace=>[:all], :options=>{}},
132
+ :ttl => {:namespace=>[:first], :options=>{}},
133
+ :type => {:namespace=>[:first], :options=>{}},
134
+ :unsubscribe => {:namespace=>[:all], :options=>{}},
135
+ :zadd => {:namespace=>[:first], :options=>{}},
136
+ :zcard => {:namespace=>[:first], :options=>{}},
137
+ :zcount => {:namespace=>[:first], :options=>{}},
138
+ :zincrby => {:namespace=>[:first], :options=>{}},
139
+ :zinterstore => {:namespace=>[:exclude_options],:options=>{}},
140
+ :zrange => {:namespace=>[:first], :options=>{}},
141
+ :zrangebyscore => {:namespace=>[:first], :options=>{}},
142
+ :zrank => {:namespace=>[:first], :options=>{}},
143
+ :zrem => {:namespace=>[:first], :options=>{}},
144
+ :zremrangebyrank => {:namespace=>[:first], :options=>{}},
145
+ :zremrangebyscore => {:namespace=>[:first], :options=>{}},
146
+ :zrevrange => {:namespace=>[:first], :options=>{}},
147
+ :zrevrangebyscore => {:namespace=>[:first], :options=>{}},
148
+ :zrevrank => {:namespace=>[:first], :options=>{}},
149
+ :zscore => {:namespace=>[:first], :options=>{}},
150
+ :zunionstore => {:namespace=>[:exclude_options], :options=>{}},
151
+ :[] => {:namespace=>[:first], :options=>{}},
152
+ :[]= => {:namespace=>[:first], :options=>{}}
153
+ }
154
+
3
155
  def initialize(options={})
4
- @client = Redis.new(options)
156
+ @namespace = options[:namespace]
157
+ @client = options[:redis] || Redis.current
5
158
  end
159
+
6
160
  def method_missing(method, *args, &block)
7
161
  if @client.respond_to? method
8
- options, args = get_options(*args) || [{}, args]
9
- key, args = get_key(*args)
10
- args = handle(*args)
11
- args = [key] + args if args && key
12
- result = Entry.new(@client.send(method, *args, &block), options).extracted_result
13
- @client.send(:expire, key, options[:expire_in].to_i) if options[:expire_in]
14
- result
162
+ @options, args = get_options(*args) || [{}, args]
163
+ @options.merge(COMMANDS[method.to_sym][:options])
164
+ args = handle(method, *args)
165
+ result = @client.send(method, *args, &block)
166
+ @client.send(:expire, args[0], @options[:expire_in].to_i) if @options[:expire_in] && args[0]
167
+ extract(method, result)
15
168
  else
16
169
  raise NameError, :message=> "method #{method} is not defined"
17
170
  end
@@ -25,13 +178,85 @@ module RedisWrapper
25
178
  end
26
179
  end
27
180
  end
28
-
29
- def get_key(*args)
30
- args.first.kind_of?(String) ? [args.shift, args] : [nil, args]
181
+
182
+ def handle(method, *args)
183
+ format = COMMANDS[method.to_sym][:namespace]
184
+ return args if format.nil?
185
+ case format[0]
186
+ when :first
187
+ if args[0]
188
+ first = args.shift
189
+ first = namespace(first) if first
190
+ args = args.map{|arg| prepare(arg)}
191
+ args.unshift(first)
192
+ end
193
+ args
194
+ when :all
195
+ namespace(args)
196
+ when :exclude_first
197
+ first = args.shift
198
+ args = namespace(args)
199
+ args.unshift(first) if first
200
+ when :exclude_last
201
+ last = args.last.kind_of?(Hash) ? args.pop : nil
202
+ args = namespace(args)
203
+ args.push(last) if !last.nil?
204
+ when :alternate
205
+ args.each_with_index do |arg,i|
206
+ case i.even?
207
+ when true
208
+ arg[i] = namespace(arg[i])
209
+ when false
210
+ arg[i] = prepare(arg[i])
211
+ end
212
+ end
213
+ when :sort
214
+ #TODO solve this problem
215
+ end
216
+ args
31
217
  end
32
-
33
- def handle(*args)
34
- args.map{|u| Entry.new(u).prepared_result} if args
218
+
219
+ def prepare(value)
220
+ Entry.new(value, @options).prepared_result if value
221
+ end
222
+
223
+ def namespace(args)
224
+ return args unless args && @namespace
225
+ case args
226
+ when Array
227
+ args.map {|k| namespace(k)}
228
+ when Hash
229
+ Hash[*args.map {|k, v| [namespace(k), prepare(v) ]}.flatten]
230
+ else
231
+ "#{@namespace}:#{args}"
232
+ end
233
+ end
234
+
235
+ def rm_namespace(args)
236
+ return args unless args && @namespace
237
+ case args.class
238
+ when Array
239
+ args.map {|k| rem_namespace(k)}
240
+ when Hash
241
+ Hash[*args.map {|k, v| [ rem_namespace(k), prepare(v) ]}.flatten]
242
+ else
243
+ args.to_s.gsub /^#{@namespace}:/, ""
244
+ end
245
+ end
246
+
247
+ def extract(method, args)
248
+ format = COMMANDS[method.to_sym]
249
+ return args if format.nil?
250
+ case format[1]
251
+ when :all
252
+ rm_namespace(args)
253
+ when nil
254
+ if args.class == String
255
+ Entry.new(args, @options).extracted_result
256
+ else
257
+ args.map{|arg| Entry.new(arg, @options).extracted_result}
258
+ end
259
+ end
35
260
  end
36
261
  end
37
262
  end
@@ -1,6 +1,6 @@
1
1
  module RedisWrapper
2
2
  MAJOR = 0
3
- MINOR = 1
3
+ MINOR = 2
4
4
  PATCH = 0
5
5
  VERSION = [MAJOR, MINOR, PATCH].compact.join('.')
6
6
  end
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
16
16
  s.test_files = `git ls-files -- {spec,spec,features}/*`.split("\n")
17
17
  s.require_paths = ["lib"]
18
18
 
19
- s.homepage = "http://github.com/wakemaster39/redis-wrapper"
19
+ s.homepage = "http://github.com/wakemaster39/redis_wrapper"
20
20
  s.licenses = ["MIT"]
21
21
  s.rubygems_version = "1.8.10"
22
22
  s.summary = "High level wrapper around redis API"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis_wrapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-01-17 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
16
- requirement: &24307320 !ruby/object:Gem::Requirement
16
+ requirement: &23933640 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.2.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *24307320
24
+ version_requirements: *23933640
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &24306720 !ruby/object:Gem::Requirement
27
+ requirement: &23933160 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *24306720
35
+ version_requirements: *23933160
36
36
  description: A high level wrapper around the redis-rb gem and API. Designed to be
37
37
  a drop in replacement for Redis class while handling object marshaling and compression,
38
38
  setting key expiries, and namespacing your keys
@@ -53,7 +53,7 @@ files:
53
53
  - redis_wrapper.gemspec
54
54
  - spec/entry_spec.rb
55
55
  - spec/redis_wrapper_spec.rb
56
- homepage: http://github.com/wakemaster39/redis-wrapper
56
+ homepage: http://github.com/wakemaster39/redis_wrapper
57
57
  licenses:
58
58
  - MIT
59
59
  post_install_message: