diff --git a/lib/couchrest/core/database.rb b/lib/couchrest/core/database.rb index 1e7ecb3..baa9257 100644 --- a/lib/couchrest/core/database.rb +++ b/lib/couchrest/core/database.rb @@ -336,7 +336,7 @@ module CouchRest end def clear_extended_doc_fresh_cache - ::CouchRest::ExtendedDocument.subclasses.each{|klass| klass.design_doc_fresh = false if klass.respond_to?(:design_doc_fresh=) } + ::CouchRest::ExtendedDocument.subclasses.each{|klass| klass.req_design_doc_refresh if klass.respond_to?(:req_design_doc_refresh)} end def uri_for_attachment(doc, name) diff --git a/lib/couchrest/mixins/class_proxy.rb b/lib/couchrest/mixins/class_proxy.rb index 5f7bd5b..40f593a 100644 --- a/lib/couchrest/mixins/class_proxy.rb +++ b/lib/couchrest/mixins/class_proxy.rb @@ -107,16 +107,12 @@ module CouchRest @klass.design_doc end - def design_doc_fresh - @klass.design_doc_fresh - end - def refresh_design_doc - @klass.refresh_design_doc_on(@database) + @klass.refresh_design_doc(@database) end def save_design_doc - @klass.save_design_doc_on(@database) + @klass.save_design_doc(@database) end end end diff --git a/lib/couchrest/mixins/design_doc.rb b/lib/couchrest/mixins/design_doc.rb index 35729a7..1624244 100644 --- a/lib/couchrest/mixins/design_doc.rb +++ b/lib/couchrest/mixins/design_doc.rb @@ -9,23 +9,23 @@ module CouchRest end module ClassMethods - attr_accessor :design_doc, :design_doc_slug_cache, :design_doc_fresh def design_doc @design_doc ||= Design.new(default_design_doc) end + + # Use when something has been changed, like a view, so that on the next request + # the design docs will be updated. + def req_design_doc_refresh + @design_doc_fresh = { } + end 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 = [] - design_doc['views'].each do |name, view| - funcs << "#{name}/#{view['map']}#{view['reduce']}" - end - self.design_doc_slug_cache = self.to_s + self.to_s end def default_design_doc @@ -43,45 +43,44 @@ module CouchRest } end - def refresh_design_doc - reset_design_doc - save_design_doc - end - - def refresh_design_doc_on(db) - reset_design_doc - save_design_doc_on(db) - end - - # Save the design doc onto the default database, and update the - # design_doc attribute - def save_design_doc - reset_design_doc unless design_doc_fresh - self.design_doc = update_design_doc(design_doc) + def refresh_design_doc(db = database) + unless design_doc_fresh(db) + reset_design_doc(db) + save_design_doc(db) + end 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) + def save_design_doc(db = database) update_design_doc(Design.new(design_doc), db) end - private - - def reset_design_doc - current = self.database.get(design_doc_id) rescue nil + protected + + def design_doc_fresh(db, fresh = nil) + @design_doc_fresh ||= {} + if fresh.nil? + @design_doc_fresh[db.uri] || false + else + @design_doc_fresh[db.uri] = fresh + end + end + + def reset_design_doc(db) + current = db.get(design_doc_id) rescue nil design_doc['_id'] = design_doc_id if current.nil? design_doc.delete('_rev') else design_doc['_rev'] = current['_rev'] end - self.design_doc_fresh = true + design_doc_fresh(db, true) end # Writes out a design_doc to a given database, returning the # updated design doc - def update_design_doc(design_doc, db = database) + def update_design_doc(design_doc, db) saved = db.get(design_doc['_id']) rescue nil if saved design_doc['views'].each do |name, view| @@ -100,4 +99,4 @@ module CouchRest end end -end \ No newline at end of file +end diff --git a/lib/couchrest/mixins/views.rb b/lib/couchrest/mixins/views.rb index 6c95066..8543b1c 100644 --- a/lib/couchrest/mixins/views.rb +++ b/lib/couchrest/mixins/views.rb @@ -83,8 +83,8 @@ module CouchRest opts[:guards].push "(doc['couchrest-type'] == '#{self.to_s}')" end keys.push opts - self.design_doc.view_by(*keys) - self.design_doc_fresh = false + design_doc.view_by(*keys) + req_design_doc_refresh end # returns stored defaults if the there is a view named this in the design doc @@ -96,9 +96,7 @@ module CouchRest # Dispatches to any named view. def view(name, query={}, &block) db = query.delete(:database) || database - unless design_doc_fresh - refresh_design_doc_on(db) - end + refresh_design_doc(db) query[:raw] = true if query[:reduce] raw = query.delete(:raw) fetch_view_with_docs(db, name, query, raw, &block) @@ -119,13 +117,6 @@ module CouchRest end end - # Deletes the current design doc for the current class. - # Running it to early could mean that live code has to regenerate - # potentially large indexes. - def cleanup_design_docs!(db = database) - save_design_doc_on(db) - end - private def fetch_view_with_docs(db, name, opts, raw=false, &block) @@ -156,7 +147,7 @@ module CouchRest # the design doc may not have been saved yet on this database rescue HttpAbstraction::ResourceNotFound => e if retryable - save_design_doc_on(db) + save_design_doc(db) retryable = false retry else diff --git a/spec/couchrest/more/extended_doc_spec.rb b/spec/couchrest/more/extended_doc_spec.rb index 3500d05..87581d8 100644 --- a/spec/couchrest/more/extended_doc_spec.rb +++ b/spec/couchrest/more/extended_doc_spec.rb @@ -327,7 +327,7 @@ describe "ExtendedDocument" do describe "finding all instances of a model" do before(:all) do - WithTemplateAndUniqueID.design_doc_fresh = false + WithTemplateAndUniqueID.req_design_doc_refresh WithTemplateAndUniqueID.all.map{|o| o.destroy(true)} WithTemplateAndUniqueID.database.bulk_delete WithTemplateAndUniqueID.new('important-field' => '1').save @@ -349,7 +349,7 @@ describe "ExtendedDocument" do describe "counting all instances of a model" do before(:each) do @db = reset_test_db! - WithTemplateAndUniqueID.design_doc_fresh = false + WithTemplateAndUniqueID.req_design_doc_refresh end it ".count should return 0 if there are no docuemtns" do @@ -368,7 +368,7 @@ describe "ExtendedDocument" do describe "finding the first instance of a model" do before(:each) do @db = reset_test_db! - WithTemplateAndUniqueID.design_doc_fresh = false + WithTemplateAndUniqueID.req_design_doc_refresh WithTemplateAndUniqueID.new('important-field' => '1').save WithTemplateAndUniqueID.new('important-field' => '2').save WithTemplateAndUniqueID.new('important-field' => '3').save diff --git a/spec/couchrest/more/extended_doc_subclass_spec.rb b/spec/couchrest/more/extended_doc_subclass_spec.rb index 6a9bdc9..a516f76 100644 --- a/spec/couchrest/more/extended_doc_subclass_spec.rb +++ b/spec/couchrest/more/extended_doc_subclass_spec.rb @@ -76,9 +76,9 @@ describe "Subclassing an ExtendedDocument" do it "should have its own design_doc_fresh" do Animal.refresh_design_doc - Dog.design_doc_fresh.should_not == true + Dog.send(:design_doc_fresh, Dog.database).should_not == true Dog.refresh_design_doc - Dog.design_doc_fresh.should == true + Dog.send(:design_doc_fresh, Dog.database).should == true end it "should not add views to the parent's design_doc" do diff --git a/spec/couchrest/more/extended_doc_view_spec.rb b/spec/couchrest/more/extended_doc_view_spec.rb index f622d7d..7d6ef08 100644 --- a/spec/couchrest/more/extended_doc_view_spec.rb +++ b/spec/couchrest/more/extended_doc_view_spec.rb @@ -126,7 +126,7 @@ describe "ExtendedDocument views" do lambda{Unattached.all}.should raise_error end it "should query all" do - Unattached.cleanup_design_docs!(@db) + # Unattached.cleanup_design_docs!(@db) rs = Unattached.all :database => @db rs.length.should == 4 end @@ -187,7 +187,7 @@ describe "ExtendedDocument views" do Unattached.view_by :questions Unattached.by_questions(:database => @db) original_revision = Unattached.model_design_doc(@db)['_rev'] - Unattached.cleanup_design_docs!(@db) + Unattached.save_design_doc(@db) Unattached.model_design_doc(@db)['_rev'].should_not == original_revision end end