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
64 65 66 |
# File 'lib/niceql.rb', line 64 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
129 130 131 132 133 134 135 136 137 |
# File 'lib/niceql.rb', line 129 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
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 117 118 119 120 121 122 123 |
# File 'lib/niceql.rb', line 89 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 = if sql_start_line_num < err.lines.length err.lines[sql_start_line_num..-1] else original_sql_query&.lines end # 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
125 126 127 |
# File 'lib/niceql.rb', line 125 def prettify_sql(sql, colorize = true) QueryNormalizer.new(sql, colorize).prettified_sql end |