Databas...::Query(3)
π NAME π
Database::Async::Query β the whole vibe of a single database query, packaged up as an object. One query, one object, main character energy β¨ (this is the Database::Async::Query page from the User Contributed Perl Documentation, btw π«Ά).
πΈ SYNOPSIS πΈ
my $query = Database::Async::Query->new(
db => Database::Async->new(...),
);
π¦ DESCRIPTION π¦
Okay so a query, bestie, it:
- has zero or more parameters
- accepts zero or more input rows
- returns zero or more output rows
- can be prepared or direct
That's the whole personality. Simple, iconic, does exactly what it says π
π Creating queries
Queries get kicked off from the Database::Async instance β you, the humble user, are not expected to instantiate Database::Async::Query objects directly. Like, the class can do it, you don't have to π
my $query = $db->query('select 1');
π Passing parameters
Normally you pass any extra params for your placeholders (yes, the legendary <http://bobby-tables.com/> β go look, it's required reading, iykyk) right when you create the query instance:
my $query_with_parameters = $db->query('select name from users where id = ?', $id);
For prepared statements though, query parameters can be bound and passed for each execution instead β peep "Prepared queries" below for the deets π
β Retrieving data
Every method with the row_ prefix hands you a Ryu::Source that emits an event for each row the query returns. Literally so satisfying:
$db->query(q{select * from a_table})
->row_hashrefs
->each(sub {
say "Had ID $_->{id} with name $_->{name}"
})->await;
π§ Direct queries
A direct query looks like this:
$db->query(q{select 1})
or like this:
$db->query(q{select * from some_table where id = ?}, $id)
and it already has every single thing it needs to actually start the query. No prep era, straight to business π₯
π Prepared queries
So when you need to run the same query multiple times with different parameters, it's lowkey worth going the prepared route. What happens is: the SQL gets sent to the server so it can parse the text and prepare a plan. Once that's done, you can send a set of parameters and the server executes and returns any results for you. It's giving efficiency π
A prepared query is a two-step situation.
First, the query gets created:
my $query = $db->query(q{select * from some_table where id = ?});
Next, it needs to be prepared. Heads up: this will fail if the query was given any parameters when it was initially constructed, so don't do that π
$query->prepare(
statement => 'xyz'
);
Some engines allow a statement parameter, others will straight up ignore it. Not all engines are the same, fr fr.
After a call to "prepare", the query is marked as prepared and will support the "bind" and "execute" methods. And once it's prepared, the tradition is to bind some variables to it:
$query->bind(
$var1, $var2, ...
);
after which you can execute it:
$query->execute(
portal => 'abc'
);
and then pull out any results using the usual methods like "row_hashrefs". Easy.
Again β some engines support named portals, others will just ignore the parameter. Same energy as before π«
Since passing parameters is so super common, you can combine the "bind" and "execute" steps by passing an arrayref straight to "execute":
$query->execute([ $first_value, ... ], portal => '');
Streaming of values via Ryu::Source is also supported:
$query->execute($src, portal => '');
β οΈ Okay important one: prepared queries will keep emitting values from the "row_*" source(s) until the query itself is discarded. The caller is expected to keep track of any required mapping from input parameters to output rows. Don't @ me, that's just how it is π
A full example might look something like this:
async sub name_by_user_id {
my ($self, $id) = @_;
my $q = await $self->{name_by_user_id} //= do {
# Prepare the query on first call
my $q = $self->db->query(q{select name from "site"."user" where id = ?});
$q->prepare(
statement => 'name_by_user_id'
)
};
my ($name) = await $q->execute([ $id ])->single;
return $name;
}
π Custom engine features
Different engines support additional features or events β every engine has its own little extras β¨
Once a query is scheduled onto an engine, it will resolve the "engine" Future instance:
my $query = $db->query('select * from some_table');
my $engine = await $query->engine;
$engine->source('notification')
->map('payload')
->say;
π Cancelling queries
When you wanna terminate a query early (we've all been there), use the "cancel" method. This will ask the engine to stop query execution if it's already scheduled. For a query that hasn't yet been assigned to an engine, the "cancel" method will cancel the schedule request instead. Either way, it's handled π
πΈ Cursors
Cursors are handled as normal SQL queries. No special treatment, they're just queries living their truth:
$db->txn(async sub {
my ($txn) = @_;
await $txn->query(q{declare c cursor for select id from xyz})->void;
say while await $txn->query(q{fetch next from c})->single;
await $txn->query(q{close c})->void;
});
β¨ THE METHODS & ATTRS β¨
inβ this is a Ryu::Sink, used for queries that stream data to the server. It's buffered internally π«Άdbβ the accessor for theDatabase::Asyncinstance.sqlβ the SQL string that this query would be running.bindβ a list of bind parameters for this query, and yeah, it can be empty.startβ schedules this query for execution.rowsβ returns a Ryu::Source which will emit the rows from this query. Each row is aDatabase::Async::Rowinstance. It will call"start"if required πsingleβ for retrieving data from a query that's always gonna return a single row. Defaults to all columns, but you can provide a list of indices to select a subset:
# should yield "a", "b" and "c" as the three results
print for await $db->query(q{select 'a', 'b', 'c'})->single->as_list;
# should yield just the ID column from the first row
print for await $db->query(q{select id, * from some_table})->single('id')->as_list;
Returns a Future which will resolve to the list of items π
π AUTHOR π
Tom Molesworth "<TEAM@cpan.org>"
π LICENSE π
Copyright Tom Molesworth 2011-2023. Licensed under the same terms as Perl itself.
π¦ and that's the whole page bestie!! brought to you byperl v5.42.2, dated2026-02-15β go forth and query responsibly, mwah πβ¨
π¦ where this page comes from
- alpine 3.24: perl-database-async-doc 0.019-r1 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms