Skip to content

Commit e366af4

Browse files
committed
feat: include more columns in latest_verifications_for_consumer_version_tags to avoid having to do extra queries for pact_versions and provider_versions
1 parent ee4e93d commit e366af4

6 files changed

+79
-36
lines changed

db/migrations/20180523_create_latest_verifications_for_consumer_version_tags.rb

+30-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
up do
33
# The latest verification id for each consumer version tag
44
create_view(:latest_verifications_ids_for_consumer_version_tags,
5-
"select pv.pacticipant_id as provider_id, lpp.consumer_id, t.name as consumer_version_tag_name, max(v.id) as latest_verification_id
5+
"select
6+
pv.pacticipant_id as provider_id,
7+
lpp.consumer_id,
8+
t.name as consumer_version_tag_name,
9+
max(v.id) as latest_verification_id
610
from verifications v
711
join latest_pact_publications_by_consumer_versions lpp
812
on v.pact_version_id = lpp.pact_version_id
@@ -12,12 +16,31 @@
1216
on v.provider_version_id = pv.id
1317
group by pv.pacticipant_id, lpp.consumer_id, t.name")
1418

15-
# The latest verification for each consumer version tag
16-
create_view(:latest_verifications_for_consumer_version_tags,
17-
"select v.*, lv.provider_id, lv.consumer_id, lv.consumer_version_tag_name
18-
from verifications v
19-
join latest_verifications_ids_for_consumer_version_tags lv
20-
on lv.latest_verification_id = v.id")
19+
# The most recent verification for each consumer/consumer version tag/provider
20+
latest_verifications = from(:verifications)
21+
.select(
22+
Sequel[:lv][:consumer_id],
23+
Sequel[:lv][:provider_id],
24+
Sequel[:lv][:consumer_version_tag_name],
25+
Sequel[:pv][:sha].as(:pact_version_sha),
26+
Sequel[:prv][:number].as(:provider_version_number),
27+
Sequel[:prv][:order].as(:provider_version_order),
28+
)
29+
.select_append{ verifications.* }
30+
.join(:latest_verifications_ids_for_consumer_version_tags,
31+
{
32+
Sequel[:verifications][:id] => Sequel[:lv][:latest_verification_id],
33+
}, { table_alias: :lv })
34+
.join(:versions,
35+
{
36+
Sequel[:verifications][:provider_version_id] => Sequel[:prv][:id]
37+
}, { table_alias: :prv })
38+
.join(:pact_versions,
39+
{
40+
Sequel[:verifications][:pact_version_id] => Sequel[:pv][:id]
41+
}, { table_alias: :pv })
42+
43+
create_or_replace_view(:latest_verifications_for_consumer_version_tags, latest_verifications)
2144
end
2245

2346
down do

lib/pact_broker/index/service.rb

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def self.find_index_items options = {}
1919
.eager(:latest_triggered_webhooks)
2020
.eager(:webhooks)
2121
.order(:consumer_name, :provider_name)
22-
.eager(:verification)
22+
#.eager(verification: [:provider_version, :pact_version])
2323

2424
if !options[:tags]
2525
rows = rows.where(consumer_version_tag_name: nil)
@@ -34,12 +34,13 @@ def self.find_index_items options = {}
3434
rows = rows.all.group_by(&:pact_publication_id).values.collect{ | rows| Matrix::AggregatedRow.new(rows) }
3535

3636
rows.sort.collect do | row |
37+
# TODO simplify
3738
PactBroker::Domain::IndexItem.create(
3839
row.consumer,
3940
row.provider,
4041
row.pact,
4142
row.overall_latest?,
42-
options[:tags] ? row.latest_verification : row.verification,
43+
row.latest_verification,
4344
row.webhooks,
4445
row.latest_triggered_webhooks,
4546
options[:tags] ? row.consumer_head_tag_names : [],

lib/pact_broker/matrix/aggregated_row.rb

+22-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# A collection of matrix rows with the same pact publication id
44
# It's basically a normalised view of a denormalised view :(
5-
5+
# A pact publication may be the overall latest, and/or the latest for a tag
66
module PactBroker
77
module Matrix
88
class AggregatedRow
@@ -13,7 +13,6 @@ class AggregatedRow
1313
delegate [:pact, :pact_version, :pact_revision_number, :webhooks, :latest_triggered_webhooks, :'<=>'] => :first_row
1414
delegate [:verification_id, :verification] => :first_row
1515

16-
1716
def initialize matrix_rows
1817
@matrix_rows = matrix_rows
1918
@first_row = matrix_rows.first
@@ -23,20 +22,26 @@ def overall_latest?
2322
!!matrix_rows.find{ | row| row.consumer_version_tag_name.nil? }
2423
end
2524

25+
# If this comes back nil, it won't be "cached", but it's a reasonably
26+
# quick query, so it's probably ok.
2627
def latest_verification
2728
@latest_verification ||= begin
2829
verification = matrix_rows.collect do | row|
29-
row.verification || row.latest_verification_for_consumer_version_tag
30-
end.compact.sort{ |v1, v2| v1.id <=> v2.id}.last
30+
row.verification || latest_verification_for_consumer_version_tag(row)
31+
end.compact.sort{ |v1, v2| v1.id <=> v2.id }.last
3132

3233
if !verification && overall_latest?
33-
PactBroker::Verifications::Repository.new.find_latest_verification_for(consumer_name, provider_name)
34+
overall_latest_verification
3435
else
3536
verification
3637
end
3738
end
3839
end
3940

41+
# The list of tag names for which this pact publication is the most recent with that tag
42+
# There could, however, be a later consumer version that does't have a pact (perhaps because it was deleted)
43+
# that has the same tag.
44+
# TODO show a warning when the data is "corrupted" as above.
4045
def consumer_head_tag_names
4146
matrix_rows.collect(&:consumer_version_tag_name).compact
4247
end
@@ -45,6 +50,18 @@ def consumer_head_tag_names
4550

4651
attr_reader :matrix_rows
4752

53+
def latest_verification_for_consumer_version_tag row
54+
row.latest_verification_for_consumer_version_tag if row.consumer_version_tag_name
55+
end
56+
57+
def overall_latest_verification
58+
# This causes the
59+
# SELECT "latest_verifications".* FROM "latest_verifications"
60+
# query in the logs for the tagged index.
61+
# Given it only happens rarely, it's ok to not lazy load it.
62+
PactBroker::Verifications::Repository.new.find_latest_verification_for(consumer_name, provider_name)
63+
end
64+
4865
def first_row
4966
@first_row
5067
end

lib/pact_broker/matrix/head_row.rb

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class HeadRow < Row
2121
tag_to_row = eo_opts[:rows].each_with_object({}) { | row, map | map[[row.provider_id, row.consumer_id, row.consumer_version_tag_name]] = row }
2222
eo_opts[:rows].each{|row| row.associations[:latest_verification_for_consumer_version_tag] = nil}
2323

24+
# Need the all then the each to ensure the eager loading works
2425
PactBroker::Verifications::LatestVerificationForConsumerVersionTag.each do | verification |
2526
key = [verification.provider_id, verification.consumer_id, verification.consumer_version_tag_name]
2627
if tag_to_row[key]

lib/pact_broker/matrix/row.rb

+8-21
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ class Row < Sequel::Model(:materialized_matrix)
1616
associate(:one_to_many, :webhooks, :class => "PactBroker::Webhooks::Webhook", primary_key: [:consumer_id, :provider_id], key: [:consumer_id, :provider_id])
1717
associate(:one_to_many, :consumer_version_tags, :class => "PactBroker::Tags::TagWithLatestFlag", primary_key: :consumer_version_id, key: :version_id)
1818
associate(:one_to_many, :provider_version_tags, :class => "PactBroker::Tags::TagWithLatestFlag", primary_key: :provider_version_id, key: :version_id)
19-
associate(:many_to_one, :verification, :class => "PactBroker::Domain::Verification", primary_key: :id, key: :verification_id)
2019

2120
dataset_module do
2221
include PactBroker::Repositories::Helpers
@@ -114,20 +113,6 @@ def [] key
114113
end
115114
end
116115

117-
# tags for which this pact publication is the latest of that tag
118-
# this is set in the code rather than the database
119-
def consumer_head_tag_names
120-
@consumer_head_tag_names ||= []
121-
end
122-
123-
def consumer_head_tag_names= consumer_head_tag_names
124-
@consumer_head_tag_names = consumer_head_tag_names
125-
end
126-
127-
# def latest_triggered_webhooks
128-
# @latest_triggered_webhooks ||= []
129-
# end
130-
131116
def summary
132117
"#{consumer_name}#{consumer_version_number} #{provider_name}#{provider_version_number || '?'} (r#{pact_revision_number}n#{verification_number || '?'})"
133118
end
@@ -141,17 +126,18 @@ def provider
141126
end
142127

143128
def consumer_version
144-
@consumer_version ||= OpenStruct.new(number: consumer_version_number, id: consumer_version_id, pacticipant: consumer)
129+
@consumer_version ||= OpenStruct.new(number: consumer_version_number, order: consumer_version_order, id: consumer_version_id, pacticipant: consumer)
145130
end
146131

147132
def provider_version
148133
if provider_version_number
149-
@provider_version ||= OpenStruct.new(number: provider_version_number, id: provider_version_id, pacticipant: provider)
134+
@provider_version ||= OpenStruct.new(number: provider_version_number, order: provider_version_order, id: provider_version_id, pacticipant: provider)
150135
end
151136
end
152137

153138
def pact
154-
@pact ||= OpenStruct.new(consumer: consumer,
139+
@pact ||= OpenStruct.new(
140+
consumer: consumer,
155141
provider: provider,
156142
consumer_version: consumer_version,
157143
consumer_version_number: consumer_version_number,
@@ -161,7 +147,7 @@ def pact
161147
)
162148
end
163149

164-
def latest_verification
150+
def verification
165151
if verification_executed_at
166152
@latest_verification ||= OpenStruct.new(
167153
id: verification_id,
@@ -170,10 +156,12 @@ def latest_verification
170156
execution_date: verification_executed_at,
171157
created_at: verification_executed_at,
172158
provider_version_number: provider_version_number,
159+
provider_version_order: provider_version_order,
173160
build_url: verification_build_url,
174161
provider_version: provider_version,
175162
consumer_name: consumer_name,
176-
provider_name: provider_name
163+
provider_name: provider_name,
164+
pact_version_sha: pact_version_sha
177165
)
178166
end
179167
end
@@ -190,7 +178,6 @@ def <=> other
190178
]
191179

192180
comparisons.find{|c| c != 0 } || 0
193-
194181
end
195182

196183
def compare_name_asc name1, name2

lib/pact_broker/verifications/latest_verification_for_consumer_version_tag.rb

+15-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@ module PactBroker
44
module Verifications
55
class LatestVerificationForConsumerVersionTag < PactBroker::Domain::Verification
66
set_dataset(:latest_verifications_for_consumer_version_tags)
7+
8+
def pact_version_sha
9+
# Don't need to load the pact_version as we do in the superclass,
10+
# as pact_version_sha is included in the view for convenience
11+
values[:pact_version_sha]
12+
end
13+
14+
def provider_version_number
15+
values[:provider_version_number]
16+
end
17+
18+
def provider_version_order
19+
values[:provider_version_order]
20+
end
721
end
822
end
9-
end
23+
end

0 commit comments

Comments
 (0)