← 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:33:29 2016

Filename/usr/share/perl5/DBIx/Class/Storage.pm
StatementsExecuted 0 statements in 0s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1111.28ms20.6msDBIx::Class::Storage::::BEGIN@16 DBIx::Class::Storage::BEGIN@16
111848µs1.49msDBIx::Class::Storage::::BEGIN@18 DBIx::Class::Storage::BEGIN@18
11131µs189µsDBIx::Class::Storage::::set_schema DBIx::Class::Storage::set_schema
11114µs20µsDBIx::Class::Storage::::BEGIN@3 DBIx::Class::Storage::BEGIN@3
11112µs49µsDBIx::Class::Storage::::BEGIN@17 DBIx::Class::Storage::BEGIN@17
11111µs67µsDBIx::Class::Storage::::BEGIN@15 DBIx::Class::Storage::BEGIN@15
11110µs35µsDBIx::Class::Storage::::BEGIN@19 DBIx::Class::Storage::BEGIN@19
11110µs46µsDBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION::::BEGIN@12DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION::BEGIN@12
11110µs14µsDBIx::Class::Storage::::BEGIN@7 DBIx::Class::Storage::BEGIN@7
1119µs57µsDBIx::Class::Storage::::BEGIN@6 DBIx::Class::Storage::BEGIN@6
1118µs12µsDBIx::Class::Storage::::BEGIN@4 DBIx::Class::Storage::BEGIN@4
1117µs129µsDBIx::Class::Storage::::BEGIN@20 DBIx::Class::Storage::BEGIN@20
0000s0sDBIx::Class::Storage::::__ANON__[:186] DBIx::Class::Storage::__ANON__[:186]
0000s0sDBIx::Class::Storage::::__ANON__[:480] DBIx::Class::Storage::__ANON__[:480]
0000s0sDBIx::Class::Storage::::__ANON__[:484] DBIx::Class::Storage::__ANON__[:484]
0000s0sDBIx::Class::Storage::::__ANON__[:506] DBIx::Class::Storage::__ANON__[:506]
0000s0sDBIx::Class::Storage::::__ANON__[:508] DBIx::Class::Storage::__ANON__[:508]
0000s0sDBIx::Class::Storage::::_svp_generate_name DBIx::Class::Storage::_svp_generate_name
0000s0sDBIx::Class::Storage::::columns_info_for DBIx::Class::Storage::columns_info_for
0000s0sDBIx::Class::Storage::::connect_info DBIx::Class::Storage::connect_info
0000s0sDBIx::Class::Storage::::connected DBIx::Class::Storage::connected
0000s0sDBIx::Class::Storage::::cursor DBIx::Class::Storage::cursor
0000s0sDBIx::Class::Storage::::debugcb DBIx::Class::Storage::debugcb
0000s0sDBIx::Class::Storage::::debugfh DBIx::Class::Storage::debugfh
0000s0sDBIx::Class::Storage::::debugobj DBIx::Class::Storage::debugobj
0000s0sDBIx::Class::Storage::::delete DBIx::Class::Storage::delete
0000s0sDBIx::Class::Storage::::deploy DBIx::Class::Storage::deploy
0000s0sDBIx::Class::Storage::::disconnect DBIx::Class::Storage::disconnect
0000s0sDBIx::Class::Storage::::ensure_connected DBIx::Class::Storage::ensure_connected
0000s0sDBIx::Class::Storage::::insert DBIx::Class::Storage::insert
0000s0sDBIx::Class::Storage::::new DBIx::Class::Storage::new
0000s0sDBIx::Class::Storage::::select DBIx::Class::Storage::select
0000s0sDBIx::Class::Storage::::select_single DBIx::Class::Storage::select_single
0000s0sDBIx::Class::Storage::::sql_maker DBIx::Class::Storage::sql_maker
0000s0sDBIx::Class::Storage::::svp_begin DBIx::Class::Storage::svp_begin
0000s0sDBIx::Class::Storage::::svp_release DBIx::Class::Storage::svp_release
0000s0sDBIx::Class::Storage::::svp_rollback DBIx::Class::Storage::svp_rollback
0000s0sDBIx::Class::Storage::::throw_exception DBIx::Class::Storage::throw_exception
0000s0sDBIx::Class::Storage::::txn_begin DBIx::Class::Storage::txn_begin
0000s0sDBIx::Class::Storage::::txn_commit DBIx::Class::Storage::txn_commit
0000s0sDBIx::Class::Storage::::txn_do DBIx::Class::Storage::txn_do
0000s0sDBIx::Class::Storage::::txn_rollback DBIx::Class::Storage::txn_rollback
0000s0sDBIx::Class::Storage::::txn_scope_guard DBIx::Class::Storage::txn_scope_guard
0000s0sDBIx::Class::Storage::::update DBIx::Class::Storage::update
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;
2
3226µs
# spent 20µs (14+6) within DBIx::Class::Storage::BEGIN@3 which was called: # once (14µs+6µs) by base::import at line 3
use strict;
# spent 20µs making 1 call to DBIx::Class::Storage::BEGIN@3 # spent 6µs making 1 call to strict::import
4215µs
# spent 12µs (8+4) within DBIx::Class::Storage::BEGIN@4 which was called: # once (8µs+4µs) by base::import at line 4
use warnings;
# spent 12µs making 1 call to DBIx::Class::Storage::BEGIN@4 # spent 4µs making 1 call to warnings::import
5
6257µs
# spent 57µs (9+47) within DBIx::Class::Storage::BEGIN@6 which was called: # once (9µs+47µs) by base::import at line 6
use base qw/DBIx::Class/;
# spent 57µs making 1 call to DBIx::Class::Storage::BEGIN@6 # spent 47µs making 1 call to base::import, recursion: max depth 2, sum of overlapping time 47µs
7219µs
# spent 14µs (10+5) within DBIx::Class::Storage::BEGIN@7 which was called: # once (10µs+5µs) by base::import at line 7
use mro 'c3';
# spent 14µs making 1 call to DBIx::Class::Storage::BEGIN@7 # spent 4µs making 1 call to mro::import
8
9{
10 package # Hide from PAUSE
11 DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION;
12246µs
# spent 46µs (10+36) within DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION::BEGIN@12 which was called: # once (10µs+36µs) by base::import at line 12
use base 'DBIx::Class::Exception';
# spent 46µs making 1 call to DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION::BEGIN@12 # spent 36µs making 1 call to base::import, recursion: max depth 2, sum of overlapping time 36µs
13}
14
152123µs
# spent 67µs (11+56) within DBIx::Class::Storage::BEGIN@15 which was called: # once (11µs+56µs) by base::import at line 15
use DBIx::Class::Carp;
# spent 67µs making 1 call to DBIx::Class::Storage::BEGIN@15 # spent 56µs making 1 call to DBIx::Class::Carp::import
16120.6ms
# spent 20.6ms (1.28+19.3) within DBIx::Class::Storage::BEGIN@16 which was called: # once (1.28ms+19.3ms) by base::import at line 16
use DBIx::Class::Storage::BlockRunner;
# spent 20.6ms making 1 call to DBIx::Class::Storage::BEGIN@16
17285µs
# spent 49µs (12+37) within DBIx::Class::Storage::BEGIN@17 which was called: # once (12µs+37µs) by base::import at line 17
use Scalar::Util qw/blessed weaken/;
# spent 49µs making 1 call to DBIx::Class::Storage::BEGIN@17 # spent 37µs making 1 call to Exporter::import
1811.49ms
# spent 1.49ms (848µs+641µs) within DBIx::Class::Storage::BEGIN@18 which was called: # once (848µs+641µs) by base::import at line 18
use DBIx::Class::Storage::TxnScopeGuard;
# spent 1.49ms making 1 call to DBIx::Class::Storage::BEGIN@18
19260µs
# spent 35µs (10+25) within DBIx::Class::Storage::BEGIN@19 which was called: # once (10µs+25µs) by base::import at line 19
use Try::Tiny;
# spent 35µs making 1 call to DBIx::Class::Storage::BEGIN@19 # spent 25µs making 1 call to Exporter::import
202251µs
# spent 129µs (7+122) within DBIx::Class::Storage::BEGIN@20 which was called: # once (7µs+122µs) by base::import at line 20
use namespace::clean;
# spent 129µs making 1 call to DBIx::Class::Storage::BEGIN@20 # spent 122µs making 1 call to namespace::clean::import
21
221281µs__PACKAGE__->mk_group_accessors(simple => qw/debug schema transaction_depth auto_savepoint savepoints/);
# spent 281µs making 1 call to Class::Accessor::Grouped::mk_group_accessors
2311.03ms__PACKAGE__->mk_group_accessors(component_class => 'cursor_class');
# spent 1.03ms making 1 call to Class::Accessor::Grouped::mk_group_accessors
24
25125µs__PACKAGE__->cursor_class('DBIx::Class::Cursor');
# spent 25µs making 1 call to DBIx::Class::Storage::cursor_class
26
27sub cursor { shift->cursor_class(@_); }
28
29=head1 NAME
30
31DBIx::Class::Storage - Generic Storage Handler
32
33=head1 DESCRIPTION
34
35A base implementation of common Storage methods. For specific
36information about L<DBI>-based storage, see L<DBIx::Class::Storage::DBI>.
37
38=head1 METHODS
39
40=head2 new
41
42Arguments: $schema
43
44Instantiates the Storage object.
45
46=cut
47
48sub new {
49 my ($self, $schema) = @_;
50
51 $self = ref $self if ref $self;
52
53 my $new = bless( {
54 transaction_depth => 0,
55 savepoints => [],
56 }, $self);
57
581189µs $new->set_schema($schema);
# spent 189µs making 1 call to DBIx::Class::Storage::set_schema
59 $new->debug(1)
60 if $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG} || $ENV{DBIC_TRACE};
61
62 $new;
63}
64
65=head2 set_schema
66
67Used to reset the schema class or object which owns this
68storage object, such as during L<DBIx::Class::Schema/clone>.
69
70=cut
71
72
# spent 189µs (31+158) within DBIx::Class::Storage::set_schema which was called: # once (31µs+158µs) by DBIx::Class::Storage::DBI::new at line 58
sub set_schema {
73 my ($self, $schema) = @_;
741157µs $self->schema($schema);
# spent 157µs making 1 call to DBIx::Class::Storage::schema
7511µs weaken $self->{schema} if ref $self->{schema};
# spent 1µs making 1 call to Scalar::Util::weaken
76}
77
78=head2 connected
79
80Returns true if we have an open storage connection, false
81if it is not (yet) open.
82
83=cut
84
85sub connected { die "Virtual method!" }
86
87=head2 disconnect
88
89Closes any open storage connection unconditionally.
90
91=cut
92
93sub disconnect { die "Virtual method!" }
94
95=head2 ensure_connected
96
97Initiate a connection to the storage if one isn't already open.
98
99=cut
100
101sub ensure_connected { die "Virtual method!" }
102
103=head2 throw_exception
104
105Throws an exception - croaks.
106
107=cut
108
109sub throw_exception {
110 my $self = shift;
111
112 if (ref $self and $self->schema) {
113 $self->schema->throw_exception(@_);
114 }
115 else {
116 DBIx::Class::Exception->throw(@_);
117 }
118}
119
120=head2 txn_do
121
122=over 4
123
124=item Arguments: C<$coderef>, @coderef_args?
125
126=item Return Value: The return value of $coderef
127
128=back
129
130Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
131returning its result (if any). If an exception is caught, a rollback is issued
132and the exception is rethrown. If the rollback fails, (i.e. throws an
133exception) an exception is thrown that includes a "Rollback failed" message.
134
135For example,
136
137 my $author_rs = $schema->resultset('Author')->find(1);
138 my @titles = qw/Night Day It/;
139
140 my $coderef = sub {
141 # If any one of these fails, the entire transaction fails
142 $author_rs->create_related('books', {
143 title => $_
144 }) foreach (@titles);
145
146 return $author->books;
147 };
148
149 my $rs;
150 try {
151 $rs = $schema->txn_do($coderef);
152 } catch {
153 my $error = shift;
154 # Transaction failed
155 die "something terrible has happened!"
156 if ($error =~ /Rollback failed/); # Rollback failed
157
158 deal_with_failed_transaction();
159 };
160
161In a nested transaction (calling txn_do() from within a txn_do() coderef) only
162the outermost transaction will issue a L</txn_commit>, and txn_do() can be
163called in void, scalar and list context and it will behave as expected.
164
165Please note that all of the code in your coderef, including non-DBIx::Class
166code, is part of a transaction. This transaction may fail out halfway, or
167it may get partially double-executed (in the case that our DB connection
168failed halfway through the transaction, in which case we reconnect and
169restart the txn). Therefore it is best that any side-effects in your coderef
170are idempotent (that is, can be re-executed multiple times and get the
171same result), and that you check up on your side-effects in the case of
172transaction failure.
173
174=cut
175
176sub txn_do {
177 my $self = shift;
178
179 DBIx::Class::Storage::BlockRunner->new(
180 storage => $self,
181 wrap_txn => 1,
182 retry_handler => sub {
183 $_[0]->failed_attempt_count == 1
184 and
185 ! $_[0]->storage->connected
186 },
187 )->run(@_);
188}
189
190=head2 txn_begin
191
192Starts a transaction.
193
194See the preferred L</txn_do> method, which allows for
195an entire code block to be executed transactionally.
196
197=cut
198
199sub txn_begin {
200 my $self = shift;
201
202 if($self->transaction_depth == 0) {
203 $self->debugobj->txn_begin()
204 if $self->debug;
205 $self->_exec_txn_begin;
206 }
207 elsif ($self->auto_savepoint) {
208 $self->svp_begin;
209 }
210 $self->{transaction_depth}++;
211
212}
213
214=head2 txn_commit
215
216Issues a commit of the current transaction.
217
218It does I<not> perform an actual storage commit unless there's a DBIx::Class
219transaction currently in effect (i.e. you called L</txn_begin>).
220
221=cut
222
223sub txn_commit {
224 my $self = shift;
225
226 if ($self->transaction_depth == 1) {
227 $self->debugobj->txn_commit() if $self->debug;
228 $self->_exec_txn_commit;
229 $self->{transaction_depth}--;
230 $self->savepoints([]);
231 }
232 elsif($self->transaction_depth > 1) {
233 $self->{transaction_depth}--;
234 $self->svp_release if $self->auto_savepoint;
235 }
236 else {
237 $self->throw_exception( 'Refusing to commit without a started transaction' );
238 }
239}
240
241=head2 txn_rollback
242
243Issues a rollback of the current transaction. A nested rollback will
244throw a L<DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION> exception,
245which allows the rollback to propagate to the outermost transaction.
246
247=cut
248
249sub txn_rollback {
250 my $self = shift;
251
252 if ($self->transaction_depth == 1) {
253 $self->debugobj->txn_rollback() if $self->debug;
254 $self->_exec_txn_rollback;
255 $self->{transaction_depth}--;
256 $self->savepoints([]);
257 }
258 elsif ($self->transaction_depth > 1) {
259 $self->{transaction_depth}--;
260
261 if ($self->auto_savepoint) {
262 $self->svp_rollback;
263 $self->svp_release;
264 }
265 else {
266 DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION->throw(
267 "A txn_rollback in nested transaction is ineffective! (depth $self->{transaction_depth})"
268 );
269 }
270 }
271 else {
272 $self->throw_exception( 'Refusing to roll back without a started transaction' );
273 }
274}
275
276=head2 svp_begin
277
278Arguments: $savepoint_name?
279
280Created a new savepoint using the name provided as argument. If no name
281is provided, a random name will be used.
282
283=cut
284
285sub svp_begin {
286 my ($self, $name) = @_;
287
288 $self->throw_exception ("You can't use savepoints outside a transaction")
289 unless $self->transaction_depth;
290
291 my $exec = $self->can('_exec_svp_begin')
292 or $self->throw_exception ("Your Storage implementation doesn't support savepoints");
293
294 $name = $self->_svp_generate_name
295 unless defined $name;
296
297 push @{ $self->{savepoints} }, $name;
298
299 $self->debugobj->svp_begin($name) if $self->debug;
300
301 $exec->($self, $name);
302}
303
304sub _svp_generate_name {
305 my ($self) = @_;
306 return 'savepoint_'.scalar(@{ $self->{'savepoints'} });
307}
308
309
310=head2 svp_release
311
312Arguments: $savepoint_name?
313
314Release the savepoint provided as argument. If none is provided,
315release the savepoint created most recently. This will implicitly
316release all savepoints created after the one explicitly released as well.
317
318=cut
319
320sub svp_release {
321 my ($self, $name) = @_;
322
323 $self->throw_exception ("You can't use savepoints outside a transaction")
324 unless $self->transaction_depth;
325
326 my $exec = $self->can('_exec_svp_release')
327 or $self->throw_exception ("Your Storage implementation doesn't support savepoints");
328
329 if (defined $name) {
330 my @stack = @{ $self->savepoints };
331 my $svp;
332
333 do { $svp = pop @stack } until $svp eq $name;
334
335 $self->throw_exception ("Savepoint '$name' does not exist")
336 unless $svp;
337
338 $self->savepoints(\@stack); # put back what's left
339 }
340 else {
341 $name = pop @{ $self->savepoints }
342 or $self->throw_exception('No savepoints to release');;
343 }
344
345 $self->debugobj->svp_release($name) if $self->debug;
346
347 $exec->($self, $name);
348}
349
350=head2 svp_rollback
351
352Arguments: $savepoint_name?
353
354Rollback to the savepoint provided as argument. If none is provided,
355rollback to the savepoint created most recently. This will implicitly
356release all savepoints created after the savepoint we rollback to.
357
358=cut
359
360sub svp_rollback {
361 my ($self, $name) = @_;
362
363 $self->throw_exception ("You can't use savepoints outside a transaction")
364 unless $self->transaction_depth;
365
366 my $exec = $self->can('_exec_svp_rollback')
367 or $self->throw_exception ("Your Storage implementation doesn't support savepoints");
368
369 if (defined $name) {
370 my @stack = @{ $self->savepoints };
371 my $svp;
372
373 # a rollback doesn't remove the named savepoint,
374 # only everything after it
375 while (@stack and $stack[-1] ne $name) {
376 pop @stack
377 };
378
379 $self->throw_exception ("Savepoint '$name' does not exist")
380 unless @stack;
381
382 $self->savepoints(\@stack); # put back what's left
383 }
384 else {
385 $name = $self->savepoints->[-1]
386 or $self->throw_exception('No savepoints to rollback');;
387 }
388
389 $self->debugobj->svp_rollback($name) if $self->debug;
390
391 $exec->($self, $name);
392}
393
394=head2 txn_scope_guard
395
396An alternative way of transaction handling based on
397L<DBIx::Class::Storage::TxnScopeGuard>:
398
399 my $txn_guard = $storage->txn_scope_guard;
400
401 $result->col1("val1");
402 $result->update;
403
404 $txn_guard->commit;
405
406If an exception occurs, or the guard object otherwise leaves the scope
407before C<< $txn_guard->commit >> is called, the transaction will be rolled
408back by an explicit L</txn_rollback> call. In essence this is akin to
409using a L</txn_begin>/L</txn_commit> pair, without having to worry
410about calling L</txn_rollback> at the right places. Note that since there
411is no defined code closure, there will be no retries and other magic upon
412database disconnection. If you need such functionality see L</txn_do>.
413
414=cut
415
416sub txn_scope_guard {
417 return DBIx::Class::Storage::TxnScopeGuard->new($_[0]);
418}
419
420=head2 sql_maker
421
422Returns a C<sql_maker> object - normally an object of class
423C<DBIx::Class::SQLMaker>.
424
425=cut
426
427sub sql_maker { die "Virtual method!" }
428
429=head2 debug
430
431Causes trace information to be emitted on the L</debugobj> object.
432(or C<STDERR> if L</debugobj> has not specifically been set).
433
434This is the equivalent to setting L</DBIC_TRACE> in your
435shell environment.
436
437=head2 debugfh
438
439An opportunistic proxy to L<< ->debugobj->debugfh(@_)
440|DBIx::Class::Storage::Statistics/debugfh >>
441If the currently set L</debugobj> does not have a L</debugfh> method, caling
442this is a no-op.
443
444=cut
445
446sub debugfh {
447 my $self = shift;
448
449 if ($self->debugobj->can('debugfh')) {
450 return $self->debugobj->debugfh(@_);
451 }
452}
453
454=head2 debugobj
455
456Sets or retrieves the object used for metric collection. Defaults to an instance
457of L<DBIx::Class::Storage::Statistics> that is compatible with the original
458method of using a coderef as a callback. See the aforementioned Statistics
459class for more information.
460
461=cut
462
463sub debugobj {
464 my $self = shift;
465
466 if (@_) {
467 return $self->{debugobj} = $_[0];
468 }
469
470 $self->{debugobj} ||= do {
471 if (my $profile = $ENV{DBIC_TRACE_PROFILE}) {
472 require DBIx::Class::Storage::Debug::PrettyPrint;
473 my @pp_args;
474
475 if ($profile =~ /^\.?\//) {
476 require Config::Any;
477
478 my $cfg = try {
479 Config::Any->load_files({ files => [$profile], use_ext => 1 });
480 } catch {
481 # sanitize the error message a bit
482 $_ =~ s/at \s+ .+ Storage\.pm \s line \s \d+ $//x;
483 $self->throw_exception("Failure processing \$ENV{DBIC_TRACE_PROFILE}: $_");
484 };
485
486 @pp_args = values %{$cfg->[0]};
487 }
488 else {
489 @pp_args = { profile => $profile };
490 }
491
492 # FIXME - FRAGILE
493 # Hash::Merge is a sorry piece of shit and tramples all over $@
494 # *without* throwing an exception
495 # This is a rather serious problem in the debug codepath
496 # Insulate the condition here with a try{} until a review of
497 # DBIx::Class::Storage::Debug::PrettyPrint takes place
498 # we do rethrow the error unconditionally, the only reason
499 # to try{} is to preserve the precise state of $@ (down
500 # to the scalar (if there is one) address level)
501 #
502 # Yes I am aware this is fragile and TxnScopeGuard needs
503 # a better fix. This is another yak to shave... :(
504 try {
505 DBIx::Class::Storage::Debug::PrettyPrint->new(@pp_args);
506 } catch {
507 $self->throw_exception($_);
508 }
509 }
510 else {
511 require DBIx::Class::Storage::Statistics;
512 DBIx::Class::Storage::Statistics->new
513 }
514 };
515}
516
517=head2 debugcb
518
519Sets a callback to be executed each time a statement is run; takes a sub
520reference. Callback is executed as $sub->($op, $info) where $op is
521SELECT/INSERT/UPDATE/DELETE and $info is what would normally be printed.
522
523See L</debugobj> for a better way.
524
525=cut
526
527sub debugcb {
528 my $self = shift;
529
530 if ($self->debugobj->can('callback')) {
531 return $self->debugobj->callback(@_);
532 }
533}
534
535=head2 cursor_class
536
537The cursor class for this Storage object.
538
539=cut
540
541=head2 deploy
542
543Deploy the tables to storage (CREATE TABLE and friends in a SQL-based
544Storage class). This would normally be called through
545L<DBIx::Class::Schema/deploy>.
546
547=cut
548
549sub deploy { die "Virtual method!" }
550
551=head2 connect_info
552
553The arguments of C<connect_info> are always a single array reference,
554and are Storage-handler specific.
555
556This is normally accessed via L<DBIx::Class::Schema/connection>, which
557encapsulates its argument list in an arrayref before calling
558C<connect_info> here.
559
560=cut
561
562sub connect_info { die "Virtual method!" }
563
564=head2 select
565
566Handle a select statement.
567
568=cut
569
570sub select { die "Virtual method!" }
571
572=head2 insert
573
574Handle an insert statement.
575
576=cut
577
578sub insert { die "Virtual method!" }
579
580=head2 update
581
582Handle an update statement.
583
584=cut
585
586sub update { die "Virtual method!" }
587
588=head2 delete
589
590Handle a delete statement.
591
592=cut
593
594sub delete { die "Virtual method!" }
595
596=head2 select_single
597
598Performs a select, fetch and return of data - handles a single row
599only.
600
601=cut
602
603sub select_single { die "Virtual method!" }
604
605=head2 columns_info_for
606
607Returns metadata for the given source's columns. This
608is *deprecated*, and will be removed before 1.0. You should
609be specifying the metadata yourself if you need it.
610
611=cut
612
613sub columns_info_for { die "Virtual method!" }
614
615=head1 ENVIRONMENT VARIABLES
616
617=head2 DBIC_TRACE
618
619If C<DBIC_TRACE> is set then trace information
620is produced (as when the L</debug> method is set).
621
622If the value is of the form C<1=/path/name> then the trace output is
623written to the file C</path/name>.
624
625This environment variable is checked when the storage object is first
626created (when you call connect on your schema). So, run-time changes
627to this environment variable will not take effect unless you also
628re-connect on your schema.
629
630=head2 DBIC_TRACE_PROFILE
631
632If C<DBIC_TRACE_PROFILE> is set, L<DBIx::Class::Storage::Debug::PrettyPrint>
633will be used to format the output from C<DBIC_TRACE>. The value it
634is set to is the C<profile> that it will be used. If the value is a
635filename the file is read with L<Config::Any> and the results are
636used as the configuration for tracing. See L<SQL::Abstract::Tree/new>
637for what that structure should look like.
638
639=head2 DBIX_CLASS_STORAGE_DBI_DEBUG
640
641Old name for DBIC_TRACE
642
643=head1 SEE ALSO
644
645L<DBIx::Class::Storage::DBI> - reference storage implementation using
646SQL::Abstract and DBI.
647
648=head1 FURTHER QUESTIONS?
649
650Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
651
652=head1 COPYRIGHT AND LICENSE
653
654This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
655by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
656redistribute it and/or modify it under the same terms as the
657L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
658
659=cut
660
6611188µs1;
# spent 188µs making 1 call to B::Hooks::EndOfScope::XS::__ANON__