Is it possible to get a plain arrayrefs as rows of a DBIx::Class search?
I can do this
my $rs = $db->resultset("SomeTable")->search({});
my $results = $dbh->selectall_arrayref("select * from " . $rs->as_query->$*->[0]);
and it works, but it looks barbarous.
The benefit is I have the columns in order, and it's column-name independent, which in case of a crosstab is nice.
Are there any cleaner approaches? and no, the HashRefInflator result class (or any hash-based approach) won't work, as I have (without some other trick I am not aware of) no guarantee of column order - as they are hashes, no guarantee of key ordering.
I recommend using a new method in your
Resultclass here, rather than one in yourResultSetclass. I say this for reasons of scalability: you probably don't want to inflate your entire resultset all at once because that would only be feasible for very tiny resultsets that all fit into memory at once.For example, let's assume there's an
as_arrayrefresult class method that does the thing you're asking for and that$some_resultsetholds your resultset object. Then if you really wanted to have all those arrayrefs at once, you could simply do:Or
More likely you will step through your resultset one result at a time, and produce an arrayref of values per result object one at a time as you go.
For example, let's assume there's an
as_arrayrefmethod that does the thing you're asking for and that$some_resultsetholds your resultset object.That still won't scale for large resultsets, but you can always "page" the resultset so that it does so:
That version now scales no matter how large your resultset.
So what does your
as_arrayrefresult class method look like?Remember that the
get_columnsresult class method returns a pairlist of key–value pairs. That makes something likeas_hashrefas simple as:STRONG WARNING! That's unsafe as written because it doesn't croak when invoked with incorrect arguments. So you should write that as:
Or, if you're using subroutine signatures, then:
or even just
Given that the
columnsresult class method returns a list of that result object's column names in order, your newas_arrayrefresult class method could just be either this withcroak:Or this with signatures:
One thing I've done here is assume that you want the literal column values from your db, not objects automatically inflated by DBIx. That's not necessarily a good assumption, but even if that's what you want, we could make it clearer by choosing better method names.
So let's fix the name by letting you have an explicitly named
as_deflated_arrayrefmethod on the one hand or anas_inflated_arrayrefmethod on the other. That removes all question of inflation that method names likeas_hashreforas_arrayrefwould leave unresolved in the eyes of the reader.That means you'd have some pair like:
Which leads to methods like these for the deflated version:
And these for the inflated versions:
I'm sure you get the general idea here, so you should now be able to adapt these various approaches to your own code.