Working on adding checksum support to design documents to handle updates
This commit is contained in:
parent
a6becd7305
commit
221e5a5470
30
Gemfile.lock
30
Gemfile.lock
|
@ -12,21 +12,22 @@ GEM
|
|||
remote: http://rubygems.org/
|
||||
specs:
|
||||
abstract (1.0.0)
|
||||
actionpack (3.0.5)
|
||||
activemodel (= 3.0.5)
|
||||
activesupport (= 3.0.5)
|
||||
actionpack (3.0.6)
|
||||
activemodel (= 3.0.6)
|
||||
activesupport (= 3.0.6)
|
||||
builder (~> 2.1.2)
|
||||
erubis (~> 2.6.6)
|
||||
i18n (~> 0.4)
|
||||
i18n (~> 0.5.0)
|
||||
rack (~> 1.2.1)
|
||||
rack-mount (~> 0.6.13)
|
||||
rack-mount (~> 0.6.14)
|
||||
rack-test (~> 0.5.7)
|
||||
tzinfo (~> 0.3.23)
|
||||
activemodel (3.0.5)
|
||||
activesupport (= 3.0.5)
|
||||
activemodel (3.0.6)
|
||||
activesupport (= 3.0.6)
|
||||
builder (~> 2.1.2)
|
||||
i18n (~> 0.4)
|
||||
activesupport (3.0.5)
|
||||
i18n (~> 0.5.0)
|
||||
activesupport (3.0.6)
|
||||
bouncy-castle-java (1.5.0145.2)
|
||||
builder (2.1.2)
|
||||
couchrest (1.1.0.pre2)
|
||||
json (~> 1.5.1)
|
||||
|
@ -36,16 +37,19 @@ GEM
|
|||
erubis (2.6.6)
|
||||
abstract (>= 1.0.0)
|
||||
i18n (0.5.0)
|
||||
jruby-openssl (0.7.3)
|
||||
bouncy-castle-java
|
||||
json (1.5.1)
|
||||
json (1.5.1-java)
|
||||
mime-types (1.16)
|
||||
rack (1.2.1)
|
||||
rack-mount (0.6.14)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (0.5.7)
|
||||
rack (>= 1.0)
|
||||
railties (3.0.5)
|
||||
actionpack (= 3.0.5)
|
||||
activesupport (= 3.0.5)
|
||||
railties (3.0.6)
|
||||
actionpack (= 3.0.6)
|
||||
activesupport (= 3.0.6)
|
||||
rake (>= 0.8.7)
|
||||
thor (~> 0.14.4)
|
||||
rake (0.8.7)
|
||||
|
@ -63,12 +67,14 @@ GEM
|
|||
tzinfo (0.3.26)
|
||||
|
||||
PLATFORMS
|
||||
java
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
activemodel (~> 3.0.0)
|
||||
couchrest (= 1.1.0.pre2)
|
||||
couchrest_model!
|
||||
jruby-openssl (>= 0.7.3)
|
||||
mime-types (~> 1.15)
|
||||
rack-test (>= 0.5.7)
|
||||
railties (~> 3.0.0)
|
||||
|
|
|
@ -30,5 +30,6 @@ Gem::Specification.new do |s|
|
|||
s.add_dependency(%q<railties>, "~> 3.0.0")
|
||||
s.add_development_dependency(%q<rspec>, ">= 2.0.0")
|
||||
s.add_development_dependency(%q<rack-test>, ">= 0.5.7")
|
||||
s.add_development_dependency("jruby-openssl", ">= 0.7.3")
|
||||
end
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
# Save the design doc for the current database. This should be efficient
|
||||
# and check for changes
|
||||
model.save_design_doc(use_database)
|
||||
retryable = false
|
||||
retry
|
||||
else
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
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
|
|
@ -45,7 +45,8 @@ require "couchrest/model/designs"
|
|||
require "couchrest/model/designs/view"
|
||||
|
||||
# Monkey patches applied to couchrest
|
||||
require "couchrest/model/support/couchrest"
|
||||
require "couchrest/model/support/couchrest_database"
|
||||
require "couchrest/model/support/couchrest_design"
|
||||
# Core Extensions
|
||||
require "couchrest/model/core_extensions/hash"
|
||||
require "couchrest/model/core_extensions/time_parsing"
|
||||
|
|
|
@ -163,6 +163,13 @@ describe "Design View" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#length" do
|
||||
it "should provide a length from the docs array" do
|
||||
@obj.should_receive(:docs).and_return([1, 2, 3])
|
||||
@obj.length.should eql(3)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#count" do
|
||||
it "should raise an error if view prepared for group" do
|
||||
@obj.should_receive(:query).and_return({:group => true})
|
||||
|
|
Loading…
Reference in a new issue