redis-objects 0.4.1 → 0.5.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/.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
|