NAME
Protocol::Database::PostgreSQL - support for the PostgreSQL wire protocol
SYNOPSIS
use strict;
use warnings;
use mro;
package Example::PostgreSQL::Client;
sub new { bless { @_[1..$#_] }, $_[0] }
sub protocol {
my ($self) = @_;
$self->{protocol} //= Protocol::Database::PostgresQL->new(
outgoing => $self->outgoing,
)
}
# Any received packets will arrive here
sub incoming { shift->{incoming} //= Ryu::Source->new }
# Anything we want to send goes here
sub outgoing { shift->{outgoing} //= Ryu::Source->new }
...
# We raise events on our incoming source in this example -
# if you prefer to handle each message as it's extracted you
# could add that directly in the loop
$self->incoming
->switch_str(
sub { $_->type },
authentication_request => sub { ... },
sub { warn 'unknown message - ' . $_->type }
);
# When there's something to write, we'll get an event here
$self->outgoing
->each(sub { $sock->write($_) });
while(1) {
$sock->read(my $buf, 1_000_000);
while(my $msg = $self->protocol->extract_message(\$buf)) {
$self->incoming->emit($msg);
}
}
DESCRIPTION
Provides protocol-level support for PostgreSQL 7.4+, as defined in http://www.postgresql.org/docs/current/static/protocol.html.
How do I use this?
The short answer: don't.
Use Database::Async::Engine::PostgreSQL instead, unless you're writing a driver for talking to PostgreSQL (or compatible) systems.
This distribution provides the abstract protocol handling, meaning that it understands the packets that make up the PostgreSQL communication protocol, but it does not attempt to send or receive those packets itself. You need to provide the transport layer (typically this would involve TCP or Unix sockets).
Connection states
Possible states:
Unconnected - we have a valid instantiated PostgreSQL object, but no connection yet.
Connected - transport layer has made a connection for us
AuthRequested - the server has challenged us to identify
Authenticated - we have successfully identified with the server
Idle - session is active and ready for commands
Parsing - a statement has been passed to the server for parsing
Describing - the indicated statement is being described, called after the transport layer has sent the Describe request
Binding - parameters for a given query have been transmitted
Executing - we have sent a request to execute
ShuttingDown - terminate request sent
CopyIn - the server is expecting data for a COPY command
Message types
The "type" in Protocol::Database::Backend for incoming messages can currently include the following:
send_request
- Called each time there is a new message to be sent to the other side of the connection.authenticated
- Called when authentication is completecopy_data
- we have received data from an ongoing COPY requestcopy_complete
- the active COPY request has completed
For the client, the following additional callbacks are available:
request_ready
- the server is ready for the next requestbind_complete
- a Bind request has completedclose_complete
- the Close request has completedcommand_complete
- the requested command has finished, this will typically be followed by an on_request_ready eventcopy_in_response
- indicates that the server is ready to receive COPY datacopy_out_response
- indicates that the server is ready to send COPY datacopy_both_response
- indicates that the server is ready to exchange COPY data (for replication)data_row
- data from the current queryempty_query
- special-case response when sent an empty query, can be used for 'ping'. Typically followed by on_request_readyerror
- server has raised an errorfunction_call_result
- results from a function callno_data
- indicate that a query returned no data, typically followed by on_request_readynotice
- server has sent us a noticenotification
- server has sent us a NOTIFYparameter_description
- parameters are being describedparameter_status
- parameter status...parse_complete
- parsing is doneportal_suspended
- the portal has been suspended, probably hit the row limitready_for_query
- we're ready for queriesrow_description
- descriptive information about the rows we're likely to be seeing shortly
And there are also these potential events back from the server:
copy_fail
- the frontend is indicating that the copy has faileddescribe
- request for something to be describedexecute
- request execution of a given portalflush
- request flushfunction_call
- request execution of a given functionparse
- request to parse somethingpassword
- password informationquery
- simple query requestssl_request
- we have an SSL requeststartup_message
- we have an SSL requestsync
- sync requestterminate
- termination request
METHODS
new
Instantiate a new object. Blesses an empty hashref and calls "configure", subclasses can bypass this entirely and just call "configure" directly after instantiation.
configure
Does the real preparation for the object.
frontend_bind
Bind parameters to an existing prepared statement.
frontend_copy_data
frontend_close
frontend_copy_done
frontend_describe
Describe expected SQL results
frontend_execute
Execute either a named or anonymous portal (prepared statement with bind vars)
frontend_parse
Parse SQL for a prepared statement
frontend_password_message
Password data, possibly encrypted depending on what the server specified.
frontend_sasl_initial
Initial client response for SASL authentication
frontend_query
Simple query
frontend_startup_message
Initial mesage informing the server which database and user we want
frontend_sync
Synchonise after a prepared statement has finished execution.
frontend_terminate
is_authenticated
Returns true if we are authenticated (and can start sending real data).
is_first_message
Returns true if this is the first message, as per http://developer.postgresql.org/pgdocs/postgres/protocol-overview.html:
"For historical reasons, the very first message sent by the client (the startup message)
has no initial message-type byte."
send_message
Send a message.
method_for_frontend_type
Returns the method name for the given frontend type.
is_known_frontend_message_type
Returns true if the given frontend type is one that we know how to handle.
message
Creates a new message of the given type.
handle_message
Handle an incoming message from the server.
message_length
Returns the length of the given message.
simple_query
Send a simple query to the server - only supports plain queries (no bind parameters).
copy_data
Send copy data to the server.
copy_done
Indicate that the COPY data from the client is complete.
backend_state
Accessor for current backend state.
is_ready
Returns true if we're ready to send more data to the server.
send_copy_data
Send COPY data to the server. Takes an arrayref and replaces any reserved characters with quoted versions.
build_message
Construct a new message.
SEE ALSO
Some PostgreSQL-related modules - plenty of things build on these so have a look at the relevant reverse deps if you're after something higher level:
DBD::Pg - uses the official library and (unlike this module) provides full support for DBI
Pg::PQ - another libpq wrapper
Postgres - quite an old (1998) libpq binding
Pg - slightly less old (2000) libpq binding
DBD::PgPP - provides another pure-Perl implemmentation, with the focus on DBI compatibility
Other related database protocols:
Protocol::MySQL - Oracle's popular database product
Protocol::TDS - the tabular data stream protocol, mainly of interest for SQL Server users
AUTHOR
Tom Molesworth <TEAM@cpan.org>
LICENSE
Copyright Tom Molesworth 2010-2019. Licensed under the same terms as Perl itself.