1
0
Fork 0
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:
bondarev 2013-02-25 19:05:22 +04:00
parent 130d3a06ad
commit 2976558bc3
3 changed files with 42 additions and 5 deletions

View file

@ -1,5 +1,9 @@
## 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
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.

View file

@ -867,11 +867,18 @@ module ActiveRecord
alias :current :current_migration
def run
target = migrations.detect { |m| m.version == @target_version }
raise UnknownMigrationVersionError.new(@target_version) if target.nil?
unless (up? && migrated.include?(target.version.to_i)) || (down? && !migrated.include?(target.version.to_i))
target.migrate(@direction)
record_version_state_after_migrating(target.version)
migration = migrations.detect { |m| m.version == @target_version }
raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
unless (up? && migrated.include?(migration.version.to_i)) || (down? && !migrated.include?(migration.version.to_i))
begin
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

View file

@ -258,6 +258,32 @@ class MigrationTest < ActiveRecord::TestCase
"On error, the Migrator should revert schema changes but it did not."
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
unless ActiveRecord::Base.connection.supports_ddl_transactions?
skip "not supported on #{ActiveRecord::Base.connection.class}"