Class: DBI::DBD::Pg::Type::Array

### Home Classes Methods

### In Files

- lib/dbd/pg/type.rb

### Parent

Object

### Methods

- ::new
- #convert_array
- #parse

### Files

- ChangeLog
- LICENSE
- README

### Class/Module Index

Quicksearch

- DBI
- DBI::DBD
- DBI::DBD::Pg
- DBI::DBD::Pg::Database
- DBI::DBD::Pg::Driver
- DBI::DBD::Pg::PgExecutor
- DBI::DBD::Pg::PgExecutorAsync
- DBI::DBD::Pg::Statement
- DBI::DBD::Pg::Statement::DummyQuoter
- DBI::DBD::Pg::Tuples
- DBI::DBD::Pg::Type
- DBI::DBD::Pg::Type::Array
- DBI::DBD::Pg::Type::ByteA

No matching classes.

# 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

[Validate]

Generated with the Darkfish Rdoc Generator 2.