class ReconcileMaterialSyncSuppressions < ActiveRecord::Migration[8.0] MATERIAL_VERSION_EVENT_CONSTRAINT = 'material_versions_event_type_valid' def up ensure_material_sync_suppressions! ensure_material_source_columns! ensure_material_active_source_key! remove_material_file_suppression! remove_material_version_file_suppression! reconcile_material_version_event_constraint! end def down raise ActiveRecord::IrreversibleMigration end private def ensure_material_sync_suppressions! return if table_exists?(:material_sync_suppressions) create_table :material_sync_suppressions do |t| t.string :source_kind, null: false t.string :source_uri t.string :drive_path t.string :drive_file_id t.string :normalized_source_key, null: false t.string :reason, null: false t.references :created_by_user, foreign_key: { to_table: :users } t.timestamps t.index :normalized_source_key, unique: true t.index :source_kind t.index :drive_file_id end end def ensure_material_source_columns! add_column :materials, :source_kind, :string unless column_exists?(:materials, :source_kind) add_column :materials, :source_uri, :string unless column_exists?(:materials, :source_uri) add_column :materials, :source_path, :string unless column_exists?(:materials, :source_path) unless column_exists?(:materials, :source_file_id) add_column :materials, :source_file_id, :string end unless column_exists?(:materials, :normalized_source_key) add_column :materials, :normalized_source_key, :string end if index_exists?(:materials, :normalized_source_key) remove_index :materials, column: :normalized_source_key end end def ensure_material_active_source_key! unless column_exists?(:materials, :active_normalized_source_key) change_table :materials do |t| t.virtual :active_normalized_source_key, type: :string, as: 'IF(discarded_at IS NULL, normalized_source_key, NULL)', stored: false end end return if index_exists?(:materials, :active_normalized_source_key, name: 'index_materials_on_active_normalized_source_key') add_index :materials, :active_normalized_source_key, unique: true, name: 'index_materials_on_active_normalized_source_key' end def remove_material_file_suppression! if foreign_key_exists?(:materials, :users, column: :file_suppressed_by_user_id) remove_foreign_key :materials, column: :file_suppressed_by_user_id end if index_exists?(:materials, :file_suppressed_by_user_id, name: 'index_materials_on_file_suppressed_by_user_id') remove_index :materials, name: 'index_materials_on_file_suppressed_by_user_id' end remove_column :materials, :file_suppressed_at if column_exists?( :materials, :file_suppressed_at) remove_column :materials, :file_suppressed_by_user_id if column_exists?( :materials, :file_suppressed_by_user_id) remove_column :materials, :file_suppression_reason if column_exists?( :materials, :file_suppression_reason) end def remove_material_version_file_suppression! remove_column :material_versions, :file_suppressed_at if column_exists?( :material_versions, :file_suppressed_at) remove_column :material_versions, :file_suppression_reason if column_exists?( :material_versions, :file_suppression_reason) end def reconcile_material_version_event_constraint! constraint = check_constraints(:material_versions).find do |candidate| candidate.name == MATERIAL_VERSION_EVENT_CONSTRAINT end return if constraint && !constraint.expression.include?('suppress') if constraint remove_check_constraint :material_versions, name: MATERIAL_VERSION_EVENT_CONSTRAINT end add_check_constraint :material_versions, "event_type IN ('create', 'update', 'discard', 'restore')", name: MATERIAL_VERSION_EVENT_CONSTRAINT end end