DEV: Migrate user_badges#notification_id to bigint (#28546)
The `notifications.id` has been migrated to bigint in previous commit
799a45a291
. This commit migrates one of
the related columns, `user_badges.notification_id`, to `bigint`.
This commit is contained in:
parent
c4ba4c5742
commit
b11d901e12
|
@ -1,6 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class UserBadge < 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 :badge
|
||||
belongs_to :user
|
||||
belongs_to :granted_by, class_name: "User"
|
||||
|
@ -120,11 +124,11 @@ end
|
|||
# granted_at :datetime not null
|
||||
# granted_by_id :integer not null
|
||||
# post_id :integer
|
||||
# notification_id :integer
|
||||
# seq :integer default(0), not null
|
||||
# featured_rank :integer
|
||||
# created_at :datetime not null
|
||||
# is_favorite :boolean
|
||||
# notification_id :bigint
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddBigIntUserBadgesNotificationId < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
# Create new column
|
||||
execute "ALTER TABLE user_badges ADD COLUMN new_notification_id BIGINT"
|
||||
|
||||
# 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 user_badges
|
||||
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 CopyUserBadgesNotificationIdValues < ActiveRecord::Migration[7.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
min_id, max_id = execute("SELECT MIN(id), MAX(id) FROM user_badges")[0].values
|
||||
batch_size = 10_000
|
||||
|
||||
(min_id..max_id).step(batch_size) { |start_id| execute <<~SQL.squish } if min_id && max_id
|
||||
UPDATE user_badges
|
||||
SET new_notification_id = notification_id
|
||||
WHERE id >= #{start_id} AND id < #{start_id + batch_size} AND notification_id IS NOT NULL AND new_notification_id IS NULL
|
||||
SQL
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SwapBigIntUserBadgesNotificationId < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
# Necessary to rename and drop columns
|
||||
Migration::SafeMigrate.disable!
|
||||
|
||||
# Drop trigger and function used to replicate new values
|
||||
execute "DROP TRIGGER user_badges_new_notification_id_trigger ON user_badges"
|
||||
execute "DROP FUNCTION mirror_user_badges_notification_id()"
|
||||
|
||||
# Swap columns
|
||||
execute "ALTER TABLE user_badges RENAME COLUMN notification_id TO old_notification_id"
|
||||
execute "ALTER TABLE user_badges RENAME COLUMN new_notification_id TO notification_id"
|
||||
|
||||
# Keep old column and mark it as read only
|
||||
Migration::ColumnDropper.mark_readonly(:user_badges, :old_notification_id)
|
||||
ensure
|
||||
Migration::SafeMigrate.enable!
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue