class SqlFormatter::Formatter

Constants

BOUNDARY
COMMA
NEWLINE
REGEX_BOUNDARY
REGEX_RESERVED_TOPLEVEL
RESERVED_TOPLEVEL
SPACE
TAB

Public Class Methods

new(string) click to toggle source
# File lib/sql_formatter/formatter.rb, line 23
def initialize(string)
  @ss       = StringScanner.new(string)
  @tokens   = []
  @space    = true
  @newline  = false
  @indent_level = 0
  @inline_parentheses = false
  @inline_parentheses_level = 0
  tokenize
  remove_space
end

Public Instance Methods

format() click to toggle source
# File lib/sql_formatter/formatter.rb, line 36
def format
  output = ''
  @tokens.each_with_index do |token, index|

    case

    # Reserved toplevel
    when  RESERVED_TOPLEVEL.include?(token)
      lower_indent_level
      output += NEWLINE if index > 0
      output += TAB * @indent_level

      # TODO: Add optional..
      if @indent_level >= 2
        @newline = false
      else
        @newline = true
      end

      raise_indent_level

    # End of tokens
    when token == ';' && index == (@tokens.size - 1)
      output += NEWLINE

    # Comma
    when token == COMMA
      @space = true

    # Left parenthesis
    when token == '('
      if @newline
        output += NEWLINE + TAB * @indent_level
      end

      if inline_left_parenthesis?(index)
        @newline = false
        @space = false
        @inline_parentheses = true
        @inline_parentheses_level += 1
        output += SPACE if @tokens[index - 1] == COMMA
      else
        @newline = true
        @indent_level += 2
        output += SPACE
      end

    # Right parenthesis
    when token == ')'
      if inline_right_parenthesis?
        @inline_parentheses_level = [0, @inline_parentheses_level - 1].max

        if @inline_parentheses_level == 0
          @inline_parentheses = false
          @space = true
        end
      else
        @indent_level -= 2
        output += NEWLINE + TAB
      end

    else
      if @inline_parentheses
        # Nothing to do
      elsif @newline
        output += NEWLINE + TAB * @indent_level
        @newline = false
      elsif @space
        output += SPACE
      else
        # Nothing to do
      end
    end

    output += token
  end
  output
end

Private Instance Methods

inline_left_parenthesis?(index) click to toggle source
# File lib/sql_formatter/formatter.rb, line 125
def inline_left_parenthesis?(index)
  RESERVED_TOPLEVEL.include?(@tokens[index + 1]) ? false : true
end
inline_right_parenthesis?() click to toggle source
# File lib/sql_formatter/formatter.rb, line 129
def inline_right_parenthesis?
  @inline_parentheses ? true : false
end
lower_indent_level() click to toggle source
# File lib/sql_formatter/formatter.rb, line 121
def lower_indent_level
  @indent_level = [0, @indent_level -1].max
end
next_token() click to toggle source
# File lib/sql_formatter/formatter.rb, line 139
def next_token
  patterns = [
    /\s+/,
    REGEX_RESERVED_TOPLEVEL,
    REGEX_BOUNDARY,
    /(^'.*?'|^".*?"|^`.*?`)/,
    /\w+/
  ]
  patterns.each do |pattern|
    return @ss.matched if @ss.scan(pattern)
  end

  # TODO: Add error handling
  p 'Warning'
  p @ss.peek 20
  @ss.pos += 1
  return nil
end
raise_indent_level() click to toggle source
# File lib/sql_formatter/formatter.rb, line 117
def raise_indent_level
  @indent_level += 1
end
remove_space() click to toggle source
# File lib/sql_formatter/formatter.rb, line 158
def remove_space
  @tokens.select! { |token| !token.match(/^\s+$/) }
end
tokenize() click to toggle source
# File lib/sql_formatter/formatter.rb, line 133
def tokenize
  until @ss.eos?
    @tokens << next_token
  end
end