diff --git a/db/migrate/20250318024953_copy_solved_topic_custom_field_to_discourse_solved_solved_topics.rb b/db/migrate/20250318024953_copy_solved_topic_custom_field_to_discourse_solved_solved_topics.rb index 6633fda..a76d2b2 100644 --- a/db/migrate/20250318024953_copy_solved_topic_custom_field_to_discourse_solved_solved_topics.rb +++ b/db/migrate/20250318024953_copy_solved_topic_custom_field_to_discourse_solved_solved_topics.rb @@ -3,12 +3,18 @@ class CopySolvedTopicCustomFieldToDiscourseSolvedSolvedTopics < ActiveRecord::Migration[7.2] disable_ddl_transaction! - BATCH_SIZE = 5000 + BATCH_SIZE = 10_000 def up + max_id = + DB.query_single( + "SELECT MAX(id) FROM topic_custom_fields WHERE topic_custom_fields.name = 'accepted_answer_post_id'", + ).first + return unless max_id + last_id = 0 - loop do - rows = DB.query(<<~SQL, last_id: last_id, batch_size: BATCH_SIZE) + while last_id < max_id + DB.exec(<<~SQL, last_id: last_id, batch_size: BATCH_SIZE) INSERT INTO discourse_solved_solved_topics ( topic_id, answer_post_id, @@ -33,11 +39,10 @@ class CopySolvedTopicCustomFieldToDiscourseSolvedSolvedTopics < ActiveRecord::Mi AND ua.action_type = 15 WHERE tc.name = 'accepted_answer_post_id' AND tc.id > :last_id - ORDER BY tc.topic_id, ua.created_at DESC - LIMIT :batch_size + AND tc.id <= :last_id + :batch_size + ON CONFLICT DO NOTHING SQL - break if rows.length == 0 last_id += BATCH_SIZE end end diff --git a/db/migrate/20250325074111_copy_remaining_solved_topic_custom_field_to_discourse_solved_solved_topics.rb b/db/migrate/20250325074111_copy_remaining_solved_topic_custom_field_to_discourse_solved_solved_topics.rb new file mode 100644 index 0000000..25adfab --- /dev/null +++ b/db/migrate/20250325074111_copy_remaining_solved_topic_custom_field_to_discourse_solved_solved_topics.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true +# +class CopyRemainingSolvedTopicCustomFieldToDiscourseSolvedSolvedTopics < ActiveRecord::Migration[ + 7.2 +] + disable_ddl_transaction! + + BATCH_SIZE = 5000 + + def up + max_id = + DB.query_single( + "SELECT MAX(id) FROM topic_custom_fields WHERE topic_custom_fields.name = 'accepted_answer_post_id'", + ).first + return unless max_id + + last_id = 0 + while last_id < max_id + DB.exec(<<~SQL, last_id: last_id, batch_size: BATCH_SIZE) + INSERT INTO discourse_solved_solved_topics ( + topic_id, + answer_post_id, + topic_timer_id, + accepter_user_id, + created_at, + updated_at + ) + SELECT DISTINCT ON (tc.topic_id) + tc.topic_id, + CAST(tc.value AS INTEGER), + CAST(tc2.value AS INTEGER), + COALESCE(ua.acting_user_id, -1), + tc.created_at, + tc.updated_at + FROM topic_custom_fields tc + LEFT JOIN topic_custom_fields tc2 + ON tc2.topic_id = tc.topic_id + AND tc2.name = 'solved_auto_close_topic_timer_id' + LEFT JOIN user_actions ua + ON ua.target_topic_id = tc.topic_id + AND ua.action_type = 15 + WHERE tc.name = 'accepted_answer_post_id' + AND tc.id > :last_id + AND tc.id <= :last_id + :batch_size + ON CONFLICT DO NOTHING + SQL + + last_id += BATCH_SIZE + end + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end