Class::DBI::Plugin::DeepAbstractSearchPager - paged queries for CDBI::Plugin::DeepAbstractSearch
Adds a deep_pager method to your class that can query using SQL::Abstract where clauses with joined table fields as described by Class::DBI::Plugin::DeepAbstractSearch, and limit the number of rows returned to a specific subset.
Class::DBI::Plugin::DeepAbstractSearch
package CD; use base 'Class::DBI'; use Class::DBI::Plugin::DeepAbstractSearch; # pager needs this use Class::DBI::Plugin::DeepAbstractSearchPager; # or to use a different syntax # use Class::DBI::Plugin::Pager::RowsTo; __PACKAGE__->set_db(...); # in a nearby piece of code... use CD; # see SQL::Abstract for how to specify the query my $where = { 'artist.name' => { -like => '%Elvis%' } }; my $order_by => 'artist.name, title'; # bit by bit: my $pager = CD->deep_pager; $pager->per_page( 10 ); $pager->page( 3 ); $pager->where( $where ); $pager->order_by( $order_by ); $pager->set_syntax( 'RowsTo' ); my @cds = $pager->deep_search_where; # or all at once my $pager = CD->deep_pager( $where, $order_by, 10, 3 ); my @cds = $pager->deep_search_where; # or my $pager = CD->deep_pager; my @cds = $pager->deep_search_where( $where, $order_by, 10, 3 ); # $pager isa Data::Page # @cds contains the CDs just for the current page
Loads the deep_pager method into the CDBI app.
deep_pager
Also accepts named arguments:
where => $where, abstract_attr => $attr, order_by => $order_by, per_page => $per_page, page => $page, syntax => $syntax
Returns a pager object. This subclasses Data::Page.
Note that for positional arguments, $abstract_attr can only be passed if preceded by a $where argument.
$abstract_attr
$where
$abstract_attr can contain the $order_by setting (just as in SQL::Abstract).
$order_by
The named arguments all exist as get/set methods.
A hashref specifying the query. See Class::DBI::Plugin::DeepAbstractSearch.
A hashref specifying extra options to be passed through to the Class::DBI::Plugin::DeepAbstractSearch constructor.
Single column name, string of column names or array ref of column names for the ORDER BY clause. Defaults to the primary key(s) if not set.
Number of results per page.
The pager will retrieve results just for this page. Defaults to 1.
Change the way the 'limit' clause is constructed. See set_syntax. Default is LimitOffset.
set_syntax
LimitOffset
Retrieves results from the pager. Accepts the same arguments as the pager method.
pager
Changes the syntax used to generate the limit or other phrase that restricts the results set to the required page.
limit
The syntax is implemented as a method called on the pager, which can be queried to provide the $rows and $offset parameters (see the subclasses included in this distribution).
$rows
$offset
A class with a make_limit method.
make_limit
Name of a class in the Class::DBI::Plugin::Pager:: namespace, which has a make_limit method.
Class::DBI::Plugin::Pager::
Will be called as a method on the pager object, so receives the pager as its argument.
Called without args, will default to LimitOffset, which causes Class::DBI::Plugin::Pager::LimitOffset to be used.
This is called automatically when you call pager, and attempts to set the syntax automatically.
If you are using a subclass of the pager, this method will not be called.
Will die if using Oracle or DB2, since there is no simple syntax for limiting the results set. DB2 has a FETCH keyword, but that seems to apply to a cursor and I don't know if there is a cursor available to the pager. There should probably be others to add to the unsupported list.
die
FETCH
Supports the following drivers:
DRIVER CDBI::P::Pager subclass my %supported = ( pg => 'LimitOffset', mysql => 'LimitOffset', # older versions need LimitXY sqlite => 'LimitOffset', # or LimitYX interbase => 'RowsTo', firebird => 'RowsTo', );
Older versions of MySQL should use the LimitXY syntax. You'll need to set it manually, either by use CDBI::P::Pager::LimitXY, or by passing syntax => 'LimitXY' to a method call, or call set_syntax directly.
use CDBI::P::Pager::LimitXY
syntax => 'LimitXY'
Any driver not in the supported or unsupported lists defaults to LimitOffset.
Any additions to the supported and unsupported lists gratefully received.
The 'limit' syntax can be set by using a subclass, e.g.
use Class::DBI::Plugin::Pager::RowsTo;
instead of setting at runtime. A subclass looks like this:
package Class::DBI::Plugin::Pager::RowsTo; use base 'Class::DBI::Plugin::DeepAbstractSearchPager'; sub make_limit { my ( $self ) = @_; my $offset = $self->skipped; my $rows = $self->entries_per_page; my $last = $rows + $offset; return "ROWS $offset TO $last"; } 1;
You can omit the use base and switch syntax by calling $pager->set_syntax( 'RowsTo' ). Or you can leave in the use base and still say $pager->set_syntax( 'RowsTo' ), because in this case the class is required and the import in the base class doesn't get called. Or something. At any rate, It Works.
use base
$pager->set_syntax( 'RowsTo' )
require
import
The subclasses implement the following LIMIT syntaxes:
LIMIT $rows OFFSET $offset
This is the default if your driver is not in the list of known drivers.
This should work for PostgreSQL, more recent MySQL, SQLite, and maybe some others.
LIMIT $offset, $rows
Older versions of MySQL.
LIMIT $rows, $offset
SQLite.
ROWS $offset TO $offset + $rows
InterBase, also FireBird, maybe others?
I've only used this on SQLite and PostgreSQL. Reports of this thing working (or not) elsewhere would be useful.
It should be possible to use set_sql to build the complex queries required by some databases to emulate LIMIT (see notes in source).
set_sql
This class can't implement the subselect mechanism required by some databases to emulate the LIMIT phrase, because it only has access to the WHERE clause, not the whole SQL statement. At the moment.
Each query issues two requests to the database - the first to count the entire result set, the second to retrieve the required subset of results. If your tables are small it may be quicker to use Class::DBI::Pager.
The order_by clause means the database has to retrieve (internally) and sort the entire results set, before chopping out the requested subset. It's probably a good idea to have an index on the column(s) used to order the results. For huge tables, this approach to paging may be too inefficient.
order_by
Data::Page, Class::DBI::Plugin::DeepAbstractSearch, Class::Accessor, Class::Data::Inheritable, Carp.
Class::DBI::Plugin::Pager is the code from which this module was derived. Use it when your search doesn't require fields from related tables.
Class::DBI::Pager does a similar job, but retrieves the entire results set into memory before chopping out the page you want.
Please report all bugs via the CPAN Request Tracker at http://rt.cpan.org/NoAuth/Bugs.html?Dist=Class-DBI-Plugin-DeepAbstractSearchPager.
Copyright 2005 by Stepan Riha. Based on Class::DBI::Plugin::Pager by David Baird.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Stepan Riha, sriha@cpan.net
sriha@cpan.net
To install Class::DBI::Plugin::DeepAbstractSearchPager, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Class::DBI::Plugin::DeepAbstractSearchPager
CPAN shell
perl -MCPAN -e shell install Class::DBI::Plugin::DeepAbstractSearchPager
For more information on module installation, please visit the detailed CPAN module installation guide.