Database-Async
view release on metacpan or search on metacpan
lib/Database/Async.pm view on Meta::CPAN
In L<DBI>:
my $sth = $dbh->prepare(q{select * from something where id = ?});
for my $id (1, 2, 3) {
$sth->bind(0, $id, 'bigint');
$sth->execute;
while(my $row = $sth->fetchrow_hashref) {
print $row->{name} . "\n";
}
}
In L<Database::Async>:
my $sth = $db->prepare(q{select * from something where id = ?});
(Future::Utils::fmap_void {
my ($id) = @_;
$sth->bind(0, $id, 'bigint')
->then(sub { $sth->execute })
->then(sub {
$sth->row_hashrefs
->each(sub {
print $_->{name} . "\n";
})->completed
})
} foreach => [1, 2, 3 ])->get;
=cut
use mro;
no indirect;
use Future::AsyncAwait qw(:experimental);
use Syntax::Keyword::Try;
use URI;
use URI::db;
use Module::Load ();
use Scalar::Util qw(blessed);
use Database::Async::Engine;
use Database::Async::Pool;
use Database::Async::Query;
use Database::Async::StatementHandle;
use Database::Async::Transaction;
use Log::Any qw($log);
=head1 METHODS
=cut
=head2 transaction
Resolves to a L<Future> which will yield a L<Database::Async::Transaction>
instance once ready.
=cut
async sub transaction {
my ($self, @args) = @_;
Scalar::Util::weaken(
$self->{transactions}[@{$self->{transactions}}] =
my $txn = Database::Async::Transaction->new(
database => $self,
@args
)
);
await $txn->begin;
return $txn;
}
=head2 txn
Executes code within a transaction. This is meant as a shorter form of
the common idiom
$db->transaction
->then(sub {
my ($txn) = @_;
Future->call($code)
->then(sub {
$txn->commit
})->on_fail(sub {
$txn->rollback
});
})
The code must return a L<Future>, and the transaction will only be committed
if that L<Future> resolves cleanly.
Returns a L<Future> which resolves once the transaction is committed.
=cut
async sub txn {
my ($self, $code, @args) = @_;
my $txn = await $self->transaction;
try {
my @data = await Future->call(
$code => ($txn, @args)
);
await $txn->commit;
return @data;
} catch {
my $exception = $@;
try {
await $txn->rollback;
} catch {
$log->warnf("exception %s in rollback", $@);
}
die $exception;
}
}
=head1 METHODS - Internal
You're welcome to call these, but they're mostly intended
for internal usage, and the API B<may> change in future versions.
=cut
( run in 0.841 second using v1.01-cache-2.11-cpan-39bf76dae61 )