Pg-PQ

 view release on metacpan or  search on metacpan

lib/Pg/PQ.pm  view on Meta::CPAN

                      sqlstate            C
                      message_primary     M
                      message_detail      D
                      message_hint        H
                      statement_position  P
                      internal_position   p
                      internal_query      q
                      context             W
                      source_file         F
                      source_line         L
                      source_function     R );

sub errorDescription {
    my $self = shift;
    my %desc;
    while (my ($field, $key) = each %error_field) {
	my $v = $self->_errorField($key);
	$desc{$field} = $v if defined $v;
    }
    return (%desc ? \%desc : ());
}

sub errorField {
    my ($self, $field) = @_;
    my $key = $error_field{$field};
    defined $key or Carp::croak("bad field name '$field'");
    $self->_errorField($key);
}

sub DESTROY {
    my $self = shift;
    $self->clear if $$self;
}

package Pg::PQ::Cancel;

sub DESTROY {
    my $self = shift;
    $self->freeCancel if $$self;
}

1;

__END__

=head1 NAME

Pg::PQ - Perl wrapper for PostgreSQL libpq

=head1 SYNOPSIS

  use Pg::PQ qw(:pgres_polling);

  my $dbc = Pg::PQ::Conn->new(dbname => 'test',
                              host => 'dbserver');

  $dbc->sendQuery("select * from foo");

  while (1) {
    $dbc->consumeInput;
    last unless $dbc->busy
    # do something else
    ...
  }

  my $res = $dbc->result;
  my @rows = $res->rows;

  print "query result:\n", Dumper \@rows;

=head1 DESCRIPTION

  *******************************************************************
  ***                                                             ***
  *** NOTE: This is a very early release that may contain lots of ***
  *** bugs. The API is not stable and may change between releases ***
  ***                                                             ***
  *******************************************************************

This module is a thin wrapper around PostgreSQL libpq C API.

Its main purpose is to let query a PostgreSQL database asynchronously
from inside common non-blocking frameworks as L<AnyEvent>, L<POE> or
even L<Coro>.

=head2 Pg::PQ::Conn class

These are the methods available from the class Pg::PQ::Conn:

=over 4

=item @defaults = Pg::PQ::Conn::defaults();

Returns a list of hashes describing the acceptable connection options.

=item $dbc = Pg::PQ::Conn->new($conninfo)

=item $dbc = Pg::PQ::Conn->new(%conninfo)

=item $dbc = Pg::PQ::Conn->new(\%conninfo)

X<new>I<(wraps PQconnectdb)>

This method creates a new Pg::PQ::Conn object and connects to the
database defined by the parameters given as a string (C<$conninfo>) or
as a set of key value pairs (C<%conninfo>).

For example:

  # parameters as an string:
  my $dbc = Pg::PQ::Conn->new("dbname=testdb user=jsmith passwd=jsmith11");

  # as key-value pairs:
  my $dbc = Pg::PQ::Conn->new(dbname => 'testdb',
                              user   => 'jsmith',
                              passwd => 'jsmith11');

The set of parameters accepted is as follows:

=over 4

lib/Pg/PQ.pm  view on Meta::CPAN


This is similar to L</sendQuery>, but the command to be executed is
specified by naming a previously-prepared statement, instead of giving
a query string. The function's parameters are handled identically to
L</execQueryPrepared>.

It will not work on 2.0-protocol connections.

=item $ok = $dbc->sendDescribePrepared($name)

Submits a request to obtain information about the specified prepared
statement, without waiting for completion.

This is an asynchronous version of L</describePrepared>: it returns 1
if it was able to dispatch the request, and 0 if not. After a
successful call, call L</result> to obtain the results.

It will not work on 2.0-protocol connections.

=item $ok = $dbc->sendDescribePortal($name)

Submits a request to obtain information about the specified portal,
without waiting for completion.

This is an asynchronous version of L</describePortal>: it returns 1 if
it was able to dispatch the request, and 0 if not. After a successful
call, call L</result> to obtain the results.

It will not work on 2.0-protocol connections.

=item $res = $dbc->result

I<(wraps PQgetResult)>

This method waits for the next result from a prior L</sendQuery>,
L</sendPrepare>, L</sendQueryPrepared>, L</sendDescribePrepare> or
L</sendDescribePortal> method call, and returns it. L</undef> is
returned when the command is complete and there will be no more
results.

C<result> must be called repeatedly until it returns C<undef>
indicating that the command is done (if called when no command is
active, C<result> will just return C<undef> at once).

Each non undefined result from C<result> should be processed using
the accessor methods for the Pg::PQ::Result class described below.

Note that C<result> will block only if a command is active and the
necessary response data has not yet been read by L</consumeInput>.

Using C<sendQuery> and C<result> solves one of L</exec>'s problems: if
a command string contains multiple SQL commands, the results of those
commands can be obtained individually.

This allows a simple form of overlapped processing, by the way: the
client can be handling the results of one command while the server is
still working on later queries in the same command string.

However, calling C<result> will still cause the client to block until the
server completes the next SQL command. This can be avoided by proper
use of the C<consumeInput> and L</busy> methods described next.

=item $ok = $dbc->consumeInput

If input is available from the server, consume it.

C<consumeInput> normally returns 1 indicating "no error", but returns
0 if there was some kind of trouble (in which case L</errorMessage> can
be consulted). Note that the result does not say whether any input
data was actually collected.

After calling C<consumeInput>, the application can check L</busy>
and/or L</notifies> to see if their state has changed.

C<consumeInput> can be called even if the application is not prepared
to deal with a result or notification just yet. The method will read
available data and save it in a buffer, thereby causing a C<select>
read-ready indication to go away.

=item $ok = $dbc->busy

Returns 1 if a command is busy, that is, L</result> would block waiting
for input. A 0 return indicates that C<result> can be called with
assurance of not blocking.

C<busy> will not itself attempt to read data from the server;
therefore L</consumeInput> must be invoked first, or the busy state
will never end.

=item $nb = $dbc->nonBlocking

=item $dbc->nonBlocking($bool)

This methods get and sets the non blocking status of the database connection.

=item $dbc->flush

Attempts to flush any queued output data to the server. Returns 0 if
successful (or if the send queue is empty), -1 if it failed for some
reason, or 1 if it was unable to send all the data in the send queue
yet (this case can only occur if the connection is nonblocking).

=item $dbc->notifies

Returns the name of the next notification from the list of unhandled
notification messages received from the server or undef if the list is
empty. See L</Asynchronous notification> below.

On list context besides the notification name, the pid of the
originating process and the payload are also returned. For instance:

  my ($name, $pid, $extra) = $dbc->notifies;

=item $esc = $dbc->escapeLiteral($literal)

C<escapeLiteral> escapes a string for use within an SQL command. This
is useful when inserting data values as literal constants in SQL
commands. Certain characters (such as quotes and backslashes) must be
escaped to prevent them from being interpreted specially by the SQL
parser.

The return string has all special characters replaced so that they can
be properly processed by the PostgreSQL string literal parser. The
single quotes that must surround PostgreSQL string literals are
included in the result string.

On error, C<escapeLiteral> returns C<undef> and a suitable message is
stored in the Pg::PQ::Conn object.

=item $esc = $conn->escapeIdentifier($identifier)

C<escapeIdentifier> escapes a string for use as an SQL identifier, such
as a table, column, or function name. This is useful when a
user-supplied identifier might contain special characters that would
otherwise not be interpreted as part of the identifier by the SQL
parser, or when the identifier might contain upper case characters
whose case should be preserved.

C<escapeIdentifier> returns a version of the str parameter escaped as
an SQL identifier. The return string has all special characters
replaced so that it will be properly processed as an SQL
identifier.

The return string will also be surrounded by double quotes.

On error, C<escapeIdentifier> returns C<undef> and a suitable message
is stored in the connection object.

lib/Pg/PQ.pm  view on Meta::CPAN

Connection OK; waiting to send.

=item CONNECTION_AWAITING_RESPONSE

Waiting for a response from the server.

=item CONNECTION_AUTH_OK

Received authentication; waiting for backend start-up to finish.

=item CONNECTION_SSL_STARTUP

Negotiating SSL encryption.

=item CONNECTION_SETENV

Negotiating environment-driven parameter settings.

=back

Note that, although these constants will remain (in order to maintain
compatibility), an application should never rely upon these occurring
in a particular order, or at all, or on the status always being one of
these documented values. An application might do something like this:


  given($dbc->status) {
      when (CONNECTION_STARTED) {
          say "Connecting...";
      }
      when (CONNECTION_MADE) {
          say "Connected to server...";
      }
      ...
      default {
          say "Connecting...";
      }
  }

The C<connect_timeout> connection parameter is ignored when using
C<start> and C<connectPoll>; it is the application's responsibility to
decide whether an excessive amount of time has elapsed. Otherwise,
C<start> followed by a C<connectPoll> loop is equivalent to
C<new>.

=head3 Non-blocking querying the database

A typical non-blocking application will have a main loop that
uses C<select> or C<poll> to wait for all the conditions that it must
respond to.

After some query is dispatched to the database using any of the
asynchronous send methods (C<sendQuery>, C<sendPrepare>,
C<sendQueryPrepared>, C<sendDescribePrepared> or
C<sendDescribePortal>) one of the conditions will be input available
from the server, which in terms of C<select> means readable data on
the file descriptor identified by C<socket>.

When the main loop detects input ready, it should call C<consumeInput>
to read the input. It can then call C<isBusy>, followed by C<result>
if C<busy> returns false (0).

It can also call C<notifies> to detect C<NOTIFY> messages (see Section
31.7 of the PostgreSQL documentation).

A client that uses C<sendQuery>/C<result> can also attempt to cancel a
command that is still being processed by the server (see Section 31.5
of the PostgreSQL documentation). But regardless of the return value
of C<cancel>, the application must continue with the normal
result-reading sequence using C<result>. A successful cancellation
will simply cause the command to terminate sooner than it would have
otherwise.

By using the functions described above, it is possible to avoid
blocking while waiting for input from the database server. However, it
is still possible that the application will block waiting to send
output to the server. This is relatively uncommon but can happen if
very long SQL commands or data values are sent (it is much more
probable if the application sends data via C<COPY IN>, however).

To prevent this possibility and achieve completely nonblocking
database operation, the nonblocking mode has to be activated for
the session using C<$dbc-E<gt>nonBlocking(1)>.

After sending any command or data on a nonblocking connection, call
C<flush>. If it returns 1, wait for the socket to be write-ready and
call it again; repeat until it returns 0. Once C<flush> returns 0,
wait for the socket to be read-ready and then read the response as
described above.

=head2 Asynchronous notifications

PostgreSQL offers asynchronous notification via the LISTEN and NOTIFY
commands. A client session registers its interest in a particular
notification channel with the LISTEN command (and can stop listening
with the UNLISTEN command). All sessions listening on a particular
channel will be notified asynchronously when a NOTIFY command with
that channel name is executed by any session. A "payload" string can
be passed to communicate additional data to the listeners.

libpq applications submit C<LISTEN>, C<UNLISTEN>, and C<NOTIFY>
commands as ordinary SQL commands. The arrival of C<NOTIFY> messages
can subsequently be detected by calling C<notifies>.

The method C<notifies> returns the next notification (Pg::PQ::Notify)
from a list of unhandled notification messages received from the
server. It returns undef if there are no pending notifications.

Once a notification is returned from C<notifies>, it is considered
handled and will be removed from the list of notifications.

C<notifies> does not actually read data from the server; it just
returns messages previously absorbed by another libpq function.

In prior releases of libpq, the only way to ensure timely receipt of
C<NOTIFY> messages was to constantly submit commands, even empty ones,
and then check C<notifies> after each C<exec>. While this still works,
it is deprecated as a waste of processing power.

A better way to check for C<NOTIFY> messages when you have no useful
commands to execute is to call C<consumeInput>, then check



( run in 0.673 second using v1.01-cache-2.11-cpan-5b529ec07f3 )