From c18567f8fcb0ed9d11ef1218afffc426d7c5f6a1 Mon Sep 17 00:00:00 2001 From: Matt Aimonetti Date: Sun, 7 Jun 2009 18:51:31 -0700 Subject: [PATCH] differentiated attachment's URI and URL --- lib/couchrest/core/database.rb | 47 ++++++++++--------- lib/couchrest/core/document.rb | 2 +- lib/couchrest/mixins/extended_attachments.rb | 6 +++ spec/couchrest/core/database_spec.rb | 3 +- .../more/extended_doc_attachment_spec.rb | 5 ++ spec/couchrest/more/property_spec.rb | 10 ++++ spec/fixtures/more/card.rb | 2 + 7 files changed, 52 insertions(+), 23 deletions(-) diff --git a/lib/couchrest/core/database.rb b/lib/couchrest/core/database.rb index 8c43917..6627117 100644 --- a/lib/couchrest/core/database.rb +++ b/lib/couchrest/core/database.rb @@ -17,7 +17,8 @@ module CouchRest @name = name @server = server @host = server.uri - @uri = @root = "#{host}/#{name.gsub('/','%2F')}" + @uri = "/#{name.gsub('/','%2F')}" + @root = host + uri @streamer = Streamer.new(self) @bulk_save_cache = [] @bulk_save_cache_limit = 500 # must be smaller than the uuid count @@ -25,18 +26,18 @@ module CouchRest # returns the database's uri def to_s - @uri + @root end # GET the database info from CouchDB def info - CouchRest.get @uri + CouchRest.get @root end # Query the _all_docs view. Accepts all the same arguments as view. def documents(params = {}) keys = params.delete(:keys) - url = CouchRest.paramify_url "#{@uri}/_all_docs", params + url = CouchRest.paramify_url "#{@root}/_all_docs", params if keys CouchRest.post(url, {:keys => keys}) else @@ -56,7 +57,7 @@ module CouchRest def slow_view(funcs, params = {}) keys = params.delete(:keys) funcs = funcs.merge({:keys => keys}) if keys - url = CouchRest.paramify_url "#{@uri}/_temp_view", params + url = CouchRest.paramify_url "#{@root}/_temp_view", params JSON.parse(RestClient.post(url, funcs.to_json, {"Content-Type" => 'application/json'})) end @@ -70,7 +71,7 @@ module CouchRest name = name.split('/') # I think this will always be length == 2, but maybe not... dname = name.shift vname = name.join('/') - url = CouchRest.paramify_url "#{@uri}/_design/#{dname}/_view/#{vname}", params + url = CouchRest.paramify_url "#{@root}/_design/#{dname}/_view/#{vname}", params if keys CouchRest.post(url, {:keys => keys}) else @@ -85,7 +86,7 @@ module CouchRest # GET a document from CouchDB, by id. Returns a Ruby Hash. def get(id, params = {}) slug = escape_docid(id) - url = CouchRest.paramify_url("#{@uri}/#{slug}", params) + url = CouchRest.paramify_url("#{@root}/#{slug}", params) result = CouchRest.get(url) return result unless result.is_a?(Hash) doc = if /^_design/ =~ result["_id"] @@ -101,7 +102,7 @@ module CouchRest def fetch_attachment(doc, name) # slug = escape_docid(docid) # name = CGI.escape(name) - uri = uri_for_attachment(doc, name) + uri = url_for_attachment(doc, name) RestClient.get uri # "#{@uri}/#{slug}/#{name}" end @@ -110,13 +111,13 @@ module CouchRest def put_attachment(doc, name, file, options = {}) docid = escape_docid(doc['_id']) name = CGI.escape(name) - uri = uri_for_attachment(doc, name) + uri = url_for_attachment(doc, name) JSON.parse(RestClient.put(uri, file, options)) end # DELETE an attachment directly from CouchDB def delete_attachment doc, name - uri = uri_for_attachment(doc, name) + uri = url_for_attachment(doc, name) # this needs a rev JSON.parse(RestClient.delete(uri)) end @@ -144,18 +145,18 @@ module CouchRest result = if doc['_id'] slug = escape_docid(doc['_id']) begin - CouchRest.put "#{@uri}/#{slug}", doc + CouchRest.put "#{@root}/#{slug}", doc rescue RestClient::ResourceNotFound p "resource not found when saving even tho an id was passed" slug = doc['_id'] = @server.next_uuid - CouchRest.put "#{@uri}/#{slug}", doc + CouchRest.put "#{@root}/#{slug}", doc end else begin slug = doc['_id'] = @server.next_uuid - CouchRest.put "#{@uri}/#{slug}", doc + CouchRest.put "#{@root}/#{slug}", doc rescue #old version of couchdb - CouchRest.post @uri, doc + CouchRest.post @root, doc end end if result['ok'] @@ -190,7 +191,7 @@ module CouchRest doc['_id'] = nextid if nextid end end - CouchRest.post "#{@uri}/_bulk_docs", {:docs => docs} + CouchRest.post "#{@root}/_bulk_docs", {:docs => docs} end alias :bulk_delete :bulk_save @@ -207,7 +208,7 @@ module CouchRest return { "ok" => true } # Mimic the non-deferred version end slug = escape_docid(doc['_id']) - CouchRest.delete "#{@uri}/#{slug}?rev=#{doc['_rev']}" + CouchRest.delete "#{@root}/#{slug}?rev=#{doc['_rev']}" end ### DEPRECATION NOTICE @@ -227,7 +228,7 @@ module CouchRest else dest end - CouchRest.copy "#{@uri}/#{slug}", destination + CouchRest.copy "#{@root}/#{slug}", destination end ### DEPRECATION NOTICE @@ -238,7 +239,7 @@ module CouchRest # Compact the database, removing old document revisions and optimizing space use. def compact! - CouchRest.post "#{@uri}/_compact" + CouchRest.post "#{@root}/_compact" end # Create the database @@ -272,7 +273,7 @@ module CouchRest # catastrophic. Use with care! def delete! clear_extended_doc_fresh_cache - CouchRest.delete @uri + CouchRest.delete @root end private @@ -280,7 +281,7 @@ module CouchRest def clear_extended_doc_fresh_cache ::CouchRest::ExtendedDocument.subclasses.each{|klass| klass.design_doc_fresh = false if klass.respond_to?(:design_doc_fresh=) } end - + def uri_for_attachment(doc, name) if doc.is_a?(String) puts "CouchRest::Database#fetch_attachment will eventually require a doc as the first argument, not a doc.id" @@ -293,7 +294,11 @@ module CouchRest docid = escape_docid(docid) name = CGI.escape(name) rev = "?rev=#{doc['_rev']}" if rev - "#{@root}/#{docid}/#{name}#{rev}" + "/#{docid}/#{name}#{rev}" + end + + def url_for_attachment(doc, name) + @root + uri_for_attachment(doc, name) end def escape_docid id diff --git a/lib/couchrest/core/document.rb b/lib/couchrest/core/document.rb index e90c5fe..941ed80 100644 --- a/lib/couchrest/core/document.rb +++ b/lib/couchrest/core/document.rb @@ -68,7 +68,7 @@ module CouchRest # Returns the CouchDB uri for the document def uri(append_rev = false) return nil if new_document? - couch_uri = "http://#{database.uri}/#{CGI.escape(id)}" + couch_uri = "http://#{database.root}/#{CGI.escape(id)}" if append_rev == true couch_uri << "?rev=#{rev}" elsif append_rev.kind_of?(Integer) diff --git a/lib/couchrest/mixins/extended_attachments.rb b/lib/couchrest/mixins/extended_attachments.rb index 278bc2b..dd78644 100644 --- a/lib/couchrest/mixins/extended_attachments.rb +++ b/lib/couchrest/mixins/extended_attachments.rb @@ -44,6 +44,12 @@ module CouchRest "#{database.root}/#{self.id}/#{attachment_name}" end + # returns URI to fetch the attachment from + def attachment_uri(attachment_name) + return unless has_attachment?(attachment_name) + "#{database.uri}/#{self.id}/#{attachment_name}" + end + private def encode_attachment(data) diff --git a/spec/couchrest/core/database_spec.rb b/spec/couchrest/core/database_spec.rb index 57dc2a4..6df866d 100644 --- a/spec/couchrest/core/database_spec.rb +++ b/spec/couchrest/core/database_spec.rb @@ -12,7 +12,8 @@ describe CouchRest::Database do it "should escape the name in the URI" do db = @cr.database("foo/bar") db.name.should == "foo/bar" - db.uri.should == "#{COUCHHOST}/foo%2Fbar" + db.root.should == "#{COUCHHOST}/foo%2Fbar" + db.uri.should == "/foo%2Fbar" end end diff --git a/spec/couchrest/more/extended_doc_attachment_spec.rb b/spec/couchrest/more/extended_doc_attachment_spec.rb index a0213a6..d82d9fe 100644 --- a/spec/couchrest/more/extended_doc_attachment_spec.rb +++ b/spec/couchrest/more/extended_doc_attachment_spec.rb @@ -126,5 +126,10 @@ describe "ExtendedDocument attachments" do it 'should return the attachment URL as specified by CouchDB HttpDocumentApi' do @obj.attachment_url(@attachment_name).should == "#{Basic.database}/#{@obj.id}/#{@attachment_name}" end + + it 'should return the attachment URI' do + @obj.attachment_uri(@attachment_name).should == "#{Basic.database.uri}/#{@obj.id}/#{@attachment_name}" + end + end end diff --git a/spec/couchrest/more/property_spec.rb b/spec/couchrest/more/property_spec.rb index 146f0f8..8559c8f 100644 --- a/spec/couchrest/more/property_spec.rb +++ b/spec/couchrest/more/property_spec.rb @@ -1,4 +1,5 @@ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') +require File.join(FIXTURE_PATH, 'more', 'person') require File.join(FIXTURE_PATH, 'more', 'card') require File.join(FIXTURE_PATH, 'more', 'invoice') require File.join(FIXTURE_PATH, 'more', 'service') @@ -36,6 +37,15 @@ describe "ExtendedDocument properties" do @card.family_name.should == @card.last_name end + it "should let you use an alias for a casted attribute" do + @card.cast_alias = Person.new(:name => "Aimonetti") + @card.cast_alias.name.should == "Aimonetti" + @card.calias.name.should == "Aimonetti" + card = Card.new(:first_name => "matt", :cast_alias => {:name => "Aimonetti"}) + card.cast_alias.name.should == "Aimonetti" + card.calias.name.should == "Aimonetti" + end + it "should be auto timestamped" do @card.created_at.should be_nil @card.updated_at.should be_nil diff --git a/spec/fixtures/more/card.rb b/spec/fixtures/more/card.rb index 2562c9d..484ba23 100644 --- a/spec/fixtures/more/card.rb +++ b/spec/fixtures/more/card.rb @@ -11,6 +11,8 @@ class Card < CouchRest::ExtendedDocument property :first_name property :last_name, :alias => :family_name property :read_only_value, :read_only => true + property :cast_alias, :cast_as => 'Person', :alias => :calias + timestamps!