From 9141669df1cea508571a125e8a0ca12005dd11ed Mon Sep 17 00:00:00 2001 From: Matt Aimonetti Date: Wed, 29 Jul 2009 18:32:34 -0700 Subject: [PATCH 1/9] extracted the rest API to its own module --- lib/couchrest.rb | 51 +++------------------------- lib/couchrest/core/rest_api.rb | 49 ++++++++++++++++++++++++++ lib/couchrest/more/casted_model.rb | 2 +- spec/couchrest/core/database_spec.rb | 2 +- 4 files changed, 56 insertions(+), 48 deletions(-) create mode 100644 lib/couchrest/core/rest_api.rb diff --git a/lib/couchrest.rb b/lib/couchrest.rb index 572902f..efb5847 100644 --- a/lib/couchrest.rb +++ b/lib/couchrest.rb @@ -45,8 +45,13 @@ module CouchRest autoload :ExtendedDocument, 'couchrest/more/extended_document' autoload :CastedModel, 'couchrest/more/casted_model' + require File.join(File.dirname(__FILE__), 'couchrest', 'core', 'rest_api') require File.join(File.dirname(__FILE__), 'couchrest', 'core', 'http_abstraction') require File.join(File.dirname(__FILE__), 'couchrest', 'mixins') + + # we extend CouchRest with the RestAPI module which gives us acess to + # the get, post, put, delete and copy + CouchRest.extend(::RestAPI) # The CouchRest module methods handle the basic JSON serialization # and deserialization, as well as query parameters. The module also includes @@ -139,52 +144,6 @@ module CouchRest cr.database(parsed[:database]) end - def put(uri, doc = nil) - payload = doc.to_json if doc - begin - JSON.parse(HttpAbstraction.put(uri, payload)) - rescue Exception => e - if $DEBUG - raise "Error while sending a PUT request #{uri}\npayload: #{payload.inspect}\n#{e}" - else - raise e - end - end - end - - def get(uri) - begin - JSON.parse(HttpAbstraction.get(uri), :max_nesting => false) - rescue => e - if $DEBUG - raise "Error while sending a GET request #{uri}\n: #{e}" - else - raise e - end - end - end - - def post uri, doc = nil - payload = doc.to_json if doc - begin - JSON.parse(HttpAbstraction.post(uri, payload)) - rescue Exception => e - if $DEBUG - raise "Error while sending a POST request #{uri}\npayload: #{payload.inspect}\n#{e}" - else - raise e - end - end - end - - def delete uri - JSON.parse(HttpAbstraction.delete(uri)) - end - - def copy uri, destination - JSON.parse(HttpAbstraction.copy(uri, {'Destination' => destination})) - end - def paramify_url url, params = {} if params && !params.empty? query = params.collect do |k,v| diff --git a/lib/couchrest/core/rest_api.rb b/lib/couchrest/core/rest_api.rb new file mode 100644 index 0000000..62075b0 --- /dev/null +++ b/lib/couchrest/core/rest_api.rb @@ -0,0 +1,49 @@ +module RestAPI + + def put(uri, doc = nil) + payload = doc.to_json if doc + begin + JSON.parse(HttpAbstraction.put(uri, payload)) + rescue Exception => e + if $DEBUG + raise "Error while sending a PUT request #{uri}\npayload: #{payload.inspect}\n#{e}" + else + raise e + end + end + end + + def get(uri) + begin + JSON.parse(HttpAbstraction.get(uri), :max_nesting => false) + rescue => e + if $DEBUG + raise "Error while sending a GET request #{uri}\n: #{e}" + else + raise e + end + end + end + + def post(uri, doc = nil) + payload = doc.to_json if doc + begin + JSON.parse(HttpAbstraction.post(uri, payload)) + rescue Exception => e + if $DEBUG + raise "Error while sending a POST request #{uri}\npayload: #{payload.inspect}\n#{e}" + else + raise e + end + end + end + + def delete(uri) + JSON.parse(HttpAbstraction.delete(uri)) + end + + def copy(uri, destination) + JSON.parse(HttpAbstraction.copy(uri, {'Destination' => destination})) + end + +end \ No newline at end of file diff --git a/lib/couchrest/more/casted_model.rb b/lib/couchrest/more/casted_model.rb index 6f442c8..5e4da2e 100644 --- a/lib/couchrest/more/casted_model.rb +++ b/lib/couchrest/more/casted_model.rb @@ -4,7 +4,7 @@ module CouchRest module CastedModel def self.included(base) - base.send(:include, CouchRest::Mixins::Properties) + base.send(:include, ::CouchRest::Mixins::Properties) base.send(:attr_accessor, :casted_by) end diff --git a/spec/couchrest/core/database_spec.rb b/spec/couchrest/core/database_spec.rb index 3375779..8d4bdd9 100644 --- a/spec/couchrest/core/database_spec.rb +++ b/spec/couchrest/core/database_spec.rb @@ -369,7 +369,7 @@ describe CouchRest::Database do it "should delete the attachment" do lambda { @db.fetch_attachment(@doc,'test.html') }.should_not raise_error @db.delete_attachment(@doc, "test.html") - lambda { @db.fetch_attachment(@doc,'test.html') }.should raise_error(RestClient::ResourceNotFound) + @db.fetch_attachment(@doc,'test.html').should be_nil end end From beb801d1bde54d780be07a9e4d925d8c23b66fa5 Mon Sep 17 00:00:00 2001 From: Matt Aimonetti Date: Wed, 29 Jul 2009 19:01:38 -0700 Subject: [PATCH 2/9] fixed the database attachment specs --- spec/couchrest/core/database_spec.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/couchrest/core/database_spec.rb b/spec/couchrest/core/database_spec.rb index 8d4bdd9..632ba52 100644 --- a/spec/couchrest/core/database_spec.rb +++ b/spec/couchrest/core/database_spec.rb @@ -368,8 +368,9 @@ describe CouchRest::Database do end it "should delete the attachment" do lambda { @db.fetch_attachment(@doc,'test.html') }.should_not raise_error - @db.delete_attachment(@doc, "test.html") - @db.fetch_attachment(@doc,'test.html').should be_nil + @db.delete_attachment(@doc, "test.html") + @doc = @db.get('mydocwithattachment') # avoid getting a 409 + lambda{ @db.fetch_attachment(@doc,'test.html')}.should raise_error end end From 41055fd5adeb8bcf4e43ed56428d86d1c5cad260 Mon Sep 17 00:00:00 2001 From: Matt Aimonetti Date: Wed, 29 Jul 2009 20:07:02 -0700 Subject: [PATCH 3/9] added an option to force the deletion of a attachment --- lib/couchrest/core/database.rb | 15 +++++++++++++-- spec/couchrest/core/database_spec.rb | 9 +++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/couchrest/core/database.rb b/lib/couchrest/core/database.rb index 08eb4cb..ce7e1a6 100644 --- a/lib/couchrest/core/database.rb +++ b/lib/couchrest/core/database.rb @@ -113,10 +113,21 @@ module CouchRest end # DELETE an attachment directly from CouchDB - def delete_attachment doc, name + def delete_attachment(doc, name, force=false) uri = url_for_attachment(doc, name) # this needs a rev - JSON.parse(HttpAbstraction.delete(uri)) + begin + JSON.parse(HttpAbstraction.delete(uri)) + rescue Exception => error + if force + # get over a 409 + doc = get(doc['_id']) + uri = url_for_attachment(doc, name) + JSON.parse(HttpAbstraction.delete(uri)) + else + error + end + end end # Save a document to CouchDB. This will use the _id field from diff --git a/spec/couchrest/core/database_spec.rb b/spec/couchrest/core/database_spec.rb index 632ba52..d1c58ad 100644 --- a/spec/couchrest/core/database_spec.rb +++ b/spec/couchrest/core/database_spec.rb @@ -372,6 +372,15 @@ describe CouchRest::Database do @doc = @db.get('mydocwithattachment') # avoid getting a 409 lambda{ @db.fetch_attachment(@doc,'test.html')}.should raise_error end + + it "should force a delete even if we get a 409" do + @doc['new_attribute'] = 'something new' + @db.put_attachment(@doc, 'test', File.open(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'attachments', 'test.html')).read) + # at this point the revision number changed, if we try to save doc one more time + # we would get a 409. + lambda{ @db.save_doc(@doc) }.should raise_error + lambda{ @db.delete_attachment(@doc, "test", true) }.should_not raise_error + end end describe "POST document with attachment (with funky name)" do From 5270fde0fafb21e9e65dfc161fc09c3740d2f62d Mon Sep 17 00:00:00 2001 From: Matt Aimonetti Date: Wed, 29 Jul 2009 20:12:35 -0700 Subject: [PATCH 4/9] added an option to force the deletion of a attachment --- lib/couchrest/core/database.rb | 15 +++++++++++++-- lib/couchrest/mixins/attachments.rb | 4 ++-- spec/couchrest/core/database_spec.rb | 9 +++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/couchrest/core/database.rb b/lib/couchrest/core/database.rb index 08eb4cb..ce7e1a6 100644 --- a/lib/couchrest/core/database.rb +++ b/lib/couchrest/core/database.rb @@ -113,10 +113,21 @@ module CouchRest end # DELETE an attachment directly from CouchDB - def delete_attachment doc, name + def delete_attachment(doc, name, force=false) uri = url_for_attachment(doc, name) # this needs a rev - JSON.parse(HttpAbstraction.delete(uri)) + begin + JSON.parse(HttpAbstraction.delete(uri)) + rescue Exception => error + if force + # get over a 409 + doc = get(doc['_id']) + uri = url_for_attachment(doc, name) + JSON.parse(HttpAbstraction.delete(uri)) + else + error + end + end end # Save a document to CouchDB. This will use the _id field from diff --git a/lib/couchrest/mixins/attachments.rb b/lib/couchrest/mixins/attachments.rb index f009b3e..b4c1bfe 100644 --- a/lib/couchrest/mixins/attachments.rb +++ b/lib/couchrest/mixins/attachments.rb @@ -19,9 +19,9 @@ module CouchRest end # deletes an attachment directly from couchdb - def delete_attachment(name) + def delete_attachment(name, force=false) raise ArgumentError, "doc.database required to delete_attachment" unless database - result = database.delete_attachment(self, name) + result = database.delete_attachment(self, name, force) self['_rev'] = result['rev'] result['ok'] end diff --git a/spec/couchrest/core/database_spec.rb b/spec/couchrest/core/database_spec.rb index 632ba52..d1c58ad 100644 --- a/spec/couchrest/core/database_spec.rb +++ b/spec/couchrest/core/database_spec.rb @@ -372,6 +372,15 @@ describe CouchRest::Database do @doc = @db.get('mydocwithattachment') # avoid getting a 409 lambda{ @db.fetch_attachment(@doc,'test.html')}.should raise_error end + + it "should force a delete even if we get a 409" do + @doc['new_attribute'] = 'something new' + @db.put_attachment(@doc, 'test', File.open(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'attachments', 'test.html')).read) + # at this point the revision number changed, if we try to save doc one more time + # we would get a 409. + lambda{ @db.save_doc(@doc) }.should raise_error + lambda{ @db.delete_attachment(@doc, "test", true) }.should_not raise_error + end end describe "POST document with attachment (with funky name)" do From 0fc1a88ede989a6d0a3a13e6e73d220aeffb6f0d Mon Sep 17 00:00:00 2001 From: Matt Aimonetti Date: Wed, 29 Jul 2009 20:16:59 -0700 Subject: [PATCH 5/9] updated the history file --- history.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index 7980257..b505d2a 100644 --- a/history.txt +++ b/history.txt @@ -12,7 +12,9 @@ you will need to make the following modifications. * Added a new Rack logger middleware letting you log/save requests/queries (Matt Aimonetti) * Minor enhancements - + + * Added an option to force the deletion of a attachments (bypass 409s) (Matt Aimonetti) + * Created a new abstraction layer for the REST API (Matt Aimonetti) * Bug fix: made ExtendedDocument#all compatible with Couch 0.10 (tc) == 0.32 From d1d8da513c9a5e8782455ab7516291a45e3e4a7e Mon Sep 17 00:00:00 2001 From: John Wood Date: Sat, 25 Jul 2009 11:12:03 +0800 Subject: [PATCH 6/9] Added code to generate a property? method for properties casted as :boolean Signed-off-by: Matt Aimonetti --- lib/couchrest/mixins/properties.rb | 15 +++++++++++++++ spec/couchrest/more/property_spec.rb | 28 +++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/lib/couchrest/mixins/properties.rb b/lib/couchrest/mixins/properties.rb index 2982d30..69c9411 100644 --- a/lib/couchrest/mixins/properties.rb +++ b/lib/couchrest/mixins/properties.rb @@ -77,6 +77,9 @@ module CouchRest # Float instances don't get initialized with #new elsif ((property.init_method == 'new') && target == 'Float') cast_float(self[key]) + # 'boolean' type is simply used to generate a property? accessor method + elsif ((property.init_method == 'new') && target == 'boolean') + self[key] else # Let people use :send as a Time parse arg klass = ::CouchRest.constantize(target) @@ -128,6 +131,18 @@ module CouchRest end EOS + if property.type == 'boolean' + class_eval <<-EOS, __FILE__, __LINE__ + def #{property.name}? + if self['#{property.name}'].nil? || self['#{property.name}'] == false || self['#{property.name}'].to_s.downcase == 'false' + false + else + true + end + end + EOS + end + if property.alias class_eval <<-EOS, __FILE__, __LINE__ alias #{property.alias.to_sym} #{property.name.to_sym} diff --git a/spec/couchrest/more/property_spec.rb b/spec/couchrest/more/property_spec.rb index 6782789..efeba94 100644 --- a/spec/couchrest/more/property_spec.rb +++ b/spec/couchrest/more/property_spec.rb @@ -161,9 +161,35 @@ describe "ExtendedDocument properties" do it "should work fine when a float is being passed" do RootBeerFloat.new(:price => 9.99).price.should == 9.99 end - end + describe "casting to a boolean value" do + class RootBeerFloat < CouchRest::ExtendedDocument + use_database DB + property :tasty, :cast_as => :boolean + end + + it "should add an accessor with a '?' for boolean attributes that returns true or false" do + RootBeerFloat.new(:tasty => true).tasty?.should == true + RootBeerFloat.new(:tasty => 'you bet').tasty?.should == true + RootBeerFloat.new(:tasty => 123).tasty?.should == true + + RootBeerFloat.new(:tasty => false).tasty?.should == false + RootBeerFloat.new(:tasty => 'false').tasty?.should == false + RootBeerFloat.new(:tasty => 'FaLsE').tasty?.should == false + RootBeerFloat.new(:tasty => nil).tasty?.should == false + end + + it "should return the real value when the default accessor is used" do + RootBeerFloat.new(:tasty => true).tasty.should == true + RootBeerFloat.new(:tasty => 'you bet').tasty.should == 'you bet' + RootBeerFloat.new(:tasty => 123).tasty.should == 123 + RootBeerFloat.new(:tasty => 'false').tasty.should == 'false' + RootBeerFloat.new(:tasty => false).tasty.should == false + RootBeerFloat.new(:tasty => nil).tasty.should == nil + end + end + end end From a17df45fc3909c48099393eb44b419881107280c Mon Sep 17 00:00:00 2001 From: Matt Aimonetti Date: Sat, 1 Aug 2009 14:21:18 -0700 Subject: [PATCH 7/9] made all the specs run on 1.9.2, yay :) --- lib/couchrest/more/casted_model.rb | 3 ++- spec/couchrest/core/couchrest_spec.rb | 2 +- spec/couchrest/core/database_spec.rb | 8 ++++++-- spec/couchrest/core/design_spec.rb | 2 +- spec/couchrest/core/document_spec.rb | 2 +- spec/couchrest/core/server_spec.rb | 2 +- spec/couchrest/helpers/pager_spec.rb | 2 +- spec/couchrest/helpers/streamer_spec.rb | 2 +- spec/couchrest/more/casted_extended_doc_spec.rb | 2 +- spec/couchrest/more/casted_model_spec.rb | 2 +- spec/couchrest/more/extended_doc_attachment_spec.rb | 2 +- spec/couchrest/more/extended_doc_spec.rb | 2 +- spec/couchrest/more/extended_doc_subclass_spec.rb | 2 +- spec/couchrest/more/extended_doc_view_spec.rb | 5 +++-- spec/couchrest/more/property_spec.rb | 2 +- 15 files changed, 23 insertions(+), 17 deletions(-) diff --git a/lib/couchrest/more/casted_model.rb b/lib/couchrest/more/casted_model.rb index 5e4da2e..5b8d383 100644 --- a/lib/couchrest/more/casted_model.rb +++ b/lib/couchrest/more/casted_model.rb @@ -1,4 +1,5 @@ -require File.join(File.dirname(__FILE__), '..', 'mixins', 'properties') +require File.expand_path('../../mixins/properties', __FILE__) + module CouchRest module CastedModel diff --git a/spec/couchrest/core/couchrest_spec.rb b/spec/couchrest/core/couchrest_spec.rb index 35e48e6..ef6637c 100644 --- a/spec/couchrest/core/couchrest_spec.rb +++ b/spec/couchrest/core/couchrest_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path("../../../spec_helper", __FILE__) describe CouchRest do diff --git a/spec/couchrest/core/database_spec.rb b/spec/couchrest/core/database_spec.rb index d1c58ad..98b7947 100644 --- a/spec/couchrest/core/database_spec.rb +++ b/spec/couchrest/core/database_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path("../../../spec_helper", __FILE__) describe CouchRest::Database do before(:each) do @@ -263,7 +263,11 @@ describe CouchRest::Database do r['ok'].should == true doc = @db.get("attach-this") attachment = @db.fetch_attachment(doc,"couchdb.png") - attachment.should == image + if attachment.respond_to?(:net_http_res) + attachment.net_http_res.body.should == image + else + attachment.should == image + end end end diff --git a/spec/couchrest/core/design_spec.rb b/spec/couchrest/core/design_spec.rb index 8b367c7..b5b2ce1 100644 --- a/spec/couchrest/core/design_spec.rb +++ b/spec/couchrest/core/design_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path("../../../spec_helper", __FILE__) describe CouchRest::Design do diff --git a/spec/couchrest/core/document_spec.rb b/spec/couchrest/core/document_spec.rb index e83c05f..287ee79 100644 --- a/spec/couchrest/core/document_spec.rb +++ b/spec/couchrest/core/document_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path("../../../spec_helper", __FILE__) class Video < CouchRest::Document; end diff --git a/spec/couchrest/core/server_spec.rb b/spec/couchrest/core/server_spec.rb index 5e0f1f7..f55dd29 100644 --- a/spec/couchrest/core/server_spec.rb +++ b/spec/couchrest/core/server_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path("../../../spec_helper", __FILE__) describe CouchRest::Server do diff --git a/spec/couchrest/helpers/pager_spec.rb b/spec/couchrest/helpers/pager_spec.rb index ed16df3..3c111f6 100644 --- a/spec/couchrest/helpers/pager_spec.rb +++ b/spec/couchrest/helpers/pager_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path("../../../spec_helper", __FILE__) describe CouchRest::Pager do before(:all) do diff --git a/spec/couchrest/helpers/streamer_spec.rb b/spec/couchrest/helpers/streamer_spec.rb index 5479390..cf828ca 100644 --- a/spec/couchrest/helpers/streamer_spec.rb +++ b/spec/couchrest/helpers/streamer_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path("../../../spec_helper", __FILE__) describe CouchRest::Streamer do before(:all) do diff --git a/spec/couchrest/more/casted_extended_doc_spec.rb b/spec/couchrest/more/casted_extended_doc_spec.rb index 51afd77..6e3e13c 100644 --- a/spec/couchrest/more/casted_extended_doc_spec.rb +++ b/spec/couchrest/more/casted_extended_doc_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') +require File.expand_path('../../../spec_helper', __FILE__) require File.join(FIXTURE_PATH, 'more', 'card') class Car < CouchRest::ExtendedDocument diff --git a/spec/couchrest/more/casted_model_spec.rb b/spec/couchrest/more/casted_model_spec.rb index 75b0c57..c1de242 100644 --- a/spec/couchrest/more/casted_model_spec.rb +++ b/spec/couchrest/more/casted_model_spec.rb @@ -1,6 +1,6 @@ # encoding: utf-8 -require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') +require File.expand_path('../../../spec_helper', __FILE__) require File.join(FIXTURE_PATH, 'more', 'card') require File.join(FIXTURE_PATH, 'more', 'cat') require File.join(FIXTURE_PATH, 'more', 'person') diff --git a/spec/couchrest/more/extended_doc_attachment_spec.rb b/spec/couchrest/more/extended_doc_attachment_spec.rb index d82d9fe..e73db96 100644 --- a/spec/couchrest/more/extended_doc_attachment_spec.rb +++ b/spec/couchrest/more/extended_doc_attachment_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path('../../../spec_helper', __FILE__) describe "ExtendedDocument attachments" do diff --git a/spec/couchrest/more/extended_doc_spec.rb b/spec/couchrest/more/extended_doc_spec.rb index f3097ff..1b05bc3 100644 --- a/spec/couchrest/more/extended_doc_spec.rb +++ b/spec/couchrest/more/extended_doc_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path("../../../spec_helper", __FILE__) require File.join(FIXTURE_PATH, 'more', 'article') require File.join(FIXTURE_PATH, 'more', 'course') diff --git a/spec/couchrest/more/extended_doc_subclass_spec.rb b/spec/couchrest/more/extended_doc_subclass_spec.rb index ef31a7a..6a9bdc9 100644 --- a/spec/couchrest/more/extended_doc_subclass_spec.rb +++ b/spec/couchrest/more/extended_doc_subclass_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path("../../../spec_helper", __FILE__) require File.join(FIXTURE_PATH, 'more', 'card') require File.join(FIXTURE_PATH, 'more', 'course') diff --git a/spec/couchrest/more/extended_doc_view_spec.rb b/spec/couchrest/more/extended_doc_view_spec.rb index be6056e..f532e95 100644 --- a/spec/couchrest/more/extended_doc_view_spec.rb +++ b/spec/couchrest/more/extended_doc_view_spec.rb @@ -1,4 +1,4 @@ -require File.dirname(__FILE__) + '/../../spec_helper' +require File.expand_path("../../../spec_helper", __FILE__) require File.join(FIXTURE_PATH, 'more', 'article') require File.join(FIXTURE_PATH, 'more', 'course') @@ -354,7 +354,8 @@ describe "ExtendedDocument views" do a = Article.new(:title => title, :date => Date.today) a.save end - end + end + require 'date' it "should return a proxy that looks like an array of 7 Article objects" do articles = Article.by_date :key => Date.today articles.class.should == Array diff --git a/spec/couchrest/more/property_spec.rb b/spec/couchrest/more/property_spec.rb index efeba94..126d86f 100644 --- a/spec/couchrest/more/property_spec.rb +++ b/spec/couchrest/more/property_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') +require File.expand_path('../../../spec_helper', __FILE__) require File.join(FIXTURE_PATH, 'more', 'person') require File.join(FIXTURE_PATH, 'more', 'card') require File.join(FIXTURE_PATH, 'more', 'invoice') From 889a923dbf25a2aba6034b063d9f3e09844b7896 Mon Sep 17 00:00:00 2001 From: Matt Aimonetti Date: Mon, 3 Aug 2009 12:19:07 -0700 Subject: [PATCH 8/9] Added #amount_pages to a paginated result array --- lib/couchrest/mixins/collection.rb | 16 ++++++++++++++-- spec/couchrest/more/extended_doc_view_spec.rb | 3 +-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/couchrest/mixins/collection.rb b/lib/couchrest/mixins/collection.rb index e388146..a5f7d99 100644 --- a/lib/couchrest/mixins/collection.rb +++ b/lib/couchrest/mixins/collection.rb @@ -1,5 +1,14 @@ module CouchRest module Mixins + module PaginatedResults + def amount_pages + @amount_pages ||= 0 + end + def amount_pages=(value) + @amount_pages = value + end + end + module Collection def self.included(base) @@ -115,7 +124,10 @@ module CouchRest results = @database.view(@view_name, pagination_options(page, per_page)) @amount_pages ||= (results['total_rows'].to_f / per_page.to_f).ceil remember_where_we_left_off(results, page) - convert_to_container_array(results) + results = convert_to_container_array(results) + results.extend(PaginatedResults) + results.amount_pages = @amount_pages + results end # See Collection.paginated_each @@ -181,7 +193,7 @@ module CouchRest @target.inspect end - def convert_to_container_array(results) + def convert_to_container_array(results) if @container_class.nil? results else diff --git a/spec/couchrest/more/extended_doc_view_spec.rb b/spec/couchrest/more/extended_doc_view_spec.rb index f532e95..d23061a 100644 --- a/spec/couchrest/more/extended_doc_view_spec.rb +++ b/spec/couchrest/more/extended_doc_view_spec.rb @@ -375,8 +375,7 @@ describe "ExtendedDocument views" do end it "should have the amount of paginated pages" do articles = Article.by_date :key => Date.today - articles.paginate(:per_page => 3) - articles.amount_pages.should == 3 + articles.paginate(:per_page => 3).amount_pages.should == 3 end it "should provide a class method to access the collection directly" do articles = Article.collection_proxy_for('Article', 'by_date', :descending => true, From 6811745a324fdac0ab282a387eb1314a182034b3 Mon Sep 17 00:00:00 2001 From: Matt Aimonetti Date: Mon, 3 Aug 2009 12:23:13 -0700 Subject: [PATCH 9/9] bumped the version number to 0.33 --- README.md | 2 +- couchrest.gemspec | 4 ++-- history.txt | 16 ++++++---------- lib/couchrest.rb | 2 +- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index d9cc490..5692d35 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Note: CouchRest only support CouchDB 0.9.0 or newer. Alternatively, you can install from Github: $ gem sources -a http://gems.github.com (you only have to do this once) - $ sudo gem install mattetti-couchrest + $ sudo gem install couchrest-couchrest ### Relax, it's RESTful diff --git a/couchrest.gemspec b/couchrest.gemspec index 9dea7e5..26fa2a0 100644 --- a/couchrest.gemspec +++ b/couchrest.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |s| s.name = %q{couchrest} - s.version = "0.32" + s.version = "0.33" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["J. Chris Anderson", "Matt Aimonetti"] @@ -10,7 +10,7 @@ Gem::Specification.new do |s| s.description = %q{CouchRest provides a simple interface on top of CouchDB's RESTful HTTP API, as well as including some utility scripts for managing views and attachments.} s.email = %q{jchris@apache.org} s.extra_rdoc_files = ["README.md", "LICENSE", "THANKS.md"] - s.files = ["LICENSE", "README.md", "Rakefile", "THANKS.md", "history.txt", "examples/model", "examples/model/example.rb", "examples/word_count", "examples/word_count/markov", "examples/word_count/views", "examples/word_count/views/books", "examples/word_count/views/books/chunked-map.js", "examples/word_count/views/books/united-map.js", "examples/word_count/views/markov", "examples/word_count/views/markov/chain-map.js", "examples/word_count/views/markov/chain-reduce.js", "examples/word_count/views/word_count", "examples/word_count/views/word_count/count-map.js", "examples/word_count/views/word_count/count-reduce.js", "examples/word_count/word_count.rb", "examples/word_count/word_count_query.rb", "examples/word_count/word_count_views.rb", "lib/couchrest", "lib/couchrest/commands", "lib/couchrest/commands/generate.rb", "lib/couchrest/commands/push.rb", "lib/couchrest/core", "lib/couchrest/core/adapters", "lib/couchrest/core/adapters/restclient.rb", "lib/couchrest/core/database.rb", "lib/couchrest/core/design.rb", "lib/couchrest/core/document.rb", "lib/couchrest/core/http_abstraction.rb", "lib/couchrest/core/response.rb", "lib/couchrest/core/server.rb", "lib/couchrest/core/view.rb", "lib/couchrest/helper", "lib/couchrest/helper/pager.rb", "lib/couchrest/helper/streamer.rb", "lib/couchrest/helper/upgrade.rb", "lib/couchrest/mixins", "lib/couchrest/mixins/attachments.rb", "lib/couchrest/mixins/callbacks.rb", "lib/couchrest/mixins/class_proxy.rb", "lib/couchrest/mixins/collection.rb", "lib/couchrest/mixins/design_doc.rb", "lib/couchrest/mixins/document_queries.rb", "lib/couchrest/mixins/extended_attachments.rb", "lib/couchrest/mixins/extended_document_mixins.rb", "lib/couchrest/mixins/properties.rb", "lib/couchrest/mixins/validation.rb", "lib/couchrest/mixins/views.rb", "lib/couchrest/mixins.rb", "lib/couchrest/monkeypatches.rb", "lib/couchrest/more", "lib/couchrest/more/casted_model.rb", "lib/couchrest/more/extended_document.rb", "lib/couchrest/more/property.rb", "lib/couchrest/support", "lib/couchrest/support/blank.rb", "lib/couchrest/support/class.rb", "lib/couchrest/support/rails.rb", "lib/couchrest/validation", "lib/couchrest/validation/auto_validate.rb", "lib/couchrest/validation/contextual_validators.rb", "lib/couchrest/validation/validation_errors.rb", "lib/couchrest/validation/validators", "lib/couchrest/validation/validators/absent_field_validator.rb", "lib/couchrest/validation/validators/confirmation_validator.rb", "lib/couchrest/validation/validators/format_validator.rb", "lib/couchrest/validation/validators/formats", "lib/couchrest/validation/validators/formats/email.rb", "lib/couchrest/validation/validators/formats/url.rb", "lib/couchrest/validation/validators/generic_validator.rb", "lib/couchrest/validation/validators/length_validator.rb", "lib/couchrest/validation/validators/method_validator.rb", "lib/couchrest/validation/validators/numeric_validator.rb", "lib/couchrest/validation/validators/required_field_validator.rb", "lib/couchrest.rb", "spec/couchrest", "spec/couchrest/core", "spec/couchrest/core/couchrest_spec.rb", "spec/couchrest/core/database_spec.rb", "spec/couchrest/core/design_spec.rb", "spec/couchrest/core/document_spec.rb", "spec/couchrest/core/server_spec.rb", "spec/couchrest/helpers", "spec/couchrest/helpers/pager_spec.rb", "spec/couchrest/helpers/streamer_spec.rb", "spec/couchrest/more", "spec/couchrest/more/casted_extended_doc_spec.rb", "spec/couchrest/more/casted_model_spec.rb", "spec/couchrest/more/extended_doc_attachment_spec.rb", "spec/couchrest/more/extended_doc_spec.rb", "spec/couchrest/more/extended_doc_subclass_spec.rb", "spec/couchrest/more/extended_doc_view_spec.rb", "spec/couchrest/more/property_spec.rb", "spec/fixtures", "spec/fixtures/attachments", "spec/fixtures/attachments/couchdb.png", "spec/fixtures/attachments/README", "spec/fixtures/attachments/test.html", "spec/fixtures/more", "spec/fixtures/more/article.rb", "spec/fixtures/more/card.rb", "spec/fixtures/more/cat.rb", "spec/fixtures/more/course.rb", "spec/fixtures/more/event.rb", "spec/fixtures/more/invoice.rb", "spec/fixtures/more/person.rb", "spec/fixtures/more/question.rb", "spec/fixtures/more/service.rb", "spec/fixtures/views", "spec/fixtures/views/lib.js", "spec/fixtures/views/test_view", "spec/fixtures/views/test_view/lib.js", "spec/fixtures/views/test_view/only-map.js", "spec/fixtures/views/test_view/test-map.js", "spec/fixtures/views/test_view/test-reduce.js", "spec/spec.opts", "spec/spec_helper.rb", "utils/remap.rb", "utils/subset.rb"] + s.files = ["LICENSE", "README.md", "Rakefile", "THANKS.md", "history.txt", "examples/model", "examples/model/example.rb", "examples/word_count", "examples/word_count/markov", "examples/word_count/views", "examples/word_count/views/books", "examples/word_count/views/books/chunked-map.js", "examples/word_count/views/books/united-map.js", "examples/word_count/views/markov", "examples/word_count/views/markov/chain-map.js", "examples/word_count/views/markov/chain-reduce.js", "examples/word_count/views/word_count", "examples/word_count/views/word_count/count-map.js", "examples/word_count/views/word_count/count-reduce.js", "examples/word_count/word_count.rb", "examples/word_count/word_count_query.rb", "examples/word_count/word_count_views.rb", "lib/couchrest", "lib/couchrest/commands", "lib/couchrest/commands/generate.rb", "lib/couchrest/commands/push.rb", "lib/couchrest/core", "lib/couchrest/core/adapters", "lib/couchrest/core/adapters/restclient.rb", "lib/couchrest/core/database.rb", "lib/couchrest/core/design.rb", "lib/couchrest/core/document.rb", "lib/couchrest/core/http_abstraction.rb", "lib/couchrest/core/response.rb", "lib/couchrest/core/rest_api.rb", "lib/couchrest/core/server.rb", "lib/couchrest/core/view.rb", "lib/couchrest/helper", "lib/couchrest/helper/pager.rb", "lib/couchrest/helper/streamer.rb", "lib/couchrest/helper/upgrade.rb", "lib/couchrest/middlewares", "lib/couchrest/middlewares/logger.rb", "lib/couchrest/mixins", "lib/couchrest/mixins/attachments.rb", "lib/couchrest/mixins/callbacks.rb", "lib/couchrest/mixins/class_proxy.rb", "lib/couchrest/mixins/collection.rb", "lib/couchrest/mixins/design_doc.rb", "lib/couchrest/mixins/document_queries.rb", "lib/couchrest/mixins/extended_attachments.rb", "lib/couchrest/mixins/extended_document_mixins.rb", "lib/couchrest/mixins/properties.rb", "lib/couchrest/mixins/validation.rb", "lib/couchrest/mixins/views.rb", "lib/couchrest/mixins.rb", "lib/couchrest/monkeypatches.rb", "lib/couchrest/more", "lib/couchrest/more/casted_model.rb", "lib/couchrest/more/extended_document.rb", "lib/couchrest/more/property.rb", "lib/couchrest/support", "lib/couchrest/support/blank.rb", "lib/couchrest/support/class.rb", "lib/couchrest/support/rails.rb", "lib/couchrest/validation", "lib/couchrest/validation/auto_validate.rb", "lib/couchrest/validation/contextual_validators.rb", "lib/couchrest/validation/validation_errors.rb", "lib/couchrest/validation/validators", "lib/couchrest/validation/validators/absent_field_validator.rb", "lib/couchrest/validation/validators/confirmation_validator.rb", "lib/couchrest/validation/validators/format_validator.rb", "lib/couchrest/validation/validators/formats", "lib/couchrest/validation/validators/formats/email.rb", "lib/couchrest/validation/validators/formats/url.rb", "lib/couchrest/validation/validators/generic_validator.rb", "lib/couchrest/validation/validators/length_validator.rb", "lib/couchrest/validation/validators/method_validator.rb", "lib/couchrest/validation/validators/numeric_validator.rb", "lib/couchrest/validation/validators/required_field_validator.rb", "lib/couchrest.rb", "spec/couchrest", "spec/couchrest/core", "spec/couchrest/core/couchrest_spec.rb", "spec/couchrest/core/database_spec.rb", "spec/couchrest/core/design_spec.rb", "spec/couchrest/core/document_spec.rb", "spec/couchrest/core/server_spec.rb", "spec/couchrest/helpers", "spec/couchrest/helpers/pager_spec.rb", "spec/couchrest/helpers/streamer_spec.rb", "spec/couchrest/more", "spec/couchrest/more/casted_extended_doc_spec.rb", "spec/couchrest/more/casted_model_spec.rb", "spec/couchrest/more/extended_doc_attachment_spec.rb", "spec/couchrest/more/extended_doc_spec.rb", "spec/couchrest/more/extended_doc_subclass_spec.rb", "spec/couchrest/more/extended_doc_view_spec.rb", "spec/couchrest/more/property_spec.rb", "spec/fixtures", "spec/fixtures/attachments", "spec/fixtures/attachments/couchdb.png", "spec/fixtures/attachments/README", "spec/fixtures/attachments/test.html", "spec/fixtures/more", "spec/fixtures/more/article.rb", "spec/fixtures/more/card.rb", "spec/fixtures/more/cat.rb", "spec/fixtures/more/course.rb", "spec/fixtures/more/event.rb", "spec/fixtures/more/invoice.rb", "spec/fixtures/more/person.rb", "spec/fixtures/more/question.rb", "spec/fixtures/more/service.rb", "spec/fixtures/views", "spec/fixtures/views/lib.js", "spec/fixtures/views/test_view", "spec/fixtures/views/test_view/lib.js", "spec/fixtures/views/test_view/only-map.js", "spec/fixtures/views/test_view/test-map.js", "spec/fixtures/views/test_view/test-reduce.js", "spec/spec.opts", "spec/spec_helper.rb", "utils/remap.rb", "utils/subset.rb"] s.homepage = %q{http://github.com/jchris/couchrest} s.require_paths = ["lib"] s.rubygems_version = %q{1.3.4} diff --git a/history.txt b/history.txt index b505d2a..5ce94b2 100644 --- a/history.txt +++ b/history.txt @@ -1,18 +1,14 @@ -== 0.40 - -=== Notes - - This release slightly modifies the API and if you were using a previous version of CouchRest, -you will need to make the following modifications. - - +== 0.33 * Major enhancements * Added a new Rack logger middleware letting you log/save requests/queries (Matt Aimonetti) * Minor enhancements - + + * Added #amount_pages to a paginated result array (Matt Aimonetti) + * Ruby 1.9.2 compatible (Matt Aimonetti) + * Added a property? method for property cast as :boolean (John Wood) * Added an option to force the deletion of a attachments (bypass 409s) (Matt Aimonetti) * Created a new abstraction layer for the REST API (Matt Aimonetti) * Bug fix: made ExtendedDocument#all compatible with Couch 0.10 (tc) @@ -64,4 +60,4 @@ you will need to make the following modifications. --- Unfortunately, before 0.30 we did not keep a track of the modifications made to CouchRest. -You can see the full commit history on GitHub: http://github.com/mattetti/couchrest/commits/master/ \ No newline at end of file +You can see the full commit history on GitHub: http://github.com/couchrest/couchrest/commits/master/ \ No newline at end of file diff --git a/lib/couchrest.rb b/lib/couchrest.rb index efb5847..3da42d8 100644 --- a/lib/couchrest.rb +++ b/lib/couchrest.rb @@ -28,7 +28,7 @@ require 'couchrest/monkeypatches' # = CouchDB, close to the metal module CouchRest - VERSION = '0.32' unless self.const_defined?("VERSION") + VERSION = '0.33' unless self.const_defined?("VERSION") autoload :Server, 'couchrest/core/server' autoload :Database, 'couchrest/core/database'