module DataMigrate::DatabaseTasks

This class extends DatabaseTasks to add a schema_file method.

Public Class Methods

migrate_with_data() click to toggle source
# File lib/data_migrate/database_tasks.rb, line 177
def self.migrate_with_data
  DataMigrate::DataMigrator.create_data_schema_table

  ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true

  # 7.2 removes the param for db_configs_with_versions in https://github.com/rails/rails/commit/9572fcb4a0bd5396436689a6a42613886871cd81
  # 7.1 stable backported the change in https://github.com/rails/rails/commit/c53ec4b60980036b43528829d4b0b7457f759224
  schema_mapped_versions = if Gem::Dependency.new("railties", ">= 7.1.4").match?("railties", Gem.loaded_specs["railties"].version, true)
    ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions
  else
    db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)

    ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions(db_configs)
  end

  data_mapped_versions = DataMigrate::DatabaseTasks.db_configs_with_versions

  mapped_versions = schema_mapped_versions.merge(data_mapped_versions) do |_key, schema_db_configs, data_db_configs|
    schema_db_configs + data_db_configs
  end

  mapped_versions.sort.each do |version, db_configs|
    db_configs.each do |db_config|
      if is_data_migration = db_config.is_a?(DataMigrate::DatabaseConfigurationWrapper)
        db_config = db_config.db_config
      end

      DataMigrate::DatabaseTasks.with_temporary_connection(db_config) do
        if is_data_migration
          DataMigrate::DataMigrator.run(:up, DataMigrate::DatabaseTasks.data_migrations_path, version)
        else
          ActiveRecord::Tasks::DatabaseTasks.migrate(version)
        end
      end
    end
  end
end
prepare_all_with_data() click to toggle source
# File lib/data_migrate/database_tasks.rb, line 215
def self.prepare_all_with_data
  seed = false

  each_current_configuration(env) do |db_config|
    next unless primary?(db_config)

    with_temporary_pool(db_config) do |pool|
      unless database_exists?(pool.connection)
        create(db_config)
        if File.exist?(schema_dump_path(db_config))
          load_schema(db_config, schema_format, nil)
          load_schema_current(
            :ruby,
            ENV["DATA_SCHEMA"]
          )
        end

        seed = true
      end

      migrate_with_data
      if dump_schema_after_migration?
        dump_schema(db_config)
        DataMigrate::Tasks::DataMigrateTasks.dump
      end
    end
  end

  load_seed if seed
end

Public Instance Methods

check_schema_file(filename) click to toggle source
# File lib/data_migrate/database_tasks.rb, line 87
def check_schema_file(filename)
  unless File.exist?(filename)
    message = +%{#{filename} doesn't exist yet. Run `rake data:migrate` to create it, then try again.}
    Kernel.abort message
  end
end
data_migrations_path() click to toggle source
# File lib/data_migrate/database_tasks.rb, line 109
def data_migrations_path
  ::DataMigrate.config.data_migrations_path
end
db_configs_with_versions() click to toggle source
# File lib/data_migrate/database_tasks.rb, line 49
def db_configs_with_versions
  db_configs_with_versions = Hash.new { |h, k| h[k] = [] }

  with_temporary_pool_for_each do |pool|
    db_config = pool.db_config
    if db_config.primary?
      versions_to_run = DataMigrate::DatabaseTasks.pending_data_migrations.map { |m| m[:version] }
      target_version = ActiveRecord::Tasks::DatabaseTasks.target_version

      versions_to_run.each do |version|
        next if target_version && target_version != version
        db_configs_with_versions[version] << DatabaseConfigurationWrapper.new(db_config)
      end
    end
  end

  db_configs_with_versions
end
dump_filename(spec_name, format = ActiveRecord::Base.schema_format) click to toggle source

This method is removed in Rails 7.0

# File lib/data_migrate/database_tasks.rb, line 77
def dump_filename(spec_name, format = ActiveRecord::Base.schema_format)
  filename = if spec_name == "primary"
    schema_file_type(format)
  else
    "#{spec_name}_#{schema_file_type(format)}"
  end

  ENV["DATA_SCHEMA"] || File.join(db_dir, filename)
end
forward(step = 1) click to toggle source
# File lib/data_migrate/database_tasks.rb, line 143
def forward(step = 1)
  DataMigrate::DataMigrator.create_data_schema_table
  migrations = pending_migrations.reverse.pop(step).reverse
  migrations.each do | pending_migration |
    if pending_migration[:kind] == :data
      ActiveRecord::Migration.write("== %s %s" % ["Data", "=" * 71])
      DataMigrate::DataMigrator.run(:up, data_migrations_path, pending_migration[:version])
    elsif pending_migration[:kind] == :schema
      ActiveRecord::Migration.write("== %s %s" % ["Schema", "=" * 69])
      DataMigrate::SchemaMigration.run(:up, DataMigrate::SchemaMigration.migrations_paths, pending_migration[:version])
    end
  end
end
past_migrations(sort = nil) click to toggle source
# File lib/data_migrate/database_tasks.rb, line 169
def past_migrations(sort = nil)
  data_versions = DataMigrate::RailsHelper.data_schema_migration.table_exists? ? DataMigrate::RailsHelper.data_schema_migration.normalized_versions : []
  schema_versions = DataMigrate::RailsHelper.schema_migration.normalized_versions
  migrations = data_versions.map { |v| { version: v.to_i, kind: :data } } + schema_versions.map { |v| { version: v.to_i, kind: :schema } }

  sort&.downcase == "asc" ? sort_migrations(migrations) : sort_migrations(migrations).reverse
end
pending_data_migrations() click to toggle source
# File lib/data_migrate/database_tasks.rb, line 157
def pending_data_migrations
  data_migrations = DataMigrate::DataMigrator.migrations(data_migrations_path)
  data_migrator = DataMigrate::RailsHelper.data_migrator(:up, data_migrations)
  sort_migrations(
    data_migrator.pending_migrations.map { |m| { version: m.version, name: m.name, kind: :data } }
    )
end
pending_migrations() click to toggle source
# File lib/data_migrate/database_tasks.rb, line 94
def pending_migrations
  sort_migrations(
    pending_schema_migrations,
    pending_data_migrations
  )
end
pending_schema_migrations() click to toggle source
# File lib/data_migrate/database_tasks.rb, line 165
def pending_schema_migrations
  ::DataMigrate::SchemaMigration.pending_schema_migrations
end
run_migration(migration, direction) click to toggle source
# File lib/data_migrate/database_tasks.rb, line 113
def run_migration(migration, direction)
  if migration[:kind] == :data
    ::ActiveRecord::Migration.write("== %s %s" % ['Data', "=" * 71])
    ::DataMigrate::DataMigrator.run(direction, data_migrations_path, migration[:version])
  else
    ::ActiveRecord::Migration.write("== %s %s" % ['Schema', "=" * 69])
    ::DataMigrate::SchemaMigration.run(
      direction,
      ::DataMigrate::SchemaMigration.migrations_paths,
      migration[:version]
    )
  end
end
schema_dump_path(db_config, format = ActiveRecord.schema_format) click to toggle source
# File lib/data_migrate/database_tasks.rb, line 127
def schema_dump_path(db_config, format = ActiveRecord.schema_format)
  return ENV["DATA_SCHEMA"] if ENV["DATA_SCHEMA"]

  # We only require a schema.rb file for the primary database
  return unless db_config.primary?

  File.join(File.dirname(ActiveRecord::Tasks::DatabaseTasks.schema_dump_path(db_config, format)), schema_file_type)
end
schema_file(_format = nil) click to toggle source
# File lib/data_migrate/database_tasks.rb, line 68
def schema_file(_format = nil)
  File.join(db_dir, "data_schema.rb")
end
schema_file_type(_format = nil) click to toggle source
# File lib/data_migrate/database_tasks.rb, line 72
def schema_file_type(_format = nil)
  "data_schema.rb"
end
schema_sha1(file) click to toggle source

Override this method from ‘ActiveRecord::Tasks::DatabaseTasks` to ensure that the sha saved in ar_internal_metadata table is from the original schema.rb file

# File lib/data_migrate/database_tasks.rb, line 139
def schema_sha1(file)
  ActiveRecord::Tasks::DatabaseTasks.schema_dump_path(ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: "primary"))
end
sort_migrations(*migrations) click to toggle source
# File lib/data_migrate/database_tasks.rb, line 101
def sort_migrations(*migrations)
  migrations.flatten.sort { |a, b|  sort_string(a) <=> sort_string(b) }
end
sort_string(migration) click to toggle source
# File lib/data_migrate/database_tasks.rb, line 105
def sort_string migration
  "#{migration[:version]}_#{migration[:kind] == :data ? 1 : 0}"
end
with_temporary_pool(db_config) { |pool| ... } click to toggle source
# File lib/data_migrate/database_tasks.rb, line 39
        def with_temporary_pool(db_config)
  original_db_config = migration_class.connection_db_config
  pool = migration_class.connection_handler.establish_connection(db_config)

  yield pool
ensure
  migration_class.connection_handler.establish_connection(original_db_config)
end

Private Instance Methods

database_exists?(connection) click to toggle source
# File lib/data_migrate/database_tasks.rb, line 248
def database_exists?(connection)
  if connection.respond_to?(:database_exists?)  # Rails 7.1+
    connection.database_exists?
  else
    connection.table_exists?(ActiveRecord::SchemaMigration.table_name)
  end
rescue ActiveRecord::NoDatabaseError
  false
end
dump_schema_after_migration?() click to toggle source
# File lib/data_migrate/database_tasks.rb, line 266
def dump_schema_after_migration?
  if ActiveRecord.respond_to?(:dump_schema_after_migration)
    ActiveRecord.dump_schema_after_migration
  else
    ActiveRecord::Base.dump_schema_after_migration
  end
end
primary?(db_config) click to toggle source
# File lib/data_migrate/database_tasks.rb, line 258
def primary?(db_config)
  if db_config.respond_to?(:primary?)  # Rails 7.0+
    db_config.primary?
  else
    db_config.name == "primary"
  end
end
schema_format() click to toggle source
# File lib/data_migrate/database_tasks.rb, line 274
def schema_format
  if ActiveRecord.respond_to?(:schema_format)
    ActiveRecord.schema_format
  else
    ActiveRecord::Base.schema_format
  end
end