1 package DBIx::Class::ResultClass::HashRefInflator;
11 DBIx::Class::ResultClass::HashRefInflator
15 my $rs = $schema->resultset('CD');
17 $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
21 DBIx::Class is not built for speed: it's built for convenience and
22 ease of use. But sometimes you just need to get the data, and skip the
23 fancy objects. That is what this class provides.
25 There are two ways of using this class.
31 Specify C<< $rs->result_class >> on a specific resultset to affect only that
32 resultset (and any chained off of it); or
36 Specify C<< __PACKAGE__->result_class >> on your source object to force all
37 uses of that result source to be inflated to hash-refs - this approach is not
42 =head1 AUTOMATICALLY INFLATING COLUMN VALUES
44 So you want to skip the DBIx::Class object creation part, but you still want
45 all your data to be inflated according to the rules you defined in your table
46 classes. Setting the global variable
47 C<$DBIx::Class::ResultClass::HashRefInflator::inflate_data> to a true value
48 will instruct L<mk_hash> to interrogate the processed columns and apply any
49 inflation methods declared via L<DBIx::Class::InflateColumn/inflate_column>.
51 For increased speed the inflation method lookups are cached in
52 C<%DBIx::Class::ResultClass::HashRefInflator::inflator_cache>. Make sure to
53 reset this hash if you modify column inflators at run time.
59 Inflates the result and prefetched data into a hash-ref using L<mk_hash>.
64 my ($self, $source, $me, $prefetch) = @_;
66 my $hashref = mk_hash($me, $prefetch);
67 inflate_hash ($source->schema, $source->result_class, $hashref) if $inflate_data;
73 This does all the work of inflating the (pre)fetched data.
80 # Generally people use this to gain as much speed as possible. If a new mk_hash is
81 # implemented, it should be benchmarked using the maint/benchmark_hashrefinflator.pl
82 # script (in addition to passing all tests of course :). Additional instructions are
83 # provided in the script itself.
87 if (ref $_[0] eq 'ARRAY') { # multi relationship
88 return [ map { mk_hash (@$_) || () } (@_) ];
92 # the main hash could be an undef if we are processing a skipped-over join
93 $_[0] ? %{$_[0]} : (),
95 # the second arg is a hash of arrays for each prefetched relation
97 { $_ => mk_hash( @{$_[1]->{$_}} ) }
98 ( $_[1] ? (keys %{$_[1]}) : () )
101 # if there is at least one defined column consider the resultset real
102 # (and not an emtpy has_many rel containing one empty hashref)
103 for (values %$hash) {
104 return $hash if defined $_;
113 This walks through a hashref produced by L<mk_hash> and inflates any data
114 for which there is a registered inflator in the C<column_info>
119 my ($schema, $rc, $data) = @_;
121 foreach my $column (keys %{$data}) {
123 if (ref $data->{$column} eq 'HASH') {
124 inflate_hash ($schema, $schema->source ($rc)->related_class ($column), $data->{$column});
126 elsif (ref $data->{$column} eq 'ARRAY') {
127 foreach my $rel (@{$data->{$column}}) {
128 inflate_hash ($schema, $schema->source ($rc)->related_class ($column), $rel);
132 # "null is null is null"
133 next if not defined $data->{$column};
135 # cache the inflator coderef
136 unless (exists $inflator_cache{$rc}{$column}) {
137 $inflator_cache{$rc}{$column} = exists $schema->source ($rc)->_relationships->{$column}
138 ? undef # currently no way to inflate a column sharing a name with a rel
139 : $rc->column_info($column)->{_inflate_info}{inflate}
143 if ($inflator_cache{$rc}{$column}) {
144 $data->{$column} = $inflator_cache{$rc}{$column}->($data->{$column});
152 This will not work for relationships that have been prefetched. Consider the
155 my $artist = $artitsts_rs->search({}, {prefetch => 'cds' })->first;
157 my $cds = $artist->cds;
158 $cds->result_class('DBIx::Class::ResultClass::HashRefInflator');
159 my $first = $cds->first;
161 C<$first> will B<not> be a hashref, it will be a normal CD row since
162 HashRefInflator only affects resultsets at inflation time, and prefetch causes
163 relations to be inflated when the master C<$artist> row is inflated.