1 package DBIx::Class::Storage;
6 use base qw/DBIx::Class/;
8 use Scalar::Util qw/weaken/;
9 use Carp::Clan qw/^DBIx::Class/;
11 use DBIx::Class::Storage::TxnScopeGuard;
13 __PACKAGE__->mk_group_accessors('simple' => qw/debug debugobj schema/);
14 __PACKAGE__->mk_group_accessors('inherited' => 'cursor_class');
16 __PACKAGE__->cursor_class('DBIx::Class::Cursor');
18 sub cursor { shift->cursor_class(@_); }
20 package # Hide from PAUSE
21 DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION;
23 use overload '"' => sub {
24 'DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION'
30 return bless $self, $class;
33 package DBIx::Class::Storage;
37 DBIx::Class::Storage - Generic Storage Handler
41 A base implementation of common Storage methods. For specific
42 information about L<DBI>-based storage, see L<DBIx::Class::Storage::DBI>.
50 Instantiates the Storage object.
55 my ($self, $schema) = @_;
57 $self = ref $self if ref $self;
62 $new->set_schema($schema);
63 $new->debugobj(new DBIx::Class::Storage::Statistics());
67 my $debug_env = $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG}
70 $new->debug(1) if $debug_env;
77 Used to reset the schema class or object which owns this
78 storage object, such as during L<DBIx::Class::Schema/clone>.
83 my ($self, $schema) = @_;
84 $self->schema($schema);
85 weaken($self->{schema}) if ref $self->{schema};
90 Returns true if we have an open storage connection, false
91 if it is not (yet) open.
95 sub connected { die "Virtual method!" }
99 Closes any open storage connection unconditionally.
103 sub disconnect { die "Virtual method!" }
105 =head2 ensure_connected
107 Initiate a connection to the storage if one isn't already open.
111 sub ensure_connected { die "Virtual method!" }
113 =head2 throw_exception
115 Throws an exception - croaks.
119 sub throw_exception {
122 $self->schema->throw_exception(@_) if $self->schema;
130 =item Arguments: C<$coderef>, @coderef_args?
132 =item Return Value: The return value of $coderef
136 Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
137 returning its result (if any). If an exception is caught, a rollback is issued
138 and the exception is rethrown. If the rollback fails, (i.e. throws an
139 exception) an exception is thrown that includes a "Rollback failed" message.
143 my $author_rs = $schema->resultset('Author')->find(1);
144 my @titles = qw/Night Day It/;
147 # If any one of these fails, the entire transaction fails
148 $author_rs->create_related('books', {
150 }) foreach (@titles);
152 return $author->books;
157 $rs = $schema->txn_do($coderef);
160 if ($@) { # Transaction failed
161 die "something terrible has happened!" #
162 if ($@ =~ /Rollback failed/); # Rollback failed
164 deal_with_failed_transaction();
167 In a nested transaction (calling txn_do() from within a txn_do() coderef) only
168 the outermost transaction will issue a L</txn_commit>, and txn_do() can be
169 called in void, scalar and list context and it will behave as expected.
171 Please note that all of the code in your coderef, including non-DBIx::Class
172 code, is part of a transaction. This transaction may fail out halfway, or
173 it may get partially double-executed (in the case that our DB connection
174 failed halfway through the transaction, in which case we reconnect and
175 restart the txn). Therefore it is best that any side-effects in your coderef
176 are idempotent (that is, can be re-executed multiple times and get the
177 same result), and that you check up on your side-effects in the case of
183 my ($self, $coderef, @args) = @_;
185 ref $coderef eq 'CODE' or $self->throw_exception
186 ('$coderef must be a CODE reference');
188 my (@return_values, $return_value);
190 $self->txn_begin; # If this throws an exception, no rollback is needed
192 my $wantarray = wantarray; # Need to save this since the context
193 # inside the eval{} block is independent
194 # of the context that called txn_do()
197 # Need to differentiate between scalar/list context to allow for
198 # returning a list in scalar context to get the size of the list
201 @return_values = $coderef->(@args);
202 } elsif (defined $wantarray) {
204 $return_value = $coderef->(@args);
220 my $rollback_error = $@;
221 my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
222 $self->throw_exception($error) # propagate nested rollback
223 if $rollback_error =~ /$exception_class/;
225 $self->throw_exception(
226 "Transaction aborted: $error. Rollback failed: ${rollback_error}"
229 $self->throw_exception($error); # txn failed but rollback succeeded
233 return $wantarray ? @return_values : $return_value;
238 Starts a transaction.
240 See the preferred L</txn_do> method, which allows for
241 an entire code block to be executed transactionally.
245 sub txn_begin { die "Virtual method!" }
249 Issues a commit of the current transaction.
253 sub txn_commit { die "Virtual method!" }
257 Issues a rollback of the current transaction. A nested rollback will
258 throw a L<DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION> exception,
259 which allows the rollback to propagate to the outermost transaction.
263 sub txn_rollback { die "Virtual method!" }
267 Arguments: $savepoint_name?
269 Created a new savepoint using the name provided as argument. If no name
270 is provided, a random name will be used.
274 sub svp_begin { die "Virtual method!" }
278 Arguments: $savepoint_name?
280 Release the savepoint provided as argument. If none is provided,
281 release the savepoint created most recently. This will implicitly
282 release all savepoints created after the one explicitly released as well.
286 sub svp_release { die "Virtual method!" }
290 Arguments: $savepoint_name?
292 Rollback to the savepoint provided as argument. If none is provided,
293 rollback to the savepoint created most recently. This will implicitly
294 release all savepoints created after the savepoint we rollback to.
298 sub svp_rollback { die "Virtual method!" }
302 =head2 txn_scope_guard (EXPERIMENTAL)
304 An alternative way of using transactions to C<txn_do>:
306 my $txn = $storage->txn_scope_guard;
313 If a exception occurs, the transaction will be rolled back. This is still very
314 experiemental, and we are not 100% sure it is working right when nested. The
315 onus is on you as the user to make sure you dont forget to call
320 sub txn_scope_guard {
321 return DBIx::Class::Storage::TxnScopeGuard->new($_[0]);
326 Returns a C<sql_maker> object - normally an object of class
327 C<DBIC::SQL::Abstract>.
331 sub sql_maker { die "Virtual method!" }
335 Causes trace information to be emitted on the C<debugobj> object.
336 (or C<STDERR> if C<debugobj> has not specifically been set).
338 This is the equivalent to setting L</DBIC_TRACE> in your
343 Set or retrieve the filehandle used for trace/debug output. This should be
344 an IO::Handle compatible ojbect (only the C<print> method is used. Initially
345 set to be STDERR - although see information on the
346 L<DBIC_TRACE> environment variable.
353 if ($self->debugobj->can('debugfh')) {
354 return $self->debugobj->debugfh(@_);
360 Sets or retrieves the object used for metric collection. Defaults to an instance
361 of L<DBIx::Class::Storage::Statistics> that is compatible with the original
362 method of using a coderef as a callback. See the aforementioned Statistics
363 class for more information.
367 Sets a callback to be executed each time a statement is run; takes a sub
368 reference. Callback is executed as $sub->($op, $info) where $op is
369 SELECT/INSERT/UPDATE/DELETE and $info is what would normally be printed.
371 See L<debugobj> for a better way.
378 if ($self->debugobj->can('callback')) {
379 return $self->debugobj->callback(@_);
385 The cursor class for this Storage object.
391 Deploy the tables to storage (CREATE TABLE and friends in a SQL-based
392 Storage class). This would normally be called through
393 L<DBIx::Class::Schema/deploy>.
397 sub deploy { die "Virtual method!" }
401 The arguments of C<connect_info> are always a single array reference,
402 and are Storage-handler specific.
404 This is normally accessed via L<DBIx::Class::Schema/connection>, which
405 encapsulates its argument list in an arrayref before calling
406 C<connect_info> here.
410 sub connect_info { die "Virtual method!" }
414 Handle a select statement.
418 sub select { die "Virtual method!" }
422 Handle an insert statement.
426 sub insert { die "Virtual method!" }
430 Handle an update statement.
434 sub update { die "Virtual method!" }
438 Handle a delete statement.
442 sub delete { die "Virtual method!" }
446 Performs a select, fetch and return of data - handles a single row
451 sub select_single { die "Virtual method!" }
453 =head2 columns_info_for
455 Returns metadata for the given source's columns. This
456 is *deprecated*, and will be removed before 1.0. You should
457 be specifying the metadata yourself if you need it.
461 sub columns_info_for { die "Virtual method!" }
463 =head1 ENVIRONMENT VARIABLES
467 If C<DBIC_TRACE> is set then trace information
468 is produced (as when the L<debug> method is set).
470 If the value is of the form C<1=/path/name> then the trace output is
471 written to the file C</path/name>.
473 This environment variable is checked when the storage object is first
474 created (when you call connect on your schema). So, run-time changes
475 to this environment variable will not take effect unless you also
476 re-connect on your schema.
478 =head2 DBIX_CLASS_STORAGE_DBI_DEBUG
480 Old name for DBIC_TRACE
484 L<DBIx::Class::Storage::DBI> - reference storage implementation using
485 SQL::Abstract and DBI.
489 Matt S. Trout <mst@shadowcatsystems.co.uk>
491 Andy Grundman <andy@hybridized.org>
495 You may distribute this code under the same terms as Perl itself.