[Dbix-class] Restricting Result Sets

Jonathan Rockway jon at jrock.us
Fri Nov 14 21:44:15 GMT 2008


* On Sat, Nov 08 2008, Ovid wrote:
> So far, no one has been able to answer a very simple question: is it
> possible to build one resultset from another?  Eden came close, but
> this is not a constraint which can be expressed via SQL.  The filter
> criteria may have nothing to do with the database.  We've found a
> frustrating work around, but frankly, it's a bit odd that this very
> simple question seems to be unanswerable.

I think the answer is "no", but nobody wants to say that for sure.

The ResultSet is not really a set of results, it's just a way of
building SQL queries incrementally.  I think what you are asking for is
impossible without DBIC becoming a query engine.  Normally, when you
say:

  $rs->filter_foos->filter_bars,

you think of it as being "get everything, then filter out foos, then
filter out bars"... but DBIC expresses this as a single SQL statement.
You say what you logically want, it figures out how to get it
efficiently.

What you want to do (I think), is have a SQL statement execute, filter
that in Perl, and then use the results to build another SQL statement.
I don't think DBIC will let you do that -- it wants to see some
resultsets and generate one query.

However... it may be possible to force a resultset to do a query (when
"chained"), examine and filter the results, then create a new resultset
that is limited to the IDs that made it through your filter.  Elegant it
ain't... but you might be able to keep the abstraction and not lose too
much performance.

  sub filter_in_perl {
      my ($self) = @_; # self is a resultset
      my @ids = map { $_->id } grep { condition } $self->all;
      return $self->new( ..., { id => { -in => [ @ids ] } } );
  }

I haven't worked out all the details in my head yet... but it might
work.  I will think about it some more.

Regards,
Jonathan Rockway

--
print just => another => perl => hacker => if $,=$"



More information about the DBIx-Class mailing list