redis-objects 0.8.0 → 0.9.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.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +20 -0
- data/README.md +7 -0
- data/lib/redis/base_object.rb +32 -0
- data/lib/redis/counter.rb +33 -0
- data/lib/redis/hash_key.rb +46 -28
- data/lib/redis/helpers/core_commands.rb +22 -2
- data/lib/redis/list.rb +15 -15
- data/lib/redis/objects.rb +11 -1
- data/lib/redis/objects/counters.rb +1 -1
- data/lib/redis/objects/hashes.rb +1 -1
- data/lib/redis/objects/lists.rb +1 -1
- data/lib/redis/objects/locks.rb +2 -2
- data/lib/redis/objects/sets.rb +1 -1
- data/lib/redis/objects/sorted_sets.rb +1 -1
- data/lib/redis/objects/values.rb +1 -1
- data/lib/redis/objects/version.rb +1 -1
- data/lib/redis/set.rb +25 -20
- data/lib/redis/sorted_set.rb +32 -22
- data/lib/redis/value.rb +5 -5
- data/spec/redis_objects_conn_spec.rb +32 -2
- data/spec/redis_objects_instance_spec.rb +171 -2
- data/spec/redis_objects_model_spec.rb +70 -4
- data/spec/spec_helper.rb +21 -16
- metadata +2 -3
- data/lib/redis/helpers/serialize.rb +0 -41
@@ -29,7 +29,7 @@ class Redis
|
|
29
29
|
instance_variable_get("@#{name}") or
|
30
30
|
instance_variable_set("@#{name}",
|
31
31
|
Redis::Counter.new(
|
32
|
-
redis_field_key(name),
|
32
|
+
redis_field_key(name), redis_field_redis(name), redis_objects[name.to_sym]
|
33
33
|
)
|
34
34
|
)
|
35
35
|
end
|
data/lib/redis/objects/hashes.rb
CHANGED
@@ -21,7 +21,7 @@ class Redis
|
|
21
21
|
instance_variable_get("@#{name}") or
|
22
22
|
instance_variable_set("@#{name}",
|
23
23
|
Redis::HashKey.new(
|
24
|
-
redis_field_key(name),
|
24
|
+
redis_field_key(name), redis_field_redis(name), redis_objects[name.to_sym]
|
25
25
|
)
|
26
26
|
)
|
27
27
|
end
|
data/lib/redis/objects/lists.rb
CHANGED
@@ -21,7 +21,7 @@ class Redis
|
|
21
21
|
instance_variable_get("@#{name}") or
|
22
22
|
instance_variable_set("@#{name}",
|
23
23
|
Redis::List.new(
|
24
|
-
redis_field_key(name),
|
24
|
+
redis_field_key(name), redis_field_redis(name), redis_objects[name.to_sym]
|
25
25
|
)
|
26
26
|
)
|
27
27
|
end
|
data/lib/redis/objects/locks.rb
CHANGED
@@ -24,7 +24,7 @@ class Redis
|
|
24
24
|
instance_variable_get("@#{lock_name}") or
|
25
25
|
instance_variable_set("@#{lock_name}",
|
26
26
|
Redis::Lock.new(
|
27
|
-
redis_field_key(lock_name),
|
27
|
+
redis_field_key(lock_name), redis_field_redis(lock_name), redis_objects[lock_name.to_sym]
|
28
28
|
)
|
29
29
|
)
|
30
30
|
end
|
@@ -49,7 +49,7 @@ class Redis
|
|
49
49
|
verify_lock_defined!(name)
|
50
50
|
raise ArgumentError, "Missing block to #{self.name}.obtain_lock" unless block_given?
|
51
51
|
lock_name = "#{name}_lock"
|
52
|
-
Redis::Lock.new(redis_field_key(lock_name, id),
|
52
|
+
Redis::Lock.new(redis_field_key(lock_name, id), redis_field_redis(lock_name), redis_objects[lock_name.to_sym]).lock(&block)
|
53
53
|
end
|
54
54
|
|
55
55
|
# Clear the lock. Use with care - usually only in an Admin page to clear
|
data/lib/redis/objects/sets.rb
CHANGED
@@ -21,7 +21,7 @@ class Redis
|
|
21
21
|
instance_variable_get("@#{name}") or
|
22
22
|
instance_variable_set("@#{name}",
|
23
23
|
Redis::Set.new(
|
24
|
-
redis_field_key(name),
|
24
|
+
redis_field_key(name), redis_field_redis(name), redis_objects[name.to_sym]
|
25
25
|
)
|
26
26
|
)
|
27
27
|
end
|
@@ -21,7 +21,7 @@ class Redis
|
|
21
21
|
instance_variable_get("@#{name}") or
|
22
22
|
instance_variable_set("@#{name}",
|
23
23
|
Redis::SortedSet.new(
|
24
|
-
redis_field_key(name),
|
24
|
+
redis_field_key(name), redis_field_redis(name), redis_objects[name.to_sym]
|
25
25
|
)
|
26
26
|
)
|
27
27
|
end
|
data/lib/redis/objects/values.rb
CHANGED
@@ -21,7 +21,7 @@ class Redis
|
|
21
21
|
instance_variable_get("@#{name}") or
|
22
22
|
instance_variable_set("@#{name}",
|
23
23
|
Redis::Value.new(
|
24
|
-
redis_field_key(name),
|
24
|
+
redis_field_key(name), redis_field_redis(name), redis_objects[name.to_sym]
|
25
25
|
)
|
26
26
|
)
|
27
27
|
end
|
data/lib/redis/set.rb
CHANGED
@@ -9,8 +9,6 @@ class Redis
|
|
9
9
|
include Enumerable
|
10
10
|
require 'redis/helpers/core_commands'
|
11
11
|
include Redis::Helpers::CoreCommands
|
12
|
-
require 'redis/helpers/serialize'
|
13
|
-
include Redis::Helpers::Serialize
|
14
12
|
|
15
13
|
attr_reader :key, :options
|
16
14
|
|
@@ -23,49 +21,54 @@ class Redis
|
|
23
21
|
# Add the specified value to the set only if it does not exist already.
|
24
22
|
# Redis: SADD
|
25
23
|
def add(value)
|
26
|
-
redis.sadd(key,
|
24
|
+
redis.sadd(key, marshal(value)) if value.nil? || !Array(value).empty?
|
27
25
|
end
|
28
26
|
|
29
27
|
# Remove and return a random member. Redis: SPOP
|
30
28
|
def pop
|
31
|
-
|
29
|
+
unmarshal redis.spop(key)
|
30
|
+
end
|
31
|
+
|
32
|
+
# return a random member. Redis: SRANDMEMBER
|
33
|
+
def randmember
|
34
|
+
unmarshal redis.srandmember(key)
|
32
35
|
end
|
33
36
|
|
34
37
|
# Adds the specified values to the set. Only works on redis > 2.4
|
35
38
|
# Redis: SADD
|
36
39
|
def merge(*values)
|
37
|
-
redis.sadd(key, values.flatten.map{|v|
|
40
|
+
redis.sadd(key, values.flatten.map{|v| marshal(v)})
|
38
41
|
end
|
39
42
|
|
40
43
|
# Return all members in the set. Redis: SMEMBERS
|
41
44
|
def members
|
42
|
-
|
43
|
-
|
45
|
+
vals = redis.smembers(key)
|
46
|
+
vals.nil? ? [] : vals.map{|v| unmarshal(v) }
|
44
47
|
end
|
45
48
|
alias_method :get, :members
|
46
49
|
|
47
50
|
# Returns true if the specified value is in the set. Redis: SISMEMBER
|
48
51
|
def member?(value)
|
49
|
-
redis.sismember(key,
|
52
|
+
redis.sismember(key, marshal(value))
|
50
53
|
end
|
51
54
|
alias_method :include?, :member?
|
52
|
-
|
55
|
+
|
53
56
|
# Delete the value from the set. Redis: SREM
|
54
57
|
def delete(value)
|
55
|
-
redis.srem(key,
|
58
|
+
redis.srem(key, marshal(value))
|
56
59
|
end
|
57
|
-
|
60
|
+
|
58
61
|
# Delete if matches block
|
59
62
|
def delete_if(&block)
|
60
63
|
res = false
|
61
64
|
redis.smembers(key).each do |m|
|
62
|
-
if block.call(
|
65
|
+
if block.call(unmarshal(m))
|
63
66
|
res = redis.srem(key, m)
|
64
67
|
end
|
65
68
|
end
|
66
69
|
res
|
67
70
|
end
|
68
|
-
|
71
|
+
|
69
72
|
# Iterate through each member of the set. Redis::Objects mixes in Enumerable,
|
70
73
|
# so you can also use familiar methods like +collect+, +detect+, and so forth.
|
71
74
|
def each(&block)
|
@@ -84,12 +87,12 @@ class Redis
|
|
84
87
|
#
|
85
88
|
# Redis: SINTER
|
86
89
|
def intersection(*sets)
|
87
|
-
|
90
|
+
redis.sinter(key, *keys_from_objects(sets)).map{|v| unmarshal(v)}
|
88
91
|
end
|
89
92
|
alias_method :intersect, :intersection
|
90
93
|
alias_method :inter, :intersection
|
91
94
|
alias_method :&, :intersection
|
92
|
-
|
95
|
+
|
93
96
|
# Calculate the intersection and store it in Redis as +name+. Returns the number
|
94
97
|
# of elements in the stored intersection. Redis: SUNIONSTORE
|
95
98
|
def interstore(name, *sets)
|
@@ -108,7 +111,7 @@ class Redis
|
|
108
111
|
#
|
109
112
|
# Redis: SUNION
|
110
113
|
def union(*sets)
|
111
|
-
|
114
|
+
redis.sunion(key, *keys_from_objects(sets)).map{|v| unmarshal(v)}
|
112
115
|
end
|
113
116
|
alias_method :|, :union
|
114
117
|
alias_method :+, :union
|
@@ -132,7 +135,7 @@ class Redis
|
|
132
135
|
#
|
133
136
|
# Redis: SDIFF
|
134
137
|
def difference(*sets)
|
135
|
-
|
138
|
+
redis.sdiff(key, *keys_from_objects(sets)).map{|v| unmarshal(v)}
|
136
139
|
end
|
137
140
|
alias_method :diff, :difference
|
138
141
|
alias_method :^, :difference
|
@@ -172,17 +175,19 @@ class Redis
|
|
172
175
|
def ==(x)
|
173
176
|
members == x
|
174
177
|
end
|
175
|
-
|
178
|
+
|
176
179
|
def to_s
|
177
180
|
members.join(', ')
|
178
181
|
end
|
179
182
|
|
183
|
+
expiration_filter :add
|
184
|
+
|
180
185
|
private
|
181
|
-
|
186
|
+
|
182
187
|
def keys_from_objects(sets)
|
183
188
|
raise ArgumentError, "Must pass in one or more set names" if sets.empty?
|
184
189
|
sets.collect{|set| set.is_a?(Redis::Set) ? set.key : set}
|
185
190
|
end
|
186
|
-
|
191
|
+
|
187
192
|
end
|
188
193
|
end
|
data/lib/redis/sorted_set.rb
CHANGED
@@ -9,8 +9,6 @@ class Redis
|
|
9
9
|
# include Enumerable
|
10
10
|
require 'redis/helpers/core_commands'
|
11
11
|
include Redis::Helpers::CoreCommands
|
12
|
-
require 'redis/helpers/serialize'
|
13
|
-
include Redis::Helpers::Serialize
|
14
12
|
|
15
13
|
attr_reader :key, :options
|
16
14
|
|
@@ -25,9 +23,19 @@ class Redis
|
|
25
23
|
# arguments to this are flipped; the member comes first rather than
|
26
24
|
# the score, since the member is the unique item (not the score).
|
27
25
|
def add(member, score)
|
28
|
-
redis.zadd(key, score,
|
26
|
+
redis.zadd(key, score, marshal(member))
|
29
27
|
end
|
30
28
|
|
29
|
+
# Add a list of members and their corresponding value (or a hash mapping
|
30
|
+
# values to scores) to Redis. Note that the arguments to this are flipped;
|
31
|
+
# the member comes first rather than the score, since the member is the unique
|
32
|
+
# item (not the score).
|
33
|
+
def merge(values)
|
34
|
+
vals = values.map{|v,s| [s, marshal(v)] }
|
35
|
+
redis.zadd(key, vals)
|
36
|
+
end
|
37
|
+
alias_method :add_all, :merge
|
38
|
+
|
31
39
|
# Same functionality as Ruby arrays. If a single number is given, return
|
32
40
|
# just the element at that index using Redis: ZRANGE. Otherwise, return
|
33
41
|
# a range of values using Redis: ZRANGE.
|
@@ -50,7 +58,7 @@ class Redis
|
|
50
58
|
# specified element does not exist in the sorted set, or the key does not exist
|
51
59
|
# at all, nil is returned. Redis: ZSCORE.
|
52
60
|
def score(member)
|
53
|
-
result = redis.zscore(key,
|
61
|
+
result = redis.zscore(key, marshal(member))
|
54
62
|
|
55
63
|
result.to_f unless result.nil?
|
56
64
|
end
|
@@ -60,7 +68,7 @@ class Redis
|
|
60
68
|
# When the given member does not exist in the sorted set, nil is returned.
|
61
69
|
# The returned rank (or index) of the member is 0-based for both commands
|
62
70
|
def rank(member)
|
63
|
-
if n = redis.zrank(key,
|
71
|
+
if n = redis.zrank(key, marshal(member))
|
64
72
|
n.to_i
|
65
73
|
else
|
66
74
|
nil
|
@@ -68,7 +76,7 @@ class Redis
|
|
68
76
|
end
|
69
77
|
|
70
78
|
def revrank(member)
|
71
|
-
if n = redis.zrevrank(key,
|
79
|
+
if n = redis.zrevrank(key, marshal(member))
|
72
80
|
n.to_i
|
73
81
|
else
|
74
82
|
nil
|
@@ -78,26 +86,26 @@ class Redis
|
|
78
86
|
# Return all members of the sorted set with their scores. Extremely CPU-intensive.
|
79
87
|
# Better to use a range instead.
|
80
88
|
def members(options={})
|
81
|
-
|
82
|
-
|
89
|
+
vals = range(0, -1, options)
|
90
|
+
vals.nil? ? [] : vals.map{|v| unmarshal(v) }
|
83
91
|
end
|
84
92
|
|
85
93
|
# Return a range of values from +start_index+ to +end_index+. Can also use
|
86
94
|
# the familiar list[start,end] Ruby syntax. Redis: ZRANGE
|
87
95
|
def range(start_index, end_index, options={})
|
88
96
|
if options[:withscores] || options[:with_scores]
|
89
|
-
|
97
|
+
redis.zrange(key, start_index, end_index, :with_scores => true).map{|v,s| [unmarshal(v), s] }
|
90
98
|
else
|
91
|
-
|
99
|
+
redis.zrange(key, start_index, end_index).map{|v| unmarshal(v) }
|
92
100
|
end
|
93
101
|
end
|
94
102
|
|
95
103
|
# Return a range of values from +start_index+ to +end_index+ in reverse order. Redis: ZREVRANGE
|
96
104
|
def revrange(start_index, end_index, options={})
|
97
105
|
if options[:withscores] || options[:with_scores]
|
98
|
-
|
106
|
+
redis.zrevrange(key, start_index, end_index, :with_scores => true).map{|v| unmarshal(v) }
|
99
107
|
else
|
100
|
-
|
108
|
+
redis.zrevrange(key, start_index, end_index).map{|v| unmarshal(v) }
|
101
109
|
end
|
102
110
|
end
|
103
111
|
|
@@ -112,7 +120,7 @@ class Redis
|
|
112
120
|
options[:offset] || options[:limit] || options[:count]
|
113
121
|
args[:with_scores] = true if options[:withscores] || options[:with_scores]
|
114
122
|
|
115
|
-
|
123
|
+
redis.zrangebyscore(key, min, max, args).map{|v| unmarshal(v) }
|
116
124
|
end
|
117
125
|
|
118
126
|
# Returns all the elements in the sorted set at key with a score between max and min
|
@@ -128,7 +136,7 @@ class Redis
|
|
128
136
|
options[:offset] || options[:limit] || options[:count]
|
129
137
|
args[:with_scores] = true if options[:withscores] || options[:with_scores]
|
130
138
|
|
131
|
-
|
139
|
+
redis.zrevrangebyscore(key, max, min, args).map{|v| unmarshal(v) }
|
132
140
|
end
|
133
141
|
|
134
142
|
# Remove all elements in the sorted set at key with rank between start and end. Start and end are
|
@@ -148,7 +156,7 @@ class Redis
|
|
148
156
|
|
149
157
|
# Delete the value from the set. Redis: ZREM
|
150
158
|
def delete(value)
|
151
|
-
redis.zrem(key,
|
159
|
+
redis.zrem(key, marshal(value))
|
152
160
|
end
|
153
161
|
|
154
162
|
# Delete element if it matches block
|
@@ -156,7 +164,7 @@ class Redis
|
|
156
164
|
raise ArgumentError, "Missing block to SortedSet#delete_if" unless block_given?
|
157
165
|
res = false
|
158
166
|
redis.zrange(key, 0, -1).each do |m|
|
159
|
-
if block.call(
|
167
|
+
if block.call(unmarshal(m))
|
160
168
|
res = redis.zrem(key, m)
|
161
169
|
end
|
162
170
|
end
|
@@ -166,14 +174,14 @@ class Redis
|
|
166
174
|
# Increment the rank of that member atomically and return the new value. This
|
167
175
|
# method is aliased as incr() for brevity. Redis: ZINCRBY
|
168
176
|
def increment(member, by=1)
|
169
|
-
redis.zincrby(key, by,
|
177
|
+
redis.zincrby(key, by, marshal(member)).to_i
|
170
178
|
end
|
171
179
|
alias_method :incr, :increment
|
172
180
|
alias_method :incrby, :increment
|
173
181
|
|
174
182
|
# Convenience to calling increment() with a negative number.
|
175
183
|
def decrement(member, by=1)
|
176
|
-
redis.zincrby(key, -by,
|
184
|
+
redis.zincrby(key, -by, marshal(member)).to_i
|
177
185
|
end
|
178
186
|
alias_method :decr, :decrement
|
179
187
|
alias_method :decrby, :decrement
|
@@ -190,7 +198,7 @@ class Redis
|
|
190
198
|
#
|
191
199
|
# Redis: SINTER
|
192
200
|
def intersection(*sets)
|
193
|
-
|
201
|
+
redis.zinter(key, *keys_from_objects(sets)).map{|v| unmarshal(v) }
|
194
202
|
end
|
195
203
|
alias_method :intersect, :intersection
|
196
204
|
alias_method :inter, :intersection
|
@@ -214,7 +222,7 @@ class Redis
|
|
214
222
|
#
|
215
223
|
# Redis: SUNION
|
216
224
|
def union(*sets)
|
217
|
-
|
225
|
+
redis.zunion(key, *keys_from_objects(sets)).map{|v| unmarshal(v) }
|
218
226
|
end
|
219
227
|
alias_method :|, :union
|
220
228
|
alias_method :+, :union
|
@@ -238,7 +246,7 @@ class Redis
|
|
238
246
|
#
|
239
247
|
# Redis: SDIFF
|
240
248
|
def difference(*sets)
|
241
|
-
|
249
|
+
redis.zdiff(key, *keys_from_objects(sets)).map{|v| unmarshal(v) }
|
242
250
|
end
|
243
251
|
alias_method :diff, :difference
|
244
252
|
alias_method :^, :difference
|
@@ -292,9 +300,11 @@ class Redis
|
|
292
300
|
|
293
301
|
# Return a boolean indicating whether +value+ is a member.
|
294
302
|
def member?(value)
|
295
|
-
!redis.zscore(key,
|
303
|
+
!redis.zscore(key, marshal(value)).nil?
|
296
304
|
end
|
297
305
|
|
306
|
+
expiration_filter :[]=, :add, :merge, :diffstore, :increment, :decrement, :intersection, :interstore, :unionstore
|
307
|
+
|
298
308
|
private
|
299
309
|
|
300
310
|
def keys_from_objects(sets)
|
data/lib/redis/value.rb
CHANGED
@@ -7,26 +7,24 @@ class Redis
|
|
7
7
|
class Value < BaseObject
|
8
8
|
require 'redis/helpers/core_commands'
|
9
9
|
include Redis::Helpers::CoreCommands
|
10
|
-
require 'redis/helpers/serialize'
|
11
|
-
include Redis::Helpers::Serialize
|
12
10
|
|
13
11
|
attr_reader :key, :options
|
14
12
|
def initialize(key, *args)
|
15
13
|
super(key, *args)
|
16
|
-
redis.setnx(key,
|
14
|
+
redis.setnx(key, marshal(@options[:default])) if @options[:default]
|
17
15
|
end
|
18
16
|
|
19
17
|
def value=(val)
|
20
18
|
if val.nil?
|
21
19
|
delete
|
22
20
|
else
|
23
|
-
redis.set key,
|
21
|
+
redis.set key, marshal(val)
|
24
22
|
end
|
25
23
|
end
|
26
24
|
alias_method :set, :value=
|
27
25
|
|
28
26
|
def value
|
29
|
-
|
27
|
+
unmarshal redis.get(key)
|
30
28
|
end
|
31
29
|
alias_method :get, :value
|
32
30
|
|
@@ -42,5 +40,7 @@ class Redis
|
|
42
40
|
def method_missing(*args)
|
43
41
|
self.value.send *args
|
44
42
|
end
|
43
|
+
|
44
|
+
expiration_filter :value=
|
45
45
|
end
|
46
46
|
end
|
@@ -9,6 +9,38 @@ BAD_REDIS = "totally bad bogus redis handle"
|
|
9
9
|
|
10
10
|
# Grab a global handle
|
11
11
|
describe 'Connection tests' do
|
12
|
+
it "should support overriding object handles" do
|
13
|
+
|
14
|
+
class CustomConnectionObject
|
15
|
+
include Redis::Objects
|
16
|
+
|
17
|
+
def id
|
18
|
+
return 1
|
19
|
+
end
|
20
|
+
|
21
|
+
redis_handle = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT, :db => 31)
|
22
|
+
value :redis_value, :redis => redis_handle, :key => 'rval'
|
23
|
+
value :default_redis_value, :key => 'rval'
|
24
|
+
end
|
25
|
+
|
26
|
+
obj = CustomConnectionObject.new
|
27
|
+
|
28
|
+
obj.default_redis_value.value.should == nil
|
29
|
+
obj.redis_value.value.should == nil
|
30
|
+
|
31
|
+
obj.default_redis_value.value = 'foo'
|
32
|
+
obj.default_redis_value.value.should == 'foo'
|
33
|
+
obj.redis_value.value.should == nil
|
34
|
+
|
35
|
+
obj.default_redis_value.clear
|
36
|
+
obj.redis_value.value = 'foo'
|
37
|
+
obj.redis_value.value.should == 'foo'
|
38
|
+
obj.default_redis_value.value.should == nil
|
39
|
+
|
40
|
+
obj.redis_value.clear
|
41
|
+
obj.default_redis_value.clear
|
42
|
+
end
|
43
|
+
|
12
44
|
it "should support local handles" do
|
13
45
|
Redis.current = nil # reset from other tests
|
14
46
|
Redis::Objects.redis = nil
|
@@ -100,5 +132,3 @@ describe 'Connection tests' do
|
|
100
132
|
end
|
101
133
|
|
102
134
|
end
|
103
|
-
|
104
|
-
|