redis_wrapper 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +3 -0
- data/lib/redis_wrapper/redis_wrapper.rb +239 -14
- data/lib/redis_wrapper/version.rb +1 -1
- data/redis_wrapper.gemspec +1 -1
- metadata +6 -6
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
|
-
@
|
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
|
-
|
10
|
-
args = handle(*args)
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
30
|
-
|
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
|
34
|
-
|
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
|
data/redis_wrapper.gemspec
CHANGED
@@ -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/
|
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.
|
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: &
|
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: *
|
24
|
+
version_requirements: *23933640
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
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: *
|
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/
|
56
|
+
homepage: http://github.com/wakemaster39/redis_wrapper
|
57
57
|
licenses:
|
58
58
|
- MIT
|
59
59
|
post_install_message:
|