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

Support transactions in Migrator.run

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