Sha256: e6ae594192392a283cce0e5171e16ca13c2218453e03515773189de9b4338f31

Contents?: true

Size: 1.97 KB

Versions: 3

Compression:

Stored size: 1.97 KB

Contents

# frozen_string_literal: true

require "anbt-sql-formatter/formatter"
require "active_record"

module Whoop
  module Formatters
    module SqlFormatter
      # Format the SQL query
      # @param [String] sql The SQL query
      # @param [Boolean] colorize - colorize the SQL query (default: false)
      # @param [Boolean] explain - also run `EXPLAIN` on the query (default: false)
      # @return [String] The formatted SQL query
      def self.format(sql, colorize: false, explain: false)
        pretty_sql = generate_pretty_sql(sql)
        return pretty_sql unless colorize

        formatter = Rouge::Formatters::TerminalTruecolor.new
        lexer = Rouge::Lexers::SQL.new

        formatted_sql = formatter.format(lexer.lex(pretty_sql))
        return formatted_sql unless explain

        raw_explain = exec_explain(sql)
        formatted_explain = formatter.format(lexer.lex(raw_explain))

        [
          "sql:\n\n".colorize(:light_black).underline,
          formatted_sql,
          "\n\n",
          "query plan:\n\n".colorize(:light_black).underline,
          formatted_explain
        ].join
      end

      # Generate a pretty SQL query
      # @param [String] sql The SQL query
      # @return [String] The formatted SQL query
      def self.generate_pretty_sql(sql)
        rule = AnbtSql::Rule.new
        rule.indent_string = "  "
        formatter = AnbtSql::Formatter.new(rule)
        formatter.format(sql.dup)
      end

      # Execute the `EXPLAIN` query
      # @param [String] sql The SQL query
      # @return [String] The formatted query plan
      def self.exec_explain(sql)
        result = ActiveRecord::Base.connection.exec_query("EXPLAIN #{sql}")
        lines = result.rows.map(&:first)

        pretty_explain = []
        pretty_explain += lines.map { |line| " #{line}" }
        nrows = result.rows.length
        rows_label = nrows == 1 ? "row" : "rows"
        pretty_explain << "\n(#{nrows} #{rows_label})"

        pretty_explain.join("\n")
      end
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
whoop-1.0.3 lib/whoop/formatters/sql_formatter.rb
whoop-1.0.2 lib/whoop/formatters/sql_formatter.rb
whoop-1.0.1 lib/whoop/formatters/sql_formatter.rb