DBIx-Class
view release on metacpan or search on metacpan
lib/DBIx/Class/Manual/Cookbook.pod view on Meta::CPAN
=head1 NAME
DBIx::Class::Manual::Cookbook - Miscellaneous recipes
=head1 SEARCHING
=head2 Paged results
When you expect a large number of results, you can ask L<DBIx::Class> for a
paged resultset, which will fetch only a defined number of records at a time:
my $rs = $schema->resultset('Artist')->search(
undef,
{
page => 1, # page to return (defaults to 1)
rows => 10, # number of results per page
},
);
return $rs->all(); # all records for page 1
return $rs->page(2); # records for page 2
You can get a L<DBIx::Class::ResultSet::Pager> object for the resultset
(suitable for use in e.g. a template) using the C<pager> method:
return $rs->pager();
=head2 Complex WHERE clauses
Sometimes you need to formulate a query using specific operators:
my @albums = $schema->resultset('Album')->search({
artist => { 'like', '%Lamb%' },
title => { 'like', '%Fear of Fours%' },
});
This results in something like the following C<WHERE> clause:
WHERE artist LIKE ? AND title LIKE ?
And the following bind values for the placeholders: C<'%Lamb%'>, C<'%Fear of
Fours%'>.
Other queries might require slightly more complex logic:
my @albums = $schema->resultset('Album')->search({
-or => [
-and => [
artist => { 'like', '%Smashing Pumpkins%' },
title => 'Siamese Dream',
],
artist => 'Starchildren',
],
});
This results in the following C<WHERE> clause:
WHERE ( artist LIKE '%Smashing Pumpkins%' AND title = 'Siamese Dream' )
OR artist = 'Starchildren'
For more information on generating complex queries, see
L<SQL::Abstract::Classic/WHERE CLAUSES>.
=head2 Retrieve one and only one row from a resultset
Sometimes you need only the first "top" row of a resultset. While this
can be easily done with L<< $rs->first|DBIx::Class::ResultSet/first
>>, it is suboptimal, as a full blown cursor for the resultset will be
created and then immediately destroyed after fetching the first row
object. L<< $rs->single|DBIx::Class::ResultSet/single >> is designed
specifically for this case - it will grab the first returned result
without even instantiating a cursor.
Before replacing all your calls to C<first()> with C<single()> please observe the
following CAVEATS:
=over
=item *
While single() takes a search condition just like search() does, it does
_not_ accept search attributes. However one can always chain a single() to
a search():
my $top_cd = $cd_rs->search({}, { order_by => 'rating' })->single;
=item *
Since single() is the engine behind find(), it is designed to fetch a
( run in 2.323 seconds using v1.01-cache-2.11-cpan-63c85eba8c4 )