aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb4
-rw-r--r--activerecord/test/cases/transactions_test.rb26
2 files changed, 30 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 8abbc6d0a4..51cfd10e5c 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -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"
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index 63f04e3014..06a76eacc3 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -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 }