[Dbix-class] How to build a "good" object with deep nested prefetched rows from raw data?

Peter Rabbitson rabbit+dbic at rabbit.us
Thu May 2 10:57:30 GMT 2013


On Thu, May 02, 2013 at 01:39:24PM +0400, Dmitry L. wrote:
>
> QUESTION
> How can I convert raw data, which could be returned by calling
> category_descendants($id), to a "good" DBIx::Class object?
> I want to call category_descendants($id), and then I want to use something
> like this:
> $rs->first->subcategories->first->subcategories->first->...->title
> 

This is something I pondered while the 0.08250 work was ongoing, but
decided to leave it out so I end up shipping something ;)
Also this is a high-enough level that it can be tried in a ResultSet
subclass bfore deciding how/whether to add it to DBIC core.

Currently we have two ways of "prepared result injection" - there is
$rs->set_cache (which deals with "ready objects") and there is
DBIx::Class::Cursor::Cached which is Storage-wide. What you need is
something in the middle - a way to say "Here is an $rs with such and
such result mangling attribute set (collapse, etc), execute it as usual
but instead of getting the data via SQL, get it from X.

Currently these are the points where data is actually retrieved/cursor is reset:
https://github.com/dbsrgits/dbix-class/blob/master/lib/DBIx/Class/ResultSet.pm#L1081
https://github.com/dbsrgits/dbix-class/blob/master/lib/DBIx/Class/ResultSet.pm#L1313
https://github.com/dbsrgits/dbix-class/blob/master/lib/DBIx/Class/ResultSet.pm#L1336
https://github.com/dbsrgits/dbix-class/blob/master/lib/DBIx/Class/ResultSet.pm#L1346
https://github.com/dbsrgits/dbix-class/blob/master/lib/DBIx/Class/ResultSet.pm#L1481
https://github.com/dbsrgits/dbix-class/blob/master/lib/DBIx/Class/ResultSet.pm#L1825
https://github.com/dbsrgits/dbix-class/blob/master/lib/DBIx/Class/ResultSet.pm#L1855

As you can see *everything* is located in ResultSet.pm, hence why you 
should be able to trivially implement and test the following in a subclass:

*) Allow {cursor} to be set (either via cursor() or make a separate setter)
*) Make it accept a coderef
*) Teach all()/next()/single() to pre-populate {_stashed_rows}
*) Make _construct_results() aware of this somehow (handwave)
*) Profit

Depending on how clean/unclean this ends up being - we can adjust the DBIC
internals. The point is that someone has to experimenwt ith this before it
becomes reality.

Hope this helps
Cheers



More information about the DBIx-Class mailing list