EV::Pg
Asynchronous PostgreSQL client for Perl using libpq and the EV event loop.
Features
- Non-blocking queries via libpq async API
- Parameterized queries and prepared statements
- Pipeline mode for batched queries
- Single-row mode, chunked rows (libpq >= 17)
- COPY IN/OUT
- LISTEN/NOTIFY
- Cancel (sync and async, libpq >= 17)
- Structured error fields and result metadata
- Protocol tracing
- Connection introspection and reset
- Notice handling
Synopsis
use v5.10;
use EV;
use EV::Pg;
my $pg = EV::Pg->new(
conninfo => 'dbname=mydb',
on_error => sub { die "PG error: $_[0]\n" },
);
$pg->on_connect(sub {
$pg->query("select 1, 'hello'", sub {
my ($rows, $err) = @_;
die $err if $err;
say $rows->[0][1]; # hello
EV::break;
});
});
EV::run;
Parameterized queries
$pg->query_params(
'select $1::int + $2::int',
[10, 20],
sub {
my ($rows, $err) = @_;
say $rows->[0][0]; # 30
},
);
Prepared statements
$pg->prepare('stmt', 'select $1::int', sub {
$pg->query_prepared('stmt', [42], sub {
my ($rows, $err) = @_;
say $rows->[0][0]; # 42
});
});
Pipeline mode
use EV::Pg qw(:pipeline);
$pg->enter_pipeline;
for my $i (0 .. 999) {
$pg->query_params('select $1::int', [$i], sub { ... });
}
$pg->pipeline_sync(sub {
$pg->exit_pipeline;
});
$pg->send_flush_request;
Callback convention
All query callbacks receive ($result) on success, (undef, $error) on error:
- SELECT:
(\@rows)where each row is an arrayref - INSERT/UPDATE/DELETE:
($cmd_tuples) - Describe:
(\%meta)with keysnfields,nparams;fieldsandparamtypeswhen non-zero - Error:
(undef, $error_message) - COPY:
("COPY_IN"),("COPY_OUT"), or("COPY_BOTH") - Pipeline sync:
(1)
Installation
Requires Alien::libpq and EV. Alien::libpq will use the system libpq if available, or build it from source.
cpanm EV::Pg
Or manually:
perl Makefile.PL
make
make test
make install
Benchmark
500k queries over Unix socket, PostgreSQL 18, libpq 18:
| Workload | EV::Pg sequential | EV::Pg pipeline | DBD::Pg sync | DBD::Pg async+EV | |----------|------------------:|----------------:|-------------:|-----------------:| | SELECT | 73,109 q/s | 124,092 q/s | 56,496 q/s | 48,744 q/s | | INSERT | 58,534 q/s | 84,467 q/s | 39,068 q/s | 41,559 q/s | | UPSERT | 26,342 q/s | 34,223 q/s | 28,134 q/s | 27,155 q/s |
EV::Pg sequential uses prepared statements (parse once, bind+execute per call).
Pipeline mode batches queries with pipeline_sync every 1000 queries.
License
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.