redis-objects 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGELOG.rdoc +14 -0
- data/README.rdoc +5 -4
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/lib/redis/base_object.rb +3 -1
- data/lib/redis/counter.rb +0 -1
- data/lib/redis/{hash.rb → hash_key.rb} +9 -14
- data/lib/redis/helpers/serialize.rb +2 -0
- data/lib/redis/list.rb +1 -1
- data/lib/redis/objects/counters.rb +15 -3
- data/lib/redis/objects/hashes.rb +3 -3
- data/lib/redis/sorted_set.rb +31 -20
- data/lib/redis/value.rb +0 -2
- data/spec/redis_namespace_compat_spec.rb +18 -0
- data/spec/redis_objects_instance_spec.rb +47 -6
- data/spec/redis_objects_model_spec.rb +29 -4
- data/spec/spec_helper.rb +3 -2
- metadata +11 -14
data/.gitignore
CHANGED
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
= Changelog for Redis::Objects
|
2
2
|
|
3
|
+
== 0.5.0 [Final] (8 November 2010)
|
4
|
+
|
5
|
+
* Incompatible change: Had to rename Redis::Hash to Redis::HashKey due to internal conflicts with Redis lib and Ruby [Nate Wiger]
|
6
|
+
|
7
|
+
* Fixed AR counter override so that Redis::Objects doesn't hide AR counters [Mattias Pfeiffer]
|
8
|
+
|
9
|
+
* Fixed delete problem with Redis::List and complex values [Esdras Mayrink]
|
10
|
+
|
11
|
+
* Fix Redis::HashKey to support complex (marshaled) types [Mattias Pfeiffer]
|
12
|
+
|
13
|
+
* Group results of SortedSet#rangebyscore and #revrangebyscore if :withscores option is passed [Szymon Nowak]
|
14
|
+
|
15
|
+
* Updated Redis DEL semantics per API change [Gabe da Silveira]
|
16
|
+
|
3
17
|
== 0.4.1 [Final] (23 August 2010)
|
4
18
|
|
5
19
|
* Fixes for Ruby 1.8 failures due to missing flatten() [Gabe da Silveira]
|
data/README.rdoc
CHANGED
@@ -45,7 +45,7 @@ config/initializers/redis.rb is a good place for this.)
|
|
45
45
|
|
46
46
|
require 'redis'
|
47
47
|
require 'redis/objects'
|
48
|
-
Redis::Objects.redis = Redis.new(:host => 127.0.0.1, :port => 6379)
|
48
|
+
Redis::Objects.redis = Redis.new(:host => '127.0.0.1', :port => 6379)
|
49
49
|
|
50
50
|
Remember you can use Redis::Objects in any Ruby code. There are *no* dependencies
|
51
51
|
on Rails. Standalone, Sinatra, Resque - no problem.
|
@@ -217,10 +217,11 @@ Complex data types are no problem with :marshal => true:
|
|
217
217
|
=== Hashes
|
218
218
|
|
219
219
|
Hashes work like a Ruby {Hash}[http://ruby-doc.org/core/classes/Hash.html], with
|
220
|
-
a few Redis-specific additions.
|
220
|
+
a few Redis-specific additions. (The class name is "HashKey" not just "Hash", due to
|
221
|
+
conflicts with the Ruby core Hash class in other gems.)
|
221
222
|
|
222
|
-
require 'redis/
|
223
|
-
@hash = Redis::
|
223
|
+
require 'redis/hash_key'
|
224
|
+
@hash = Redis::HashKey.new('hash_name')
|
224
225
|
@hash['a'] = 1
|
225
226
|
@hash['b'] = 2
|
226
227
|
@hash.each do |k,v|
|
data/Rakefile
CHANGED
@@ -11,8 +11,8 @@ begin
|
|
11
11
|
gem.homepage = "http://github.com/nateware/redis-objects"
|
12
12
|
gem.authors = ["Nate Wiger"]
|
13
13
|
gem.add_development_dependency "bacon", ">= 0"
|
14
|
-
gem.requirements << 'redis, v2.
|
15
|
-
gem.add_dependency('redis', '>= 2.
|
14
|
+
gem.requirements << 'redis, v2.1.1 or greater'
|
15
|
+
gem.add_dependency('redis', '>= 2.1.1') # ALSO: update spec/spec_helper.rb
|
16
16
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
17
|
end
|
18
18
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/lib/redis/base_object.rb
CHANGED
@@ -3,8 +3,10 @@ class Redis
|
|
3
3
|
class BaseObject
|
4
4
|
def initialize(key, *args)
|
5
5
|
@key = key.is_a?(Array) ? key.flatten.join(':') : key
|
6
|
-
@options = args.last.is_a?(
|
6
|
+
@options = args.last.is_a?(Hash) ? args.pop : {}
|
7
7
|
@redis = args.first || $redis
|
8
8
|
end
|
9
|
+
|
10
|
+
alias :inspect :to_s # Ruby 1.9.2
|
9
11
|
end
|
10
12
|
end
|
data/lib/redis/counter.rb
CHANGED
@@ -2,7 +2,7 @@ class Redis
|
|
2
2
|
#
|
3
3
|
# Class representing a Redis hash.
|
4
4
|
#
|
5
|
-
class
|
5
|
+
class HashKey < BaseObject
|
6
6
|
require 'enumerator'
|
7
7
|
include Enumerable
|
8
8
|
require 'redis/helpers/core_commands'
|
@@ -10,16 +10,11 @@ class Redis
|
|
10
10
|
require 'redis/helpers/serialize'
|
11
11
|
include Redis::Helpers::Serialize
|
12
12
|
|
13
|
-
attr_reader :key, :redis
|
14
|
-
|
15
|
-
# Needed since Redis::Hash masks bare Hash in redis.rb
|
16
|
-
def self.[](*args)
|
17
|
-
::Hash[*args]
|
18
|
-
end
|
13
|
+
attr_reader :key, :options, :redis
|
19
14
|
|
20
15
|
# Sets a field to value
|
21
16
|
def []=(field, value)
|
22
|
-
store(field, value)
|
17
|
+
store(field, to_redis(value))
|
23
18
|
end
|
24
19
|
|
25
20
|
# Gets the value of a field
|
@@ -29,12 +24,12 @@ class Redis
|
|
29
24
|
|
30
25
|
# Redis: HSET
|
31
26
|
def store(field, value)
|
32
|
-
redis.hset(key, field, value)
|
27
|
+
redis.hset(key, field, to_redis(value))
|
33
28
|
end
|
34
29
|
|
35
30
|
# Redis: HGET
|
36
31
|
def fetch(field)
|
37
|
-
redis.hget(key, field)
|
32
|
+
from_redis redis.hget(key, field)
|
38
33
|
end
|
39
34
|
|
40
35
|
# Verify that a field exists. Redis: HEXISTS
|
@@ -57,13 +52,13 @@ class Redis
|
|
57
52
|
|
58
53
|
# Return all the values of the hash. Redis: HVALS
|
59
54
|
def values
|
60
|
-
redis.hvals(key)
|
55
|
+
from_redis redis.hvals(key)
|
61
56
|
end
|
62
57
|
alias_method :vals, :values
|
63
58
|
|
64
59
|
# Retrieve the entire hash. Redis: HGETALL
|
65
60
|
def all
|
66
|
-
redis.hgetall(key)
|
61
|
+
from_redis redis.hgetall(key)
|
67
62
|
end
|
68
63
|
alias_method :clone, :all
|
69
64
|
|
@@ -102,7 +97,7 @@ class Redis
|
|
102
97
|
# Set keys in bulk, takes a hash of field/values {'field1' => 'val1'}. Redis: HMSET
|
103
98
|
def bulk_set(*args)
|
104
99
|
raise ArgumentError, "Argument to bulk_set must be hash of key/value pairs" unless args.last.is_a?(::Hash)
|
105
|
-
redis.hmset(key, *args.last.inject([]){ |arr,kv| arr + kv })
|
100
|
+
redis.hmset(key, *args.last.inject([]){ |arr,kv| arr + [kv[0], to_redis(kv[1])] })
|
106
101
|
end
|
107
102
|
|
108
103
|
# Get keys in bulk, takes an array of fields as arguments. Redis: HMGET
|
@@ -110,7 +105,7 @@ class Redis
|
|
110
105
|
hsh = {}
|
111
106
|
res = redis.hmget(key, *fields.flatten)
|
112
107
|
fields.each do |k|
|
113
|
-
hsh[k] = res.shift
|
108
|
+
hsh[k] = from_redis(res.shift)
|
114
109
|
end
|
115
110
|
hsh
|
116
111
|
end
|
data/lib/redis/list.rb
CHANGED
@@ -73,7 +73,7 @@ class Redis
|
|
73
73
|
# Use .del to completely delete the entire key.
|
74
74
|
# Redis: LREM
|
75
75
|
def delete(name, count=0)
|
76
|
-
redis.lrem(key, count, name) # weird api
|
76
|
+
redis.lrem(key, count, to_redis(name)) # weird api
|
77
77
|
end
|
78
78
|
|
79
79
|
# Iterate through each member of the set. Redis::Objects mixes in Enumerable,
|
@@ -81,12 +81,16 @@ class Redis
|
|
81
81
|
private
|
82
82
|
|
83
83
|
def verify_counter_defined!(name, id) #:nodoc:
|
84
|
-
raise Redis::Objects::UndefinedCounter, "Undefined counter :#{name} for class #{self.name}" unless
|
84
|
+
raise Redis::Objects::UndefinedCounter, "Undefined counter :#{name} for class #{self.name}" unless counter_defined?(name)
|
85
85
|
if id.nil? and !@redis_objects[name][:global]
|
86
86
|
raise Redis::Objects::MissingID, "Missing ID for non-global counter #{self.name}##{name}"
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
+
def counter_defined?(name) #:nodoc:
|
91
|
+
@redis_objects && @redis_objects.has_key?(name)
|
92
|
+
end
|
93
|
+
|
90
94
|
def initialize_counter!(name, id) #:nodoc:
|
91
95
|
key = redis_field_key(name, id)
|
92
96
|
unless @initialized_counters[key]
|
@@ -117,14 +121,22 @@ class Redis
|
|
117
121
|
# It is more efficient to use increment_[counter_name] directly.
|
118
122
|
# This is mainly just for completeness to override ActiveRecord.
|
119
123
|
def increment(name, by=1)
|
120
|
-
send(name)
|
124
|
+
if self.class.send("counter_defined?", name)
|
125
|
+
send(name).increment(by)
|
126
|
+
else
|
127
|
+
super
|
128
|
+
end
|
121
129
|
end
|
122
130
|
|
123
131
|
# Decrement a counter.
|
124
132
|
# It is more efficient to use increment_[counter_name] directly.
|
125
133
|
# This is mainly just for completeness to override ActiveRecord.
|
126
134
|
def decrement(name, by=1)
|
127
|
-
send(name)
|
135
|
+
if self.class.send("counter_defined?", name)
|
136
|
+
send(name).decrement(by)
|
137
|
+
else
|
138
|
+
super
|
139
|
+
end
|
128
140
|
end
|
129
141
|
end
|
130
142
|
end
|
data/lib/redis/objects/hashes.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# This is the class loader, for use as "include Redis::Objects::Hashes"
|
2
2
|
# For the object itself, see "Redis::Hash"
|
3
|
-
require 'redis/
|
3
|
+
require 'redis/hash_key'
|
4
4
|
class Redis
|
5
5
|
module Objects
|
6
6
|
module Hashes
|
@@ -19,7 +19,7 @@ class Redis
|
|
19
19
|
if options[:global]
|
20
20
|
instance_eval <<-EndMethods
|
21
21
|
def #{name}
|
22
|
-
@#{name} ||= Redis::
|
22
|
+
@#{name} ||= Redis::HashKey.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
|
23
23
|
end
|
24
24
|
EndMethods
|
25
25
|
class_eval <<-EndMethods
|
@@ -30,7 +30,7 @@ class Redis
|
|
30
30
|
else
|
31
31
|
class_eval <<-EndMethods
|
32
32
|
def #{name}
|
33
|
-
@#{name} ||= Redis::
|
33
|
+
@#{name} ||= Redis::HashKey.new(redis_field_key(:#{name}), #{klass_name}.redis, #{klass_name}.redis_objects[:#{name}])
|
34
34
|
end
|
35
35
|
EndMethods
|
36
36
|
end
|
data/lib/redis/sorted_set.rb
CHANGED
@@ -16,7 +16,7 @@ class Redis
|
|
16
16
|
|
17
17
|
# How to add values using a sorted set. The key is the member, eg,
|
18
18
|
# "Peter", and the value is the score, eg, 163. So:
|
19
|
-
# num_posts['Peter'] = 163
|
19
|
+
# num_posts['Peter'] = 163
|
20
20
|
def []=(member, score)
|
21
21
|
add(member, score)
|
22
22
|
end
|
@@ -77,11 +77,7 @@ class Redis
|
|
77
77
|
def range(start_index, end_index, options={})
|
78
78
|
if options[:withscores] || options[:with_scores]
|
79
79
|
val = from_redis redis.zrange(key, start_index, end_index, :with_scores => true)
|
80
|
-
|
81
|
-
while k = val.shift and v = val.shift
|
82
|
-
ret << [k, v.to_f]
|
83
|
-
end
|
84
|
-
ret
|
80
|
+
group_set_with_scores(val)
|
85
81
|
else
|
86
82
|
from_redis redis.zrange(key, start_index, end_index)
|
87
83
|
end
|
@@ -91,11 +87,7 @@ class Redis
|
|
91
87
|
def revrange(start_index, end_index, options={})
|
92
88
|
if options[:withscores] || options[:with_scores]
|
93
89
|
val = from_redis redis.zrevrange(key, start_index, end_index, :with_scores => true)
|
94
|
-
|
95
|
-
while k = val.shift and v = val.shift
|
96
|
-
ret << [k, v.to_f]
|
97
|
-
end
|
98
|
-
ret
|
90
|
+
group_set_with_scores(val)
|
99
91
|
else
|
100
92
|
from_redis redis.zrevrange(key, start_index, end_index)
|
101
93
|
end
|
@@ -111,7 +103,13 @@ class Redis
|
|
111
103
|
args[:limit] = [options[:offset] || 0, options[:limit] || options[:count]] if
|
112
104
|
options[:offset] || options[:limit] || options[:count]
|
113
105
|
args[:with_scores] = true if options[:withscores] || options[:with_scores]
|
114
|
-
|
106
|
+
|
107
|
+
if args[:with_scores]
|
108
|
+
val = from_redis redis.zrangebyscore(key, min, max, args)
|
109
|
+
group_set_with_scores(val)
|
110
|
+
else
|
111
|
+
from_redis redis.zrangebyscore(key, min, max, args)
|
112
|
+
end
|
115
113
|
end
|
116
114
|
|
117
115
|
# Forwards compat (not yet implemented in Redis)
|
@@ -120,13 +118,19 @@ class Redis
|
|
120
118
|
args[:limit] = [options[:offset] || 0, options[:limit] || options[:count]] if
|
121
119
|
options[:offset] || options[:limit] || options[:count]
|
122
120
|
args[:with_scores] = true if options[:withscores] || options[:with_scores]
|
123
|
-
|
121
|
+
|
122
|
+
if args[:with_scores]
|
123
|
+
val = from_redis redis.zrevrangebyscore(key, min, max, args)
|
124
|
+
group_set_with_scores(val)
|
125
|
+
else
|
126
|
+
from_redis redis.zrevrangebyscore(key, min, max, args)
|
127
|
+
end
|
124
128
|
end
|
125
129
|
|
126
130
|
# Remove all elements in the sorted set at key with rank between start and end. Start and end are
|
127
131
|
# 0-based with rank 0 being the element with the lowest score. Both start and end can be negative
|
128
132
|
# numbers, where they indicate offsets starting at the element with the highest rank. For example:
|
129
|
-
# -1 is the element with the highest score, -2 the element with the second highest score and so forth.
|
133
|
+
# -1 is the element with the highest score, -2 the element with the second highest score and so forth.
|
130
134
|
# Redis: ZREMRANGEBYRANK
|
131
135
|
def remrangebyrank(min, max)
|
132
136
|
redis.zremrangebyrank(key, min, max)
|
@@ -163,7 +167,7 @@ class Redis
|
|
163
167
|
alias_method :incr, :increment
|
164
168
|
alias_method :incrby, :increment
|
165
169
|
|
166
|
-
# Convenience to calling increment() with a negative number.
|
170
|
+
# Convenience to calling increment() with a negative number.
|
167
171
|
def decrement(by=1)
|
168
172
|
redis.zincrby(key, -by).to_i
|
169
173
|
end
|
@@ -187,7 +191,7 @@ class Redis
|
|
187
191
|
alias_method :intersect, :intersection
|
188
192
|
alias_method :inter, :intersection
|
189
193
|
alias_method :&, :intersection
|
190
|
-
|
194
|
+
|
191
195
|
# Calculate the intersection and store it in Redis as +name+. Returns the number
|
192
196
|
# of elements in the stored intersection. Redis: SUNIONSTORE
|
193
197
|
def interstore(name, *sets)
|
@@ -250,7 +254,7 @@ class Redis
|
|
250
254
|
def ==(x)
|
251
255
|
members == x
|
252
256
|
end
|
253
|
-
|
257
|
+
|
254
258
|
def to_s
|
255
259
|
members.join(', ')
|
256
260
|
end
|
@@ -270,7 +274,7 @@ class Redis
|
|
270
274
|
def last
|
271
275
|
at(-1)
|
272
276
|
end
|
273
|
-
|
277
|
+
|
274
278
|
# The number of members in the set. Aliased as size. Redis: ZCARD
|
275
279
|
def length
|
276
280
|
redis.zcard(key)
|
@@ -278,11 +282,18 @@ class Redis
|
|
278
282
|
alias_method :size, :length
|
279
283
|
|
280
284
|
private
|
281
|
-
|
285
|
+
|
282
286
|
def keys_from_objects(sets)
|
283
287
|
raise ArgumentError, "Must pass in one or more set names" if sets.empty?
|
284
288
|
sets.collect{|set| set.is_a?(Redis::SortedSet) ? set.key : set}
|
285
289
|
end
|
286
|
-
|
290
|
+
|
291
|
+
def group_set_with_scores(set_with_scores)
|
292
|
+
ret = []
|
293
|
+
while k = set_with_scores.shift and v = set_with_scores.shift
|
294
|
+
ret << [k, v.to_f]
|
295
|
+
end
|
296
|
+
ret
|
297
|
+
end
|
287
298
|
end
|
288
299
|
end
|
data/lib/redis/value.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
require 'redis/objects'
|
4
|
+
Redis::Objects.redis = $redis
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../../redis-namespace/lib')
|
7
|
+
require 'redis/namespace'
|
8
|
+
|
9
|
+
describe 'Redis::Namespace compat' do
|
10
|
+
it "tests the compatibility of Hash and ::Hash conflicts" do
|
11
|
+
ns = Redis::Namespace.new("resque", :redis => $redis)
|
12
|
+
ns.instance_eval { rem_namespace({"resque:x" => nil}) }.should == {"x"=>nil}
|
13
|
+
class Foo
|
14
|
+
include Redis::Objects
|
15
|
+
end
|
16
|
+
ns.instance_eval { rem_namespace({"resque:x" => nil}) }.should == {"x"=>nil}
|
17
|
+
end
|
18
|
+
end
|
@@ -7,7 +7,7 @@ require 'redis/value'
|
|
7
7
|
require 'redis/lock'
|
8
8
|
require 'redis/set'
|
9
9
|
require 'redis/sorted_set'
|
10
|
-
require 'redis/
|
10
|
+
require 'redis/hash_key'
|
11
11
|
|
12
12
|
describe Redis::Value do
|
13
13
|
before do
|
@@ -20,7 +20,7 @@ describe Redis::Value do
|
|
20
20
|
@value.value = 'Trevor Hoffman'
|
21
21
|
@value.should == 'Trevor Hoffman'
|
22
22
|
@value.get.should == 'Trevor Hoffman'
|
23
|
-
@value.del.should
|
23
|
+
@value.del.should == 1
|
24
24
|
@value.should.be.nil
|
25
25
|
end
|
26
26
|
|
@@ -40,7 +40,7 @@ describe Redis::Value do
|
|
40
40
|
@value.value = [[1,2], {:t3 => 4}]
|
41
41
|
@value.should == [[1,2], {:t3 => 4}]
|
42
42
|
@value.get.should == [[1,2], {:t3 => 4}]
|
43
|
-
@value.del.should
|
43
|
+
@value.del.should == 1
|
44
44
|
@value.should.be.nil
|
45
45
|
@value.options[:marshal] = false
|
46
46
|
end
|
@@ -197,6 +197,9 @@ describe Redis::List do
|
|
197
197
|
@list << [1,2,3,[4,5]]
|
198
198
|
@list.last.should == [1,2,3,[4,5]]
|
199
199
|
@list.shift.should == {:json => 'data'}
|
200
|
+
@list.size.should == 2
|
201
|
+
@list.delete(v2)
|
202
|
+
@list.size.should == 1
|
200
203
|
@list.options[:marshal] = false
|
201
204
|
end
|
202
205
|
|
@@ -356,12 +359,50 @@ describe Redis::Lock do
|
|
356
359
|
end
|
357
360
|
|
358
361
|
|
359
|
-
describe Redis::
|
362
|
+
describe Redis::HashKey do
|
360
363
|
before do
|
361
|
-
@hash = Redis::
|
364
|
+
@hash = Redis::HashKey.new('test_hash')
|
362
365
|
@hash.clear
|
363
366
|
end
|
364
367
|
|
368
|
+
it "should handle complex marshaled values" do
|
369
|
+
@hash.options[:marshal] = true
|
370
|
+
@hash['abc'].should == nil
|
371
|
+
@hash['abc'] = {:json => 'data'}
|
372
|
+
@hash['abc'].should == {:json => 'data'}
|
373
|
+
|
374
|
+
# no marshaling
|
375
|
+
@hash.options[:marshal] = false
|
376
|
+
v = {:json => 'data'}
|
377
|
+
@hash['abc'] = v
|
378
|
+
@hash['abc'].should == v.to_s
|
379
|
+
|
380
|
+
@hash.options[:marshal] = true
|
381
|
+
@hash['abc'] = [[1,2], {:t3 => 4}]
|
382
|
+
@hash['abc'].should == [[1,2], {:t3 => 4}]
|
383
|
+
@hash.fetch('abc').should == [[1,2], {:t3 => 4}]
|
384
|
+
@hash.delete('abc').should == 1
|
385
|
+
@hash.fetch('abc').should.be.nil
|
386
|
+
|
387
|
+
@hash.options[:marshal] = true
|
388
|
+
@hash.bulk_set('abc' => [[1,2], {:t3 => 4}], 'def' => [[6,8], {:t4 => 8}])
|
389
|
+
hsh = @hash.bulk_get('abc', 'def', 'foo')
|
390
|
+
hsh['abc'].should == [[1,2], {:t3 => 4}]
|
391
|
+
hsh['def'].should == [[6,8], {:t4 => 8}]
|
392
|
+
hsh['foo'].should.be.nil
|
393
|
+
|
394
|
+
hsh = @hash.all
|
395
|
+
hsh['abc'].should == [[1,2], {:t3 => 4}]
|
396
|
+
hsh['def'].should == [[6,8], {:t4 => 8}]
|
397
|
+
|
398
|
+
@hash.values.should == [[[1,2], {:t3 => 4}], [[6,8], {:t4 => 8}]]
|
399
|
+
|
400
|
+
@hash.delete('def').should == 1
|
401
|
+
@hash.delete('abc').should == 1
|
402
|
+
|
403
|
+
@hash.options[:marshal] = false
|
404
|
+
end
|
405
|
+
|
365
406
|
it "should get and set values" do
|
366
407
|
@hash['foo'] = 'bar'
|
367
408
|
@hash['foo'].should == 'bar'
|
@@ -406,7 +447,7 @@ describe Redis::Hash do
|
|
406
447
|
end
|
407
448
|
|
408
449
|
it "should respond to empty?" do
|
409
|
-
@empty = Redis::
|
450
|
+
@empty = Redis::HashKey.new('test_empty_hash')
|
410
451
|
@empty.respond_to?(:empty?).should == true
|
411
452
|
end
|
412
453
|
|
@@ -46,6 +46,21 @@ class CustomRoster < Roster
|
|
46
46
|
counter :special # New
|
47
47
|
end
|
48
48
|
|
49
|
+
class MethodRoster
|
50
|
+
def increment(attribute, by=1)
|
51
|
+
42
|
52
|
+
end
|
53
|
+
|
54
|
+
def initialize(id=1) @id = id end
|
55
|
+
def id; @id; end
|
56
|
+
end
|
57
|
+
|
58
|
+
class CustomMethodRoster < MethodRoster
|
59
|
+
include Redis::Objects
|
60
|
+
|
61
|
+
attr_accessor :counter
|
62
|
+
counter :basic
|
63
|
+
end
|
49
64
|
|
50
65
|
describe Redis::Objects do
|
51
66
|
before do
|
@@ -363,7 +378,7 @@ describe Redis::Objects do
|
|
363
378
|
@roster.starting_pitcher.get.should == 'Trevor Hoffman'
|
364
379
|
@roster.starting_pitcher = 'Tom Selleck'
|
365
380
|
@roster.starting_pitcher.should == 'Tom Selleck'
|
366
|
-
@roster.starting_pitcher.del.should
|
381
|
+
@roster.starting_pitcher.del.should == 1
|
367
382
|
@roster.starting_pitcher.should.be.nil
|
368
383
|
end
|
369
384
|
|
@@ -372,7 +387,7 @@ describe Redis::Objects do
|
|
372
387
|
@roster.starting_pitcher = {:json => 'data'}
|
373
388
|
@roster.starting_pitcher.should == {:json => 'data'}
|
374
389
|
@roster.starting_pitcher.get.should == {:json => 'data'}
|
375
|
-
@roster.starting_pitcher.del.should
|
390
|
+
@roster.starting_pitcher.del.should == 1
|
376
391
|
@roster.starting_pitcher.should.be.nil
|
377
392
|
end
|
378
393
|
|
@@ -630,7 +645,7 @@ describe Redis::Objects do
|
|
630
645
|
Roster.last_player.get.should == 'Trevor Hoffman'
|
631
646
|
Roster.last_player = 'Tom Selleck'
|
632
647
|
Roster.last_player.should == 'Tom Selleck'
|
633
|
-
Roster.last_player.del.should
|
648
|
+
Roster.last_player.del.should == 1
|
634
649
|
Roster.last_player.should.be.nil
|
635
650
|
end
|
636
651
|
|
@@ -664,7 +679,7 @@ describe Redis::Objects do
|
|
664
679
|
@roster2.last_player.get.should == 'Trevor Hoffman'
|
665
680
|
@roster2.last_player = 'Tom Selleck'
|
666
681
|
@roster.last_player.should == 'Tom Selleck'
|
667
|
-
@roster.last_player.del.should
|
682
|
+
@roster.last_player.del.should == 1
|
668
683
|
@roster.last_player.should.be.nil
|
669
684
|
@roster2.last_player.should.be.nil
|
670
685
|
end
|
@@ -748,4 +763,14 @@ describe Redis::Objects do
|
|
748
763
|
it "should handle new subclass objects" do
|
749
764
|
@custom_roster.special.increment.should == 1
|
750
765
|
end
|
766
|
+
|
767
|
+
it "should allow passing of increment/decrement to super class" do
|
768
|
+
@custom_method_roster = CustomMethodRoster.new
|
769
|
+
@custom_method_roster.counter.should.be.nil
|
770
|
+
|
771
|
+
@custom_method_roster.increment(:counter).should == 42
|
772
|
+
|
773
|
+
@custom_method_roster.increment(:basic).should == 1
|
774
|
+
@custom_method_roster.basic.should.be.kind_of(Redis::Counter)
|
775
|
+
end
|
751
776
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'rubygems' # poor people still on 1.8
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
gem 'redis', '>= 2.1.1'
|
4
3
|
require 'redis'
|
5
4
|
|
5
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
6
6
|
require 'bacon'
|
7
7
|
Bacon.summary_at_exit
|
8
8
|
|
@@ -11,3 +11,4 @@ $redis = Redis.new(:host => ENV['REDIS_HOST'], :port => ENV['REDIS_PORT'])
|
|
11
11
|
UNIONSTORE_KEY = 'test:unionstore'
|
12
12
|
INTERSTORE_KEY = 'test:interstore'
|
13
13
|
DIFFSTORE_KEY = 'test:diffstore'
|
14
|
+
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-objects
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 13
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
7
|
+
- 5
|
8
|
+
- 0
|
9
|
+
version: 0.5.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Nate Wiger
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-08
|
17
|
+
date: 2010-11-08 00:00:00 -08:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
@@ -26,7 +25,6 @@ dependencies:
|
|
26
25
|
requirements:
|
27
26
|
- - ">="
|
28
27
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
28
|
segments:
|
31
29
|
- 0
|
32
30
|
version: "0"
|
@@ -40,12 +38,11 @@ dependencies:
|
|
40
38
|
requirements:
|
41
39
|
- - ">="
|
42
40
|
- !ruby/object:Gem::Version
|
43
|
-
hash: 7
|
44
41
|
segments:
|
45
42
|
- 2
|
46
|
-
-
|
47
|
-
-
|
48
|
-
version: 2.
|
43
|
+
- 1
|
44
|
+
- 1
|
45
|
+
version: 2.1.1
|
49
46
|
type: :runtime
|
50
47
|
version_requirements: *id002
|
51
48
|
description: Map Redis types directly to Ruby objects. Works with any class or ORM.
|
@@ -65,7 +62,7 @@ files:
|
|
65
62
|
- VERSION
|
66
63
|
- lib/redis/base_object.rb
|
67
64
|
- lib/redis/counter.rb
|
68
|
-
- lib/redis/
|
65
|
+
- lib/redis/hash_key.rb
|
69
66
|
- lib/redis/helpers/core_commands.rb
|
70
67
|
- lib/redis/helpers/serialize.rb
|
71
68
|
- lib/redis/list.rb
|
@@ -82,6 +79,7 @@ files:
|
|
82
79
|
- lib/redis/sorted_set.rb
|
83
80
|
- lib/redis/value.rb
|
84
81
|
- redis-objects.gemspec
|
82
|
+
- spec/redis_namespace_compat_spec.rb
|
85
83
|
- spec/redis_objects_instance_spec.rb
|
86
84
|
- spec/redis_objects_model_spec.rb
|
87
85
|
- spec/spec_helper.rb
|
@@ -99,7 +97,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
97
|
requirements:
|
100
98
|
- - ">="
|
101
99
|
- !ruby/object:Gem::Version
|
102
|
-
hash: 3
|
103
100
|
segments:
|
104
101
|
- 0
|
105
102
|
version: "0"
|
@@ -108,18 +105,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
105
|
requirements:
|
109
106
|
- - ">="
|
110
107
|
- !ruby/object:Gem::Version
|
111
|
-
hash: 3
|
112
108
|
segments:
|
113
109
|
- 0
|
114
110
|
version: "0"
|
115
111
|
requirements:
|
116
|
-
- redis, v2.
|
112
|
+
- redis, v2.1.1 or greater
|
117
113
|
rubyforge_project:
|
118
114
|
rubygems_version: 1.3.7
|
119
115
|
signing_key:
|
120
116
|
specification_version: 3
|
121
117
|
summary: Map Redis types directly to Ruby objects
|
122
118
|
test_files:
|
119
|
+
- spec/redis_namespace_compat_spec.rb
|
123
120
|
- spec/redis_objects_instance_spec.rb
|
124
121
|
- spec/redis_objects_model_spec.rb
|
125
122
|
- spec/spec_helper.rb
|