DEV: Migrate shelved_notifications#notification_id to bigint (#28549)
DEV: Migrate shelved_notifications#notification_id to bigint
The `notifications.id` has been migrated to `bigint` in previous commit
799a45a291
.
This commit is contained in:
parent
82b50ab7a7
commit
ec8ba5a0b9
|
@ -1,6 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Notification < ActiveRecord::Base
|
class Notification < ActiveRecord::Base
|
||||||
|
self.ignored_columns = [
|
||||||
|
:old_id, # TODO: Remove when column is dropped. At this point, the migration to drop the column has not been writted.
|
||||||
|
]
|
||||||
|
|
||||||
attr_accessor :acting_user
|
attr_accessor :acting_user
|
||||||
attr_accessor :acting_username
|
attr_accessor :acting_username
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ShelvedNotification < ActiveRecord::Base
|
class ShelvedNotification < ActiveRecord::Base
|
||||||
|
self.ignored_columns = [
|
||||||
|
:old_notification_id, # TODO: Remove when column is dropped. At this point, the migration to drop the column has not been writted.
|
||||||
|
]
|
||||||
|
|
||||||
belongs_to :notification
|
belongs_to :notification
|
||||||
|
|
||||||
def process
|
def process
|
||||||
|
@ -12,8 +16,9 @@ end
|
||||||
#
|
#
|
||||||
# Table name: shelved_notifications
|
# Table name: shelved_notifications
|
||||||
#
|
#
|
||||||
# id :bigint not null, primary key
|
# id :bigint not null, primary key
|
||||||
# notification_id :integer not null
|
# old_notification_id :integer
|
||||||
|
# notification_id :bigint not null
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddBigIntShelvedNotificationsNotificationId < ActiveRecord::Migration[7.0]
|
||||||
|
def up
|
||||||
|
# Create new column
|
||||||
|
execute "ALTER TABLE shelved_notifications ADD COLUMN new_notification_id BIGINT NOT NULL DEFAULT 0"
|
||||||
|
|
||||||
|
# Mirror new `notification_id` values to `new_notification_id`
|
||||||
|
execute <<~SQL.squish
|
||||||
|
CREATE FUNCTION mirror_user_badges_notification_id()
|
||||||
|
RETURNS trigger AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
NEW.new_notification_id = NEW.notification_id;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
SQL
|
||||||
|
|
||||||
|
execute <<~SQL.squish
|
||||||
|
CREATE TRIGGER user_badges_new_notification_id_trigger BEFORE INSERT ON shelved_notifications
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE mirror_user_badges_notification_id()
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,20 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class CopyShelvedNotificationsNotificationIdValues < ActiveRecord::Migration[7.0]
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def up
|
||||||
|
min_id, max_id = execute("SELECT MIN(id), MAX(id) FROM shelved_notifications")[0].values
|
||||||
|
batch_size = 10_000
|
||||||
|
|
||||||
|
(min_id..max_id).step(batch_size) { |start_id| execute <<~SQL.squish } if min_id && max_id
|
||||||
|
UPDATE shelved_notifications
|
||||||
|
SET new_notification_id = notification_id
|
||||||
|
WHERE id >= #{start_id} AND id < #{start_id + batch_size} AND notification_id != new_notification_id
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,14 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class CopyShelvedNotificationsNotificationIdIndexes < ActiveRecord::Migration[7.0]
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def up
|
||||||
|
execute "DROP INDEX #{Rails.env.test? ? "" : "CONCURRENTLY"} IF EXISTS index_shelved_notifications_on_new_notification_id"
|
||||||
|
execute "CREATE INDEX #{Rails.env.test? ? "" : "CONCURRENTLY"} index_shelved_notifications_on_new_notification_id ON shelved_notifications (new_notification_id)"
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,32 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class SwapBigIntShelvedNotificationsNotificationId < ActiveRecord::Migration[7.0]
|
||||||
|
def up
|
||||||
|
# Necessary to rename columns and drop triggers/functions
|
||||||
|
Migration::SafeMigrate.disable!
|
||||||
|
|
||||||
|
# Drop trigger and function used to replicate new values
|
||||||
|
execute "DROP TRIGGER user_badges_new_notification_id_trigger ON shelved_notifications"
|
||||||
|
execute "DROP FUNCTION mirror_user_badges_notification_id()"
|
||||||
|
|
||||||
|
execute "ALTER TABLE shelved_notifications ALTER COLUMN new_notification_id DROP DEFAULT"
|
||||||
|
|
||||||
|
# Swap columns
|
||||||
|
execute "ALTER TABLE shelved_notifications RENAME COLUMN notification_id TO old_notification_id"
|
||||||
|
execute "ALTER TABLE shelved_notifications RENAME COLUMN new_notification_id TO notification_id"
|
||||||
|
|
||||||
|
# Keep old column and mark it as read only
|
||||||
|
execute "ALTER TABLE shelved_notifications ALTER COLUMN old_notification_id DROP NOT NULL"
|
||||||
|
Migration::ColumnDropper.mark_readonly(:shelved_notifications, :old_notification_id)
|
||||||
|
|
||||||
|
# Rename indexes
|
||||||
|
execute "DROP INDEX IF EXISTS index_shelved_notifications_on_notification_id"
|
||||||
|
execute "ALTER INDEX index_shelved_notifications_on_new_notification_id RENAME TO index_shelved_notifications_on_notification_id"
|
||||||
|
ensure
|
||||||
|
Migration::SafeMigrate.enable!
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue