# class PG::TextDecoder::Record

This class decodes one record of values received from a composite type column in text format. See PostgreSQL Composite Types for a description of the format and how it can be used.

PostgreSQL allows composite types to be used in many of the same ways that simple types can be used. For example, a column of a table can be declared to be of a composite type.

The columns are returned from the decoder as array of values. The single values are decoded as defined in the assigned `type_map`. If no type_map was assigned, all values are converted to strings by `PG::TextDecoder::String`.

Decode a record in Composite Type format from `String` to `Array<String>` (uses default type map `TypeMapAllStrings`):

    PG::TextDecoder::Record.new.decode("(1,2)")  # => ["1", "2"]

Decode a record from `String` to `Array<Float>` :

    # Build a type map for two Floats
    tm = PG::TypeMapByColumn.new([PG::TextDecoder::Float.new]*2)
    # Use this type map to decode the record:
    PG::TextDecoder::Record.new(type_map: tm).decode("(1,2)")
    # => [1.0, 2.0]

Records can also be encoded and decoded directly to and from the database. This avoids intermediate `String` allocations and is very fast. Take the following type and table definitions:

    conn.exec("CREATE TYPE complex AS (r float, i float) ")
    conn.exec("CREATE TABLE my_table (v1 complex, v2 complex) ")
    conn.exec("INSERT INTO my_table VALUES((2,3), (4,5)), ((6,7), (8,9)) ")

The record can be decoded by applying a type map to the `PG::Result` object:

    # Build a type map for two floats "r" and "i"
    tm = PG::TypeMapByColumn.new([PG::TextDecoder::Float.new]*2)
    # Build a record decoder to decode this two-value type:
    deco = PG::TextDecoder::Record.new(type_map: tm)
    # Fetch table data and use the decoder to cast the two complex values "v1" and "v2":
    conn.exec("SELECT * FROM my_table").map_types!(PG::TypeMapByColumn.new([deco]*2)).to_a
    # => [{"v1"=>[2.0, 3.0], "v2"=>[4.0, 5.0]}, {"v1"=>[6.0, 7.0], "v2"=>[8.0, 9.0]}]

It's more very convenient to use the `PG::BasicTypeRegistry`, which is based on database OIDs.

    # Fetch a NULL record of our type to retrieve the OIDs of the two fields "r" and "i"
    oids = conn.exec( "SELECT (NULL::complex).*" )
    # Build a type map (PG::TypeMapByColumn) for decoding the "complex" type
    dtm = PG::BasicTypeMapForResults.new(conn).build_column_map( oids )
    # Register a record decoder for decoding our type "complex"
    PG::BasicTypeRegistry.register_coder(PG::TextDecoder::Record.new(type_map: dtm, name: "complex"))
    # Apply the basic type registry to all results retrieved from the server
    conn.type_map_for_results = PG::BasicTypeMapForResults.new(conn)
    # Now queries decode the "complex" type (and many basic types) automatically
    conn.exec("SELECT * FROM my_table").to_a
    # => [{"v1"=>[2.0, 3.0], "v2"=>[4.0, 5.0]}, {"v1"=>[6.0, 7.0], "v2"=>[8.0, 9.0]}]

Records can also be nested or further wrapped into other decoders like `PG::TextDecoder::CopyRow`.

See also `PG::TextEncoder::Record` for the encoding direction (data sent to the server).