Public Class methods
extended(db)
[show source]
# File lib/sequel/extensions/sql_log_normalizer.rb 33 def self.extended(db) 34 type = case db.literal("'") 35 when "''''" 36 :standard 37 when "'\\''" 38 :backslash 39 when "N''''" 40 :n_standard 41 else 42 raise Error, "SQL log normalization is not supported on this database (' literalized as #{db.literal("'").inspect})" 43 end 44 db.instance_variable_set(:@sql_string_escape_type, type) 45 end
Public Instance methods
log_connection_yield(sql, conn, args=nil)
Normalize the SQL
before calling super.
[show source]
# File lib/sequel/extensions/sql_log_normalizer.rb 48 def log_connection_yield(sql, conn, args=nil) 49 unless skip_logging? 50 sql = normalize_logged_sql(sql) 51 args = nil 52 end 53 super 54 end
normalize_logged_sql(sql)
Replace literal strings and numbers in SQL
with question mark placeholders.
[show source]
# File lib/sequel/extensions/sql_log_normalizer.rb 57 def normalize_logged_sql(sql) 58 sql = sql.dup 59 sql.force_encoding('BINARY') 60 start_index = 0 61 check_n = @sql_string_escape_type == :n_standard 62 outside_string = true 63 64 if @sql_string_escape_type == :backslash 65 search_char = /[\\']/ 66 escape_char_offset = 0 67 escape_char_value = 92 # backslash 68 else 69 search_char = "'" 70 escape_char_offset = 1 71 escape_char_value = 39 # apostrophe 72 end 73 74 # The approach used here goes against Sequel's philosophy of never attempting 75 # to parse SQL. However, parsing the SQL is basically the only way to implement 76 # this support with Sequel's design, and it's better to be pragmatic and accept 77 # this than not be able to support this. 78 79 # Replace literal strings 80 while outside_string && (index = start_index = sql.index("'", start_index)) 81 if check_n && index != 0 && sql.getbyte(index-1) == 78 # N' start 82 start_index -= 1 83 end 84 index += 1 85 outside_string = false 86 87 while (index = sql.index(search_char, index)) && (sql.getbyte(index + escape_char_offset) == escape_char_value) 88 # skip escaped characters inside string literal 89 index += 2 90 end 91 92 if index 93 # Found end of string 94 sql[start_index..index] = '?' 95 start_index += 1 96 outside_string = true 97 end 98 end 99 100 # Replace integer and decimal floating point numbers 101 sql.gsub!(/\b-?\d+(?:\.\d+)?\b/, '?') 102 103 sql 104 end