Parent

Class/Module Index [+]

Quicksearch

Sequel::Postgres::PGArray::Parser

PostgreSQL array parser that handles all types of input.

This parser is very simple and unoptimized, but should still be O(n) where n is the length of the input string.

Attributes

pos[R]

Current position in the input string.

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.

# File lib/sequel/extensions/pg_array.rb, line 362
def initialize(source, converter=nil)
  @source = source
  @source_length = source.length
  @converter = converter 
  @pos = -1
  @entries = []
  @recorded = ""
  @dimension = 0
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 391
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
    @entries.push(entry)
    @recorded = ""
  end
end
next_char() click to toggle source

Return 2 objects, whether the next character in the input was escaped with a backslash, and what the next character is.

# File lib/sequel/extensions/pg_array.rb, line 374
def next_char
  @pos += 1
  if (c = @source[@pos..@pos]) == BACKSLASH
    @pos += 1
    [true, @source[@pos..@pos]]
  else
    [false, c]
  end
end
parse(nested=false) 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 406
def parse(nested=false)
  # quote sets whether we are inside of a quoted string.
  quote = false
  until @pos >= @source_length
    escaped, char = next_char
    if char == OPEN_BRACE && !quote
      @dimension += 1
      if (@dimension > 1)
        # Multi-dimensional array encounter, use a subparser
        # to parse the next level down.
        subparser = self.class.new(@source[@pos..-1], @converter)
        @entries.push(subparser.parse(true))
        @pos += subparser.pos - 1
      end
    elsif char == CLOSE_BRACE && !quote
      @dimension -= 1
      if (@dimension == 0)
        new_entry
        # Exit early if inside a subparser, since the
        # text after parsing the current level should be
        # ignored as it is handled by the parent parser.
        return @entries if nested
      end
    elsif char == QUOTE && !escaped
      # If already inside the quoted string, this is the
      # ending quote, so add the entry.  Otherwise, this
      # is the opening quote, so set the quote flag.
      new_entry(true) if quote
      quote = !quote
    elsif char == COMMA && !quote
      # If not inside a string and a comma occurs, it indicates
      # the end of the entry, so add the entry.
      new_entry
    else
      # Add the character to the recorded character buffer.
      record(char)
    end
  end
  raise Sequel::Error, "array dimensions not balanced" unless @dimension == 0
  @entries
end
record(c) click to toggle source

Add a new character to the buffer of recorded characters.

# File lib/sequel/extensions/pg_array.rb, line 385
def record(c)
  @recorded << c
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.