class DBQueryMatchers::QueryCounter

Counter to keep track of the number of queries caused by running a piece of code. Closely tied to the `:make_database_queries` matcher, this class is designed to be a consumer of `sql.active_record` events.

@example

counter = DBQueryMatchers::QueryCounter.new
ActiveSupport::Notifications.subscribed(counter.to_proc,
                                       'sql.active_record') do
  # run code here
end
puts counter.count          # prints the number of queries made
puts counter.log.join(', ') # prints all queries made

@see api.rubyonrails.org/classes/ActiveSupport/Notifications.html#module-ActiveSupport::Notifications-label-Temporary+Subscriptions

Attributes

count[R]
log[R]

Public Class Methods

new(options = {}) click to toggle source
# File lib/db_query_matchers/query_counter.rb, line 19
def initialize(options = {})
  @matches = options[:matches]
  @count = 0
  @log   = []
end

Public Instance Methods

callback(_name, _start, _finish, _message_id, payload) click to toggle source

Method called from the ActiveSupport::Notifications module (through the lambda created by `to_proc`) when an SQL query is made.

@param _name [String] name of the event @param _start [Time] when the instrumented block started execution @param _finish [Time] when the instrumented block ended execution @param _message_id [String] unique ID for this notification @param payload [Hash] the payload

# File lib/db_query_matchers/query_counter.rb, line 41
def callback(_name, _start,  _finish, _message_id, payload)
  return if @matches && !any_match?(@matches, payload[:sql])
  return if any_match?(DBQueryMatchers.configuration.ignores, payload[:sql])
  return if DBQueryMatchers.configuration.schemaless && payload[:name] == "SCHEMA"

  count_query
  log_query(payload[:sql])

  DBQueryMatchers.configuration.on_query_counted.call(payload)
end
to_proc() click to toggle source

Turns a QueryCounter instance into a lambda. Designed to be used when subscribing to events through the ActiveSupport::Notifications module.

@return [Proc]

# File lib/db_query_matchers/query_counter.rb, line 29
def to_proc
  lambda(&method(:callback))
end

Private Instance Methods

any_match?(patterns, sql) click to toggle source
# File lib/db_query_matchers/query_counter.rb, line 54
def any_match?(patterns, sql)
  patterns.any? { |pattern| sql =~ pattern }
end
count_query() click to toggle source
# File lib/db_query_matchers/query_counter.rb, line 58
def count_query
  @count += 1
end
log_query(sql) click to toggle source
# File lib/db_query_matchers/query_counter.rb, line 62
def log_query(sql)
  log_entry = sql.strip

  if DBQueryMatchers.configuration.log_backtrace
    raw_backtrace = caller
    filtered_backtrace = DBQueryMatchers.configuration.backtrace_filter.call(raw_backtrace)
    log_entry += "\n#{filtered_backtrace.join("\n")}\n"
  end

  @log << log_entry
end