redis-objects 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,12 +1,36 @@
1
1
  = Changelog for Redis::Objects
2
2
 
3
- == 0.5.2 [Development]
3
+ == 0.6.0 (24 October 2012)
4
+
5
+ * Add +@set.merge()+ method to add multiple members at once [hfwang]
6
+
7
+ * Add +insert+ method to Redis::List instances [giglemad]
8
+
9
+ * Updated APIs for recent redis-server sort API compat [nateware]
10
+
11
+ * Add HashKey#bulk_values for fetching values in the same order than the given keys [aspgems]
12
+
13
+ * Lists now handle the insert command
14
+
15
+ * Changed +@sset.score+ method on SortedSet to return nil for invalid members [hkarthik]
16
+
17
+ * Test using redis-objects counters and fix when AR passes a string
18
+
19
+ * Add LSET to lists [neonlex]
20
+
21
+ * Fix interstore/unionstore for redis 2.6 [david]
22
+
23
+ * Redis-rb 3.0.0 support [seomoz]
24
+
25
+ * group_set_with_scores is no longer needed.
26
+
27
+ == 0.5.2 (13 June 2012)
4
28
 
5
29
  * Added Redis::SortedSet#member? method [Karl Varga]
6
30
 
7
31
  * Added +ttl+ method to CoreCommands [Karl Varga]
8
32
 
9
- == 0.5.1 [Final] (23 May 2011)
33
+ == 0.5.1 (23 May 2011)
10
34
 
11
35
  * Fixed super class delegation conflicts with Redis Counters vs ActiveRecord [Tim Aßmann]
12
36
 
@@ -16,7 +40,7 @@
16
40
 
17
41
  * Updated URLs to reflect new redis.io website [Jérémy Lecour]
18
42
 
19
- == 0.5.0 [Final] (8 November 2010)
43
+ == 0.5.0 (8 November 2010)
20
44
 
21
45
  * Incompatible change: Had to rename Redis::Hash to Redis::HashKey due to internal conflicts with Redis lib and Ruby [Nate Wiger]
22
46
 
@@ -30,7 +54,7 @@
30
54
 
31
55
  * Updated Redis DEL semantics per API change [Gabe da Silveira]
32
56
 
33
- == 0.4.1 [Final] (23 August 2010)
57
+ == 0.4.1 (23 August 2010)
34
58
 
35
59
  * Fixes for Ruby 1.8 failures due to missing flatten() [Gabe da Silveira]
36
60
 
@@ -40,7 +64,7 @@
40
64
 
41
65
  * Fixed a typo in delete_if and added missing test coverage [Julio Capote, Nate Wiger]
42
66
 
43
- == 0.4.0 [Final] (11 August 2010)
67
+ == 0.4.0 (11 August 2010)
44
68
 
45
69
  * Full support for redis hashes via new Redis::Hash class [Julio Capote, Nate Wiger]
46
70
 
@@ -54,7 +78,7 @@
54
78
 
55
79
  * Renamed :withscores option to :with_scores for consistency with redis-rb 2.0, but kept backwards compat [Tom Stuart, Nate Wiger]
56
80
 
57
- == 0.3.2 [Final] (21 July 2010)
81
+ == 0.3.2 (21 July 2010)
58
82
 
59
83
  * New "maxlength" option to Redis::List can create length-limited lists (eg, like a ring buffer) from dbalatero [David Balatero]
60
84
 
@@ -62,21 +86,21 @@
62
86
 
63
87
  * Switched from rspec to bacon for tests
64
88
 
65
- == 0.3.1 [Final] (1 June 2010)
89
+ == 0.3.1 (1 June 2010)
66
90
 
67
91
  * Integrated fixes for sorted_set deletions from capotej [Julio Capote]
68
92
 
69
- == 0.3.0 [Final] (14 April 2010)
93
+ == 0.3.0 (14 April 2010)
70
94
 
71
95
  * Due to Ruby 1.9 bugs and performance considerations, marshaling of data types is now OFF by default. You must say :marshal => true for any objects that you want serialization enabled on. [Nate Wiger]
72
96
 
73
97
  * Sorted Set class changed slightly due to feedback. You can now get an individual element back via @set['item'] since it acts like a Hash.
74
98
 
75
- == 0.2.4 [Final] (9 April 2010)*
99
+ == 0.2.4 (9 April 2010)
76
100
 
77
101
  * Added sorted set support via Redis::SortedSet [Nate Wiger]
78
102
 
79
- == 0.2.3 [Final] (18 February 2010)*
103
+ == 0.2.3 (18 February 2010)
80
104
 
81
105
  * Added lock expiration to Redis::Lock [Ben VandenBos]
82
106
 
@@ -84,7 +108,7 @@
84
108
 
85
109
  * Added lock tests and test helpers [Ben VandenBos]
86
110
 
87
- == 0.2.2 [Final] (14 December 2009)*
111
+ == 0.2.2 (14 December 2009)
88
112
 
89
113
  * Added @set.diff(@set2) with "^" and "-" synonyms (oversight). [Nate Wiger]
90
114
 
@@ -94,7 +118,7 @@
94
118
 
95
119
  * More spec coverage. [Nate Wiger]
96
120
 
97
- == 0.2.1 [Final] (27 November 2009)*
121
+ == 0.2.1 (27 November 2009)
98
122
 
99
123
  * First worthwhile public release, with good spec coverage and functionality. [Nate Wiger]
100
124
 
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+ gem 'redis', '>= 3.0.2'
3
+ gem 'redis-namespace'
4
+ gem 'bacon'
5
+ gem 'jeweler'
6
+ gem 'activerecord'
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ activemodel (3.2.8)
5
+ activesupport (= 3.2.8)
6
+ builder (~> 3.0.0)
7
+ activerecord (3.2.8)
8
+ activemodel (= 3.2.8)
9
+ activesupport (= 3.2.8)
10
+ arel (~> 3.0.2)
11
+ tzinfo (~> 0.3.29)
12
+ activesupport (3.2.8)
13
+ i18n (~> 0.6)
14
+ multi_json (~> 1.0)
15
+ arel (3.0.2)
16
+ bacon (1.1.0)
17
+ builder (3.0.4)
18
+ git (1.2.5)
19
+ i18n (0.6.1)
20
+ jeweler (1.8.4)
21
+ bundler (~> 1.0)
22
+ git (>= 1.2.5)
23
+ rake
24
+ rdoc
25
+ json (1.7.5)
26
+ multi_json (1.3.6)
27
+ rake (0.9.2.2)
28
+ rdoc (3.12)
29
+ json (~> 1.4)
30
+ redis (3.0.2)
31
+ redis-namespace (1.2.1)
32
+ redis (~> 3.0.0)
33
+ tzinfo (0.3.33)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ activerecord
40
+ bacon
41
+ jeweler
42
+ redis (>= 3.0.2)
43
+ redis-namespace
data/Rakefile CHANGED
@@ -11,9 +11,9 @@ 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.add_development_dependency "redis-namespace", ">= 0"
15
- gem.requirements << 'redis, v2.1.1 or greater'
16
- gem.add_dependency('redis', '>= 2.1.1') # ALSO: update spec/spec_helper.rb
14
+ gem.add_development_dependency "redis-namespace", ">= 1.2.0"
15
+ gem.requirements << 'redis, v3.0.2 or greater'
16
+ gem.add_dependency('redis', '>= 3.0.2') # ALSO: update spec/spec_helper.rb
17
17
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
18
  end
19
19
  Jeweler::GemcutterTasks.new
@@ -21,7 +21,7 @@ rescue LoadError
21
21
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
22
  end
23
23
 
24
- # require 'rake/testtask'
24
+ # require 'rdoc/task'
25
25
  # Rake::TestTask.new(:spec) do |spec|
26
26
  # spec.libs << 'lib' << 'spec'
27
27
  # spec.pattern = 'spec/**/*_spec.rb'
@@ -30,7 +30,7 @@ end
30
30
 
31
31
  desc "run all the specs"
32
32
  task :test do
33
- sh "bacon spec/*_spec.rb"
33
+ sh "bundle exec bacon spec/*_spec.rb"
34
34
  end
35
35
 
36
36
 
@@ -51,7 +51,7 @@ task :spec => :check_dependencies
51
51
 
52
52
  task :default => :spec
53
53
 
54
- require 'rake/rdoctask'
54
+ require 'rdoc/task'
55
55
  Rake::RDocTask.new do |rdoc|
56
56
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
57
57
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.3
1
+ 0.6.0
@@ -135,6 +135,13 @@ class Redis
135
135
  hsh
136
136
  end
137
137
 
138
+ # Get values in bulk, takes an array of keys as arguments.
139
+ # Values are returned in a collection in the same order than their keys in *keys Redis: HMGET
140
+ def bulk_values(*keys)
141
+ res = redis.hmget(key, *keys.flatten)
142
+ keys.inject([]){|collection, k| collection << from_redis(res.shift)}
143
+ end
144
+
138
145
  # Increment value by integer at field. Redis: HINCRBY
139
146
  def incrby(field, val = 1)
140
147
  ret = redis.hincrby(key, field, val)
@@ -51,7 +51,7 @@ class Redis
51
51
  end
52
52
 
53
53
  def sort(options={})
54
- options[:order] ||= "asc alpha"
54
+ options[:order] = "asc alpha" if options.keys.count == 0 # compat with Ruby
55
55
  redis.sort(key, options)
56
56
  end
57
57
  end
data/lib/redis/list.rb CHANGED
@@ -20,6 +20,11 @@ class Redis
20
20
  push(value)
21
21
  self # for << 'a' << 'b'
22
22
  end
23
+
24
+ # Add a member before or after pivot in the list. Redis: LINSERT
25
+ def insert(where,pivot,value)
26
+ redis.linsert(key,where,to_redis(pivot),to_redis(value))
27
+ end
23
28
 
24
29
  # Add a member to the end of the list. Redis: RPUSH
25
30
  def push(value)
@@ -81,6 +86,11 @@ class Redis
81
86
  end
82
87
  alias_method :slice, :[]
83
88
 
89
+ # Same functionality as Ruby arrays.
90
+ def []=(index, value)
91
+ redis.lset(key, index, value)
92
+ end
93
+
84
94
  # Delete the element(s) from the list that match name. If count is specified,
85
95
  # only the first-N (if positive) or last-N (if negative) will be removed.
86
96
  # Use .del to completely delete the entire key.
@@ -55,6 +55,7 @@ class Redis
55
55
  # Increment a counter with the specified name and id. Accepts a block
56
56
  # like the instance method. See Redis::Objects::Counter for details.
57
57
  def increment_counter(name, id=nil, by=1, &block)
58
+ name = name.to_sym
58
59
  return super(name, id) unless counter_defined?(name)
59
60
  verify_counter_defined!(name, id)
60
61
  initialize_counter!(name, id)
@@ -65,6 +66,7 @@ class Redis
65
66
  # Decrement a counter with the specified name and id. Accepts a block
66
67
  # like the instance method. See Redis::Objects::Counter for details.
67
68
  def decrement_counter(name, id=nil, by=1, &block)
69
+ name = name.to_sym
68
70
  return super(name, id) unless counter_defined?(name)
69
71
  verify_counter_defined!(name, id)
70
72
  initialize_counter!(name, id)
@@ -86,20 +88,20 @@ class Redis
86
88
  to = @redis_objects[name][:start] if to.nil?
87
89
  redis.getset(redis_field_key(name, id), to.to_i).to_i
88
90
  end
89
-
91
+
90
92
  private
91
-
93
+
92
94
  def verify_counter_defined!(name, id) #:nodoc:
93
95
  raise NoMethodError, "Undefined counter :#{name} for class #{self.name}" unless counter_defined?(name)
94
96
  if id.nil? and !@redis_objects[name][:global]
95
97
  raise Redis::Objects::MissingID, "Missing ID for non-global counter #{self.name}##{name}"
96
98
  end
97
99
  end
98
-
100
+
99
101
  def counter_defined?(name) #:nodoc:
100
102
  @redis_objects && @redis_objects.has_key?(name)
101
103
  end
102
-
104
+
103
105
  def initialize_counter!(name, id) #:nodoc:
104
106
  key = redis_field_key(name, id)
105
107
  unless @initialized_counters[key]
@@ -107,7 +109,7 @@ class Redis
107
109
  end
108
110
  @initialized_counters[key] = true
109
111
  end
110
-
112
+
111
113
  # Implements increment/decrement blocks on a class level
112
114
  def rewindable_block(rewind, name, id, value, &block) #:nodoc:
113
115
  # Unfortunately this is almost exactly duplicated from Redis::Counter
data/lib/redis/set.rb CHANGED
@@ -26,11 +26,17 @@ class Redis
26
26
  redis.sadd(key, to_redis(value))
27
27
  end
28
28
 
29
- # Remove and return a random member. Redis:SPOP
29
+ # Remove and return a random member. Redis: SPOP
30
30
  def pop
31
31
  from_redis redis.spop(key)
32
32
  end
33
33
 
34
+ # Adds the specified values to the set. Only works on redis > 2.4
35
+ # Redis: SADD
36
+ def merge(*values)
37
+ redis.sadd(key, values.flatten.map{|v| to_redis(v)})
38
+ end
39
+
34
40
  # Return all members in the set. Redis: SMEMBERS
35
41
  def members
36
42
  v = from_redis redis.smembers(key)
@@ -41,7 +41,7 @@ class Redis
41
41
  when -1 then nil # Ruby does this (a bit weird)
42
42
  end
43
43
  else
44
- score(index)
44
+ result = score(index) || 0 # handles a nil score
45
45
  end
46
46
  end
47
47
  alias_method :slice, :[]
@@ -50,7 +50,9 @@ class Redis
50
50
  # specified element does not exist in the sorted set, or the key does not exist
51
51
  # at all, nil is returned. Redis: ZSCORE.
52
52
  def score(member)
53
- redis.zscore(key, to_redis(member)).to_f
53
+ result = redis.zscore(key, to_redis(member))
54
+
55
+ result.to_f unless result.nil?
54
56
  end
55
57
 
56
58
  # Return the rank of the member in the sorted set, with scores ordered from
@@ -84,8 +86,7 @@ class Redis
84
86
  # the familiar list[start,end] Ruby syntax. Redis: ZRANGE
85
87
  def range(start_index, end_index, options={})
86
88
  if options[:withscores] || options[:with_scores]
87
- val = from_redis redis.zrange(key, start_index, end_index, :with_scores => true)
88
- group_set_with_scores(val)
89
+ from_redis redis.zrange(key, start_index, end_index, :with_scores => true)
89
90
  else
90
91
  from_redis redis.zrange(key, start_index, end_index)
91
92
  end
@@ -94,8 +95,7 @@ class Redis
94
95
  # Return a range of values from +start_index+ to +end_index+ in reverse order. Redis: ZREVRANGE
95
96
  def revrange(start_index, end_index, options={})
96
97
  if options[:withscores] || options[:with_scores]
97
- val = from_redis redis.zrevrange(key, start_index, end_index, :with_scores => true)
98
- group_set_with_scores(val)
98
+ from_redis redis.zrevrange(key, start_index, end_index, :with_scores => true)
99
99
  else
100
100
  from_redis redis.zrevrange(key, start_index, end_index)
101
101
  end
@@ -112,12 +112,7 @@ class Redis
112
112
  options[:offset] || options[:limit] || options[:count]
113
113
  args[:with_scores] = true if options[:withscores] || options[:with_scores]
114
114
 
115
- if args[:with_scores]
116
- val = from_redis redis.zrangebyscore(key, min, max, args)
117
- group_set_with_scores(val)
118
- else
119
- from_redis redis.zrangebyscore(key, min, max, args)
120
- end
115
+ from_redis redis.zrangebyscore(key, min, max, args)
121
116
  end
122
117
 
123
118
  # Forwards compat (not yet implemented in Redis)
@@ -127,12 +122,7 @@ class Redis
127
122
  options[:offset] || options[:limit] || options[:count]
128
123
  args[:with_scores] = true if options[:withscores] || options[:with_scores]
129
124
 
130
- if args[:with_scores]
131
- val = from_redis redis.zrevrangebyscore(key, min, max, args)
132
- group_set_with_scores(val)
133
- else
134
- from_redis redis.zrevrangebyscore(key, min, max, args)
135
- end
125
+ from_redis redis.zrevrangebyscore(key, min, max, args)
136
126
  end
137
127
 
138
128
  # Remove all elements in the sorted set at key with rank between start and end. Start and end are
@@ -203,7 +193,7 @@ class Redis
203
193
  # Calculate the intersection and store it in Redis as +name+. Returns the number
204
194
  # of elements in the stored intersection. Redis: SUNIONSTORE
205
195
  def interstore(name, *sets)
206
- redis.zinterstore(name, key, *keys_from_objects(sets))
196
+ redis.zinterstore(name, keys_from_objects([self] + sets))
207
197
  end
208
198
 
209
199
  # Return the union with another set. Can pass it either another set
@@ -226,7 +216,7 @@ class Redis
226
216
  # Calculate the union and store it in Redis as +name+. Returns the number
227
217
  # of elements in the stored union. Redis: SUNIONSTORE
228
218
  def unionstore(name, *sets)
229
- redis.zunionstore(name, key, *keys_from_objects(sets))
219
+ redis.zunionstore(name, keys_from_objects([self] + sets))
230
220
  end
231
221
 
232
222
  # Return the difference vs another set. Can pass it either another set
@@ -288,7 +278,7 @@ class Redis
288
278
  redis.zcard(key)
289
279
  end
290
280
  alias_method :size, :length
291
-
281
+
292
282
  # The number of members within a range of scores. Redis: ZCOUNT
293
283
  def range_size(min, max)
294
284
  redis.zcount(key, min, max)
@@ -305,13 +295,5 @@ class Redis
305
295
  raise ArgumentError, "Must pass in one or more set names" if sets.empty?
306
296
  sets.collect{|set| set.is_a?(Redis::SortedSet) ? set.key : set}
307
297
  end
308
-
309
- def group_set_with_scores(set_with_scores)
310
- ret = []
311
- while k = set_with_scores.shift and v = set_with_scores.shift
312
- ret << [k, v.to_f]
313
- end
314
- ret
315
- end
316
298
  end
317
299
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "redis-objects"
8
- s.version = "0.5.3"
8
+ s.version = "0.6.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nate Wiger"]
12
- s.date = "2012-06-13"
12
+ s.date = "2012-10-24"
13
13
  s.description = "Map Redis types directly to Ruby objects. Works with any class or ORM."
14
14
  s.email = "nate@wiger.org"
15
15
  s.extra_rdoc_files = [
@@ -18,6 +18,8 @@ Gem::Specification.new do |s|
18
18
  s.files = [
19
19
  "ATOMICITY.rdoc",
20
20
  "CHANGELOG.rdoc",
21
+ "Gemfile",
22
+ "Gemfile.lock",
21
23
  "README.rdoc",
22
24
  "Rakefile",
23
25
  "VERSION",
@@ -48,26 +50,41 @@ Gem::Specification.new do |s|
48
50
  ]
49
51
  s.homepage = "http://github.com/nateware/redis-objects"
50
52
  s.require_paths = ["lib"]
51
- s.requirements = ["redis, v2.1.1 or greater"]
52
- s.rubygems_version = "1.8.10"
53
+ s.requirements = ["redis, v3.0.2 or greater"]
54
+ s.rubygems_version = "1.8.24"
53
55
  s.summary = "Map Redis types directly to Ruby objects"
54
56
 
55
57
  if s.respond_to? :specification_version then
56
58
  s.specification_version = 3
57
59
 
58
60
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
61
+ s.add_runtime_dependency(%q<redis>, [">= 3.0.2"])
62
+ s.add_runtime_dependency(%q<redis-namespace>, [">= 0"])
63
+ s.add_runtime_dependency(%q<bacon>, [">= 0"])
64
+ s.add_runtime_dependency(%q<jeweler>, [">= 0"])
65
+ s.add_runtime_dependency(%q<activerecord>, [">= 0"])
59
66
  s.add_development_dependency(%q<bacon>, [">= 0"])
60
- s.add_development_dependency(%q<redis-namespace>, [">= 0"])
61
- s.add_runtime_dependency(%q<redis>, [">= 2.1.1"])
67
+ s.add_development_dependency(%q<redis-namespace>, [">= 1.2.0"])
68
+ s.add_runtime_dependency(%q<redis>, [">= 3.0.2"])
62
69
  else
63
- s.add_dependency(%q<bacon>, [">= 0"])
70
+ s.add_dependency(%q<redis>, [">= 3.0.2"])
64
71
  s.add_dependency(%q<redis-namespace>, [">= 0"])
65
- s.add_dependency(%q<redis>, [">= 2.1.1"])
72
+ s.add_dependency(%q<bacon>, [">= 0"])
73
+ s.add_dependency(%q<jeweler>, [">= 0"])
74
+ s.add_dependency(%q<activerecord>, [">= 0"])
75
+ s.add_dependency(%q<bacon>, [">= 0"])
76
+ s.add_dependency(%q<redis-namespace>, [">= 1.2.0"])
77
+ s.add_dependency(%q<redis>, [">= 3.0.2"])
66
78
  end
67
79
  else
68
- s.add_dependency(%q<bacon>, [">= 0"])
80
+ s.add_dependency(%q<redis>, [">= 3.0.2"])
69
81
  s.add_dependency(%q<redis-namespace>, [">= 0"])
70
- s.add_dependency(%q<redis>, [">= 2.1.1"])
82
+ s.add_dependency(%q<bacon>, [">= 0"])
83
+ s.add_dependency(%q<jeweler>, [">= 0"])
84
+ s.add_dependency(%q<activerecord>, [">= 0"])
85
+ s.add_dependency(%q<bacon>, [">= 0"])
86
+ s.add_dependency(%q<redis-namespace>, [">= 1.2.0"])
87
+ s.add_dependency(%q<redis>, [">= 3.0.2"])
71
88
  end
72
89
  end
73
90
 
@@ -49,16 +49,37 @@ begin
49
49
  class Post < ActiveRecord::Base
50
50
  include Redis::Objects
51
51
  counter :total
52
+ counter :comments_count
52
53
  belongs_to :blog, :counter_cache => true
53
54
  end
54
55
 
56
+ class CreateComments < ActiveRecord::Migration
57
+ def self.up
58
+ create_table :comments do |t|
59
+ t.string :body
60
+ t.integer :post_id
61
+ t.timestamps
62
+ end
63
+ end
64
+
65
+ def self.down
66
+ drop_table :comments
67
+ end
68
+ end
69
+
70
+ class Comment < ActiveRecord::Base
71
+ include Redis::Objects
72
+ belongs_to :post, :counter_cache => true
73
+ end
55
74
 
56
75
  describe Redis::Objects do
57
76
  before do
77
+ CreateComments.up
58
78
  CreatePosts.up
59
79
  CreateBlogs.up
60
80
  end
61
81
  after do
82
+ CreateComments.down
62
83
  CreatePosts.down
63
84
  CreateBlogs.down
64
85
  end
@@ -88,6 +109,15 @@ begin
88
109
  @ar2.destroy
89
110
  end
90
111
 
112
+ it "uses the redis objects counter cache when present" do
113
+ post = Post.create
114
+ post.comments_count.should == 0
115
+ comment = Comment.create :post => post
116
+ post.reload.comments_count.should == 1
117
+ comment.destroy
118
+ post.reload.comments_count.should == 0
119
+ end
120
+
91
121
  it "falls back to ActiveRecord if redis counter is not defined" do
92
122
  blog = Blog.create
93
123
  blog.reload.posts_count.should == 0
@@ -230,6 +230,15 @@ describe Redis::List do
230
230
  list2.should == ["b"]
231
231
  end
232
232
 
233
+ it "should handle insert" do
234
+ @list << 'b' << 'd'
235
+ @list.insert(:before,'b','a')
236
+ @list.insert(:after,'b','c')
237
+ @list.insert("before",'a','z')
238
+ @list.insert("after",'d','e')
239
+ @list.should == ['z','a','b','c','d','e']
240
+ end
241
+
233
242
  it "should handle lists of complex data types" do
234
243
  @list.options[:marshal] = true
235
244
  v1 = {:json => 'data'}
@@ -596,18 +605,18 @@ describe Redis::Set do
596
605
  @set.should.be.empty
597
606
  @set << 'a' << 'a' << 'a'
598
607
  @set.should == ['a']
608
+ @set.to_s.should == 'a'
599
609
  @set.get.should == ['a']
600
610
  @set << 'b' << 'b'
601
- @set.to_s.should == 'a, b'
602
- @set.should == ['a','b']
603
- @set.members.should == ['a','b']
604
- @set.members.reverse.should == ['b','a'] # common question
605
- @set.get.should == ['a','b']
611
+ @set.sort.should == ['a','b']
612
+ @set.members.sort.should == ['a','b']
613
+ @set.members.sort.reverse.should == ['b','a'] # common question
614
+ @set.get.sort.should == ['a','b']
606
615
  @set << 'c'
607
616
  @set.sort.should == ['a','b','c']
608
617
  @set.get.sort.should == ['a','b','c']
609
618
  @set.delete('c')
610
- @set.should == ['a','b']
619
+ @set.sort.should == ['a','b']
611
620
  @set.get.sort.should == ['a','b']
612
621
  @set.length.should == 2
613
622
  @set.size.should == 2
@@ -623,10 +632,10 @@ describe Redis::Set do
623
632
  end
624
633
  i.should == @set.length
625
634
 
626
- coll = @set.collect{|st| st}
635
+ coll = @set.sort.collect{|st| st}
627
636
  coll.should == ['a','b']
628
- @set.should == ['a','b']
629
- @set.get.should == ['a','b']
637
+ @set.sort.should == ['a','b']
638
+ @set.get.sort.should == ['a','b']
630
639
 
631
640
  @set << 'c'
632
641
  @set.member?('c').should.be.true
@@ -694,17 +703,27 @@ describe Redis::Set do
694
703
  @set.redis.del('spec/set2')
695
704
  end
696
705
 
706
+ it "should handle variadic sadd operations" do
707
+ @set.should.be.empty
708
+ @set << 'a'
709
+ @set.merge('b', 'c')
710
+ @set.members.sort.should == ['a', 'b', 'c']
711
+ @set.merge(['d','c','e'])
712
+ @set.members.sort.should == ['a', 'b', 'c', 'd', 'e']
713
+ end
714
+
697
715
  it "should support sorting" do
698
- @set_1 << 'a' << 'b' << 'c' << 'd' << 'e'
699
- @set_2 << 1 << 2 << 3 << 4 << 5
700
- @set_3 << 'm_1' << 'm_2'
716
+ @set_1 << 'c' << 'b' << 'a' << 'e' << 'd'
701
717
  @set_1.sort.should == %w(a b c d e)
702
- @set_2.sort.should == %w(1 2 3 4 5)
703
-
704
718
  @set_1.sort(SORT_ORDER).should == %w(e d c b a)
705
- @set_3.sort(SORT_BY).should == %w(m_1 m_2)
719
+
720
+ @set_2 << 2 << 4 << 3 << 1 << 5
721
+ @set_2.sort.should == %w(1 2 3 4 5)
706
722
  @set_2.sort(SORT_LIMIT).should == %w(3 4)
707
723
 
724
+ @set_3 << 'm_4' << 'm_5' << 'm_1' << 'm_3' << 'm_2'
725
+ @set_3.sort(:by => 'm_*').should == %w(m_1 m_2 m_3 m_4 m_5)
726
+
708
727
  val1 = Redis::Value.new('spec/3/sorted')
709
728
  val2 = Redis::Value.new('spec/4/sorted')
710
729
 
@@ -743,7 +762,7 @@ describe Redis::SortedSet do
743
762
  @set_3.clear
744
763
  end
745
764
 
746
- it "should handle sets of simple values" do
765
+ it "should handle sorted sets of simple values" do
747
766
  @set.should.be.empty
748
767
  @set['a'] = 11
749
768
  @set['a'] = 21
@@ -781,6 +800,7 @@ describe Redis::SortedSet do
781
800
  @set['b'] = 5
782
801
  @set['b'] = 6
783
802
  @set.score('b').should == 6
803
+ @set.score('f').should == nil
784
804
  @set.delete('c')
785
805
  @set.to_s.should == 'a, b'
786
806
  @set.should == ['a','b']
@@ -836,7 +856,7 @@ describe Redis::SortedSet do
836
856
  @set.size.should == 3
837
857
  end
838
858
 
839
- it "should support renaming sets" do
859
+ it "should support renaming sorted sets" do
840
860
  @set.should.be.empty
841
861
  @set['zynga'] = 151
842
862
  @set['playfish'] = 202
@@ -504,15 +504,14 @@ describe Redis::Objects do
504
504
  @roster.outfielders.should == ['a']
505
505
  @roster.outfielders.get.should == ['a']
506
506
  @roster.outfielders << 'b' << 'b'
507
- @roster.outfielders.to_s.should == 'a, b'
508
- @roster.outfielders.should == ['a','b']
509
- @roster.outfielders.members.should == ['a','b']
510
- @roster.outfielders.get.should == ['a','b']
507
+ @roster.outfielders.sort.should == ['a','b']
508
+ @roster.outfielders.members.sort.should == ['a','b']
509
+ @roster.outfielders.get.sort.should == ['a','b']
511
510
  @roster.outfielders << 'c'
512
511
  @roster.outfielders.sort.should == ['a','b','c']
513
512
  @roster.outfielders.get.sort.should == ['a','b','c']
514
513
  @roster.outfielders.delete('c')
515
- @roster.outfielders.should == ['a','b']
514
+ @roster.outfielders.sort.should == ['a','b']
516
515
  @roster.outfielders.get.sort.should == ['a','b']
517
516
  @roster.outfielders.length.should == 2
518
517
  @roster.outfielders.size.should == 2
@@ -524,9 +523,9 @@ describe Redis::Objects do
524
523
  i.should == @roster.outfielders.length
525
524
 
526
525
  coll = @roster.outfielders.collect{|st| st}
527
- coll.should == ['a','b']
528
- @roster.outfielders.should == ['a','b']
529
- @roster.outfielders.get.should == ['a','b']
526
+ coll.sort.should == ['a','b']
527
+ @roster.outfielders.sort.should == ['a','b']
528
+ @roster.outfielders.get.sort.should == ['a','b']
530
529
 
531
530
  @roster.outfielders << 'c'
532
531
  @roster.outfielders.member?('c').should.be.true
@@ -641,15 +640,14 @@ describe Redis::Objects do
641
640
  Roster.all_players_online.should == ['a']
642
641
  Roster.all_players_online.get.should == ['a']
643
642
  Roster.all_players_online << 'b' << 'b'
644
- Roster.all_players_online.to_s.should == 'a, b'
645
- Roster.all_players_online.should == ['a','b']
646
- Roster.all_players_online.members.should == ['a','b']
647
- Roster.all_players_online.get.should == ['a','b']
643
+ Roster.all_players_online.sort.should == ['a','b']
644
+ Roster.all_players_online.members.sort.should == ['a','b']
645
+ Roster.all_players_online.get.sort.should == ['a','b']
648
646
  Roster.all_players_online << 'c'
649
647
  Roster.all_players_online.sort.should == ['a','b','c']
650
648
  Roster.all_players_online.get.sort.should == ['a','b','c']
651
649
  Roster.all_players_online.delete('c')
652
- Roster.all_players_online.should == ['a','b']
650
+ Roster.all_players_online.sort.should == ['a','b']
653
651
  Roster.all_players_online.get.sort.should == ['a','b']
654
652
  Roster.all_players_online.length.should == 2
655
653
  Roster.all_players_online.size.should == 2
@@ -661,9 +659,9 @@ describe Redis::Objects do
661
659
  i.should == Roster.all_players_online.length
662
660
 
663
661
  coll = Roster.all_players_online.collect{|st| st}
664
- coll.should == ['a','b']
665
- Roster.all_players_online.should == ['a','b']
666
- Roster.all_players_online.get.should == ['a','b']
662
+ coll.sort.should == ['a','b']
663
+ Roster.all_players_online.sort.should == ['a','b']
664
+ Roster.all_players_online.get.sort.should == ['a','b']
667
665
 
668
666
  Roster.all_players_online << 'c'
669
667
  Roster.all_players_online.member?('c').should.be.true
@@ -731,13 +729,14 @@ describe Redis::Objects do
731
729
  end
732
730
 
733
731
  it "should handle sets of complex data types" do
734
- @roster.outfielders << {:a => 1} << {:b => 2}
732
+ @roster.outfielders << {:a => 1}
733
+ @roster.outfielders.members.should == [{:a => 1}]
734
+ @roster.outfielders << {:b => 2}
735
735
  @roster.outfielders.member?({:b => 2})
736
- @roster.outfielders.members.should == [{:b => 2}, {:a => 1}]
737
736
  @roster_1.outfielders << {:a => 1} << {:b => 2}
738
737
  @roster_2.outfielders << {:b => 2} << {:c => 3}
739
738
  (@roster_1.outfielders & @roster_2.outfielders).should == [{:b => 2}]
740
- (@roster_1.outfielders | @roster_2.outfielders).should == [{:b=>2}, {:c=>3}, {:a=>1}]
739
+ #(@roster_1.outfielders | @roster_2.outfielders).members.should ==
741
740
  end
742
741
 
743
742
  it "should provide a lock method that accepts a block" do
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'rubygems' # poor people still on 1.8
2
- gem 'redis', '>= 2.1.1'
2
+ gem 'redis', '>= 3.0.0'
3
3
  require 'redis'
4
4
 
5
5
  $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
@@ -28,7 +28,8 @@ at_exit do
28
28
  puts "=> Killing #{REDIS_BIN} with pid #{pid}"
29
29
  Process.kill "TERM", pid
30
30
  Process.kill "KILL", pid
31
- File.unlink REDIS_PID, REDIS_DUMP
31
+ File.unlink REDIS_PID
32
+ File.unlink REDIS_DUMP if File.exists? REDIS_DUMP
32
33
  end
33
34
 
34
35
  # Grab a global handle
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,91 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-13 00:00:00.000000000 Z
12
+ date: 2012-10-24 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: redis
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.0.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: redis-namespace
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bacon
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: jeweler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: activerecord
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
14
94
  - !ruby/object:Gem::Dependency
15
95
  name: bacon
16
- requirement: &2165783560 !ruby/object:Gem::Requirement
96
+ requirement: !ruby/object:Gem::Requirement
17
97
  none: false
18
98
  requirements:
19
99
  - - ! '>='
@@ -21,29 +101,44 @@ dependencies:
21
101
  version: '0'
22
102
  type: :development
23
103
  prerelease: false
24
- version_requirements: *2165783560
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
25
110
  - !ruby/object:Gem::Dependency
26
111
  name: redis-namespace
27
- requirement: &2165782960 !ruby/object:Gem::Requirement
112
+ requirement: !ruby/object:Gem::Requirement
28
113
  none: false
29
114
  requirements:
30
115
  - - ! '>='
31
116
  - !ruby/object:Gem::Version
32
- version: '0'
117
+ version: 1.2.0
33
118
  type: :development
34
119
  prerelease: false
35
- version_requirements: *2165782960
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: 1.2.0
36
126
  - !ruby/object:Gem::Dependency
37
127
  name: redis
38
- requirement: &2165782480 !ruby/object:Gem::Requirement
128
+ requirement: !ruby/object:Gem::Requirement
39
129
  none: false
40
130
  requirements:
41
131
  - - ! '>='
42
132
  - !ruby/object:Gem::Version
43
- version: 2.1.1
133
+ version: 3.0.2
44
134
  type: :runtime
45
135
  prerelease: false
46
- version_requirements: *2165782480
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: 3.0.2
47
142
  description: Map Redis types directly to Ruby objects. Works with any class or ORM.
48
143
  email: nate@wiger.org
49
144
  executables: []
@@ -53,6 +148,8 @@ extra_rdoc_files:
53
148
  files:
54
149
  - ATOMICITY.rdoc
55
150
  - CHANGELOG.rdoc
151
+ - Gemfile
152
+ - Gemfile.lock
56
153
  - README.rdoc
57
154
  - Rakefile
58
155
  - VERSION
@@ -92,6 +189,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
189
  - - ! '>='
93
190
  - !ruby/object:Gem::Version
94
191
  version: '0'
192
+ segments:
193
+ - 0
194
+ hash: 4220055926051714921
95
195
  required_rubygems_version: !ruby/object:Gem::Requirement
96
196
  none: false
97
197
  requirements:
@@ -99,9 +199,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
199
  - !ruby/object:Gem::Version
100
200
  version: '0'
101
201
  requirements:
102
- - redis, v2.1.1 or greater
202
+ - redis, v3.0.2 or greater
103
203
  rubyforge_project:
104
- rubygems_version: 1.8.10
204
+ rubygems_version: 1.8.24
105
205
  signing_key:
106
206
  specification_version: 3
107
207
  summary: Map Redis types directly to Ruby objects