Enable detecting duplicate queries inside a block
Methods
Public Class
Public Instance
Classes and Modules
Public Class methods
# File lib/sequel/extensions/pg_auto_parameterize_duplicate_query_detection.rb 62 def self.extended(db) 63 db.instance_exec do 64 @duplicate_query_detection_contexts = {} 65 @duplicate_query_detection_mutex = Mutex.new 66 end 67 end
Public Instance methods
Run the duplicate query detector during the block. Options:
| :backtrace_filter |
Regexp used to filter the displayed backtrace. |
| :handler |
If present, called with hash of duplicate query information, instead of raising or warning. |
| :warn |
Always warn instead of raising for duplicate queries. |
Note that if you nest calls to this method, only the top level call will respect the passed options.
# File lib/sequel/extensions/pg_auto_parameterize_duplicate_query_detection.rb 122 def detect_duplicate_queries(opts=OPTS, &block) 123 current = Sequel.current 124 if state = duplicate_query_recorder_state(current) 125 return change_duplicate_query_recorder_state(state, true, &block) 126 end 127 128 @duplicate_query_detection_mutex.synchronize do 129 @duplicate_query_detection_contexts[current] = [true, Hash.new(0)] 130 end 131 132 begin 133 yield 134 rescue Exception => e 135 raise 136 ensure 137 _, queries = @duplicate_query_detection_mutex.synchronize do 138 @duplicate_query_detection_contexts.delete(current) 139 end 140 queries.delete_if{|_,v| v < 2} 141 142 unless queries.empty? 143 if handler = opts[:handler] 144 handler.call(queries) 145 else 146 backtrace_filter = opts[:backtrace_filter] 147 backtrace_filter_note = backtrace_filter ? " (filtered)" : "" 148 query_info = queries.map do |k,v| 149 backtrace = k[1] 150 backtrace = backtrace.grep(backtrace_filter) if backtrace_filter 151 "times:#{v}\nsql:#{k[0]}\nbacktrace#{backtrace_filter_note}:\n#{backtrace.join("\n")}\n" 152 end 153 message = "duplicate queries detected:\n\n#{query_info.join("\n")}" 154 155 if e || opts[:warn] 156 warn(message) 157 else 158 raise DuplicateQueries.new(message, queries) 159 end 160 end 161 end 162 end 163 end
Record each query executed so duplicates can be detected, if queries are being recorded.
# File lib/sequel/extensions/pg_auto_parameterize_duplicate_query_detection.rb 85 def execute(sql, opts=OPTS, &block) 86 record, queries = duplicate_query_recorder_state 87 88 if record 89 queries[[sql.is_a?(Symbol) ? sql : sql.to_s, caller].freeze] += 1 90 end 91 92 super 93 end
Ignore (do not record) queries inside given block. This can be useful in situations where you want to run your entire test suite with duplicate query detection, but you have duplicate queries in some parts of your application where it is not trivial to use a different approach. You can mark those specific sections with ignore_duplicate_queries, and still get duplicate query detection for the rest of the application.
# File lib/sequel/extensions/pg_auto_parameterize_duplicate_query_detection.rb 102 def ignore_duplicate_queries(&block) 103 if state = duplicate_query_recorder_state 104 change_duplicate_query_recorder_state(state, false, &block) 105 else 106 # If we are not inside a detect_duplicate_queries block, there is 107 # no need to do anything, since we are not recording queries. 108 yield 109 end 110 end