From eedbed77f9dadcd348731633e7af15ada5049edc Mon Sep 17 00:00:00 2001 From: Alexander Lang Date: Sun, 8 Jun 2025 17:26:58 +0200 Subject: [PATCH] fix querying single design doc when view name digesting is enabled was querying design doc without digest in name --- lib/couch_potato/view/view_query.rb | 51 ++++++++++++++++++----------- spec/single_design_document_spec.rb | 12 +++++++ 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/lib/couch_potato/view/view_query.rb b/lib/couch_potato/view/view_query.rb index c1eb719..acd01c3 100644 --- a/lib/couch_potato/view/view_query.rb +++ b/lib/couch_potato/view/view_query.rb @@ -25,6 +25,8 @@ def query_view!(parameters = {}) # only after clearing the cache design docs will be updated/re-created. def self.clear_cache __updated_views.clear + @all_views = nil + @all_views_digest = nil end def self.__updated_views @@ -32,53 +34,62 @@ def self.__updated_views @updated_views end + def self.all_views + @all_views ||= CouchPotato.views.flat_map do |klass| + specs = klass.views.map { |view_name, view| klass.execute_view(view_name, {}) } + specs.map do |klass_spec| + { klass_spec.view_name => view_functions(klass_spec.map_function, klass_spec.reduce_function) } + end + end.inject(&:merge) + end + + def self.all_views_digest + @all_views_digest ||= Digest::SHA256.hexdigest(all_views.to_json) + end + private def update_view - design_doc = @database.get "_design/#{@design_document_name}" rescue nil + design_doc = @database.get "_design/#{design_document_name}" rescue nil original_views = design_doc && design_doc['views'].dup view_updated design_doc ||= empty_design_document if CouchPotato::Config.single_design_document - design_doc['views'] = all_views - if CouchPotato::Config.digest_view_names - design_doc['_id'] = "_design/#{@design_document_name}-#{Digest::SHA256.hexdigest(design_doc['views'].to_json)}" - end + design_doc['views'] = self.class.all_views else - design_doc['views'][@view_name.to_s] = view_functions + design_doc['views'][@view_name.to_s] = self.class.view_functions(@map_function, @reduce_function) end if original_views != design_doc['views'] @database.save_doc(design_doc) end end - def all_views - CouchPotato.views.flat_map do |klass| - specs = klass.views.map { |view_name, view| klass.execute_view(view_name, {}) } - specs.map do |klass_spec| - { klass_spec.view_name => view_functions(klass_spec.map_function, klass_spec.reduce_function) } - end - end.inject(&:merge) - end - - def view_functions(map_function = @map_function, reduce_function = @reduce_function) + def self.view_functions(map_function, reduce_function) {'map' => map_function, 'reduce' => reduce_function}.compact end def empty_design_document - {'views' => {}, "_id" => "_design/#{@design_document_name}", "language" => @language.to_s} + {'views' => {}, "_id" => "_design/#{design_document_name}", "language" => @language.to_s} + end + + def design_document_name + name = @design_document_name + if CouchPotato::Config.digest_view_names && CouchPotato::Config.single_design_document + name += "-#{self.class.all_views_digest}" + end + name end def view_has_been_updated? if CouchPotato::Config.single_design_document updated_views.any? else - updated_views[[@design_document_name, @view_name]] + updated_views[[design_document_name, @view_name]] end end def view_updated - updated_views[[@design_document_name, @view_name]] = true + updated_views[[design_document_name, @view_name]] = true end def updated_views @@ -90,7 +101,7 @@ def query_view(parameters) end def view_url - "#{@design_document_name}/#{@view_name}" + "#{design_document_name}/#{@view_name}" end end end diff --git a/spec/single_design_document_spec.rb b/spec/single_design_document_spec.rb index 97a4e33..ef36246 100644 --- a/spec/single_design_document_spec.rb +++ b/spec/single_design_document_spec.rb @@ -30,10 +30,13 @@ class Thing3 < Thing1 # should work with inheritance recreate_db CouchPotato::Config.single_design_document = true CouchPotato.views.select! { |v| [Thing1, Thing2, Thing3].include?(v) } # clear classes from other specs + CouchPotato::View::ViewQuery.clear_cache end after(:each) do CouchPotato::Config.single_design_document = false + CouchPotato::Config.digest_view_names = false + CouchPotato::View::ViewQuery.clear_cache end it 'creates a single design document for all views' do @@ -60,4 +63,13 @@ class Thing3 < Thing1 # should work with inheritance expect(db.view(Thing2.all('n2'))).to eq([thing2]) expect(db.view(Thing3.by_tag('tag1'))).to eq([thing3]) end + + it 'queries the single design doc with digest_view_names enabled' do + CouchPotato::Config.digest_view_names = true + + thing1 = Thing1.new title: 't1' + db.save! thing1 + + expect(db.view(Thing1.all)).to(eq([thing1])) + end end