lib/niceql.rb in niceql-0.1.7 vs lib/niceql.rb in niceql-0.1.8

- old
+ new

@@ -1,8 +1,9 @@ require "niceql/version" module Niceql + module StringColorize def self.colorize_verb( str) #yellow ANSI color "\e[0;33;49m#{str}\e[0m" end @@ -15,15 +16,15 @@ "\e[0;31;49m#{err}\e[0m" end end module ArExtentions - def explain_err + def exec_niceql begin - connection.execute( "EXPLAIN #{to_niceql}" ) + connection.execute( to_niceql ) rescue StandardError => e - puts Prettifier.prettify_err(e ) + raise e.class.new( Prettifier.prettify_err(e ) ) end end def to_niceql Prettifier.prettify_sql(to_sql, false) @@ -33,38 +34,59 @@ puts Prettifier.prettify_sql( to_sql, colorize ) end end module Prettifier - INLINE_VERBS = %w(ASC IN AS WHEN THEN ELSE END AND UNION ALL WITH ON DISTINCT INTERSECT EXCEPT EXISTS NOT).join('| ') + INLINE_VERBS = %w(ASC IN AS WHEN THEN ELSE END AND UNION ALL WITH ON DISTINCT INTERSECT EXCEPT EXISTS NOT COUNT).join('| ') NEW_LINE_VERBS = 'SELECT|FROM|WHERE|CASE|ORDER BY|LIMIT|GROUP BY|WITH|LEFT JOIN|RIGHT JOIN|JOIN|HAVING|OFFSET' VERBS = "#{INLINE_VERBS}|#{NEW_LINE_VERBS}" STRINGS = /("[^"]+")|('[^']+')/ BRACKETS = '[\(\)]' def self.prettify_err(err) if ActiveRecord::Base.configurations[Rails.env]['adapter'] == 'postgresql' prettify_pg_err( err.to_s ) else - puts err + err end end def self.prettify_pg_err(err) err_line_num = err[/LINE \d+/][5..-1].to_i + start_sql_line = err.lines[3][/(HINT|DETAIL)/] ? 4 : 3 err_body = err.lines[start_sql_line..-1] - err_line = StringColorize.colorize_err( err_body[err_line_num-1] ) + err_quote = ( err.lines[1][/\.\.\..+\.\.\./] && err.lines[1][/\.\.\..+\.\.\./][3..-4] ) || + ( err.lines[1][/\.\.\..+/] && err.lines[1][/\.\.\..+/][3..-1] ) + + # line 2 is err carret line + err_carret_line = err.lines[2][err.lines[1][/LINE \d+:/].length+1..-1] + # err line painted red completly, so we just remembering it and use + # to replace after paiting the verbs + err_line = err_body[err_line_num-1] + + # when err line is too long postgres quotes it part in doble ... + if err_quote + err_quote_carret_offset = err_carret_line.length - err.lines[1].index( '...' ) + 3 + err_carret_line = ' ' * ( err_line.index( err_quote ) + err_quote_carret_offset ) + end + + # if mistake is on last string than err_line.last != \n so we need to prepend \n to carret line + err_line = ( err_line.last == "\n" ? err_line + "\n" : "\n" + err_line ) + + #colorizing verbs and strings err_body = err_body.join.gsub(/#{VERBS}/ ) { |verb| StringColorize.colorize_verb(verb) } err_body = err_body.gsub(STRINGS){ |str| StringColorize.colorize_str(str) } + #reassemling error message err_body = err_body.lines - err_body[err_line_num-1]= err_line - err_body.insert( err_line_num, StringColorize.colorize_err( err.lines[2][err.lines[1][/LINE \d+:/].length+1..-1] ) ) - puts err.lines[0..start_sql_line-1].join + err_body.join + err_body[err_line_num-1]= StringColorize.colorize_err( err_line ) + err_body.insert( err_line_num, StringColorize.colorize_err( err_carret_line ) ) + + err.lines[0..start_sql_line-1].join + err_body.join end def self.prettify_sql( sql, colorize = true ) indent = 0 parentness = [] @@ -99,10 +121,43 @@ add_new_line ? "\n#{' ' * indent}" + verb : verb end end end + module PostgresAdapterNiceQL + def exec_query(sql, name = "SQL", binds = [], prepare: false) + begin + # replacing sql with prettified sql, thats all + super( Prettifier.prettify_sql(sql, false), name, binds, prepare: prepare ) + rescue StandardError => e + raise e.class.new( Prettifier.prettify_err(e ) ) + end + end + end + + class NiceQLConfig + attr_accessor :pg_adapter_with_nicesql + def initialize + self.pg_adapter_with_nicesql = false + end + end + + + def self.configure + @config ||= NiceQLConfig.new + + yield( @config ) + + if @config.pg_adapter_with_nicesql + ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.include(PostgresAdapterNiceQL) + end + end + + if defined? ::ActiveRecord::Base ::ActiveRecord::Base.extend ArExtentions [::ActiveRecord::Relation, ::ActiveRecord::Associations::CollectionProxy].each { |klass| klass.send(:include, ArExtentions) } end + end + +