Profile of DBIx/Class/ResultSetColumn.pm

← Index
NYTProf Performance Profile «block view•line view•sub view»
For xt/tapper-mcp-scheduler-with-db-longrun.t
Run on Tue May 22 17:18:39 2012
Reported on Tue May 22 17:23:02 2012

Filename | /2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/DBIx/Class/ResultSetColumn.pm
Statements | Executed 56874 statements in 225ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1954 | 1 | 1 | 174ms | 998ms | DBIx::Class::ResultSetColumn::::newDBIx::Class::ResultSetColumn::new
1954 | 2 | 2 | 51.5ms | 3.63s | DBIx::Class::ResultSetColumn::::nextDBIx::Class::ResultSetColumn::next
1954 | 1 | 1 | 16.6ms | 566ms | DBIx::Class::ResultSetColumn::::_resultsetDBIx::Class::ResultSetColumn::_resultset
9961 | 1 | 1 | 4.45ms | 4.45ms | DBIx::Class::ResultSetColumn::::CORE:matchDBIx::Class::ResultSetColumn::CORE:match (opcode)
1 | 1 | 1 | 12µs | 14µs | DBIx::Class::ResultSetColumn::::BEGIN@3DBIx::Class::ResultSetColumn::BEGIN@3
1 | 1 | 1 | 6µs | 14µs | DBIx::Class::ResultSetColumn::::BEGIN@4DBIx::Class::ResultSetColumn::BEGIN@4
1 | 1 | 1 | 6µs | 64µs | DBIx::Class::ResultSetColumn::::BEGIN@6DBIx::Class::ResultSetColumn::BEGIN@6
1 | 1 | 1 | 5µs | 50µs | DBIx::Class::ResultSetColumn::::BEGIN@7DBIx::Class::ResultSetColumn::BEGIN@7
1 | 1 | 1 | 4µs | 4µs | DBIx::Class::ResultSetColumn::::BEGIN@11DBIx::Class::ResultSetColumn::BEGIN@11
1 | 1 | 1 | 4µs | 4µs | DBIx::Class::ResultSetColumn::::BEGIN@8DBIx::Class::ResultSetColumn::BEGIN@8
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::__ANON__[:57]DBIx::Class::ResultSetColumn::__ANON__[:57]
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::allDBIx::Class::ResultSetColumn::all
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::as_queryDBIx::Class::ResultSetColumn::as_query
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::firstDBIx::Class::ResultSetColumn::first
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::funcDBIx::Class::ResultSetColumn::func
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::func_rsDBIx::Class::ResultSetColumn::func_rs
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::maxDBIx::Class::ResultSetColumn::max
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::max_rsDBIx::Class::ResultSetColumn::max_rs
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::minDBIx::Class::ResultSetColumn::min
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::min_rsDBIx::Class::ResultSetColumn::min_rs
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::resetDBIx::Class::ResultSetColumn::reset
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::singleDBIx::Class::ResultSetColumn::single
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::sumDBIx::Class::ResultSetColumn::sum
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::sum_rsDBIx::Class::ResultSetColumn::sum_rs
0 | 0 | 0 | 0s | 0s | DBIx::Class::ResultSetColumn::::throw_exceptionDBIx::Class::ResultSetColumn::throw_exception

Call graph for these subroutines as a Graphviz dot language file.

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | package DBIx::Class::ResultSetColumn;
2 |  |  |  |  |
3 | 3 | 17µs | 2 | 15µs | # spent 14µs (12+2) within DBIx::Class::ResultSetColumn::BEGIN@3 which was called: # once (12µs+2µs) by DBIx::Class::ResultSet::BEGIN@8 at line 3 use strict; # spent 14µs making 1 call to DBIx::Class::ResultSetColumn::BEGIN@3 # spent 2µs making 1 call to strict::import
4 | 3 | 18µs | 2 | 22µs | # spent 14µs (6+8) within DBIx::Class::ResultSetColumn::BEGIN@4 which was called: # once (6µs+8µs) by DBIx::Class::ResultSet::BEGIN@8 at line 4 use warnings; # spent 14µs making 1 call to DBIx::Class::ResultSetColumn::BEGIN@4 # spent 8µs making 1 call to warnings::import
5 |  |  |  |  |
6 | 3 | 18µs | 2 | 122µs | # spent 64µs (6+58) within DBIx::Class::ResultSetColumn::BEGIN@6 which was called: # once (6µs+58µs) by DBIx::Class::ResultSet::BEGIN@8 at line 6 use base 'DBIx::Class'; # spent 64µs making 1 call to DBIx::Class::ResultSetColumn::BEGIN@6 # spent 58µs making 1 call to base::import
7 | 3 | 18µs | 2 | 95µs | # spent 50µs (5+45) within DBIx::Class::ResultSetColumn::BEGIN@7 which was called: # once (5µs+45µs) by DBIx::Class::ResultSet::BEGIN@8 at line 7 use DBIx::Class::Carp; # spent 50µs making 1 call to DBIx::Class::ResultSetColumn::BEGIN@7 # spent 45µs making 1 call to DBIx::Class::Carp::import
8 | 3 | 17µs | 1 | 4µs | # spent 4µs within DBIx::Class::ResultSetColumn::BEGIN@8 which was called: # once (4µs+0s) by DBIx::Class::ResultSet::BEGIN@8 at line 8 use DBIx::Class::Exception; # spent 4µs making 1 call to DBIx::Class::ResultSetColumn::BEGIN@8
9 |  |  |  |  |
10 |  |  |  |  | # not importing first() as it will clash with our own method
11 | 3 | 867µs | 1 | 4µs | # spent 4µs within DBIx::Class::ResultSetColumn::BEGIN@11 which was called: # once (4µs+0s) by DBIx::Class::ResultSet::BEGIN@8 at line 11 use List::Util (); # spent 4µs making 1 call to DBIx::Class::ResultSetColumn::BEGIN@11
12 |  |  |  |  |
13 |  |  |  |  | =head1 NAME
14 |  |  |  |  |
15 |  |  |  |  | DBIx::Class::ResultSetColumn - helpful methods for messing
16 |  |  |  |  | with a single column of the resultset
17 |  |  |  |  |
18 |  |  |  |  | =head1 SYNOPSIS
19 |  |  |  |  |
20 |  |  |  |  | $rs = $schema->resultset('CD')->search({ artist => 'Tool' });
21 |  |  |  |  | $rs_column = $rs->get_column('year');
22 |  |  |  |  | $max_year = $rs_column->max; #returns latest year
23 |  |  |  |  |
24 |  |  |  |  | =head1 DESCRIPTION
25 |  |  |  |  |
26 |  |  |  |  | A convenience class used to perform operations on a specific column of
27 |  |  |  |  | a resultset.
28 |  |  |  |  |
29 |  |  |  |  | =cut
30 |  |  |  |  |
31 |  |  |  |  | =head1 METHODS
32 |  |  |  |  |
33 |  |  |  |  | =head2 new
34 |  |  |  |  |
35 |  |  |  |  | my $obj = DBIx::Class::ResultSetColumn->new($rs, $column);
36 |  |  |  |  |
37 |  |  |  |  | Creates a new resultset column object from the resultset and column
38 |  |  |  |  | passed as params. Used internally by L<DBIx::Class::ResultSet/get_column>.
39 |  |  |  |  |
40 |  |  |  |  | =cut
41 |  |  |  |  |
42 |  |  |  |  | # spent 998ms (174+824) within DBIx::Class::ResultSetColumn::new which was called 1954 times, avg 511µs/call: # 1954 times (174ms+824ms) by DBIx::Class::ResultSet::get_column at line 1090 of DBIx/Class/ResultSet.pm, avg 511µs/call sub new {
43 | 35172 | 118ms |  |  | my ($class, $rs, $column) = @_;
44 |  |  |  |  | $class = ref $class if ref $class;
45 |  |  |  |  |
46 |  |  |  |  | $rs->throw_exception('column must be supplied') unless $column;
47 |  |  |  |  |
48 |  |  | 1954 | 167ms | my $orig_attrs = $rs->_resolved_attrs; # spent 167ms making 1954 calls to DBIx::Class::ResultSet::_resolved_attrs, avg 86µs/call
49 |  |  | 1954 | 6.79ms | my $alias = $rs->current_source_alias; # spent 6.79ms making 1954 calls to DBIx::Class::ResultSet::current_source_alias, avg 3µs/call
50 |  |  |  |  |
51 |  |  |  |  | # If $column can be found in the 'as' list of the parent resultset, use the
52 |  |  |  |  | # corresponding element of its 'select' list (to keep any custom column
53 |  |  |  |  | # definition set up with 'select' or '+select' attrs), otherwise use $column
54 |  |  |  |  | # (to create a new column definition on-the-fly).
55 |  |  |  |  | my $as_list = $orig_attrs->{as} || [];
56 |  |  |  |  | my $select_list = $orig_attrs->{select} || [];
57 | 1954 | 9.52ms | 1954 | 4.30ms | my $as_index = List::Util::first { ($as_list->[$_] || "") eq $column } 0..$#$as_list; # spent 4.30ms making 1954 calls to List::Util::first, avg 2µs/call
58 |  |  |  |  | my $select = defined $as_index ? $select_list->[$as_index] : $column;
59 |  |  |  |  |
60 |  |  |  |  | my $new_parent_rs;
61 |  |  |  |  | # analyze the order_by, and see if it is done over a function/nonexistentcolumn
62 |  |  |  |  | # if this is the case we will need to wrap a subquery since the result of RSC
63 |  |  |  |  | # *must* be a single column select
64 |  |  | 9961 | 4.45ms | my %collist = map # spent 4.45ms making 9961 calls to DBIx::Class::ResultSetColumn::CORE:match, avg 447ns/call
65 | 9961 | 32.5ms | 1955 | 5.87ms | { $_ => 1, ($_ =~ /\./) ? () : ( "$alias.$_" => 1 ) } # spent 5.87ms making 1954 calls to DBIx::Class::ResultSource::columns, avg 3µs/call # spent 3µs making 1 call to DBIx::Class::ResultSet::result_source
66 |  |  |  |  | ($rs->result_source->columns, $column)
67 |  |  |  |  | ;
68 |  |  | 5863 | 290ms | if ( # spent 262ms making 1954 calls to DBIx::Class::Storage::DBIHacks::_extract_order_criteria, avg 134µs/call # spent 23.2ms making 1954 calls to DBIx::Class::Schema::storage, avg 12µs/call # spent 4.29ms making 1954 calls to DBIx::Class::ResultSource::schema, avg 2µs/call # spent 2µs making 1 call to DBIx::Class::ResultSet::result_source
69 |  |  |  |  | scalar grep
70 |  |  |  |  | { ! $collist{$_->[0]} }
71 |  |  |  |  | ( $rs->result_source->schema->storage->_extract_order_criteria ($orig_attrs->{order_by} ) )
72 |  |  |  |  | ) {
73 |  |  |  |  | # nuke the prefetch before collapsing to sql
74 |  |  |  |  | my $subq_rs = $rs->search;
75 |  |  |  |  | $subq_rs->{attrs}{join} = $subq_rs->_merge_joinpref_attr( $subq_rs->{attrs}{join}, delete $subq_rs->{attrs}{prefetch} );
76 |  |  |  |  | $new_parent_rs = $subq_rs->as_subselect_rs;
77 |  |  |  |  | }
78 |  |  |  |  |
79 |  |  | 1954 | 338ms | $new_parent_rs ||= $rs->search_rs; # spent 338ms making 1954 calls to DBIx::Class::ResultSet::search_rs, avg 173µs/call
80 |  |  |  |  | my $new_attrs = $new_parent_rs->{attrs} ||= {};
81 |  |  |  |  |
82 |  |  |  |  | # prefetch causes additional columns to be fetched, but we can not just make a new
83 |  |  |  |  | # rs via the _resolved_attrs trick - we need to retain the separation between
84 |  |  |  |  | # +select/+as and select/as. At the same time we want to preserve any joins that the
85 |  |  |  |  | # prefetch would otherwise generate.
86 |  |  | 1954 | 7.21ms | $new_attrs->{join} = $rs->_merge_joinpref_attr( $new_attrs->{join}, delete $new_attrs->{prefetch} ); # spent 7.21ms making 1954 calls to DBIx::Class::ResultSet::_merge_joinpref_attr, avg 4µs/call
87 |  |  |  |  |
88 |  |  |  |  | # {collapse} would mean a has_many join was injected, which in turn means
89 |  |  |  |  | # we need to group *IF WE CAN* (only if the column in question is unique)
90 |  |  |  |  | if (!$orig_attrs->{group_by} && keys %{$orig_attrs->{collapse}}) {
91 |  |  |  |  |
92 |  |  |  |  | # scan for a constraint that would contain our column only - that'd be proof
93 |  |  |  |  | # enough it is unique
94 |  |  |  |  | my $constraints = { $rs->result_source->unique_constraints };
95 |  |  |  |  | for my $constraint_columns ( values %$constraints ) {
96 |  |  |  |  |
97 |  |  |  |  | next unless @$constraint_columns == 1;
98 |  |  |  |  |
99 |  |  |  |  | my $col = $constraint_columns->[0];
100 |  |  |  |  | my $fqcol = join ('.', $new_attrs->{alias}, $col);
101 |  |  |  |  |
102 |  |  |  |  | if ($col eq $select or $fqcol eq $select) {
103 |  |  |  |  | $new_attrs->{group_by} = [ $select ];
104 |  |  |  |  | delete $new_attrs->{distinct}; # it is ignored when group_by is present
105 |  |  |  |  | last;
106 |  |  |  |  | }
107 |  |  |  |  | }
108 |  |  |  |  |
109 |  |  |  |  | if (!$new_attrs->{group_by}) {
110 |  |  |  |  | carp (
111 |  |  |  |  | "Attempting to retrieve non-unique column '$column' on a resultset containing "
112 |  |  |  |  | . 'one-to-many joins will return duplicate results.'
113 |  |  |  |  | );
114 |  |  |  |  | }
115 |  |  |  |  | }
116 |  |  |  |  |
117 |  |  |  |  | my $new = bless { _select => $select, _as => $column, _parent_resultset => $new_parent_rs }, $class;
118 |  |  |  |  | return $new;
119 |  |  |  |  | }
120 |  |  |  |  |
121 |  |  |  |  | =head2 as_query
122 |  |  |  |  |
123 |  |  |  |  | =over 4
124 |  |  |  |  |
125 |  |  |  |  | =item Arguments: none
126 |  |  |  |  |
127 |  |  |  |  | =item Return Value: \[ $sql, @bind ]
128 |  |  |  |  |
129 |  |  |  |  | =back
130 |  |  |  |  |
131 |  |  |  |  | Returns the SQL query and bind vars associated with the invocant.
132 |  |  |  |  |
133 |  |  |  |  | This is generally used as the RHS for a subquery.
134 |  |  |  |  |
135 |  |  |  |  | =cut
136 |  |  |  |  |
137 |  |  |  |  | sub as_query { return shift->_resultset->as_query(@_) }
138 |  |  |  |  |
139 |  |  |  |  | =head2 next
140 |  |  |  |  |
141 |  |  |  |  | =over 4
142 |  |  |  |  |
143 |  |  |  |  | =item Arguments: none
144 |  |  |  |  |
145 |  |  |  |  | =item Return Value: $value
146 |  |  |  |  |
147 |  |  |  |  | =back
148 |  |  |  |  |
149 |  |  |  |  | Returns the next value of the column in the resultset (or C<undef> if
150 |  |  |  |  | there is none).
151 |  |  |  |  |
152 |  |  |  |  | Much like L<DBIx::Class::ResultSet/next> but just returning the
153 |  |  |  |  | one value.
154 |  |  |  |  |
155 |  |  |  |  | =cut
156 |  |  |  |  |
157 |  |  |  |  | # spent 3.63s (51.5ms+3.58) within DBIx::Class::ResultSetColumn::next which was called 1954 times, avg 1.86ms/call: # 1949 times (50.5ms+3.55s) by DBIx::Class::ResultSet::count at line 1434 of DBIx/Class/ResultSet.pm, avg 1.85ms/call # 5 times (975µs+27.7ms) by DBIx::Class::Schema::Versioned::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/DBIx/Class/Schema/Versioned.pm:533] at line 530 of DBIx/Class/Schema/Versioned.pm, avg 5.74ms/call sub next {
158 | 5860 | 48.2ms |  |  | my $self = shift;
159 |  |  |  |  |
160 |  |  |  |  | # using cursor so we don't inflate anything
161 |  |  | 5862 | 3.58s | my ($row) = $self->_resultset->cursor->next; # spent 2.62s making 1954 calls to DBIx::Class::Storage::DBI::Cursor::next, avg 1.34ms/call # spent 566ms making 1954 calls to DBIx::Class::ResultSetColumn::_resultset, avg 290µs/call # spent 388ms making 1954 calls to DBIx::Class::ResultSet::cursor, avg 198µs/call
162 |  |  |  |  |
163 |  |  |  |  | return $row;
164 |  |  |  |  | }
165 |  |  |  |  |
166 |  |  |  |  | =head2 all
167 |  |  |  |  |
168 |  |  |  |  | =over 4
169 |  |  |  |  |
170 |  |  |  |  | =item Arguments: none
171 |  |  |  |  |
172 |  |  |  |  | =item Return Value: @values
173 |  |  |  |  |
174 |  |  |  |  | =back
175 |  |  |  |  |
176 |  |  |  |  | Returns all values of the column in the resultset (or C<undef> if
177 |  |  |  |  | there are none).
178 |  |  |  |  |
179 |  |  |  |  | Much like L<DBIx::Class::ResultSet/all> but returns values rather
180 |  |  |  |  | than row objects.
181 |  |  |  |  |
182 |  |  |  |  | =cut
183 |  |  |  |  |
184 |  |  |  |  | sub all {
185 |  |  |  |  | my $self = shift;
186 |  |  |  |  |
187 |  |  |  |  | # using cursor so we don't inflate anything
188 |  |  |  |  | return map { $_->[0] } $self->_resultset->cursor->all;
189 |  |  |  |  | }
190 |  |  |  |  |
191 |  |  |  |  | =head2 reset
192 |  |  |  |  |
193 |  |  |  |  | =over 4
194 |  |  |  |  |
195 |  |  |  |  | =item Arguments: none
196 |  |  |  |  |
197 |  |  |  |  | =item Return Value: $self
198 |  |  |  |  |
199 |  |  |  |  | =back
200 |  |  |  |  |
201 |  |  |  |  | Resets the underlying resultset's cursor, so you can iterate through the
202 |  |  |  |  | elements of the column again.
203 |  |  |  |  |
204 |  |  |  |  | Much like L<DBIx::Class::ResultSet/reset>.
205 |  |  |  |  |
206 |  |  |  |  | =cut
207 |  |  |  |  |
208 |  |  |  |  | sub reset {
209 |  |  |  |  | my $self = shift;
210 |  |  |  |  | $self->_resultset->cursor->reset;
211 |  |  |  |  | return $self;
212 |  |  |  |  | }
213 |  |  |  |  |
214 |  |  |  |  | =head2 first
215 |  |  |  |  |
216 |  |  |  |  | =over 4
217 |  |  |  |  |
218 |  |  |  |  | =item Arguments: none
219 |  |  |  |  |
220 |  |  |  |  | =item Return Value: $value
221 |  |  |  |  |
222 |  |  |  |  | =back
223 |  |  |  |  |
224 |  |  |  |  | Resets the underlying resultset and returns the next value of the column in the
225 |  |  |  |  | resultset (or C<undef> if there is none).
226 |  |  |  |  |
227 |  |  |  |  | Much like L<DBIx::Class::ResultSet/first> but just returning the one value.
228 |  |  |  |  |
229 |  |  |  |  | =cut
230 |  |  |  |  |
231 |  |  |  |  | sub first {
232 |  |  |  |  | my $self = shift;
233 |  |  |  |  |
234 |  |  |  |  | # using cursor so we don't inflate anything
235 |  |  |  |  | $self->_resultset->cursor->reset;
236 |  |  |  |  | my ($row) = $self->_resultset->cursor->next;
237 |  |  |  |  |
238 |  |  |  |  | return $row;
239 |  |  |  |  | }
240 |  |  |  |  |
241 |  |  |  |  | =head2 single
242 |  |  |  |  |
243 |  |  |  |  | =over 4
244 |  |  |  |  |
245 |  |  |  |  | =item Arguments: none
246 |  |  |  |  |
247 |  |  |  |  | =item Return Value: $value
248 |  |  |  |  |
249 |  |  |  |  | =back
250 |  |  |  |  |
251 |  |  |  |  | Much like L<DBIx::Class::ResultSet/single> fetches one and only one column
252 |  |  |  |  | value using the cursor directly. If additional rows are present a warning
253 |  |  |  |  | is issued before discarding the cursor.
254 |  |  |  |  |
255 |  |  |  |  | =cut
256 |  |  |  |  |
257 |  |  |  |  | sub single {
258 |  |  |  |  | my $self = shift;
259 |  |  |  |  |
260 |  |  |  |  | my $attrs = $self->_resultset->_resolved_attrs;
261 |  |  |  |  | my ($row) = $self->_resultset->result_source->storage->select_single(
262 |  |  |  |  | $attrs->{from}, $attrs->{select}, $attrs->{where}, $attrs
263 |  |  |  |  | );
264 |  |  |  |  |
265 |  |  |  |  | return $row;
266 |  |  |  |  | }
267 |  |  |  |  |
268 |  |  |  |  | =head2 min
269 |  |  |  |  |
270 |  |  |  |  | =over 4
271 |  |  |  |  |
272 |  |  |  |  | =item Arguments: none
273 |  |  |  |  |
274 |  |  |  |  | =item Return Value: $lowest_value
275 |  |  |  |  |
276 |  |  |  |  | =back
277 |  |  |  |  |
278 |  |  |  |  | my $first_year = $year_col->min();
279 |  |  |  |  |
280 |  |  |  |  | Wrapper for ->func. Returns the lowest value of the column in the
281 |  |  |  |  | resultset (or C<undef> if there are none).
282 |  |  |  |  |
283 |  |  |  |  | =cut
284 |  |  |  |  |
285 |  |  |  |  | sub min {
286 |  |  |  |  | return shift->func('MIN');
287 |  |  |  |  | }
288 |  |  |  |  |
289 |  |  |  |  | =head2 min_rs
290 |  |  |  |  |
291 |  |  |  |  | =over 4
292 |  |  |  |  |
293 |  |  |  |  | =item Arguments: none
294 |  |  |  |  |
295 |  |  |  |  | =item Return Value: $resultset
296 |  |  |  |  |
297 |  |  |  |  | =back
298 |  |  |  |  |
299 |  |  |  |  | my $rs = $year_col->min_rs();
300 |  |  |  |  |
301 |  |  |  |  | Wrapper for ->func_rs for function MIN().
302 |  |  |  |  |
303 |  |  |  |  | =cut
304 |  |  |  |  |
305 |  |  |  |  | sub min_rs { return shift->func_rs('MIN') }
306 |  |  |  |  |
307 |  |  |  |  | =head2 max
308 |  |  |  |  |
309 |  |  |  |  | =over 4
310 |  |  |  |  |
311 |  |  |  |  | =item Arguments: none
312 |  |  |  |  |
313 |  |  |  |  | =item Return Value: $highest_value
314 |  |  |  |  |
315 |  |  |  |  | =back
316 |  |  |  |  |
317 |  |  |  |  | my $last_year = $year_col->max();
318 |  |  |  |  |
319 |  |  |  |  | Wrapper for ->func. Returns the highest value of the column in the
320 |  |  |  |  | resultset (or C<undef> if there are none).
321 |  |  |  |  |
322 |  |  |  |  | =cut
323 |  |  |  |  |
324 |  |  |  |  | sub max {
325 |  |  |  |  | return shift->func('MAX');
326 |  |  |  |  | }
327 |  |  |  |  |
328 |  |  |  |  | =head2 max_rs
329 |  |  |  |  |
330 |  |  |  |  | =over 4
331 |  |  |  |  |
332 |  |  |  |  | =item Arguments: none
333 |  |  |  |  |
334 |  |  |  |  | =item Return Value: $resultset
335 |  |  |  |  |
336 |  |  |  |  | =back
337 |  |  |  |  |
338 |  |  |  |  | my $rs = $year_col->max_rs();
339 |  |  |  |  |
340 |  |  |  |  | Wrapper for ->func_rs for function MAX().
341 |  |  |  |  |
342 |  |  |  |  | =cut
343 |  |  |  |  |
344 |  |  |  |  | sub max_rs { return shift->func_rs('MAX') }
345 |  |  |  |  |
346 |  |  |  |  | =head2 sum
347 |  |  |  |  |
348 |  |  |  |  | =over 4
349 |  |  |  |  |
350 |  |  |  |  | =item Arguments: none
351 |  |  |  |  |
352 |  |  |  |  | =item Return Value: $sum_of_values
353 |  |  |  |  |
354 |  |  |  |  | =back
355 |  |  |  |  |
356 |  |  |  |  | my $total = $prices_col->sum();
357 |  |  |  |  |
358 |  |  |  |  | Wrapper for ->func. Returns the sum of all the values in the column of
359 |  |  |  |  | the resultset. Use on varchar-like columns at your own risk.
360 |  |  |  |  |
361 |  |  |  |  | =cut
362 |  |  |  |  |
363 |  |  |  |  | sub sum {
364 |  |  |  |  | return shift->func('SUM');
365 |  |  |  |  | }
366 |  |  |  |  |
367 |  |  |  |  | =head2 sum_rs
368 |  |  |  |  |
369 |  |  |  |  | =over 4
370 |  |  |  |  |
371 |  |  |  |  | =item Arguments: none
372 |  |  |  |  |
373 |  |  |  |  | =item Return Value: $resultset
374 |  |  |  |  |
375 |  |  |  |  | =back
376 |  |  |  |  |
377 |  |  |  |  | my $rs = $year_col->sum_rs();
378 |  |  |  |  |
379 |  |  |  |  | Wrapper for ->func_rs for function SUM().
380 |  |  |  |  |
381 |  |  |  |  | =cut
382 |  |  |  |  |
383 |  |  |  |  | sub sum_rs { return shift->func_rs('SUM') }
384 |  |  |  |  |
385 |  |  |  |  | =head2 func
386 |  |  |  |  |
387 |  |  |  |  | =over 4
388 |  |  |  |  |
389 |  |  |  |  | =item Arguments: $function
390 |  |  |  |  |
391 |  |  |  |  | =item Return Value: $function_return_value
392 |  |  |  |  |
393 |  |  |  |  | =back
394 |  |  |  |  |
395 |  |  |  |  | $rs = $schema->resultset("CD")->search({});
396 |  |  |  |  | $length = $rs->get_column('title')->func('LENGTH');
397 |  |  |  |  |
398 |  |  |  |  | Runs a query using the function on the column and returns the
399 |  |  |  |  | value. Produces the following SQL:
400 |  |  |  |  |
401 |  |  |  |  | SELECT LENGTH( title ) FROM cd me
402 |  |  |  |  |
403 |  |  |  |  | =cut
404 |  |  |  |  |
405 |  |  |  |  | sub func {
406 |  |  |  |  | my ($self,$function) = @_;
407 |  |  |  |  | my $cursor = $self->func_rs($function)->cursor;
408 |  |  |  |  |
409 |  |  |  |  | if( wantarray ) {
410 |  |  |  |  | return map { $_->[ 0 ] } $cursor->all;
411 |  |  |  |  | }
412 |  |  |  |  |
413 |  |  |  |  | return ( $cursor->next )[ 0 ];
414 |  |  |  |  | }
415 |  |  |  |  |
416 |  |  |  |  | =head2 func_rs
417 |  |  |  |  |
418 |  |  |  |  | =over 4
419 |  |  |  |  |
420 |  |  |  |  | =item Arguments: $function
421 |  |  |  |  |
422 |  |  |  |  | =item Return Value: $resultset
423 |  |  |  |  |
424 |  |  |  |  | =back
425 |  |  |  |  |
426 |  |  |  |  | Creates the resultset that C<func()> uses to run its query.
427 |  |  |  |  |
428 |  |  |  |  | =cut
429 |  |  |  |  |
430 |  |  |  |  | sub func_rs {
431 |  |  |  |  | my ($self,$function) = @_;
432 |  |  |  |  | return $self->{_parent_resultset}->search(
433 |  |  |  |  | undef, {
434 |  |  |  |  | select => {$function => $self->{_select}},
435 |  |  |  |  | as => [$self->{_as}],
436 |  |  |  |  | },
437 |  |  |  |  | );
438 |  |  |  |  | }
439 |  |  |  |  |
440 |  |  |  |  | =head2 throw_exception
441 |  |  |  |  |
442 |  |  |  |  | See L<DBIx::Class::Schema/throw_exception> for details.
443 |  |  |  |  |
444 |  |  |  |  | =cut
445 |  |  |  |  |
446 |  |  |  |  | sub throw_exception {
447 |  |  |  |  | my $self=shift;
448 |  |  |  |  |
449 |  |  |  |  | if (ref $self && $self->{_parent_resultset}) {
450 |  |  |  |  | $self->{_parent_resultset}->throw_exception(@_);
451 |  |  |  |  | }
452 |  |  |  |  | else {
453 |  |  |  |  | DBIx::Class::Exception->throw(@_);
454 |  |  |  |  | }
455 |  |  |  |  | }
456 |  |  |  |  |
457 |  |  |  |  | # _resultset
458 |  |  |  |  | #
459 |  |  |  |  | # Arguments: none
460 |  |  |  |  | #
461 |  |  |  |  | # Return Value: $resultset
462 |  |  |  |  | #
463 |  |  |  |  | # $year_col->_resultset->next
464 |  |  |  |  | #
465 |  |  |  |  | # Returns the underlying resultset. Creates it from the parent resultset if
466 |  |  |  |  | # necessary.
467 |  |  |  |  | #
468 |  |  |  |  | # spent 566ms (16.6+549) within DBIx::Class::ResultSetColumn::_resultset which was called 1954 times, avg 290µs/call: # 1954 times (16.6ms+549ms) by DBIx::Class::ResultSetColumn::next at line 161, avg 290µs/call sub _resultset {
469 | 3908 | 15.5ms |  |  | my $self = shift;
470 |  |  |  |  |
471 |  |  | 1954 | 549ms | return $self->{_resultset} ||= $self->{_parent_resultset}->search(undef, # spent 549ms making 1954 calls to DBIx::Class::ResultSet::search, avg 281µs/call
472 |  |  |  |  | {
473 |  |  |  |  | select => [$self->{_select}],
474 |  |  |  |  | as => [$self->{_as}]
475 |  |  |  |  | }
476 |  |  |  |  | );
477 |  |  |  |  | }
478 |  |  |  |  |
479 | 1 | 2µs |  |  | 1;
480 |  |  |  |  |
481 |  |  |  |  | =head1 AUTHORS
482 |  |  |  |  |
483 |  |  |  |  | Luke Saunders <luke.saunders@gmail.com>
484 |  |  |  |  |
485 |  |  |  |  | Jess Robinson
486 |  |  |  |  |
487 |  |  |  |  | =head1 LICENSE
488 |  |  |  |  |
489 |  |  |  |  | You may distribute this code under the same terms as Perl itself.
490 |  |  |  |  |
491 | 1 | 6µs | 1 | 237µs | =cut # spent 237µs making 1 call to B::Hooks::EndOfScope::__ANON__[B/Hooks/EndOfScope.pm:26]
|  |  |  |  | # spent 4.45ms within DBIx::Class::ResultSetColumn::CORE:match which was called 9961 times, avg 447ns/call: # 9961 times (4.45ms+0s) by DBIx::Class::ResultSetColumn::new at line 64, avg 447ns/call sub DBIx::Class::ResultSetColumn::CORE:match; # opcode