From e6db2310eb11a3fc8c3a5e6fdf5f89caf9af8f9a Mon Sep 17 00:00:00 2001 From: Nat Date: Thu, 11 Jul 2024 18:18:40 +0800 Subject: [PATCH] DEV: Move OnceOff to a post migration of the same date --- app/jobs/onceoff/voting_ensure_consistency.rb | 94 ------------------- .../20200817111111_ensure_consistency.rb | 86 +++++++++++++++++ spec/ensure_consistency_spec.rb | 9 +- 3 files changed, 91 insertions(+), 98 deletions(-) delete mode 100644 app/jobs/onceoff/voting_ensure_consistency.rb create mode 100644 db/post_migrate/20200817111111_ensure_consistency.rb diff --git a/app/jobs/onceoff/voting_ensure_consistency.rb b/app/jobs/onceoff/voting_ensure_consistency.rb deleted file mode 100644 index 13165bae..00000000 --- a/app/jobs/onceoff/voting_ensure_consistency.rb +++ /dev/null @@ -1,94 +0,0 @@ -# frozen_string_literal: true - -module Jobs - class VotingEnsureConsistency < ::Jobs::Onceoff - def execute_onceoff(args) - # archive votes to closed or archived or deleted topics - DB.exec(<<~SQL) - UPDATE discourse_voting_votes - SET archive=true - FROM topics - WHERE topics.id = discourse_voting_votes.topic_id - AND discourse_voting_votes.archive IS NOT TRUE - AND (topics.closed OR topics.archived OR topics.deleted_at IS NOT NULL) - SQL - - # un-archive votes to open topics - DB.exec(<<~SQL) - UPDATE discourse_voting_votes - SET archive=false - FROM topics - WHERE topics.id = discourse_voting_votes.topic_id - AND discourse_voting_votes.archive IS TRUE - AND NOT topics.closed - AND NOT topics.archived - AND topics.deleted_at IS NULL - SQL - - # delete duplicate votes - DB.exec(<<~SQL) - DELETE FROM discourse_voting_votes dvv1 - USING discourse_voting_votes dvv2 - WHERE dvv1.id < dvv2.id AND - dvv1.user_id = dvv2.user_id AND - dvv1.topic_id = dvv2.topic_id AND - dvv1.archive = dvv2.archive - SQL - - # delete votes associated with no user - DB.exec(<<~SQL) - DELETE FROM discourse_voting_votes - WHERE user_id NOT IN (SELECT id FROM users) - SQL - - # delete votes associated with no topics - DB.exec(<<~SQL) - DELETE FROM discourse_voting_votes - WHERE discourse_voting_votes.topic_id IS NULL - SQL - - # delete duplicate vote counts for topics - DB.exec(<<~SQL) - DELETE FROM discourse_voting_topic_vote_count dvtvc - USING discourse_voting_topic_vote_count dvtvc2 - WHERE dvtvc.id < dvtvc2.id AND - dvtvc.topic_id = dvtvc2.topic_id AND - dvtvc.votes_count = dvtvc2.votes_count - SQL - - # insert missing vote counts for topics - # ensures we have "something" for every topic with votes - DB.exec(<<~SQL) - WITH missing_ids AS ( - SELECT DISTINCT t.id FROM topics t - JOIN discourse_voting_votes dvv ON t.id = dvv.topic_id - LEFT JOIN discourse_voting_topic_vote_count dvtvc ON t.id = dvtvc.topic_id - WHERE dvtvc.topic_id IS NULL - ) - INSERT INTO discourse_voting_topic_vote_count (votes_count, topic_id, created_at, updated_at) - SELECT '0', id, now(), now() FROM missing_ids - SQL - - # remove all superflous vote count custom fields - DB.exec(<<~SQL) - DELETE FROM discourse_voting_topic_vote_count - WHERE topic_id IN ( - SELECT t1.id FROM topics t1 - LEFT JOIN discourse_voting_votes dvv - ON dvv.topic_id = t1.id - WHERE dvv.id IS NULL - ) - SQL - - # correct topics vote counts - DB.exec(<<~SQL) - UPDATE discourse_voting_topic_vote_count dvtvc - SET votes_count = ( - SELECT COUNT(*) FROM discourse_voting_votes dvv - WHERE dvtvc.topic_id = dvv.topic_id - GROUP BY dvv.topic_id - ) - SQL - end - end -end diff --git a/db/post_migrate/20200817111111_ensure_consistency.rb b/db/post_migrate/20200817111111_ensure_consistency.rb new file mode 100644 index 00000000..49c4145c --- /dev/null +++ b/db/post_migrate/20200817111111_ensure_consistency.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +class EnsureConsistency < ActiveRecord::Migration[7.0] + def up + # un-archive votes to open topics + DB.exec(<<~SQL) + UPDATE discourse_voting_votes + SET archive=false + FROM topics + WHERE topics.id = discourse_voting_votes.topic_id + AND discourse_voting_votes.archive IS TRUE + AND NOT topics.closed + AND NOT topics.archived + AND topics.deleted_at IS NULL + SQL + + # delete duplicate votes + DB.exec(<<~SQL) + DELETE FROM discourse_voting_votes dvv1 + USING discourse_voting_votes dvv2 + WHERE dvv1.id < dvv2.id AND + dvv1.user_id = dvv2.user_id AND + dvv1.topic_id = dvv2.topic_id AND + dvv1.archive = dvv2.archive + SQL + + # delete votes associated with no user + DB.exec(<<~SQL) + DELETE FROM discourse_voting_votes + WHERE user_id NOT IN (SELECT id FROM users) + SQL + + # delete votes associated with no topics + DB.exec(<<~SQL) + DELETE FROM discourse_voting_votes + WHERE discourse_voting_votes.topic_id IS NULL + SQL + + # delete duplicate vote counts for topics + DB.exec(<<~SQL) + DELETE FROM discourse_voting_topic_vote_count dvtvc + USING discourse_voting_topic_vote_count dvtvc2 + WHERE dvtvc.id < dvtvc2.id AND + dvtvc.topic_id = dvtvc2.topic_id AND + dvtvc.votes_count = dvtvc2.votes_count + SQL + + # insert missing vote counts for topics + # ensures we have "something" for every topic with votes + DB.exec(<<~SQL) + WITH missing_ids AS ( + SELECT DISTINCT t.id FROM topics t + JOIN discourse_voting_votes dvv ON t.id = dvv.topic_id + LEFT JOIN discourse_voting_topic_vote_count dvtvc ON t.id = dvtvc.topic_id + WHERE dvtvc.topic_id IS NULL + ) + INSERT INTO discourse_voting_topic_vote_count (votes_count, topic_id, created_at, updated_at) + SELECT '0', id, now(), now() FROM missing_ids + SQL + + # remove all superflous vote count custom fields + DB.exec(<<~SQL) + DELETE FROM discourse_voting_topic_vote_count + WHERE topic_id IN ( + SELECT t1.id FROM topics t1 + LEFT JOIN discourse_voting_votes dvv + ON dvv.topic_id = t1.id + WHERE dvv.id IS NULL + ) + SQL + + # correct topics vote counts + DB.exec(<<~SQL) + UPDATE discourse_voting_topic_vote_count dvtvc + SET votes_count = ( + SELECT COUNT(*) FROM discourse_voting_votes dvv + WHERE dvtvc.topic_id = dvv.topic_id + GROUP BY dvv.topic_id + ) + SQL + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/spec/ensure_consistency_spec.rb b/spec/ensure_consistency_spec.rb index b980029a..23d78be0 100644 --- a/spec/ensure_consistency_spec.rb +++ b/spec/ensure_consistency_spec.rb @@ -1,10 +1,11 @@ # frozen_string_literal: true require "rails_helper" +require Rails.root.join( + "plugins/discourse-topic-voting/db/post_migrate/20200817111111_ensure_consistency.rb", + ) -describe Jobs::VotingEnsureConsistency do - subject(:job) { described_class.new } - +describe EnsureConsistency do it "ensures consistency" do user = Fabricate(:user) user2 = Fabricate(:user) @@ -24,7 +25,7 @@ DiscourseTopicVoting::Vote.create!(user: user, topic: two_vote_topic, archive: true) DiscourseTopicVoting::Vote.create!(user: user2, topic: two_vote_topic) - job.execute_onceoff(nil) + EnsureConsistency.new.up no_vote_topic.reload