removed retarded global; if you want this feature, make it a bloody constructor argum...
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultClass / HashRefInflator.pm
CommitLineData
b0930c1e 1package DBIx::Class::ResultClass::HashRefInflator;
2
83304545 3use strict;
4use warnings;
5
137c657c 6=head1 NAME
7
8DBIx::Class::ResultClass::HashRefInflator
9
10=head1 SYNOPSIS
11
12 my $rs = $schema->resultset('CD');
13
14 $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
15
16=head1 DESCRIPTION
17
18DBIx::Class is not built for speed: it's built for convenience and
19ease of use. But sometimes you just need to get the data, and skip the
20fancy objects. That is what this class provides.
21
22There are two ways of using this class.
23
24=over
25
26=item *
27
28Specify C<< $rs->result_class >> on a specific resultset to affect only that
57dd9393 29resultset (and any chained off of it); or
137c657c 30
31=item *
32
33Specify C<< __PACKAGE__->result_class >> on your source object to force all
34uses of that result source to be inflated to hash-refs - this approach is not
57dd9393 35recommended.
137c657c 36
37=back
38
2328814a 39=head1 AUTOMATICALLY INFLATING COLUMN VALUES
40
41So you want to skip the DBIx::Class object creation part, but you still want
42all your data to be inflated according to the rules you defined in your table
43classes. Setting the global variable
44C<$DBIx::Class::ResultClass::HashRefInflator::inflate_data> to a true value
45will instruct L<mk_hash> to interrogate the processed columns and apply any
46inflation methods declared via L<DBIx::Class::InflateColumn/inflate_column>.
47
48For increased speed the inflation method lookups are cached in
49C<%DBIx::Class::ResultClass::HashRefInflator::inflator_cache>. Make sure to
50reset this hash if you modify column inflators at run time.
51
137c657c 52=head1 METHODS
53
54=head2 inflate_result
55
56Inflates the result and prefetched data into a hash-ref using L<mk_hash>.
57
58=cut
59
60sub inflate_result {
61 my ($self, $source, $me, $prefetch) = @_;
62
2328814a 63 my $hashref = mk_hash($me, $prefetch);
2328814a 64 return $hashref;
137c657c 65}
66
67=head2 mk_hash
68
69This does all the work of inflating the (pre)fetched data.
70
71=cut
b0930c1e 72
2328814a 73##############
74# NOTE
75#
76# Generally people use this to gain as much speed as possible. If a new mk_hash is
77# implemented, it should be benchmarked using the maint/benchmark_hashrefinflator.pl
78# script (in addition to passing all tests of course :). Additional instructions are
79# provided in the script itself.
80#
81
82sub mk_hash {
83 if (ref $_[0] eq 'ARRAY') { # multi relationship
84 return [ map { mk_hash (@$_) || () } (@_) ];
85 }
86 else {
87 my $hash = {
88 # the main hash could be an undef if we are processing a skipped-over join
89 $_[0] ? %{$_[0]} : (),
90
91 # the second arg is a hash of arrays for each prefetched relation
92 map
93 { $_ => mk_hash( @{$_[1]->{$_}} ) }
94 ( $_[1] ? (keys %{$_[1]}) : () )
95 };
96
97 # if there is at least one defined column consider the resultset real
98 # (and not an emtpy has_many rel containing one empty hashref)
99 for (values %$hash) {
100 return $hash if defined $_;
101 }
b0930c1e 102
2328814a 103 return undef;
104 }
105}
106
419ff184 107=head1 CAVEAT
108
109This will not work for relationships that have been prefetched. Consider the
110following:
111
112 my $artist = $artitsts_rs->search({}, {prefetch => 'cds' })->first;
113
114 my $cds = $artist->cds;
115 $cds->result_class('DBIx::Class::ResultClass::HashRefInflator');
116 my $first = $cds->first;
117
118C<$first> will B<not> be a hashref, it will be a normal CD row since
119HashRefInflator only affects resultsets at inflation time, and prefetch causes
120relations to be inflated when the master C<$artist> row is inflated.
121
122=cut
123
b0930c1e 1241;