niceql 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.rubocop.yml +2 -0
 - data/CHANGELOG.md +8 -0
 - data/Gemfile +3 -1
 - data/README.md +5 -4
 - data/Rakefile +3 -1
 - data/bin/console +1 -0
 - data/lib/generators/niceql/install_generator.rb +4 -2
 - data/lib/generators/templates/niceql_initializer.rb +3 -1
 - data/lib/niceql/version.rb +3 -1
 - data/lib/niceql.rb +337 -105
 - data/niceql.gemspec +19 -11
 - metadata +37 -11
 - data/lib/benchmark/cat.rb +0 -34
 - data/lib/benchmark/gsub.rb +0 -34
 - data/lib/benchmark/txt +0 -748
 
    
        data/lib/niceql.rb
    CHANGED
    
    | 
         @@ -1,33 +1,57 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require "niceql/version"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "securerandom"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "forwardable"
         
     | 
| 
       2 
6 
     | 
    
         | 
| 
       3 
7 
     | 
    
         
             
            module Niceql
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
8 
     | 
    
         
             
              module StringColorize
         
     | 
| 
       6 
     | 
    
         
            -
                def self. 
     | 
| 
      
 9 
     | 
    
         
            +
                def self.colorize_keyword(str)
         
     | 
| 
       7 
10 
     | 
    
         
             
                  # yellow ANSI color
         
     | 
| 
       8 
11 
     | 
    
         
             
                  "\e[0;33;49m#{str}\e[0m"
         
     | 
| 
       9 
12 
     | 
    
         
             
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
       10 
14 
     | 
    
         
             
                def self.colorize_str(str)
         
     | 
| 
       11 
15 
     | 
    
         
             
                  # cyan ANSI color
         
     | 
| 
       12 
16 
     | 
    
         
             
                  "\e[0;36;49m#{str}\e[0m"
         
     | 
| 
       13 
17 
     | 
    
         
             
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       14 
19 
     | 
    
         
             
                def self.colorize_err(err)
         
     | 
| 
       15 
20 
     | 
    
         
             
                  # red ANSI color
         
     | 
| 
       16 
21 
     | 
    
         
             
                  "\e[0;31;49m#{err}\e[0m"
         
     | 
| 
       17 
22 
     | 
    
         
             
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def self.colorize_comment(comment)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # bright black bold ANSI color
         
     | 
| 
      
 26 
     | 
    
         
            +
                  "\e[0;90;1;49m#{comment}\e[0m"
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
       18 
28 
     | 
    
         
             
              end
         
     | 
| 
       19 
29 
     | 
    
         | 
| 
       20 
30 
     | 
    
         
             
              module Prettifier
         
     | 
| 
       21 
     | 
    
         
            -
                 
     | 
| 
       22 
     | 
    
         
            -
                 
     | 
| 
      
 31 
     | 
    
         
            +
                # ?= -- should be present but without being added to MatchData
         
     | 
| 
      
 32 
     | 
    
         
            +
                AFTER_KEYWORD_SPACE = '(?=\s{1})'
         
     | 
| 
      
 33 
     | 
    
         
            +
                JOIN_KEYWORDS = '(RIGHT\s+|LEFT\s+){0,1}(INNER\s+|OUTER\s+){0,1}JOIN(\s+LATERAL){0,1}'
         
     | 
| 
      
 34 
     | 
    
         
            +
                INLINE_KEYWORDS = "WITH|ASC|COALESCE|AS|WHEN|THEN|ELSE|END|AND|UNION|ALL|ON|DISTINCT|INTERSECT|EXCEPT|EXISTS|NOT|COUNT|ROUND|CAST|IN"
         
     | 
| 
      
 35 
     | 
    
         
            +
                NEW_LINE_KEYWORDS = "SELECT|FROM|WHERE|CASE|ORDER BY|LIMIT|GROUP BY|HAVING|OFFSET|UPDATE|SET|#{JOIN_KEYWORDS}"
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
       23 
37 
     | 
    
         
             
                POSSIBLE_INLINER = /(ORDER BY|CASE)/
         
     | 
| 
       24 
     | 
    
         
            -
                 
     | 
| 
       25 
     | 
    
         
            -
                 
     | 
| 
      
 38 
     | 
    
         
            +
                KEYWORDS = "(#{NEW_LINE_KEYWORDS}|#{INLINE_KEYWORDS})#{AFTER_KEYWORD_SPACE}"
         
     | 
| 
      
 39 
     | 
    
         
            +
                # ?: -- will not match partial enclosed by (..)
         
     | 
| 
      
 40 
     | 
    
         
            +
                MULTILINE_INDENTABLE_LITERAL = /(?:'[^']+'\s*\n+\s*)+(?:'[^']+')+/
         
     | 
| 
      
 41 
     | 
    
         
            +
                # STRINGS matched both kind of strings the multiline solid
         
     | 
| 
      
 42 
     | 
    
         
            +
                # and single quoted multiline strings with \s*\n+\s* separation
         
     | 
| 
      
 43 
     | 
    
         
            +
                STRINGS = /("[^"]+")|((?:'[^']+'\s*\n+\s*)*(?:'[^']+')+)/
         
     | 
| 
       26 
44 
     | 
    
         
             
                BRACKETS = '[\(\)]'
         
     | 
| 
       27 
     | 
    
         
            -
                 
     | 
| 
       28 
     | 
    
         
            -
                #  
     | 
| 
       29 
     | 
    
         
            -
                 
     | 
| 
      
 45 
     | 
    
         
            +
                # will match all /* single line and multiline comments */ and -- based comments
         
     | 
| 
      
 46 
     | 
    
         
            +
                # the last will be matched as single block whenever comment lines followed each other.
         
     | 
| 
      
 47 
     | 
    
         
            +
                # For instance:
         
     | 
| 
      
 48 
     | 
    
         
            +
                # SELECT * -- comment 1
         
     | 
| 
      
 49 
     | 
    
         
            +
                # -- comment 2
         
     | 
| 
      
 50 
     | 
    
         
            +
                # all comments will be matched as a single block
         
     | 
| 
      
 51 
     | 
    
         
            +
                SQL_COMMENTS = %r{(\s*?--[^\n]+\n*)+|(\s*?/\*[^/\*]*\*/\s*)}m
         
     | 
| 
       30 
52 
     | 
    
         
             
                COMMENT_CONTENT = /[\S]+[\s\S]*[\S]+/
         
     | 
| 
      
 53 
     | 
    
         
            +
                NAMED_DOLLAR_QUOTED_STRINGS_REGEX = /[^\$](\$[^\$]+\$)[^\$]/
         
     | 
| 
      
 54 
     | 
    
         
            +
                DOLLAR_QUOTED_STRINGS = /(\$\$.*\$\$)/
         
     | 
| 
       31 
55 
     | 
    
         | 
| 
       32 
56 
     | 
    
         
             
                class << self
         
     | 
| 
       33 
57 
     | 
    
         
             
                  def config
         
     | 
| 
         @@ -35,10 +59,9 @@ module Niceql 
     | 
|
| 
       35 
59 
     | 
    
         
             
                  end
         
     | 
| 
       36 
60 
     | 
    
         | 
| 
       37 
61 
     | 
    
         
             
                  def prettify_err(err, original_sql_query = nil)
         
     | 
| 
       38 
     | 
    
         
            -
                    prettify_pg_err( 
     | 
| 
      
 62 
     | 
    
         
            +
                    prettify_pg_err(err.to_s, original_sql_query)
         
     | 
| 
       39 
63 
     | 
    
         
             
                  end
         
     | 
| 
       40 
64 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
65 
     | 
    
         
             
                  # Postgres error output:
         
     | 
| 
       43 
66 
     | 
    
         
             
                  # ERROR:  VALUES in FROM must have an alias
         
     | 
| 
       44 
67 
     | 
    
         
             
                  # LINE 2: FROM ( VALUES(1), (2) );
         
     | 
| 
         @@ -54,7 +77,7 @@ module Niceql 
     | 
|
| 
       54 
77 
     | 
    
         
             
                  # ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column "usr" does not exist
         
     | 
| 
       55 
78 
     | 
    
         
             
                  # LINE 1: SELECT usr FROM users ORDER BY 1
         
     | 
| 
       56 
79 
     | 
    
         
             
                  #                ^
         
     | 
| 
       57 
     | 
    
         
            -
                   
     | 
| 
      
 80 
     | 
    
         
            +
                  # : SELECT usr FROM users ORDER BY 1
         
     | 
| 
       58 
81 
     | 
    
         | 
| 
       59 
82 
     | 
    
         
             
                  # prettify_pg_err parses ActiveRecord::StatementInvalid string,
         
     | 
| 
       60 
83 
     | 
    
         
             
                  # but you may use it without ActiveRecord either way:
         
     | 
| 
         @@ -62,6 +85,7 @@ module Niceql 
     | 
|
| 
       62 
85 
     | 
    
         
             
                  # don't mess with original sql query, or prettify_pg_err will deliver incorrect results
         
     | 
| 
       63 
86 
     | 
    
         
             
                  def prettify_pg_err(err, original_sql_query = nil)
         
     | 
| 
       64 
87 
     | 
    
         
             
                    return err if err[/LINE \d+/].nil?
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
       65 
89 
     | 
    
         
             
                    # LINE 2: ... -> err_line_num = 2
         
     | 
| 
       66 
90 
     | 
    
         
             
                    err_line_num = err.match(/LINE (\d+):/)[1].to_i
         
     | 
| 
       67 
91 
     | 
    
         
             
                    # LINE 1: SELECT usr FROM users ORDER BY 1
         
     | 
| 
         @@ -80,130 +104,335 @@ module Niceql 
     | 
|
| 
       80 
104 
     | 
    
         
             
                    # and to apply a full red colorizing schema on an SQL line with error
         
     | 
| 
       81 
105 
     | 
    
         
             
                    err_line = sql_body_lines[err_line_num - 1]
         
     | 
| 
       82 
106 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
                    #colorizing  
     | 
| 
       84 
     | 
    
         
            -
                    err_body = sql_body_lines.map  
     | 
| 
      
 107 
     | 
    
         
            +
                    # colorizing keywords, strings and error line
         
     | 
| 
      
 108 
     | 
    
         
            +
                    err_body = sql_body_lines.map do |ln|
         
     | 
| 
      
 109 
     | 
    
         
            +
                      ln == err_line ? StringColorize.colorize_err(ln) : colorize_err_line(ln)
         
     | 
| 
      
 110 
     | 
    
         
            +
                    end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                    err_caret_line = extract_err_caret_line(err_address_line, err_line, sql_body_lines, err)
         
     | 
| 
      
 113 
     | 
    
         
            +
                    err_body.insert(err_line_num, StringColorize.colorize_err(err_caret_line))
         
     | 
| 
       85 
114 
     | 
    
         | 
| 
       86 
     | 
    
         
            -
                     
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
      
 115 
     | 
    
         
            +
                    err.lines[0..sql_start_line_num - 1].join + err_body.join
         
     | 
| 
      
 116 
     | 
    
         
            +
                  end
         
     | 
| 
       88 
117 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
      
 118 
     | 
    
         
            +
                  def prettify_sql(sql, colorize = true)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    QueryNormalizer.new(sql, colorize).prettified_sql
         
     | 
| 
       90 
120 
     | 
    
         
             
                  end
         
     | 
| 
       91 
121 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
                  def  
     | 
| 
      
 122 
     | 
    
         
            +
                  def prettify_multiple(sql_multi, colorize = true)
         
     | 
| 
      
 123 
     | 
    
         
            +
                    sql_multi.split(/(?>#{SQL_COMMENTS})|(\;)/).each_with_object([""]) do |pattern, queries|
         
     | 
| 
      
 124 
     | 
    
         
            +
                      queries[-1] += pattern
         
     | 
| 
      
 125 
     | 
    
         
            +
                      queries << "" if pattern == ";"
         
     | 
| 
      
 126 
     | 
    
         
            +
                    end.map! do |sql|
         
     | 
| 
      
 127 
     | 
    
         
            +
                      # we were splitting by comments and ';', so if next sql start with comment we've got a misplaced \n\n
         
     | 
| 
      
 128 
     | 
    
         
            +
                      sql.match?(/\A\s+\z/) ? nil : prettify_sql(sql, colorize)
         
     | 
| 
      
 129 
     | 
    
         
            +
                    end.compact.join("\n")
         
     | 
| 
      
 130 
     | 
    
         
            +
                  end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                  private
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                  def colorize_err_line(line)
         
     | 
| 
      
 135 
     | 
    
         
            +
                    line.gsub(/#{KEYWORDS}/) { |keyword| StringColorize.colorize_keyword(keyword) }
         
     | 
| 
      
 136 
     | 
    
         
            +
                      .gsub(STRINGS) { |str| StringColorize.colorize_str(str) }
         
     | 
| 
      
 137 
     | 
    
         
            +
                  end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                  def extract_err_caret_line(err_address_line, err_line, sql_body, err)
         
     | 
| 
      
 140 
     | 
    
         
            +
                    # LINE could be quoted ( both sides and sometimes only from one ):
         
     | 
| 
      
 141 
     | 
    
         
            +
                    # "LINE 1: ...t_id\" = $13 AND \"products\".\"carrier_id\" = $14 AND \"product_t...\n",
         
     | 
| 
      
 142 
     | 
    
         
            +
                    err_quote = (err_address_line.match(/\.\.\.(.+)\.\.\./) || err_address_line.match(/\.\.\.(.+)/))&.send(:[], 1)
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                    # line[2] is original err caret line i.e.: '      ^'
         
     | 
| 
      
 145 
     | 
    
         
            +
                    # err_address_line[/LINE \d+:/].length+1..-1 - is a position from error quote begin
         
     | 
| 
      
 146 
     | 
    
         
            +
                    err_caret_line = err.lines[2][err_address_line[/LINE \d+:/].length + 1..-1]
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                    # when err line is too long postgres quotes it in double '...'
         
     | 
| 
      
 149 
     | 
    
         
            +
                    # so we need to reposition caret against original line
         
     | 
| 
      
 150 
     | 
    
         
            +
                    if err_quote
         
     | 
| 
      
 151 
     | 
    
         
            +
                      err_quote_caret_offset = err_caret_line.length - err_address_line.index("...").to_i + 3
         
     | 
| 
      
 152 
     | 
    
         
            +
                      err_caret_line = " " * (err_line.index(err_quote) + err_quote_caret_offset) + "^\n"
         
     | 
| 
      
 153 
     | 
    
         
            +
                    end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                    # older versions of ActiveRecord were adding ': ' before an original query :(
         
     | 
| 
      
 156 
     | 
    
         
            +
                    err_caret_line.prepend("  ") if sql_body[0].start_with?(": ")
         
     | 
| 
      
 157 
     | 
    
         
            +
                    # if mistake is on last string than err_line.last != \n then we need to prepend \n to caret line
         
     | 
| 
      
 158 
     | 
    
         
            +
                    err_caret_line.prepend("\n") unless err_line[-1] == "\n"
         
     | 
| 
      
 159 
     | 
    
         
            +
                    err_caret_line
         
     | 
| 
      
 160 
     | 
    
         
            +
                  end
         
     | 
| 
      
 161 
     | 
    
         
            +
                end
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                # The normalizing and formatting logic:
         
     | 
| 
      
 164 
     | 
    
         
            +
                # 1. Split the original query onto the query part + literals + comments
         
     | 
| 
      
 165 
     | 
    
         
            +
                #   a. find all potential dollar-signed separators
         
     | 
| 
      
 166 
     | 
    
         
            +
                #   b. prepare full literal extractor regex
         
     | 
| 
      
 167 
     | 
    
         
            +
                # 2. Find and separate all literals and comments into mutable/format-able types and immutable  ( see the typing and formatting rules below )
         
     | 
| 
      
 168 
     | 
    
         
            +
                # 3. Replace all literals and comments with uniq ids on the original query to get the parametrized query
         
     | 
| 
      
 169 
     | 
    
         
            +
                # 4. Format parametrized query alongside with mutable/format-able comments and literals
         
     | 
| 
      
 170 
     | 
    
         
            +
                #   a. clear space characters: replace all \s+ to \s, remove all "\n" e.t.c
         
     | 
| 
      
 171 
     | 
    
         
            +
                #   b. split in lines -> indent -> colorize
         
     | 
| 
      
 172 
     | 
    
         
            +
                # 5. Restore literals and comments with their values
         
     | 
| 
      
 173 
     | 
    
         
            +
                class QueryNormalizer
         
     | 
| 
      
 174 
     | 
    
         
            +
                  extend Forwardable
         
     | 
| 
      
 175 
     | 
    
         
            +
                  def_delegator :Niceql, :config
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                  # Literals content should not be indented, only string parts separated by new lines can be indented
         
     | 
| 
      
 178 
     | 
    
         
            +
                  # indentable_string:
         
     | 
| 
      
 179 
     | 
    
         
            +
                  # UPDATE docs SET body = 'First line'
         
     | 
| 
      
 180 
     | 
    
         
            +
                  # 'Second line'
         
     | 
| 
      
 181 
     | 
    
         
            +
                  # 'Third line', ...
         
     | 
| 
      
 182 
     | 
    
         
            +
                  #
         
     | 
| 
      
 183 
     | 
    
         
            +
                  # SQL standard allow such multiline separation.
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                  # newline_end_comments:
         
     | 
| 
      
 186 
     | 
    
         
            +
                  # SELECT * -- get all column
         
     | 
| 
      
 187 
     | 
    
         
            +
                  # SELECT * /* get all column */
         
     | 
| 
      
 188 
     | 
    
         
            +
                  #
         
     | 
| 
      
 189 
     | 
    
         
            +
                  # SELECT * -- get all column
         
     | 
| 
      
 190 
     | 
    
         
            +
                  # -- we need all columns for this request
         
     | 
| 
      
 191 
     | 
    
         
            +
                  # SELECT * /* get all column
         
     | 
| 
      
 192 
     | 
    
         
            +
                  # we need all columns for this request */
         
     | 
| 
      
 193 
     | 
    
         
            +
                  #
         
     | 
| 
      
 194 
     | 
    
         
            +
                  # rare case newline_start_comments:
         
     | 
| 
      
 195 
     | 
    
         
            +
                  # SELECT *
         
     | 
| 
      
 196 
     | 
    
         
            +
                  # /* get all column
         
     | 
| 
      
 197 
     | 
    
         
            +
                  # we need all columns for this request */ FROM table
         
     | 
| 
      
 198 
     | 
    
         
            +
                  #
         
     | 
| 
      
 199 
     | 
    
         
            +
                  # newline_wrapped_comments:
         
     | 
| 
      
 200 
     | 
    
         
            +
                  # SELECT *
         
     | 
| 
      
 201 
     | 
    
         
            +
                  # /* get all column
         
     | 
| 
      
 202 
     | 
    
         
            +
                  # we need all columns for this request */
         
     | 
| 
      
 203 
     | 
    
         
            +
                  # FROM table
         
     | 
| 
      
 204 
     | 
    
         
            +
                  #
         
     | 
| 
      
 205 
     | 
    
         
            +
                  # SELECT *
         
     | 
| 
      
 206 
     | 
    
         
            +
                  # -- get all column
         
     | 
| 
      
 207 
     | 
    
         
            +
                  # -- we need all columns for this request
         
     | 
| 
      
 208 
     | 
    
         
            +
                  # FROM ...
         
     | 
| 
      
 209 
     | 
    
         
            +
                  # Potentially we could prettify different type of comments and strings a little bit differently,
         
     | 
| 
      
 210 
     | 
    
         
            +
                  # but right now there is no difference between the
         
     | 
| 
      
 211 
     | 
    
         
            +
                  # newline_wrapped_comment, newline_start_comment, newline_end_comment, they all will be wrapped in newlines
         
     | 
| 
      
 212 
     | 
    
         
            +
                  COMMENT_AND_LITERAL_TYPES = [:immutable_string, :indentable_string, :inline_comment, :newline_wrapped_comment,
         
     | 
| 
      
 213 
     | 
    
         
            +
                                               :newline_start_comment, :newline_end_comment]
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                  attr_reader :parametrized_sql, :initial_sql, :string_regex, :literals_and_comments_types, :colorize
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
                  def initialize(sql, colorize)
         
     | 
| 
      
 218 
     | 
    
         
            +
                    @initial_sql = sql
         
     | 
| 
      
 219 
     | 
    
         
            +
                    @colorize = colorize
         
     | 
| 
      
 220 
     | 
    
         
            +
                    @parametrized_sql = ""
         
     | 
| 
      
 221 
     | 
    
         
            +
                    @guids_to_content = {}
         
     | 
| 
      
 222 
     | 
    
         
            +
                    @literals_and_comments_types = {}
         
     | 
| 
      
 223 
     | 
    
         
            +
                    @counter = Hash.new(0)
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
                    init_strings_regex
         
     | 
| 
      
 226 
     | 
    
         
            +
                    prepare_parametrized_sql
         
     | 
| 
      
 227 
     | 
    
         
            +
                    prettify_parametrized_sql
         
     | 
| 
      
 228 
     | 
    
         
            +
                  end
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
                  def prettified_sql
         
     | 
| 
      
 231 
     | 
    
         
            +
                    @parametrized_sql % @guids_to_content.transform_keys(&:to_sym)
         
     | 
| 
      
 232 
     | 
    
         
            +
                  end
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
                  private
         
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
                  def prettify_parametrized_sql
         
     | 
| 
       93 
237 
     | 
    
         
             
                    indent = 0
         
     | 
| 
       94 
     | 
    
         
            -
                     
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
                       
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
                    sql.gsub!( /(#{VERBS}|#{BRACKETS}|#{SQL_COMMENTS_CLEARED})/) do |verb|
         
     | 
| 
       112 
     | 
    
         
            -
                      if 'SELECT' == verb
         
     | 
| 
       113 
     | 
    
         
            -
                        indent += config.indentation_base if !config.open_bracket_is_newliner || parentness.last.nil? || parentness.last[:nested]
         
     | 
| 
       114 
     | 
    
         
            -
                        parentness.last[:nested] = true if parentness.last
         
     | 
| 
       115 
     | 
    
         
            -
                        add_new_line = !first_verb
         
     | 
| 
       116 
     | 
    
         
            -
                      elsif verb == '('
         
     | 
| 
       117 
     | 
    
         
            -
                        next_closing_bracket = Regexp.last_match.post_match.index(')')
         
     | 
| 
      
 238 
     | 
    
         
            +
                    brackets = []
         
     | 
| 
      
 239 
     | 
    
         
            +
                    first_keyword = true
         
     | 
| 
      
 240 
     | 
    
         
            +
             
     | 
| 
      
 241 
     | 
    
         
            +
                    parametrized_sql.gsub!(query_split_regex) do |matched_part|
         
     | 
| 
      
 242 
     | 
    
         
            +
                      if inline_piece?(matched_part)
         
     | 
| 
      
 243 
     | 
    
         
            +
                        first_keyword = false
         
     | 
| 
      
 244 
     | 
    
         
            +
                        next matched_part
         
     | 
| 
      
 245 
     | 
    
         
            +
                      end
         
     | 
| 
      
 246 
     | 
    
         
            +
                      post_match_str = Regexp.last_match.post_match
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
                      if ["SELECT", "UPDATE", "INSERT"].include?(matched_part)
         
     | 
| 
      
 249 
     | 
    
         
            +
                        indent += config.indentation_base if !config.open_bracket_is_newliner || brackets.last.nil? || brackets.last[:nested]
         
     | 
| 
      
 250 
     | 
    
         
            +
                        brackets.last[:nested] = true if brackets.last
         
     | 
| 
      
 251 
     | 
    
         
            +
                        add_new_line = !first_keyword
         
     | 
| 
      
 252 
     | 
    
         
            +
                      elsif matched_part == "("
         
     | 
| 
      
 253 
     | 
    
         
            +
                        next_closing_bracket = post_match_str.index(")")
         
     | 
| 
       118 
254 
     | 
    
         
             
                        # check if brackets contains SELECT statement
         
     | 
| 
       119 
     | 
    
         
            -
                        add_new_line = !! 
     | 
| 
       120 
     | 
    
         
            -
                         
     | 
| 
       121 
     | 
    
         
            -
                      elsif  
     | 
| 
      
 255 
     | 
    
         
            +
                        add_new_line = !!post_match_str[0..next_closing_bracket][/SELECT/] && config.open_bracket_is_newliner
         
     | 
| 
      
 256 
     | 
    
         
            +
                        brackets << { nested: add_new_line }
         
     | 
| 
      
 257 
     | 
    
         
            +
                      elsif matched_part == ")"
         
     | 
| 
       122 
258 
     | 
    
         
             
                        # this also covers case when right bracket is used without corresponding left one
         
     | 
| 
       123 
     | 
    
         
            -
                        add_new_line =  
     | 
| 
       124 
     | 
    
         
            -
                        indent -= ( 
     | 
| 
      
 259 
     | 
    
         
            +
                        add_new_line = brackets.last.nil? || brackets.last[:nested]
         
     | 
| 
      
 260 
     | 
    
         
            +
                        indent -= (brackets.last.nil? && 2 || brackets.last[:nested] && 1 || 0) * config.indentation_base
         
     | 
| 
       125 
261 
     | 
    
         
             
                        indent = 0 if indent < 0
         
     | 
| 
       126 
     | 
    
         
            -
                         
     | 
| 
       127 
     | 
    
         
            -
                      elsif  
     | 
| 
      
 262 
     | 
    
         
            +
                        brackets.pop
         
     | 
| 
      
 263 
     | 
    
         
            +
                      elsif matched_part[POSSIBLE_INLINER]
         
     | 
| 
       128 
264 
     | 
    
         
             
                        # in postgres ORDER BY can be used in aggregation function this will keep it
         
     | 
| 
       129 
265 
     | 
    
         
             
                        # inline with its agg function
         
     | 
| 
       130 
     | 
    
         
            -
                        add_new_line =  
     | 
| 
      
 266 
     | 
    
         
            +
                        add_new_line = brackets.last.nil? || brackets.last[:nested]
         
     | 
| 
       131 
267 
     | 
    
         
             
                      else
         
     | 
| 
       132 
     | 
    
         
            -
                         
     | 
| 
      
 268 
     | 
    
         
            +
                        # since we are matching KEYWORD without space on the end
         
     | 
| 
      
 269 
     | 
    
         
            +
                        # IN will be present in JOIN, DISTINCT e.t.c, so we need to exclude it explicitly
         
     | 
| 
      
 270 
     | 
    
         
            +
                        add_new_line = matched_part.match?(/(#{NEW_LINE_KEYWORDS})/)
         
     | 
| 
       133 
271 
     | 
    
         
             
                      end
         
     | 
| 
       134 
272 
     | 
    
         | 
| 
       135 
     | 
    
         
            -
                      #  
     | 
| 
       136 
     | 
    
         
            -
                       
     | 
| 
       137 
     | 
    
         
            -
                      # inliners match with a space before so we need to strip it
         
     | 
| 
       138 
     | 
    
         
            -
                      verb.lstrip! if !add_new_line && prev_was_comment
         
     | 
| 
      
 273 
     | 
    
         
            +
                      # do not indent first keyword in query, and indent everytime we started new line
         
     | 
| 
      
 274 
     | 
    
         
            +
                      add_indent_to_keyword = !first_keyword && add_new_line
         
     | 
| 
       139 
275 
     | 
    
         | 
| 
       140 
     | 
    
         
            -
                       
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
                         
     | 
| 
       145 
     | 
    
         
            -
                         
     | 
| 
      
 276 
     | 
    
         
            +
                      if literals_and_comments_types[matched_part]
         
     | 
| 
      
 277 
     | 
    
         
            +
                        # this is a case when comment followed by ordinary SQL part not by any keyword
         
     | 
| 
      
 278 
     | 
    
         
            +
                        # this means that it will not be gsubed and no indent will be added before this part, while needed
         
     | 
| 
      
 279 
     | 
    
         
            +
                        last_comment_followed_by_keyword = post_match_str.match?(/\A\}\s{0,1}(?:#{KEYWORDS})/)
         
     | 
| 
      
 280 
     | 
    
         
            +
                        indent_parametrized_part(matched_part, indent, !last_comment_followed_by_keyword, !first_keyword)
         
     | 
| 
      
 281 
     | 
    
         
            +
                        matched_part
         
     | 
| 
       146 
282 
     | 
    
         
             
                      else
         
     | 
| 
       147 
     | 
    
         
            -
                         
     | 
| 
       148 
     | 
    
         
            -
                         
     | 
| 
      
 283 
     | 
    
         
            +
                        first_keyword = false
         
     | 
| 
      
 284 
     | 
    
         
            +
                        indented_sql = (add_indent_to_keyword ? indent_multiline(matched_part, indent) : matched_part)
         
     | 
| 
      
 285 
     | 
    
         
            +
                        add_new_line ? "\n" + indented_sql : indented_sql
         
     | 
| 
       149 
286 
     | 
    
         
             
                      end
         
     | 
| 
      
 287 
     | 
    
         
            +
                    end
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
      
 289 
     | 
    
         
            +
                    parametrized_sql.gsub!(" \n", "\n") # moved keywords could keep space before it, we can crop it anyway
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
      
 291 
     | 
    
         
            +
                    clear_extra_newline_after_comments
         
     | 
| 
      
 292 
     | 
    
         
            +
             
     | 
| 
      
 293 
     | 
    
         
            +
                    colorize_query if colorize
         
     | 
| 
      
 294 
     | 
    
         
            +
                  end
         
     | 
| 
       150 
295 
     | 
    
         | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
      
 296 
     | 
    
         
            +
                  def add_string_or_comment(string_or_comment)
         
     | 
| 
      
 297 
     | 
    
         
            +
                    # when we splitting original SQL, it could and could not end with literal/comment
         
     | 
| 
      
 298 
     | 
    
         
            +
                    # hence we could try to add nil...
         
     | 
| 
      
 299 
     | 
    
         
            +
                    return if string_or_comment.nil?
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
      
 301 
     | 
    
         
            +
                    type = get_placeholder_type(string_or_comment)
         
     | 
| 
      
 302 
     | 
    
         
            +
                    # will be formatted to comment_1_guid
         
     | 
| 
      
 303 
     | 
    
         
            +
                    typed_id = new_placeholder_name(type)
         
     | 
| 
      
 304 
     | 
    
         
            +
                    @guids_to_content[typed_id] = string_or_comment
         
     | 
| 
      
 305 
     | 
    
         
            +
                    @counter[type] += 1
         
     | 
| 
      
 306 
     | 
    
         
            +
                    @literals_and_comments_types[typed_id] = type
         
     | 
| 
      
 307 
     | 
    
         
            +
                    "%{#{typed_id}}"
         
     | 
| 
      
 308 
     | 
    
         
            +
                  end
         
     | 
| 
      
 309 
     | 
    
         
            +
             
     | 
| 
      
 310 
     | 
    
         
            +
                  def literal_and_comments_placeholders_regex
         
     | 
| 
      
 311 
     | 
    
         
            +
                    /(#{@literals_and_comments_types.keys.join("|")})/
         
     | 
| 
      
 312 
     | 
    
         
            +
                  end
         
     | 
| 
      
 313 
     | 
    
         
            +
             
     | 
| 
      
 314 
     | 
    
         
            +
                  def inline_piece?(comment_or_string)
         
     | 
| 
      
 315 
     | 
    
         
            +
                    [:immutable_string, :inline_comment].include?(literals_and_comments_types[comment_or_string])
         
     | 
| 
      
 316 
     | 
    
         
            +
                  end
         
     | 
| 
      
 317 
     | 
    
         
            +
             
     | 
| 
      
 318 
     | 
    
         
            +
                  def prepare_parametrized_sql
         
     | 
| 
      
 319 
     | 
    
         
            +
                    @parametrized_sql = @initial_sql.split(/#{SQL_COMMENTS}|#{string_regex}/)
         
     | 
| 
      
 320 
     | 
    
         
            +
                      .each_slice(2).map do |sql_part, comment_or_string|
         
     | 
| 
      
 321 
     | 
    
         
            +
                      # remove additional formatting for sql_parts and replace comment and strings with a guids
         
     | 
| 
      
 322 
     | 
    
         
            +
                      [sql_part.gsub(/[\s]+/, " "), add_string_or_comment(comment_or_string)]
         
     | 
| 
      
 323 
     | 
    
         
            +
                    end.flatten.compact.join("")
         
     | 
| 
      
 324 
     | 
    
         
            +
                  end
         
     | 
| 
       152 
325 
     | 
    
         | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
      
 326 
     | 
    
         
            +
                  def query_split_regex(with_brackets = true)
         
     | 
| 
      
 327 
     | 
    
         
            +
                    if with_brackets
         
     | 
| 
      
 328 
     | 
    
         
            +
                      /(#{KEYWORDS}|#{BRACKETS}|#{literal_and_comments_placeholders_regex})/
         
     | 
| 
      
 329 
     | 
    
         
            +
                    else
         
     | 
| 
      
 330 
     | 
    
         
            +
                      /(#{KEYWORDS}|#{literal_and_comments_placeholders_regex})/
         
     | 
| 
       155 
331 
     | 
    
         
             
                    end
         
     | 
| 
      
 332 
     | 
    
         
            +
                  end
         
     | 
| 
       156 
333 
     | 
    
         | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
      
 334 
     | 
    
         
            +
                  # when comment ending with newline followed by a keyword we should remove double newlines
         
     | 
| 
      
 335 
     | 
    
         
            +
                  def clear_extra_newline_after_comments
         
     | 
| 
      
 336 
     | 
    
         
            +
                    newlined_comments = @literals_and_comments_types.select { |k,| new_line_ending_comment?(k) }
         
     | 
| 
      
 337 
     | 
    
         
            +
                    parametrized_sql.gsub!(/(#{newlined_comments.keys.join("}\n|")}}\n)/, &:chop)
         
     | 
| 
       159 
338 
     | 
    
         
             
                  end
         
     | 
| 
       160 
339 
     | 
    
         | 
| 
       161 
     | 
    
         
            -
                  def  
     | 
| 
       162 
     | 
    
         
            -
                     
     | 
| 
       163 
     | 
    
         
            -
                       
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
                       
     | 
| 
       169 
     | 
    
         
            -
                     
     | 
| 
      
 340 
     | 
    
         
            +
                  def colorize_query
         
     | 
| 
      
 341 
     | 
    
         
            +
                    parametrized_sql.gsub!(query_split_regex(false)) do |matched_part|
         
     | 
| 
      
 342 
     | 
    
         
            +
                      if literals_and_comments_types[matched_part]
         
     | 
| 
      
 343 
     | 
    
         
            +
                        colorize_comment_or_literal(matched_part)
         
     | 
| 
      
 344 
     | 
    
         
            +
                        matched_part
         
     | 
| 
      
 345 
     | 
    
         
            +
                      else
         
     | 
| 
      
 346 
     | 
    
         
            +
                        StringColorize.colorize_keyword(matched_part)
         
     | 
| 
      
 347 
     | 
    
         
            +
                      end
         
     | 
| 
      
 348 
     | 
    
         
            +
                    end
         
     | 
| 
       170 
349 
     | 
    
         
             
                  end
         
     | 
| 
       171 
350 
     | 
    
         | 
| 
       172 
     | 
    
         
            -
                   
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
                     
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
      
 351 
     | 
    
         
            +
                  def indent_parametrized_part(matched_typed_id, indent, indent_after_comment, start_with_newline = true)
         
     | 
| 
      
 352 
     | 
    
         
            +
                    case @literals_and_comments_types[matched_typed_id]
         
     | 
| 
      
 353 
     | 
    
         
            +
                    # technically we will not get here, since this types of literals/comments are not indentable
         
     | 
| 
      
 354 
     | 
    
         
            +
                    when :inline_comment, :immutable_string
         
     | 
| 
      
 355 
     | 
    
         
            +
                    when :indentable_string
         
     | 
| 
      
 356 
     | 
    
         
            +
                      lines = @guids_to_content[matched_typed_id].lines
         
     | 
| 
      
 357 
     | 
    
         
            +
                      @guids_to_content[matched_typed_id] = lines[0] +
         
     | 
| 
      
 358 
     | 
    
         
            +
                        lines[1..-1].map! { |ln| indent_multiline(ln[/'[^']+'/], indent) }.join("\n")
         
     | 
| 
       176 
359 
     | 
    
         
             
                    else
         
     | 
| 
       177 
     | 
    
         
            -
                       
     | 
| 
      
 360 
     | 
    
         
            +
                      content = @guids_to_content[matched_typed_id][COMMENT_CONTENT]
         
     | 
| 
      
 361 
     | 
    
         
            +
                      @guids_to_content[matched_typed_id] = (start_with_newline ? "\n" : "") +
         
     | 
| 
      
 362 
     | 
    
         
            +
                        "#{indent_multiline(content, indent)}\n" +
         
     | 
| 
      
 363 
     | 
    
         
            +
                        (indent_after_comment ? indent_multiline("", indent) : "")
         
     | 
| 
       178 
364 
     | 
    
         
             
                    end
         
     | 
| 
       179 
365 
     | 
    
         
             
                  end
         
     | 
| 
       180 
366 
     | 
    
         | 
| 
       181 
     | 
    
         
            -
                  def  
     | 
| 
       182 
     | 
    
         
            -
                     
     | 
| 
       183 
     | 
    
         
            -
                       
     | 
| 
      
 367 
     | 
    
         
            +
                  def colorize_comment_or_literal(matched_typed_id)
         
     | 
| 
      
 368 
     | 
    
         
            +
                    @guids_to_content[matched_typed_id] = if comment?(@literals_and_comments_types[matched_typed_id])
         
     | 
| 
      
 369 
     | 
    
         
            +
                      StringColorize.colorize_comment(@guids_to_content[matched_typed_id])
         
     | 
| 
      
 370 
     | 
    
         
            +
                    else
         
     | 
| 
      
 371 
     | 
    
         
            +
                      StringColorize.colorize_str(@guids_to_content[matched_typed_id])
         
     | 
| 
      
 372 
     | 
    
         
            +
                    end
         
     | 
| 
       184 
373 
     | 
    
         
             
                  end
         
     | 
| 
       185 
374 
     | 
    
         | 
| 
       186 
     | 
    
         
            -
                  def  
     | 
| 
       187 
     | 
    
         
            -
                     
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
     | 
    
         
            -
                     
     | 
| 
      
 375 
     | 
    
         
            +
                  def get_placeholder_type(comment_or_string)
         
     | 
| 
      
 376 
     | 
    
         
            +
                    if SQL_COMMENTS.match?(comment_or_string)
         
     | 
| 
      
 377 
     | 
    
         
            +
                      get_comment_type(comment_or_string)
         
     | 
| 
      
 378 
     | 
    
         
            +
                    else
         
     | 
| 
      
 379 
     | 
    
         
            +
                      get_string_type(comment_or_string)
         
     | 
| 
      
 380 
     | 
    
         
            +
                    end
         
     | 
| 
      
 381 
     | 
    
         
            +
                  end
         
     | 
| 
       190 
382 
     | 
    
         | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
                     
     | 
| 
       193 
     | 
    
         
            -
                     
     | 
| 
      
 383 
     | 
    
         
            +
                  def get_comment_type(comment)
         
     | 
| 
      
 384 
     | 
    
         
            +
                    case comment
         
     | 
| 
      
 385 
     | 
    
         
            +
                    when /\s*\n+\s*.+\s*\n+\s*/ then :newline_wrapped_comment
         
     | 
| 
      
 386 
     | 
    
         
            +
                    when /\s*\n+\s*.+/ then :newline_start_comment
         
     | 
| 
      
 387 
     | 
    
         
            +
                    when /.+\s*\n+\s*/ then :newline_end_comment
         
     | 
| 
      
 388 
     | 
    
         
            +
                    else :inline_comment
         
     | 
| 
      
 389 
     | 
    
         
            +
                    end
         
     | 
| 
      
 390 
     | 
    
         
            +
                  end
         
     | 
| 
       194 
391 
     | 
    
         | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
       196 
     | 
    
         
            -
                     
     | 
| 
       197 
     | 
    
         
            -
             
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
      
 392 
     | 
    
         
            +
                  def get_string_type(string)
         
     | 
| 
      
 393 
     | 
    
         
            +
                    MULTILINE_INDENTABLE_LITERAL.match?(string) ? :indentable_string : :immutable_string
         
     | 
| 
      
 394 
     | 
    
         
            +
                  end
         
     | 
| 
      
 395 
     | 
    
         
            +
             
     | 
| 
      
 396 
     | 
    
         
            +
                  def new_placeholder_name(placeholder_type)
         
     | 
| 
      
 397 
     | 
    
         
            +
                    "#{placeholder_type}_#{@counter[placeholder_type]}_#{SecureRandom.uuid}"
         
     | 
| 
      
 398 
     | 
    
         
            +
                  end
         
     | 
| 
      
 399 
     | 
    
         
            +
             
     | 
| 
      
 400 
     | 
    
         
            +
                  def get_sql_named_strs(sql)
         
     | 
| 
      
 401 
     | 
    
         
            +
                    freq = Hash.new(0)
         
     | 
| 
      
 402 
     | 
    
         
            +
                    sql.scan(NAMED_DOLLAR_QUOTED_STRINGS_REGEX).select do |str|
         
     | 
| 
      
 403 
     | 
    
         
            +
                      freq[str] += 1
         
     | 
| 
      
 404 
     | 
    
         
            +
                      freq[str] == 2
         
     | 
| 
       200 
405 
     | 
    
         
             
                    end
         
     | 
| 
      
 406 
     | 
    
         
            +
                      .flatten
         
     | 
| 
      
 407 
     | 
    
         
            +
                      .map { |str| str.gsub!("$", '\$') }
         
     | 
| 
      
 408 
     | 
    
         
            +
                  end
         
     | 
| 
       201 
409 
     | 
    
         | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
       203 
     | 
    
         
            -
                     
     | 
| 
       204 
     | 
    
         
            -
                     
     | 
| 
       205 
     | 
    
         
            -
                     
     | 
| 
       206 
     | 
    
         
            -
                     
     | 
| 
      
 410 
     | 
    
         
            +
                  def init_strings_regex
         
     | 
| 
      
 411 
     | 
    
         
            +
                    # /($STR$.+$STR$|$$[^$]$$|'[^']'|"[^"]")/
         
     | 
| 
      
 412 
     | 
    
         
            +
                    strs = get_sql_named_strs(initial_sql).map { |dq_str| "#{dq_str}.+#{dq_str}" }
         
     | 
| 
      
 413 
     | 
    
         
            +
                    strs = ["(#{strs.join("|")})"] if strs != []
         
     | 
| 
      
 414 
     | 
    
         
            +
                    @string_regex ||= /#{[*strs, DOLLAR_QUOTED_STRINGS, STRINGS].join("|")}/m
         
     | 
| 
      
 415 
     | 
    
         
            +
                  end
         
     | 
| 
      
 416 
     | 
    
         
            +
             
     | 
| 
      
 417 
     | 
    
         
            +
                  def comment?(piece_type)
         
     | 
| 
      
 418 
     | 
    
         
            +
                    !literal?(piece_type)
         
     | 
| 
      
 419 
     | 
    
         
            +
                  end
         
     | 
| 
      
 420 
     | 
    
         
            +
             
     | 
| 
      
 421 
     | 
    
         
            +
                  def literal?(piece_type)
         
     | 
| 
      
 422 
     | 
    
         
            +
                    [:indentable_string, :immutable_string].include?(piece_type)
         
     | 
| 
      
 423 
     | 
    
         
            +
                  end
         
     | 
| 
      
 424 
     | 
    
         
            +
             
     | 
| 
      
 425 
     | 
    
         
            +
                  def new_line_ending_comment?(comment_or_literal)
         
     | 
| 
      
 426 
     | 
    
         
            +
                    [:newline_wrapped_comment, :newline_end_comment, :newline_start_comment]
         
     | 
| 
      
 427 
     | 
    
         
            +
                      .include?(@literals_and_comments_types[comment_or_literal])
         
     | 
| 
      
 428 
     | 
    
         
            +
                  end
         
     | 
| 
      
 429 
     | 
    
         
            +
             
     | 
| 
      
 430 
     | 
    
         
            +
                  def indent_multiline(keyword, indent)
         
     | 
| 
      
 431 
     | 
    
         
            +
                    if keyword.match?(/.\s*\n\s*./)
         
     | 
| 
      
 432 
     | 
    
         
            +
                      keyword.lines.map! { |ln| " " * indent + ln }.join("")
         
     | 
| 
      
 433 
     | 
    
         
            +
                    else
         
     | 
| 
      
 434 
     | 
    
         
            +
                      " " * indent + keyword
         
     | 
| 
      
 435 
     | 
    
         
            +
                    end
         
     | 
| 
       207 
436 
     | 
    
         
             
                  end
         
     | 
| 
       208 
437 
     | 
    
         
             
                end
         
     | 
| 
       209 
438 
     | 
    
         
             
              end
         
     | 
| 
         @@ -217,8 +446,11 @@ module Niceql 
     | 
|
| 
       217 
446 
     | 
    
         
             
                end
         
     | 
| 
       218 
447 
     | 
    
         
             
              end
         
     | 
| 
       219 
448 
     | 
    
         | 
| 
       220 
     | 
    
         
            -
              def self.configure 
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
       222 
     | 
    
         
            -
               
     | 
| 
      
 449 
     | 
    
         
            +
              def self.configure
         
     | 
| 
      
 450 
     | 
    
         
            +
                yield(config)
         
     | 
| 
      
 451 
     | 
    
         
            +
              end
         
     | 
| 
       223 
452 
     | 
    
         | 
| 
      
 453 
     | 
    
         
            +
              def self.config
         
     | 
| 
      
 454 
     | 
    
         
            +
                @config ||= NiceQLConfig.new
         
     | 
| 
      
 455 
     | 
    
         
            +
              end
         
     | 
| 
       224 
456 
     | 
    
         
             
            end
         
     | 
    
        data/niceql.gemspec
    CHANGED
    
    | 
         @@ -1,4 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # coding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
       2 
4 
     | 
    
         
             
            lib = File.expand_path("../lib", __FILE__)
         
     | 
| 
       3 
5 
     | 
    
         
             
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         
     | 
| 
       4 
6 
     | 
    
         
             
            require "niceql/version"
         
     | 
| 
         @@ -9,8 +11,12 @@ Gem::Specification.new do |spec| 
     | 
|
| 
       9 
11 
     | 
    
         
             
              spec.authors       = ["alekseyl"]
         
     | 
| 
       10 
12 
     | 
    
         
             
              spec.email         = ["leshchuk@gmail.com"]
         
     | 
| 
       11 
13 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
              spec.summary       =  
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
      
 14 
     | 
    
         
            +
              spec.summary       = "This is a simple and nice gem for SQL prettifying and formatting. "\
         
     | 
| 
      
 15 
     | 
    
         
            +
                "Niceql splits, indent and colorize SQL query and PG errors if any. "
         
     | 
| 
      
 16 
     | 
    
         
            +
              spec.description   = "This is a simple and nice gem for SQL prettifying and formatting. "\
         
     | 
| 
      
 17 
     | 
    
         
            +
                "Niceql splits, indent and colorize SQL query and PG errors if any. "\
         
     | 
| 
      
 18 
     | 
    
         
            +
                "Could be used as a standalone gem without any dependencies. "\
         
     | 
| 
      
 19 
     | 
    
         
            +
                "Seamless ActiveRecord integration via rails_sql_prettifier gem. "
         
     | 
| 
       14 
20 
     | 
    
         
             
              spec.homepage      = "https://github.com/alekseyl/niceql"
         
     | 
| 
       15 
21 
     | 
    
         
             
              spec.license       = "MIT"
         
     | 
| 
       16 
22 
     | 
    
         | 
| 
         @@ -23,21 +29,23 @@ Gem::Specification.new do |spec| 
     | 
|
| 
       23 
29 
     | 
    
         
             
                  "public gem pushes."
         
     | 
| 
       24 
30 
     | 
    
         
             
              end
         
     | 
| 
       25 
31 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
              spec.files 
     | 
| 
      
 32 
     | 
    
         
            +
              spec.files = %x(git ls-files -z).split("\x0").reject do |f|
         
     | 
| 
       27 
33 
     | 
    
         
             
                f.match(%r{^(test|spec|features)/})
         
     | 
| 
       28 
34 
     | 
    
         
             
              end
         
     | 
| 
       29 
35 
     | 
    
         
             
              spec.bindir        = "exe"
         
     | 
| 
       30 
36 
     | 
    
         
             
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         
     | 
| 
       31 
37 
     | 
    
         
             
              spec.require_paths = ["lib"]
         
     | 
| 
       32 
38 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
              spec.required_ruby_version =  
     | 
| 
      
 39 
     | 
    
         
            +
              spec.required_ruby_version = ">= 2.4"
         
     | 
| 
       34 
40 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
              spec.add_development_dependency 
     | 
| 
       36 
     | 
    
         
            -
              spec.add_development_dependency 
     | 
| 
       37 
     | 
    
         
            -
              spec.add_development_dependency 
     | 
| 
      
 41 
     | 
    
         
            +
              spec.add_development_dependency("awesome_print")
         
     | 
| 
      
 42 
     | 
    
         
            +
              spec.add_development_dependency("bundler", ">= 1")
         
     | 
| 
      
 43 
     | 
    
         
            +
              spec.add_development_dependency("minitest", "~> 5.0")
         
     | 
| 
      
 44 
     | 
    
         
            +
              spec.add_development_dependency("rake", ">= 12.3.3")
         
     | 
| 
      
 45 
     | 
    
         
            +
              spec.add_development_dependency("rubocop-shopify", "~> 2.0.0")
         
     | 
| 
       38 
46 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
              spec.add_development_dependency 
     | 
| 
       40 
     | 
    
         
            -
              spec.add_development_dependency 
     | 
| 
       41 
     | 
    
         
            -
              spec.add_development_dependency 
     | 
| 
       42 
     | 
    
         
            -
              spec.add_development_dependency 
     | 
| 
      
 47 
     | 
    
         
            +
              spec.add_development_dependency("benchmark-ips")
         
     | 
| 
      
 48 
     | 
    
         
            +
              spec.add_development_dependency("differ")
         
     | 
| 
      
 49 
     | 
    
         
            +
              spec.add_development_dependency("pry-byebug")
         
     | 
| 
      
 50 
     | 
    
         
            +
              spec.add_development_dependency("sqlite3")
         
     | 
| 
       43 
51 
     | 
    
         
             
            end
         
     |