require "date" require "sequel" module PactBroker module DB class DeleteOverwrittenData def self.call database_connection, options = {} new(database_connection, options).call end def initialize database_connection, options = {} @db = database_connection @options = options @cut_off_date = options[:max_age] ? (DateTime.now - options[:max_age]) : DateTime.now @limit = options[:limit] || 1000 end def call require "pact_broker/pacts/pact_publication" require "pact_broker/domain/verification" deleted_counts = {} kept_counts = {} deleted_counts.merge!(delete_overwritten_pact_publications) deleted_counts.merge!(delete_overwritten_verifications) deleted_counts.merge!(delete_orphan_pact_versions) deleted_counts.merge!(delete_webhook_data) kept_counts[:pact_publications] = db[:pact_publications].count kept_counts[:verification_results] = db[:verifications].count kept_counts[:pact_versions] = db[:pact_versions].count kept_counts[:triggered_webhooks] = db[:triggered_webhooks].count if dry_run? to_keep = deleted_counts.keys.each_with_object({}) do | table_name, new_counts | new_counts[table_name] = kept_counts[table_name] - deleted_counts[table_name] end deleted_counts.each_with_object({}) do | (key, value), new_hash | new_hash[key] = { toDelete: value, toKeep: to_keep[key] } end else deleted_counts.each_with_object({}) do | (key, value), new_hash | new_hash[key] = { deleted: value, kept: kept_counts[key] } end end end private attr_reader :db, :options, :cut_off_date, :limit def dry_run? options[:dry_run] end def delete_webhook_data ltw_join = { Sequel[:triggered_webhooks][:id] => Sequel[:ltw][:id] } resolved_ids_to_delete = db[:triggered_webhooks] .select(Sequel[:triggered_webhooks][:id]) .left_join(:latest_triggered_webhooks, ltw_join, { table_alias: :ltw }) .where(Sequel[:ltw][:id] => nil) .where(Sequel.lit("triggered_webhooks.created_at < ?", cut_off_date)) .order(Sequel[:triggered_webhooks][:id]) .limit(limit) .collect{ |row| row[:id] } PactBroker::Webhooks::TriggeredWebhook.where(id: resolved_ids_to_delete).delete unless dry_run? { triggered_webhooks: resolved_ids_to_delete.count } end def delete_orphan_pact_versions referenced_pact_version_ids = db[:pact_publications].select(:pact_version_id).union(db[:verifications].select(:pact_version_id)) rpv_join = { Sequel[:pact_versions][:id] => Sequel[:rpv][:pact_version_id] } pact_version_ids_to_delete = db[:pact_versions] .select(Sequel[:pact_versions][:id]) .left_join(referenced_pact_version_ids, rpv_join, { table_alias: :rpv }) .where(Sequel[:rpv][:pact_version_id] => nil) .order(Sequel[:pact_versions][:id]) .limit(limit) .collect{ |row| row[:id] } db[:pact_versions].where(id: pact_version_ids_to_delete).delete unless dry_run? { pact_versions: pact_version_ids_to_delete.count } end def delete_overwritten_pact_publications lp_join = { Sequel[:pact_publications][:id] => Sequel[:lp][:pact_publication_id] } resolved_ids_to_delete = db[:pact_publications] .select(Sequel[:pact_publications][:id]) .left_join(:latest_pact_publication_ids_for_consumer_versions, lp_join, { table_alias: :lp }) .where(Sequel[:lp][:pact_publication_id] => nil) .where(Sequel.lit("pact_publications.created_at < ?", cut_off_date)) .order(:id) .limit(limit) .collect{ |row| row[:id] } PactBroker::Pacts::PactPublication.where(id: resolved_ids_to_delete).delete unless dry_run? { pact_publications: resolved_ids_to_delete.count } end def delete_overwritten_verifications lv_join = { Sequel[:verifications][:id] => Sequel[:lv][:verification_id] } resolved_ids_to_delete = db[:verifications] .select(Sequel[:verifications][:id]) .left_join(:latest_verification_id_for_pact_version_and_provider_version, lv_join, { table_alias: :lv}) .where(Sequel[:lv][:verification_id] => nil) .where(Sequel.lit("verifications.created_at < ?", cut_off_date)) .order(Sequel[:verifications][:id]) .limit(limit) .collect{ |row| row[:id] } PactBroker::Domain::Verification.where(id: resolved_ids_to_delete).delete unless dry_run? { verification_results: resolved_ids_to_delete.count } end end end end