Skip to content

Commit

Permalink
feat: optimise query to find head tags for a pact
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Nov 27, 2020
1 parent fb4e28c commit 67309e3
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 13 deletions.
48 changes: 40 additions & 8 deletions lib/pact_broker/domain/tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,59 @@
require 'pact_broker/repositories/helpers'

module PactBroker

module Domain
class Tag < Sequel::Model
plugin :timestamps, update_on_create: true
plugin :insert_ignore, identifying_columns: [:name, :version_id]

unrestrict_primary_key
associate(:many_to_one, :version, :class => "PactBroker::Domain::Version", :key => :version_id, :primary_key => :id)

dataset_module do
include PactBroker::Repositories::Helpers
end

plugin :insert_ignore, identifying_columns: [:name, :version_id]
def head_tags_for_consumer_id(consumer_id)
lp = :latest_pact_publication_ids_for_consumer_versions
tags_versions_join = {
Sequel[:tags][:version_id] => Sequel[:versions][:id],
Sequel[:versions][:pacticipant_id] => consumer_id
}

unrestrict_primary_key
versions_pact_publications_join = {
Sequel[:versions][:id] => Sequel[lp][:consumer_version_id],
Sequel[lp][:consumer_id] => consumer_id
}
# head tags for this consumer
# the latest tag, pacticipant_id, version order
# for versions that have a pact publication
PactBroker::Domain::Tag
.select_group(Sequel[:tags][:name], Sequel[:versions][:pacticipant_id])
.select_append{ max(order).as(latest_consumer_version_order) }
.join(:versions, tags_versions_join)
.join(lp, versions_pact_publications_join)
end

associate(:many_to_one, :version, :class => "PactBroker::Domain::Version", :key => :version_id, :primary_key => :id)
def head_tags_for_pact_publication(pact_publication)
head_tags_versions_join = {
Sequel[:head_tags][:latest_consumer_version_order] => Sequel[:versions][:order],
Sequel[:head_tags][:pacticipant_id] => Sequel[:versions][:pacticipant_id],
Sequel[:versions][:pacticipant_id] => pact_publication.consumer_id
}

# Find the head tags that belong to this pact publication
# Note: The tag model has the name and version_id,
# but does not have the created_at value set - but don't need it for now
head_tags_for_consumer_id(pact_publication.consumer_id).from_self(alias: :head_tags)
.select(Sequel[:head_tags][:name], Sequel[:versions][:id].as(:version_id))
.join(:versions, head_tags_versions_join)
.where(Sequel[:versions][:id] => pact_publication.consumer_version_id)
end
end

def <=> other
name <=> other.name
end

end

Tag.plugin :timestamps, :update_on_create=>true
end
end

Expand Down
4 changes: 1 addition & 3 deletions lib/pact_broker/pacts/all_pact_publications.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,7 @@ def to_domain_without_tags
end

def head_tag_names
# Avoid circular dependency
require 'pact_broker/pacts/latest_tagged_pact_publications'
@head_tag_names ||= LatestTaggedPactPublications.where(id: id).select(:tag_name).collect{|t| t[:tag_name]}
@head_tag_names ||= PactBroker::Domain::Tag.head_tags_for_pact_publication(self).collect(&:name)
end

def to_domain_with_content
Expand Down
2 changes: 1 addition & 1 deletion lib/pact_broker/pacts/pact_publication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def before_create
# The names of the tags for which this pact is the latest pact with that tag
# (ie. it is not necessarily the pact for the latest consumer version with the given tag)
def head_tag_names
LatestTaggedPactPublications.where(id: id).select(:tag_name).collect{|t| t[:tag_name]}
@head_tag_names ||= PactBroker::Domain::Tag.head_tags_for_pact_publication(self).collect(&:name)
end

def consumer_version_tags
Expand Down
4 changes: 3 additions & 1 deletion spec/lib/pact_broker/pacts/pact_publication_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,11 @@ module Pacts
.create_pact
.create_consumer_version("5.6.7")
.create_consumer_version_tag("no")
.create_consumer("Foo2")
.create_consumer_version("3.4.5")
.create_consumer_version_tag("yes", comment: "actually no, just here to make sure it selects the right one")
end

let(:td) { TestDataBuilder.new }
let(:pact_publication) { PactPublication.find(id: td.pact.id) }

context "when the pact is the latest for a tag" do
Expand Down

0 comments on commit 67309e3

Please sign in to comment.