Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Allow Jennifer::Migration::Runner.migrate to specify an adapter. #333

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 25 additions & 32 deletions src/jennifer/migration/runner.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@ module Jennifer
# This modules is responsible for processing database migration operations like creation,
# dropping and migration.
module Runner
@@pending_versions = [] of String

# Invokes migrations. *count* with negative or zero value will invoke all pending migrations.
def self.migrate(count : Int = -1)
def self.migrate(count : Int = -1, adapter : Adapter::Base = default_adapter)
performed = false
default_adapter.ready_to_migrate!
return unless pending_migration?
Version.adapter = adapter
adapter.ready_to_migrate!
pending_versions = get_pending_versions
return if pending_versions.empty?

assert_outdated_pending_migrations
assert_outdated_pending_migrations pending_versions
migrations = Base.migrations

pending_versions.each_with_index do |version, i|
return if count > 0 && i >= count

process_up_migration(migrations[version].new)
process_up_migration(migrations[version].new, adapter)
performed = true
end
ensure
default_adapter.generate_schema if performed && !Config.skip_dumping_schema_sql
adapter.generate_schema if performed && !adapter.config.skip_dumping_schema_sql
end

# Creates database using given *adapter*.
Expand Down Expand Up @@ -51,9 +51,9 @@ module Jennifer
# Allowed options:
# - *count* - count of migrations to be rolled back
# - *to* - migration timestamp to which database should be rolled back
def self.rollback(options : Hash(Symbol, DBAny))
def self.rollback(options : Hash(Symbol, DBAny), *, adapter : Adapter::Base = default_adapter)
processed = true
default_adapter.ready_to_migrate!
adapter.ready_to_migrate!
migrations = Base.migrations
return if migrations.empty? || !Version.all.exists?

Expand All @@ -68,43 +68,36 @@ module Jennifer
end

versions.each do |version|
process_down_migration(migrations[version].new)
process_down_migration(migrations[version].new, adapter)
processed = true
end
ensure
default_adapter.generate_schema if processed && !Config.skip_dumping_schema_sql
adapter.generate_schema if processed && !adapter.config.skip_dumping_schema_sql
end

# Loads schema from the SQL schema file.
def self.load_schema
return if Config.skip_dumping_schema_sql
def self.load_schema(adapter : Adapter::Base = default_adapter)
return if adapter.config.skip_dumping_schema_sql

default_adapter.load_schema
adapter.load_schema
puts "Schema loaded"
end

# Returns whether pending migration exists.
#
# Pending migration - known Jennifer::Migration::Base subclasses that hasn't been run.
def self.pending_migration?
!pending_versions.empty?
end

private def self.default_adapter
Adapter.default_adapter
end

# NOTE: pending versions are memorized so reloading should be performed manually.
private def self.pending_versions
@@pending_versions = (Base.versions - Version.list).sort! if @@pending_versions.empty?
@@pending_versions
private def self.get_pending_versions
pending_versions = (Base.versions - Version.list).sort!
pending_versions
end

private def self.default_adapter_class
Adapter.default_adapter_class
end

private def self.process_up_migration(migration)
private def self.process_up_migration(migration, adapter)
optional_transaction(migration) do
process_with_announcement(migration, :up) do
migration.up
Expand All @@ -113,17 +106,17 @@ module Jennifer
end
rescue e
optional_transaction(migration) do
if Config.instance.migration_failure_handler_method.reverse_direction?
if adapter.config.migration_failure_handler_method.reverse_direction?
migration.down
elsif Config.instance.migration_failure_handler_method.callback?
elsif adapter.config.migration_failure_handler_method.callback?
migration.after_up_failure
end
end

raise e
end

private def self.process_down_migration(migration)
private def self.process_down_migration(migration, adapter)
optional_transaction(migration) do
process_with_announcement(migration, :down) do
migration.down
Expand All @@ -132,9 +125,9 @@ module Jennifer
end
rescue e
optional_transaction(migration) do
if Config.instance.migration_failure_handler_method.reverse_direction?
if adapter.config.migration_failure_handler_method.reverse_direction?
migration.up
elsif Config.instance.migration_failure_handler_method.callback?
elsif adapter.config.migration_failure_handler_method.callback?
migration.after_down_failure
end
end
Expand All @@ -156,7 +149,7 @@ module Jennifer
puts "#{header} #{words[:end]} (#{time.milliseconds} ms)\n" if Config.config.verbose_migrations
end

private def self.assert_outdated_pending_migrations
private def self.assert_outdated_pending_migrations(pending_versions)
return if !Version.all.exists? || Config.config.allow_outdated_pending_migration

db_version = Version.all.order(version: :desc).limit(1).pluck(:version)[0].as(String)
Expand Down
11 changes: 11 additions & 0 deletions src/jennifer/migration/version.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ module Jennifer
version: String
)

@@adapter : Adapter::Base?

def self.adapter
@@adapter.not_nil!
end

def self.adapter=(adapter : Adapter::Base)
@@adapter = adapter
adapter
end

def self.has_table?
false
end
Expand Down