niceql 0.1.25 → 0.4.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/CHANGELOG.md +22 -0
- data/README.md +20 -15
- data/lib/niceql/version.rb +1 -1
- data/lib/niceql.rb +182 -168
- data/niceql.gemspec +7 -4
- metadata +44 -17
- data/lib/niceql/string.rb +0 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2056d114407ed81b47224f1bc0f60d2e65bb88118667f074fd972149203bd6ea
         | 
| 4 | 
            +
              data.tar.gz: 48c228ee2240a0fd8beec6ecc1c312b42197a8a259bf1d5b438e41fd55c51680
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 070a9574f50f434136474dfc1b671956b8df3529434f2e13f36e4b4c952a1dbc23da5a9e81a5d8eba082154c523c6056476b25396ec52654dcbe0436ae04c18e
         | 
| 7 | 
            +
              data.tar.gz: e8b550669250d612233b7fdbced172d12cd6d348dd8bfda21ff6ff8dda0358c6cf59e23aa917bbade0f49286017173a10099488a830d1e0802efd71faa98b35a
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,25 @@ | |
| 1 | 
            +
            # 0.4.0
         | 
| 2 | 
            +
            * merged PR https://github.com/alekseyl/niceql/pull/19, now Arel is also extended with niceql methods!!
         | 
| 3 | 
            +
            * test and better niceql comparisons assertion
         | 
| 4 | 
            +
            * tests were trialed against rails 4.2 and some additional conditions were added for later cases
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            # 0.3.0 
         | 
| 7 | 
            +
            * ruby forced to >= 2.4
         | 
| 8 | 
            +
            * String match extension no longer needed 
         | 
| 9 | 
            +
            * fixed issue with missing HINT and DETAIL string ( https://github.com/alekseyl/niceql/issues/18 )
         | 
| 10 | 
            +
            * both new and old activerecord StatementInvalid formats supported
         | 
| 11 | 
            +
            * major prettify_pg_err refactoring ( much cleaner code now )
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            # 0.2.0
         | 
| 14 | 
            +
            * Fix to issue https://github.com/alekseyl/niceql/pull/17#issuecomment-924278172. ActiveRecord base config is no longer a hash, 
         | 
| 15 | 
            +
            so it does not have dig method, hence it's breaking the ar_using_pg_adapter? method. 
         | 
| 16 | 
            +
            * active_record added as development dependency :( for proper testing cover. 
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            # 0.1.30
         | 
| 19 | 
            +
            * ActiveRecord pg check for config now will try both connection_db_config and connection_config for adapter verification 
         | 
| 20 | 
            +
            * prettify_pg_errors will not be set to true if ActiveRecord adapter is not using pg, i.e. ar_using_pg_adapter? is false. 
         | 
| 21 | 
            +
            * rake dev dependency bumped according to security issues
         | 
| 22 | 
            +
             | 
| 1 23 | 
             
            # 0.1.24/25
         | 
| 2 24 |  | 
| 3 25 | 
             
            * No features, just strict ruby dependency for >= 2.3,
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,10 +1,13 @@ | |
| 1 1 | 
             
            # Niceql
         | 
| 2 2 |  | 
| 3 | 
            -
            This is a small, nice, simple and  | 
| 3 | 
            +
            This is a small, nice, simple and zero dependency solution for SQL prettifying for Ruby. 
         | 
| 4 4 | 
             
            It can be used in an irb console without any dependencies ( run bin/console and look for examples ).
         | 
| 5 5 |  | 
| 6 | 
            -
            Any reasonable suggestions  | 
| 6 | 
            +
            Any reasonable suggestions are welcome. 
         | 
| 7 7 |  | 
| 8 | 
            +
            **Please pay attention: untill issue https://github.com/alekseyl/niceql/issues/16 is resolved any UPDATE or INSERT request might corrupt your data, don't use on production!**
         | 
| 9 | 
            +
             | 
| 10 | 
            +
             
         | 
| 8 11 | 
             
            ## Before/After 
         | 
| 9 12 | 
             
            ### SQL prettifier: 
         | 
| 10 13 | 
             
            
         | 
| @@ -41,9 +44,11 @@ Or install it yourself as: | |
| 41 44 | 
             
            ```ruby
         | 
| 42 45 | 
             
            Niceql.configure do |c|
         | 
| 43 46 | 
             
              # Setting pg_adapter_with_nicesql to true will force formatting SQL queries
         | 
| 44 | 
            -
              # before  | 
| 47 | 
            +
              # before execution. Formatted SQL will lead to much better SQL-query debugging and much more clearer error messages 
         | 
| 45 48 | 
             
              # if you are using Postgresql as a data source.  
         | 
| 46 | 
            -
              #  | 
| 49 | 
            +
              # 
         | 
| 50 | 
            +
              # You can adjust pg_adapter in production but do it at your own risk!
         | 
| 51 | 
            +
              # 
         | 
| 47 52 | 
             
              # If you need to debug SQL queries in production use exec_niceql
         | 
| 48 53 | 
             
              # default: false
         | 
| 49 54 | 
             
              # uncomment next string to enable in development
         | 
| @@ -53,7 +58,7 @@ Niceql.configure do |c| | |
| 53 58 | 
             
              # default: false
         | 
| 54 59 | 
             
              # c.prettify_active_record_log_output = true
         | 
| 55 60 |  | 
| 56 | 
            -
              #  | 
| 61 | 
            +
              # Error prettifying is also configurable
         | 
| 57 62 | 
             
              # default: defined? ::ActiveRecord::Base && ActiveRecord::Base.configurations[Rails.env]['adapter'] == 'postgresql'
         | 
| 58 63 | 
             
              # c.prettify_pg_errors = defined? ::ActiveRecord::Base && ActiveRecord::Base.configurations[Rails.env]['adapter'] == 'postgresql'
         | 
| 59 64 |  | 
| @@ -82,7 +87,7 @@ end | |
| 82 87 | 
             
            ### With ActiveRecord
         | 
| 83 88 |  | 
| 84 89 | 
             
            ```ruby
         | 
| 85 | 
            -
              # puts colorized  | 
| 90 | 
            +
              # puts colorized and formatted corresponding SQL query
         | 
| 86 91 | 
             
              Model.scope.niceql
         | 
| 87 92 |  | 
| 88 93 | 
             
              # only formatting without colorization, you can run output of to_niceql as a SQL query in connection.execute  
         | 
| @@ -107,23 +112,23 @@ end | |
| 107 112 | 
             
                #=>
         | 
| 108 113 | 
             
                #=>  SELECT * 
         | 
| 109 114 | 
             
                #=>  FROM table
         | 
| 110 | 
            -
             | 
| 111 | 
            -
               
         | 
| 112 | 
            -
             | 
| 115 | 
            +
                
         | 
| 113 116 |  | 
| 114 | 
            -
                | 
| 115 | 
            -
               puts Niceql::Prettifier.prettify_pg_err( "#{pg_err_output}\n#{sql_query}" )
         | 
| 117 | 
            +
               puts Niceql::Prettifier.prettify_pg_err( pg_err_output, sql_query )
         | 
| 116 118 |  | 
| 117 119 | 
             
               # to get real nice result you should execute prettified version (i.e. execute( prettified_sql ) !) of query on your DB! 
         | 
| 118 120 | 
             
               # otherwise you will not get such a nice output
         | 
| 119 | 
            -
                 | 
| 121 | 
            +
                raw_sql = <<~SQL
         | 
| 122 | 
            +
                 SELECT err 
         | 
| 123 | 
            +
                 FROM ( VALUES(1), (2) )
         | 
| 124 | 
            +
                 ORDER BY 1
         | 
| 125 | 
            +
                SQL
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                puts Niceql::Prettifier.prettify_pg_err(<<~ERR, raw_sql )
         | 
| 120 128 | 
             
                    ERROR:  VALUES in FROM must have an alias
         | 
| 121 129 | 
             
                    LINE 2:  FROM ( VALUES(1), (2) )
         | 
| 122 130 | 
             
                                  ^
         | 
| 123 131 | 
             
                    HINT:  For example, FROM (VALUES ...) [AS] foo.
         | 
| 124 | 
            -
                     SELECT err 
         | 
| 125 | 
            -
                     FROM ( VALUES(1), (2) )
         | 
| 126 | 
            -
                     ORDER BY 1
         | 
| 127 132 | 
             
                ERR
         | 
| 128 133 |  | 
| 129 134 |  | 
    
        data/lib/niceql/version.rb
    CHANGED
    
    
    
        data/lib/niceql.rb
    CHANGED
    
    | @@ -1,19 +1,18 @@ | |
| 1 1 | 
             
            require "niceql/version"
         | 
| 2 | 
            -
            require 'niceql/string'
         | 
| 3 2 |  | 
| 4 3 | 
             
            module Niceql
         | 
| 5 4 |  | 
| 6 5 | 
             
              module StringColorize
         | 
| 7 6 | 
             
                def self.colorize_verb( str)
         | 
| 8 | 
            -
                  #yellow ANSI color
         | 
| 7 | 
            +
                  # yellow ANSI color
         | 
| 9 8 | 
             
                  "\e[0;33;49m#{str}\e[0m"
         | 
| 10 9 | 
             
                end
         | 
| 11 10 | 
             
                def self.colorize_str(str)
         | 
| 12 | 
            -
                  #cyan ANSI color
         | 
| 11 | 
            +
                  # cyan ANSI color
         | 
| 13 12 | 
             
                  "\e[0;36;49m#{str}\e[0m"
         | 
| 14 13 | 
             
                end
         | 
| 15 14 | 
             
                def self.colorize_err(err)
         | 
| 16 | 
            -
                  #red ANSI color
         | 
| 15 | 
            +
                  # red ANSI color
         | 
| 17 16 | 
             
                  "\e[0;31;49m#{err}\e[0m"
         | 
| 18 17 | 
             
                end
         | 
| 19 18 | 
             
              end
         | 
| @@ -45,168 +44,182 @@ module Niceql | |
| 45 44 | 
             
                SQL_COMMENTS_CLEARED = /(\s*?--.+\s{1})|(\s*$\s*\/\*[^\/\*]*\*\/\s{1})/
         | 
| 46 45 | 
             
                COMMENT_CONTENT = /[\S]+[\s\S]*[\S]+/
         | 
| 47 46 |  | 
| 48 | 
            -
                 | 
| 49 | 
            -
                   | 
| 50 | 
            -
             | 
| 47 | 
            +
                class << self
         | 
| 48 | 
            +
                  def config
         | 
| 49 | 
            +
                    Niceql.config
         | 
| 50 | 
            +
                  end
         | 
| 51 51 |  | 
| 52 | 
            +
                  def prettify_err(err, original_sql_query = nil)
         | 
| 53 | 
            +
                    prettify_pg_err( err.to_s, original_sql_query )
         | 
| 54 | 
            +
                  end
         | 
| 52 55 |  | 
| 53 | 
            -
                def self.prettify_err(err)
         | 
| 54 | 
            -
                  prettify_pg_err( err.to_s )
         | 
| 55 | 
            -
                end
         | 
| 56 56 |  | 
| 57 | 
            +
                  # Postgres error output:
         | 
| 58 | 
            +
                  # ERROR:  VALUES in FROM must have an alias
         | 
| 59 | 
            +
                  # LINE 2: FROM ( VALUES(1), (2) );
         | 
| 60 | 
            +
                  #              ^
         | 
| 61 | 
            +
                  # HINT:  For example, FROM (VALUES ...) [AS] foo.
         | 
| 57 62 |  | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
                # HINT:  For example, FROM (VALUES ...) [AS] foo.
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                # May go without HINT or DETAIL:
         | 
| 65 | 
            -
                # ERROR:  column "usr" does not exist
         | 
| 66 | 
            -
                # LINE 1: SELECT usr FROM users ORDER BY 1
         | 
| 67 | 
            -
                #                ^
         | 
| 68 | 
            -
             | 
| 69 | 
            -
                # ActiveRecord::StatementInvalid will add original SQL query to the bottom like this:
         | 
| 70 | 
            -
                # ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column "usr" does not exist
         | 
| 71 | 
            -
                # LINE 1: SELECT usr FROM users ORDER BY 1
         | 
| 72 | 
            -
                #                ^
         | 
| 73 | 
            -
                #: SELECT usr FROM users ORDER BY 1
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                # prettify_pg_err parses ActiveRecord::StatementInvalid string,
         | 
| 76 | 
            -
                # but you may use it without ActiveRecord either way:
         | 
| 77 | 
            -
                # prettify_pg_err( err + "\n" + sql ) OR prettify_pg_err( err, sql )
         | 
| 78 | 
            -
                # don't mess with original sql query, or prettify_pg_err will deliver incorrect results
         | 
| 79 | 
            -
                def self.prettify_pg_err(err, original_sql_query = nil)
         | 
| 80 | 
            -
                  return err if err[/LINE \d+/].nil?
         | 
| 81 | 
            -
                  err_line_num = err[/LINE \d+/][5..-1].to_i
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                  #
         | 
| 84 | 
            -
                  start_sql_line = err.lines[3][/(HINT|DETAIL)/] ? 4 : 3
         | 
| 85 | 
            -
                  err_body = start_sql_line < err.lines.length ? err.lines[start_sql_line..-1] : original_sql_query&.lines
         | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
                  # this means original query is missing so it's nothing to prettify
         | 
| 89 | 
            -
                  return err unless err_body
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                  err_quote = ( err.lines[1][/\.\.\..+\.\.\./] && err.lines[1][/\.\.\..+\.\.\./][3..-4] ) ||
         | 
| 92 | 
            -
                      ( err.lines[1][/\.\.\..+/] && err.lines[1][/\.\.\..+/][3..-1] )
         | 
| 93 | 
            -
             | 
| 94 | 
            -
                  # line[2] is err carret line i.e.: '      ^'
         | 
| 95 | 
            -
                  # err.lines[1][/LINE \d+:/].length+1..-1 - is a position from error quote begin
         | 
| 96 | 
            -
                  err_carret_line = err.lines[2][err.lines[1][/LINE \d+:/].length+1..-1]
         | 
| 97 | 
            -
                  # err line will be painted in red completely, so we just remembering it and use
         | 
| 98 | 
            -
                  # to replace after paiting the verbs
         | 
| 99 | 
            -
                  err_line = err_body[err_line_num-1]
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                  # when err line is too long postgres quotes it part in double '...'
         | 
| 102 | 
            -
                  if err_quote
         | 
| 103 | 
            -
                    err_quote_carret_offset = err_carret_line.length - err.lines[1].index( '...' ) + 3
         | 
| 104 | 
            -
                    err_carret_line =  ' ' * ( err_line.index( err_quote ) + err_quote_carret_offset ) + "^\n"
         | 
| 105 | 
            -
                  end
         | 
| 63 | 
            +
                  # May go without HINT or DETAIL:
         | 
| 64 | 
            +
                  # ERROR:  column "usr" does not exist
         | 
| 65 | 
            +
                  # LINE 1: SELECT usr FROM users ORDER BY 1
         | 
| 66 | 
            +
                  #                ^
         | 
| 106 67 |  | 
| 107 | 
            -
                   | 
| 108 | 
            -
                  #  | 
| 109 | 
            -
                   | 
| 68 | 
            +
                  # ActiveRecord::StatementInvalid will add original SQL query to the bottom like this:
         | 
| 69 | 
            +
                  # ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column "usr" does not exist
         | 
| 70 | 
            +
                  # LINE 1: SELECT usr FROM users ORDER BY 1
         | 
| 71 | 
            +
                  #                ^
         | 
| 72 | 
            +
                  #: SELECT usr FROM users ORDER BY 1
         | 
| 110 73 |  | 
| 111 | 
            -
                  # | 
| 112 | 
            -
                   | 
| 113 | 
            -
             | 
| 74 | 
            +
                  # prettify_pg_err parses ActiveRecord::StatementInvalid string,
         | 
| 75 | 
            +
                  # but you may use it without ActiveRecord either way:
         | 
| 76 | 
            +
                  # prettify_pg_err( err + "\n" + sql ) OR prettify_pg_err( err, sql )
         | 
| 77 | 
            +
                  # don't mess with original sql query, or prettify_pg_err will deliver incorrect results
         | 
| 78 | 
            +
                  def prettify_pg_err(err, original_sql_query = nil)
         | 
| 79 | 
            +
                    return err if err[/LINE \d+/].nil?
         | 
| 80 | 
            +
                    err_line_num = err[/LINE \d+/][5..-1].to_i
         | 
| 81 | 
            +
                    # LINE 1: SELECT usr FROM users ORDER BY 1
         | 
| 82 | 
            +
                    err_address_line = err.lines[1]
         | 
| 114 83 |  | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 84 | 
            +
                    start_sql_line = 3 if err.lines.length <= 3
         | 
| 85 | 
            +
                    # error not always contains HINT
         | 
| 86 | 
            +
                    start_sql_line ||= err.lines[3][/(HINT|DETAIL)/] ? 4 : 3
         | 
| 87 | 
            +
                    sql_body = start_sql_line < err.lines.length ? err.lines[start_sql_line..-1] : original_sql_query&.lines
         | 
| 119 88 |  | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 89 | 
            +
                    # this means original query is missing so it's nothing to prettify
         | 
| 90 | 
            +
                    return err unless sql_body
         | 
| 122 91 |  | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 126 | 
            -
             | 
| 127 | 
            -
                  sql = sql.split( SQL_COMMENTS ).each_slice(2).map{ | sql_part, comment |
         | 
| 128 | 
            -
                    # remove additional formatting for sql_parts but leave comment intact
         | 
| 129 | 
            -
                    [sql_part.gsub(/[\s]+/, ' '),
         | 
| 130 | 
            -
                     # comment.match?(/\A\s*$/) - SQL_COMMENTS gets all comment content + all whitespaced chars around
         | 
| 131 | 
            -
                     # so this sql_part.length == 0 || comment.match?(/\A\s*$/) checks does the comment starts from new line
         | 
| 132 | 
            -
                     comment && ( sql_part.length == 0 || comment.match?(/\A\s*$/) ? "\n#{comment[COMMENT_CONTENT]}\n" : comment[COMMENT_CONTENT] ) ]
         | 
| 133 | 
            -
                  }.flatten.join(' ')
         | 
| 134 | 
            -
             | 
| 135 | 
            -
                  sql.gsub!(/ \n/, "\n")
         | 
| 136 | 
            -
             | 
| 137 | 
            -
                  sql.gsub!(STRINGS){ |str| StringColorize.colorize_str(str) } if colorize
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                  first_verb  = true
         | 
| 140 | 
            -
                  prev_was_comment = false
         | 
| 141 | 
            -
             | 
| 142 | 
            -
                  sql.gsub!( /(#{VERBS}|#{BRACKETS}|#{SQL_COMMENTS_CLEARED})/) do |verb|
         | 
| 143 | 
            -
                    if 'SELECT' == verb
         | 
| 144 | 
            -
                      indent += config.indentation_base if !config.open_bracket_is_newliner || parentness.last.nil? || parentness.last[:nested]
         | 
| 145 | 
            -
                      parentness.last[:nested] = true if parentness.last
         | 
| 146 | 
            -
                      add_new_line = !first_verb
         | 
| 147 | 
            -
                    elsif verb == '('
         | 
| 148 | 
            -
                      next_closing_bracket = Regexp.last_match.post_match.index(')')
         | 
| 149 | 
            -
                      # check if brackets contains SELECT statement
         | 
| 150 | 
            -
                      add_new_line = !!Regexp.last_match.post_match[0..next_closing_bracket][/SELECT/] && config.open_bracket_is_newliner
         | 
| 151 | 
            -
                      parentness << { nested: add_new_line }
         | 
| 152 | 
            -
                    elsif verb == ')'
         | 
| 153 | 
            -
                      # this also covers case when right bracket is used without corresponding left one
         | 
| 154 | 
            -
                      add_new_line = parentness.last.nil? || parentness.last[:nested]
         | 
| 155 | 
            -
                      indent -= ( parentness.last.nil? ? 2 * config.indentation_base : (parentness.last[:nested] ? config.indentation_base : 0) )
         | 
| 156 | 
            -
                      indent = 0 if indent < 0
         | 
| 157 | 
            -
                      parentness.pop
         | 
| 158 | 
            -
                    elsif verb[POSSIBLE_INLINER]
         | 
| 159 | 
            -
                      # in postgres ORDER BY can be used in aggregation function this will keep it
         | 
| 160 | 
            -
                      # inline with its agg function
         | 
| 161 | 
            -
                      add_new_line = parentness.last.nil? || parentness.last[:nested]
         | 
| 162 | 
            -
                    else
         | 
| 163 | 
            -
                      add_new_line = verb[/(#{INLINE_VERBS})/].nil?
         | 
| 164 | 
            -
                    end
         | 
| 92 | 
            +
                    # err line will be painted in red completely, so we just remembering it and use
         | 
| 93 | 
            +
                    # to replace after painting the verbs
         | 
| 94 | 
            +
                    err_line = sql_body[err_line_num - 1]
         | 
| 165 95 |  | 
| 166 | 
            -
                    # !add_new_line && previous_was_comment means we had newlined comment, and now even
         | 
| 167 | 
            -
                    # if verb is inline verb we will need to add new line with indentation BUT all
         | 
| 168 | 
            -
                    # inliners match with a space before so we need to strip it
         | 
| 169 | 
            -
                    verb.lstrip! if !add_new_line && prev_was_comment
         | 
| 170 96 |  | 
| 171 | 
            -
                     | 
| 172 | 
            -
                     | 
| 97 | 
            +
                    #colorizing verbs and strings
         | 
| 98 | 
            +
                    colorized_sql_body = sql_body.join.gsub(/#{VERBS}/ ) { |verb| StringColorize.colorize_verb(verb) }
         | 
| 99 | 
            +
                      .gsub(STRINGS){ |str| StringColorize.colorize_str(str) }
         | 
| 173 100 |  | 
| 174 | 
            -
                     | 
| 175 | 
            -
             | 
| 176 | 
            -
             | 
| 177 | 
            -
                     | 
| 178 | 
            -
             | 
| 179 | 
            -
             | 
| 101 | 
            +
                    #reassemling error message
         | 
| 102 | 
            +
                    err_body = colorized_sql_body.lines
         | 
| 103 | 
            +
                    # replacing colorized line contained error and adding caret line
         | 
| 104 | 
            +
                    err_body[err_line_num - 1]= StringColorize.colorize_err( err_line )
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                    err_caret_line = extract_err_caret_line( err_address_line, err_line, sql_body, err )
         | 
| 107 | 
            +
                    err_body.insert( err_line_num, StringColorize.colorize_err( err_caret_line ) )
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                    err.lines[0..start_sql_line-1].join + err_body.join
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  def prettify_sql( sql, colorize = true )
         | 
| 113 | 
            +
                    indent = 0
         | 
| 114 | 
            +
                    parentness = []
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                    sql = sql.split( SQL_COMMENTS ).each_slice(2).map{ | sql_part, comment |
         | 
| 117 | 
            +
                      # remove additional formatting for sql_parts but leave comment intact
         | 
| 118 | 
            +
                      [sql_part.gsub(/[\s]+/, ' '),
         | 
| 119 | 
            +
                       # comment.match?(/\A\s*$/) - SQL_COMMENTS gets all comment content + all whitespaced chars around
         | 
| 120 | 
            +
                       # so this sql_part.length == 0 || comment.match?(/\A\s*$/) checks does the comment starts from new line
         | 
| 121 | 
            +
                       comment && ( sql_part.length == 0 || comment.match?(/\A\s*$/) ? "\n#{comment[COMMENT_CONTENT]}\n" : comment[COMMENT_CONTENT] ) ]
         | 
| 122 | 
            +
                    }.flatten.join(' ')
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                    sql.gsub!(/ \n/, "\n")
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                    sql.gsub!(STRINGS){ |str| StringColorize.colorize_str(str) } if colorize
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                    first_verb  = true
         | 
| 129 | 
            +
                    prev_was_comment = false
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                    sql.gsub!( /(#{VERBS}|#{BRACKETS}|#{SQL_COMMENTS_CLEARED})/) do |verb|
         | 
| 132 | 
            +
                      if 'SELECT' == verb
         | 
| 133 | 
            +
                        indent += config.indentation_base if !config.open_bracket_is_newliner || parentness.last.nil? || parentness.last[:nested]
         | 
| 134 | 
            +
                        parentness.last[:nested] = true if parentness.last
         | 
| 135 | 
            +
                        add_new_line = !first_verb
         | 
| 136 | 
            +
                      elsif verb == '('
         | 
| 137 | 
            +
                        next_closing_bracket = Regexp.last_match.post_match.index(')')
         | 
| 138 | 
            +
                        # check if brackets contains SELECT statement
         | 
| 139 | 
            +
                        add_new_line = !!Regexp.last_match.post_match[0..next_closing_bracket][/SELECT/] && config.open_bracket_is_newliner
         | 
| 140 | 
            +
                        parentness << { nested: add_new_line }
         | 
| 141 | 
            +
                      elsif verb == ')'
         | 
| 142 | 
            +
                        # this also covers case when right bracket is used without corresponding left one
         | 
| 143 | 
            +
                        add_new_line = parentness.last.nil? || parentness.last[:nested]
         | 
| 144 | 
            +
                        indent -= ( parentness.last.nil? ? 2 * config.indentation_base : (parentness.last[:nested] ? config.indentation_base : 0) )
         | 
| 145 | 
            +
                        indent = 0 if indent < 0
         | 
| 146 | 
            +
                        parentness.pop
         | 
| 147 | 
            +
                      elsif verb[POSSIBLE_INLINER]
         | 
| 148 | 
            +
                        # in postgres ORDER BY can be used in aggregation function this will keep it
         | 
| 149 | 
            +
                        # inline with its agg function
         | 
| 150 | 
            +
                        add_new_line = parentness.last.nil? || parentness.last[:nested]
         | 
| 151 | 
            +
                      else
         | 
| 152 | 
            +
                        add_new_line = verb[/(#{INLINE_VERBS})/].nil?
         | 
| 153 | 
            +
                      end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                      # !add_new_line && previous_was_comment means we had newlined comment, and now even
         | 
| 156 | 
            +
                      # if verb is inline verb we will need to add new line with indentation BUT all
         | 
| 157 | 
            +
                      # inliners match with a space before so we need to strip it
         | 
| 158 | 
            +
                      verb.lstrip! if !add_new_line && prev_was_comment
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                      add_new_line = prev_was_comment unless add_new_line
         | 
| 161 | 
            +
                      add_indent = !first_verb && add_new_line
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                      if verb[SQL_COMMENTS_CLEARED]
         | 
| 164 | 
            +
                        verb = verb[COMMENT_CONTENT]
         | 
| 165 | 
            +
                        prev_was_comment = true
         | 
| 166 | 
            +
                      else
         | 
| 167 | 
            +
                        first_verb = false
         | 
| 168 | 
            +
                        prev_was_comment = false
         | 
| 169 | 
            +
                      end
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                      verb = StringColorize.colorize_verb(verb) if !%w[( )].include?(verb) && colorize
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                      subs = ( add_indent ? indent_multiline(verb, indent) : verb)
         | 
| 174 | 
            +
                      !first_verb && add_new_line ? "\n" + subs : subs
         | 
| 180 175 | 
             
                    end
         | 
| 181 176 |  | 
| 182 | 
            -
                     | 
| 177 | 
            +
                    # clear all spaces before newlines, and all whitespaces before strings endings
         | 
| 178 | 
            +
                    sql.tap{ |slf| slf.gsub!( /\s+\n/, "\n" ) }.tap{ |slf| slf.gsub!(/\s+\z/, '') }
         | 
| 179 | 
            +
                  end
         | 
| 183 180 |  | 
| 184 | 
            -
             | 
| 185 | 
            -
                     | 
| 181 | 
            +
                  def prettify_multiple( sql_multi, colorize = true )
         | 
| 182 | 
            +
                    sql_multi.split( /(?>#{SQL_COMMENTS})|(\;)/ ).inject(['']) { |queries, pattern|
         | 
| 183 | 
            +
                      queries.last << pattern
         | 
| 184 | 
            +
                      queries << '' if pattern == ';'
         | 
| 185 | 
            +
                      queries
         | 
| 186 | 
            +
                    }.map!{ |sql|
         | 
| 187 | 
            +
                      # we were splitting by comments and ;, so if next sql start with comment we've got a misplaced \n\n
         | 
| 188 | 
            +
                      sql.match?(/\A\s+\z/) ? nil : prettify_sql( sql, colorize )
         | 
| 189 | 
            +
                    }.compact.join("\n\n")
         | 
| 186 190 | 
             
                  end
         | 
| 187 191 |  | 
| 188 | 
            -
                   | 
| 189 | 
            -
                   | 
| 190 | 
            -
             | 
| 192 | 
            +
                  private_class_method
         | 
| 193 | 
            +
                  def indent_multiline( verb, indent )
         | 
| 194 | 
            +
                    if verb.match?(/.\s*\n\s*./)
         | 
| 195 | 
            +
                      verb.lines.map!{|ln| ln.prepend(' ' * indent)}.join("\n")
         | 
| 196 | 
            +
                    else
         | 
| 197 | 
            +
                      verb.prepend(' ' * indent)
         | 
| 198 | 
            +
                    end
         | 
| 199 | 
            +
                  end
         | 
| 191 200 |  | 
| 192 | 
            -
             | 
| 193 | 
            -
                   | 
| 194 | 
            -
                     | 
| 195 | 
            -
                     | 
| 196 | 
            -
                     | 
| 197 | 
            -
             | 
| 198 | 
            -
                    #  | 
| 199 | 
            -
                     | 
| 200 | 
            -
             | 
| 201 | 
            -
             | 
| 201 | 
            +
                  private_class_method
         | 
| 202 | 
            +
                  def extract_err_caret_line( err_address_line, err_line, sql_body, err )
         | 
| 203 | 
            +
                    # LINE could be quoted ( both sides and sometimes only from one ):
         | 
| 204 | 
            +
                    # "LINE 1: ...t_id\" = $13 AND \"products\".\"carrier_id\" = $14 AND \"product_t...\n",
         | 
| 205 | 
            +
                    err_quote = (err_address_line.match(/\.\.\.(.+)\.\.\./) || err_address_line.match(/\.\.\.(.+)/) ).try(:[], 1)
         | 
| 206 | 
            +
             | 
| 207 | 
            +
                    # line[2] is original err caret line i.e.: '      ^'
         | 
| 208 | 
            +
                    # err_address_line[/LINE \d+:/].length+1..-1 - is a position from error quote begin
         | 
| 209 | 
            +
                    err_caret_line = err.lines[2][err_address_line[/LINE \d+:/].length+1..-1]
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                    # when err line is too long postgres quotes it in double '...'
         | 
| 212 | 
            +
                    # so we need to reposition caret against original line
         | 
| 213 | 
            +
                    if err_quote
         | 
| 214 | 
            +
                      err_quote_caret_offset = err_caret_line.length - err_address_line.index( '...' ).to_i + 3
         | 
| 215 | 
            +
                      err_caret_line =  ' ' * ( err_line.index( err_quote ) + err_quote_caret_offset ) + "^\n"
         | 
| 216 | 
            +
                    end
         | 
| 202 217 |  | 
| 203 | 
            -
             | 
| 204 | 
            -
             | 
| 205 | 
            -
             | 
| 206 | 
            -
             | 
| 207 | 
            -
                     | 
| 208 | 
            -
                  else
         | 
| 209 | 
            -
                    "#{' ' * indent}" + verb.to_s
         | 
| 218 | 
            +
                    # older versions of ActiveRecord were adding ': ' before an original query :(
         | 
| 219 | 
            +
                    err_caret_line.prepend('  ') if sql_body[0].start_with?(': ')
         | 
| 220 | 
            +
                    # if mistake is on last string than err_line.last != \n then we need to prepend \n to caret line
         | 
| 221 | 
            +
                    err_caret_line.prepend("\n") unless err_line[-1] == "\n"
         | 
| 222 | 
            +
                    err_caret_line
         | 
| 210 223 | 
             
                  end
         | 
| 211 224 | 
             
                end
         | 
| 212 225 | 
             
              end
         | 
| @@ -229,15 +242,22 @@ module Niceql | |
| 229 242 |  | 
| 230 243 | 
             
              module ErrorExt
         | 
| 231 244 | 
             
                def to_s
         | 
| 232 | 
            -
                   | 
| 233 | 
            -
             | 
| 234 | 
            -
                   | 
| 235 | 
            -
                    super
         | 
| 236 | 
            -
                  end
         | 
| 245 | 
            +
                  # older rails version do not provide sql as a standalone query, instead they
         | 
| 246 | 
            +
                  # deliver joined message
         | 
| 247 | 
            +
                  Niceql.config.prettify_pg_errors ? Prettifier.prettify_err(super, try(:sql) ) : super
         | 
| 237 248 | 
             
                end
         | 
| 238 249 | 
             
              end
         | 
| 239 250 |  | 
| 240 251 | 
             
              class NiceQLConfig
         | 
| 252 | 
            +
                def ar_using_pg_adapter?
         | 
| 253 | 
            +
                  return false unless defined?(::ActiveRecord::Base)
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                  adapter = ActiveRecord::Base.try(:connection_db_config).try(:adapter) ||
         | 
| 256 | 
            +
                    ActiveRecord::Base.try(:connection_config)&.with_indifferent_access&.dig(:adapter)
         | 
| 257 | 
            +
             | 
| 258 | 
            +
                  adapter == 'postgresql'
         | 
| 259 | 
            +
                end
         | 
| 260 | 
            +
             | 
| 241 261 | 
             
                attr_accessor :pg_adapter_with_nicesql,
         | 
| 242 262 | 
             
                              :indentation_base,
         | 
| 243 263 | 
             
                              :open_bracket_is_newliner,
         | 
| @@ -250,36 +270,30 @@ module Niceql | |
| 250 270 | 
             
                  self.indentation_base = 2
         | 
| 251 271 | 
             
                  self.open_bracket_is_newliner = false
         | 
| 252 272 | 
             
                  self.prettify_active_record_log_output = false
         | 
| 253 | 
            -
                  self.prettify_pg_errors =  | 
| 273 | 
            +
                  self.prettify_pg_errors = ar_using_pg_adapter?
         | 
| 254 274 | 
             
                end
         | 
| 255 275 | 
             
              end
         | 
| 256 276 |  | 
| 257 | 
            -
             | 
| 258 277 | 
             
              def self.configure
         | 
| 259 278 | 
             
                yield( config )
         | 
| 260 279 |  | 
| 261 | 
            -
                 | 
| 262 | 
            -
                  ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.include(PostgresAdapterNiceQL)
         | 
| 263 | 
            -
                end
         | 
| 280 | 
            +
                return unless defined? ::ActiveRecord::Base
         | 
| 264 281 |  | 
| 265 | 
            -
                if config. | 
| 266 | 
            -
                  ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend( AbstractAdapterLogPrettifier )
         | 
| 267 | 
            -
                end
         | 
| 282 | 
            +
                ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.include(PostgresAdapterNiceQL) if config.pg_adapter_with_nicesql
         | 
| 268 283 |  | 
| 269 | 
            -
                if config. | 
| 270 | 
            -
             | 
| 271 | 
            -
                 | 
| 284 | 
            +
                ::ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend( AbstractAdapterLogPrettifier ) if config.prettify_active_record_log_output
         | 
| 285 | 
            +
             | 
| 286 | 
            +
                ::ActiveRecord::StatementInvalid.include( Niceql::ErrorExt ) if config.prettify_pg_errors && config.ar_using_pg_adapter?
         | 
| 272 287 | 
             
              end
         | 
| 273 288 |  | 
| 274 289 | 
             
              def self.config
         | 
| 275 290 | 
             
                @config ||= NiceQLConfig.new
         | 
| 276 291 | 
             
              end
         | 
| 277 292 |  | 
| 278 | 
            -
              if defined? ::ActiveRecord | 
| 279 | 
            -
                ::ActiveRecord:: | 
| 280 | 
            -
             | 
| 293 | 
            +
              if defined? ::ActiveRecord
         | 
| 294 | 
            +
                [::ActiveRecord::Relation,
         | 
| 295 | 
            +
                 ::Arel::TreeManager,
         | 
| 296 | 
            +
                 ::Arel::Nodes::Node].each { |klass| klass.send(:include, ArExtentions) }
         | 
| 281 297 | 
             
              end
         | 
| 282 298 |  | 
| 283 299 | 
             
            end
         | 
| 284 | 
            -
             | 
| 285 | 
            -
             | 
    
        data/niceql.gemspec
    CHANGED
    
    | @@ -9,8 +9,8 @@ Gem::Specification.new do |spec| | |
| 9 9 | 
             
              spec.authors       = ["alekseyl"]
         | 
| 10 10 | 
             
              spec.email         = ["leshchuk@gmail.com"]
         | 
| 11 11 |  | 
| 12 | 
            -
              spec.summary       = %q{This is simple and nice sql  | 
| 13 | 
            -
              spec.description   = %q{This is simple and nice sql  | 
| 12 | 
            +
              spec.summary       = %q{This is simple and nice gem for sql prettifying and formatting. Niceql splits, indent and colorize SQL query and PG errors if any }
         | 
| 13 | 
            +
              spec.description   = %q{This is simple and nice gem for sql prettifying and formatting. Niceql splits, indent and colorize SQL query and PG errors if any. Seemless activerecord integration }
         | 
| 14 14 | 
             
              spec.homepage      = "https://github.com/alekseyl/niceql"
         | 
| 15 15 | 
             
              spec.license       = "MIT"
         | 
| 16 16 |  | 
| @@ -30,12 +30,15 @@ Gem::Specification.new do |spec| | |
| 30 30 | 
             
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         | 
| 31 31 | 
             
              spec.require_paths = ["lib"]
         | 
| 32 32 |  | 
| 33 | 
            -
              spec.required_ruby_version = '>= 2. | 
| 33 | 
            +
              spec.required_ruby_version = '>= 2.4'
         | 
| 34 | 
            +
              spec.add_development_dependency "activerecord", ">= 6.1"
         | 
| 35 | 
            +
             | 
| 34 36 | 
             
              spec.add_development_dependency "bundler", ">= 1"
         | 
| 35 | 
            -
              spec.add_development_dependency "rake", " | 
| 37 | 
            +
              spec.add_development_dependency "rake", ">= 12.3.3"
         | 
| 36 38 | 
             
              spec.add_development_dependency "minitest", "~> 5.0"
         | 
| 37 39 |  | 
| 38 40 | 
             
              spec.add_development_dependency "differ"
         | 
| 39 41 | 
             
              spec.add_development_dependency "pry-byebug"
         | 
| 40 42 | 
             
              spec.add_development_dependency "benchmark-ips"
         | 
| 43 | 
            +
              spec.add_development_dependency 'sqlite3'
         | 
| 41 44 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,15 +1,29 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: niceql
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.4.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - alekseyl
         | 
| 8 | 
            -
            autorequire: | 
| 8 | 
            +
            autorequire:
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2021-11-01 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: activerecord
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - ">="
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '6.1'
         | 
| 20 | 
            +
              type: :development
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - ">="
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '6.1'
         | 
| 13 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 28 | 
             
              name: bundler
         | 
| 15 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -28,16 +42,16 @@ dependencies: | |
| 28 42 | 
             
              name: rake
         | 
| 29 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 44 | 
             
                requirements:
         | 
| 31 | 
            -
                - - " | 
| 45 | 
            +
                - - ">="
         | 
| 32 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            -
                    version:  | 
| 47 | 
            +
                    version: 12.3.3
         | 
| 34 48 | 
             
              type: :development
         | 
| 35 49 | 
             
              prerelease: false
         | 
| 36 50 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 51 | 
             
                requirements:
         | 
| 38 | 
            -
                - - " | 
| 52 | 
            +
                - - ">="
         | 
| 39 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            -
                    version:  | 
| 54 | 
            +
                    version: 12.3.3
         | 
| 41 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 56 | 
             
              name: minitest
         | 
| 43 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -94,8 +108,23 @@ dependencies: | |
| 94 108 | 
             
                - - ">="
         | 
| 95 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 110 | 
             
                    version: '0'
         | 
| 97 | 
            -
             | 
| 98 | 
            -
               | 
| 111 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 112 | 
            +
              name: sqlite3
         | 
| 113 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 | 
            +
                requirements:
         | 
| 115 | 
            +
                - - ">="
         | 
| 116 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            +
                    version: '0'
         | 
| 118 | 
            +
              type: :development
         | 
| 119 | 
            +
              prerelease: false
         | 
| 120 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 | 
            +
                requirements:
         | 
| 122 | 
            +
                - - ">="
         | 
| 123 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 124 | 
            +
                    version: '0'
         | 
| 125 | 
            +
            description: 'This is simple and nice gem for sql prettifying and formatting. Niceql
         | 
| 126 | 
            +
              splits, indent and colorize SQL query and PG errors if any. Seemless activerecord
         | 
| 127 | 
            +
              integration '
         | 
| 99 128 | 
             
            email:
         | 
| 100 129 | 
             
            - leshchuk@gmail.com
         | 
| 101 130 | 
             
            executables: []
         | 
| @@ -119,7 +148,6 @@ files: | |
| 119 148 | 
             
            - lib/generators/niceql/install_generator.rb
         | 
| 120 149 | 
             
            - lib/generators/templates/niceql_initializer.rb
         | 
| 121 150 | 
             
            - lib/niceql.rb
         | 
| 122 | 
            -
            - lib/niceql/string.rb
         | 
| 123 151 | 
             
            - lib/niceql/version.rb
         | 
| 124 152 | 
             
            - niceql.gemspec
         | 
| 125 153 | 
             
            - to_niceql.png
         | 
| @@ -128,7 +156,7 @@ licenses: | |
| 128 156 | 
             
            - MIT
         | 
| 129 157 | 
             
            metadata:
         | 
| 130 158 | 
             
              allowed_push_host: https://rubygems.org
         | 
| 131 | 
            -
            post_install_message: | 
| 159 | 
            +
            post_install_message:
         | 
| 132 160 | 
             
            rdoc_options: []
         | 
| 133 161 | 
             
            require_paths:
         | 
| 134 162 | 
             
            - lib
         | 
| @@ -136,17 +164,16 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 136 164 | 
             
              requirements:
         | 
| 137 165 | 
             
              - - ">="
         | 
| 138 166 | 
             
                - !ruby/object:Gem::Version
         | 
| 139 | 
            -
                  version: '2. | 
| 167 | 
            +
                  version: '2.4'
         | 
| 140 168 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 141 169 | 
             
              requirements:
         | 
| 142 170 | 
             
              - - ">="
         | 
| 143 171 | 
             
                - !ruby/object:Gem::Version
         | 
| 144 172 | 
             
                  version: '0'
         | 
| 145 173 | 
             
            requirements: []
         | 
| 146 | 
            -
             | 
| 147 | 
            -
             | 
| 148 | 
            -
            signing_key: 
         | 
| 174 | 
            +
            rubygems_version: 3.0.9
         | 
| 175 | 
            +
            signing_key:
         | 
| 149 176 | 
             
            specification_version: 4
         | 
| 150 | 
            -
            summary: This is simple and nice  | 
| 151 | 
            -
              query and PG errors if any
         | 
| 177 | 
            +
            summary: This is simple and nice gem for sql prettifying and formatting. Niceql splits,
         | 
| 178 | 
            +
              indent and colorize SQL query and PG errors if any
         | 
| 152 179 | 
             
            test_files: []
         |