require "pact_broker/db" require "pact_broker/verifications/pseudo_branch_status" require "pact_broker/domain/verification" require "pact_broker/webhooks/latest_triggered_webhook" require "pact_broker/webhooks/webhook" module PactBroker module Integrations class Integration < Sequel::Model(Sequel::Model.db[:integrations].select(:id, :consumer_id, :provider_id)) plugin :insert_ignore, identifying_columns: [:consumer_id, :provider_id] associate(:many_to_one, :consumer, :class => "PactBroker::Domain::Pacticipant", :key => :consumer_id, :primary_key => :id) associate(:many_to_one, :provider, :class => "PactBroker::Domain::Pacticipant", :key => :provider_id, :primary_key => :id) associate(:one_to_one, :latest_verification, :class => "PactBroker::Verifications::LatestVerificationForConsumerAndProvider", key: [:consumer_id, :provider_id], primary_key: [:consumer_id, :provider_id]) associate(:one_to_many, :latest_triggered_webhooks, :class => "PactBroker::Webhooks::LatestTriggeredWebhook", key: [:consumer_id, :provider_id], primary_key: [:consumer_id, :provider_id]) # When viewing the index, every latest_pact in the database will match at least one of the rows, so # it makes sense to load the entire table and match each pact to the appropriate row. # Update: now we have pagination, we should probably filter the pacts by consumer/provider id. LATEST_PACT_EAGER_LOADER = proc do |eo_opts| eo_opts[:rows].each do |integration| integration.associations[:latest_pact] = nil end PactBroker::Pacts::PactPublication.overall_latest.each do | pact | eo_opts[:rows].each do | integration | if integration.consumer_id == pact.consumer_id && integration.provider_id == pact.provider_id integration.associations[:latest_pact] = pact end end end end one_to_one(:latest_pact, class: "PactBroker::Pacts::PactPublication", :key => [:consumer_id, :provider_id], primary_key: [:consumer_id, :provider_id], :eager_loader=> LATEST_PACT_EAGER_LOADER) do | _ds | PactBroker::Pacts::PactPublication.overall_latest_for_consumer_id_and_provider_id(consumer_id, provider_id) end # When viewing the index, every webhook in the database will match at least one of the rows, so # it makes sense to load the entire table and match each webhook to the appropriate row. # This will only work when using eager loading. The keys are just blanked out to avoid errors. # I don't understand how they work at all. # It would be nice to do this declaratively. many_to_many :webhooks, class: "PactBroker::Webhooks::Webhook", :left_key => [], left_primary_key: [], :eager_loader=>(proc do |eo_opts| eo_opts[:rows].each do |integration| integration.associations[:webhooks] = [] end PactBroker::Webhooks::Webhook.each do | webhook | eo_opts[:rows].each do | integration | if webhook.is_for?(integration) integration.associations[:webhooks] << webhook end end end end) def self.compare_by_last_action_date a, b if b.latest_pact_or_verification_publication_date && a.latest_pact_or_verification_publication_date b.latest_pact_or_verification_publication_date <=> a.latest_pact_or_verification_publication_date elsif b.latest_pact_or_verification_publication_date 1 elsif a.latest_pact_or_verification_publication_date -1 else a <=> b end end def verification_status_for_latest_pact @verification_status_for_latest_pact ||= PactBroker::Verifications::PseudoBranchStatus.new(latest_pact, latest_pact&.latest_verification) end def latest_pact_or_verification_publication_date [latest_pact&.created_at, latest_verification_publication_date].compact.max end def latest_verification_publication_date latest_verification&.execution_date end def <=>(other) [consumer_name.downcase, provider_name.downcase] <=> [other.consumer_name.downcase, other.provider_name.downcase] end def consumer_name consumer.name end def provider_name provider.name end end end end # Table: integrations # Columns: # id | integer | PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY # consumer_id | integer | NOT NULL # provider_id | integer | NOT NULL # Indexes: # integrations_pkey | PRIMARY KEY btree (id) # integrations_consumer_id_provider_id_unique | UNIQUE btree (consumer_id, provider_id) # Foreign key constraints: # integrations_consumer_id_foreign_key | (consumer_id) REFERENCES pacticipants(id) ON DELETE CASCADE # integrations_provider_id_foreign_key | (provider_id) REFERENCES pacticipants(id) ON DELETE CASCADE