couchrest_model/lib/couchrest/mixins/design_doc.rb
Brian Candler ec7848b783 Multiple database support for ExtendedDocument.
New optional parameters are available to select the database:

Mixins::DocumentQueries
  * get <id>, <db>
  * all :database => <db>
  * first :database => <db>

Mixins::Views
  * view <name>, :database => <db>
  * all_design_doc_versions <db>
  * cleanup_design_docs! <db>

Mixins::DesignDoc
  * refresh_design_doc now only updates the design_doc _id and removes _rev
  * call save_design_doc to save and update the design_doc
  * call save_design_doc_on <db> to save the design doc on a given
    database without modifying the model's design_doc object

Design (core/design.rb)
  * new method view_on <db>, ...

Bug fixes:
  * design_doc_slug in mixins/design_doc.rb was using an empty document
    to calculate the slug each time
  * method_missing in core/extended_document.rb now passes a block through
2009-03-27 11:27:37 +00:00

88 lines
2.5 KiB
Ruby

require 'digest/md5'
module CouchRest
module Mixins
module DesignDoc
def self.included(base)
base.extend(ClassMethods)
base.send(:extlib_inheritable_accessor, :design_doc)
base.send(:extlib_inheritable_accessor, :design_doc_slug_cache)
base.send(:extlib_inheritable_accessor, :design_doc_fresh)
end
module ClassMethods
def design_doc_id
"_design/#{design_doc_slug}"
end
def design_doc_slug
return design_doc_slug_cache if (design_doc_slug_cache && design_doc_fresh)
funcs = []
self.design_doc ||= Design.new(default_design_doc)
design_doc['views'].each do |name, view|
funcs << "#{name}/#{view['map']}#{view['reduce']}"
end
md5 = Digest::MD5.hexdigest(funcs.sort.join(''))
self.design_doc_slug_cache = "#{self.to_s}-#{md5}"
end
def default_design_doc
{
"language" => "javascript",
"views" => {
'all' => {
'map' => "function(doc) {
if (doc['couchrest-type'] == '#{self.to_s}') {
emit(null,null);
}
}"
}
}
}
end
def refresh_design_doc
design_doc['_id'] = design_doc_id
design_doc.delete('_rev')
#design_doc.database = nil
self.design_doc_fresh = true
end
# Save the design doc onto the default database, and update the
# design_doc attribute
def save_design_doc
refresh_design_doc unless design_doc_fresh
self.design_doc = update_design_doc(design_doc)
end
# Save the design doc onto a target database in a thread-safe way,
# not modifying the model's design_doc
def save_design_doc_on(db)
update_design_doc(Design.new(design_doc), db)
end
private
# Writes out a design_doc to a given database, returning the
# updated design doc
def update_design_doc(design_doc, db = database)
saved = db.get(design_doc['_id']) rescue nil
if saved
design_doc['views'].each do |name, view|
saved['views'][name] = view
end
db.save_doc(saved)
saved
else
design_doc.database = db
design_doc.save
design_doc
end
end
end # module ClassMethods
end
end
end