123456789_123456789_123456789_123456789_123456789_

Class: PG::BasicTypeMapForResults

Relationships & Source Files
Namespace Children
Classes:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
Inherits: PG::TypeMapByOid
Defined in: lib/pg/basic_type_map_for_results.rb

Overview

Simple set of rules for type casting common PostgreSQL types to Ruby.

OIDs of supported type casts are not hard-coded in the sources, but are retrieved from the PostgreSQL’s pg_type table in .new .

Result values are type casted based on the type OID of the given result column.

Higher level libraries will most likely not make use of this class, but use their own set of rules to choose suitable encoders and decoders.

Example:

conn = PG::Connection.new
# Assign a default ruleset for type casts of output values.
conn.type_map_for_results = PG::BasicTypeMapForResults.new(conn)
# Execute a query.
res = conn.exec_params( "SELECT $1::INT", ['5'] )
# Retrieve and cast the result value. Value format is 0 (text) and OID is 20. Therefore typecasting
# is done by PG::TextDecoder::Integer internally for all value retrieval methods.
res.values  # => [[5]]

TypeMapByOid#build_column_map(result) can be used to generate a result independent TypeMapByColumn type map, which can subsequently be used to cast #get_copy_data fields:

For the following table:

conn.exec( "CREATE TABLE copytable AS VALUES('a', 123, '{5,4,3}'::INT[])" )

# Retrieve table OIDs per empty result set.
res = conn.exec( "SELECT * FROM copytable LIMIT 0" )
# Build a type map for common database to ruby type decoders.
btm = PG::BasicTypeMapForResults.new(conn)
# Build a PG::TypeMapByColumn with decoders suitable for copytable.
tm = btm.build_column_map( res )
row_decoder = PG::TextDecoder::CopyRow.new type_map: tm

conn.copy_data( "COPY copytable TO STDOUT", row_decoder ) do |res|
  while row=conn.get_copy_data
    p row
  end
end

This prints the rows with type casted columns:

["a", 123, [5, 4, 3]]

Very similar with binary format:

conn.exec( "CREATE TABLE copytable AS VALUES('a', 123, '2023-03-19 18:39:44'::TIMESTAMP)" )

# Retrieve table OIDs per empty result set in binary format.
res = conn.exec_params( "SELECT * FROM copytable LIMIT 0", [], 1 )
# Build a type map for common database to ruby type decoders.
btm = PG::BasicTypeMapForResults.new(conn)
# Build a PG::TypeMapByColumn with decoders suitable for copytable.
tm = btm.build_column_map( res )
row_decoder = PG::BinaryDecoder::CopyRow.new type_map: tm

conn.copy_data( "COPY copytable TO STDOUT WITH (FORMAT binary)", row_decoder ) do |res|
  while row=conn.get_copy_data
    p row
  end
end

This prints the rows with type casted columns:

["a", 123, 2023-03-19 18:39:44 UTC]

See also BasicTypeMapBasedOnResult for the encoder direction and BasicTypeRegistry for the definition of additional types.

Constant Summary

BasicTypeRegistry::Checker - Included

ValidDirections, ValidFormats

Class Method Summary

Instance Attribute Summary

TypeMapByOid - Inherited

#max_rows_for_online_lookup,
#max_rows_for_online_lookup=

Threshold for doing Hash lookups versus creation of a dedicated TypeMapByColumn.

TypeMap::DefaultTypeMappable - Included

#default_type_map

Returns the default TypeMap that is currently set for values that could not be casted by this type map.

#default_type_map=

Set the default TypeMap that is used for values that could not be casted by this type map.

Instance Method Summary

TypeMapByOid - Inherited

#add_coder

Assigns a new Coder object to the type map.

#build_column_map

This builds a TypeMapByColumn that fits to the given Result object based on it’s type OIDs and binary/text format.

#coders

Array of all assigned Coder objects.

#rm_coder

Removes a Coder object from the type map based on the given oid and format codes.

TypeMap::DefaultTypeMappable - Included

#with_default_type_map

Set the default TypeMap that is used for values that could not be casted by this type map.

Constructor Details

.new(connection_or_coder_maps, registry: nil) ⇒ BasicTypeMapForResults

[ GitHub ]

  
# File 'lib/pg/basic_type_map_for_results.rb', line 93

def initialize(connection_or_coder_maps, registry: nil)
	@coder_maps = build_coder_maps(connection_or_coder_maps, registry: registry)

	# Populate TypeMapByOid hash with decoders
	@coder_maps.each_format(:decoder).flat_map{|f| f.coders }.each do |coder|
		add_coder(coder)
	end

	typenames = @coder_maps.typenames_by_oid
	self.default_type_map = WarningTypeMap.new(typenames)
end