redis-objects 0.7.0 → 0.8.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.
@@ -0,0 +1,5 @@
1
+ class Redis
2
+ module Objects
3
+ VERSION = "0.8.0"
4
+ end
5
+ end
@@ -115,14 +115,20 @@ class Redis
115
115
  from_redis redis.zrangebyscore(key, min, max, args)
116
116
  end
117
117
 
118
- # Forwards compat (not yet implemented in Redis)
119
- def revrangebyscore(min, max, options={})
118
+ # Returns all the elements in the sorted set at key with a score between max and min
119
+ # (including elements with score equal to max or min). In contrary to the default ordering of sorted sets,
120
+ # for this command the elements are considered to be ordered from high to low scores.
121
+ # Options:
122
+ # :count, :offset - passed to LIMIT
123
+ # :withscores - if true, scores are returned as well
124
+ # Redis: ZREVRANGEBYSCORE
125
+ def revrangebyscore(max, min, options={})
120
126
  args = {}
121
127
  args[:limit] = [options[:offset] || 0, options[:limit] || options[:count]] if
122
128
  options[:offset] || options[:limit] || options[:count]
123
129
  args[:with_scores] = true if options[:withscores] || options[:with_scores]
124
130
 
125
- from_redis redis.zrevrangebyscore(key, min, max, args)
131
+ from_redis redis.zrevrangebyscore(key, max, min, args)
126
132
  end
127
133
 
128
134
  # Remove all elements in the sorted set at key with rank between start and end. Start and end are
@@ -160,14 +166,14 @@ class Redis
160
166
  # Increment the rank of that member atomically and return the new value. This
161
167
  # method is aliased as incr() for brevity. Redis: ZINCRBY
162
168
  def increment(member, by=1)
163
- redis.zincrby(key, by, member).to_i
169
+ redis.zincrby(key, by, to_redis(member)).to_i
164
170
  end
165
171
  alias_method :incr, :increment
166
172
  alias_method :incrby, :increment
167
173
 
168
174
  # Convenience to calling increment() with a negative number.
169
175
  def decrement(member, by=1)
170
- redis.zincrby(key, -by, member).to_i
176
+ redis.zincrby(key, -by, to_redis(member)).to_i
171
177
  end
172
178
  alias_method :decr, :decrement
173
179
  alias_method :decrby, :decrement
@@ -1,76 +1,30 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'redis/objects/version'
5
5
 
6
- Gem::Specification.new do |s|
7
- s.name = "redis-objects"
8
- s.version = "0.7.0"
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "redis-objects"
8
+ spec.version = Redis::Objects::VERSION
9
+ spec.authors = ["Nate Wiger"]
10
+ spec.email = ["nwiger@gmail.com"]
11
+ spec.description = %q{Map Redis types directly to Ruby objects. Works with any class or ORM.}
12
+ spec.summary = %q{Map Redis types directly to Ruby objects}
13
+ spec.homepage = "http://github.com/nateware/redis-objects"
14
+ spec.license = "Artistic"
9
15
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Nate Wiger"]
12
- s.date = "2013-02-27"
13
- s.description = "Map Redis types directly to Ruby objects. Works with any class or ORM."
14
- s.email = "nwiger@gmail.com"
15
- s.extra_rdoc_files = [
16
- "README.md"
17
- ]
18
- s.files = [
19
- "ATOMICITY.rdoc",
20
- "CHANGELOG.rdoc",
21
- "Gemfile",
22
- "README.md",
23
- "Rakefile",
24
- "VERSION",
25
- "lib/redis-objects.rb",
26
- "lib/redis/base_object.rb",
27
- "lib/redis/counter.rb",
28
- "lib/redis/hash_key.rb",
29
- "lib/redis/helpers/core_commands.rb",
30
- "lib/redis/helpers/serialize.rb",
31
- "lib/redis/list.rb",
32
- "lib/redis/lock.rb",
33
- "lib/redis/objects.rb",
34
- "lib/redis/objects/counters.rb",
35
- "lib/redis/objects/hashes.rb",
36
- "lib/redis/objects/lists.rb",
37
- "lib/redis/objects/locks.rb",
38
- "lib/redis/objects/sets.rb",
39
- "lib/redis/objects/sorted_sets.rb",
40
- "lib/redis/objects/values.rb",
41
- "lib/redis/set.rb",
42
- "lib/redis/sorted_set.rb",
43
- "lib/redis/value.rb",
44
- "redis-objects.gemspec",
45
- "spec/redis_autoload_objects_spec.rb",
46
- "spec/redis_namespace_compat_spec.rb",
47
- "spec/redis_objects_active_record_spec.rb",
48
- "spec/redis_objects_conn_spec.rb",
49
- "spec/redis_objects_instance_spec.rb",
50
- "spec/redis_objects_model_spec.rb",
51
- "spec/spec_helper.rb"
52
- ]
53
- s.homepage = "http://github.com/nateware/redis-objects"
54
- s.require_paths = ["lib"]
55
- s.rubygems_version = "1.8.24"
56
- s.summary = "Map Redis types directly to Ruby objects"
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
57
20
 
58
- if s.respond_to? :specification_version then
59
- s.specification_version = 3
21
+ spec.add_dependency "redis", ">= 3.0.2"
60
22
 
61
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
62
- s.add_runtime_dependency(%q<redis>, [">= 3.0.2"])
63
- s.add_development_dependency(%q<bacon>, [">= 0"])
64
- s.add_development_dependency(%q<redis-namespace>, [">= 1.2.0"])
65
- else
66
- s.add_dependency(%q<redis>, [">= 3.0.2"])
67
- s.add_dependency(%q<bacon>, [">= 0"])
68
- s.add_dependency(%q<redis-namespace>, [">= 1.2.0"])
69
- end
70
- else
71
- s.add_dependency(%q<redis>, [">= 3.0.2"])
72
- s.add_dependency(%q<bacon>, [">= 0"])
73
- s.add_dependency(%q<redis-namespace>, [">= 1.2.0"])
74
- end
75
- end
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "bacon"
76
26
 
27
+ # compatability testing
28
+ spec.add_development_dependency "redis-namespace"
29
+ spec.add_development_dependency "activerecord", "~> 3.2"
30
+ end
@@ -8,7 +8,7 @@ describe Redis::Value do
8
8
  @value = Redis::Value.new('spec/value')
9
9
  @value.delete
10
10
  end
11
-
11
+
12
12
  it "should marshal default value" do
13
13
  @value = Redis::Value.new('spec/value', :default => {:json => 'data'}, :marshal => true)
14
14
  @value.value.should == {:json => 'data'}
@@ -30,7 +30,7 @@ describe Redis::Value do
30
30
  @value.should == nil
31
31
  @value.value = {:json => 'data'}
32
32
  @value.should == {:json => 'data'}
33
-
33
+
34
34
  # no marshaling
35
35
  @value.options[:marshal] = false
36
36
  v = {:json => 'data'}
@@ -171,6 +171,9 @@ describe Redis::List do
171
171
  @list.get.should == ['a','c','f']
172
172
  @list << 'j'
173
173
  @list.should == ['a','c','f','j']
174
+ @list.push 'h'
175
+ @list.push 'i', 'j'
176
+ @list.should == ['a','c','f','j','h','i','j']
174
177
  # Test against similar Ruby functionality
175
178
  a = @list.values
176
179
  @list[0..2].should == a[0..2]
@@ -184,34 +187,35 @@ describe Redis::List do
184
187
  @list.slice(1, 3).should == a.slice(1, 3)
185
188
  @list[0, 0].should == []
186
189
  @list[0, -1].should == a[0, -1]
187
- @list.length.should == 4
188
- @list.size.should == 4
190
+ @list.length.should == 7
189
191
  @list.should == a
190
192
  @list.get.should == a
193
+ @list.pop # lose 'j'
194
+ @list.size.should == 6
191
195
 
192
196
  i = -1
193
197
  @list.each do |st|
194
198
  st.should == @list[i += 1]
195
199
  end
196
- @list.should == ['a','c','f','j']
197
- @list.get.should == ['a','c','f','j']
200
+ @list.should == ['a','c','f','j','h','i']
201
+ @list.get.should == ['a','c','f','j','h','i']
198
202
 
199
203
  @list.each_with_index do |st,i|
200
204
  st.should == @list[i]
201
205
  end
202
- @list.should == ['a','c','f','j']
203
- @list.get.should == ['a','c','f','j']
206
+ @list.should == ['a','c','f','j','h','i']
207
+ @list.get.should == ['a','c','f','j','h','i']
204
208
 
205
209
  coll = @list.collect{|st| st}
206
- coll.should == ['a','c','f','j']
207
- @list.should == ['a','c','f','j']
208
- @list.get.should == ['a','c','f','j']
210
+ coll.should == ['a','c','f','j','h','i']
211
+ @list.should == ['a','c','f','j','h','i']
212
+ @list.get.should == ['a','c','f','j','h','i']
209
213
 
210
214
  @list << 'a'
211
215
  coll = @list.select{|st| st == 'a'}
212
216
  coll.should == ['a','a']
213
- @list.should == ['a','c','f','j','a']
214
- @list.get.should == ['a','c','f','j','a']
217
+ @list.should == ['a','c','f','j','h','i','a']
218
+ @list.get.should == ['a','c','f','j','h','i','a']
215
219
  end
216
220
 
217
221
  it "should handle rpoplpush" do
@@ -234,23 +238,42 @@ describe Redis::List do
234
238
  @list.should == ['z','a','b','c','d','e']
235
239
  end
236
240
 
241
+ it "should handle insert at a specific index" do
242
+ @list << 'b' << 'd'
243
+ @list.should == ['b','d']
244
+ @list[0] = 'a'
245
+ @list.should == ['a', 'd']
246
+ @list[1] = 'b'
247
+ @list.should == ['a', 'b']
248
+ end
249
+
237
250
  it "should handle lists of complex data types" do
238
251
  @list.options[:marshal] = true
239
252
  v1 = {:json => 'data'}
240
253
  v2 = {:json2 => 'data2'}
254
+ v3 = [1,2,3]
241
255
  @list << v1
242
256
  @list << v2
243
257
  @list.first.should == v1
258
+ @list[0] = @list[0].tap{|d| d[:json] = 'data_4'}
259
+ @list.first.should == {:json => 'data_4'}
244
260
  @list.last.should == v2
245
- @list << [1,2,3,[4,5]]
246
- @list.last.should == [1,2,3,[4,5]]
247
- @list.shift.should == {:json => 'data'}
261
+ @list << [1,2,3,[4,5],6]
262
+ @list.last.should == [1,2,3,[4,5],6]
263
+ @list.shift.should == {:json => 'data_4'}
248
264
  @list.size.should == 2
249
265
  @list.delete(v2)
250
266
  @list.size.should == 1
267
+ @list.push v1, v2
268
+ @list[1].should == v1
269
+ @list.last.should == v2
270
+ @list.size.should == 3
271
+ @list.unshift v2, v3
272
+ @list.size.should == 5
273
+ @list.first.should == v3
251
274
  @list.options[:marshal] = false
252
275
  end
253
-
276
+
254
277
  it "should support renaming lists" do
255
278
  @list.should.be.empty
256
279
  @list << 'a' << 'b' << 'a' << 3
@@ -292,7 +315,7 @@ describe Redis::Counter do
292
315
  @counter.key.should == 'spec/counter'
293
316
  @counter.incr(10)
294
317
  @counter.should == 10
295
-
318
+
296
319
  # math proxy ops
297
320
  (@counter == 10).should.be.true
298
321
  (@counter <= 10).should.be.true
@@ -446,13 +469,13 @@ describe Redis::HashKey do
446
469
  @hash = Redis::HashKey.new('test_hash')
447
470
  @hash.clear
448
471
  end
449
-
472
+
450
473
  it "should handle complex marshaled values" do
451
474
  @hash.options[:marshal] = true
452
475
  @hash['abc'].should == nil
453
476
  @hash['abc'] = {:json => 'data'}
454
477
  @hash['abc'].should == {:json => 'data'}
455
-
478
+
456
479
  # no marshaling
457
480
  @hash.options[:marshal] = false
458
481
  v = {:json => 'data'}
@@ -465,26 +488,26 @@ describe Redis::HashKey do
465
488
  @hash.fetch('abc').should == [[1,2], {:t3 => 4}]
466
489
  @hash.delete('abc').should == 1
467
490
  @hash.fetch('abc').should.be.nil
468
-
491
+
469
492
  @hash.options[:marshal] = true
470
493
  @hash.bulk_set('abc' => [[1,2], {:t3 => 4}], 'def' => [[6,8], {:t4 => 8}])
471
494
  hsh = @hash.bulk_get('abc', 'def', 'foo')
472
495
  hsh['abc'].should == [[1,2], {:t3 => 4}]
473
496
  hsh['def'].should == [[6,8], {:t4 => 8}]
474
497
  hsh['foo'].should.be.nil
475
-
498
+
476
499
  hsh = @hash.all
477
500
  hsh['abc'].should == [[1,2], {:t3 => 4}]
478
501
  hsh['def'].should == [[6,8], {:t4 => 8}]
479
-
480
- @hash.values.should == [[[1,2], {:t3 => 4}], [[6,8], {:t4 => 8}]]
481
-
502
+
503
+ @hash.values.sort.should == [[[1,2], {:t3 => 4}], [[6,8], {:t4 => 8}]].sort
504
+
482
505
  @hash.delete('def').should == 1
483
506
  @hash.delete('abc').should == 1
484
-
507
+
485
508
  @hash.options[:marshal] = false
486
509
  end
487
-
510
+
488
511
  it "should get and set values" do
489
512
  @hash['foo'] = 'bar'
490
513
  @hash['foo'].should == 'bar'
@@ -508,7 +531,7 @@ describe Redis::HashKey do
508
531
  val.should == 'bar'
509
532
  end
510
533
  end
511
-
534
+
512
535
  it "should have 1 item" do
513
536
  @hash['foo'] = 'bar'
514
537
  @hash.size.should == 1
@@ -539,7 +562,7 @@ describe Redis::HashKey do
539
562
  @hash.clear
540
563
  @hash.should.be.empty
541
564
  end
542
-
565
+
543
566
  it "should respond to bulk_set" do
544
567
  @hash.bulk_set({'abc' => 'xyz', 'bizz' => 'bazz'})
545
568
  @hash['abc'].should == 'xyz'
@@ -569,18 +592,20 @@ describe Redis::HashKey do
569
592
 
570
593
  it "should respond to fill" do
571
594
  @hash['foo'] = 'bar'
572
-
595
+
573
596
  @hash.fill('abc' => '123', 'bang' => 'michael')
574
597
  @hash['foo'].should == 'bar'
575
598
  @hash['abc'].should == '123'
576
599
  @hash['bang'].should == 'michael'
600
+
601
+ it "raises an error if a non-Hash is passed to fill" do
602
+ lambda { @hash.fill([]) }.should.raise(ArgumentError)
603
+ end
577
604
  end
578
-
579
605
 
580
606
  after do
581
607
  @hash.clear
582
608
  end
583
-
584
609
  end
585
610
 
586
611
  describe Redis::Set do
@@ -616,7 +641,7 @@ describe Redis::Set do
616
641
  @set.size.should == 2
617
642
  @set.delete('a')
618
643
  @set.pop.should == 'b'
619
-
644
+
620
645
  @set.add('a')
621
646
  @set.add('b')
622
647
 
@@ -641,7 +666,7 @@ describe Redis::Set do
641
666
  @set.delete_if{|m| m == 'c'}
642
667
  @set.sort.should == ['a','b']
643
668
  end
644
-
669
+
645
670
  it "should handle set intersections, unions, and diffs" do
646
671
  @set_1 << 'a' << 'b' << 'c' << 'd' << 'e'
647
672
  @set_2 << 'c' << 'd' << 'e' << 'f' << 'g'
@@ -716,14 +741,21 @@ describe Redis::Set do
716
741
  @set_2.sort(SORT_LIMIT).should == %w(3 4)
717
742
 
718
743
  @set_3 << 'm_4' << 'm_5' << 'm_1' << 'm_3' << 'm_2'
719
- @set_3.sort(:by => 'm_*').should == %w(m_1 m_2 m_3 m_4 m_5)
744
+ ### incorrect interpretation of what the :by parameter means
745
+ ### :by will look up values of keys so it would try to find a value in
746
+ ### redis of "m_m_1" which doesn't exist at this point, it is not a way to
747
+ ### alter the value to sort by but rather use a different value for this value
748
+ ### in the set (Kris Fox)
749
+ # @set_3.sort(:by => 'm_*').should == %w(m_1 m_2 m_3 m_4 m_5)
750
+ # below passes just fine
751
+ @set_3.sort.should == %w(m_1 m_2 m_3 m_4 m_5)
720
752
 
721
753
  val1 = Redis::Value.new('spec/3/sorted')
722
754
  val2 = Redis::Value.new('spec/4/sorted')
723
755
 
724
756
  val1.set('val3')
725
757
  val2.set('val4')
726
-
758
+
727
759
  @set_2.sort(SORT_GET).should == ['val3', 'val4']
728
760
  @set_2.sort(SORT_STORE).should == 2
729
761
  @set_2.redis.type(SORT_STORE[:store]).should == 'list'
@@ -740,7 +772,6 @@ describe Redis::Set do
740
772
  @set_1.clear
741
773
  @set_2.clear
742
774
  @set_3.clear
743
-
744
775
  end
745
776
  end
746
777
 
@@ -750,10 +781,12 @@ describe Redis::SortedSet do
750
781
  @set_1 = Redis::SortedSet.new('spec/zset_1')
751
782
  @set_2 = Redis::SortedSet.new('spec/zset_2')
752
783
  @set_3 = Redis::SortedSet.new('spec/zset_3')
784
+ @set_4 = Redis::SortedSet.new('spec/zset_3', :marshal => true)
753
785
  @set.clear
754
786
  @set_1.clear
755
787
  @set_2.clear
756
788
  @set_3.clear
789
+ @set_4.clear
757
790
  end
758
791
 
759
792
  it "should handle sorted sets of simple values" do
@@ -800,18 +833,17 @@ describe Redis::SortedSet do
800
833
  @set.should == ['a','b']
801
834
  @set.members.should == ['a','b']
802
835
  @set['d'] = 0
803
-
836
+
804
837
  @set.rangebyscore(0, 4).should == ['d','a']
805
838
  @set.rangebyscore(0, 4, :count => 1).should == ['d']
806
839
  @set.rangebyscore(0, 4, :count => 2).should == ['d','a']
807
840
  @set.rangebyscore(0, 4, :limit => 2).should == ['d','a']
808
841
 
809
- # Redis 1.3.5
810
- # @set.rangebyscore(0,4, :withscores => true).should == [['d',4],['a',3]]
811
- # @set.revrangebyscore(0,4).should == ['d','a']
812
- # @set.revrangebyscore(0,4, :count => 2).should == ['a','d']
813
- # @set.rank('b').should == 2
814
- # @set.revrank('b').should == 3
842
+ @set.revrangebyscore(4, 0, :withscores => true).should == [['a', 3], ['d', 0]]
843
+ @set.revrangebyscore(4, 0).should == ['a', 'd']
844
+ @set.revrangebyscore(4, 0, :count => 2).should == ['a','d']
845
+ @set.rank('b').should == 2
846
+ @set.revrank('b').should == 0
815
847
 
816
848
  # shouldn't report a rank for a key that doesn't exist
817
849
  @set.rank('foo').should.not == @set.rank(@set.first)
@@ -841,15 +873,24 @@ describe Redis::SortedSet do
841
873
  @set.delete('c')
842
874
  @set.length.should == 4
843
875
  @set.size.should == 4
844
-
876
+
845
877
  @set.range_size(100, 120).should == 0
846
878
  @set.range_size(0, 100).should == 2
847
879
  @set.range_size('-inf', 'inf').should == 4
848
-
880
+
849
881
  @set.delete_if{|m| m == 'b'}
850
882
  @set.size.should == 3
851
883
  end
852
884
 
885
+ it "should support marshaling key names" do
886
+ @set_4[Object] = 1.20
887
+ @set_4[Module] = 2.30
888
+ @set_4.incr(Object, 0.5)
889
+ @set_4.decr(Module, 0.5)
890
+ @set_4[Object].round(1).should == 1.7
891
+ @set_4[Module].round(1).should == 1.8
892
+ end
893
+
853
894
  it "should support renaming sorted sets" do
854
895
  @set.should.be.empty
855
896
  @set['zynga'] = 151
@@ -873,5 +914,6 @@ describe Redis::SortedSet do
873
914
  @set_1.clear
874
915
  @set_2.clear
875
916
  @set_3.clear
917
+ @set_4.clear
876
918
  end
877
919
  end