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 Unlike L</DBIx::Class::Storage/dbh_do>, the coderef will I<not> be
172 automatically retried on error.
177 my ($self, $coderef, @args) = @_;
179 ref $coderef eq 'CODE' or $self->throw_exception
180 ('$coderef must be a CODE reference');
182 my (@return_values, $return_value);
184 $self->txn_begin; # If this throws an exception, no rollback is needed
186 my $wantarray = wantarray; # Need to save this since the context
187 # inside the eval{} block is independent
188 # of the context that called txn_do()
191 # Need to differentiate between scalar/list context to allow for
192 # returning a list in scalar context to get the size of the list
195 @return_values = $coderef->(@args);
196 } elsif (defined $wantarray) {
198 $return_value = $coderef->(@args);
214 my $rollback_error = $@;
215 my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
216 $self->throw_exception($error) # propagate nested rollback
217 if $rollback_error =~ /$exception_class/;
219 $self->throw_exception(
220 "Transaction aborted: $error. Rollback failed: ${rollback_error}"
223 $self->throw_exception($error); # txn failed but rollback succeeded
227 return $wantarray ? @return_values : $return_value;
232 Starts a transaction.
234 See the preferred L</txn_do> method, which allows for
235 an entire code block to be executed transactionally.
239 sub txn_begin { die "Virtual method!" }
243 Issues a commit of the current transaction.
245 It does I<not> perform an actual storage commit unless there's a DBIx::Class
246 transaction currently in effect (i.e. you called L</txn_begin>).
250 sub txn_commit { die "Virtual method!" }
254 Issues a rollback of the current transaction. A nested rollback will
255 throw a L<DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION> exception,
256 which allows the rollback to propagate to the outermost transaction.
260 sub txn_rollback { die "Virtual method!" }
264 Arguments: $savepoint_name?
266 Created a new savepoint using the name provided as argument. If no name
267 is provided, a random name will be used.
271 sub svp_begin { die "Virtual method!" }
275 Arguments: $savepoint_name?
277 Release the savepoint provided as argument. If none is provided,
278 release the savepoint created most recently. This will implicitly
279 release all savepoints created after the one explicitly released as well.
283 sub svp_release { die "Virtual method!" }
287 Arguments: $savepoint_name?
289 Rollback to the savepoint provided as argument. If none is provided,
290 rollback to the savepoint created most recently. This will implicitly
291 release all savepoints created after the savepoint we rollback to.
295 sub svp_rollback { die "Virtual method!" }
299 =head2 txn_scope_guard
301 An alternative way of transaction handling based on
302 L<DBIx::Class::Storage::TxnScopeGuard>:
304 my $txn_guard = $storage->txn_scope_guard;
311 If an exception occurs, or the guard object otherwise leaves the scope
312 before C<< $txn_guard->commit >> is called, the transaction will be rolled
313 back by an explicit L</txn_rollback> call. In essence this is akin to
314 using a L</txn_begin>/L</txn_commit> pair, without having to worry
315 about calling L</txn_rollback> at the right places. Note that since there
316 is no defined code closure, there will be no retries and other magic upon
317 database disconnection. If you need such functionality see L</txn_do>.
321 sub txn_scope_guard {
322 return DBIx::Class::Storage::TxnScopeGuard->new($_[0]);
327 Returns a C<sql_maker> object - normally an object of class
328 C<DBIx::Class::SQLAHacks>.
332 sub sql_maker { die "Virtual method!" }
336 Causes trace information to be emitted on the C<debugobj> object.
337 (or C<STDERR> if C<debugobj> has not specifically been set).
339 This is the equivalent to setting L</DBIC_TRACE> in your
344 Set or retrieve the filehandle used for trace/debug output. This should be
345 an IO::Handle compatible ojbect (only the C<print> method is used. Initially
346 set to be STDERR - although see information on the
347 L<DBIC_TRACE> environment variable.
354 if ($self->debugobj->can('debugfh')) {
355 return $self->debugobj->debugfh(@_);
361 Sets or retrieves the object used for metric collection. Defaults to an instance
362 of L<DBIx::Class::Storage::Statistics> that is compatible with the original
363 method of using a coderef as a callback. See the aforementioned Statistics
364 class for more information.
368 Sets a callback to be executed each time a statement is run; takes a sub
369 reference. Callback is executed as $sub->($op, $info) where $op is
370 SELECT/INSERT/UPDATE/DELETE and $info is what would normally be printed.
372 See L<debugobj> for a better way.
379 if ($self->debugobj->can('callback')) {
380 return $self->debugobj->callback(@_);
386 The cursor class for this Storage object.
392 Deploy the tables to storage (CREATE TABLE and friends in a SQL-based
393 Storage class). This would normally be called through
394 L<DBIx::Class::Schema/deploy>.
398 sub deploy { die "Virtual method!" }
402 The arguments of C<connect_info> are always a single array reference,
403 and are Storage-handler specific.
405 This is normally accessed via L<DBIx::Class::Schema/connection>, which
406 encapsulates its argument list in an arrayref before calling
407 C<connect_info> here.
411 sub connect_info { die "Virtual method!" }
415 Handle a select statement.
419 sub select { die "Virtual method!" }
423 Handle an insert statement.
427 sub insert { die "Virtual method!" }
431 Handle an update statement.
435 sub update { die "Virtual method!" }
439 Handle a delete statement.
443 sub delete { die "Virtual method!" }
447 Performs a select, fetch and return of data - handles a single row
452 sub select_single { die "Virtual method!" }
454 =head2 columns_info_for
456 Returns metadata for the given source's columns. This
457 is *deprecated*, and will be removed before 1.0. You should
458 be specifying the metadata yourself if you need it.
462 sub columns_info_for { die "Virtual method!" }
464 =head1 ENVIRONMENT VARIABLES
468 If C<DBIC_TRACE> is set then trace information
469 is produced (as when the L<debug> method is set).
471 If the value is of the form C<1=/path/name> then the trace output is
472 written to the file C</path/name>.
474 This environment variable is checked when the storage object is first
475 created (when you call connect on your schema). So, run-time changes
476 to this environment variable will not take effect unless you also
477 re-connect on your schema.
479 =head2 DBIX_CLASS_STORAGE_DBI_DEBUG
481 Old name for DBIC_TRACE
485 L<DBIx::Class::Storage::DBI> - reference storage implementation using
486 SQL::Abstract and DBI.
490 Matt S. Trout <mst@shadowcatsystems.co.uk>
492 Andy Grundman <andy@hybridized.org>
496 You may distribute this code under the same terms as Perl itself.