ohm 0.0.17 → 0.0.18

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 +43 -9
  2. data/test/model_test.rb +27 -4
  3. data/test/mutex_test.rb +36 -0
  4. metadata +6 -7
data/lib/ohm.rb CHANGED
@@ -385,10 +385,7 @@ module Ohm
385
385
 
386
386
  def initialize(attrs = {})
387
387
  @_attributes = Hash.new {|hash,key| hash[key] = read_remote(key) }
388
-
389
- attrs.each do |key, value|
390
- send(:"#{key}=", value)
391
- end
388
+ update_attributes(attrs)
392
389
  end
393
390
 
394
391
  def new?
@@ -398,16 +395,33 @@ module Ohm
398
395
  def create
399
396
  return unless valid?
400
397
  initialize_id
401
- create_model_membership
402
- add_to_indices
403
- save!
398
+
399
+ mutex do
400
+ create_model_membership
401
+ add_to_indices
402
+ save!
403
+ end
404
404
  end
405
405
 
406
406
  def save
407
407
  return create if new?
408
408
  return unless valid?
409
- update_indices
410
- save!
409
+
410
+ mutex do
411
+ update_indices
412
+ save!
413
+ end
414
+ end
415
+
416
+ def update(attrs)
417
+ update_attributes(attrs)
418
+ save
419
+ end
420
+
421
+ def update_attributes(attrs)
422
+ attrs.each do |key, value|
423
+ send(:"#{key}=", value)
424
+ end
411
425
  end
412
426
 
413
427
  def delete
@@ -457,6 +471,14 @@ module Ohm
457
471
  false
458
472
  end
459
473
 
474
+ # Lock the object before ejecuting the block, and release it once the block is done.
475
+ def mutex
476
+ lock!
477
+ yield
478
+ unlock!
479
+ self
480
+ end
481
+
460
482
  protected
461
483
 
462
484
  def key(*args)
@@ -553,5 +575,17 @@ module Ohm
553
575
  def index_key_for(attrs, values)
554
576
  self.class.key *(attrs + self.class.encode_each(values))
555
577
  end
578
+
579
+ # Lock the object so no other instances can modify it.
580
+ # @see Model#mutex
581
+ def lock!
582
+ lock = db.setnx(key(:_lock), 1) until lock == 1
583
+ end
584
+
585
+ # Release the lock.
586
+ # @see Model#mutex
587
+ def unlock!
588
+ db.del(key(:_lock))
589
+ end
556
590
  end
557
591
  end
data/test/model_test.rb CHANGED
@@ -24,7 +24,6 @@ class Event < Ohm::Model
24
24
  set :attendees, Person
25
25
  end
26
26
 
27
-
28
27
  class TestRedis < Test::Unit::TestCase
29
28
  context "An event initialized with a hash of attributes" do
30
29
  should "assign the passed attributes" do
@@ -45,6 +44,28 @@ class TestRedis < Test::Unit::TestCase
45
44
  end
46
45
  end
47
46
 
47
+ context "An event updated from a hash of attributes" do
48
+
49
+ class Meetup < Ohm::Model
50
+ attribute :name
51
+
52
+ def validate
53
+ assert_present :name
54
+ end
55
+ end
56
+
57
+ should "assign an id and save the object" do
58
+ event = Meetup.create(:name => "Ruby Tuesday")
59
+ event.update(:name => "Ruby Meetup")
60
+ assert_equal "Ruby Meetup", event.name
61
+ end
62
+
63
+ should "return false if the validation fails" do
64
+ event = Meetup.create(:name => "Ruby Tuesday")
65
+ assert !event.update(:name => nil)
66
+ end
67
+ end
68
+
48
69
  context "Finding an event" do
49
70
  setup do
50
71
  Ohm.redis.sadd("Event", 1)
@@ -350,18 +371,20 @@ class TestRedis < Test::Unit::TestCase
350
371
  end
351
372
 
352
373
  context "Applying arbitrary transformations" do
374
+ require "date"
375
+
353
376
  class Calendar < Ohm::Model
354
377
  list :holidays, lambda { |v| Date.parse(v) }
355
378
  end
356
379
 
357
380
  setup do
358
381
  @calendar = Calendar.create
359
- @calendar.holidays << "05/25/2009"
360
- @calendar.holidays << "07/09/2009"
382
+ @calendar.holidays << "2009-05-25"
383
+ @calendar.holidays << "2009-07-09"
361
384
  end
362
385
 
363
386
  should "apply a transformation" do
364
- assert_equal [Date.parse("2009-05-25"), Date.parse("2009-07-09")], @calendar.holidays
387
+ assert_equal [Date.new(2009, 5, 25), Date.new(2009, 7, 9)], @calendar.holidays
365
388
  end
366
389
  end
367
390
 
@@ -0,0 +1,36 @@
1
+ require File.join(File.dirname(__FILE__), "test_helper")
2
+
3
+ class TestMutex < Test::Unit::TestCase
4
+ class Person < Ohm::Model
5
+ attribute :name
6
+ end
7
+
8
+ setup do
9
+ Ohm.flush
10
+ @p1 = Person.create :name => "Albert"
11
+ @p2 = Person[1]
12
+ end
13
+
14
+ context "Using a mutex on an object" do
15
+ should "prevent other instances of the same object from grabing a locked record" do
16
+ t1 = t2 = nil
17
+ p1 = Thread.new do
18
+ @p1.mutex do
19
+ sleep 0.4
20
+ t1 = Time.now
21
+ end
22
+ end
23
+
24
+ p2 = Thread.new do
25
+ sleep 0.1
26
+ @p2.mutex do
27
+ t2 = Time.now
28
+ end
29
+ end
30
+
31
+ p1.join
32
+ p2.join
33
+ assert t2 > t1
34
+ end
35
+ end
36
+ end
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.17
4
+ version: 0.0.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michel Martens
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-08-25 00:00:00 -07:00
13
+ date: 2009-09-07 00:00:00 -03:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -37,14 +37,13 @@ files:
37
37
  - test/errors_test.rb
38
38
  - test/indices_test.rb
39
39
  - test/model_test.rb
40
+ - test/mutex_test.rb
40
41
  - test/redis_test.rb
41
42
  - test/test_helper.rb
42
43
  - test/validations_test.rb
43
44
  - test/test.conf
44
- has_rdoc: true
45
+ has_rdoc: false
45
46
  homepage: http://github.com/soveran/ohm
46
- licenses: []
47
-
48
47
  post_install_message:
49
48
  rdoc_options: []
50
49
 
@@ -65,9 +64,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
64
  requirements: []
66
65
 
67
66
  rubyforge_project: ohm
68
- rubygems_version: 1.3.4
67
+ rubygems_version: 1.3.1
69
68
  signing_key:
70
- specification_version: 3
69
+ specification_version: 2
71
70
  summary: Object-hash mapping library for Redis.
72
71
  test_files: []
73
72