2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
# 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 = []
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
full_table_scans = full_table_scans.uniq
promised_full_table_scans = promised.map { |model| model.table_name }
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
|