Module: PactBroker::Matrix::MatrixRowDatasetModule
- Defined in:
- lib/pact_broker/matrix/matrix_row_dataset_module.rb
Constant Summary collapse
- EAGER_LOADED_RELATIONSHIPS_FOR_VERSION =
{ current_deployed_versions: :environment, current_supported_released_versions: :environment, branch_versions: [:branch_head, :version, branch: :pacticipant] }
- LAST_ACTION_DATE =
Sequel.lit("CASE WHEN (provider_version_created_at IS NOT NULL AND provider_version_created_at > consumer_version_created_at) THEN provider_version_created_at ELSE consumer_version_created_at END").as(:last_action_date)
Instance Method Summary collapse
- #consumer_criteria_for_selectors(resolved_selectors) ⇒ Array<Hash>
-
#default_scope ⇒ Object
Just for testing purposes.
-
#eager_all_the_things ⇒ Object
eager load tags?.
- #inner_join_verifications_dataset(verifications_dataset) ⇒ Object
- #left_outer_join_verifications ⇒ Object
- #left_outer_join_verifications_dataset(verifications) ⇒ Object
-
#matching_one_selector_for_either_consumer_or_provider(resolved_selectors, limit:) ⇒ Object
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.
-
#matching_only_selectors_as_consumer(resolved_selectors, limit:) ⇒ Sequel::Dataset<MatrixRow>
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.
-
#matching_only_selectors_as_consumer_where_not_only_pacticipant_name_in_selector(resolved_selectors, limit:) ⇒ Sequel::Dataset<MatrixRow>?
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.
-
#matching_only_selectors_as_consumer_where_only_pacticipant_name_in_selector(resolved_selectors, limit:) ⇒ Sequel::Dataset<MatrixRow>?
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.
-
#matching_only_selectors_joining_verifications(resolved_selectors, limit:) ⇒ Sequel::Dataset<MatrixRow>
Find the matrix rows When the user has specified multiple selectors, we only want to join the verifications for the specified selectors.
-
#matching_selectors(resolved_selectors, limit:) ⇒ Object
The matrix query used to determine the final dataset.
- #most_recent(limit) ⇒ Object
- #order_by_last_action_date ⇒ Object
-
#where_consumer_version_matches_selectors(resolved_selectors) ⇒ Object
Name-only selectors carry no version ID — matching_one_selector_for_either_consumer_or_provider passes its selectors unfiltered — so they filter on the pacticipant instead.
Instance Method Details
#consumer_criteria_for_selectors(resolved_selectors) ⇒ Array<Hash>
175 176 177 178 179 180 181 182 |
# File 'lib/pact_broker/matrix/matrix_row_dataset_module.rb', line 175 def consumer_criteria_for_selectors(resolved_selectors) name_only, with_versions = resolved_selectors.partition(&:only_pacticipant_name_specified?) criteria = [] criteria << { Sequel[:p][:consumer_id] => name_only.collect(&:pacticipant_id).uniq } if name_only.any? criteria << { Sequel[:p][:consumer_version_id] => with_versions.collect(&:pacticipant_version_id).uniq } if with_versions.any? criteria end |
#default_scope ⇒ Object
Just for testing purposes
45 46 47 48 49 50 |
# 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 ⇒ Object
eager load tags?
30 31 32 33 34 35 36 37 38 39 40 41 42 |
# 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) ⇒ Object
194 195 196 |
# File 'lib/pact_broker/matrix/matrix_row_dataset_module.rb', line 194 def inner_join_verifications_dataset(verifications_dataset) join(verifications_dataset, { Sequel[:p][:pact_version_id] => Sequel[:v][:pact_version_id] }, { table_alias: :v } ) end |
#left_outer_join_verifications ⇒ Object
185 186 187 |
# File 'lib/pact_broker/matrix/matrix_row_dataset_module.rb', line 185 def left_outer_join_verifications left_outer_join_verifications_dataset(verification_dataset.select_verification_columns_with_aliases) end |
#left_outer_join_verifications_dataset(verifications) ⇒ Object
189 190 191 |
# File 'lib/pact_broker/matrix/matrix_row_dataset_module.rb', line 189 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:) ⇒ Object
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
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# 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) .where_consumer_version_matches_selectors(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:) ⇒ Sequel::Dataset<MatrixRow>
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.
111 112 113 114 115 116 |
# File 'lib/pact_broker/matrix/matrix_row_dataset_module.rb', line 111 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:) ⇒ Sequel::Dataset<MatrixRow>?
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.
145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/pact_broker/matrix/matrix_row_dataset_module.rb', line 145 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 .where_consumer_version_matches_selectors(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:) ⇒ Sequel::Dataset<MatrixRow>?
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.
125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/pact_broker/matrix/matrix_row_dataset_module.rb', line 125 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:) ⇒ Sequel::Dataset<MatrixRow>
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?
94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/pact_broker/matrix/matrix_row_dataset_module.rb', line 94 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:) ⇒ Object
The matrix query used to determine the final dataset
15 16 17 18 19 20 21 |
# 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) ⇒ Object
198 199 200 |
# File 'lib/pact_broker/matrix/matrix_row_dataset_module.rb', line 198 def most_recent(limit) order(Sequel.desc(:created_at)).limit(limit) end |
#order_by_last_action_date ⇒ Object
24 25 26 |
# 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 |
#where_consumer_version_matches_selectors(resolved_selectors) ⇒ Object
Name-only selectors carry no version ID — matching_one_selector_for_either_consumer_or_provider passes its selectors unfiltered — so they filter on the pacticipant instead. That identifies the same rows, because a pact publication's consumer_id is the pacticipant_id of its consumer_version.
163 164 165 166 167 168 169 170 |
# File 'lib/pact_broker/matrix/matrix_row_dataset_module.rb', line 163 def where_consumer_version_matches_selectors(resolved_selectors) if resolved_selectors.empty? raise ArgumentError.new("resolved_selectors must not be empty") end criteria = consumer_criteria_for_selectors(resolved_selectors) where(criteria.size > 1 ? Sequel.|(*criteria) : criteria.first) end |