module ActiveRecord::QueryLogs

def build_handler(name, handler = nil)

def build_handler(name, handler = nil)
  handler ||= @taggings[name]
  if handler.nil?
    GetKeyHandler.new(name)
  elsif handler.respond_to?(:call)
    if handler.arity == 0
      ZeroArityHandler.new(handler)
    else
      handler
    end
  else
    IdentityHandler.new(handler)
  end
end

def call(sql, connection) # :nodoc:

:nodoc:
def call(sql, connection) # :nodoc:
  comment = self.comment(connection)
  if comment.blank?
    sql
  elsif prepend_comment
    "#{comment} #{sql}"
  else
    "#{sql} #{comment}"
  end
end

def clear_cache # :nodoc:

:nodoc:
def clear_cache # :nodoc:
  self.cached_comment = nil
end

def comment(connection)

Sets and returns a cached comment if cache_query_log_tags is +true+.
Returns an SQL comment +String+ containing the query log tags.
def comment(connection)
  if cache_query_log_tags
    self.cached_comment ||= uncached_comment(connection)
  else
    uncached_comment(connection)
  end
end

def escape_sql_comment(content)

def escape_sql_comment(content)
  # Sanitize a string to appear within a SQL comment
  # For compatibility, this also surrounding "/*+", "/*", and "*/"
  # characters, possibly with single surrounding space.
  # Then follows that by replacing any internal "*/" or "/ *" with
  # "* /" or "/ *"
  comment = content.to_s.dup
  comment.gsub!(%r{\A\s*/\*\+?\s?|\s?\*/\s*\Z}, "")
  comment.gsub!("*/", "* /")
  comment.gsub!("/*", "/ *")
  comment
end

def query_source_location # :nodoc:

:nodoc:
def query_source_location # :nodoc:
  Thread.each_caller_location do |location|
    frame = LogSubscriber.backtrace_cleaner.clean_frame(location)
    return frame if frame
  end
  nil
end

def rebuild_handlers

def rebuild_handlers
  handlers = []
  @tags.each do |i|
    if i.is_a?(Hash)
      i.each do |k, v|
        handlers << [k, build_handler(k, v)]
      end
    else
      handlers << [i, build_handler(i)]
    end
  end
  handlers.sort_by! { |(key, _)| key.to_s }
end

def tag_content(connection)

def tag_content(connection)
  context = ActiveSupport::ExecutionContext.to_h
  context[:connection] ||= connection
  pairs = @handlers.filter_map do |(key, handler)|
    val = handler.call(context)
    @formatter.format(key, val) unless val.nil?
  end
  @formatter.join(pairs)
end

def taggings=(taggings) # :nodoc:

:nodoc:
def taggings=(taggings) # :nodoc:
  @taggings = taggings.freeze
  @handlers = rebuild_handlers
end

def tags=(tags) # :nodoc:

:nodoc:
def tags=(tags) # :nodoc:
  @tags = tags.freeze
  @handlers = rebuild_handlers
end

def tags_formatter=(format) # :nodoc:

:nodoc:
def tags_formatter=(format) # :nodoc:
  @formatter = case format
  when :legacy
    LegacyFormatter
  when :sqlcommenter
    SQLCommenter
  else
    raise ArgumentError, "Formatter is unsupported: #{format}"
  end
  @tags_formatter = format
end

def uncached_comment(connection)

def uncached_comment(connection)
  content = tag_content(connection)
  if content.present?
    "/*#{escape_sql_comment(content)}*/"
  end
end