about summary refs log tree commit diff
path: root/db/migrate
diff options
context:
space:
mode:
Diffstat (limited to 'db/migrate')
-rw-r--r--db/migrate/20160305115639_add_devise_to_users.rb2
-rw-r--r--db/migrate/20161006213403_rails_settings_migration.rb10
-rw-r--r--db/migrate/20161122163057_remove_unneeded_indexes.rb6
-rw-r--r--db/migrate/20170125145934_add_spoiler_text_to_statuses.rb2
-rw-r--r--db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb2
-rw-r--r--db/migrate/20170716191202_add_hide_notifications_to_mute.rb14
-rw-r--r--db/migrate/20170914032032_default_existing_mutes_to_hiding_notifications.rb11
-rw-r--r--db/migrate/20170918125918_ids_to_bigints.rb26
-rw-r--r--db/migrate/20170920032311_fix_reblogs_in_feeds.rb2
-rw-r--r--db/migrate/20170927215609_add_description_to_media_attachments.rb2
-rw-r--r--db/migrate/20170928082043_create_email_domain_blocks.rb2
-rw-r--r--db/migrate/20171005102658_create_account_moderation_notes.rb2
-rw-r--r--db/migrate/20171005171936_add_disabled_to_custom_emojis.rb2
-rw-r--r--db/migrate/20171006142024_add_uri_to_custom_emojis.rb2
-rw-r--r--db/migrate/20171009222537_create_keyword_mutes.rb2
-rw-r--r--db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb2
-rw-r--r--db/migrate/20171010025614_change_accounts_nonnullable_in_account_moderation_notes.rb2
-rw-r--r--db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb6
-rw-r--r--db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb2
-rw-r--r--db/migrate/20171028221157_add_reblogs_to_follows.rb2
-rw-r--r--db/migrate/20171107143332_add_memorial_to_accounts.rb2
-rw-r--r--db/migrate/20171107143624_add_disabled_to_users.rb2
-rw-r--r--db/migrate/20171109012327_add_moderator_to_accounts.rb2
-rw-r--r--db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb2
-rw-r--r--db/migrate/20171114231651_create_lists.rb2
-rw-r--r--db/migrate/20171116161857_create_list_accounts.rb2
-rw-r--r--db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb2
-rw-r--r--db/migrate/20171119172437_create_admin_action_logs.rb2
-rw-r--r--db/migrate/20171122120436_add_index_account_and_reblog_of_id_to_statuses.rb2
-rw-r--r--db/migrate/20171125024930_create_invites.rb2
-rw-r--r--db/migrate/20171125031751_add_invite_id_to_users.rb2
-rw-r--r--db/migrate/20171125185353_add_index_reblog_of_id_and_account_to_statuses.rb2
-rw-r--r--db/migrate/20171125190735_remove_old_reblog_index_on_statuses.rb2
-rw-r--r--db/migrate/20171129172043_add_index_on_stream_entries.rb2
-rw-r--r--db/migrate/20171130000000_add_embed_url_to_preview_cards.rb2
-rw-r--r--db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb2
-rw-r--r--db/migrate/20171210213213_add_local_only_flag_to_statuses.rb2
-rw-r--r--db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb6
-rw-r--r--db/migrate/20171226094803_more_faster_index_on_notifications.rb2
-rw-r--r--db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb2
-rw-r--r--db/migrate/20180109143959_add_remember_token_to_users.rb2
-rw-r--r--db/migrate/20180204034416_create_identities.rb6
-rw-r--r--db/migrate/20180206000000_change_user_id_nonnullable.rb2
-rw-r--r--db/migrate/20180211015820_create_backups.rb2
-rw-r--r--db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb2
-rw-r--r--db/migrate/20180310000000_change_columns_in_notifications_nonnullable.rb2
-rw-r--r--db/migrate/20180402031200_add_assigned_account_id_to_reports.rb2
-rw-r--r--db/migrate/20180402040909_create_report_notes.rb2
-rw-r--r--db/migrate/20180410204633_add_fields_to_accounts.rb2
-rw-r--r--db/migrate/20180410220657_create_bookmarks.rb2
-rw-r--r--db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb10
-rw-r--r--db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb6
-rw-r--r--db/migrate/20180528141303_fix_accounts_unique_index.rb41
-rw-r--r--db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb2
-rw-r--r--db/migrate/20180707193142_migrate_filters.rb12
-rw-r--r--db/migrate/20180812173710_copy_status_stats.rb12
-rw-r--r--db/migrate/20180831171112_create_bookmarks.rb2
-rw-r--r--db/migrate/20181024224956_migrate_account_conversations.rb21
-rw-r--r--db/migrate/20181116173541_copy_account_stats.rb12
-rw-r--r--db/migrate/20190306145741_add_lock_version_to_polls.rb1
-rw-r--r--db/migrate/20190314181829_migrate_open_registrations_setting.rb2
-rw-r--r--db/migrate/20190512200918_add_content_type_to_statuses.rb2
-rw-r--r--db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb4
-rw-r--r--db/migrate/20190807135426_add_comments_to_domain_blocks.rb1
-rw-r--r--db/migrate/20191031163205_change_list_account_follow_nullable.rb2
-rw-r--r--db/migrate/20200312162302_add_status_ids_to_announcements.rb1
-rw-r--r--db/migrate/20200407202420_migrate_unavailable_inboxes.rb5
-rw-r--r--db/migrate/20200510110808_reset_web_app_secret.rb3
-rw-r--r--db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb1
-rw-r--r--db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb2
-rw-r--r--db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb2
-rw-r--r--db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb4
-rw-r--r--db/migrate/20200628133322_create_account_notes.rb1
-rw-r--r--db/migrate/20200917192924_add_notify_to_follows.rb2
-rw-r--r--db/migrate/20210306164523_account_ids_to_timestamp_ids.rb4
-rw-r--r--db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb3
-rw-r--r--db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb1
-rw-r--r--db/migrate/20220209175231_add_content_type_to_status_edits.rb2
-rw-r--r--db/migrate/20220613110834_add_action_to_custom_filters.rb1
-rw-r--r--db/migrate/20230215074327_add_settings_to_users.rb7
-rw-r--r--db/migrate/20230215074423_move_user_settings.rb84
-rw-r--r--db/migrate/20230215074424_move_glitch_user_settings.rb57
82 files changed, 312 insertions, 167 deletions
diff --git a/db/migrate/20160305115639_add_devise_to_users.rb b/db/migrate/20160305115639_add_devise_to_users.rb
index 0e12e6053..fa1e521b2 100644
--- a/db/migrate/20160305115639_add_devise_to_users.rb
+++ b/db/migrate/20160305115639_add_devise_to_users.rb
@@ -2,7 +2,7 @@ class AddDeviseToUsers < ActiveRecord::Migration[4.2]
   def self.up
     change_table(:users) do |t|
       ## Database authenticatable
-      t.string :encrypted_password, null: false, default: ""
+      t.string :encrypted_password, null: false, default: ''
 
       ## Recoverable
       t.string   :reset_password_token
diff --git a/db/migrate/20161006213403_rails_settings_migration.rb b/db/migrate/20161006213403_rails_settings_migration.rb
index 9d565cb5c..02932610c 100644
--- a/db/migrate/20161006213403_rails_settings_migration.rb
+++ b/db/migrate/20161006213403_rails_settings_migration.rb
@@ -1,8 +1,8 @@
 MIGRATION_BASE_CLASS = if ActiveRecord::VERSION::MAJOR >= 5
-  ActiveRecord::Migration[5.0]
-else
-  ActiveRecord::Migration[4.2]
-end
+                         ActiveRecord::Migration[5.0]
+                       else
+                         ActiveRecord::Migration[4.2]
+                       end
 
 class RailsSettingsMigration < MIGRATION_BASE_CLASS
   def self.up
@@ -12,7 +12,7 @@ class RailsSettingsMigration < MIGRATION_BASE_CLASS
       t.references :target, null: false, polymorphic: true, index: { name: 'index_settings_on_target_type_and_target_id' }
       t.timestamps null: true
     end
-    add_index :settings, [ :target_type, :target_id, :var ], unique: true
+    add_index :settings, [:target_type, :target_id, :var], unique: true
   end
 
   def self.down
diff --git a/db/migrate/20161122163057_remove_unneeded_indexes.rb b/db/migrate/20161122163057_remove_unneeded_indexes.rb
index 3832b878d..12cc9c5b2 100644
--- a/db/migrate/20161122163057_remove_unneeded_indexes.rb
+++ b/db/migrate/20161122163057_remove_unneeded_indexes.rb
@@ -1,7 +1,7 @@
 class RemoveUnneededIndexes < ActiveRecord::Migration[5.0]
   def change
-    remove_index :notifications, name: "index_notifications_on_account_id"
-    remove_index :settings, name: "index_settings_on_target_type_and_target_id"
-    remove_index :statuses_tags, name: "index_statuses_tags_on_tag_id"
+    remove_index :notifications, name: 'index_notifications_on_account_id'
+    remove_index :settings, name: 'index_settings_on_target_type_and_target_id'
+    remove_index :statuses_tags, name: 'index_statuses_tags_on_tag_id'
   end
 end
diff --git a/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb b/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb
index 2c43210ba..39cd41c00 100644
--- a/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb
+++ b/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb
@@ -1,5 +1,5 @@
 class AddSpoilerTextToStatuses < ActiveRecord::Migration[5.0]
   def change
-    add_column :statuses, :spoiler_text, :text, default: "", null: false
+    add_column :statuses, :spoiler_text, :text, default: '', null: false
   end
 end
diff --git a/db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb b/db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb
index 3e74346a8..86e425559 100644
--- a/db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb
+++ b/db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb
@@ -6,7 +6,7 @@ class AddStatusesIndexOnAccountIdId < ActiveRecord::Migration[5.1]
     # of an account to show them in his status page is one of the most
     # significant examples.
     # Add this index to improve the performance in such cases.
-    add_index 'statuses', ['account_id', 'id'], algorithm: :concurrently, name: 'index_statuses_on_account_id_id'
+    add_index 'statuses', %w(account_id id), algorithm: :concurrently, name: 'index_statuses_on_account_id_id'
 
     remove_index 'statuses', algorithm: :concurrently, column: 'account_id', name: 'index_statuses_on_account_id'
   end
diff --git a/db/migrate/20170716191202_add_hide_notifications_to_mute.rb b/db/migrate/20170716191202_add_hide_notifications_to_mute.rb
index de7d2a4a2..a498396b7 100644
--- a/db/migrate/20170716191202_add_hide_notifications_to_mute.rb
+++ b/db/migrate/20170716191202_add_hide_notifications_to_mute.rb
@@ -1,5 +1,15 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
 class AddHideNotificationsToMute < ActiveRecord::Migration[5.1]
-  def change
-    add_column :mutes, :hide_notifications, :boolean, default: false, null: false
+  include Mastodon::MigrationHelpers
+
+  disable_ddl_transaction!
+
+  def up
+    add_column_with_default :mutes, :hide_notifications, :boolean, default: true, allow_null: false
+  end
+
+  def down
+    remove_column :mutes, :hide_notifications
   end
 end
diff --git a/db/migrate/20170914032032_default_existing_mutes_to_hiding_notifications.rb b/db/migrate/20170914032032_default_existing_mutes_to_hiding_notifications.rb
index 8e6cac455..d9866dfde 100644
--- a/db/migrate/20170914032032_default_existing_mutes_to_hiding_notifications.rb
+++ b/db/migrate/20170914032032_default_existing_mutes_to_hiding_notifications.rb
@@ -1,8 +1,13 @@
+# frozen_string_literal: true
+
+# This migration is glitch-soc-only because mutes were originally developed in
+# glitch-soc and the default value changed when submitting the code upstream.
+
+# This migration originally changed existing values to `true`, but this has
+# been dropped as to not cause issues when migrating from upstream.
+
 class DefaultExistingMutesToHidingNotifications < ActiveRecord::Migration[5.1]
   def up
     change_column_default :mutes, :hide_notifications, from: false, to: true
-
-    # Unfortunately if this is applied sometime after the one to add the table we lose some data, so this is irreversible.
-    Mute.update_all(hide_notifications: true)
   end
 end
diff --git a/db/migrate/20170918125918_ids_to_bigints.rb b/db/migrate/20170918125918_ids_to_bigints.rb
index bf875e4e5..e3fc34a51 100644
--- a/db/migrate/20170918125918_ids_to_bigints.rb
+++ b/db/migrate/20170918125918_ids_to_bigints.rb
@@ -1,7 +1,9 @@
-require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+require_relative '../../lib/mastodon/migration_helpers'
+require_relative '../../lib/mastodon/migration_warning'
 
 class IdsToBigints < ActiveRecord::Migration[5.1]
   include Mastodon::MigrationHelpers
+  include Mastodon::MigrationWarning
 
   disable_ddl_transaction!
 
@@ -69,24 +71,12 @@ class IdsToBigints < ActiveRecord::Migration[5.1]
     ]
     included_columns << [:deprecated_preview_cards, :id] if table_exists?(:deprecated_preview_cards)
 
-    # Print out a warning that this will probably take a while.
-    if $stdout.isatty
-      say ''
-      say 'WARNING: This migration may take a *long* time for large instances'
-      say 'It will *not* lock tables for any significant time, but it may run'
-      say 'for a very long time. We will pause for 10 seconds to allow you to'
-      say 'interrupt this migration if you are not ready.'
-      say ''
-      say 'This migration has some sections that can be safely interrupted'
-      say 'and restarted later, and will tell you when those are occurring.'
-      say ''
-      say 'For more information, see https://github.com/mastodon/mastodon/pull/5088'
+    migration_duration_warning(<<~EXPLANATION)
+      This migration has some sections that can be safely interrupted
+      and restarted later, and will tell you when those are occurring.
 
-      10.downto(1) do |i|
-        say "Continuing in #{i} second#{i == 1 ? '' : 's'}...", true
-        sleep 1
-      end
-    end
+      For more information, see https://github.com/mastodon/mastodon/pull/5088
+    EXPLANATION
 
     tables = included_columns.map(&:first).uniq
     table_sizes = {}
diff --git a/db/migrate/20170920032311_fix_reblogs_in_feeds.rb b/db/migrate/20170920032311_fix_reblogs_in_feeds.rb
index 4ab68e8f3..7e2db0ff3 100644
--- a/db/migrate/20170920032311_fix_reblogs_in_feeds.rb
+++ b/db/migrate/20170920032311_fix_reblogs_in_feeds.rb
@@ -1,6 +1,6 @@
 class FixReblogsInFeeds < ActiveRecord::Migration[5.1]
   def up
-    redis = Redis.current
+    redis = RedisConfiguration.pool.checkout
     fm = FeedManager.instance
 
     # Old scheme:
diff --git a/db/migrate/20170927215609_add_description_to_media_attachments.rb b/db/migrate/20170927215609_add_description_to_media_attachments.rb
index db8d76566..9c3312373 100644
--- a/db/migrate/20170927215609_add_description_to_media_attachments.rb
+++ b/db/migrate/20170927215609_add_description_to_media_attachments.rb
@@ -1,4 +1,4 @@
-class AddDescriptionToMediaAttachments < ActiveRecord::Migration[5.1]
+class AddDescriptionToMediaAttachments < ActiveRecord::Migration[5.2]
   def change
     add_column :media_attachments, :description, :text
   end
diff --git a/db/migrate/20170928082043_create_email_domain_blocks.rb b/db/migrate/20170928082043_create_email_domain_blocks.rb
index 1f0fb7587..2baed54ef 100644
--- a/db/migrate/20170928082043_create_email_domain_blocks.rb
+++ b/db/migrate/20170928082043_create_email_domain_blocks.rb
@@ -1,4 +1,4 @@
-class CreateEmailDomainBlocks < ActiveRecord::Migration[5.1]
+class CreateEmailDomainBlocks < ActiveRecord::Migration[5.2]
   def change
     create_table :email_domain_blocks do |t|
       t.string :domain, null: false
diff --git a/db/migrate/20171005102658_create_account_moderation_notes.rb b/db/migrate/20171005102658_create_account_moderation_notes.rb
index 010b94586..afa2f5f25 100644
--- a/db/migrate/20171005102658_create_account_moderation_notes.rb
+++ b/db/migrate/20171005102658_create_account_moderation_notes.rb
@@ -1,4 +1,4 @@
-class CreateAccountModerationNotes < ActiveRecord::Migration[5.1]
+class CreateAccountModerationNotes < ActiveRecord::Migration[5.2]
   def change
     create_table :account_moderation_notes do |t|
       t.text :content, null: false
diff --git a/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb b/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb
index 067a7bee0..7cf007ae9 100644
--- a/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb
+++ b/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb
@@ -1,6 +1,6 @@
 require Rails.root.join('lib', 'mastodon', 'migration_helpers')
 
-class AddDisabledToCustomEmojis < ActiveRecord::Migration[5.1]
+class AddDisabledToCustomEmojis < ActiveRecord::Migration[5.2]
   include Mastodon::MigrationHelpers
 
   disable_ddl_transaction!
diff --git a/db/migrate/20171006142024_add_uri_to_custom_emojis.rb b/db/migrate/20171006142024_add_uri_to_custom_emojis.rb
index 04dfcf397..ff62aed20 100644
--- a/db/migrate/20171006142024_add_uri_to_custom_emojis.rb
+++ b/db/migrate/20171006142024_add_uri_to_custom_emojis.rb
@@ -1,4 +1,4 @@
-class AddUriToCustomEmojis < ActiveRecord::Migration[5.1]
+class AddUriToCustomEmojis < ActiveRecord::Migration[5.2]
   def change
     add_column :custom_emojis, :uri, :string
     add_column :custom_emojis, :image_remote_url, :string
diff --git a/db/migrate/20171009222537_create_keyword_mutes.rb b/db/migrate/20171009222537_create_keyword_mutes.rb
index 66411ba1d..77c88b0a5 100644
--- a/db/migrate/20171009222537_create_keyword_mutes.rb
+++ b/db/migrate/20171009222537_create_keyword_mutes.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class CreateKeywordMutes < ActiveRecord::Migration[5.1]
   def change
     create_table :keyword_mutes do |t|
diff --git a/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb b/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb
index cdcd15934..a2c0fbcc4 100644
--- a/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb
+++ b/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb
@@ -1,4 +1,4 @@
-class AddForeignKeyToAccountModerationNotes < ActiveRecord::Migration[5.1]
+class AddForeignKeyToAccountModerationNotes < ActiveRecord::Migration[5.2]
   def change
     safety_assured { add_foreign_key :account_moderation_notes, :accounts }
   end
diff --git a/db/migrate/20171010025614_change_accounts_nonnullable_in_account_moderation_notes.rb b/db/migrate/20171010025614_change_accounts_nonnullable_in_account_moderation_notes.rb
index 1d7a0086c..62725c88d 100644
--- a/db/migrate/20171010025614_change_accounts_nonnullable_in_account_moderation_notes.rb
+++ b/db/migrate/20171010025614_change_accounts_nonnullable_in_account_moderation_notes.rb
@@ -1,4 +1,4 @@
-class ChangeAccountsNonnullableInAccountModerationNotes < ActiveRecord::Migration[5.1]
+class ChangeAccountsNonnullableInAccountModerationNotes < ActiveRecord::Migration[5.2]
   def change
     safety_assured do
       change_column_null :account_moderation_notes, :account_id, false
diff --git a/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb b/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb
index 60a287101..5f7c60a3e 100644
--- a/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb
+++ b/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb
@@ -1,7 +1,7 @@
-class AddVisibleInPickerToCustomEmoji < ActiveRecord::Migration[5.1]
+class AddVisibleInPickerToCustomEmoji < ActiveRecord::Migration[5.2]
   def change
-    safety_assured {
+    safety_assured do
       add_column :custom_emojis, :visible_in_picker, :boolean, default: true, null: false
-    }
+    end
   end
 end
diff --git a/db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb b/db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb
index 269bb49d6..b6ea537c2 100644
--- a/db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb
+++ b/db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class MoveKeywordMutesIntoGlitchNamespace < ActiveRecord::Migration[5.1]
   def change
     safety_assured do
diff --git a/db/migrate/20171028221157_add_reblogs_to_follows.rb b/db/migrate/20171028221157_add_reblogs_to_follows.rb
index 3b2e46ed8..773904249 100644
--- a/db/migrate/20171028221157_add_reblogs_to_follows.rb
+++ b/db/migrate/20171028221157_add_reblogs_to_follows.rb
@@ -1,6 +1,6 @@
 require Rails.root.join('lib', 'mastodon', 'migration_helpers')
 
-class AddReblogsToFollows < ActiveRecord::Migration[5.1]
+class AddReblogsToFollows < ActiveRecord::Migration[5.2]
   include Mastodon::MigrationHelpers
 
   disable_ddl_transaction!
diff --git a/db/migrate/20171107143332_add_memorial_to_accounts.rb b/db/migrate/20171107143332_add_memorial_to_accounts.rb
index f3e012ce8..4fb1216a1 100644
--- a/db/migrate/20171107143332_add_memorial_to_accounts.rb
+++ b/db/migrate/20171107143332_add_memorial_to_accounts.rb
@@ -1,6 +1,6 @@
 require Rails.root.join('lib', 'mastodon', 'migration_helpers')
 
-class AddMemorialToAccounts < ActiveRecord::Migration[5.1]
+class AddMemorialToAccounts < ActiveRecord::Migration[5.2]
   include Mastodon::MigrationHelpers
 
   disable_ddl_transaction!
diff --git a/db/migrate/20171107143624_add_disabled_to_users.rb b/db/migrate/20171107143624_add_disabled_to_users.rb
index a71cac1c6..fb736786d 100644
--- a/db/migrate/20171107143624_add_disabled_to_users.rb
+++ b/db/migrate/20171107143624_add_disabled_to_users.rb
@@ -1,6 +1,6 @@
 require Rails.root.join('lib', 'mastodon', 'migration_helpers')
 
-class AddDisabledToUsers < ActiveRecord::Migration[5.1]
+class AddDisabledToUsers < ActiveRecord::Migration[5.2]
   include Mastodon::MigrationHelpers
 
   disable_ddl_transaction!
diff --git a/db/migrate/20171109012327_add_moderator_to_accounts.rb b/db/migrate/20171109012327_add_moderator_to_accounts.rb
index ddd87583a..70b0b598c 100644
--- a/db/migrate/20171109012327_add_moderator_to_accounts.rb
+++ b/db/migrate/20171109012327_add_moderator_to_accounts.rb
@@ -1,6 +1,6 @@
 require Rails.root.join('lib', 'mastodon', 'migration_helpers')
 
-class AddModeratorToAccounts < ActiveRecord::Migration[5.1]
+class AddModeratorToAccounts < ActiveRecord::Migration[5.2]
   include Mastodon::MigrationHelpers
 
   disable_ddl_transaction!
diff --git a/db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb b/db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb
index 84a341510..34dc6ff00 100644
--- a/db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb
+++ b/db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb
@@ -1,4 +1,4 @@
-class AddIndexDomainToEmailDomainBlocks < ActiveRecord::Migration[5.1]
+class AddIndexDomainToEmailDomainBlocks < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
   def change
diff --git a/db/migrate/20171114231651_create_lists.rb b/db/migrate/20171114231651_create_lists.rb
index 21285e901..b7761abe4 100644
--- a/db/migrate/20171114231651_create_lists.rb
+++ b/db/migrate/20171114231651_create_lists.rb
@@ -1,4 +1,4 @@
-class CreateLists < ActiveRecord::Migration[5.1]
+class CreateLists < ActiveRecord::Migration[5.2]
   def change
     create_table :lists do |t|
       t.references :account, foreign_key: { on_delete: :cascade }
diff --git a/db/migrate/20171116161857_create_list_accounts.rb b/db/migrate/20171116161857_create_list_accounts.rb
index b76c90651..7dbb78d8d 100644
--- a/db/migrate/20171116161857_create_list_accounts.rb
+++ b/db/migrate/20171116161857_create_list_accounts.rb
@@ -1,4 +1,4 @@
-class CreateListAccounts < ActiveRecord::Migration[5.1]
+class CreateListAccounts < ActiveRecord::Migration[5.2]
   def change
     create_table :list_accounts do |t|
       t.belongs_to :list, foreign_key: { on_delete: :cascade }, null: false
diff --git a/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb b/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb
index 586ef6f02..893972848 100644
--- a/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb
+++ b/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb
@@ -1,4 +1,4 @@
-class AddMovedToAccountIdToAccounts < ActiveRecord::Migration[5.1]
+class AddMovedToAccountIdToAccounts < ActiveRecord::Migration[5.2]
   def change
     add_column :accounts, :moved_to_account_id, :bigint, null: true, default: nil
     safety_assured { add_foreign_key :accounts, :accounts, column: :moved_to_account_id, on_delete: :nullify }
diff --git a/db/migrate/20171119172437_create_admin_action_logs.rb b/db/migrate/20171119172437_create_admin_action_logs.rb
index b690735d2..80d5a3dba 100644
--- a/db/migrate/20171119172437_create_admin_action_logs.rb
+++ b/db/migrate/20171119172437_create_admin_action_logs.rb
@@ -1,4 +1,4 @@
-class CreateAdminActionLogs < ActiveRecord::Migration[5.1]
+class CreateAdminActionLogs < ActiveRecord::Migration[5.2]
   def change
     create_table :admin_action_logs do |t|
       t.belongs_to :account, foreign_key: { on_delete: :cascade }
diff --git a/db/migrate/20171122120436_add_index_account_and_reblog_of_id_to_statuses.rb b/db/migrate/20171122120436_add_index_account_and_reblog_of_id_to_statuses.rb
index 131e54b72..a02ffe09d 100644
--- a/db/migrate/20171122120436_add_index_account_and_reblog_of_id_to_statuses.rb
+++ b/db/migrate/20171122120436_add_index_account_and_reblog_of_id_to_statuses.rb
@@ -1,4 +1,4 @@
-class AddIndexAccountAndReblogOfIdToStatuses < ActiveRecord::Migration[5.1]
+class AddIndexAccountAndReblogOfIdToStatuses < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
   def up
diff --git a/db/migrate/20171125024930_create_invites.rb b/db/migrate/20171125024930_create_invites.rb
index bcf03bd72..2e814babf 100644
--- a/db/migrate/20171125024930_create_invites.rb
+++ b/db/migrate/20171125024930_create_invites.rb
@@ -1,4 +1,4 @@
-class CreateInvites < ActiveRecord::Migration[5.1]
+class CreateInvites < ActiveRecord::Migration[5.2]
   def change
     create_table :invites do |t|
       t.belongs_to :user, foreign_key: { on_delete: :cascade }
diff --git a/db/migrate/20171125031751_add_invite_id_to_users.rb b/db/migrate/20171125031751_add_invite_id_to_users.rb
index 9cfb0c542..2ff6c3430 100644
--- a/db/migrate/20171125031751_add_invite_id_to_users.rb
+++ b/db/migrate/20171125031751_add_invite_id_to_users.rb
@@ -1,4 +1,4 @@
-class AddInviteIdToUsers < ActiveRecord::Migration[5.1]
+class AddInviteIdToUsers < ActiveRecord::Migration[5.2]
   def change
     safety_assured { add_reference :users, :invite, null: true, default: nil, foreign_key: { on_delete: :nullify }, index: false }
   end
diff --git a/db/migrate/20171125185353_add_index_reblog_of_id_and_account_to_statuses.rb b/db/migrate/20171125185353_add_index_reblog_of_id_and_account_to_statuses.rb
index 37662eaa5..8952387b5 100644
--- a/db/migrate/20171125185353_add_index_reblog_of_id_and_account_to_statuses.rb
+++ b/db/migrate/20171125185353_add_index_reblog_of_id_and_account_to_statuses.rb
@@ -1,4 +1,4 @@
-class AddIndexReblogOfIdAndAccountToStatuses < ActiveRecord::Migration[5.1]
+class AddIndexReblogOfIdAndAccountToStatuses < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
   def change
diff --git a/db/migrate/20171125190735_remove_old_reblog_index_on_statuses.rb b/db/migrate/20171125190735_remove_old_reblog_index_on_statuses.rb
index 68146c5ce..dc7e09a25 100644
--- a/db/migrate/20171125190735_remove_old_reblog_index_on_statuses.rb
+++ b/db/migrate/20171125190735_remove_old_reblog_index_on_statuses.rb
@@ -1,4 +1,4 @@
-class RemoveOldReblogIndexOnStatuses < ActiveRecord::Migration[5.1]
+class RemoveOldReblogIndexOnStatuses < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
   def up
diff --git a/db/migrate/20171129172043_add_index_on_stream_entries.rb b/db/migrate/20171129172043_add_index_on_stream_entries.rb
index 181c4f288..4580fb42f 100644
--- a/db/migrate/20171129172043_add_index_on_stream_entries.rb
+++ b/db/migrate/20171129172043_add_index_on_stream_entries.rb
@@ -1,4 +1,4 @@
-class AddIndexOnStreamEntries < ActiveRecord::Migration[5.1]
+class AddIndexOnStreamEntries < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
   def change
diff --git a/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb b/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb
index 8fcabef9f..811f6ceae 100644
--- a/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb
+++ b/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb
@@ -1,6 +1,6 @@
 require Rails.root.join('lib', 'mastodon', 'migration_helpers')
 
-class AddEmbedURLToPreviewCards < ActiveRecord::Migration[5.1]
+class AddEmbedURLToPreviewCards < ActiveRecord::Migration[5.2]
   include Mastodon::MigrationHelpers
 
   disable_ddl_transaction!
diff --git a/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb b/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb
index ac86c9e77..e8e878611 100644
--- a/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb
+++ b/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb
@@ -1,4 +1,4 @@
-class ChangeAccountIdNonnullableInLists < ActiveRecord::Migration[5.1]
+class ChangeAccountIdNonnullableInLists < ActiveRecord::Migration[5.2]
   def change
     safety_assured do
       change_column_null :lists, :account_id, false
diff --git a/db/migrate/20171210213213_add_local_only_flag_to_statuses.rb b/db/migrate/20171210213213_add_local_only_flag_to_statuses.rb
index af1e29d6a..010503b10 100644
--- a/db/migrate/20171210213213_add_local_only_flag_to_statuses.rb
+++ b/db/migrate/20171210213213_add_local_only_flag_to_statuses.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class AddLocalOnlyFlagToStatuses < ActiveRecord::Migration[5.1]
   def change
     add_column :statuses, :local_only, :boolean
diff --git a/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb b/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb
index 03f2591a8..f3007c77c 100644
--- a/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb
+++ b/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb
@@ -1,6 +1,6 @@
-class RemoveDuplicateIndexesInLists < ActiveRecord::Migration[5.1]
+class RemoveDuplicateIndexesInLists < ActiveRecord::Migration[5.2]
   def change
-    remove_index :list_accounts, name: "index_list_accounts_on_account_id"
-    remove_index :list_accounts, name: "index_list_accounts_on_list_id"
+    remove_index :list_accounts, name: 'index_list_accounts_on_account_id'
+    remove_index :list_accounts, name: 'index_list_accounts_on_list_id'
   end
 end
diff --git a/db/migrate/20171226094803_more_faster_index_on_notifications.rb b/db/migrate/20171226094803_more_faster_index_on_notifications.rb
index 0273a4e7c..e0e73b27a 100644
--- a/db/migrate/20171226094803_more_faster_index_on_notifications.rb
+++ b/db/migrate/20171226094803_more_faster_index_on_notifications.rb
@@ -1,4 +1,4 @@
-class MoreFasterIndexOnNotifications < ActiveRecord::Migration[5.1]
+class MoreFasterIndexOnNotifications < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
   def change
diff --git a/db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb b/db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb
index 401fc5e62..eb277d3bc 100644
--- a/db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb
+++ b/db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb
@@ -1,4 +1,4 @@
-class AddIndexOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.1]
+class AddIndexOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
   def change
diff --git a/db/migrate/20180109143959_add_remember_token_to_users.rb b/db/migrate/20180109143959_add_remember_token_to_users.rb
index 662905bcb..f244fc6f6 100644
--- a/db/migrate/20180109143959_add_remember_token_to_users.rb
+++ b/db/migrate/20180109143959_add_remember_token_to_users.rb
@@ -1,4 +1,4 @@
-class AddRememberTokenToUsers < ActiveRecord::Migration[5.1]
+class AddRememberTokenToUsers < ActiveRecord::Migration[5.2]
   def change
     add_column :users, :remember_token, :string, null: true
   end
diff --git a/db/migrate/20180204034416_create_identities.rb b/db/migrate/20180204034416_create_identities.rb
index f6f5da910..68288aadf 100644
--- a/db/migrate/20180204034416_create_identities.rb
+++ b/db/migrate/20180204034416_create_identities.rb
@@ -1,7 +1,7 @@
-class CreateIdentities < ActiveRecord::Migration[5.0]
+class CreateIdentities < ActiveRecord::Migration[5.2]
   def change
-    create_table :identities do |t|
-      t.references :user, foreign_key: { on_delete: :cascade }
+    create_table :identities, id: :integer do |t|
+      t.references :user, type: :integer, foreign_key: { on_delete: :cascade }
       t.string :provider, null: false, default: ''
       t.string :uid, null: false, default: ''
 
diff --git a/db/migrate/20180206000000_change_user_id_nonnullable.rb b/db/migrate/20180206000000_change_user_id_nonnullable.rb
index 2d2cf20d3..119638387 100644
--- a/db/migrate/20180206000000_change_user_id_nonnullable.rb
+++ b/db/migrate/20180206000000_change_user_id_nonnullable.rb
@@ -1,4 +1,4 @@
-class ChangeUserIdNonnullable < ActiveRecord::Migration[5.1]
+class ChangeUserIdNonnullable < ActiveRecord::Migration[5.2]
   def change
     safety_assured do
       change_column_null :invites, :user_id, false
diff --git a/db/migrate/20180211015820_create_backups.rb b/db/migrate/20180211015820_create_backups.rb
index 9725a3e9f..4aaeed83b 100644
--- a/db/migrate/20180211015820_create_backups.rb
+++ b/db/migrate/20180211015820_create_backups.rb
@@ -1,4 +1,4 @@
-class CreateBackups < ActiveRecord::Migration[5.1]
+class CreateBackups < ActiveRecord::Migration[5.2]
   def change
     create_table :backups do |t|
       t.references :user, foreign_key: { on_delete: :nullify }
diff --git a/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb b/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb
index 1964b5121..46842a9e3 100644
--- a/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb
+++ b/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb
@@ -1,4 +1,4 @@
-class AddFeaturedCollectionURLToAccounts < ActiveRecord::Migration[5.1]
+class AddFeaturedCollectionURLToAccounts < ActiveRecord::Migration[5.2]
   def change
     add_column :accounts, :featured_collection_url, :string
   end
diff --git a/db/migrate/20180310000000_change_columns_in_notifications_nonnullable.rb b/db/migrate/20180310000000_change_columns_in_notifications_nonnullable.rb
index dba789207..8577d0235 100644
--- a/db/migrate/20180310000000_change_columns_in_notifications_nonnullable.rb
+++ b/db/migrate/20180310000000_change_columns_in_notifications_nonnullable.rb
@@ -1,4 +1,4 @@
-class ChangeColumnsInNotificationsNonnullable < ActiveRecord::Migration[5.1]
+class ChangeColumnsInNotificationsNonnullable < ActiveRecord::Migration[5.2]
   def change
     safety_assured do
       change_column_null :notifications, :activity_id, false
diff --git a/db/migrate/20180402031200_add_assigned_account_id_to_reports.rb b/db/migrate/20180402031200_add_assigned_account_id_to_reports.rb
index e2d1371d2..27cbd6c2a 100644
--- a/db/migrate/20180402031200_add_assigned_account_id_to_reports.rb
+++ b/db/migrate/20180402031200_add_assigned_account_id_to_reports.rb
@@ -1,4 +1,4 @@
-class AddAssignedAccountIdToReports < ActiveRecord::Migration[5.1]
+class AddAssignedAccountIdToReports < ActiveRecord::Migration[5.2]
   def change
     safety_assured { add_reference :reports, :assigned_account, null: true, default: nil, foreign_key: { on_delete: :nullify, to_table: :accounts }, index: false }
   end
diff --git a/db/migrate/20180402040909_create_report_notes.rb b/db/migrate/20180402040909_create_report_notes.rb
index 429cb4534..5d5a33627 100644
--- a/db/migrate/20180402040909_create_report_notes.rb
+++ b/db/migrate/20180402040909_create_report_notes.rb
@@ -1,4 +1,4 @@
-class CreateReportNotes < ActiveRecord::Migration[5.1]
+class CreateReportNotes < ActiveRecord::Migration[5.2]
   def change
     create_table :report_notes do |t|
       t.text :content, null: false
diff --git a/db/migrate/20180410204633_add_fields_to_accounts.rb b/db/migrate/20180410204633_add_fields_to_accounts.rb
index 5b8c17480..a1b9504b6 100644
--- a/db/migrate/20180410204633_add_fields_to_accounts.rb
+++ b/db/migrate/20180410204633_add_fields_to_accounts.rb
@@ -1,4 +1,4 @@
-class AddFieldsToAccounts < ActiveRecord::Migration[5.1]
+class AddFieldsToAccounts < ActiveRecord::Migration[5.2]
   def change
     add_column :accounts, :fields, :jsonb
   end
diff --git a/db/migrate/20180410220657_create_bookmarks.rb b/db/migrate/20180410220657_create_bookmarks.rb
index bc79022e4..aba21f5ea 100644
--- a/db/migrate/20180410220657_create_bookmarks.rb
+++ b/db/migrate/20180410220657_create_bookmarks.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 # This migration is a duplicate of 20180831171112 and may get ignored, see
 # config/initializers/0_duplicate_migrations.rb
 
diff --git a/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb b/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb
index b29e62803..48d156bef 100644
--- a/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb
+++ b/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb
@@ -1,12 +1,12 @@
 # frozen_string_literal: true
 
-class ImproveIndexOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.1]
+class ImproveIndexOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
   def change
-  #  These changes ware reverted by migration 20180514140000.
-  #  add_index :statuses, [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)', algorithm: :concurrently
-  #  add_index :statuses, [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently
-  #  remove_index :statuses, column: [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106
+    #  These changes were reverted by migration 20180514140000.
+    #  add_index :statuses, [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)', algorithm: :concurrently
+    #  add_index :statuses, [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently
+    #  remove_index :statuses, column: [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106
   end
 end
diff --git a/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb b/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb
index ccd2ec7ea..242ae7410 100644
--- a/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb
+++ b/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb
@@ -1,15 +1,15 @@
 # frozen_string_literal: true
 
-class RevertIndexChangeOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.1]
+class RevertIndexChangeOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
   def change
     safety_assured do
-      add_index :statuses, [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 unless index_name_exists?(:statuses, "index_statuses_20180106")
+      add_index :statuses, [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 unless index_name_exists?(:statuses, 'index_statuses_20180106')
     end
 
     # These index may not exists (see migration 20180514130000)
     remove_index :statuses, column: [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)', algorithm: :concurrently if index_exists?(:statuses, [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)')
-    remove_index :statuses, column: [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently if index_exists?(:statuses, ["account_id", "id"], where: "(visibility = 3)")
+    remove_index :statuses, column: [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently if index_exists?(:statuses, %w(account_id id), where: '(visibility = 3)')
   end
 end
diff --git a/db/migrate/20180528141303_fix_accounts_unique_index.rb b/db/migrate/20180528141303_fix_accounts_unique_index.rb
index 3e33e2cac..1e67b4bb4 100644
--- a/db/migrate/20180528141303_fix_accounts_unique_index.rb
+++ b/db/migrate/20180528141303_fix_accounts_unique_index.rb
@@ -1,4 +1,8 @@
+require_relative '../../lib/mastodon/migration_warning'
+
 class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2]
+  include Mastodon::MigrationWarning
+
   class Account < ApplicationRecord
     # Dummy class, to make migration possible across version changes
     has_one :user, inverse_of: :account
@@ -35,22 +39,11 @@ class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
   def up
-    if $stdout.isatty
-      say ''
-      say 'WARNING: This migration may take a *long* time for large instances'
-      say 'It will *not* lock tables for any significant time, but it may run'
-      say 'for a very long time. We will pause for 10 seconds to allow you to'
-      say 'interrupt this migration if you are not ready.'
-      say ''
-      say 'This migration will irreversibly delete user accounts with duplicate'
-      say 'usernames. You may use the `rake mastodon:maintenance:find_duplicate_usernames`'
-      say 'task to manually deal with such accounts before running this migration.'
-
-      10.downto(1) do |i|
-        say "Continuing in #{i} second#{i == 1 ? '' : 's'}...", true
-        sleep 1
-      end
-    end
+    migration_duration_warning(<<~EXPLANATION)
+      This migration will irreversibly delete user accounts with duplicate
+      usernames. You may use the `rake mastodon:maintenance:find_duplicate_usernames`
+      task to manually deal with such accounts before running this migration.
+    EXPLANATION
 
     duplicates = Account.connection.select_all('SELECT string_agg(id::text, \',\') AS ids FROM accounts GROUP BY lower(username), lower(domain) HAVING count(*) > 1').to_ary
 
@@ -106,21 +99,17 @@ class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2]
     # to check for (and skip past) uniqueness errors
     [Favourite, Follow, FollowRequest, Block, Mute].each do |klass|
       klass.where(account_id: duplicate_account.id).find_each do |record|
-        begin
-          record.update_attribute(:account_id, main_account.id)
-        rescue ActiveRecord::RecordNotUnique
-          next
-        end
+        record.update_attribute(:account_id, main_account.id)
+      rescue ActiveRecord::RecordNotUnique
+        next
       end
     end
 
     [Follow, FollowRequest, Block, Mute].each do |klass|
       klass.where(target_account_id: duplicate_account.id).find_each do |record|
-        begin
-          record.update_attribute(:target_account_id, main_account.id)
-        rescue ActiveRecord::RecordNotUnique
-          next
-        end
+        record.update_attribute(:target_account_id, main_account.id)
+      rescue ActiveRecord::RecordNotUnique
+        next
       end
     end
   end
diff --git a/db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb b/db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb
index cd97d0f20..8078a07bf 100644
--- a/db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb
+++ b/db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'mastodon/migration_helpers'
 
 class AddApplyToMentionsFlagToKeywordMutes < ActiveRecord::Migration[5.2]
diff --git a/db/migrate/20180707193142_migrate_filters.rb b/db/migrate/20180707193142_migrate_filters.rb
index 067c53357..8f6b3e1bb 100644
--- a/db/migrate/20180707193142_migrate_filters.rb
+++ b/db/migrate/20180707193142_migrate_filters.rb
@@ -1,7 +1,9 @@
+# frozen_string_literal: true
+
 class MigrateFilters < ActiveRecord::Migration[5.2]
   class GlitchKeywordMute < ApplicationRecord
     # Dummy class, as we removed Glitch::KeywordMute
-    belongs_to :account, required: true
+    belongs_to :account, optional: false
     validates_presence_of :keyword
   end
 
@@ -15,7 +17,7 @@ class MigrateFilters < ActiveRecord::Migration[5.2]
     private
 
     def clean_up_contexts
-      self.context = Array(context).map(&:strip).map(&:presence).compact
+      self.context = Array(context).map(&:strip).filter_map(&:presence)
     end
   end
 
@@ -27,7 +29,8 @@ class MigrateFilters < ActiveRecord::Migration[5.2]
         phrase: filter.keyword,
         context: filter.apply_to_mentions ? %w(home public notifications) : %w(home public),
         whole_word: filter.whole_word,
-        irreversible: true)
+        irreversible: true
+      )
     end
   end
 
@@ -48,7 +51,8 @@ class MigrateFilters < ActiveRecord::Migration[5.2]
       GlitchKeywordMute.where(account: filter.account).create!(
         keyword: filter.phrase,
         whole_word: filter.whole_word,
-        apply_to_mentions: filter.context.include?('notifications'))
+        apply_to_mentions: filter.context.include?('notifications')
+      )
     end
   end
 end
diff --git a/db/migrate/20180812173710_copy_status_stats.rb b/db/migrate/20180812173710_copy_status_stats.rb
index ff10c18d9..45eb9501c 100644
--- a/db/migrate/20180812173710_copy_status_stats.rb
+++ b/db/migrate/20180812173710_copy_status_stats.rb
@@ -19,7 +19,7 @@ class CopyStatusStats < ActiveRecord::Migration[5.2]
 
   def supports_upsert?
     version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i
-    version >= 90500
+    version >= 90_500
   end
 
   def up_fast
@@ -43,12 +43,10 @@ class CopyStatusStats < ActiveRecord::Migration[5.2]
     # We cannot use bulk INSERT or overarching transactions here because of possible
     # uniqueness violations that we need to skip over
     Status.unscoped.select('id, reblogs_count, favourites_count, created_at, updated_at').find_each do |status|
-      begin
-        params = [[nil, status.id], [nil, status.reblogs_count], [nil, status.favourites_count], [nil, status.created_at], [nil, status.updated_at]]
-        exec_insert('INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)', nil, params)
-      rescue ActiveRecord::RecordNotUnique
-        next
-      end
+      params = [[nil, status.id], [nil, status.reblogs_count], [nil, status.favourites_count], [nil, status.created_at], [nil, status.updated_at]]
+      exec_insert('INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)', nil, params)
+    rescue ActiveRecord::RecordNotUnique
+      next
     end
   end
 end
diff --git a/db/migrate/20180831171112_create_bookmarks.rb b/db/migrate/20180831171112_create_bookmarks.rb
index 5d587b7e9..9f6bfae57 100644
--- a/db/migrate/20180831171112_create_bookmarks.rb
+++ b/db/migrate/20180831171112_create_bookmarks.rb
@@ -1,7 +1,7 @@
 # This migration is a duplicate of 20180410220657 and may get ignored, see
 # config/initializers/0_duplicate_migrations.rb
 
-class CreateBookmarks < ActiveRecord::Migration[5.1]
+class CreateBookmarks < ActiveRecord::Migration[5.2]
   def change
     create_table :bookmarks do |t|
       t.references :account, null: false
diff --git a/db/migrate/20181024224956_migrate_account_conversations.rb b/db/migrate/20181024224956_migrate_account_conversations.rb
index 9e6497d81..e4dcdb18b 100644
--- a/db/migrate/20181024224956_migrate_account_conversations.rb
+++ b/db/migrate/20181024224956_migrate_account_conversations.rb
@@ -1,4 +1,8 @@
+require_relative '../../lib/mastodon/migration_warning'
+
 class MigrateAccountConversations < ActiveRecord::Migration[5.2]
+  include Mastodon::MigrationWarning
+
   disable_ddl_transaction!
 
   class Mention < ApplicationRecord
@@ -62,19 +66,7 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2]
   end
 
   def up
-    if $stdout.isatty
-      say ''
-      say 'WARNING: This migration may take a *long* time for large instances'
-      say 'It will *not* lock tables for any significant time, but it may run'
-      say 'for a very long time. We will pause for 10 seconds to allow you to'
-      say 'interrupt this migration if you are not ready.'
-      say ''
-
-      10.downto(1) do |i|
-        say "Continuing in #{i} second#{i == 1 ? '' : 's'}...", true
-        sleep 1
-      end
-    end
+    migration_duration_warning
 
     migrated  = 0
     last_time = Time.zone.now
@@ -100,8 +92,7 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2]
     end
   end
 
-  def down
-  end
+  def down; end
 
   private
 
diff --git a/db/migrate/20181116173541_copy_account_stats.rb b/db/migrate/20181116173541_copy_account_stats.rb
index 8e27eb11b..f908575cb 100644
--- a/db/migrate/20181116173541_copy_account_stats.rb
+++ b/db/migrate/20181116173541_copy_account_stats.rb
@@ -19,7 +19,7 @@ class CopyAccountStats < ActiveRecord::Migration[5.2]
 
   def supports_upsert?
     version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i
-    version >= 90500
+    version >= 90_500
   end
 
   def up_fast
@@ -43,12 +43,10 @@ class CopyAccountStats < ActiveRecord::Migration[5.2]
     # We cannot use bulk INSERT or overarching transactions here because of possible
     # uniqueness violations that we need to skip over
     Account.unscoped.select('id, statuses_count, following_count, followers_count, created_at, updated_at').find_each do |account|
-      begin
-        params = [[nil, account.id], [nil, account[:statuses_count]], [nil, account[:following_count]], [nil, account[:followers_count]], [nil, account.created_at], [nil, account.updated_at]]
-        exec_insert('INSERT INTO account_stats (account_id, statuses_count, following_count, followers_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6)', nil, params)
-      rescue ActiveRecord::RecordNotUnique
-        next
-      end
+      params = [[nil, account.id], [nil, account[:statuses_count]], [nil, account[:following_count]], [nil, account[:followers_count]], [nil, account.created_at], [nil, account.updated_at]]
+      exec_insert('INSERT INTO account_stats (account_id, statuses_count, following_count, followers_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6)', nil, params)
+    rescue ActiveRecord::RecordNotUnique
+      next
     end
   end
 end
diff --git a/db/migrate/20190306145741_add_lock_version_to_polls.rb b/db/migrate/20190306145741_add_lock_version_to_polls.rb
index 5bb8cd3b4..c9fa471ad 100644
--- a/db/migrate/20190306145741_add_lock_version_to_polls.rb
+++ b/db/migrate/20190306145741_add_lock_version_to_polls.rb
@@ -21,4 +21,3 @@ class AddLockVersionToPolls < ActiveRecord::Migration[5.2]
     remove_column :polls, :lock_version
   end
 end
-
diff --git a/db/migrate/20190314181829_migrate_open_registrations_setting.rb b/db/migrate/20190314181829_migrate_open_registrations_setting.rb
index e5fe95009..d2f6bf2c1 100644
--- a/db/migrate/20190314181829_migrate_open_registrations_setting.rb
+++ b/db/migrate/20190314181829_migrate_open_registrations_setting.rb
@@ -2,6 +2,7 @@ class MigrateOpenRegistrationsSetting < ActiveRecord::Migration[5.2]
   def up
     open_registrations = Setting.find_by(var: 'open_registrations')
     return if open_registrations.nil? || open_registrations.value
+
     setting = Setting.where(var: 'registrations_mode').first_or_initialize(var: 'registrations_mode')
     setting.update(value: 'none')
   end
@@ -9,6 +10,7 @@ class MigrateOpenRegistrationsSetting < ActiveRecord::Migration[5.2]
   def down
     registrations_mode = Setting.find_by(var: 'registrations_mode')
     return if registrations_mode.nil?
+
     setting = Setting.where(var: 'open_registrations').first_or_initialize(var: 'open_registrations')
     setting.update(value: registrations_mode.value == 'open')
   end
diff --git a/db/migrate/20190512200918_add_content_type_to_statuses.rb b/db/migrate/20190512200918_add_content_type_to_statuses.rb
index efbe2caa7..31c1a4f17 100644
--- a/db/migrate/20190512200918_add_content_type_to_statuses.rb
+++ b/db/migrate/20190512200918_add_content_type_to_statuses.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class AddContentTypeToStatuses < ActiveRecord::Migration[5.2]
   def change
     add_column :statuses, :content_type, :string
diff --git a/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb b/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb
index 72b7c609d..1c18b85cb 100644
--- a/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb
+++ b/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb
@@ -8,10 +8,10 @@ class PreserveOldLayoutForExistingUsers < ActiveRecord::Migration[5.2]
 
     User.where(User.arel_table[:current_sign_in_at].gteq(1.month.ago)).find_each do |user|
       next if Setting.unscoped.where(thing_type: 'User', thing_id: user.id, var: 'advanced_layout').exists?
+
       user.settings.advanced_layout = true
     end
   end
 
-  def down
-  end
+  def down; end
 end
diff --git a/db/migrate/20190807135426_add_comments_to_domain_blocks.rb b/db/migrate/20190807135426_add_comments_to_domain_blocks.rb
index b660a71ad..79b9f0212 100644
--- a/db/migrate/20190807135426_add_comments_to_domain_blocks.rb
+++ b/db/migrate/20190807135426_add_comments_to_domain_blocks.rb
@@ -4,4 +4,3 @@ class AddCommentsToDomainBlocks < ActiveRecord::Migration[5.2]
     add_column :domain_blocks, :public_comment, :text
   end
 end
-
diff --git a/db/migrate/20191031163205_change_list_account_follow_nullable.rb b/db/migrate/20191031163205_change_list_account_follow_nullable.rb
index 65ff93365..43ebfe892 100644
--- a/db/migrate/20191031163205_change_list_account_follow_nullable.rb
+++ b/db/migrate/20191031163205_change_list_account_follow_nullable.rb
@@ -1,4 +1,4 @@
-class ChangeListAccountFollowNullable < ActiveRecord::Migration[5.1]
+class ChangeListAccountFollowNullable < ActiveRecord::Migration[5.2]
   def change
     safety_assured do
       change_column_null :list_accounts, :follow_id, true
diff --git a/db/migrate/20200312162302_add_status_ids_to_announcements.rb b/db/migrate/20200312162302_add_status_ids_to_announcements.rb
index 42aa6513d..704d3773e 100644
--- a/db/migrate/20200312162302_add_status_ids_to_announcements.rb
+++ b/db/migrate/20200312162302_add_status_ids_to_announcements.rb
@@ -3,4 +3,3 @@ class AddStatusIdsToAnnouncements < ActiveRecord::Migration[5.2]
     add_column :announcements, :status_ids, :bigint, array: true
   end
 end
-
diff --git a/db/migrate/20200407202420_migrate_unavailable_inboxes.rb b/db/migrate/20200407202420_migrate_unavailable_inboxes.rb
index 92a3acb5d..8f9c68794 100644
--- a/db/migrate/20200407202420_migrate_unavailable_inboxes.rb
+++ b/db/migrate/20200407202420_migrate_unavailable_inboxes.rb
@@ -2,7 +2,8 @@ class MigrateUnavailableInboxes < ActiveRecord::Migration[5.2]
   disable_ddl_transaction!
 
   def up
-    urls = Redis.current.smembers('unavailable_inboxes')
+    redis = RedisConfiguration.pool.checkout
+    urls = redis.smembers('unavailable_inboxes')
 
     hosts = urls.map do |url|
       Addressable::URI.parse(url).normalized_host
@@ -14,7 +15,7 @@ class MigrateUnavailableInboxes < ActiveRecord::Migration[5.2]
       UnavailableDomain.create(domain: host)
     end
 
-    Redis.current.del(*(['unavailable_inboxes'] + Redis.current.keys('exhausted_deliveries:*')))
+    redis.del(*(['unavailable_inboxes'] + redis.keys('exhausted_deliveries:*')))
   end
 
   def down; end
diff --git a/db/migrate/20200510110808_reset_web_app_secret.rb b/db/migrate/20200510110808_reset_web_app_secret.rb
index b274844c5..8c0c06a83 100644
--- a/db/migrate/20200510110808_reset_web_app_secret.rb
+++ b/db/migrate/20200510110808_reset_web_app_secret.rb
@@ -10,6 +10,5 @@ class ResetWebAppSecret < ActiveRecord::Migration[5.2]
     web_app.save!
   end
 
-  def down
-  end
+  def down; end
 end
diff --git a/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb b/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb
index 1d6ba1fe9..59bb1b9e2 100644
--- a/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb
+++ b/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb
@@ -19,4 +19,3 @@ class RemoveDuplicatedIndexesPghero < ActiveRecord::Migration[5.2]
     add_index :markers, :user_id, name: :index_markers_on_user_id                                       unless index_exists?(:markers, :user_id, name: :index_markers_on_user_id)
   end
 end
-
diff --git a/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb b/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb
index 24d43a0bf..c5c80b795 100644
--- a/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb
+++ b/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb
@@ -6,7 +6,7 @@ class EncryptedMessageIdsToTimestampIds < ActiveRecord::Migration[5.2]
   end
 
   def down
-    execute("LOCK encrypted_messages")
+    execute('LOCK encrypted_messages')
     execute("SELECT setval('encrypted_messages_id_seq', (SELECT MAX(id) FROM encrypted_messages))")
     execute("ALTER TABLE encrypted_messages ALTER COLUMN id SET DEFAULT nextval('encrypted_messages_id_seq')")
   end
diff --git a/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb b/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb
index 652ce9752..b350ee9f2 100644
--- a/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb
+++ b/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb
@@ -16,7 +16,7 @@ class AddFixedLowercaseIndexToAccounts < ActiveRecord::Migration[5.2]
       add_index :accounts, "lower (username), COALESCE(lower(domain), '')", name: 'index_accounts_on_username_and_domain_lower', unique: true, algorithm: :concurrently
     rescue ActiveRecord::RecordNotUnique
       remove_index :accounts, name: 'index_accounts_on_username_and_domain_lower'
-      raise CorruptionError.new('index_accounts_on_username_and_domain_lower')
+      raise CorruptionError, 'index_accounts_on_username_and_domain_lower'
     end
 
     remove_index :accounts, name: 'old_index_accounts_on_username_and_domain_lower' if index_name_exists?(:accounts, 'old_index_accounts_on_username_and_domain_lower')
diff --git a/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb b/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb
index 5c6865b92..7c141e7af 100644
--- a/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb
+++ b/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb
@@ -1,4 +1,4 @@
-class MediaAttachmentIdsToTimestampIds < ActiveRecord::Migration[5.1]
+class MediaAttachmentIdsToTimestampIds < ActiveRecord::Migration[5.2]
   def up
     # Set up the media_attachments.id column to use our timestamp-based IDs.
     safety_assured do
@@ -10,7 +10,7 @@ class MediaAttachmentIdsToTimestampIds < ActiveRecord::Migration[5.1]
   end
 
   def down
-    execute("LOCK media_attachments")
+    execute('LOCK media_attachments')
     execute("SELECT setval('media_attachments_id_seq', (SELECT MAX(id) FROM media_attachments))")
     execute("ALTER TABLE media_attachments ALTER COLUMN id SET DEFAULT nextval('media_attachments_id_seq')")
   end
diff --git a/db/migrate/20200628133322_create_account_notes.rb b/db/migrate/20200628133322_create_account_notes.rb
index 664727e60..022e0ff3a 100644
--- a/db/migrate/20200628133322_create_account_notes.rb
+++ b/db/migrate/20200628133322_create_account_notes.rb
@@ -10,4 +10,3 @@ class CreateAccountNotes < ActiveRecord::Migration[5.2]
     end
   end
 end
-
diff --git a/db/migrate/20200917192924_add_notify_to_follows.rb b/db/migrate/20200917192924_add_notify_to_follows.rb
index d27471c44..342eaa38d 100644
--- a/db/migrate/20200917192924_add_notify_to_follows.rb
+++ b/db/migrate/20200917192924_add_notify_to_follows.rb
@@ -1,6 +1,6 @@
 require Rails.root.join('lib', 'mastodon', 'migration_helpers')
 
-class AddNotifyToFollows < ActiveRecord::Migration[5.1]
+class AddNotifyToFollows < ActiveRecord::Migration[5.2]
   include Mastodon::MigrationHelpers
 
   disable_ddl_transaction!
diff --git a/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb b/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb
index 39cd4cdea..b287c60dd 100644
--- a/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb
+++ b/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb
@@ -1,4 +1,4 @@
-class AccountIdsToTimestampIds < ActiveRecord::Migration[5.1]
+class AccountIdsToTimestampIds < ActiveRecord::Migration[5.2]
   def up
     # Set up the accounts.id column to use our timestamp-based IDs.
     safety_assured do
@@ -10,7 +10,7 @@ class AccountIdsToTimestampIds < ActiveRecord::Migration[5.1]
   end
 
   def down
-    execute("LOCK accounts")
+    execute('LOCK accounts')
     execute("SELECT setval('accounts_id_seq', (SELECT MAX(id) FROM accounts))")
     execute("ALTER TABLE accounts ALTER COLUMN id SET DEFAULT nextval('accounts_id_seq')")
   end
diff --git a/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb b/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb
index b3ee11d09..a3cc854d7 100644
--- a/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb
+++ b/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb
@@ -10,7 +10,8 @@ class AddCaseInsensitiveBtreeIndexToTags < ActiveRecord::Migration[5.2]
       safety_assured { execute 'CREATE UNIQUE INDEX CONCURRENTLY index_tags_on_name_lower_btree ON tags (lower(name) text_pattern_ops)' }
     rescue ActiveRecord::StatementInvalid => e
       remove_index :tags, name: 'index_tags_on_name_lower_btree'
-      raise CorruptionError.new('index_tags_on_name_lower_btree') if e.is_a?(ActiveRecord::RecordNotUnique)
+      raise CorruptionError, 'index_tags_on_name_lower_btree' if e.is_a?(ActiveRecord::RecordNotUnique)
+
       raise e
     end
 
diff --git a/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb b/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb
index 28cfb6ef5..db168676a 100644
--- a/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb
+++ b/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb
@@ -17,4 +17,3 @@ class CreateAccountStatusesCleanupPolicies < ActiveRecord::Migration[6.1]
     end
   end
 end
-
diff --git a/db/migrate/20220209175231_add_content_type_to_status_edits.rb b/db/migrate/20220209175231_add_content_type_to_status_edits.rb
index 0e4e52fcb..bb414535d 100644
--- a/db/migrate/20220209175231_add_content_type_to_status_edits.rb
+++ b/db/migrate/20220209175231_add_content_type_to_status_edits.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 class AddContentTypeToStatusEdits < ActiveRecord::Migration[6.1]
   def change
     add_column :status_edits, :content_type, :string
diff --git a/db/migrate/20220613110834_add_action_to_custom_filters.rb b/db/migrate/20220613110834_add_action_to_custom_filters.rb
index 9427a66fc..c1daf3c94 100644
--- a/db/migrate/20220613110834_add_action_to_custom_filters.rb
+++ b/db/migrate/20220613110834_add_action_to_custom_filters.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+
 require Rails.root.join('lib', 'mastodon', 'migration_helpers')
 
 class AddActionToCustomFilters < ActiveRecord::Migration[6.1]
diff --git a/db/migrate/20230215074327_add_settings_to_users.rb b/db/migrate/20230215074327_add_settings_to_users.rb
new file mode 100644
index 000000000..ff5308f42
--- /dev/null
+++ b/db/migrate/20230215074327_add_settings_to_users.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddSettingsToUsers < ActiveRecord::Migration[6.1]
+  def change
+    add_column :users, :settings, :text
+  end
+end
diff --git a/db/migrate/20230215074423_move_user_settings.rb b/db/migrate/20230215074423_move_user_settings.rb
new file mode 100644
index 000000000..8dbca9ecd
--- /dev/null
+++ b/db/migrate/20230215074423_move_user_settings.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+class MoveUserSettings < ActiveRecord::Migration[6.1]
+  class User < ApplicationRecord; end
+
+  MAPPING = {
+    default_privacy: 'default_privacy',
+    default_sensitive: 'web.default_sensitive',
+    default_language: 'default_language',
+    noindex: 'noindex',
+    theme: 'theme',
+    trends: 'web.trends',
+    unfollow_modal: 'web.unfollow_modal',
+    boost_modal: 'web.reblog_modal',
+    delete_modal: 'web.delete_modal',
+    auto_play_gif: 'web.auto_play',
+    display_media: 'web.display_media',
+    expand_spoilers: 'web.expand_content_warnings',
+    reduce_motion: 'web.reduce_motion',
+    disable_swiping: 'web.disable_swiping',
+    show_application: 'show_application',
+    system_font_ui: 'web.use_system_font',
+    aggregate_reblogs: 'aggregate_reblogs',
+    advanced_layout: 'web.advanced_layout',
+    use_blurhash: 'web.use_blurhash',
+    use_pending_items: 'web.use_pending_items',
+    crop_images: 'web.crop_images',
+    notification_emails: {
+      follow: 'notification_emails.follow',
+      reblog: 'notification_emails.reblog',
+      favourite: 'notification_emails.favourite',
+      mention: 'notification_emails.mention',
+      follow_request: 'notification_emails.follow_request',
+      report: 'notification_emails.report',
+      pending_account: 'notification_emails.pending_account',
+      trending_tag: 'notification_emails.trends',
+      appeal: 'notification_emails.appeal',
+    }.freeze,
+    always_send_emails: 'always_send_emails',
+    interactions: {
+      must_be_follower: 'interactions.must_be_follower',
+      must_be_following: 'interactions.must_be_following',
+      must_be_following_dm: 'interactions.must_be_following_dm',
+    }.freeze,
+  }.freeze
+
+  class LegacySetting < ApplicationRecord
+    self.table_name = 'settings'
+
+    def var
+      self[:var]&.to_sym
+    end
+
+    def value
+      YAML.safe_load(self[:value], permitted_classes: [ActiveSupport::HashWithIndifferentAccess, Symbol]) if self[:value].present?
+    end
+  end
+
+  def up
+    User.find_each do |user|
+      previous_settings = LegacySetting.where(thing_type: 'User', thing_id: user.id).index_by(&:var)
+
+      user_settings = {}
+
+      MAPPING.each do |legacy_key, new_key|
+        value = previous_settings[legacy_key]&.value
+
+        next if value.blank?
+
+        if value.is_a?(Hash)
+          value.each do |nested_key, nested_value|
+            user_settings[MAPPING[legacy_key][nested_key.to_sym]] = nested_value
+          end
+        else
+          user_settings[new_key] = value
+        end
+      end
+
+      user.update_column('settings', Oj.dump(user_settings)) # rubocop:disable Rails/SkipsModelValidations
+    end
+  end
+
+  def down; end
+end
diff --git a/db/migrate/20230215074424_move_glitch_user_settings.rb b/db/migrate/20230215074424_move_glitch_user_settings.rb
new file mode 100644
index 000000000..76fafdd76
--- /dev/null
+++ b/db/migrate/20230215074424_move_glitch_user_settings.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+class MoveGlitchUserSettings < ActiveRecord::Migration[6.1]
+  class User < ApplicationRecord; end
+
+  MAPPING = {
+    favourite_modal: 'web.favourite_modal',
+    system_emoji_font: 'web.use_system_emoji_font',
+    hide_followers_count: 'hide_followers_count',
+    default_content_type: 'default_content_type',
+    flavour: 'flavour',
+    skin: 'skin',
+    notification_emails: {
+      trending_link: 'notification_emails.link_trends',
+      trending_status: 'notification_emails.status_trends',
+    }.freeze,
+  }.freeze
+
+  class LegacySetting < ApplicationRecord
+    self.table_name = 'settings'
+
+    def var
+      self[:var]&.to_sym
+    end
+
+    def value
+      YAML.safe_load(self[:value], permitted_classes: [ActiveSupport::HashWithIndifferentAccess, Symbol]) if self[:value].present?
+    end
+  end
+
+  def up
+    User.find_each do |user|
+      previous_settings = LegacySetting.where(thing_type: 'User', thing_id: user.id).index_by(&:var)
+
+      user_settings = Oj.load(user.settings || '{}')
+      user_settings.delete('theme')
+
+      MAPPING.each do |legacy_key, new_key|
+        value = previous_settings[legacy_key]&.value
+
+        next if value.blank?
+
+        if value.is_a?(Hash)
+          value.each do |nested_key, nested_value|
+            user_settings[MAPPING[legacy_key][nested_key.to_sym]] = nested_value
+          end
+        else
+          user_settings[new_key] = value
+        end
+      end
+
+      user.update_column('settings', Oj.dump(user_settings)) # rubocop:disable Rails/SkipsModelValidations
+    end
+  end
+
+  def down; end
+end