Class Sequel::Postgres::PGArray::Parser
In: lib/sequel/extensions/pg_array.rb
Parent: StringScanner

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.

Methods

new   new_entry   parse  

Constants

UNQUOTED_RE = /[{}",]|[^{}",]+/
QUOTED_RE = /["\\]|[^"\\]+/
NULL_RE = /NULL",/
OPEN_RE = /\{/

Public Class methods

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.

[Source]

     # File lib/sequel/extensions/pg_array.rb, line 343
343:         def initialize(source, converter=nil)
344:           super(source)
345:           @converter = converter 
346:           @stack = [[]]
347:           @recorded = ""
348:         end

Public Instance methods

Take the buffer of recorded characters and add it to the array of entries, and use a new buffer for recorded characters.

[Source]

     # File lib/sequel/extensions/pg_array.rb, line 352
352:         def new_entry(include_empty=false)
353:           if !@recorded.empty? || include_empty
354:             entry = @recorded
355:             if entry == NULL && !include_empty
356:               entry = nil
357:             elsif @converter
358:               entry = @converter.call(entry)
359:             end
360:             @stack.last.push(entry)
361:             @recorded = ""
362:           end
363:         end

Parse the input character by character, returning an array of parsed (and potentially converted) objects.

[Source]

     # File lib/sequel/extensions/pg_array.rb, line 367
367:         def parse
368:           raise Sequel::Error, "invalid array, empty string" if eos?
369:           raise Sequel::Error, "invalid array, doesn't start with {" unless scan(OPEN_RE)
370: 
371:           while !eos?
372:             char = scan(UNQUOTED_RE)
373:             if char == COMMA
374:               # Comma outside quoted string indicates end of current entry
375:               new_entry
376:             elsif char == QUOTE
377:               raise Sequel::Error, "invalid array, opening quote with existing recorded data" unless @recorded.empty?
378:               while true
379:                 char = scan(QUOTED_RE)
380:                 if char == BACKSLASH
381:                   @recorded << getch
382:                 elsif char == QUOTE
383:                   n = peek(1)
384:                   raise Sequel::Error, "invalid array, closing quote not followed by comma or closing brace" unless n == COMMA || n == CLOSE_BRACE
385:                   break
386:                 else
387:                   @recorded << char
388:                 end
389:               end
390:               new_entry(true)
391:             elsif char == OPEN_BRACE
392:               raise Sequel::Error, "invalid array, opening brace with existing recorded data" unless @recorded.empty?
393: 
394:               # Start of new array, add it to the stack
395:               new = []
396:               @stack.last << new
397:               @stack << new
398:             elsif char == CLOSE_BRACE
399:               # End of current array, add current entry to the current array
400:               new_entry
401: 
402:               if @stack.length == 1
403:                 raise Sequel::Error, "array parsing finished without parsing entire string" unless eos?
404: 
405:                 # Top level of array, parsing should be over.
406:                 # Pop current array off stack and return it as result
407:                 return @stack.pop
408:               else
409:                 # Nested array, pop current array off stack
410:                 @stack.pop
411:               end
412:             else
413:               # Add the character to the recorded character buffer.
414:               @recorded << char
415:             end
416:           end
417: 
418:           raise Sequel::Error, "array parsing finished with array unclosed"
419:         end

[Validate]