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