mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
AS::Concern is not really needed for AR::Explain
This commit is contained in:
parent
05316ba127
commit
0065f37826
3 changed files with 74 additions and 76 deletions
|
@ -699,7 +699,7 @@ module ActiveRecord #:nodoc:
|
|||
include Associations
|
||||
include IdentityMap
|
||||
include ActiveModel::SecurePassword
|
||||
include Explain
|
||||
extend Explain
|
||||
|
||||
# AutosaveAssociation needs to be included before Transactions, because we want
|
||||
# #save_with_autosave_associations to be wrapped inside a transaction.
|
||||
|
|
|
@ -1,85 +1,83 @@
|
|||
require 'active_support/concern'
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActiveRecord
|
||||
module Explain
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
# If a query takes longer than these many seconds we log its query plan
|
||||
# automatically. nil disables this feature.
|
||||
class_attribute :auto_explain_threshold_in_seconds, :instance_writer => false
|
||||
self.auto_explain_threshold_in_seconds = nil
|
||||
def self.extended(base)
|
||||
base.class_eval do
|
||||
# If a query takes longer than these many seconds we log its query plan
|
||||
# automatically. nil disables this feature.
|
||||
class_attribute :auto_explain_threshold_in_seconds, :instance_writer => false
|
||||
self.auto_explain_threshold_in_seconds = nil
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# If auto explain is enabled, this method triggers EXPLAIN logging for the
|
||||
# queries triggered by the block if it takes more than the threshold as a
|
||||
# whole. That is, the threshold is not checked against each individual
|
||||
# query, but against the duration of the entire block. This approach is
|
||||
# convenient for relations.
|
||||
#
|
||||
# The available_queries_for_explain thread variable collects the queries
|
||||
# to be explained. If the value is nil, it means queries are not being
|
||||
# currently collected. A false value indicates collecting is turned
|
||||
# off. Otherwise it is an array of queries.
|
||||
def logging_query_plan # :nodoc:
|
||||
threshold = auto_explain_threshold_in_seconds
|
||||
current = Thread.current
|
||||
if threshold && current[:available_queries_for_explain].nil?
|
||||
begin
|
||||
queries = current[:available_queries_for_explain] = []
|
||||
start = Time.now
|
||||
result = yield
|
||||
logger.warn(exec_explain(queries)) if Time.now - start > threshold
|
||||
result
|
||||
ensure
|
||||
current[:available_queries_for_explain] = nil
|
||||
end
|
||||
else
|
||||
yield
|
||||
# If auto explain is enabled, this method triggers EXPLAIN logging for the
|
||||
# queries triggered by the block if it takes more than the threshold as a
|
||||
# whole. That is, the threshold is not checked against each individual
|
||||
# query, but against the duration of the entire block. This approach is
|
||||
# convenient for relations.
|
||||
#
|
||||
# The available_queries_for_explain thread variable collects the queries
|
||||
# to be explained. If the value is nil, it means queries are not being
|
||||
# currently collected. A false value indicates collecting is turned
|
||||
# off. Otherwise it is an array of queries.
|
||||
def logging_query_plan # :nodoc:
|
||||
threshold = auto_explain_threshold_in_seconds
|
||||
current = Thread.current
|
||||
if threshold && current[:available_queries_for_explain].nil?
|
||||
begin
|
||||
queries = current[:available_queries_for_explain] = []
|
||||
start = Time.now
|
||||
result = yield
|
||||
logger.warn(exec_explain(queries)) if Time.now - start > threshold
|
||||
result
|
||||
ensure
|
||||
current[:available_queries_for_explain] = nil
|
||||
end
|
||||
end
|
||||
|
||||
# Relation#explain needs to be able to collect the queries regardless of
|
||||
# whether auto explain is enabled. This method serves that purpose.
|
||||
def collecting_queries_for_explain # :nodoc:
|
||||
current = Thread.current
|
||||
original, current[:available_queries_for_explain] = current[:available_queries_for_explain], []
|
||||
return yield, current[:available_queries_for_explain]
|
||||
ensure
|
||||
# Note that the return value above does not depend on this assigment.
|
||||
current[:available_queries_for_explain] = original
|
||||
end
|
||||
|
||||
# Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
|
||||
# Returns a formatted string ready to be logged.
|
||||
def exec_explain(queries) # :nodoc:
|
||||
queries && queries.map do |sql, bind|
|
||||
[].tap do |msg|
|
||||
msg << "EXPLAIN for: #{sql}"
|
||||
unless bind.empty?
|
||||
bind_msg = bind.map {|col, val| [col.name, val]}.inspect
|
||||
msg.last << " #{bind_msg}"
|
||||
end
|
||||
msg << connection.explain(sql, bind)
|
||||
end.join("\n")
|
||||
end.join("\n")
|
||||
end
|
||||
|
||||
# Silences automatic EXPLAIN logging for the duration of the block.
|
||||
#
|
||||
# This has high priority, no EXPLAINs will be run even if downwards
|
||||
# the threshold is set to 0.
|
||||
#
|
||||
# As the name of the method suggests this only applies to automatic
|
||||
# EXPLAINs, manual calls to +ActiveRecord::Relation#explain+ run.
|
||||
def silence_auto_explain
|
||||
current = Thread.current
|
||||
original, current[:available_queries_for_explain] = current[:available_queries_for_explain], false
|
||||
else
|
||||
yield
|
||||
ensure
|
||||
current[:available_queries_for_explain] = original
|
||||
end
|
||||
end
|
||||
|
||||
# Relation#explain needs to be able to collect the queries regardless of
|
||||
# whether auto explain is enabled. This method serves that purpose.
|
||||
def collecting_queries_for_explain # :nodoc:
|
||||
current = Thread.current
|
||||
original, current[:available_queries_for_explain] = current[:available_queries_for_explain], []
|
||||
return yield, current[:available_queries_for_explain]
|
||||
ensure
|
||||
# Note that the return value above does not depend on this assigment.
|
||||
current[:available_queries_for_explain] = original
|
||||
end
|
||||
|
||||
# Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
|
||||
# Returns a formatted string ready to be logged.
|
||||
def exec_explain(queries) # :nodoc:
|
||||
queries && queries.map do |sql, bind|
|
||||
[].tap do |msg|
|
||||
msg << "EXPLAIN for: #{sql}"
|
||||
unless bind.empty?
|
||||
bind_msg = bind.map {|col, val| [col.name, val]}.inspect
|
||||
msg.last << " #{bind_msg}"
|
||||
end
|
||||
msg << connection.explain(sql, bind)
|
||||
end.join("\n")
|
||||
end.join("\n")
|
||||
end
|
||||
|
||||
# Silences automatic EXPLAIN logging for the duration of the block.
|
||||
#
|
||||
# This has high priority, no EXPLAINs will be run even if downwards
|
||||
# the threshold is set to 0.
|
||||
#
|
||||
# As the name of the method suggests this only applies to automatic
|
||||
# EXPLAINs, manual calls to +ActiveRecord::Relation#explain+ run.
|
||||
def silence_auto_explain
|
||||
current = Thread.current
|
||||
original, current[:available_queries_for_explain] = current[:available_queries_for_explain], false
|
||||
yield
|
||||
ensure
|
||||
current[:available_queries_for_explain] = original
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ module ActiveRecord
|
|||
MULTI_VALUE_METHODS = [:select, :group, :order, :joins, :where, :having, :bind]
|
||||
SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :from, :reorder, :reverse_order, :uniq]
|
||||
|
||||
include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain::ClassMethods, Delegation
|
||||
include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain, Delegation
|
||||
|
||||
attr_reader :table, :klass, :loaded
|
||||
attr_accessor :extensions, :default_scoped
|
||||
|
|
Loading…
Reference in a new issue