Module: Niceql::Prettifier
- Defined in:
- lib/niceql.rb
Defined Under Namespace
Classes: QueryNormalizer
Constant Summary collapse
- AFTER_KEYWORD_SPACE =
?= – should be present but without being added to MatchData
'(?=\s{1})'- JOIN_KEYWORDS =
'(RIGHT\s+|LEFT\s+){0,1}(INNER\s+|OUTER\s+){0,1}JOIN(\s+LATERAL){0,1}'- INLINE_KEYWORDS =
"WITH|ASC|COALESCE|AS|WHEN|THEN|ELSE|END|AND|UNION|ALL|ON|DISTINCT|INTERSECT|EXCEPT|EXISTS|NOT|COUNT|ROUND|CAST|IN"- NEW_LINE_KEYWORDS =
"SELECT|FROM|WHERE|CASE|ORDER BY|LIMIT|GROUP BY|HAVING|OFFSET|UPDATE|SET|#{JOIN_KEYWORDS}"- POSSIBLE_INLINER =
/(ORDER BY|CASE)/- KEYWORDS =
"(#{NEW_LINE_KEYWORDS}|#{INLINE_KEYWORDS})#{AFTER_KEYWORD_SPACE}"- MULTILINE_INDENTABLE_LITERAL =
?: – will not match partial enclosed by (..)
/(?:'[^']+'\s*\n+\s*)+(?:'[^']+')+/- STRINGS =
STRINGS matched both kind of strings the multiline solid and single quoted multiline strings with s*n+s* separation
/("[^"]+")|((?:'[^']+'\s*\n+\s*)*(?:'[^']+')+)/- BRACKETS =
'[\(\)]'- SQL_COMMENTS =
will match all /* single line and multiline comments */ and – based comments the last will be matched as single block whenever comment lines followed each other. For instance: SELECT * – comment 1 – comment 2 all comments will be matched as a single block
%r{(\s*?--[^\n]+\n*)+|(\s*?/\*[^/\*]*\*/\s*)}m- COMMENT_CONTENT =
/[\S]+[\s\S]*[\S]+/- NAMED_DOLLAR_QUOTED_STRINGS_REGEX =
/[^\$](\$[^\$]+\$)[^\$]/- DOLLAR_QUOTED_STRINGS =
/(\$\$.*\$\$)/
Class Method Summary collapse
- .config ⇒ Object
- .prettify_err(err, original_sql_query = nil) ⇒ Object
- .prettify_multiple(sql_multi, colorize = true) ⇒ Object
-
.prettify_pg_err(err, original_sql_query = nil) ⇒ Object
prettify_pg_err parses ActiveRecord::StatementInvalid string, but you may use it without ActiveRecord either way: prettify_pg_err( err + “n” + sql ) OR prettify_pg_err( err, sql ) don’t mess with original sql query, or prettify_pg_err will deliver incorrect results.
- .prettify_sql(sql, colorize = true) ⇒ Object
Class Method Details
.prettify_err(err, original_sql_query = nil) ⇒ Object
61 62 63 |
# File 'lib/niceql.rb', line 61 def prettify_err(err, original_sql_query = nil) prettify_pg_err(err.to_s, original_sql_query) end |
.prettify_multiple(sql_multi, colorize = true) ⇒ Object
122 123 124 125 126 127 128 129 130 |
# File 'lib/niceql.rb', line 122 def prettify_multiple(sql_multi, colorize = true) sql_multi.split(/(?>#{SQL_COMMENTS})|(\;)/).each_with_object([""]) do |pattern, queries| queries[-1] += pattern queries << "" if pattern == ";" end.map! do |sql| # we were splitting by comments and ';', so if next sql start with comment we've got a misplaced \n\n sql.match?(/\A\s+\z/) ? nil : prettify_sql(sql, colorize) end.compact.join("\n") end |
.prettify_pg_err(err, original_sql_query = nil) ⇒ Object
prettify_pg_err parses ActiveRecord::StatementInvalid string, but you may use it without ActiveRecord either way: prettify_pg_err( err + “n” + sql ) OR prettify_pg_err( err, sql ) don’t mess with original sql query, or prettify_pg_err will deliver incorrect results
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/niceql.rb', line 86 def prettify_pg_err(err, original_sql_query = nil) return err if err[/LINE \d+/].nil? # LINE 2: ... -> err_line_num = 2 err_line_num = err.match(/LINE (\d+):/)[1].to_i # LINE 1: SELECT usr FROM users ORDER BY 1 err_address_line = err.lines[1] sql_start_line_num = 3 if err.lines.length <= 3 # error not always contains HINT sql_start_line_num ||= err.lines[3][/(HINT|DETAIL)/] ? 4 : 3 sql_body_lines = sql_start_line_num < err.lines.length ? err.lines[sql_start_line_num..-1] : original_sql_query&.lines # this means original query is missing so it's nothing to prettify return err unless sql_body_lines # this is an SQL line with an error. # we need err_line to properly align the caret in the caret line # and to apply a full red colorizing schema on an SQL line with error err_line = sql_body_lines[err_line_num - 1] # colorizing keywords, strings and error line err_body = sql_body_lines.map do |ln| ln == err_line ? StringColorize.colorize_err(ln) : colorize_err_line(ln) end err_caret_line = extract_err_caret_line(err_address_line, err_line, sql_body_lines, err) err_body.insert(err_line_num, StringColorize.colorize_err(err_caret_line)) err.lines[0..sql_start_line_num - 1].join + err_body.join end |
.prettify_sql(sql, colorize = true) ⇒ Object
118 119 120 |
# File 'lib/niceql.rb', line 118 def prettify_sql(sql, colorize = true) QueryNormalizer.new(sql, colorize).prettified_sql end |