couchrest_model/lib/couchrest/mixins/extended_attachments.rb
Johannes J. Schmidt a7ee95b33c fixed extended attachment encoding part 2
encoding was done twice, once while setting attachment
and once while saving the document.

Also the attachment was decoded while retreaving, but this is done by
CouchDB itself automatically, as described in
http://wiki.apache.org/couchdb/HTTP_Document_API#line-463.

Signed-off-by: Marcos Tapajós <tapajos@gmail.com>
2010-01-29 22:18:55 -02:00

70 lines
2.4 KiB
Ruby

module CouchRest
module Mixins
module ExtendedAttachments
# creates a file attachment to the current doc
def create_attachment(args={})
raise ArgumentError unless args[:file] && args[:name]
return if has_attachment?(args[:name])
self['_attachments'] ||= {}
set_attachment_attr(args)
rescue ArgumentError => e
raise ArgumentError, 'You must specify :file and :name'
end
# reads the data from an attachment
def read_attachment(attachment_name)
database.fetch_attachment(self, attachment_name)
end
# modifies a file attachment on the current doc
def update_attachment(args={})
raise ArgumentError unless args[:file] && args[:name]
return unless has_attachment?(args[:name])
delete_attachment(args[:name])
set_attachment_attr(args)
rescue ArgumentError => e
raise ArgumentError, 'You must specify :file and :name'
end
# deletes a file attachment from the current doc
def delete_attachment(attachment_name)
return unless self['_attachments']
self['_attachments'].delete attachment_name
end
# returns true if attachment_name exists
def has_attachment?(attachment_name)
!!(self['_attachments'] && self['_attachments'][attachment_name] && !self['_attachments'][attachment_name].empty?)
end
# returns URL to fetch the attachment from
def attachment_url(attachment_name)
return unless has_attachment?(attachment_name)
"#{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 get_mime_type(file)
::MIME::Types.type_for(file.path).empty? ?
'text\/plain' : MIME::Types.type_for(file.path).first.content_type.gsub(/\//,'\/')
end
def set_attachment_attr(args)
content_type = args[:content_type] ? args[:content_type] : get_mime_type(args[:file])
self['_attachments'][args[:name]] = {
'content_type' => content_type,
'data' => args[:file].read
}
end
end # module ExtendedAttachments
end
end