Class: Nuggets::MySQL::ValueParser

Inherits:
Object
  • Object
show all
Defined in:
lib/nuggets/mysql.rb

Defined Under Namespace

Classes: AST

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.parse(input) ⇒ Object



115
116
117
# File 'lib/nuggets/mysql.rb', line 115

def self.parse(input)
  new.parse(input)
end

Instance Method Details

#error(message) ⇒ Object



198
199
200
201
202
203
204
# File 'lib/nuggets/mysql.rb', line 198

def error(message)
  if @input.eos?
    raise "Unexpected end of input (#{message})."
  else
    raise "#{message} at #{$.}:#{@input.pos}: #{@input.peek(16).inspect}"
  end
end

#parse(input) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/nuggets/mysql.rb', line 119

def parse(input)
  @input = StringScanner.new(input)

  rows, block_given = [], block_given?

  while result = parse_row
    row = result.value
    block_given ? yield(row) : rows << row
    break unless @input.scan(/,\s*/)
  end

  @input.scan(/;/)  # optional

  error('Unexpected data') unless @input.eos?

  rows unless block_given
end

#parse_keywordObject



192
193
194
195
196
# File 'lib/nuggets/mysql.rb', line 192

def parse_keyword
  if @input.scan(/null/i)
    AST.new(nil)
  end
end

#parse_numberObject



186
187
188
189
190
# File 'lib/nuggets/mysql.rb', line 186

def parse_number
  if @input.scan(/-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/)
    AST.new(eval(@input.matched))
  end
end

#parse_rowObject



137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/nuggets/mysql.rb', line 137

def parse_row
  return unless @input.scan(/\(/)

  row = []

  while result = parse_value
    row << result.value
    break unless @input.scan(/,\s*/)
  end

  error('Unclosed row') unless @input.scan(/\)/)

  AST.new(row)
end

#parse_stringObject



158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/nuggets/mysql.rb', line 158

def parse_string
  return unless @input.scan(/'/)

  string = ''

  while contents = parse_string_content || parse_string_escape
    string << contents.value
  end

  error('Unclosed string') unless @input.scan(/'/)

  AST.new(string)
end

#parse_string_contentObject



172
173
174
175
176
# File 'lib/nuggets/mysql.rb', line 172

def parse_string_content
  if @input.scan(/[^\\']+/)
    AST.new(@input.matched)
  end
end

#parse_string_escapeObject



178
179
180
181
182
183
184
# File 'lib/nuggets/mysql.rb', line 178

def parse_string_escape
  if @input.scan(/\\[abtnvfr]/)
    AST.new(eval(%Q{"#{@input.matched}"}))
  elsif @input.scan(/\\.|''/)
    AST.new(@input.matched[-1, 1])
  end
end

#parse_valueObject



152
153
154
155
156
# File 'lib/nuggets/mysql.rb', line 152

def parse_value
  parse_string ||
  parse_number ||
  parse_keyword
end