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) ## ## 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.

View file

@ -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

View file

@ -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}"