1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
# frozen_string_literal: true
module ClickHouse
module MigrationSupport
# MigrationContext sets the context in which a migration is run.
#
# A migration context requires the path to the migrations is set
# in the +migrations_paths+ parameter. Optionally a +schema_migration+
# class can be provided. For most applications, +SchemaMigration+ is
# sufficient. Multiple database applications need a +SchemaMigration+
# per primary database.
class MigrationContext
def initialize(connection, migrations_paths, schema_migration)
@connection = connection
@migrations_paths = migrations_paths
@schema_migration = schema_migration
end
def up(target_version = nil, step = nil, &block)
selected_migrations = block ? migrations.select(&block) : migrations
migrate(:up, selected_migrations, target_version, step)
end
def down(target_version = nil, step = 1, &block)
selected_migrations = block ? migrations.select(&block) : migrations
migrate(:down, selected_migrations, target_version, step)
end
private
attr_reader :migrations_paths, :schema_migration, :connection
def migrate(direction, selected_migrations, target_version = nil, step = nil)
ClickHouse::MigrationSupport::Migrator.new(
direction,
selected_migrations,
schema_migration,
target_version,
step
).migrate
end
def migrations
migrations = migration_files.map do |file|
version, name, scope = parse_migration_filename(file)
raise ClickHouse::MigrationSupport::Errors::IllegalMigrationNameError, file unless version
version = version.to_i
name = name.camelize
MigrationProxy.new(connection, name, version, file, scope)
end
migrations.sort_by(&:version)
end
def migration_files
paths = Array(migrations_paths)
Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
end
def parse_migration_filename(filename)
File.basename(filename).scan(ClickHouse::Migration::MIGRATION_FILENAME_REGEXP).first
end
end
# MigrationProxy is used to defer loading of the actual migration classes
# until they are needed
class MigrationProxy
attr_reader :name, :version, :filename, :scope
def initialize(connection, name, version, filename, scope)
@connection = connection
@name = name
@version = version
@filename = filename
@scope = scope
@migration = nil
end
def basename
File.basename(filename)
end
delegate :migrate, :announce, :write, :database, to: :migration
private
def migration
@migration ||= load_migration
end
def load_migration
require(File.expand_path(filename))
name.constantize.new(@connection, name, version)
end
end
end
end
|