1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Clear query cache when insert all is used

The `InsertAll` class currently calls `exec_query`, which doesn't give
the query cache enough information to know that it needs to be cleared.

By adding an `exec_insert_all` method that calls `exec_query` internally
we can configure the query cache to clear when that method is called.
This commit is contained in:
Eugene Kenny 2019-09-09 00:55:16 +01:00
parent cf43b71b64
commit fad44a6999
5 changed files with 36 additions and 2 deletions

View file

@ -1,3 +1,7 @@
* `insert`, `insert_all`, `upsert`, and `upsert_all` now clear the query cache.
*Eugene Kenny*
* Call `while_preventing_writes` directly from `connected_to`.
In some cases application authors want to use the database switching middleware and make explicit calls with `connected_to`. It's possible for an app to turn off writes and not turn them back on by the time we call `connected_to(role: :writing)`.

View file

@ -151,6 +151,10 @@ module ActiveRecord
exec_query(sql, name, binds)
end
def exec_insert_all(sql, name) # :nodoc:
exec_query(sql, name)
end
# Executes an INSERT query and returns the new record's ID
#
# +id_value+ will be returned unless the value is +nil+, in

View file

@ -8,7 +8,7 @@ module ActiveRecord
class << self
def included(base) #:nodoc:
dirties_query_cache base, :insert, :update, :delete, :truncate, :truncate_tables,
:rollback_to_savepoint, :rollback_db_transaction
:rollback_to_savepoint, :rollback_db_transaction, :exec_insert_all
base.set_callback :checkout, :after, :configure_query_cache!
base.set_callback :checkin, :after, :disable_query_cache!

View file

@ -24,7 +24,7 @@ module ActiveRecord
message = +"#{model} "
message << "Bulk " if inserts.many?
message << (on_duplicate == :update ? "Upsert" : "Insert")
connection.exec_query to_sql, message
connection.exec_insert_all to_sql, message
end
def updatable_columns

View file

@ -650,6 +650,32 @@ class QueryCacheExpiryTest < ActiveRecord::TestCase
end
end
def test_insert_all
assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
Task.cache { Task.insert({ starting: Time.now }) }
end
assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
Task.cache { Task.insert_all([{ starting: Time.now }]) }
end
assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
Task.cache { Task.insert!({ starting: Time.now }) }
end
assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
Task.cache { Task.insert_all!([{ starting: Time.now }]) }
end
assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
Task.cache { Task.upsert({ starting: Time.now }) }
end
assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
Task.cache { Task.upsert_all([{ starting: Time.now }]) }
end
end
def test_cache_is_expired_by_habtm_update
assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
ActiveRecord::Base.cache do