Skip to content

Commit

Permalink
feat(clean): allow date to be specified for data to clean and return …
Browse files Browse the repository at this point in the history
…counts of deleted and kept rows
  • Loading branch information
bethesque committed Oct 21, 2019
1 parent 1459b46 commit 29dcbac
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 24 deletions.
83 changes: 67 additions & 16 deletions lib/pact_broker/db/clean.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,91 @@ def initialize database_connection, options = {}
end

def call
deleted_counts = {}
kept_counts = {}
date = options[:date]
pact_publication_ids_to_delete = if date
db[:pact_publications].select(:id).where(Sequel.lit('created_at < ?', date))
else
db[:pact_publications].select(:id).where(id: db[:head_matrix].select(:pact_publication_id)).invert
end

deleted_counts[:pact_publications] = pact_publication_ids_to_delete.count
kept_counts[:pact_publications] = db[:pact_publications].where(id: pact_publication_ids_to_delete).invert.count

# TODO head matrix is the head for the consumer tags, not the provider tags.
# Work out how to keep the head verifications for the provider tags.
verification_ids = db[:verifications].where(id: db[:head_matrix].select(:verification_id)).invert.select(:verification_id)

triggered_webhook_ids = db[:triggered_webhooks].where(verification_id: verification_ids).select(:id)
db[:webhook_executions].where(triggered_webhook_id: triggered_webhook_ids).delete
db[:triggered_webhooks].where(id: triggered_webhook_ids).delete
verification_ids = get_verification_ids(pact_publication_ids_to_delete)
deleted_counts[:verification_results] = verification_ids.count
kept_counts[:verification_results] = db[:verifications].where(id:verification_ids ).invert.count

delete_webhook_data(db[:triggered_webhooks].where(verification_id: verification_ids).select(:id))
verification_ids.delete

pp_ids = db[:head_matrix].select(:pact_publication_id)
delete_webhook_data(db[:triggered_webhooks].where(pact_publication_id: pact_publication_ids_to_delete).select(:id))
delete_deprecated_webhook_executions(pact_publication_ids_to_delete)
delete_pact_publications(pact_publication_ids_to_delete)

delete_orphan_pact_versions
overwritten_delete_counts = delete_overwritten_verifications
deleted_counts[:verification_results] = deleted_counts[:verification_results] + overwritten_delete_counts[:verification_results]
kept_counts[:verification_results] = kept_counts[:verification_results] - overwritten_delete_counts[:verification_results]


referenced_version_ids = db[:pact_publications].select(:consumer_version_id).collect{ | h| h[:consumer_version_id] } +
db[:verifications].select(:provider_version_id).collect{ | h| h[:provider_version_id] }

delete_orphan_tags(referenced_version_ids)
delete_orphan_versions(referenced_version_ids)

{ kept: kept_counts, deleted: deleted_counts }
end

private

attr_reader :db, :options

def get_verification_ids(pact_publication_ids)
db[:verifications].select(:id).where(pact_version_id: db[:pact_publications].select(:pact_version_id).where(id: pact_publication_ids))
end

triggered_webhook_ids = db[:triggered_webhooks].where(pact_publication_id: pp_ids).invert.select(:id)
def delete_webhook_data(triggered_webhook_ids)
db[:webhook_executions].where(triggered_webhook_id: triggered_webhook_ids).delete
db[:triggered_webhooks].where(id: triggered_webhook_ids).delete
db[:webhook_executions].where(pact_publication_id: pp_ids).invert.delete

db[:pact_publications].where(id: pp_ids).invert.delete
end

def delete_deprecated_webhook_executions(pact_publication_ids)
db[:webhook_executions].where(pact_publication_id: pact_publication_ids).delete
end

def delete_pact_publications(pact_publication_ids)
db[:pact_publications].where(id: pact_publication_ids).delete
db[:pact_versions].where(id: db[:pact_publications].select(:pact_version_id)).invert.delete
end

def delete_orphan_pact_versions
# TODO use union
referenced_pact_version_ids = db[:pact_publications].select(:pact_version_id).collect{ | h| h[:pact_version_id] } +
db[:verifications].select(:pact_version_id).collect{ | h| h[:pact_version_id] }
db[:pact_versions].where(id: referenced_pact_version_ids).invert.delete
end

referenced_version_ids = db[:pact_publications].select(:consumer_version_id).collect{ | h| h[:consumer_version_id] } +
db[:verifications].select(:provider_version_id).collect{ | h| h[:provider_version_id] }

def delete_orphan_tags(referenced_version_ids)
db[:tags].where(version_id: referenced_version_ids).invert.delete
db[:versions].where(id: referenced_version_ids).invert.delete
end

private

attr_reader :db
def delete_orphan_versions(referenced_version_ids)
db[:versions].where(id: referenced_version_ids).invert.delete
end

def delete_overwritten_verifications
verification_ids = db[:verifications].select(:id).where(id: db[:latest_verification_id_for_pact_version_and_provider_version].select(:verification_id)).invert
deleted_counts = { verification_results: verification_ids.count }
delete_webhook_data(db[:triggered_webhooks].where(verification_id: verification_ids).select(:id))
verification_ids.delete
deleted_counts
end
end
end
end
74 changes: 66 additions & 8 deletions spec/lib/pact_broker/db/clean_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

module PactBroker
module DB
describe Clean do
# Inner queries don't work on MySQL. Seriously, MySQL???
describe ".call", pending: IS_MYSQL do
let(:td) { TestDataBuilder.new }
let(:db) { PactBroker::DB.connection }
# Inner queries don't work on MySQL. Seriously, MySQL???
describe Clean, pending: IS_MYSQL do
let(:options) { {} }
let(:db) { PactBroker::DB.connection }

subject { Clean.call(PactBroker::DB.connection, options) }

describe ".call"do

before do
td.create_pact_with_hierarchy("Foo", "0", "Bar")
Expand All @@ -33,10 +36,10 @@ module DB
.create_pact
.comment("keep")
.create_verification(provider_version: "40")
.create_verification(provider_version: "50", number: 2)
.create_verification(provider_version: "40", number: 2)
.create_verification(provider_version: "50", number: 3)
end

subject { Clean.call(PactBroker::DB.connection) }

it "does not delete any rows in the head matrix" do
head_matrix_before = db[:head_matrix].select_all
Expand All @@ -59,9 +62,64 @@ module DB
subject
expect(db[:versions].where(number: "20").count).to be 1
expect(db[:versions].where(number: "30").count).to be 0
expect(db[:versions].where(number: "40").count).to be 0
expect(db[:versions].where(number: "40").count).to be 1
expect(db[:versions].where(number: "50").count).to be 1
end

it "deletes overwritten verifications" do
expect(db[:matrix].where(provider_version_number: "40").count).to eq 2
subject
expect(db[:matrix].where(provider_version_number: "40", verification_number: 2).count).to eq 1
end
end

describe ".call with a date" do
before do
td.set_now(DateTime.new(2019, 1, 1))
.create_pact_with_hierarchy
.create_verification
end
let(:options) { { date: date } }

context "when the data is older than the given date" do
let(:date) { DateTime.new(2019, 1, 2) }
let(:expected_report) do
{
kept: { pact_publications: 0, verification_results: 0 },
deleted: { pact_publications: 1, verification_results: 1 }
}
end

it "is deleted" do
subject
expect(db[:head_matrix].count).to be 0
end

it "returns a report" do
expect(subject).to include(expected_report)
end
end

context "when the data is not older than the given date" do
let(:date) { DateTime.new(2019, 1, 1) }
let(:expected_report) do
{
kept: { pact_publications: 1, verification_results: 1 },
deleted: { pact_publications: 0, verification_results: 0 }
}
end

it "is not deleted" do
subject
expect(db[:head_matrix].count).to be 1
expect(db[:pact_publications].count).to be 1
expect(db[:verifications].count).to be 1
end

it "returns a report" do
expect(subject).to include(expected_report)
end
end
end
end
end
Expand Down

0 comments on commit 29dcbac

Please sign in to comment.