ohm 0.0.28 → 0.0.29

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/lib/ohm.rb +63 -17
  2. data/test/model_test.rb +20 -0
  3. data/test/redis_test.rb +74 -52
  4. metadata +1 -1
data/lib/ohm.rb CHANGED
@@ -368,15 +368,18 @@ module Ohm
368
368
  #
369
369
  # @param name [Symbol] Name of the attribute.
370
370
  def self.attribute(name)
371
- define_method(name) do
372
- read_local(name)
373
- end
371
+ unless attributes.include?(name)
374
372
 
375
- define_method(:"#{name}=") do |value|
376
- write_local(name, value)
377
- end
373
+ define_method(name) do
374
+ read_local(name)
375
+ end
378
376
 
379
- attributes << name
377
+ define_method(:"#{name}=") do |value|
378
+ write_local(name, value)
379
+ end
380
+
381
+ attributes << name
382
+ end
380
383
  end
381
384
 
382
385
  # Defines a counter attribute for the model. This attribute can't be assigned, only incremented
@@ -384,11 +387,14 @@ module Ohm
384
387
  #
385
388
  # @param name [Symbol] Name of the counter.
386
389
  def self.counter(name)
387
- define_method(name) do
388
- read_local(name).to_i
389
- end
390
+ unless counters.include?(name)
391
+
392
+ define_method(name) do
393
+ read_local(name).to_i
394
+ end
390
395
 
391
- counters << name
396
+ counters << name
397
+ end
392
398
  end
393
399
 
394
400
  # Defines a list attribute for the model. It can be accessed only after the model instance
@@ -396,8 +402,10 @@ module Ohm
396
402
  #
397
403
  # @param name [Symbol] Name of the list.
398
404
  def self.list(name, model = nil)
399
- attr_list_reader(name, model)
400
- collections << name
405
+ unless collections.include?(name)
406
+ attr_list_reader(name, model)
407
+ collections << name
408
+ end
401
409
  end
402
410
 
403
411
  # Defines a set attribute for the model. It can be accessed only after the model instance
@@ -406,8 +414,10 @@ module Ohm
406
414
  #
407
415
  # @param name [Symbol] Name of the set.
408
416
  def self.set(name, model = nil)
409
- attr_set_reader(name, model)
410
- collections << name
417
+ unless collections.include?(name)
418
+ attr_set_reader(name, model)
419
+ collections << name
420
+ end
411
421
  end
412
422
 
413
423
  # Creates an index (a set) that will be used for finding instances.
@@ -426,7 +436,9 @@ module Ohm
426
436
  #
427
437
  # @param name [Symbol] Name of the attribute to be indexed.
428
438
  def self.index(att)
429
- indices << att
439
+ unless indices.include?(att)
440
+ indices << att
441
+ end
430
442
  end
431
443
 
432
444
  def self.attr_list_reader(name, model = nil)
@@ -609,10 +621,37 @@ module Ohm
609
621
  self.class.key(id, *args)
610
622
  end
611
623
 
624
+ # Rewrite at runtime to use either SET or MSET for persisting to
625
+ # Redis. The idea is to use MSET when possible.
612
626
  def write
627
+ if legacy_redis_version?
628
+ def write
629
+ write_with_set
630
+ end
631
+ else
632
+ def write
633
+ write_with_mset
634
+ end
635
+ end
636
+ write
637
+ end
638
+
639
+ # Write attributes using SET
640
+ # This method will be removed once MSET becomes standard.
641
+ def write_with_set
642
+ attributes.each do |att|
643
+ (value = send(att)) ?
644
+ db.set(key(att), value) :
645
+ db.del(key(att))
646
+ end
647
+ end
648
+
649
+ # Write attributes using MSET
650
+ # This is the preferred method, and will be the only option
651
+ # available once MSET becomes standard.
652
+ def write_with_mset
613
653
  unless attributes.empty?
614
654
  rems, adds = attributes.map { |a| [key(a), send(a)] }.partition { |t| t.last.nil? }
615
-
616
655
  db.del(*rems.flatten.compact) unless rems.empty?
617
656
  db.mset(adds.flatten) unless adds.empty?
618
657
  end
@@ -620,6 +659,13 @@ module Ohm
620
659
 
621
660
  private
622
661
 
662
+ # Determine if MSET is available. This method
663
+ # and the branch at #write will be deprecated
664
+ # once Redis 1.1 becomes the recommended version.
665
+ def legacy_redis_version?
666
+ db.info[:redis_version] <= "1.02"
667
+ end
668
+
623
669
  def self.db
624
670
  Ohm.redis
625
671
  end
@@ -626,4 +626,24 @@ class TestRedis < Test::Unit::TestCase
626
626
  assert_equal %Q{#<Bar:#{bar.id} name="Albert" friends=#<Set: ["1", "2"]> comments=#<List: ["A"]> visits=1>}, Bar[bar.id].inspect
627
627
  end
628
628
  end
629
+
630
+ context "Overwritting write" do
631
+ class ::Baz < Ohm::Model
632
+ attribute :name
633
+
634
+ def write
635
+ self.name = "Foobar"
636
+ super
637
+ end
638
+ end
639
+
640
+ should "work properly" do
641
+ baz = Baz.new
642
+ baz.name = "Foo"
643
+ baz.save
644
+ baz.name = "Foo"
645
+ baz.save
646
+ assert_equal "Foobar", Baz[baz.id].name
647
+ end
648
+ end
629
649
  end
@@ -14,6 +14,12 @@ class Foo
14
14
  end
15
15
 
16
16
  class RedisTest < Test::Unit::TestCase
17
+ setup do
18
+ @legacy ||= begin
19
+ Ohm.redis.info[:redis_version] <= "1.02"
20
+ end
21
+ end
22
+
17
23
  describe "redis" do
18
24
  setup do
19
25
  @r ||= Ohm.redis
@@ -41,9 +47,11 @@ class RedisTest < Test::Unit::TestCase
41
47
  end
42
48
 
43
49
  should "be able to MSET keys" do
44
- @r.mset(:foo => "foobar", :bar => 1000)
45
- assert_equal ["foobar", "1000"], @r.mget("foo", "bar")
46
- assert_equal ["foobar", "1000", nil], @r.mget("foo", "bar", "baz")
50
+ unless @legacy
51
+ @r.mset(:foo => "foobar", :bar => 1000)
52
+ assert_equal ["foobar", "1000"], @r.mget("foo", "bar")
53
+ assert_equal ["foobar", "1000", nil], @r.mget("foo", "bar", "baz")
54
+ end
47
55
  end
48
56
 
49
57
  should "be able to MGET keys" do
@@ -224,19 +232,21 @@ class RedisTest < Test::Unit::TestCase
224
232
  end
225
233
 
226
234
  should "be able to pop values from a list and push them onto a temp list with RPOPLPUSH" do
227
- @r.rpush "list", 'one'
228
- @r.rpush "list", 'two'
229
- @r.rpush "list", 'three'
230
- assert_equal "list", @r.type('list')
231
- assert_equal 3, @r.llen('list')
232
- assert_equal %w(one two three), @r.lrange('list',0,-1)
233
- assert_equal [], @r.lrange('tmp',0,-1)
234
- assert_equal "three", @r.rpoplpush('list', 'tmp')
235
- assert_equal %w(three), @r.lrange('tmp',0,-1)
236
- assert_equal "two", @r.rpoplpush('list', 'tmp')
237
- assert_equal %w(two three), @r.lrange('tmp',0,-1)
238
- assert_equal "one", @r.rpoplpush('list', 'tmp')
239
- assert_equal %w(one two three), @r.lrange('tmp',0,-1)
235
+ unless @legacy
236
+ @r.rpush "list", 'one'
237
+ @r.rpush "list", 'two'
238
+ @r.rpush "list", 'three'
239
+ assert_equal "list", @r.type('list')
240
+ assert_equal 3, @r.llen('list')
241
+ assert_equal %w(one two three), @r.lrange('list',0,-1)
242
+ assert_equal [], @r.lrange('tmp',0,-1)
243
+ assert_equal "three", @r.rpoplpush('list', 'tmp')
244
+ assert_equal %w(three), @r.lrange('tmp',0,-1)
245
+ assert_equal "two", @r.rpoplpush('list', 'tmp')
246
+ assert_equal %w(two three), @r.lrange('tmp',0,-1)
247
+ assert_equal "one", @r.rpoplpush('list', 'tmp')
248
+ assert_equal %w(one two three), @r.lrange('tmp',0,-1)
249
+ end
240
250
  end
241
251
 
242
252
  should "be able add members to a set" do
@@ -310,58 +320,70 @@ class RedisTest < Test::Unit::TestCase
310
320
  end
311
321
 
312
322
  should "be able add members to a zset ZADD" do
313
- @r.zadd 'zset', 1, 'set'
314
- assert_equal %w(set), @r.zrange('zset', 0, 1)
315
- assert_equal 1, @r.zcard('zset')
316
- @r.del('zset')
323
+ unless @legacy
324
+ @r.zadd 'zset', 1, 'set'
325
+ assert_equal %w(set), @r.zrange('zset', 0, 1)
326
+ assert_equal 1, @r.zcard('zset')
327
+ @r.del('zset')
328
+ end
317
329
  end
318
330
 
319
331
  should "be able count the members of a zset ZCARD" do
320
- @r.zadd 'zset', 1, 'foo'
321
- @r.zcard('zset')
322
- @r.del('zset')
332
+ unless @legacy
333
+ @r.zadd 'zset', 1, 'foo'
334
+ @r.zcard('zset')
335
+ @r.del('zset')
336
+ end
323
337
  end
324
338
 
325
339
 
326
340
  should "be able delete members of a zset ZREM" do
327
- @r.zadd 'zset', 1, 'set'
328
- assert_equal 1, @r.zcard('zset')
329
- @r.zadd 'zset', 2, 'set2'
330
- assert_equal 2, @r.zcard('zset')
331
- @r.zrem 'zset', 'set'
332
- assert_equal 1, @r.zcard('zset')
333
- @r.del('zset')
341
+ unless @legacy
342
+ @r.zadd 'zset', 1, 'set'
343
+ assert_equal 1, @r.zcard('zset')
344
+ @r.zadd 'zset', 2, 'set2'
345
+ assert_equal 2, @r.zcard('zset')
346
+ @r.zrem 'zset', 'set'
347
+ assert_equal 1, @r.zcard('zset')
348
+ @r.del('zset')
349
+ end
334
350
  end
335
351
 
336
352
  should "be able to get a range of values from a zset ZRANGE" do
337
- @r.zadd 'zset', 1, 'set'
338
- @r.zadd 'zset', 2, 'set2'
339
- @r.zadd 'zset', 3, 'set3'
340
- assert_equal 3, @r.zcard('zset')
341
- assert_equal %w(set set2 set3), @r.zrange('zset', 0, 3)
342
- @r.del('set')
343
- @r.del('set2')
344
- @r.del('set3')
345
- @r.del('zset')
353
+ unless @legacy
354
+ @r.zadd 'zset', 1, 'set'
355
+ @r.zadd 'zset', 2, 'set2'
356
+ @r.zadd 'zset', 3, 'set3'
357
+ assert_equal 3, @r.zcard('zset')
358
+ assert_equal %w(set set2 set3), @r.zrange('zset', 0, 3)
359
+ @r.del('set')
360
+ @r.del('set2')
361
+ @r.del('set3')
362
+ @r.del('zset')
363
+ end
346
364
  end
347
365
 
348
366
  should "be able to get a reverse range of values from a zset ZREVRANGE" do
349
- @r.zadd 'zset', 1, 'set'
350
- @r.zadd 'zset', 2, 'set2'
351
- @r.zadd 'zset', 3, 'set3'
352
- assert_equal 3, @r.zcard('zset')
353
- assert_equal %w(set3 set2 set), @r.zrevrange('zset', 0, 3)
354
- @r.del('zset')
367
+ unless @legacy
368
+ @r.zadd 'zset', 1, 'set'
369
+ @r.zadd 'zset', 2, 'set2'
370
+ @r.zadd 'zset', 3, 'set3'
371
+ assert_equal 3, @r.zcard('zset')
372
+ assert_equal %w(set3 set2 set), @r.zrevrange('zset', 0, 3)
373
+ @r.del('zset')
374
+ end
355
375
  end
356
376
 
357
377
  should "be able to get a range by score of values from a zset ZRANGEBYSCORE" do
358
- @r.zadd 'zset', 1, 'set'
359
- @r.zadd 'zset', 2, 'set2'
360
- @r.zadd 'zset', 3, 'set3'
361
- @r.zadd 'zset', 4, 'set4'
362
- assert_equal 4, @r.zcard('zset')
363
- assert_equal %w(set2 set3), @r.zrangebyscore('zset', 2, 3)
364
- @r.del('zset')
378
+ unless @legacy
379
+ @r.zadd 'zset', 1, 'set'
380
+ @r.zadd 'zset', 2, 'set2'
381
+ @r.zadd 'zset', 3, 'set3'
382
+ @r.zadd 'zset', 4, 'set4'
383
+ assert_equal 4, @r.zcard('zset')
384
+ assert_equal %w(set2 set3), @r.zrangebyscore('zset', 2, 3)
385
+ @r.del('zset')
386
+ end
365
387
  end
366
388
 
367
389
  should "provide info" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ohm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.28
4
+ version: 0.0.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michel Martens