mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Support transactions in Migrator.run
This commit is contained in:
parent
130d3a06ad
commit
2976558bc3
3 changed files with 42 additions and 5 deletions
|
@ -1,5 +1,9 @@
|
||||||
## Rails 4.0.0 (unreleased) ##
|
## Rails 4.0.0 (unreleased) ##
|
||||||
|
|
||||||
|
* Run migrate:down & migrate:up in transaction if database supports
|
||||||
|
|
||||||
|
*Alexander Bondarev*
|
||||||
|
|
||||||
* Added Statement Cache to allow the caching of a single statement. The cache works by
|
* Added Statement Cache to allow the caching of a single statement. The cache works by
|
||||||
duping the relation returned from yielding a statement, which allows skipping the AST
|
duping the relation returned from yielding a statement, which allows skipping the AST
|
||||||
building phase for following executes. The cache returns results in array format.
|
building phase for following executes. The cache returns results in array format.
|
||||||
|
|
|
@ -867,11 +867,18 @@ module ActiveRecord
|
||||||
alias :current :current_migration
|
alias :current :current_migration
|
||||||
|
|
||||||
def run
|
def run
|
||||||
target = migrations.detect { |m| m.version == @target_version }
|
migration = migrations.detect { |m| m.version == @target_version }
|
||||||
raise UnknownMigrationVersionError.new(@target_version) if target.nil?
|
raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
|
||||||
unless (up? && migrated.include?(target.version.to_i)) || (down? && !migrated.include?(target.version.to_i))
|
unless (up? && migrated.include?(migration.version.to_i)) || (down? && !migrated.include?(migration.version.to_i))
|
||||||
target.migrate(@direction)
|
begin
|
||||||
record_version_state_after_migrating(target.version)
|
ddl_transaction(migration) do
|
||||||
|
migration.migrate(@direction)
|
||||||
|
record_version_state_after_migrating(migration.version)
|
||||||
|
end
|
||||||
|
rescue => e
|
||||||
|
canceled_msg = use_transaction?(migration) ? ", the migration canceled" : ""
|
||||||
|
raise StandardError, "An error has occurred#{canceled_msg}:\n\n#{e}", e.backtrace
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -258,6 +258,32 @@ class MigrationTest < ActiveRecord::TestCase
|
||||||
"On error, the Migrator should revert schema changes but it did not."
|
"On error, the Migrator should revert schema changes but it did not."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_migrator_one_up_with_exception_and_rollback_using_run
|
||||||
|
unless ActiveRecord::Base.connection.supports_ddl_transactions?
|
||||||
|
skip "not supported on #{ActiveRecord::Base.connection.class}"
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_not Person.column_methods_hash.include?(:last_name)
|
||||||
|
|
||||||
|
migration = Class.new(ActiveRecord::Migration) {
|
||||||
|
def version; 100 end
|
||||||
|
def migrate(x)
|
||||||
|
add_column "people", "last_name", :string
|
||||||
|
raise 'Something broke'
|
||||||
|
end
|
||||||
|
}.new
|
||||||
|
|
||||||
|
migrator = ActiveRecord::Migrator.new(:up, [migration], 100)
|
||||||
|
|
||||||
|
e = assert_raise(StandardError) { migrator.run }
|
||||||
|
|
||||||
|
assert_equal "An error has occurred, the migration canceled:\n\nSomething broke", e.message
|
||||||
|
|
||||||
|
Person.reset_column_information
|
||||||
|
assert_not Person.column_methods_hash.include?(:last_name),
|
||||||
|
"On error, the Migrator should revert schema changes but it did not."
|
||||||
|
end
|
||||||
|
|
||||||
def test_migration_without_transaction
|
def test_migration_without_transaction
|
||||||
unless ActiveRecord::Base.connection.supports_ddl_transactions?
|
unless ActiveRecord::Base.connection.supports_ddl_transactions?
|
||||||
skip "not supported on #{ActiveRecord::Base.connection.class}"
|
skip "not supported on #{ActiveRecord::Base.connection.class}"
|
||||||
|
|
Loading…
Reference in a new issue