Class: ArQueryMatchers::Queries::QueryCounter

Inherits:
Object
  • Object
show all
Defined in:
lib/ar_query_matchers/queries/query_counter.rb

Overview

The QueryCounter instruments a ruby block and collect stats on the SQL queries performed during its execution.

It’s “generic” meaning it requires an instance of a QueryFilter to operate. The QueryFilter is an interface that both filters SQL statements and maps them to an ActiveRecord model, sort of a Enumerator#filter_map.

This class is meant to be wrapped by another class that provides a concrete QueryFilter implementation. For example, you could implement a SelectQueryFilter using it: class SelectQueryCounter

class SelectFilter < Queries::QueryFilter
  def extract(_name, sql)
    select_from_table = sql.match(/SELECT .* FROM [`"](?<table_name>[^`"]+)[`"]/)
    Queries::TableName.new(select_from_table[:table_name]) if select_from_table
  end
end

def self.instrument(&block)
  QueryCounter.new(SelectFilter.new).instrument(&block)
end

end

stats = SelectQueryCounter.instrument do

Company.first
Employee.last(100)
User.find(1)
User.find(2)

end

stats.query_counts == { ‘Company’ => 1, Employee => ‘1’, ‘User’ => 2 }

Defined Under Namespace

Classes: QueryStats

Instance Method Summary collapse

Constructor Details

#initialize(query_filter) ⇒ QueryCounter

Returns a new instance of QueryCounter.



58
59
60
# File 'lib/ar_query_matchers/queries/query_counter.rb', line 58

def initialize(query_filter)
  @query_filter = query_filter
end

Instance Method Details

#instrument(&block) ⇒ QueryStats

Returns stats about all the SQL queries executed during the block.

Parameters:

  • block (block)

    to instrument

Returns:

  • (QueryStats)

    stats about all the SQL queries executed during the block



64
65
66
67
68
# File 'lib/ar_query_matchers/queries/query_counter.rb', line 64

def instrument(&block)
  queries = Hash.new { |h, k| h[k] = { count: 0, lines: [], time: BigDecimal(0) } }
  ActiveSupport::Notifications.subscribed(to_proc(queries), 'sql.active_record', &block)
  QueryStats.new(queries)
end