DBD-KB
view release on metacpan or search on metacpan
=item B<pg_ready>
This method can be called as a database handle method or (for convenience) as a statement handle method. Both simply
see if a previously issued asynchronous query has completed yet. It returns true if the statement has finished, in which
case you should then call the L</pg_result> method. Calls to C<pg_ready()> should only be used when you have other
things to do while the query is running. If you simply want to wait until the query is done, do not call pg_ready()
over and over, but simply call the pg_result() method.
my $time = 0;
while (!$dbh->pg_ready) {
print "Query is still running. Seconds: $time\n";
$time++;
sleep 1;
}
$result = $dbh->pg_result;
=item B<pg_result>
This database handle method returns the results of a previously issued asynchronous query. If the query is still
running, this method will wait until it has finished. The result returned is the number of rows: the same thing
that would have been returned by the asynchronous L</do> or L</execute> if it had been called without an asynchronous flag.
$result = $dbh->pg_result;
=back
=head3 Asynchronous Examples
Here are some working examples of asynchronous queries. Note that we'll use the B<pg_sleep> function to emulate a
long-running query.
use strict;
use warnings;
use Time::HiRes 'sleep';
use DBD::KB ':async';
my $dbh = DBI->connect('dbi:KB:dbname=postgres', 'postgres', '', {AutoCommit=>0,RaiseError=>1});
## Kick off a long running query on the first database:
my $sth = $dbh->prepare("SELECT pg_sleep(?)", {pg_async => PG_ASYNC});
$sth->execute(5);
## While that is running, do some other things
print "Your query is processing. Thanks for waiting\n";
check_on_the_kids(); ## Expensive sub, takes at least three seconds.
while (!$dbh->pg_ready) {
check_on_the_kids();
## If the above function returns quickly for some reason, we add a small sleep
sleep 0.1;
}
print "The query has finished. Gathering results\n";
my $result = $sth->pg_result;
print "Result: $result\n";
my $info = $sth->fetchall_arrayref();
Without asynchronous queries, the above script would take about 8 seconds to run: five seconds waiting
for the execute to finish, then three for the check_on_the_kids() function to return. With asynchronous
queries, the script takes about 6 seconds to run, and gets in two iterations of check_on_the_kids in
the process.
Here's an example showing the ability to cancel a long-running query. Imagine two slave databases in
different geographic locations over a slow network. You need information as quickly as possible, so
you query both at once. When you get an answer, you tell the other one to stop working on your query,
as you don't need it anymore.
use strict;
use warnings;
use Time::HiRes 'sleep';
use DBD::KB ':async';
my $dbhslave1 = DBI->connect('dbi:KB:dbname=postgres;host=slave1', 'postgres', '', {AutoCommit=>0,RaiseError=>1});
my $dbhslave2 = DBI->connect('dbi:KB:dbname=postgres;host=slave2', 'postgres', '', {AutoCommit=>0,RaiseError=>1});
$SQL = "SELECT count(*) FROM largetable WHERE flavor='blueberry'";
my $sth1 = $dbhslave1->prepare($SQL, {pg_async => PG_ASYNC});
my $sth2 = $dbhslave2->prepare($SQL, {pg_async => PG_ASYNC});
$sth1->execute();
$sth2->execute();
my $winner;
while (!defined $winner) {
if ($sth1->pg_ready) {
$winner = 1;
}
elsif ($sth2->pg_ready) {
$winner = 2;
}
Time::HiRes::sleep 0.05;
}
my $count;
if ($winner == 1) {
$sth2->pg_cancel();
$sth1->pg_result();
$count = $sth1->fetchall_arrayref()->[0][0];
}
else {
$sth1->pg_cancel();
$sth2->pg_result();
$count = $sth2->fetchall_arrayref()->[0][0];
}
=head2 Array support
DBD::KB allows arrays (as arrayrefs) to be passed in to both
the L</quote> and the L</execute> methods. In both cases, the array is
flattened into a string representing a Postgres array.
When fetching rows from a table that contains a column with an
array type, the result will be passed back to your script as an arrayref.
To turn off the automatic parsing of returned arrays into arrayrefs,
you can set the attribute L<pg_expand_array|/pg_expand_array (boolean)>, which is true by default.
$dbh->{pg_expand_array} = 0;
( run in 0.946 second using v1.01-cache-2.11-cpan-71847e10f99 )