mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
DEV: Promote old post-deploy migrations to pre-deploy migrations (#13477)
Having a large number of post-deploy migrations running out-of-numerical-sequence with pre-deploy migrations can be problematic. For example, if we have the sequence - db/migrate/2017... - add column - db/post_migrate/2018... - drop the column - db/migrate/2021... - add the same column again It will work fine in numerical order. But if you run the pre-deploy migrations **followed by** the post-deploy migrations, you will not get the same result. Our post-deploy system is designed to allow for seamless upgrades of Discourse. However, it is reasonable for us to only support this totally seamless experience for a limited period of time. This commit moves all post_deploy migrations which are more than 1 year old (i.e. more than 2 major Discourse versions ago) into the regular pre-deploy migrations directory. This limits the impact of any edge cases caused by out-of-numerical-sequence migrations.
This commit is contained in:
@@ -1,87 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'migration/column_dropper'
|
||||
require 'badge_posts_view_manager'
|
||||
|
||||
class RemoveSuperfluousColumns < ActiveRecord::Migration[5.2]
|
||||
DROPPED_COLUMNS ||= {
|
||||
user_profiles: %i{
|
||||
card_image_badge_id
|
||||
},
|
||||
categories: %i{
|
||||
logo_url
|
||||
background_url
|
||||
suppress_from_homepage
|
||||
},
|
||||
groups: %i{
|
||||
visible
|
||||
public
|
||||
alias_level
|
||||
},
|
||||
theme_fields: %i{target},
|
||||
user_stats: %i{first_topic_unread_at},
|
||||
topics: %i{
|
||||
auto_close_at
|
||||
auto_close_user_id
|
||||
auto_close_started_at
|
||||
auto_close_based_on_last_post
|
||||
auto_close_hours
|
||||
inappropriate_count
|
||||
bookmark_count
|
||||
off_topic_count
|
||||
illegal_count
|
||||
notify_user_count
|
||||
last_unread_at
|
||||
vote_count
|
||||
},
|
||||
users: %i{
|
||||
email
|
||||
email_always
|
||||
mailing_list_mode
|
||||
email_digests
|
||||
email_direct
|
||||
email_private_messages
|
||||
external_links_in_new_tab
|
||||
enable_quoting
|
||||
dynamic_favicon
|
||||
disable_jump_reply
|
||||
edit_history_public
|
||||
automatically_unpin_topics
|
||||
digest_after_days
|
||||
auto_track_topics_after_msecs
|
||||
new_topic_duration_minutes
|
||||
last_redirected_to_top_at
|
||||
auth_token
|
||||
auth_token_updated_at
|
||||
blocked
|
||||
silenced
|
||||
trust_level_locked
|
||||
},
|
||||
user_auth_tokens: %i{legacy},
|
||||
user_options: %i{theme_key},
|
||||
themes: %i{key},
|
||||
email_logs: %i{
|
||||
topic_id
|
||||
reply_key
|
||||
skipped
|
||||
skipped_reason
|
||||
},
|
||||
posts: %i{vote_count}
|
||||
}
|
||||
|
||||
def up
|
||||
BadgePostsViewManager.drop!
|
||||
|
||||
DROPPED_COLUMNS.each do |table, columns|
|
||||
Migration::ColumnDropper.execute_drop(table, columns)
|
||||
end
|
||||
|
||||
DB.exec "DROP FUNCTION IF EXISTS first_unread_topic_for(int)"
|
||||
|
||||
BadgePostsViewManager.create!
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,21 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'migration/table_dropper'
|
||||
|
||||
class RemoveSuperfluousTables < ActiveRecord::Migration[5.2]
|
||||
DROPPED_TABLES ||= %i{
|
||||
category_featured_users
|
||||
versions
|
||||
topic_status_updates
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_TABLES.each do |table|
|
||||
Migration::TableDropper.execute_drop(table)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,19 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'migration/column_dropper'
|
||||
|
||||
class DropGroupLockedTrustLevelFromUser < ActiveRecord::Migration[5.2]
|
||||
DROPPED_COLUMNS ||= {
|
||||
posts: %i{group_locked_trust_level}
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_COLUMNS.each do |table, columns|
|
||||
Migration::ColumnDropper.execute_drop(table, columns)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class MigrateUrlSiteSettings < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
# Do nothing, the migration was moved into a onceoff job
|
||||
end
|
||||
end
|
||||
@@ -1,19 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'migration/column_dropper'
|
||||
|
||||
class RemoveUploadedMetaIdFromCategory < ActiveRecord::Migration[5.2]
|
||||
DROPPED_COLUMNS ||= {
|
||||
categories: %i{uploaded_meta_id}
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_COLUMNS.each do |table, columns|
|
||||
Migration::ColumnDropper.execute_drop(table, columns)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,11 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DropQueuedPostIdFromUserActions < ActiveRecord::Migration[5.2]
|
||||
def up
|
||||
remove_column :user_actions, :queued_post_id
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :user_actions, :queued_post_id, :integer
|
||||
end
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DropQueuedPosts < ActiveRecord::Migration[5.2]
|
||||
def up
|
||||
drop_table :queued_posts
|
||||
end
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'migration/table_dropper'
|
||||
|
||||
class DropUnusedAuthTables < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
# this migration was defect
|
||||
end
|
||||
end
|
||||
@@ -1,20 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'migration/table_dropper'
|
||||
|
||||
class DropUnusedAuthTablesAgain < ActiveRecord::Migration[5.2]
|
||||
DROPPED_TABLES ||= %i{
|
||||
facebook_user_infos
|
||||
twitter_user_infos
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_TABLES.each do |table|
|
||||
Migration::TableDropper.execute_drop(table)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,23 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'migration/column_dropper'
|
||||
|
||||
class DropEmailUserOptionsColumns < ActiveRecord::Migration[5.2]
|
||||
DROPPED_COLUMNS ||= {
|
||||
user_options: %i{
|
||||
email_direct
|
||||
email_private_messages
|
||||
email_always
|
||||
},
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_COLUMNS.each do |table, columns|
|
||||
Migration::ColumnDropper.execute_drop(table, columns)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DropClaimedById < ActiveRecord::Migration[5.2]
|
||||
def up
|
||||
remove_column :reviewables, :claimed_by_id
|
||||
end
|
||||
end
|
||||
@@ -1,19 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'migration/column_dropper'
|
||||
|
||||
class RemoveViaEmailFromInvite < ActiveRecord::Migration[5.2]
|
||||
DROPPED_COLUMNS ||= {
|
||||
invites: %i{via_email}
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_COLUMNS.each do |table, columns|
|
||||
Migration::ColumnDropper.execute_drop(table, columns)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,11 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ChangeNotificationLevel < ActiveRecord::Migration[6.0]
|
||||
def up
|
||||
change_column :category_users, :notification_level, :integer, null: true
|
||||
end
|
||||
|
||||
def down
|
||||
change_column :category_users, :notification_level, :integer, null: false
|
||||
end
|
||||
end
|
||||
@@ -1,48 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class RemoveSuppressFromLatestFromCategory < ActiveRecord::Migration[6.0]
|
||||
DROPPED_COLUMNS ||= {
|
||||
categories: %i{suppress_from_latest}
|
||||
}
|
||||
|
||||
def up
|
||||
ids = DB.query_single("SELECT id::text FROM categories WHERE suppress_from_latest = TRUE")
|
||||
|
||||
if ids.present?
|
||||
muted_ids = DB.query_single("SELECT value from site_settings WHERE name = 'default_categories_muted'").first
|
||||
ids += muted_ids.split("|") if muted_ids.present?
|
||||
ids.uniq!
|
||||
|
||||
# We shouldn't encourage to have more than 10 categories in `default_categories_muted` site setting.
|
||||
if ids.count <= 10
|
||||
# CategoryUser.notification_levels[:muted] is 0, avoid reaching to object model
|
||||
DB.exec(<<~SQL, muted: 0)
|
||||
INSERT INTO category_users (category_id, user_id, notification_level)
|
||||
SELECT c.id category_id, u.id user_id, :muted
|
||||
FROM users u
|
||||
CROSS JOIN categories c
|
||||
LEFT JOIN category_users cu
|
||||
ON u.id = cu.user_id
|
||||
AND c.id = cu.category_id
|
||||
WHERE c.suppress_from_latest = TRUE
|
||||
AND cu.notification_level IS NULL
|
||||
ON CONFLICT DO NOTHING
|
||||
SQL
|
||||
|
||||
DB.exec(<<~SQL, value: ids.join("|"))
|
||||
UPDATE site_settings
|
||||
SET value = :value
|
||||
WHERE name = 'default_categories_muted'
|
||||
SQL
|
||||
end
|
||||
end
|
||||
|
||||
DROPPED_COLUMNS.each do |table, columns|
|
||||
Migration::ColumnDropper.execute_drop(table, columns)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,20 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'migration/table_dropper'
|
||||
|
||||
class DropUnusedGoogleInstagramAuthTables < ActiveRecord::Migration[6.0]
|
||||
DROPPED_TABLES ||= %i{
|
||||
google_user_infos
|
||||
instagram_user_infos
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_TABLES.each do |table|
|
||||
Migration::TableDropper.execute_drop(table)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,16 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
class RemoveKeyFromApiKeys < ActiveRecord::Migration[6.0]
|
||||
DROPPED_COLUMNS ||= {
|
||||
api_keys: %i{key}
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_COLUMNS.each do |table, columns|
|
||||
Migration::ColumnDropper.execute_drop(table, columns)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,12 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class MakePostReplyIdColumnReadOnly < ActiveRecord::Migration[6.0]
|
||||
def up
|
||||
Migration::ColumnDropper.mark_readonly(:post_replies, :reply_id)
|
||||
DB.exec("DROP FUNCTION IF EXISTS post_replies_sync_reply_id() CASCADE")
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,23 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DropUnusedColumns < ActiveRecord::Migration[6.0]
|
||||
DROPPED_COLUMNS ||= {
|
||||
post_replies: %i{
|
||||
reply_id
|
||||
},
|
||||
user_profiles: %i{
|
||||
card_background
|
||||
profile_background
|
||||
}
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_COLUMNS.each do |table, columns|
|
||||
Migration::ColumnDropper.execute_drop(table, columns)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,12 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DropOldUnreadPmNotificationIndices < ActiveRecord::Migration[6.0]
|
||||
def up
|
||||
DB.exec("DROP INDEX IF EXISTS index_notifications_on_user_id_and_id")
|
||||
DB.exec("DROP INDEX IF EXISTS index_notifications_on_read_or_n_type")
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,17 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class RemoveKeyFromUserApiKey < ActiveRecord::Migration[6.0]
|
||||
DROPPED_COLUMNS ||= {
|
||||
user_api_keys: %i{key}
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_COLUMNS.each do |table, columns|
|
||||
Migration::ColumnDropper.execute_drop(table, columns)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,19 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DropAutomaticMembershipRetroactiveFromGroup < ActiveRecord::Migration[6.0]
|
||||
DROPPED_COLUMNS ||= {
|
||||
groups: %i{
|
||||
automatic_membership_retroactive
|
||||
}
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_COLUMNS.each do |table, columns|
|
||||
Migration::ColumnDropper.execute_drop(table, columns)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,13 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class RemoveCanonicalEmailFromUserEmails < ActiveRecord::Migration[6.0]
|
||||
def up
|
||||
execute <<~SQL
|
||||
ALTER TABLE user_emails
|
||||
DROP COLUMN IF EXISTS canonical_email
|
||||
SQL
|
||||
end
|
||||
def down
|
||||
# nothing to do, we already nuke the migrations
|
||||
end
|
||||
end
|
||||
@@ -1,41 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class RemoveAvgTimeFromTopicsPosts < ActiveRecord::Migration[6.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
# this makes it re-runnable and also works if it was not created initially
|
||||
execute <<~SQL
|
||||
ALTER TABLE topics DROP COLUMN IF EXISTS avg_time
|
||||
SQL
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
execute "DROP VIEW badge_posts"
|
||||
|
||||
execute <<~SQL
|
||||
ALTER TABLE posts DROP COLUMN IF EXISTS avg_time
|
||||
SQL
|
||||
|
||||
# we must recreate this view every time we amend posts
|
||||
# p.* is auto expanded and persisted into the view definition
|
||||
# at create time
|
||||
execute <<~SQL
|
||||
CREATE VIEW badge_posts AS
|
||||
SELECT p.*
|
||||
FROM posts p
|
||||
JOIN topics t ON t.id = p.topic_id
|
||||
JOIN categories c ON c.id = t.category_id
|
||||
WHERE c.allow_badges AND
|
||||
p.deleted_at IS NULL AND
|
||||
t.deleted_at IS NULL AND
|
||||
NOT c.read_restricted AND
|
||||
t.visible AND
|
||||
p.post_type IN (1,2,3)
|
||||
SQL
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
# do nothing re-runnable
|
||||
end
|
||||
end
|
||||
@@ -1,11 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AllowNullOldEmailOnEmailChangeRequests < ActiveRecord::Migration[6.0]
|
||||
def up
|
||||
change_column :email_change_requests, :old_email, :string, null: true
|
||||
end
|
||||
|
||||
def down
|
||||
change_column :email_change_requests, :old_email, :string, null: false
|
||||
end
|
||||
end
|
||||
@@ -1,19 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DropTopicReplyCount < ActiveRecord::Migration[6.0]
|
||||
DROPPED_COLUMNS ||= {
|
||||
user_stats: %i{
|
||||
topic_reply_count
|
||||
}
|
||||
}
|
||||
|
||||
def up
|
||||
DROPPED_COLUMNS.each do |table, columns|
|
||||
Migration::ColumnDropper.execute_drop(table, columns)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class RemoveFksFromBookmarks < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
remove_foreign_key :bookmarks, :topics
|
||||
remove_foreign_key :bookmarks, :posts
|
||||
remove_foreign_key :bookmarks, :users
|
||||
end
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class RemoveAccessControlPostFk < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
remove_foreign_key :uploads, column: :access_control_post_id
|
||||
end
|
||||
end
|
||||
@@ -1,40 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class RemoveImageUrlFromPostAndTopic < ActiveRecord::Migration[6.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
execute <<~SQL
|
||||
ALTER TABLE topics DROP COLUMN IF EXISTS image_url
|
||||
SQL
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
execute "DROP VIEW badge_posts"
|
||||
|
||||
execute <<~SQL
|
||||
ALTER TABLE posts DROP COLUMN IF EXISTS image_url
|
||||
SQL
|
||||
|
||||
# we must recreate this view every time we amend posts
|
||||
# p.* is auto expanded and persisted into the view definition
|
||||
# at create time
|
||||
execute <<~SQL
|
||||
CREATE VIEW badge_posts AS
|
||||
SELECT p.*
|
||||
FROM posts p
|
||||
JOIN topics t ON t.id = p.topic_id
|
||||
JOIN categories c ON c.id = t.category_id
|
||||
WHERE c.allow_badges AND
|
||||
p.deleted_at IS NULL AND
|
||||
t.deleted_at IS NULL AND
|
||||
NOT c.read_restricted AND
|
||||
t.visible AND
|
||||
p.post_type IN (1,2,3)
|
||||
SQL
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
# do nothing re-runnable
|
||||
end
|
||||
end
|
||||
@@ -1,48 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CorrectPostsSchema < ActiveRecord::Migration[6.0]
|
||||
# In the past, rails changed the default behavior for varchar columns
|
||||
# This only affects older discourse installations
|
||||
# This migration removes the character limits from posts columns, so that they match modern behavior
|
||||
#
|
||||
# To modify the posts table schema we need to recreate the badge_posts view
|
||||
# This should be done in a transaction
|
||||
def up
|
||||
result = DB.query <<~SQL
|
||||
SELECT character_maximum_length
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema='public'
|
||||
AND table_name = 'posts'
|
||||
AND column_name IN ('action_code', 'edit_reason')
|
||||
SQL
|
||||
|
||||
# No need to continue if the schema is already correct
|
||||
return if result.all? { |r| r.character_maximum_length.nil? }
|
||||
|
||||
execute "DROP VIEW badge_posts"
|
||||
|
||||
execute "ALTER TABLE posts ALTER COLUMN action_code TYPE varchar"
|
||||
execute "ALTER TABLE posts ALTER COLUMN edit_reason TYPE varchar"
|
||||
|
||||
# we must recreate this view every time we amend posts
|
||||
# p.* is auto expanded and persisted into the view definition
|
||||
# at create time
|
||||
execute <<~SQL
|
||||
CREATE VIEW badge_posts AS
|
||||
SELECT p.*
|
||||
FROM posts p
|
||||
JOIN topics t ON t.id = p.topic_id
|
||||
JOIN categories c ON c.id = t.category_id
|
||||
WHERE c.allow_badges AND
|
||||
p.deleted_at IS NULL AND
|
||||
t.deleted_at IS NULL AND
|
||||
NOT c.read_restricted AND
|
||||
t.visible AND
|
||||
p.post_type IN (1,2,3)
|
||||
SQL
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user