50 lines
		
	
	
		
			992 B
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			50 lines
		
	
	
		
			992 B
		
	
	
	
		
			Ruby
		
	
	
	
	
	
# frozen_string_literal: true
 | 
						|
 | 
						|
class AddIndexToIdentitiesUidProvider < ActiveRecord::Migration[7.0]
 | 
						|
  disable_ddl_transaction!
 | 
						|
 | 
						|
  def up
 | 
						|
    add_index_to_table
 | 
						|
  rescue ActiveRecord::RecordNotUnique
 | 
						|
    remove_duplicates_and_reindex
 | 
						|
  end
 | 
						|
 | 
						|
  def down
 | 
						|
    remove_index_from_table
 | 
						|
  end
 | 
						|
 | 
						|
  private
 | 
						|
 | 
						|
  def remove_duplicates_and_reindex
 | 
						|
    deduplicate_records
 | 
						|
    reindex_records
 | 
						|
  rescue ActiveRecord::RecordNotUnique
 | 
						|
    retry
 | 
						|
  end
 | 
						|
 | 
						|
  def reindex_records
 | 
						|
    remove_index_from_table
 | 
						|
    add_index_to_table
 | 
						|
  end
 | 
						|
 | 
						|
  def add_index_to_table
 | 
						|
    add_index :identities, [:uid, :provider], unique: true, algorithm: :concurrently
 | 
						|
  end
 | 
						|
 | 
						|
  def remove_index_from_table
 | 
						|
    remove_index :identities, [:uid, :provider]
 | 
						|
  end
 | 
						|
 | 
						|
  def deduplicate_records
 | 
						|
    safety_assured do
 | 
						|
      execute <<~SQL.squish
 | 
						|
        DELETE FROM identities
 | 
						|
          WHERE id NOT IN (
 | 
						|
          SELECT DISTINCT ON(uid, provider) id FROM identities
 | 
						|
          ORDER BY uid, provider, id ASC
 | 
						|
        )
 | 
						|
      SQL
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |