Working on adding checksum support to design documents to handle updates
This commit is contained in:
parent
a6becd7305
commit
221e5a5470
8 changed files with 89 additions and 41 deletions
|
@ -7,7 +7,7 @@ module CouchRest
|
|||
module ClassMethods
|
||||
|
||||
def design_doc
|
||||
@design_doc ||= Design.new(default_design_doc)
|
||||
@design_doc ||= ::CouchRest::Design.new(default_design_doc)
|
||||
end
|
||||
|
||||
# Use when something has been changed, like a view, so that on the next request
|
||||
|
@ -90,24 +90,17 @@ module CouchRest
|
|||
# Writes out a design_doc to a given database, returning the
|
||||
# updated design doc
|
||||
def update_design_doc(design_doc, db, force = false)
|
||||
design_doc['couchrest-hash'] = design_doc.checksum
|
||||
saved = stored_design_doc(db)
|
||||
if saved
|
||||
changes = force
|
||||
design_doc['views'].each do |name, view|
|
||||
if !compare_views(saved['views'][name], view)
|
||||
changes = true
|
||||
saved['views'][name] = view
|
||||
end
|
||||
end
|
||||
if changes
|
||||
if force || saved['couchrest-hash'] != design_doc['couchrest-hash']
|
||||
saved.merge!(design_doc)
|
||||
db.save_doc(saved)
|
||||
end
|
||||
design_doc
|
||||
else
|
||||
design_doc.database = db
|
||||
design_doc.save
|
||||
design_doc
|
||||
db.save_doc(design_doc)
|
||||
end
|
||||
design_doc
|
||||
end
|
||||
|
||||
# Return true if the two views match
|
||||
|
@ -117,7 +110,7 @@ module CouchRest
|
|||
end
|
||||
|
||||
end # module ClassMethods
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -90,6 +90,13 @@ module CouchRest
|
|||
result ? all.last : limit(1).descending.all.last
|
||||
end
|
||||
|
||||
# Return the number of documents in the currently defined result set.
|
||||
# Use <tt>#count</tt> for the total number of documents regardless
|
||||
# of the current limit defined.
|
||||
def length
|
||||
docs.length
|
||||
end
|
||||
|
||||
# Perform a count operation based on the current view. If the view
|
||||
# can be reduced, the reduce will be performed and return the first
|
||||
# value. This is okay for most simple queries, but may provide
|
||||
|
@ -383,30 +390,24 @@ module CouchRest
|
|||
def execute
|
||||
return self.result if result
|
||||
raise "Database must be defined in model or view!" if use_database.nil?
|
||||
retryable = true
|
||||
|
||||
# Remove the reduce value if its not needed
|
||||
query.delete(:reduce) unless can_reduce?
|
||||
begin
|
||||
self.result = model.design_doc.view_on(use_database, name, query.reject{|k,v| v.nil?})
|
||||
rescue RestClient::ResourceNotFound => e
|
||||
if retryable
|
||||
model.save_design_doc(use_database)
|
||||
retryable = false
|
||||
retry
|
||||
else
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
# Save the design doc for the current database. This should be efficient
|
||||
# and check for changes
|
||||
model.save_design_doc(use_database)
|
||||
|
||||
self.result = model.design_doc.view_on(use_database, name, query.reject{|k,v| v.nil?})
|
||||
end
|
||||
|
||||
# Class Methods
|
||||
class << self
|
||||
|
||||
# Simplified view creation. A new view will be added to the
|
||||
# provided model's design document using the name and options.
|
||||
#
|
||||
# If the view name starts with "by_" and +:by+ is not provided in
|
||||
# the options, the new view's map method will be interpretted and
|
||||
# the options, the new view's map method will be interpreted and
|
||||
# generated automatically. For example:
|
||||
#
|
||||
# View.create(Meeting, "by_date_and_name")
|
||||
|
|
15
lib/couchrest/model/support/couchrest_database.rb
Normal file
15
lib/couchrest/model/support/couchrest_database.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
CouchRest::Database.class_eval do
|
||||
|
||||
alias :delete_orig! :delete!
|
||||
def delete!
|
||||
clear_model_fresh_cache
|
||||
delete_orig!
|
||||
end
|
||||
|
||||
# If the database is deleted, ensure that the design docs will be refreshed.
|
||||
def clear_model_fresh_cache
|
||||
::CouchRest::Model::Base.subclasses.each{|klass| klass.req_design_doc_refresh if klass.respond_to?(:req_design_doc_refresh)}
|
||||
end
|
||||
|
||||
end
|
24
lib/couchrest/model/support/couchrest_design.rb
Normal file
24
lib/couchrest/model/support/couchrest_design.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
CouchRest::Design.class_eval do
|
||||
|
||||
# Calculate a checksum of the Design document. Used for ensuring the latest
|
||||
# version has been sent to the database.
|
||||
#
|
||||
# This will generate an flatterned, ordered array of all the elements of the
|
||||
# design document, convert to string then generate an MD5 Hash. This should
|
||||
# result in a consisitent Hash accross all platforms.
|
||||
#
|
||||
def checksum
|
||||
# create a copy of basic elements
|
||||
base = self.dup
|
||||
base.delete('_id')
|
||||
base.delete('_rev')
|
||||
result = nil
|
||||
flatten =
|
||||
lambda{|v|
|
||||
v.is_a?(Hash) ? v.flatten.map{|v| flatten.call(v)}.flatten : v
|
||||
}
|
||||
Digest::MD5.hexdigest(flatten.call(base).sort.join(''))
|
||||
end
|
||||
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue