lib/niceql.rb in niceql-0.1.20 vs lib/niceql.rb in niceql-0.1.21
- old
+ new
@@ -1,6 +1,7 @@
require "niceql/version"
+require 'niceql/string'
module Niceql
module StringColorize
def self.colorize_verb( str)
@@ -31,11 +32,11 @@
end
end
module Prettifier
- INLINE_VERBS = %w(WITH ASC (IN\s) COALESCE AS WHEN THEN ELSE END AND UNION ALL WITH ON DISTINCT INTERSECT EXCEPT EXISTS NOT COUNT ROUND CAST).join('| ')
+ INLINE_VERBS = %w(WITH ASC (IN\s) COALESCE AS WHEN THEN ELSE END AND UNION ALL ON DISTINCT INTERSECT EXCEPT EXISTS NOT COUNT ROUND CAST).join('| ')
NEW_LINE_VERBS = 'SELECT|FROM|WHERE|CASE|ORDER BY|LIMIT|GROUP BY|(RIGHT |LEFT )*(INNER |OUTER )*JOIN|HAVING|OFFSET|UPDATE'
POSSIBLE_INLINER = /(ORDER BY|CASE)/
VERBS = "#{NEW_LINE_VERBS}|#{INLINE_VERBS}"
STRINGS = /("[^"]+")|('[^']+')/
BRACKETS = '[\(\)]'
@@ -121,31 +122,33 @@
def self.prettify_sql( sql, colorize = true )
indent = 0
parentness = []
- #it's better to remove all new lines because it will break formatting + remove any additional formatting with many spaces
- # second map! is add newlines at start and begining for all comments started with new line
- sql = sql.split( SQL_COMMENTS ).each_slice(2).map{ | crmb, cmmnt |
- [crmb.gsub(/[\s]+/, ' '),
- cmmnt && ( cmmnt&.match?(/\A\s*$/) ? "\n" + cmmnt[/[\S]+[\s\S]*[\S]+/] + "\n" : cmmnt[/[\S]+[\s\S]*[\S]+/] ) ]
+ sql = sql.split( SQL_COMMENTS ).each_slice(2).map{ | sql_part, comment |
+ # remove additional formatting for sql_parts but leave comment intact
+ [sql_part.gsub(/[\s]+/, ' '),
+ # comment.match?(/\A\s*$/) - SQL_COMMENTS gets all comment content + all whitespaced chars around
+ # so this sql_part.length == 0 || comment.match?(/\A\s*$/) checks does the comment starts from new line
+ comment && ( sql_part.length == 0 || comment.match?(/\A\s*$/) ? "\n#{comment[COMMENT_CONTENT]}\n" : comment[COMMENT_CONTENT] ) ]
}.flatten.join(' ')
sql.gsub!(/ \n/, "\n")
sql.gsub!(STRINGS){ |str| StringColorize.colorize_str(str) } if colorize
first_verb = true
- previous_was_comment = false
+ prev_was_comment = false
sql.gsub!( /(#{VERBS}|#{BRACKETS}|#{SQL_COMMENTS_CLEARED})/) do |verb|
if 'SELECT' == verb
indent += config.indentation_base if !config.open_bracket_is_newliner || parentness.last.nil? || parentness.last[:nested]
parentness.last[:nested] = true if parentness.last
add_new_line = !first_verb
elsif verb == '('
next_closing_bracket = Regexp.last_match.post_match.index(')')
+ # check if brackets contains SELECT statement
add_new_line = !!Regexp.last_match.post_match[0..next_closing_bracket][/SELECT/] && config.open_bracket_is_newliner
parentness << { nested: add_new_line }
elsif verb == ')'
# this also covers case when right bracket is used without corresponding left one
add_new_line = parentness.last.nil? || parentness.last[:nested]
@@ -157,29 +160,43 @@
# inline with its agg function
add_new_line = parentness.last.nil? || parentness.last[:nested]
else
add_new_line = verb[/(#{INLINE_VERBS})/].nil?
end
- first_verb = false
- verb = verb[COMMENT_CONTENT] if verb[SQL_COMMENTS_CLEARED]
# !add_new_line && previous_was_comment means we had newlined comment, and now even
# if verb is inline verb we will need to add new line with indentation BUT all
- # newliners match with a space before so we need to strip it
- verb.lstrip! if !add_new_line && previous_was_comment
+ # inliners match with a space before so we need to strip it
+ verb.lstrip! if !add_new_line && prev_was_comment
+
+ add_new_line = prev_was_comment unless add_new_line
+ add_indent = !first_verb && add_new_line
+
+ if verb[SQL_COMMENTS_CLEARED]
+ verb = verb[COMMENT_CONTENT]
+ prev_was_comment = true
+ else
+ first_verb = false
+ prev_was_comment = false
+ end
+
verb = StringColorize.colorize_verb(verb) if !['(', ')'].include?(verb) && colorize
- (previous_was_comment || add_new_line ? indent_multiline(verb, indent) : verb).tap{ previous_was_comment = !verb.to_s[SQL_COMMENTS_CLEARED].nil? }
+
+ subs = ( add_indent ? indent_multiline(verb, indent) : verb)
+ !first_verb && add_new_line ? "\n" + subs : subs
end
- sql.gsub( /\s+\n/, "\n" ).gsub(/\s+\z/, '')
+
+ # clear all spaces before newlines, and all whitespaces before string end
+ sql.tap{ |slf| slf.gsub!( /\s+\n/, "\n" ) }.tap{ |slf| slf.gsub!(/\s+\z/, '') }
end
private
def self.indent_multiline( verb, indent )
- # byebug
- if verb.match?(/.\n./)
- verb.lines.map!{|ln| "\n#{' ' * indent}" + ln}.join
+ #
+ if verb.match?(/.\s*\n\s*./)
+ verb.lines.map!{|ln| "#{' ' * indent}" + ln}.join("\n")
else
- "\n#{' ' * indent}" + verb.to_s
+ "#{' ' * indent}" + verb.to_s
end
end
end
module PostgresAdapterNiceQL