Skip to content
This repository
Browse code

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.
  • Loading branch information...
commit 089251581137b041828a7e6dcbf75ecbef55b4a3 1 parent 1b0128c
Pratik authored May 20, 2008
4  activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -214,6 +214,10 @@ def rename_table(name, new_name)
214 214
       end
215 215
 
216 216
       def add_column(table_name, column_name, type, options = {}) #:nodoc:
  217
+        if @connection.respond_to?(:transaction_active?) && @connection.transaction_active?
  218
+          raise StatementInvalid, 'Cannot add columns to a SQLite database while inside a transaction'
  219
+        end
  220
+        
217 221
         super(table_name, column_name, type, options)
218 222
         # See last paragraph on http://www.sqlite.org/lang_altertable.html
219 223
         execute "VACUUM"
26  activerecord/test/cases/transactions_test.rb
@@ -179,6 +179,32 @@ def test_rollback_when_commit_raises
179 179
     end
180 180
   end
181 181
 
  182
+  def test_sqlite_add_column_in_transaction_raises_statement_invalid
  183
+    return true unless current_adapter?(:SQLite3Adapter, :SQLiteAdapter)
  184
+
  185
+    # Test first if column creation/deletion works correctly when no
  186
+    # transaction is in place.
  187
+    #
  188
+    # We go back to the connection for the column queries because
  189
+    # Topic.columns is cached and won't report changes to the DB
  190
+    
  191
+    assert_nothing_raised do
  192
+      Topic.reset_column_information
  193
+      Topic.connection.add_column('topics', 'stuff', :string)
  194
+      assert Topic.column_names.include?('stuff')
  195
+      
  196
+      Topic.reset_column_information
  197
+      Topic.connection.remove_column('topics', 'stuff')
  198
+      assert !Topic.column_names.include?('stuff')
  199
+    end
  200
+
  201
+    # Test now inside a transaction: add_column should raise a StatementInvalid
  202
+    Topic.transaction do
  203
+      assert_raises(ActiveRecord::StatementInvalid) { Topic.connection.add_column('topics', 'stuff', :string) }
  204
+      raise ActiveRecord::Rollback
  205
+    end
  206
+  end
  207
+
182 208
   private
183 209
     def add_exception_raising_after_save_callback_to_topic
184 210
       Topic.class_eval { def after_save() raise "Make the transaction rollback" end }

0 notes on commit 0892515

Please sign in to comment.
Something went wrong with that request. Please try again.