class DBI::DBD::Pg::Type::Array
PostgreSQL arrays are simply a specification that sits on top of normal types. They have a specialized string grammar and this class facilitates converting that syntax and the types within those arrays.
Attributes
base_type[R]
Public Class Methods
new(base_type)
click to toggle source
base_type
is a DBI::Type that is used to parse the inner types when a non-array one is found.
For instance, if you had an array of integer, one would pass DBI::Type::Integer here.
# File lib/dbd/pg/type.rb, line 99 def initialize(base_type) @base_type = base_type end
Public Instance Methods
convert_array(str)
click to toggle source
Parse a PostgreSQL-Array output and convert into ruby array. This does the real parsing work.
# File lib/dbd/pg/type.rb, line 125 def convert_array(str) array_nesting = 0 # nesting level of the array in_string = false # currently inside a quoted string ? escaped = false # if the character is escaped sbuffer = '' # buffer for the current element result_array = ::Array.new # the resulting Array str.each_byte { |char| # parse character by character char = char.chr # we need the Character, not it's Integer if escaped then # if this character is escaped, just add it to the buffer sbuffer += char escaped = false next end case char # let's see what kind of character we have #------------- {: beginning of an array ----# when '{' if in_string then # ignore inside a string sbuffer += char next end if array_nesting >= 1 then # if it's an nested array, defer for recursion sbuffer += char end array_nesting += 1 # inside another array #------------- ": string deliminator --------# when '"' in_string = !in_string #------------- \: escape character, next is regular character # when "\\" # single \, must be extra escaped in Ruby if array_nesting > 1 sbuffer += char else escaped = true end #------------- ,: element separator ---------# when ',' if in_string or array_nesting > 1 then # don't care if inside string or sbuffer += char # nested array else if !sbuffer.is_a? ::Array then sbuffer = @base_type.parse(sbuffer) end result_array << sbuffer # otherwise, here ends an element sbuffer = '' end #------------- }: End of Array --------------# when '}' if in_string then # ignore if inside quoted string sbuffer += char next end array_nesting -=1 # decrease nesting level if array_nesting == 1 # must be the end of a nested array sbuffer += char sbuffer = convert_array( sbuffer ) # recurse, using the whole nested array elsif array_nesting > 1 # inside nested array, keep it for later sbuffer += char else # array_nesting = 0, must be the last } if !sbuffer.is_a? ::Array then sbuffer = @base_type.parse( sbuffer ) end result_array << sbuffer unless sbuffer.nil? # upto here was the last element end #------------- all other characters ---------# else sbuffer += char # simply append end } return result_array end
parse(obj)
click to toggle source
Object method. Please note that this is different than most DBI::Type classes! One must initialize an Array
object with an appropriate DBI::Type used to convert the indices of the array before this method can be called.
Returns an appropriately converted array.
# File lib/dbd/pg/type.rb, line 111 def parse(obj) if obj.nil? nil elsif obj.index('{') == 0 and obj.rindex('}') == (obj.length - 1) convert_array(obj) else raise "Not an array" end end