mirror of
https://github.com/github/rails.git
synced 2026-02-06 20:25:28 -05:00
Ensure add_column gives valid error for sqlite. [Gunnar Wolf, Pratik] [#197 state:resolved]
SQLite#add_column executes "VACUUM", which fails if inside a live transaction. This patch ensures a valid exception is raised if add_column is executed within a live transaction for sqlite adapter.
This commit is contained in:
@@ -214,6 +214,10 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def add_column(table_name, column_name, type, options = {}) #:nodoc:
|
||||
if @connection.respond_to?(:transaction_active?) && @connection.transaction_active?
|
||||
raise StatementInvalid, 'Cannot add columns to a SQLite database while inside a transaction'
|
||||
end
|
||||
|
||||
super(table_name, column_name, type, options)
|
||||
# See last paragraph on http://www.sqlite.org/lang_altertable.html
|
||||
execute "VACUUM"
|
||||
|
||||
@@ -179,6 +179,32 @@ class TransactionTest < ActiveRecord::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def test_sqlite_add_column_in_transaction_raises_statement_invalid
|
||||
return true unless current_adapter?(:SQLite3Adapter, :SQLiteAdapter)
|
||||
|
||||
# Test first if column creation/deletion works correctly when no
|
||||
# transaction is in place.
|
||||
#
|
||||
# We go back to the connection for the column queries because
|
||||
# Topic.columns is cached and won't report changes to the DB
|
||||
|
||||
assert_nothing_raised do
|
||||
Topic.reset_column_information
|
||||
Topic.connection.add_column('topics', 'stuff', :string)
|
||||
assert Topic.column_names.include?('stuff')
|
||||
|
||||
Topic.reset_column_information
|
||||
Topic.connection.remove_column('topics', 'stuff')
|
||||
assert !Topic.column_names.include?('stuff')
|
||||
end
|
||||
|
||||
# Test now inside a transaction: add_column should raise a StatementInvalid
|
||||
Topic.transaction do
|
||||
assert_raises(ActiveRecord::StatementInvalid) { Topic.connection.add_column('topics', 'stuff', :string) }
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def add_exception_raising_after_save_callback_to_topic
|
||||
Topic.class_eval { def after_save() raise "Make the transaction rollback" end }
|
||||
|
||||
Reference in New Issue
Block a user