class SQLint::Linter
Constants
- END_PARSE
- Lint
- ParseState
Public Class Methods
new(filename, input_stream)
click to toggle source
# File lib/sqlint/linter.rb, line 9 def initialize(filename, input_stream) @input = input_stream.read @filename = filename end
Public Instance Methods
run()
click to toggle source
# File lib/sqlint/linter.rb, line 14 def run Enumerator.new do |results| state = ParseState.new(@input, 0) while state != END_PARSE error, new_parse_state = parse_next_error(state) results << error if error state = new_parse_state end end end
Private Instance Methods
clean_message(message)
click to toggle source
# File lib/sqlint/linter.rb, line 58 def clean_message(message) message .gsub(/(?<=at or near ")(.*)(?=")/) { |match| match[0..49] } .gsub(/\s+\(scan\.l\:\d+\)/, '') end
find_absolute_position(offset)
click to toggle source
# File lib/sqlint/linter.rb, line 51 def find_absolute_position(offset) lines_before_error = @input[0...(offset)].split("\n") line_number = lines_before_error.size column_number = lines_before_error.any? ? lines_before_error.last.size : 1 [line_number, column_number] end
parse_next_error(parse_state)
click to toggle source
# File lib/sqlint/linter.rb, line 27 def parse_next_error(parse_state) begin PgQuery.parse(parse_state.input) [nil, END_PARSE] rescue PgQuery::ParseError => e offset = e.location + parse_state.offset line_number, column_number = find_absolute_position(offset) lint = Lint.new(@filename, line_number, column_number, :error, clean_message(e.message)) input_from_error = parse_state.input[e.location..-1] semicolon_pos = input_from_error.index(";") if input_from_error [ lint, if semicolon_pos remaining_input = input_from_error[semicolon_pos+1..-1] new_offset = offset + semicolon_pos + 1 ParseState.new(remaining_input, new_offset) else END_PARSE end ] end end