← Index
NYTProf Performance Profile   « line view »
For starman worker -M FindBin --max-requests 50 --workers 2 --user=kohadev-koha --group kohadev-koha --pid /var/run/koha/kohadev/plack.pid --daemonize --access-log /var/log/koha/kohadev/plack.log --error-log /var/log/koha/kohadev/plack-error.log -E deployment --socket /var/run/koha/kohadev/plack.sock /etc/koha/sites/kohadev/plack.psgi
  Run on Fri Jan 8 14:31:06 2016
Reported on Fri Jan 8 14:31:39 2016

Filename/usr/share/perl5/DBIx/Class/Storage/DBI/Cursor.pm
StatementsExecuted 52 statements in 2.24ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11191µs1.54msDBIx::Class::Storage::DBI::Cursor::::nextDBIx::Class::Storage::DBI::Cursor::next
11126µs37µsDBIx::Class::Storage::DBI::Cursor::::BEGIN@10DBIx::Class::Storage::DBI::Cursor::BEGIN@10
11120µs33µsDBIx::Class::Storage::DBI::Cursor::::BEGIN@3DBIx::Class::Storage::DBI::Cursor::BEGIN@3
11114µs50µsDBIx::Class::Storage::DBI::Cursor::::BEGIN@8DBIx::Class::Storage::DBI::Cursor::BEGIN@8
11114µs15µsDBIx::Class::Storage::DBI::Cursor::::newDBIx::Class::Storage::DBI::Cursor::new
11112µs544µsDBIx::Class::Storage::DBI::Cursor::::BEGIN@6DBIx::Class::Storage::DBI::Cursor::BEGIN@6
11112µs55µsDBIx::Class::Storage::DBI::Cursor::::__finish_sthDBIx::Class::Storage::DBI::Cursor::__finish_sth
11111µs34µsDBIx::Class::Storage::DBI::Cursor::::BEGIN@9DBIx::Class::Storage::DBI::Cursor::BEGIN@9
11110µs161µsDBIx::Class::Storage::DBI::Cursor::::BEGIN@11DBIx::Class::Storage::DBI::Cursor::BEGIN@11
1119µs17µsDBIx::Class::Storage::DBI::Cursor::::BEGIN@4DBIx::Class::Storage::DBI::Cursor::BEGIN@4
2218µs8µsDBIx::Class::Storage::DBI::Cursor::::sthDBIx::Class::Storage::DBI::Cursor::sth
1116µs62µsDBIx::Class::Storage::DBI::Cursor::::DESTROYDBIx::Class::Storage::DBI::Cursor::DESTROY
0000s0sDBIx::Class::Storage::DBI::Cursor::::CLONEDBIx::Class::Storage::DBI::Cursor::CLONE
0000s0sDBIx::Class::Storage::DBI::Cursor::::__ANON__[:251]DBIx::Class::Storage::DBI::Cursor::__ANON__[:251]
0000s0sDBIx::Class::Storage::DBI::Cursor::::__ANON__[:252]DBIx::Class::Storage::DBI::Cursor::__ANON__[:252]
0000s0sDBIx::Class::Storage::DBI::Cursor::::allDBIx::Class::Storage::DBI::Cursor::all
0000s0sDBIx::Class::Storage::DBI::Cursor::::resetDBIx::Class::Storage::DBI::Cursor::reset
0000s0sDBIx::Class::Storage::DBI::Cursor::::try {...} DBIx::Class::Storage::DBI::Cursor::try {...}
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package DBIx::Class::Storage::DBI::Cursor;
2
3249µs246µs
# spent 33µs (20+13) within DBIx::Class::Storage::DBI::Cursor::BEGIN@3 which was called: # once (20µs+13µs) by Class::C3::Componentised::ensure_class_loaded at line 3
use strict;
# spent 33µs making 1 call to DBIx::Class::Storage::DBI::Cursor::BEGIN@3 # spent 13µs making 1 call to strict::import
4238µs224µs
# spent 17µs (9+8) within DBIx::Class::Storage::DBI::Cursor::BEGIN@4 which was called: # once (9µs+8µs) by Class::C3::Componentised::ensure_class_loaded at line 4
use warnings;
# spent 17µs making 1 call to DBIx::Class::Storage::DBI::Cursor::BEGIN@4 # spent 8µs making 1 call to warnings::import
5
62222µs21.08ms
# spent 544µs (12+532) within DBIx::Class::Storage::DBI::Cursor::BEGIN@6 which was called: # once (12µs+532µs) by Class::C3::Componentised::ensure_class_loaded at line 6
use base 'DBIx::Class::Cursor';
# spent 544µs making 1 call to DBIx::Class::Storage::DBI::Cursor::BEGIN@6 # spent 532µs making 1 call to base::import
7
8273µs286µs
# spent 50µs (14+36) within DBIx::Class::Storage::DBI::Cursor::BEGIN@8 which was called: # once (14µs+36µs) by Class::C3::Componentised::ensure_class_loaded at line 8
use Try::Tiny;
# spent 50µs making 1 call to DBIx::Class::Storage::DBI::Cursor::BEGIN@8 # spent 36µs making 1 call to Exporter::import
9256µs256µs
# spent 34µs (11+22) within DBIx::Class::Storage::DBI::Cursor::BEGIN@9 which was called: # once (11µs+22µs) by Class::C3::Componentised::ensure_class_loaded at line 9
use Scalar::Util qw(refaddr weaken);
# spent 34µs making 1 call to DBIx::Class::Storage::DBI::Cursor::BEGIN@9 # spent 22µs making 1 call to Exporter::import
10258µs249µs
# spent 37µs (26+11) within DBIx::Class::Storage::DBI::Cursor::BEGIN@10 which was called: # once (26µs+11µs) by Class::C3::Componentised::ensure_class_loaded at line 10
use List::Util 'shuffle';
# spent 37µs making 1 call to DBIx::Class::Storage::DBI::Cursor::BEGIN@10 # spent 11µs making 1 call to List::Util::import
1121.58ms2312µs
# spent 161µs (10+151) within DBIx::Class::Storage::DBI::Cursor::BEGIN@11 which was called: # once (10µs+151µs) by Class::C3::Componentised::ensure_class_loaded at line 11
use namespace::clean;
# spent 161µs making 1 call to DBIx::Class::Storage::DBI::Cursor::BEGIN@11 # spent 151µs making 1 call to namespace::clean::import
12
13114µs1207µs__PACKAGE__->mk_group_accessors('simple' =>
# spent 207µs making 1 call to Class::Accessor::Grouped::mk_group_accessors
14 qw/storage args attrs/
15);
16
17=head1 NAME
18
19DBIx::Class::Storage::DBI::Cursor - Object representing a query cursor on a
20resultset.
21
22=head1 SYNOPSIS
23
24 my $cursor = $schema->resultset('CD')->cursor();
25
26 # raw values off the database handle in resultset columns/select order
27 my @next_cd_column_values = $cursor->next;
28
29 # list of all raw values as arrayrefs
30 my @all_cds_column_values = $cursor->all;
31
32=head1 DESCRIPTION
33
34A Cursor represents a query cursor on a L<DBIx::Class::ResultSet> object. It
35allows for traversing the result set with L</next>, retrieving all results with
36L</all> and resetting the cursor with L</reset>.
37
38Usually, you would use the cursor methods built into L<DBIx::Class::ResultSet>
39to traverse it. See L<DBIx::Class::ResultSet/next>,
40L<DBIx::Class::ResultSet/reset> and L<DBIx::Class::ResultSet/all> for more
41information.
42
43=head1 METHODS
44
45=head2 new
46
47Returns a new L<DBIx::Class::Storage::DBI::Cursor> object.
48
49=cut
50
51{
522500ns my %cursor_registry;
53
54
# spent 15µs (14+1) within DBIx::Class::Storage::DBI::Cursor::new which was called: # once (14µs+1µs) by DBIx::Class::Storage::DBI::select at line 2559 of DBIx/Class/Storage/DBI.pm
sub new {
551600ns my ($class, $storage, $args, $attrs) = @_;
56
5713µs my $self = bless {
58 storage => $storage,
59 args => $args,
60 attrs => $attrs,
61 }, ref $class || $class;
62
631200ns if (DBIx::Class::_ENV_::HAS_ITHREADS) {
64
65 # quick "garbage collection" pass - prevents the registry
66 # from slowly growing with a bunch of undef-valued keys
67 defined $cursor_registry{$_} or delete $cursor_registry{$_}
6811µs for keys %cursor_registry;
69
7019µs21µs weaken( $cursor_registry{ refaddr($self) } = $self )
# spent 700ns making 1 call to Scalar::Util::refaddr # spent 700ns making 1 call to Scalar::Util::weaken
71 }
72
7313µs return $self;
74 }
75
76 sub CLONE {
77 for (keys %cursor_registry) {
78 # once marked we no longer care about them, hence no
79 # need to keep in the registry, left alone renumber the
80 # keys (all addresses are now different)
81 my $self = delete $cursor_registry{$_}
82 or next;
83
84 $self->{_intra_thread} = 1;
85 }
86 }
87}
88
89=head2 next
90
91=over 4
92
93=item Arguments: none
94
95=item Return Value: \@row_columns
96
97=back
98
99Advances the cursor to the next row and returns an array of column
100values (the result of L<DBI/fetchrow_array> method).
101
102=cut
103
104
# spent 1.54ms (91µs+1.45) within DBIx::Class::Storage::DBI::Cursor::next which was called: # once (91µs+1.45ms) by DBIx::Class::ResultSetColumn::next at line 160 of DBIx/Class/ResultSetColumn.pm
sub next {
1051300ns my $self = shift;
106
107111µs return if $self->{_done};
108
1091100ns my $sth;
110
1111800ns if (
112 $self->{attrs}{software_limit}
113 && $self->{attrs}{rows}
114 && ($self->{_pos}||0) >= $self->{attrs}{rows}
115 ) {
116 if ($sth = $self->sth) {
117 # explicit finish will issue warnings, unlike the DESTROY below
118 $sth->finish if $sth->FETCH('Active');
119 }
120 $self->{_done} = 1;
121 return;
122 }
123
12412µs12µs unless ($sth = $self->sth) {
# spent 2µs making 1 call to DBIx::Class::Storage::DBI::Cursor::sth
125120µs21.39ms (undef, $sth, undef) = $self->storage->_select( @{$self->{args}} );
# spent 1.24ms making 1 call to DBIx::Class::Storage::DBI::_select # spent 149µs making 1 call to DBIx::Class::Storage::DBI::Cursor::storage
126
127113µs16µs $self->{_results} = [ (undef) x $sth->FETCH('NUM_OF_FIELDS') ];
# spent 6µs making 1 call to DBI::common::FETCH
12819µs265µs $sth->bind_columns( \( @{$self->{_results}} ) );
# spent 35µs making 1 call to DBI::st::bind_columns # spent 30µs making 1 call to DBD::mysql::st::__ANON__[DBD/mysql.pm:810]
129
1301700ns if ( $self->{attrs}{software_limit} and $self->{attrs}{offset} ) {
131 $sth->fetch for 1 .. $self->{attrs}{offset};
132 }
133
13412µs16µs $self->sth($sth);
# spent 6µs making 1 call to DBIx::Class::Storage::DBI::Cursor::sth
135 }
136
13717µs13µs if ($sth->fetch) {
# spent 3µs making 1 call to DBI::st::fetch
13811µs $self->{_pos}++;
13914µs return @{$self->{_results}};
140 } else {
141 $self->{_done} = 1;
142 return ();
143 }
144}
145
146
147=head2 all
148
149=over 4
150
151=item Arguments: none
152
153=item Return Value: \@row_columns+
154
155=back
156
157Returns a list of arrayrefs of column values for all rows in the
158L<DBIx::Class::ResultSet>.
159
160=cut
161
162sub all {
163 my $self = shift;
164
165 # delegate to DBIC::Cursor which will delegate back to next()
166 if ($self->{attrs}{software_limit}
167 && ($self->{attrs}{offset} || $self->{attrs}{rows})) {
168 return $self->next::method(@_);
169 }
170
171 my $sth;
172
173 if ($sth = $self->sth) {
174 # explicit finish will issue warnings, unlike the DESTROY below
175 $sth->finish if ( ! $self->{_done} and $sth->FETCH('Active') );
176 $self->sth(undef);
177 }
178
179 (undef, $sth) = $self->storage->_select( @{$self->{args}} );
180
181 return (
182 DBIx::Class::_ENV_::SHUFFLE_UNORDERED_RESULTSETS
183 and
184 ! $self->{attrs}{order_by}
185 )
186 ? shuffle @{$sth->fetchall_arrayref}
187 : @{$sth->fetchall_arrayref}
188 ;
189}
190
191
# spent 8µs within DBIx::Class::Storage::DBI::Cursor::sth which was called 2 times, avg 4µs/call: # once (6µs+0s) by DBIx::Class::Storage::DBI::Cursor::next at line 134 # once (2µs+0s) by DBIx::Class::Storage::DBI::Cursor::next at line 124
sub sth {
1922500ns my $self = shift;
193
19421µs if (@_) {
19511µs delete @{$self}{qw/_pos _done _pid _intra_thread/};
196
1971500ns $self->{sth} = $_[0];
19812µs $self->{_pid} = $$ if ! DBIx::Class::_ENV_::BROKEN_FORK and $_[0];
199 }
200 elsif ($self->{sth} and ! $self->{_done}) {
201
202 my $invalidate_handle_reason;
203
204 if (DBIx::Class::_ENV_::HAS_ITHREADS and $self->{_intra_thread} ) {
205 $invalidate_handle_reason = 'Multi-thread';
206 }
207 elsif (!DBIx::Class::_ENV_::BROKEN_FORK and $self->{_pid} != $$ ) {
208 $invalidate_handle_reason = 'Multi-process';
209 }
210
211 if ($invalidate_handle_reason) {
212 $self->storage->throw_exception("$invalidate_handle_reason access attempted while cursor in progress (position $self->{_pos})")
213 if $self->{_pos};
214
215 # reinvokes the reset logic above
216 $self->sth(undef);
217 }
218 }
219
22028µs return $self->{sth};
221}
222
223=head2 reset
224
225Resets the cursor to the beginning of the L<DBIx::Class::ResultSet>.
226
227=cut
228
229sub reset {
230 $_[0]->__finish_sth if $_[0]->{sth};
231 $_[0]->sth(undef);
232}
233
234
235
# spent 62µs (6+55) within DBIx::Class::Storage::DBI::Cursor::DESTROY which was called: # once (6µs+55µs) by DBIx::Class::ResultSet::count at line 32 of Koha/Borrower/Discharge.pm
sub DESTROY {
236111µs155µs $_[0]->__finish_sth if $_[0]->{sth};
# spent 55µs making 1 call to DBIx::Class::Storage::DBI::Cursor::__finish_sth
237}
238
239
# spent 55µs (12+44) within DBIx::Class::Storage::DBI::Cursor::__finish_sth which was called: # once (12µs+44µs) by DBIx::Class::Storage::DBI::Cursor::DESTROY at line 236
sub __finish_sth {
240 # It is (sadly) extremely important to finish() handles we are about
241 # to lose (due to reset() or a DESTROY() ). $rs->reset is the closest
242 # thing the user has to getting to the underlying finish() API and some
243 # DBDs mandate this (e.g. DBD::InterBase will segfault, DBD::Sybase
244 # won't start a transaction sanely, etc)
245 # We also can't use the accessor here, as it will trigger a fork/thread
246 # check, and resetting a cursor in a child is perfectly valid
247
2481600ns my $self = shift;
249
250 # No need to care about failures here
251215µs13µs try { local $SIG{__WARN__} = sub {}; $self->{sth}->finish } if (
# spent 3µs making 1 call to DBI::st::finish
25217µs12µs $self->{sth} and ! try { ! $self->{sth}->FETCH('Active') }
# spent 2µs making 1 call to DBI::common::FETCH
253113µs244µs );
# spent 44µs making 2 calls to Try::Tiny::try, avg 22µs/call
254}
255
256=head1 FURTHER QUESTIONS?
257
258Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
259
260=head1 COPYRIGHT AND LICENSE
261
262This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
263by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
264redistribute it and/or modify it under the same terms as the
265L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
266
267=cut
268
26914µs1167µs1;
# spent 167µs making 1 call to B::Hooks::EndOfScope::XS::__ANON__