From 36945d5a13bead8270b9f6f9f5bb22d02de2715f Mon Sep 17 00:00:00 2001 From: Antony Blakey Date: Fri, 9 Jan 2009 20:29:08 +1030 Subject: [PATCH] Add bulk save deferal option to db.delete / doc.destroy, just like on save. --- lib/couchrest/core/database.rb | 11 ++++++++++- lib/couchrest/core/document.rb | 6 ++++-- spec/couchrest/core/database_spec.rb | 8 ++++++++ spec/couchrest/core/document_spec.rb | 19 +++++++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/lib/couchrest/core/database.rb b/lib/couchrest/core/database.rb index cf2494c..504ee00 100644 --- a/lib/couchrest/core/database.rb +++ b/lib/couchrest/core/database.rb @@ -165,9 +165,18 @@ module CouchRest # DELETE the document from CouchDB that has the given _id and # _rev. - def delete doc + # + # If bulk is true (false by default) the deletion is recorded for bulk-saving (bulk-deletion :) later. + # Bulk saving happens automatically when #bulk_save_cache limit is exceded, or on the next non bulk save. + def delete (doc, bulk = false) raise ArgumentError, "_id and _rev required for deleting" unless doc['_id'] && doc['_rev'] + if bulk + @bulk_save_cache << { '_id' => doc['_id'], '_rev' => doc['_rev'], '_deleted' => true } + return bulk_save if @bulk_save_cache.length >= @bulk_save_cache_limit + return { "ok" => true } # Mimic the non-deferred version + end + slug = CGI.escape(doc['_id']) CouchRest.delete "#{@root}/#{slug}?rev=#{doc['_rev']}" end diff --git a/lib/couchrest/core/document.rb b/lib/couchrest/core/document.rb index 71a5135..b47a7e0 100644 --- a/lib/couchrest/core/document.rb +++ b/lib/couchrest/core/document.rb @@ -45,9 +45,11 @@ module CouchRest # Deletes the document from the database. Runs the :delete callbacks. # Removes the _id and _rev fields, preparing the # document to be saved to a new _id. - def destroy + # If bulk is true (defaults to false) the document won't + # actually be deleted from the db until bulk save. + def destroy(bulk = false) raise ArgumentError, "doc.database required to destroy" unless database - result = database.delete self + result = database.delete(self, bulk) if result['ok'] self['_rev'] = nil self['_id'] = nil diff --git a/spec/couchrest/core/database_spec.rb b/spec/couchrest/core/database_spec.rb index 132d3c7..e84b5e3 100644 --- a/spec/couchrest/core/database_spec.rb +++ b/spec/couchrest/core/database_spec.rb @@ -472,6 +472,14 @@ describe CouchRest::Database do it "should fail without an _id" do lambda{@db.delete({"not"=>"a real doc"})}.should raise_error(ArgumentError) end + it "should defer actual deletion when using bulk save" do + doc = @db.get(@docid) + @db.delete doc, true + lambda{@db.get @docid}.should_not raise_error + @db.bulk_save + lambda{@db.get @docid}.should raise_error + end + end describe "COPY existing document" do diff --git a/spec/couchrest/core/document_spec.rb b/spec/couchrest/core/document_spec.rb index 485f638..0aef0bc 100644 --- a/spec/couchrest/core/document_spec.rb +++ b/spec/couchrest/core/document_spec.rb @@ -109,3 +109,22 @@ describe "destroying a document from a db" do lambda{@doc.destroy}.should raise_error(ArgumentError) end end + + +describe "destroying a document from a db using bulk save" do + before(:all) do + @db = reset_test_db! + @resp = @db.save({ + "key" => "value" + }) + @doc = @db.get @resp['id'] + end + it "should defer actual deletion" do + @doc.destroy(true) + @doc['_id'].should == nil + @doc['_rev'].should == nil + lambda{@db.get @resp['id']}.should_not raise_error + @db.bulk_save + lambda{@db.get @resp['id']}.should raise_error + end +end