From f4779ba2e160e862beed8fdcac061b1bfd516daf Mon Sep 17 00:00:00 2001 From: Kevin Yeh Date: Tue, 17 Oct 2017 12:52:52 -0400 Subject: [PATCH] [Rails 5] Add select_prepared to whitelist, duplicate 4.2 QueryCache behavior (#19) --- lib/replica_pools/engine.rb | 8 +++++++- lib/replica_pools/query_cache.rb | 33 ++++++++++++++++++++------------ lib/replica_pools/version.rb | 2 +- spec/query_cache_spec.rb | 2 -- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/lib/replica_pools/engine.rb b/lib/replica_pools/engine.rb index 1683459..4c04fa9 100644 --- a/lib/replica_pools/engine.rb +++ b/lib/replica_pools/engine.rb @@ -15,12 +15,18 @@ class Engine < Rails::Engine :select_rows, :select, :verify!, :raw_connection, :active?, :reconnect!, :disconnect!, :reset_runtime, :log, :log_info ] - elsif [4, 5].include? ActiveRecord::VERSION::MAJOR + elsif ActiveRecord::VERSION::MAJOR == 4 [ :select_all, :select_one, :select_value, :select_values, :select_rows, :select, :verify!, :raw_connection, :active?, :reconnect!, :disconnect!, :reset_runtime, :log ] + elsif ActiveRecord::VERSION::MAJOR == 5 + [ + :select_all, :select_one, :select_value, :select_values, + :select_rows, :select, :select_prepared, :verify!, :raw_connection, + :active?, :reconnect!, :disconnect!, :reset_runtime, :log + ] else warn "Unsupported ActiveRecord version #{ActiveRecord.version}. Please whitelist the safe methods." end diff --git a/lib/replica_pools/query_cache.rb b/lib/replica_pools/query_cache.rb index 307567a..2e01eba 100644 --- a/lib/replica_pools/query_cache.rb +++ b/lib/replica_pools/query_cache.rb @@ -21,20 +21,29 @@ def #{method_name}(*a, &b) # connection for cache logic, but ultimately pass its query # through to whatever connection is current. def select_all(*args) - # there are more args, but we only care about arel, name, and binds for caching - arel, name, binds = args - if query_cache_enabled && !locked?(arel) - sql = to_sql(arel, binds) - args[0] = sql - - if ActiveRecord::VERSION::STRING >= '5.1' - cache_sql(sql, name, binds) { route_to(current, :select_all, *args) } - else - cache_sql(sql, binds) { route_to(current, :select_all, *args) } - end + # there may be more args for Rails 5.0+, but we only care about arel, name, and binds for caching. + relation, name, raw_binds = args + + if !query_cache_enabled || locked?(relation) + return route_to(current, :select_all, *args) + end + + # duplicate binds_from_relation behavior introduced in 4.2. + if raw_binds.blank? && relation.is_a?(ActiveRecord::Relation) + arel, binds = relation.arel, relation.bind_values + else + arel, binds = relation, raw_binds + end + + sql = to_sql(arel, binds) + + args[0] = sql + args[2] = binds + if Gem::Version.new(ActiveRecord.version) < Gem::Version.new('5.1') + cache_sql(sql, binds) { route_to(current, :select_all, *args) } else - route_to(current, :select_all, *args) + cache_sql(sql, name, binds) { route_to(current, :select_all, *args) } end end diff --git a/lib/replica_pools/version.rb b/lib/replica_pools/version.rb index e1262fd..8156cb5 100644 --- a/lib/replica_pools/version.rb +++ b/lib/replica_pools/version.rb @@ -1,3 +1,3 @@ module ReplicaPools - VERSION = "2.1.0.rc1" + VERSION = "2.1.0" end diff --git a/spec/query_cache_spec.rb b/spec/query_cache_spec.rb index fe27406..ac8dc59 100644 --- a/spec/query_cache_spec.rb +++ b/spec/query_cache_spec.rb @@ -2,7 +2,6 @@ require_relative 'spec_helper' describe ReplicaPools::QueryCache do - before(:each) do @sql = 'SELECT NOW()' @@ -104,5 +103,4 @@ def executor end end end - end