提交 2976558b 编写于 作者: B bondarev

Support transactions in Migrator.run

上级 130d3a06
## 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 @@ def current_migration
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 @@ def migrate(x)
"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}"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册