hensei-api/lib/post_deployment/database_migrator.rb
Justin Edmund 11db6674fc
fix migrator (#183)
- rename migration so it happens first
- postdeployment database migrator now migrates database and data migrations in chronological order
2025-02-18 01:47:23 -08:00

122 lines
3.5 KiB
Ruby

# frozen_string_literal: true
require_relative '../logging_helper'
module PostDeployment
class DatabaseMigrator
include LoggingHelper
class CombinedMigration
attr_reader :version, :name, :migration, :type
def initialize(version, name, migration, type)
@version = version
@name = name
@migration = migration
@type = type
end
def schema_migration?
@type == :schema
end
def data_migration?
@type == :data
end
end
def initialize(test_mode:, verbose:)
@test_mode = test_mode
@verbose = verbose
end
def run
log_header 'Running database migrations...', '-'
puts "\n"
if @test_mode
simulate_migrations
else
perform_migrations
end
end
private
def collect_pending_migrations
# Collect schema migrations
schema_context = ActiveRecord::Base.connection.pool.migration_context
schema_migrations = schema_context.migrations.map do |migration|
CombinedMigration.new(
migration.version,
migration.name,
migration,
:schema
)
end
# Collect data migrations
data_migrations_path = DataMigrate.config.data_migrations_path
data_migration_context = DataMigrate::MigrationContext.new(data_migrations_path)
data_migrations = data_migration_context.migrations.map do |migration|
CombinedMigration.new(
migration.version,
migration.name,
migration,
:data
)
end
# Combine and sort all migrations by version
(schema_migrations + data_migrations).sort_by(&:version)
end
def simulate_migrations
pending_migrations = collect_pending_migrations
if pending_migrations.any?
log_step "TEST MODE: Would run #{pending_migrations.size} pending migrations in this order:"
pending_migrations.each do |migration|
type = migration.schema_migration? ? 'schema' : 'data'
log_step " • [#{type}] #{migration.name} (#{migration.version})"
end
else
log_step 'No pending migrations.'
end
end
def perform_migrations
ActiveRecord::Migration.verbose = @verbose
pending_migrations = collect_pending_migrations
return log_step 'No pending migrations.' if pending_migrations.empty?
schema_context = ActiveRecord::Base.connection.pool.migration_context
data_context = DataMigrate::MigrationContext.new(DataMigrate.config.data_migrations_path)
initial_schema_version = schema_context.current_version
initial_data_version = data_context.current_version
pending_migrations.each do |combined_migration|
if combined_migration.schema_migration?
# Execute schema migration using Rails migration context
schema_context.run(:up, combined_migration.version)
else
# Execute data migration using data-migrate context
data_context.run(:up, combined_migration.version)
end
end
final_schema_version = schema_context.current_version
final_data_version = data_context.current_version
if initial_schema_version != final_schema_version
log_step "Migrated schema from version #{initial_schema_version} to #{final_schema_version}"
end
if initial_data_version != final_data_version
log_step "Migrated data from version #{initial_data_version} to #{final_data_version}"
end
end
end
end