diff --git a/lib/ork/model/document.rb b/lib/ork/model/document.rb index 5e38867..ffea127 100644 --- a/lib/ork/model/document.rb +++ b/lib/ork/model/document.rb @@ -69,13 +69,20 @@ def update(attributes) # u = User.new(:name => "John").save # # => #"John"}> # - def save + def save(options = {}) + quorum_types = [:r, :w, :dw] + quorum = options.fetch(:quorum, {}) + + unless quorum.empty? + raise ArgumentError.new("invalid quorum option") unless quorum.keys.select { |key| !quorum_types.include?(key) }.empty? + end + __robject.content_type = model.content_type __robject.data = __persist_attributes __check_unique_indices __update_indices - __robject.store + __robject.store(quorum) @id = __robject.key @@ -83,13 +90,16 @@ def save end # Preload all the attributes of this model from Riak. - def reload - new? ? self : self.load!(@id) + def reload(options = {}) + new? ? self : self.load!(@id, options) end # Delete the model - def delete - __robject.delete unless new? + def delete(options = {}) + opts = {} + opts.merge!(rw: options[:quorum].to_i) if options[:quorum] + + __robject.delete(opts) unless new? freeze rescue Riak::FailedRequest false @@ -99,9 +109,13 @@ def delete # Overwrite attributes with the persisted attributes in Riak. # - def load!(id) + def load!(id, options = {}) + opts = {} + opts.merge!(force: true) if options[:force] + opts.merge!(r: options[:quorum].to_i) if options[:quorum] + self.__robject.key = id - __load_robject! id, @__robject.reload(force: true) + __load_robject! id, @__robject.reload(opts) end # Transform a RObject returned by Riak into a Ork::Document. diff --git a/lib/ork/model/finders.rb b/lib/ork/model/finders.rb index c375230..a5c6b8e 100644 --- a/lib/ork/model/finders.rb +++ b/lib/ork/model/finders.rb @@ -11,13 +11,16 @@ module Finders # u == User[u.id] # # => true # - def [](id) - load_key(id) if exist?(id) + def [](id, options = {}) + load_key(id, options) if exist?(id, options) end # Check if the ID exists. - def exist?(id) - !id.nil? && bucket.exists?(id) + def exist?(id, options = {}) + opts = {} + opts.merge!(r: options[:quorum].to_i) if options[:quorum] + + !id.nil? && bucket.exists?(id, opts) end alias :exists? :exist? @@ -69,8 +72,8 @@ def find(by_index, value, options = {}) private - def load_key(id) - new.send(:load!, id) + def load_key(id, options) + new.send(:load!, id, options.merge(force: true)) rescue Riak::FailedRequest => e raise e unless e.not_found? end diff --git a/test/model/finders_test.rb b/test/model/finders_test.rb index 5253e03..251fac4 100644 --- a/test/model/finders_test.rb +++ b/test/model/finders_test.rb @@ -37,6 +37,17 @@ class Human test 'return nil when the id does not belong to an object of this bucket' do assert_equal nil, Human['not_an_id'] end + + test 'retrieve an object with given quorum' do + quorum = 1 + robject = Human.bucket.new + Human.bucket.stubs(:new).returns(robject) + robject.expects(:reload).with(force: true, r: quorum).returns(@human1.send(:__robject)) + + Human[@human1.id, quorum: quorum] + + Human.bucket.unstub(:new) + end end context '*exist?*' do @@ -45,6 +56,13 @@ class Human assert !Human.exist?('not_an_id') assert Human.exist?(@human1.id) end + + test 'check existence with given quorum' do + quorum = 1 + Human.bucket.expects(:exists?).once.with(@human1.id, r: quorum).returns(true) + + assert Human.exist?(@human1.id, quorum: quorum) + end end context '*all*' do diff --git a/test/model/model_test.rb b/test/model/model_test.rb index e13b91f..061c237 100644 --- a/test/model/model_test.rb +++ b/test/model/model_test.rb @@ -112,6 +112,14 @@ class Event assert_equal nil, @event.location end + test 'reload object with given quorum' do + quorum = 1 + robject = @event.send(:__robject) + robject.expects(:reload).with(force: true, r: quorum).returns(robject) + + @event.reload(quorum: quorum) + end + context 'Deletion' do test 'freeze the object' do assert !@event.frozen? @@ -126,6 +134,13 @@ class Event assert !Event.bucket.exist?(@event.id) end + test 'delete with quorum options' do + quorum = 1 + @event.send(:__robject).expects(:delete).with(rw: quorum) + + @event.delete(quorum: quorum) + end + test 'return false when something occurs' do exception = Riak::HTTPFailedRequest.new(:get, 200, 401, {}, {}) Riak::RObject.any_instance.stubs(:delete).raises(exception) @@ -153,6 +168,23 @@ class Event assert_equal 'text/plain', event.send(:__robject).content_type Event.content_type 'application/json' end + + test 'persist the object with quorum options' do + event = Event.create(name: 'Ruby') + + q = { w: 1, dw: 1 } + event.send(:__robject).expects(:store).with(q).once + event.save(quorum: q) + end + + test 'raises an error with invalid quorum options' do + event = Event.create(name: 'Ruby') + + q = { type: 'something' } + assert_raise ArgumentError do + event.save(quorum: q) + end + end end end