1 package DBIx::Class::Storage;
6 use base qw/DBIx::Class/;
8 use Scalar::Util qw/weaken/;
9 use Carp::Clan qw/^DBIx::Class/;
12 __PACKAGE__->mk_group_accessors('simple' => qw/debug debugobj schema/);
14 package # Hide from PAUSE
15 DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION;
17 use overload '"' => sub {
18 'DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION'
24 return bless $self, $class;
27 package DBIx::Class::Storage;
31 DBIx::Class::Storage - Generic Storage Handler
35 A base implementation of common Storage methods. For specific
36 information about L<DBI>-based storage, see L<DBIx::Class::Storage::DBI>.
44 Instantiates the Storage object.
49 my ($self, $schema) = @_;
51 $self = ref $self if ref $self;
56 $new->set_schema($schema);
57 $new->debugobj(new DBIx::Class::Storage::Statistics());
61 my $debug_env = $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG}
64 if (defined($debug_env) && ($debug_env =~ /=(.+)$/)) {
65 $fh = IO::File->new($1, 'w')
66 or $new->throw_exception("Cannot open trace file $1");
68 $fh = IO::File->new('>&STDERR');
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 {
125 $self->schema->throw_exception(@_) if $self->schema;
133 =item Arguments: C<$coderef>, @coderef_args?
135 =item Return Value: The return value of $coderef
139 Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
140 returning its result (if any). If an exception is caught, a rollback is issued
141 and the exception is rethrown. If the rollback fails, (i.e. throws an
142 exception) an exception is thrown that includes a "Rollback failed" message.
146 my $author_rs = $schema->resultset('Author')->find(1);
147 my @titles = qw/Night Day It/;
150 # If any one of these fails, the entire transaction fails
151 $author_rs->create_related('books', {
153 }) foreach (@titles);
155 return $author->books;
160 $rs = $schema->txn_do($coderef);
163 if ($@) { # Transaction failed
164 die "something terrible has happened!" #
165 if ($@ =~ /Rollback failed/); # Rollback failed
167 deal_with_failed_transaction();
170 In a nested transaction (calling txn_do() from within a txn_do() coderef) only
171 the outermost transaction will issue a L</txn_commit>, and txn_do() can be
172 called in void, scalar and list context and it will behave as expected.
174 Please note that all of the code in your coderef, including non-DBIx::Class
175 code, is part of a transaction. This transaction may fail out halfway, or
176 it may get partially double-executed (in the case that our DB connection
177 failed halfway through the transaction, in which case we reconnect and
178 restart the txn). Therefore it is best that any side-effects in your coderef
179 are idempotent (that is, can be re-executed multiple times and get the
180 same result), and that you check up on your side-effects in the case of
186 my ($self, $coderef, @args) = @_;
188 ref $coderef eq 'CODE' or $self->throw_exception
189 ('$coderef must be a CODE reference');
191 my (@return_values, $return_value);
193 $self->txn_begin; # If this throws an exception, no rollback is needed
195 my $wantarray = wantarray; # Need to save this since the context
196 # inside the eval{} block is independent
197 # of the context that called txn_do()
200 # Need to differentiate between scalar/list context to allow for
201 # returning a list in scalar context to get the size of the list
204 @return_values = $coderef->(@args);
205 } elsif (defined $wantarray) {
207 $return_value = $coderef->(@args);
223 my $rollback_error = $@;
224 my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
225 $self->throw_exception($error) # propagate nested rollback
226 if $rollback_error =~ /$exception_class/;
228 $self->throw_exception(
229 "Transaction aborted: $error. Rollback failed: ${rollback_error}"
232 $self->throw_exception($error); # txn failed but rollback succeeded
236 return $wantarray ? @return_values : $return_value;
241 Starts a transaction.
243 See the preferred L</txn_do> method, which allows for
244 an entire code block to be executed transactionally.
248 sub txn_begin { die "Virtual method!" }
252 Issues a commit of the current transaction.
256 sub txn_commit { die "Virtual method!" }
260 Issues a rollback of the current transaction. A nested rollback will
261 throw a L<DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION> exception,
262 which allows the rollback to propagate to the outermost transaction.
266 sub txn_rollback { die "Virtual method!" }
270 Returns a C<sql_maker> object - normally an object of class
271 C<DBIC::SQL::Abstract>.
275 sub sql_maker { die "Virtual method!" }
279 Causes trace information to be emitted on the C<debugobj> object.
280 (or C<STDERR> if C<debugobj> has not specifically been set).
282 This is the equivalent to setting L</DBIC_TRACE> in your
287 Set or retrieve the filehandle used for trace/debug output. This should be
288 an IO::Handle compatible ojbect (only the C<print> method is used. Initially
289 set to be STDERR - although see information on the
290 L<DBIC_TRACE> environment variable.
297 if ($self->debugobj->can('debugfh')) {
298 return $self->debugobj->debugfh(@_);
304 Sets or retrieves the object used for metric collection. Defaults to an instance
305 of L<DBIx::Class::Storage::Statistics> that is compatible with the original
306 method of using a coderef as a callback. See the aforementioned Statistics
307 class for more information.
311 Sets a callback to be executed each time a statement is run; takes a sub
312 reference. Callback is executed as $sub->($op, $info) where $op is
313 SELECT/INSERT/UPDATE/DELETE and $info is what would normally be printed.
315 See L<debugobj> for a better way.
322 if ($self->debugobj->can('callback')) {
323 return $self->debugobj->callback(@_);
329 The cursor class for this Storage object.
333 sub cursor { die "Virtual method!" }
337 Deploy the tables to storage (CREATE TABLE and friends in a SQL-based
338 Storage class). This would normally be called through
339 L<DBIx::Class::Schema/deploy>.
343 sub deploy { die "Virtual method!" }
347 The arguments of C<connect_info> are always a single array reference,
348 and are Storage-handler specific.
350 This is normally accessed via L<DBIx::Class::Schema/connection>, which
351 encapsulates its argument list in an arrayref before calling
352 C<connect_info> here.
356 sub connect_info { die "Virtual method!" }
360 Handle a select statement.
364 sub select { die "Virtual method!" }
368 Handle an insert statement.
372 sub insert { die "Virtual method!" }
376 Handle an update statement.
380 sub update { die "Virtual method!" }
384 Handle a delete statement.
388 sub delete { die "Virtual method!" }
392 Performs a select, fetch and return of data - handles a single row
397 sub select_single { die "Virtual method!" }
399 =head2 columns_info_for
401 Returns metadata for the given source's columns. This
402 is *deprecated*, and will be removed before 1.0. You should
403 be specifying the metadata yourself if you need it.
407 sub columns_info_for { die "Virtual method!" }
409 =head1 ENVIRONMENT VARIABLES
413 If C<DBIC_TRACE> is set then trace information
414 is produced (as when the L<debug> method is set).
416 If the value is of the form C<1=/path/name> then the trace output is
417 written to the file C</path/name>.
419 This environment variable is checked when the storage object is first
420 created (when you call connect on your schema). So, run-time changes
421 to this environment variable will not take effect unless you also
422 re-connect on your schema.
424 =head2 DBIX_CLASS_STORAGE_DBI_DEBUG
426 Old name for DBIC_TRACE
430 Matt S. Trout <mst@shadowcatsystems.co.uk>
432 Andy Grundman <andy@hybridized.org>
436 You may distribute this code under the same terms as Perl itself.