pg_async
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Values input/output

There are two types of formats for data on-the-wire with PostgreSQL: text and binary. The text format is more universal, but the binary format is more compact and sometimes closer to the native client data formats.

Value Input (read query results)

Query results in simple query mode are always in text format.

In extended query mode the resultset can contain fields in text and in binary formats. When a request is prepared pg_async specifies data formats for each of the fields. A PostgreSQL type oid is determined by a tip::db::pg::io::traits::cpppg_data_mapping specialization for a type. A binary format for a field will be requested if the presence of a binary parser was explicitly specified. (tip::db::pg::io::traits::register_binary_parser )

protocol_parser Concept

A protocol parser is a functor that gets an lvalue reference to a value in constructor and defines a template operator() that takes two iterators to a char buffer (begin and end iterators) and uses that data range to parse the value. If the parse was a success return the new position of input iterator. If it fails, returns the starting position of the input iterator. It must define a value_type.

Protocol parsers are used by the result set to extract values from data row buffers.

Adding Support for a Data Type Input

To support parsing of a data type from input buffer a structure conforming to protocol_parser concept must be implemented. It can be either a specialization of tip::db::pg::io::protocol_parser or any other structure. In the latter case tip::db::pg::io::protocol_io_traits must be specialized for the type using the parser class as a typedef for parser_type.

A text parser for a data type is mandatory, binary parser is optional. To make pg_async request the data type in a binary format, the PostgreSQL type oid must be registered as having a binary parser.

Adding text data format parser:

Adding a binary data parser:

// Example specialization of a parser for boolean type
namespace tip { namespace db { namespace pg { namespace io {
template < >
struct protocol_parser < bool, BINARY_DATA_FORMAT > {
typedef bool value_type;
value_type& value;
protocol_parser(value_type& value) : value(value) {}
template < typename InputIterator >
InputIterator
operator()(InputIterator begin, InputIterator end)
{
// input, parse, assign to the value
}
};
}}}} // namespace tip::db::pg::io
// Example separate structure
struct bool_parser {
typedef bool value_type;
value_type& value;
bool_parser(value_type& value) : value(value) {}
template < typename InputIterator >
InputIterator
operator()(InputIterator begin, InputIterator end)
{
// input, parse, assign to the value
}
};
namespace tip { namespace db { namespace pg { namespace io {
// Specialization of protocol_io_traits
template <>
struct protocol_io_traits < bool, BINARY_DATA_FORMAT > {
// ...
typedef bool_parser parser_type;
// ...
};
namespace traits {
// Enable binary parser for the type
template <> struct has_parser<bool, BINARY_DATA_FORMAT > : std::true_type {};
} // namespace traits
}}}} // namespace tip::db::pg::io
// Somewhere in initialization code
using namespace tip::db::pg;
See Also
tip::db::pg::io::protocol_read
tip::db::pg::io::protocol_io_traits
tip::db::pg::io::protocol_parser

Value Output (write query parameters)

When there is no specialization of a protocol_formatter for a type, default implementation based on standard C++ iostreams is used. Protocol data format is text in this case.

protocol_formatter Concept

A protocol_fomatter is a functor that gets an rvalue reference to data that needs to be output and defines an operator() that takes a reference to a data buffer (std::vector<byte>) for output.

Protocol formatters are used by query to write parameters sent to PostgreSQL server.

Adding Support for a Data Type Output

To support formatting of a data type to send data to PostgreSQL server a structure conforming to protocol_formatter concept must be implemented. It can be either a specialization of tip::db::pg::io::protocol_formatter or any other structure. In the latter case tip::db::pg::io::protocol_io_traits must be specialized for the type using the formatter class as a typedef for formatter_type.

A text formatter for a data type is mandatory, binary formaater is optional.

Adding text data format parser:

Adding a binary data parser:

// Example specialization of a formatter for boolean type
namespace tip { namespace db { namespace pg { namespace io {
template < >
struct protocol_formatter < bool, BINARY_DATA_FORMAT > {
typedef bool value_type;
value_type const& value;
protocol_formatter(value_type const& value) : value(value) {}
bool
operator()(std::vector<byte>& buffer)
{
buffer.push_back(value ? 1 : 0);
return true;
}
};
}}}} // namespace tip::db::pg::io
// Example separate structure
struct bool_formatter {
typedef bool value_type;
value_type const& value;
bool_formatter(value_type const& value) : value(value) {}
bool
operator()(std::vector<byte>& buffer)
{
buffer.push_back(value ? 1 : 0);
return true;
}
};
namespace tip { namespace db { namespace pg { namespace io {
// Specialization of protocol_io_traits
template <>
struct protocol_io_traits < bool, BINARY_DATA_FORMAT > {
// ...
typedef bool_formatter formatter_type;
// ...
};
namespace traits {
// Enable binary formatter for the type
template <> struct has_formatter<bool, BINARY_DATA_FORMAT > : std::true_type {};
} // namespace traits
}}}} // namespace tip::db::pg::io
See Also
tip::db::pg::io::protocol_write
tip::db::pg::io::protocol_io_traits
tip::db::pg::io::protocol_formatter