Re: Any more thoughts on the LIMIT/extra SQL issue?
[prev]
[thread]
[next]
[Date index for 2004/07/30]
Here's a quick patch which converts the current order_by functionality
to "handlers" as I suggested earlier. There are some commented out
lines where I was going to add a distinct_on handler until I realized
how difficult (I think) it is to get at the "SELECT ..." part of the
SQL due to the Ima::DBI closure. "DISTINCT ON" functionality is
something I use pretty regularly and have to add in as new search_*
methods normally. It would be nice to be able to add this
functionality as a plugin that works with regular searches.
This is meant just for discussion - I wouldn't suggest using this
code, though it does pass all the current tests. The current patch
croaks on unhandled $search_opts. There's stuff that could be added
to this such as more specific ordering (assign each handler an order
number?) if people think it's a good idea to go down this road.
Todd
--
Todd Holbrook
Systems Consultant
Simon Fraser University Library
Patch to Class/DBI.pm:
104a105
> __PACKAGE__->mk_classdata('__search_handlers');
1091,1092c1092,1100
< $frag .= " ORDER BY $search_opts->{order_by}"
< if $search_opts->{order_by};
---
>
> foreach my $handler (@{$class->__search_handlers}) {
> &$handler(\$frag, $search_opts);
> }
>
> if (scalar(keys(%{$search_opts}))) {
> $class->_croak("Not all search_opts were handled: ", join ',', keys(%{$search_opts}));
> }
>
1097a1106,1154
>
> sub append_search_handler {
> my ($class, $handler) = @_;
>
> my $handlers = $class->__search_handlers;
> push @$handlers, $handler;
> $class->__search_handlers($handlers);
>
> return $class;
> }
>
> sub prepend_search_handler {
> my ($class, $handler) = @_;
>
> my $handlers = $class->__search_handlers;
> unshift @$handlers, $handler;
> $class->__search_handlers($handlers);
>
> return $class;
> }
>
>
> sub _search_handler_order_by {
> my ($frag_ref, $search_opts) = @_;
>
> if ($search_opts->{order_by}) {
> $$frag_ref .= " ORDER BY $search_opts->{order_by}";
> delete $search_opts->{order_by};
> }
>
> return 1;
> }
>
> #sub _search_handler_distinct_on {
> # my ($frag_ref, $search_opts) = @_;
> #
> # if ($search_opts->{distinct_on}) {
> # my $distinct = "DISTINCT ON ($search_opts->{distinct_on}) ";
> # $$frag_ref =~ s/SELECT\s+/SELECT $distinct/;
> # delete $search_opts->{distinct_on};
> # }
> #
> # return 1;
> #}
>
> __PACKAGE__->append_search_handler(\&_search_handler_order_by);
> #__PACKAGE__->prepend_search_handler(\&_search_handler_distinct_on);
>
>