module ValidateFullTableScans
Public Instance Methods
validate_full_table_scans(db_queries, render_time, promised)
click to toggle source
# File lib/performance_promise/validations/full_table_scans.rb, line 2 def validate_full_table_scans(db_queries, render_time, promised) full_table_scans = [] backtrace = [] # check the explained queries to see if there were any # SCAN TABLEs db_queries.each do |db_query| if db_query[:explained] join_type = db_query[:explained].first[3] if join_type adapter_name = ActiveRecord::Base.connection.adapter_name if adapter_name == 'Mysql2' makes_full_table_scan = join_type.match(/ALL/) table_name = db_query[:explained][0][2] elsif adapter_name == 'SQLite' makes_full_table_scan = join_type.match(/SCAN TABLE (.*)/) table_name = makes_full_table_scan[1] else PerformancePromise.configuration.logger.warn("Unkown database adapter {adapter_name}") makes_full_table_scan = join_type.match(/SCAN TABLE (.*)/) table_name = makes_full_table_scan[1] end if makes_full_table_scan full_table_scans << table_name backtrace << db_query[:sql] db_query[:trace].each do |trace| if trace.starts_with?('app') file, line_number = trace.split(':') trace = ' |_' + File.read(file).split("\n")[line_number.to_i - 1].strip + ' (' + trace + ')' end backtrace << trace end end end end end # we do not care about duplicates full_table_scans = full_table_scans.uniq # map the models in the promise to their corresponding table names promised_full_table_scans = promised.map { |model| model.table_name } # check that the performed FTSs are a subset of the promised FTSs passes = (full_table_scans & promised_full_table_scans == full_table_scans) error_message = '' unless passes model_names = full_table_scans.map { |table_name| table_name.classify } error_message = ":full_table_scans => [#{model_names.join(', ')}]" end return passes, error_message, backtrace end