aboutsummaryrefslogblamecommitdiffstats
path: root/activerecord/lib/active_record/explain.rb
blob: 15736575a2283930933df9c10c439ed209c2f2b5 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                                        
 
                   
                
                                                               


                                                                                                     

                                                    
          
                                                                            

                                                        
 


                                                                               
                                                 






                                                                    
                      
                    
 
                                                                               



                     
       

     
require 'active_support/lazy_load_hooks'

module ActiveRecord
  module Explain
    # Relation#explain needs to be able to collect the queries.
    def collecting_queries_for_explain # :nodoc:
      current = Thread.current
      original, current[:available_queries_for_explain] = current[:available_queries_for_explain], []
      yield
      return current[:available_queries_for_explain]
    ensure
      # Note that the return value above does not depend on this assignment.
      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:
      str = 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")

      # Overriding inspect to be more human readable, specially in the console.
      def str.inspect
        self
      end
      str
    end
  end
end