module PG::BasicTypeRegistry

This module defines the mapping between OID and encoder/decoder classes for PG::BasicTypeMapForResults, PG::BasicTypeMapForQueries and PG::BasicTypeMapBasedOnResult.

Additional types can be added like so:

require 'pg'
require 'ipaddr'

class InetDecoder < PG::SimpleDecoder
  def decode(string, tuple=nil, field=nil)
    IPAddr.new(string)
  end
end
class InetEncoder < PG::SimpleEncoder
  def encode(ip_addr)
    ip_addr.to_s
  end
end

# 0 if for text format, can also be 1 for binary
PG::BasicTypeRegistry.register_type(0, 'inet', InetEncoder, InetDecoder)

Constants

CODERS_BY_NAME

The key of this hash maps to the `typname` column from the table. encoder_map is then dynamically built with oids as the key and Type objects as values.

ValidDirections
ValidFormats

Public Class Methods

alias_type(format, new, old) click to toggle source

Alias the old type to the new type.

# File lib/pg/basic_type_mapping.rb, line 180
def self.alias_type(format, new, old)
        [:encoder, :decoder].each do |ende|
                enc = CODERS_BY_NAME[format][ende][old]
                if enc
                        CODERS_BY_NAME[format][ende][new] = enc
                else
                        CODERS_BY_NAME[format][ende].delete(new)
                end
        end
end
register_coder(coder) click to toggle source

Register an encoder or decoder instance for casting a PostgreSQL type.

Coder#name must correspond to the typname column in the pg_type table. Coder#format can be 0 for text format and 1 for binary.

# File lib/pg/basic_type_mapping.rb, line 163
def self.register_coder(coder)
        h = CODERS_BY_NAME[coder.format] ||= { encoder: {}, decoder: {} }
        name = coder.name || raise(ArgumentError, "name of #{coder.inspect} must be defined")
        h[:encoder][name] = coder if coder.respond_to?(:encode)
        h[:decoder][name] = coder if coder.respond_to?(:decode)
end
register_type(format, name, encoder_class, decoder_class) click to toggle source

Register the given encoder_class and/or decoder_class for casting a PostgreSQL type.

name must correspond to the typname column in the pg_type table. format can be 0 for text format and 1 for binary.

# File lib/pg/basic_type_mapping.rb, line 174
def self.register_type(format, name, encoder_class, decoder_class)
        register_coder(encoder_class.new(name: name, format: format)) if encoder_class
        register_coder(decoder_class.new(name: name, format: format)) if decoder_class
end

Protected Instance Methods

check_format_and_direction(format, direction) click to toggle source
# File lib/pg/basic_type_mapping.rb, line 146
def check_format_and_direction(format, direction)
        raise(ArgumentError, "Invalid format value %p" % format) unless ValidFormats[format]
        raise(ArgumentError, "Invalid direction %p" % direction) unless ValidDirections[direction]
end

Private Instance Methods

build_coder_maps(connection) click to toggle source
# File lib/pg/basic_type_mapping.rb, line 117
        def build_coder_maps(connection)
                if supports_ranges?(connection)
                        result = connection.exec <<-SQL
                                SELECT t.oid, t.typname::text, t.typelem, t.typdelim, t.typinput::text, r.rngsubtype
                                FROM pg_type as t
                                LEFT JOIN pg_range as r ON oid = rngtypid
                        SQL
                else
                        result = connection.exec <<-SQL
                                SELECT t.oid, t.typname::text, t.typelem, t.typdelim, t.typinput::text
                                FROM pg_type as t
                        SQL
                end

                [
                        [0, :encoder, PG::TextEncoder::Array],
                        [0, :decoder, PG::TextDecoder::Array],
                        [1, :encoder, nil],
                        [1, :decoder, nil],
                ].inject([]) do |h, (format, direction, arraycoder)|
                        h[format] ||= {}
                        h[format][direction] = CoderMap.new result, CODERS_BY_NAME[format][direction], format, arraycoder
                        h
                end
        end
supports_ranges?(connection) click to toggle source
# File lib/pg/basic_type_mapping.rb, line 113
def supports_ranges?(connection)
        connection.server_version >= 90200
end