Class: SqlFormatter::Formatter

Inherits:
Object
  • Object
show all
Defined in:
lib/sql_formatter/formatter.rb

Constant Summary collapse

NEWLINE =
"\n"
SPACE =
" " * 1
TAB =
" " * 2
COMMA =
","
RESERVED_TOPLEVEL =
[
  'select',
  'from',
  'where',
  'group by',
  'order by'
]
BOUNDARY =
%w( , ; : ( ) . = < > + - * / ! ~ % | & # )
REGEX_RESERVED_TOPLEVEL =
Regexp.new(RESERVED_TOPLEVEL.join('|').gsub(/ /, '\s+'))
REGEX_BOUNDARY =
Regexp.new(BOUNDARY.map{ |m| Regexp.escape m }.join('|'))

Instance Method Summary collapse

Constructor Details

#initialize(string) ⇒ Formatter

Returns a new instance of Formatter.



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/sql_formatter/formatter.rb', line 22

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

Instance Method Details

#formatObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/sql_formatter/formatter.rb', line 35

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