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) ##
|
||||
|
||||
* 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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}"
|
||||
|
|
Loading…
Reference in a new issue