Skip to content

Instantly share code, notes, and snippets.

@arika
Created August 4, 2018 01:12
Show Gist options
  • Save arika/762aa661c62779f7a7761e6c4e2eb63f to your computer and use it in GitHub Desktop.
Save arika/762aa661c62779f7a7761e6c4e2eb63f to your computer and use it in GitHub Desktop.
require 'ostruct'
require 'anbt-sql-formatter/formatter'
module PrettyPrintSql
module ActiveRecord
def ppsql
to_sql.tap {|sql| ::PrettyPrintSql.pp(sql) }
end
end
module_function
def pp(str, out = $>, theme = nil)
out << pretty_print(str.dup, theme: theme, corlorize: out.tty?) << "\n"
end
def pretty_print(str, theme: nil, corlorize: false)
@sql_formatter ||= sql_formatter
sql = @sql_formatter.format(str)
return sql unless corlorize && @terminal_formatter
public_send(@terminal_formatter, sql, theme)
end
def config
@config ||= OpenStruct.new().tap do |config|
config.default_theme = 'github' if @terminal_formatter == :rouge
end
end
def themes
@terminal_formatter == :rouge ? Rouge::Theme.registry.keys : []
end
def load_terminal_formatter!(formatter = nil)
@terminal_formatter = nil
load_terminal_formatter(formatter)
end
private
module_function
def sql_formatter
rule = AnbtSql::Rule.new
rule.keyword = AnbtSql::Rule::KEYWORD_UPPER_CASE
rule.kw_minus1_indent_nl_x_plus1_indent += ['INNER JOIN', 'LEFT OUTER JOIN']
rule.kw_nl_x += ['ON']
rule.kw_nl_x_plus1_indent -= ['ON']
rule.kw_multi_words += ['INNER JOIN', 'LEFT OUTER JOIN']
AnbtSql::Formatter.new(rule)
end
def coderay(sql, _theme)
@duo ||= CodeRay::Duo[:sql, :terminal]
@duo.encode(sql)
end
def rouge(sql, theme)
@rouge_lexer ||= Rouge::Lexer.find('sql').new
formatter =
if theme.nil? || theme == config.default_theme
@rouge_formatter ||= rouge_formatter(config.default_theme)
else
rouge_formatter(theme)
end
formatter.format(@rouge_lexer.lex(sql))
end
def rouge_formatter(theme)
Rouge::Formatter.find('terminal256')
.new(Rouge::Theme.find(theme).new)
end
def detect_loaded_terminal_formatter
if defined?(::CodeRay)
:coderay
elsif defined?(::Rouge)
:rouge
else
nil
end
end
def load_terminal_formatter(formatter = nil)
return if @terminal_formatter
if formatter.nil?
@terminal_formatter = detect_loaded_terminal_formatter
return if @terminal_formatter
end
{
rouge: 'rouge',
coderay: 'coderay',
}.each do |name, lib|
next if name && name != formatter
begin
require lib
@terminal_formatter = name
break
rescue LoadError
end
end
end
load_terminal_formatter
end
if defined?(::ActiveRecord)
::ActiveRecord::Relation.include(PrettyPrintSql::ActiveRecord)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment