From 6ae039de5de2fbb97110845bb84db156a00c3c6a Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Tue, 6 Feb 2018 19:55:44 +1100 Subject: [PATCH] feat(matrix): speed up matrix query for latestby=cvpv and latestby=cvp --- lib/pact_broker/matrix/repository.rb | 27 ++++++++++++++++++++++----- lib/pact_broker/matrix/row.rb | 2 +- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/pact_broker/matrix/repository.rb b/lib/pact_broker/matrix/repository.rb index 6b1250124..5c8ad19d6 100644 --- a/lib/pact_broker/matrix/repository.rb +++ b/lib/pact_broker/matrix/repository.rb @@ -15,6 +15,8 @@ class Repository # TODO move latest verification logic in to database + TP_COLS = PactBroker::Matrix::Row::TP_COLS + GROUP_BY_PROVIDER_VERSION_NUMBER = [:consumer_name, :consumer_version_number, :provider_name, :provider_version_number] GROUP_BY_PROVIDER = [:consumer_name, :consumer_version_number, :provider_name] GROUP_BY_PACT = [:consumer_name, :provider_name] @@ -38,26 +40,41 @@ def find selectors, options = {} lines.sort end - def apply_latestby options, selectors, lines - return lines unless options[:latestby] == 'cvp' || options[:latestby] == 'cp' + + def apply_latestby options, selectors, lines + return lines unless options[:latestby] group_by_columns = case options[:latestby] + when 'cvpv' then GROUP_BY_PROVIDER_VERSION_NUMBER when 'cvp' then GROUP_BY_PROVIDER when 'cp' then GROUP_BY_PACT end # The group with the nil provider_version_numbers will be the results of the left outer join # that don't have verifications, so we need to include them all. - lines.group_by{|line| group_by_columns.collect{|key| line.send(key) }} + remove_overwritten_revisions(lines).group_by{|line| group_by_columns.collect{|key| line.send(key) }} .values .collect{ | lines | lines.first.provider_version_number.nil? ? lines : lines.first } .flatten end + def remove_overwritten_revisions lines + latest_revisions_keys = {} + latest_revisions = [] + lines.each do | line | + key = "#{line.consumer_name}-#{line.provider_name}-#{line.consumer_version_number}" + if !latest_revisions_keys.key?(key) || latest_revisions_keys[key] == line.pact_revision_number + latest_revisions << line + latest_revisions_keys[key] ||= line.pact_revision_number + end + end + latest_revisions + end + def find_for_consumer_and_provider pacticipant_1_name, pacticipant_2_name selectors = [{ pacticipant_name: pacticipant_1_name }, { pacticipant_name: pacticipant_2_name }] options = { latestby: 'cvpv' } - query_matrix(resolve_selectors(selectors, options), options).sort + find(selectors, options) end def find_compatible_pacticipant_versions selectors @@ -75,7 +92,7 @@ def query_matrix selectors, options end def view_for(options) - options[:latestby] ? LatestRow : Row + Row end def resolve_selectors(selectors, options) diff --git a/lib/pact_broker/matrix/row.rb b/lib/pact_broker/matrix/row.rb index a8343185f..1a7fcf995 100644 --- a/lib/pact_broker/matrix/row.rb +++ b/lib/pact_broker/matrix/row.rb @@ -7,7 +7,7 @@ module Matrix class Row < Sequel::Model(:materialized_matrix) # Used when using table_print to output query results - TP_COLS = [:consumer_id, :consumer_version_id, :provider_id, :provider_version_id] + TP_COLS = [ :consumer_version_number, :pact_revision_number, :provider_version_number, :verification_number] associate(:one_to_many, :latest_triggered_webhooks, :class => "PactBroker::Webhooks::LatestTriggeredWebhook", primary_key: :pact_publication_id, key: :pact_publication_id) associate(:one_to_many, :webhooks, :class => "PactBroker::Webhooks::Webhook", primary_key: [:consumer_id, :provider_id], key: [:consumer_id, :provider_id])