class Sequel::Postgres::PGArray::Parser
PostgreSQL array parser that handles PostgreSQL array output format. Note that does not handle all forms out input that PostgreSQL will accept, and it will not raise an error for all forms of invalid input.
Constants
- NULL_RE
- OPEN_RE
- QUOTED_RE
- UNQUOTED_RE
Public Class Methods
new(source, converter=nil)
click to toggle source
Set the source for the input, and any converter callable to call with objects to be created. For nested parsers the source may contain text after the end current parse, which will be ignored.
Calls superclass method
# File lib/sequel/extensions/pg_array.rb, line 343 def initialize(source, converter=nil) super(source) @converter = converter @stack = [[]] @recorded = "" end
Public Instance Methods
new_entry(include_empty=false)
click to toggle source
Take the buffer of recorded characters and add it to the array of entries, and use a new buffer for recorded characters.
# File lib/sequel/extensions/pg_array.rb, line 352 def new_entry(include_empty=false) if !@recorded.empty? || include_empty entry = @recorded if entry == NULL && !include_empty entry = nil elsif @converter entry = @converter.call(entry) end @stack.last.push(entry) @recorded = "" end end
parse()
click to toggle source
Parse the input character by character, returning an array of parsed (and potentially converted) objects.
# File lib/sequel/extensions/pg_array.rb, line 367 def parse raise Sequel::Error, "invalid array, empty string" if eos? raise Sequel::Error, "invalid array, doesn't start with {" unless scan(OPEN_RE) while !eos? char = scan(UNQUOTED_RE) if char == COMMA # Comma outside quoted string indicates end of current entry new_entry elsif char == QUOTE raise Sequel::Error, "invalid array, opening quote with existing recorded data" unless @recorded.empty? while true char = scan(QUOTED_RE) if char == BACKSLASH @recorded << getch elsif char == QUOTE n = peek(1) raise Sequel::Error, "invalid array, closing quote not followed by comma or closing brace" unless n == COMMA || n == CLOSE_BRACE break else @recorded << char end end new_entry(true) elsif char == OPEN_BRACE raise Sequel::Error, "invalid array, opening brace with existing recorded data" unless @recorded.empty? # Start of new array, add it to the stack new = [] @stack.last << new @stack << new elsif char == CLOSE_BRACE # End of current array, add current entry to the current array new_entry if @stack.length == 1 raise Sequel::Error, "array parsing finished without parsing entire string" unless eos? # Top level of array, parsing should be over. # Pop current array off stack and return it as result return @stack.pop else # Nested array, pop current array off stack @stack.pop end else # Add the character to the recorded character buffer. @recorded << char end end raise Sequel::Error, "array parsing finished with array unclosed" end