module PactBroker::Matrix::MatrixRowDatasetModule

Constants

EAGER_LOADED_RELATIONSHIPS_FOR_VERSION
LAST_ACTION_DATE

Public Instance Methods

default_scope() click to toggle source

Just for testing purposes

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 45
def default_scope
  select_pact_columns_with_aliases
    .from_self(alias: :p)
    .left_outer_join_verifications
    .select_all_columns_after_join
end
eager_all_the_things() click to toggle source

eager load tags? @public

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 30
def eager_all_the_things
  eager(
    :consumer,
    :provider,
    :verification,
    :pact_publication,
    :pact_version,
    consumer_version: EAGER_LOADED_RELATIONSHIPS_FOR_VERSION,
    provider_version: EAGER_LOADED_RELATIONSHIPS_FOR_VERSION,
    consumer_version_tags: [:head_tag, { version: :pacticipant }],
    provider_version_tags: [:head_tag, { version: :pacticipant }]
  )
end
inner_join_verifications_dataset(verifications_dataset) click to toggle source

@private

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 176
def inner_join_verifications_dataset(verifications_dataset)
  join(verifications_dataset, { Sequel[:p][:pact_version_id] => Sequel[:v][:pact_version_id] }, { table_alias: :v } )
end
inner_join_versions_dataset(versions) click to toggle source

@private

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 161
def inner_join_versions_dataset(versions)
  versions_join = { Sequel[:p][:consumer_version_id] => Sequel[:versions][:id] }
  join(versions, versions_join, table_alias: :versions)
end
inner_join_versions_for_selectors_as_consumer(resolved_selectors) click to toggle source

@private

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 153
def inner_join_versions_for_selectors_as_consumer(resolved_selectors)
  # get the UnresolvedSelector objects back out of the resolved_selectors because the Version.for_selector() method uses the UnresolvedSelector
  unresolved_selectors = resolved_selectors.collect(&:original_selector).uniq
  versions = PactBroker::Domain::Version.ids_for_selectors(unresolved_selectors)
  inner_join_versions_dataset(versions)
end
left_outer_join_verifications() click to toggle source

@private

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 167
def left_outer_join_verifications
  left_outer_join_verifications_dataset(verification_dataset.select_verification_columns_with_aliases)
end
left_outer_join_verifications_dataset(verifications) click to toggle source
# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 171
def left_outer_join_verifications_dataset(verifications)
  left_outer_join(verifications, { Sequel[:p][:pact_version_id] => Sequel[:v][:pact_version_id] }, { table_alias: :v } )
end
matching_one_selector_for_either_consumer_or_provider(resolved_selectors, limit: ) click to toggle source

Final matrix query with one selector (not the normal use case) When we have one selector, we need to join ALL the verifications to find out what integrations exist @private

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 58
def matching_one_selector_for_either_consumer_or_provider(resolved_selectors, limit: )
  if resolved_selectors.size != 1
    raise ArgumentError.new("Expected one selector to be provided, but received #{resolved_selectors.size}:  #{resolved_selectors}")
  end

  # consumer
  pact_publication_matching_consumer = select_pact_columns_with_aliases.most_recent(limit).from_self(alias: :p).inner_join_versions_for_selectors_as_consumer(resolved_selectors)
  rows_where_selector_matches_consumer = pact_publication_matching_consumer.left_outer_join_verifications.select_all_columns_after_join

  # provider
  verifications_matching_provider = verification_dataset.matching_selectors_as_provider_for_any_consumer(resolved_selectors)
  rows_where_selector_matches_provider = select_pact_columns_with_aliases.most_recent(limit).from_self(alias: :p).inner_join_verifications_dataset(verifications_matching_provider).select_all_columns_after_join

  # union
  rows_where_selector_matches_consumer.union(rows_where_selector_matches_provider)
end
matching_only_selectors_as_consumer(resolved_selectors, limit: ) click to toggle source

Return pact publications where the consumer/consumer version is described by any of the resolved_selectors, AND the provider is described by any of the resolved selectors. @private @param [Array<PactBroker::Matrix::ResolvedSelector>] resolved_selectors @return [Sequel::Dataset<MatrixRow>]

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 106
def matching_only_selectors_as_consumer(resolved_selectors, limit: )
  [
    matching_only_selectors_as_consumer_where_only_pacticipant_name_in_selector(resolved_selectors, limit: limit),
    matching_only_selectors_as_consumer_where_not_only_pacticipant_name_in_selector(resolved_selectors, limit: limit),
  ].compact.reduce(&:union)
end
matching_only_selectors_as_consumer_where_not_only_pacticipant_name_in_selector(resolved_selectors, limit:) click to toggle source

Return pact publications where the consumer version is described by any of the resolved_selectors *that specify more than just the pacticipant name*, AND the provider is described by any of the resolved selectors. If the selector uses any of the tag/branch/environment/latest attributes, we need to join to the versions table to identify the required pact_publications. Return nil if there are no resolved selectors where anything other than the pacticipant name is specified. @private @param [Array<PactBroker::Matrix::ResolvedSelector>] resolved_selectors @return [Sequel::Dataset<MatrixRow>, nil]

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 140
def matching_only_selectors_as_consumer_where_not_only_pacticipant_name_in_selector(resolved_selectors, limit:)
  all_pacticipant_ids = resolved_selectors.collect(&:pacticipant_id).uniq
  resolved_selectors_with_versions_specified = resolved_selectors.reject(&:only_pacticipant_name_specified?)

  if resolved_selectors_with_versions_specified.any?
    select_pact_columns_with_aliases
      .inner_join_versions_for_selectors_as_consumer(resolved_selectors_with_versions_specified)
      .where(provider_id: all_pacticipant_ids)
      .most_recent(limit)
  end
end
matching_only_selectors_as_consumer_where_only_pacticipant_name_in_selector(resolved_selectors, limit:) click to toggle source

Return pact publications where the consumer is described by any of the resolved_selectors *that only specify the pacticipant NAME*, AND the provider is described by any of the resolved selectors. If the original selector only specified the pacticipant name, we don’t need to join to the versions table to identify the required pact_publications. Return nil if there are no resolved selectors where only the pacticipant name is specified. @private @param [Array<PactBroker::Matrix::ResolvedSelector>] resolved_selectors @return [Sequel::Dataset<MatrixRow>, nil]

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 120
def matching_only_selectors_as_consumer_where_only_pacticipant_name_in_selector(resolved_selectors, limit:)
  all_pacticipant_ids = resolved_selectors.collect(&:pacticipant_id).uniq
  pacticipant_ids_for_pacticipant_only_selectors = resolved_selectors.select(&:only_pacticipant_name_specified?).collect(&:pacticipant_id).uniq

  if pacticipant_ids_for_pacticipant_only_selectors.any?
    select_pact_columns_with_aliases
      .where(consumer_id: pacticipant_ids_for_pacticipant_only_selectors)
      .where(provider_id: all_pacticipant_ids)
      .most_recent(limit)
  end
end
matching_only_selectors_joining_verifications(resolved_selectors, limit: ) click to toggle source

Find the matrix rows When the user has specified multiple selectors, we only want to join the verifications for the specified selectors. This is because of the behaviour of the left outer join. Imagine a pact has been verified by a provider version that was NOT specified in the selectors. If we join all the verifications and THEN filter the rows to only show the versions specified in the selectors, we won’t get a row for that pact, and hence, we won’t know that it hasn’t been verified by the provider version we’re interested in. Instead, we need to filter the verifications dataset down to only the ones specified in the selectors first, and THEN join them to the pacts, so that we get a row for the pact with null provider version and verification fields. IDEA FOR OPTIMISATION - would it work to limit the pact_publications query and the verifications query to the limit of the overall query? @private @param [Array<PactBroker::Matrix::ResolvedSelector>] resolved_selectors @return [Sequel::Dataset<MatrixRow>]

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 89
def matching_only_selectors_joining_verifications(resolved_selectors, limit: )
  pact_publications = matching_only_selectors_as_consumer(resolved_selectors, limit: limit)
  verifications = verification_dataset.matching_only_selectors_as_provider(resolved_selectors)

  specified_pacticipant_ids = resolved_selectors.select(&:specified?).collect(&:pacticipant_id).uniq

  pact_publications
    .from_self(alias: :p)
    .select_all_columns_after_join
    .left_outer_join_verifications_dataset(verifications)
    .where(consumer_id: specified_pacticipant_ids).or(provider_id: specified_pacticipant_ids)
end
matching_selectors(resolved_selectors, limit:) click to toggle source

The matrix query used to determine the final dataset @param [Array<PactBroker::Matrix::ResolvedSelector>] resolved_selectors

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 15
def matching_selectors(resolved_selectors, limit:)
  if resolved_selectors.size == 1
    matching_one_selector_for_either_consumer_or_provider(resolved_selectors, limit: limit)
  else
    matching_only_selectors_joining_verifications(resolved_selectors, limit: limit)
  end
end
most_recent(limit) click to toggle source
# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 180
def most_recent(limit)
  order(Sequel.desc(:created_at)).limit(limit)
end
order_by_last_action_date() click to toggle source

@public

# File lib/pact_broker/matrix/matrix_row_dataset_module.rb, line 24
def order_by_last_action_date
  from_self(alias: :unordered_rows).select(LAST_ACTION_DATE, Sequel[:unordered_rows].* ).order(Sequel.desc(:last_action_date), Sequel.desc(:pact_order), Sequel.desc(:verification_id))
end