Merge pull request #45324 from adrianna-chang-shopify/ac-migration-strategy-objects
Introduce "Execution Strategy" object for Migrations
This commit is contained in:
commit
d51b171849
|
@ -1,3 +1,11 @@
|
||||||
|
* Introduce strategy pattern for executing migrations.
|
||||||
|
|
||||||
|
By default, migrations will use a strategy object that delegates the method
|
||||||
|
to the connection adapter. Consumers can implement custom strategy objects
|
||||||
|
to change how their migrations run.
|
||||||
|
|
||||||
|
*Adrianna Chang*
|
||||||
|
|
||||||
* Add adapter option disallowing foreign keys
|
* Add adapter option disallowing foreign keys
|
||||||
|
|
||||||
This adds a new option to be added to `database.yml` which enables skipping
|
This adds a new option to be added to `database.yml` which enables skipping
|
||||||
|
|
|
@ -302,6 +302,12 @@ module ActiveRecord
|
||||||
singleton_class.attr_accessor :timestamped_migrations
|
singleton_class.attr_accessor :timestamped_migrations
|
||||||
self.timestamped_migrations = true
|
self.timestamped_migrations = true
|
||||||
|
|
||||||
|
##
|
||||||
|
# :singleton-method:
|
||||||
|
# Specify strategy to use for executing migrations.
|
||||||
|
singleton_class.attr_accessor :migration_strategy
|
||||||
|
self.migration_strategy = Migration::DefaultStrategy
|
||||||
|
|
||||||
##
|
##
|
||||||
# :singleton-method:
|
# :singleton-method:
|
||||||
# Specify whether schema dump should happen at the end of the
|
# Specify whether schema dump should happen at the end of the
|
||||||
|
|
|
@ -548,6 +548,8 @@ module ActiveRecord
|
||||||
autoload :CommandRecorder, "active_record/migration/command_recorder"
|
autoload :CommandRecorder, "active_record/migration/command_recorder"
|
||||||
autoload :Compatibility, "active_record/migration/compatibility"
|
autoload :Compatibility, "active_record/migration/compatibility"
|
||||||
autoload :JoinTable, "active_record/migration/join_table"
|
autoload :JoinTable, "active_record/migration/join_table"
|
||||||
|
autoload :ExecutionStrategy, "active_record/migration/execution_strategy"
|
||||||
|
autoload :DefaultStrategy, "active_record/migration/default_strategy"
|
||||||
|
|
||||||
# This must be defined before the inherited hook, below
|
# This must be defined before the inherited hook, below
|
||||||
class Current < Migration # :nodoc:
|
class Current < Migration # :nodoc:
|
||||||
|
@ -694,6 +696,10 @@ module ActiveRecord
|
||||||
@connection = nil
|
@connection = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def execution_strategy
|
||||||
|
@execution_strategy ||= ActiveRecord.migration_strategy.new(self)
|
||||||
|
end
|
||||||
|
|
||||||
self.verbose = true
|
self.verbose = true
|
||||||
# instantiate the delegate object after initialize is defined
|
# instantiate the delegate object after initialize is defined
|
||||||
self.delegate = new
|
self.delegate = new
|
||||||
|
@ -881,6 +887,7 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
@connection = nil
|
@connection = nil
|
||||||
|
@execution_strategy = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def write(text = "")
|
def write(text = "")
|
||||||
|
@ -935,8 +942,8 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return super unless connection.respond_to?(method)
|
return super unless execution_strategy.respond_to?(method)
|
||||||
connection.send(method, *arguments, &block)
|
execution_strategy.send(method, *arguments, &block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
ruby2_keywords(:method_missing)
|
ruby2_keywords(:method_missing)
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module ActiveRecord
|
||||||
|
class Migration
|
||||||
|
# The default strategy for executing migrations. Delegates method calls
|
||||||
|
# to the connection adapter.
|
||||||
|
class DefaultStrategy < ExecutionStrategy # :nodoc:
|
||||||
|
private
|
||||||
|
def method_missing(method, *arguments, &block)
|
||||||
|
connection.send(method, *arguments, &block)
|
||||||
|
end
|
||||||
|
ruby2_keywords(:method_missing)
|
||||||
|
|
||||||
|
def respond_to_missing?(method, *)
|
||||||
|
connection.respond_to?(method) || super
|
||||||
|
end
|
||||||
|
|
||||||
|
def connection
|
||||||
|
migration.connection
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module ActiveRecord
|
||||||
|
class Migration
|
||||||
|
# ExecutionStrategy is used by the migration to respond to any method calls
|
||||||
|
# that the migration class does not implement directly. This is the base strategy.
|
||||||
|
# All strategies should inherit from this class.
|
||||||
|
#
|
||||||
|
# The ExecutionStrategy receives the current +migration+ when initialized.
|
||||||
|
class ExecutionStrategy # :nodoc:
|
||||||
|
def initialize(migration)
|
||||||
|
@migration = migration
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
attr_reader :migration
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -767,6 +767,22 @@ Specifies if an error should be raised if the order of a query is ignored during
|
||||||
|
|
||||||
Controls whether migrations are numbered with serial integers or with timestamps. The default is `true`, to use timestamps, which are preferred if there are multiple developers working on the same application.
|
Controls whether migrations are numbered with serial integers or with timestamps. The default is `true`, to use timestamps, which are preferred if there are multiple developers working on the same application.
|
||||||
|
|
||||||
|
#### `config.active_record.migration_strategy`
|
||||||
|
|
||||||
|
Controls the strategy class used to perform schema statement methods in a migration. The default class
|
||||||
|
delegates to the connection adapter. Custom strategies should inherit from `ActiveRecord::Migration::ExecutionStrategy`,
|
||||||
|
or may inherit from `DefaultStrategy`, which will preserve the default behaviour for methods that aren't implemented:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class CustomMigrationStrategy < ActiveRecord::Migration::DefaultStrategy
|
||||||
|
def drop_table(*)
|
||||||
|
raise "Dropping tables is not supported!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
config.active_record.migration_strategy = CustomMigrationStrategy
|
||||||
|
```
|
||||||
|
|
||||||
#### `config.active_record.lock_optimistically`
|
#### `config.active_record.lock_optimistically`
|
||||||
|
|
||||||
Controls whether Active Record will use optimistic locking and is `true` by default.
|
Controls whether Active Record will use optimistic locking and is `true` by default.
|
||||||
|
|
Loading…
Reference in New Issue