diff --git a/lib/couchrest/core/database.rb b/lib/couchrest/core/database.rb index 7c26c50..6f19128 100644 --- a/lib/couchrest/core/database.rb +++ b/lib/couchrest/core/database.rb @@ -144,6 +144,8 @@ module CouchRest # DELETE the document from CouchDB that has the given _id and # _rev. def delete doc + raise ArgumentError, "_id and _rev required for deleting" unless doc['_id'] && doc['_rev'] + slug = CGI.escape(doc['_id']) CouchRest.delete "#{@root}/#{slug}?rev=#{doc['_rev']}" end diff --git a/lib/couchrest/core/design.rb b/lib/couchrest/core/design.rb index 4570100..e284a6c 100644 --- a/lib/couchrest/core/design.rb +++ b/lib/couchrest/core/design.rb @@ -1,7 +1,6 @@ module CouchRest class Design < Document def view_by *keys - # @stale = true opts = keys.pop if keys.last.is_a?(Hash) opts ||= {} self['views'] ||= {} @@ -29,6 +28,7 @@ module CouchRest self['views'][method_name] = { 'map' => map_function } + self['views'][method_name]['couchrest-defaults'] = opts method_name end end @@ -43,24 +43,23 @@ module CouchRest # end # Dispatches to any named view. - def view name, query={}, &block - # if @stale - # self.save - # end - view_name = "#{slug}/#{name}" - fetch_view(view_name, query, &block) + def view view_name, query={}, &block + view_name = view_name.to_s + view_slug = "#{name}/#{view_name}" + defaults = (self['views'][view_name] && self['views'][view_name]["couchrest-defaults"]) || {} + fetch_view(view_slug, defaults.merge(query), &block) end - def slug - id.sub('_design/','') + def name + id.sub('_design/','') if id end - def slug= newslug - self['_id'] = "_design/#{newslug}" + def name= newname + self['_id'] = "_design/#{newname}" end def save - raise ArgumentError, "_design" unless slug && slug.length > 0 + raise ArgumentError, "_design docs require a name" unless name && name.length > 0 super end diff --git a/lib/couchrest/core/document.rb b/lib/couchrest/core/document.rb index 42c02e2..1df61ea 100644 --- a/lib/couchrest/core/document.rb +++ b/lib/couchrest/core/document.rb @@ -37,17 +37,15 @@ module CouchRest # CouchDB's response. def save raise ArgumentError, "doc.database required for saving" unless database - if new_record? - create - else - update - end + result = database.save self + result['ok'] end # 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 + raise ArgumentError, "doc.database required to destroy" unless database result = database.delete self if result['ok'] self['_rev'] = nil @@ -56,27 +54,6 @@ module CouchRest result['ok'] end - protected - - # Saves a document for the first time, after running the before(:create) - # callbacks, and applying the unique_id. - def create - set_unique_id if respond_to?(:set_unique_id) # hack - save_doc - end - - # Saves the document and runs the :update callbacks. - def update - save_doc - end - - private - - def save_doc - result = database.save self - result['ok'] - end - end diff --git a/spec/couchrest/core/database_spec.rb b/spec/couchrest/core/database_spec.rb index 6e48909..5fb2e70 100644 --- a/spec/couchrest/core/database_spec.rb +++ b/spec/couchrest/core/database_spec.rb @@ -418,6 +418,9 @@ describe CouchRest::Database do @db.delete doc lambda{@db.get @docid}.should raise_error end + it "should fail without an _id" do + lambda{@db.delete({"not"=>"a real doc"})}.should raise_error(ArgumentError) + end end it "should list documents" do diff --git a/spec/couchrest/core/design_spec.rb b/spec/couchrest/core/design_spec.rb index 926d61a..bbe2f2e 100644 --- a/spec/couchrest/core/design_spec.rb +++ b/spec/couchrest/core/design_spec.rb @@ -2,22 +2,13 @@ require File.dirname(__FILE__) + '/../../spec_helper' describe CouchRest::Design do - # before(:each) do - # @db = reset_test_db! - # end - describe "defining a view" do - # before(:each) do - # @design_docs = @db.documents :startkey => "_design/", - # :endkey => "_design/\u9999" - # end it "should add a view to the design doc" do @des = CouchRest::Design.new method = @des.view_by :name method.should == "by_name" @des["views"]["by_name"].should_not be_nil end - end describe "with an unsaved view" do @@ -25,9 +16,9 @@ describe CouchRest::Design do @des = CouchRest::Design.new method = @des.view_by :name end - it "should accept a slug" do - @des.slug = "mytest" - @des.slug.should == "mytest" + it "should accept a name" do + @des.name = "mytest" + @des.name.should == "mytest" end it "should not save on view definition" do @des.rev.should be_nil @@ -37,6 +28,21 @@ describe CouchRest::Design do end end + describe "saving" do + before(:each) do + @des = CouchRest::Design.new + method = @des.view_by :name + @des.database = reset_test_db! + end + it "should fail without a name" do + lambda{@des.save}.should raise_error(ArgumentError) + end + it "should work with a name" do + @des.name = "myview" + @des.save + end + end + describe "when it's saved" do before(:each) do @db = reset_test_db! @@ -45,11 +51,8 @@ describe CouchRest::Design do @des.database = @db method = @des.view_by :name end - it "should become angry when saved without a slug" do - lambda{@des.save}.should raise_error - end it "should by queryable when it's saved" do - @des.slug = "mydesign" + @des.name = "mydesign" @des.save res = @des.view :by_name res["rows"][0]["key"].should == "x" @@ -73,9 +76,9 @@ describe CouchRest::Design do it "should be a Design" do @des.should be_an_instance_of CouchRest::Design end - it "should have a slug" do - @des.slug.should == "test" - @des.slug = "supertest" + it "should have a modifiable name" do + @des.name.should == "test" + @des.name = "supertest" @des.id.should == "_design/supertest" end it "should by queryable" do @@ -83,4 +86,45 @@ describe CouchRest::Design do res["rows"][0]["key"].should == "a" end end + + describe "a view with default options" do + before(:all) do + @db = reset_test_db! + @des = CouchRest::Design.new + @des.name = "test" + method = @des.view_by :name, :descending => true + @des.database = @db + @des.save + @db.bulk_save([{"name" => "a"},{"name" => "z"}]) + end + it "should save them" do + @d2 = @db.get(@des.id) + @d2["views"]["by_name"]["couchrest-defaults"].should == {"descending"=>true} + end + it "should use them" do + res = @des.view :by_name + res["rows"].first["key"].should == "z" + end + it "should override them" do + res = @des.view :by_name, :descending => false + res["rows"].first["key"].should == "a" + end + end + + describe "a view with multiple keys" do + before(:all) do + @db = reset_test_db! + @des = CouchRest::Design.new + @des.name = "test" + method = @des.view_by :name, :age + @des.database = @db + @des.save + @db.bulk_save([{"name" => "a", "age" => 2},{"name" => "a", "age" => 4},{"name" => "z", "age" => 9}]) + end + it "should work" do + res = @des.view :by_name_and_age + res["rows"].first["key"].should == ["a",2] + end + end + end \ No newline at end of file diff --git a/spec/couchrest/core/document_spec.rb b/spec/couchrest/core/document_spec.rb index 062c34d..31c7151 100644 --- a/spec/couchrest/core/document_spec.rb +++ b/spec/couchrest/core/document_spec.rb @@ -44,7 +44,7 @@ describe CouchRest::Document, "saving using a database" do @db = reset_test_db! @resp = @db.save(@doc) end - it "should get the database" do + it "should apply the database" do @doc.database.should == @db end it "should get id and rev" do @@ -67,9 +67,30 @@ describe "getting from a database" do it "should have a database" do @doc.database.should == @db end - it "should be saveable" do + it "should be saveable and resavable" do @doc["more"] = "keys" @doc.save @db.get(@resp['id'])["more"].should == "keys" + @doc["more"] = "these keys" + @doc.save + @db.get(@resp['id'])["more"].should == "these keys" + end +end + +describe "destroying a document from a db" do + before(:all) do + @db = reset_test_db! + @resp = @db.save({ + "key" => "value" + }) + @doc = @db.get @resp['id'] + end + it "should make it disappear" do + @doc.destroy + lambda{@db.get @resp['id']}.should raise_error + end + it "should error when there's no db" do + @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values") + lambda{@doc.destroy}.should raise_error(ArgumentError) end end \ No newline at end of file diff --git a/spec/couchrest/core/model_spec.rb b/spec/couchrest/core/model_spec.rb index 112eada..8b5c1e0 100644 --- a/spec/couchrest/core/model_spec.rb +++ b/spec/couchrest/core/model_spec.rb @@ -1,5 +1,5 @@ require File.dirname(__FILE__) + '/../../spec_helper' - +__END__ class Basic < CouchRest::Model end