1 package DBIx::Class::Storage;
6 use base qw/DBIx::Class/;
9 use DBIx::Class::Exception;
10 use Scalar::Util 'weaken';
12 use DBIx::Class::Storage::TxnScopeGuard;
16 __PACKAGE__->mk_group_accessors('simple' => qw/debug debugobj schema/);
17 __PACKAGE__->mk_group_accessors('inherited' => 'cursor_class');
19 __PACKAGE__->cursor_class('DBIx::Class::Cursor');
21 sub cursor { shift->cursor_class(@_); }
23 package # Hide from PAUSE
24 DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION;
26 use overload '"' => sub {
27 'DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION'
33 return bless $self, $class;
36 package DBIx::Class::Storage;
40 DBIx::Class::Storage - Generic Storage Handler
44 A base implementation of common Storage methods. For specific
45 information about L<DBI>-based storage, see L<DBIx::Class::Storage::DBI>.
53 Instantiates the Storage object.
58 my ($self, $schema) = @_;
60 $self = ref $self if ref $self;
65 $new->set_schema($schema);
66 $new->debugobj(new DBIx::Class::Storage::Statistics());
70 my $debug_env = $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG}
73 $new->debug(1) if $debug_env;
80 Used to reset the schema class or object which owns this
81 storage object, such as during L<DBIx::Class::Schema/clone>.
86 my ($self, $schema) = @_;
87 $self->schema($schema);
88 weaken $self->{schema} if ref $self->{schema};
93 Returns true if we have an open storage connection, false
94 if it is not (yet) open.
98 sub connected { die "Virtual method!" }
102 Closes any open storage connection unconditionally.
106 sub disconnect { die "Virtual method!" }
108 =head2 ensure_connected
110 Initiate a connection to the storage if one isn't already open.
114 sub ensure_connected { die "Virtual method!" }
116 =head2 throw_exception
118 Throws an exception - croaks.
122 sub throw_exception {
126 $self->schema->throw_exception(@_);
129 DBIx::Class::Exception->throw(@_);
137 =item Arguments: C<$coderef>, @coderef_args?
139 =item Return Value: The return value of $coderef
143 Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
144 returning its result (if any). If an exception is caught, a rollback is issued
145 and the exception is rethrown. If the rollback fails, (i.e. throws an
146 exception) an exception is thrown that includes a "Rollback failed" message.
150 my $author_rs = $schema->resultset('Author')->find(1);
151 my @titles = qw/Night Day It/;
154 # If any one of these fails, the entire transaction fails
155 $author_rs->create_related('books', {
157 }) foreach (@titles);
159 return $author->books;
164 $rs = $schema->txn_do($coderef);
168 die "something terrible has happened!" #
169 if ($error =~ /Rollback failed/); # Rollback failed
171 deal_with_failed_transaction();
174 In a nested transaction (calling txn_do() from within a txn_do() coderef) only
175 the outermost transaction will issue a L</txn_commit>, and txn_do() can be
176 called in void, scalar and list context and it will behave as expected.
178 Please note that all of the code in your coderef, including non-DBIx::Class
179 code, is part of a transaction. This transaction may fail out halfway, or
180 it may get partially double-executed (in the case that our DB connection
181 failed halfway through the transaction, in which case we reconnect and
182 restart the txn). Therefore it is best that any side-effects in your coderef
183 are idempotent (that is, can be re-executed multiple times and get the
184 same result), and that you check up on your side-effects in the case of
193 ref $coderef eq 'CODE' or $self->throw_exception
194 ('$coderef must be a CODE reference');
196 my (@return_values, $return_value);
198 $self->txn_begin; # If this throws an exception, no rollback is needed
200 my $wantarray = wantarray; # Need to save this since the context
201 # inside the try{} block is independent
202 # of the context that called txn_do()
207 # Need to differentiate between scalar/list context to allow for
208 # returning a list in scalar context to get the size of the list
211 @return_values = $coderef->(@$args);
212 } elsif (defined $wantarray) {
214 $return_value = $coderef->(@$args);
227 my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
228 $self->throw_exception($error) # propagate nested rollback
229 if $_ =~ /$exception_class/;
231 $self->throw_exception(
232 "Transaction aborted: $error. Rollback failed: $_"
235 $self->throw_exception($error); # txn failed but rollback succeeded
238 return $wantarray ? @return_values : $return_value;
243 Starts a transaction.
245 See the preferred L</txn_do> method, which allows for
246 an entire code block to be executed transactionally.
250 sub txn_begin { die "Virtual method!" }
254 Issues a commit of the current transaction.
256 It does I<not> perform an actual storage commit unless there's a DBIx::Class
257 transaction currently in effect (i.e. you called L</txn_begin>).
261 sub txn_commit { die "Virtual method!" }
265 Issues a rollback of the current transaction. A nested rollback will
266 throw a L<DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION> exception,
267 which allows the rollback to propagate to the outermost transaction.
271 sub txn_rollback { die "Virtual method!" }
275 Arguments: $savepoint_name?
277 Created a new savepoint using the name provided as argument. If no name
278 is provided, a random name will be used.
282 sub svp_begin { die "Virtual method!" }
286 Arguments: $savepoint_name?
288 Release the savepoint provided as argument. If none is provided,
289 release the savepoint created most recently. This will implicitly
290 release all savepoints created after the one explicitly released as well.
294 sub svp_release { die "Virtual method!" }
298 Arguments: $savepoint_name?
300 Rollback to the savepoint provided as argument. If none is provided,
301 rollback to the savepoint created most recently. This will implicitly
302 release all savepoints created after the savepoint we rollback to.
306 sub svp_rollback { die "Virtual method!" }
310 =head2 txn_scope_guard
312 An alternative way of transaction handling based on
313 L<DBIx::Class::Storage::TxnScopeGuard>:
315 my $txn_guard = $storage->txn_scope_guard;
322 If an exception occurs, or the guard object otherwise leaves the scope
323 before C<< $txn_guard->commit >> is called, the transaction will be rolled
324 back by an explicit L</txn_rollback> call. In essence this is akin to
325 using a L</txn_begin>/L</txn_commit> pair, without having to worry
326 about calling L</txn_rollback> at the right places. Note that since there
327 is no defined code closure, there will be no retries and other magic upon
328 database disconnection. If you need such functionality see L</txn_do>.
332 sub txn_scope_guard {
333 return DBIx::Class::Storage::TxnScopeGuard->new($_[0]);
338 Returns a C<sql_maker> object - normally an object of class
339 C<DBIx::Class::SQLAHacks>.
343 sub sql_maker { die "Virtual method!" }
347 Causes trace information to be emitted on the C<debugobj> object.
348 (or C<STDERR> if C<debugobj> has not specifically been set).
350 This is the equivalent to setting L</DBIC_TRACE> in your
355 Set or retrieve the filehandle used for trace/debug output. This should be
356 an IO::Handle compatible object (only the C<print> method is used. Initially
357 set to be STDERR - although see information on the
358 L<DBIC_TRACE> environment variable.
365 if ($self->debugobj->can('debugfh')) {
366 return $self->debugobj->debugfh(@_);
372 Sets or retrieves the object used for metric collection. Defaults to an instance
373 of L<DBIx::Class::Storage::Statistics> that is compatible with the original
374 method of using a coderef as a callback. See the aforementioned Statistics
375 class for more information.
379 Sets a callback to be executed each time a statement is run; takes a sub
380 reference. Callback is executed as $sub->($op, $info) where $op is
381 SELECT/INSERT/UPDATE/DELETE and $info is what would normally be printed.
383 See L<debugobj> for a better way.
390 if ($self->debugobj->can('callback')) {
391 return $self->debugobj->callback(@_);
397 The cursor class for this Storage object.
403 Deploy the tables to storage (CREATE TABLE and friends in a SQL-based
404 Storage class). This would normally be called through
405 L<DBIx::Class::Schema/deploy>.
409 sub deploy { die "Virtual method!" }
413 The arguments of C<connect_info> are always a single array reference,
414 and are Storage-handler specific.
416 This is normally accessed via L<DBIx::Class::Schema/connection>, which
417 encapsulates its argument list in an arrayref before calling
418 C<connect_info> here.
422 sub connect_info { die "Virtual method!" }
426 Handle a select statement.
430 sub select { die "Virtual method!" }
434 Handle an insert statement.
438 sub insert { die "Virtual method!" }
442 Handle an update statement.
446 sub update { die "Virtual method!" }
450 Handle a delete statement.
454 sub delete { die "Virtual method!" }
458 Performs a select, fetch and return of data - handles a single row
463 sub select_single { die "Virtual method!" }
465 =head2 columns_info_for
467 Returns metadata for the given source's columns. This
468 is *deprecated*, and will be removed before 1.0. You should
469 be specifying the metadata yourself if you need it.
473 sub columns_info_for { die "Virtual method!" }
475 =head1 ENVIRONMENT VARIABLES
479 If C<DBIC_TRACE> is set then trace information
480 is produced (as when the L<debug> method is set).
482 If the value is of the form C<1=/path/name> then the trace output is
483 written to the file C</path/name>.
485 This environment variable is checked when the storage object is first
486 created (when you call connect on your schema). So, run-time changes
487 to this environment variable will not take effect unless you also
488 re-connect on your schema.
490 =head2 DBIX_CLASS_STORAGE_DBI_DEBUG
492 Old name for DBIC_TRACE
496 L<DBIx::Class::Storage::DBI> - reference storage implementation using
497 SQL::Abstract and DBI.
501 Matt S. Trout <mst@shadowcatsystems.co.uk>
503 Andy Grundman <andy@hybridized.org>
507 You may distribute this code under the same terms as Perl itself.