public
Description: Ruby interface to CouchDB
Homepage: http://code.google.com/p/activecouch/
Clone URL: git://github.com/JackDanger/active_couch.git
- Added class-level delete method (POLS)
- Instance level delete method should set id and rev on deletion, should 
return true if successfully deleted
- Specs for both methods

git-svn-id: http://activecouch.googlecode.com/svn/trunk@63 
e44de9e2-1e40-0410-bb6c-c9d70e891a3e
arun.thampi (author)
Mon Jan 21 20:20:11 -0800 2008
commit  9382da6dd9089dd98b31f21d9406481577e3ed3a
tree    43f25e4087208e7bffbc53ff82738dd93ae968bb
parent  ecb96ae4395eab4d4afdb0f81f6050f17e01efdc
...
107
108
109
110
 
 
 
 
 
 
 
 
111
112
113
 
114
115
 
 
 
 
 
 
 
116
117
 
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
...
273
274
275
276
 
 
277
 
 
278
279
280
...
308
309
310
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
312
313
...
338
339
340
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
342
343
...
107
108
109
 
110
111
112
113
114
115
116
117
118
119
 
120
121
 
122
123
124
125
126
127
128
129
 
130
131
132
133
134
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
137
138
...
270
271
272
 
273
274
275
276
277
278
279
280
...
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
0
@@ -107,35 +107,32 @@ module ActiveCouch
0
       rev.nil?
0
     end
0
 
0
- # Deletes a document from a CouchDB database.
0
+ # Deletes a document from a CouchDB database. This is an instance-level delete method.
0
+ # Example:
0
+ # class Person < ActiveCouch::Base
0
+ # has :name
0
+ # end
0
+ #
0
+ # person = Person.create(:name => 'McLovin')
0
+ # person.delete # true
0
     def delete
0
       if new?
0
- raise ActiveCouchError, "You must specify a revision for the document to be deleted"
0
+ raise ArgumentError, "You must specify a revision for the document to be deleted"
0
       elsif id.nil?
0
- raise ActiveCouchError, "You must specify an ID for the document to be deleted"
0
+ raise ArgumentError, "You must specify an ID for the document to be deleted"
0
+ end
0
+ response = connection.delete("/#{self.class.database_name}/#{id}?rev=#{rev}")
0
+ # Set the id and rev to nil, since the object has been successfully deleted from CouchDB
0
+ if response.code == '202'
0
+ self.id = nil; self.rev = nil
0
+ true
0
       else
0
- connection.delete("/#{self.class.database_name}/#{id}?rev=#{rev}")
0
+ false
0
       end
0
     end
0
 
0
     class << self # Class methods
0
 
0
- def inherited(subklass)
0
- # TODO: Need a cleaner way to do this
0
- subklass.instance_variable_set "@attributes", { :_id => Attribute.new(:_id, :with_default_value => nil),
0
- :_rev => Attribute.new(:_rev, :with_default_value => nil) }
0
- subklass.instance_variable_set "@associations", {}
0
- subklass.instance_variable_set "@connections", nil
0
-
0
- SPECIAL_MEMBERS.each do |k|
0
- subklass.instance_eval "def #{k}; @#{k}; end"
0
- end
0
- end
0
-
0
- def base_class
0
- class_of_active_couch_descendant(self)
0
- end
0
-
0
       # Returns the CouchDB database name that's backing this model. The database name is guessed from the name of the
0
       # class somewhat similar to ActiveRecord conventions.
0
       #
0
@@ -273,8 +270,11 @@ module ActiveCouch
0
       # class Person < ActiveCouch::Base
0
       # has :name
0
       # end
0
- #
0
+ #
0
+ # # This returns a single instance of an ActiveCouch::Base subclass
0
       # people = Person.find(:first, :params => {:name => "McLovin"})
0
+ #
0
+ # # This returns an array of ActiveCouch::Base subclass instances
0
       # person = Person.find(:all, :params => {:name => "McLovin"})
0
       def find(*arguments)
0
         scope = arguments.slice!(0)
0
@@ -308,6 +308,24 @@ module ActiveCouch
0
         end
0
       end
0
 
0
+ # Deletes a document from the CouchDB database, based on the id and rev parameters passed to it.
0
+ # Returns true if the document has been deleted
0
+ #
0
+ # Example:
0
+ # class Person < ActiveCouch::Base
0
+ # has :name
0
+ # end
0
+ #
0
+ # Person.delete(:id => 'abc-def', :rev => '1235')
0
+ def delete(options = {})
0
+ if options.nil? || !options.has_key?(:id) || !options.has_key?(:rev)
0
+ raise ArgumentError, "You must specify both an id and a rev for the document to be deleted"
0
+ end
0
+ response = connection.delete("/#{self.database_name}/#{options[:id]}?rev=#{options[:rev]}")
0
+ # Returns true if the
0
+ response.code == '202'
0
+ end
0
+
0
       # Defines an "attribute" method. A new (class) method will be created with the
0
       # given name. If a value is specified, the new method will
0
       # return that value (as a string). Otherwise, the given block
0
@@ -338,6 +356,22 @@ module ActiveCouch
0
         end
0
       end
0
 
0
+ def inherited(subklass)
0
+ # TODO: Need a cleaner way to do this
0
+ subklass.instance_variable_set "@attributes", { :_id => Attribute.new(:_id, :with_default_value => nil),
0
+ :_rev => Attribute.new(:_rev, :with_default_value => nil) }
0
+ subklass.instance_variable_set "@associations", {}
0
+ subklass.instance_variable_set "@connections", nil
0
+
0
+ SPECIAL_MEMBERS.each do |k|
0
+ subklass.instance_eval "def #{k}; @#{k}; end"
0
+ end
0
+ end
0
+
0
+ def base_class
0
+ class_of_active_couch_descendant(self)
0
+ end
0
+
0
       private
0
       
0
         # Returns the class descending directly from ActiveCouch in the inheritance hierarchy.
...
1
2
3
 
4
5
6
...
14
15
16
17
 
18
19
20
21
22
 
 
 
 
23
24
25
...
27
28
29
30
 
31
32
33
34
35
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
38
39
...
1
2
 
3
4
5
6
...
14
15
16
 
17
18
19
20
 
 
21
22
23
24
25
26
27
...
29
30
31
 
32
33
34
35
36
37
 
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
0
@@ -1,6 +1,6 @@
0
 require File.dirname(__FILE__) + '/../spec_helper.rb'
0
 
0
-describe "ActiveCouch::Base #delete method" do
0
+describe "ActiveCouch::Base #delete instance-level method" do
0
   before(:each) do
0
     class Person < ActiveCouch::Base
0
       site 'http://localhost:5984/'
0
@@ -14,12 +14,14 @@ describe "ActiveCouch::Base #delete method" do
0
     ActiveCouch::Migrator.delete_database('http://localhost:5984/', 'people')
0
   end
0
   
0
- it "should have a class method called delete" do
0
+ it "should have an instance method called delete" do
0
     @person.methods.include?('delete').should == true
0
   end
0
   
0
- it "should be able to delete itself from the CouchDB database" do
0
- @person.delete
0
+ it "should be able to delete itself from the CouchDB database and return true" do
0
+ @person.delete.should == true
0
+ @person.id.should == nil
0
+ @person.rev.should == nil
0
     # Check whether document has actually been deleted
0
     response = Net::HTTP.get_response URI.parse("http://localhost:5984/people/_all_docs/")
0
     response.body.index('"total_rows":0').should_not == nil
0
@@ -27,12 +29,50 @@ describe "ActiveCouch::Base #delete method" do
0
   
0
   it "should raise an error if the revision for the object is not set and is attempted to be deleted" do
0
     p = Person.new(:name => 'McLovin')
0
- lambda { p.delete }.should raise_error(ActiveCouch::ActiveCouchError, "You must specify a revision for the document to be deleted")
0
+ lambda { p.delete }.should raise_error(ArgumentError, "You must specify a revision for the document to be deleted")
0
   end
0
   
0
   it "should raise an error if the id for the object is not set, but the revision is set and is attempted to be deleted" do
0
     p = Person.new(:name => 'McLovin')
0
     p.rev = '123'
0
- lambda { p.delete }.should raise_error(ActiveCouch::ActiveCouchError, "You must specify an ID for the document to be deleted")
0
+ lambda { p.delete }.should raise_error(ArgumentError, "You must specify an ID for the document to be deleted")
0
+ end
0
+end
0
+
0
+describe "ActiveCouch::Base #delete class-level method" do
0
+ before(:each) do
0
+ class Person < ActiveCouch::Base
0
+ site 'http://localhost:5984/'
0
+ has :name
0
+ end
0
+ ActiveCouch::Migrator.create_database('http://localhost:5984/', 'people')
0
+ @person = Person.create(:name => 'McLovin')
0
+ end
0
+
0
+ after(:each) do
0
+ ActiveCouch::Migrator.delete_database('http://localhost:5984/', 'people')
0
+ end
0
+
0
+ it "should have a class method called delete" do
0
+ Person.methods.include?('delete').should == true
0
+ end
0
+
0
+ it "should be able to delete a CouchDB document and return true after successful deletion" do
0
+ Person.delete(:id => @person.id, :rev => @person.rev).should == true
0
+ # Check whether document has actually been deleted
0
+ response = Net::HTTP.get_response URI.parse("http://localhost:5984/people/_all_docs/")
0
+ response.body.index('"total_rows":0').should_not == nil
0
+ end
0
+
0
+ it "should raise an error if the id is not specified in the options hash" do
0
+ lambda { Person.delete(:rev => 'abc') }.should raise_error(ArgumentError, "You must specify both an id and a rev for the document to be deleted")
0
+ end
0
+
0
+ it "should raise an error if the rev is not specified in the options hash" do
0
+ lambda { Person.delete(:id => 'abc') }.should raise_error(ArgumentError, "You must specify both an id and a rev for the document to be deleted")
0
+ end
0
+
0
+ it "should raise an error if a nil object is passed as a param to delete" do
0
+ lambda { Person.delete(nil) }.should raise_error(ArgumentError, "You must specify both an id and a rev for the document to be deleted")
0
   end
0
 end
0
\ No newline at end of file

Comments

    No one has commented yet.