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/);
13 __PACKAGE__->mk_group_accessors('inherited' => 'cursor_class');
15 __PACKAGE__->cursor_class('DBIx::Class::Cursor');
17 sub cursor { shift->cursor_class(@_); }
19 package # Hide from PAUSE
20 DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION;
22 use overload '"' => sub {
23 'DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION'
29 return bless $self, $class;
32 package DBIx::Class::Storage;
36 DBIx::Class::Storage - Generic Storage Handler
40 A base implementation of common Storage methods. For specific
41 information about L<DBI>-based storage, see L<DBIx::Class::Storage::DBI>.
49 Instantiates the Storage object.
54 my ($self, $schema) = @_;
56 $self = ref $self if ref $self;
61 $new->set_schema($schema);
62 $new->debugobj(new DBIx::Class::Storage::Statistics());
66 my $debug_env = $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG}
69 $new->debug(1) if $debug_env;
76 Used to reset the schema class or object which owns this
77 storage object, such as during L<DBIx::Class::Schema/clone>.
82 my ($self, $schema) = @_;
83 $self->schema($schema);
84 weaken($self->{schema}) if ref $self->{schema};
89 Returns true if we have an open storage connection, false
90 if it is not (yet) open.
94 sub connected { die "Virtual method!" }
98 Closes any open storage connection unconditionally.
102 sub disconnect { die "Virtual method!" }
104 =head2 ensure_connected
106 Initiate a connection to the storage if one isn't already open.
110 sub ensure_connected { die "Virtual method!" }
112 =head2 throw_exception
114 Throws an exception - croaks.
118 sub throw_exception {
121 $self->schema->throw_exception(@_) if $self->schema;
129 =item Arguments: C<$coderef>, @coderef_args?
131 =item Return Value: The return value of $coderef
135 Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
136 returning its result (if any). If an exception is caught, a rollback is issued
137 and the exception is rethrown. If the rollback fails, (i.e. throws an
138 exception) an exception is thrown that includes a "Rollback failed" message.
142 my $author_rs = $schema->resultset('Author')->find(1);
143 my @titles = qw/Night Day It/;
146 # If any one of these fails, the entire transaction fails
147 $author_rs->create_related('books', {
149 }) foreach (@titles);
151 return $author->books;
156 $rs = $schema->txn_do($coderef);
159 if ($@) { # Transaction failed
160 die "something terrible has happened!" #
161 if ($@ =~ /Rollback failed/); # Rollback failed
163 deal_with_failed_transaction();
166 In a nested transaction (calling txn_do() from within a txn_do() coderef) only
167 the outermost transaction will issue a L</txn_commit>, and txn_do() can be
168 called in void, scalar and list context and it will behave as expected.
170 Please note that all of the code in your coderef, including non-DBIx::Class
171 code, is part of a transaction. This transaction may fail out halfway, or
172 it may get partially double-executed (in the case that our DB connection
173 failed halfway through the transaction, in which case we reconnect and
174 restart the txn). Therefore it is best that any side-effects in your coderef
175 are idempotent (that is, can be re-executed multiple times and get the
176 same result), and that you check up on your side-effects in the case of
182 my ($self, $coderef, @args) = @_;
184 ref $coderef eq 'CODE' or $self->throw_exception
185 ('$coderef must be a CODE reference');
187 my (@return_values, $return_value);
189 $self->txn_begin; # If this throws an exception, no rollback is needed
191 my $wantarray = wantarray; # Need to save this since the context
192 # inside the eval{} block is independent
193 # of the context that called txn_do()
196 # Need to differentiate between scalar/list context to allow for
197 # returning a list in scalar context to get the size of the list
200 @return_values = $coderef->(@args);
201 } elsif (defined $wantarray) {
203 $return_value = $coderef->(@args);
219 my $rollback_error = $@;
220 my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
221 $self->throw_exception($error) # propagate nested rollback
222 if $rollback_error =~ /$exception_class/;
224 $self->throw_exception(
225 "Transaction aborted: $error. Rollback failed: ${rollback_error}"
228 $self->throw_exception($error); # txn failed but rollback succeeded
232 return $wantarray ? @return_values : $return_value;
237 Starts a transaction.
239 See the preferred L</txn_do> method, which allows for
240 an entire code block to be executed transactionally.
244 sub txn_begin { die "Virtual method!" }
248 Issues a commit of the current transaction.
252 sub txn_commit { die "Virtual method!" }
256 Issues a rollback of the current transaction. A nested rollback will
257 throw a L<DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION> exception,
258 which allows the rollback to propagate to the outermost transaction.
262 sub txn_rollback { die "Virtual method!" }
266 Returns a C<sql_maker> object - normally an object of class
267 C<DBIC::SQL::Abstract>.
271 sub sql_maker { die "Virtual method!" }
275 Causes trace information to be emitted on the C<debugobj> object.
276 (or C<STDERR> if C<debugobj> has not specifically been set).
278 This is the equivalent to setting L</DBIC_TRACE> in your
283 Set or retrieve the filehandle used for trace/debug output. This should be
284 an IO::Handle compatible ojbect (only the C<print> method is used. Initially
285 set to be STDERR - although see information on the
286 L<DBIC_TRACE> environment variable.
293 if ($self->debugobj->can('debugfh')) {
294 return $self->debugobj->debugfh(@_);
300 Sets or retrieves the object used for metric collection. Defaults to an instance
301 of L<DBIx::Class::Storage::Statistics> that is compatible with the original
302 method of using a coderef as a callback. See the aforementioned Statistics
303 class for more information.
307 Sets a callback to be executed each time a statement is run; takes a sub
308 reference. Callback is executed as $sub->($op, $info) where $op is
309 SELECT/INSERT/UPDATE/DELETE and $info is what would normally be printed.
311 See L<debugobj> for a better way.
318 if ($self->debugobj->can('callback')) {
319 return $self->debugobj->callback(@_);
325 The cursor class for this Storage object.
331 Deploy the tables to storage (CREATE TABLE and friends in a SQL-based
332 Storage class). This would normally be called through
333 L<DBIx::Class::Schema/deploy>.
337 sub deploy { die "Virtual method!" }
341 The arguments of C<connect_info> are always a single array reference,
342 and are Storage-handler specific.
344 This is normally accessed via L<DBIx::Class::Schema/connection>, which
345 encapsulates its argument list in an arrayref before calling
346 C<connect_info> here.
350 sub connect_info { die "Virtual method!" }
354 Handle a select statement.
358 sub select { die "Virtual method!" }
362 Handle an insert statement.
366 sub insert { die "Virtual method!" }
370 Handle an update statement.
374 sub update { die "Virtual method!" }
378 Handle a delete statement.
382 sub delete { die "Virtual method!" }
386 Performs a select, fetch and return of data - handles a single row
391 sub select_single { die "Virtual method!" }
393 =head2 columns_info_for
395 Returns metadata for the given source's columns. This
396 is *deprecated*, and will be removed before 1.0. You should
397 be specifying the metadata yourself if you need it.
401 sub columns_info_for { die "Virtual method!" }
403 =head1 ENVIRONMENT VARIABLES
407 If C<DBIC_TRACE> is set then trace information
408 is produced (as when the L<debug> method is set).
410 If the value is of the form C<1=/path/name> then the trace output is
411 written to the file C</path/name>.
413 This environment variable is checked when the storage object is first
414 created (when you call connect on your schema). So, run-time changes
415 to this environment variable will not take effect unless you also
416 re-connect on your schema.
418 =head2 DBIX_CLASS_STORAGE_DBI_DEBUG
420 Old name for DBIC_TRACE
424 Matt S. Trout <mst@shadowcatsystems.co.uk>
426 Andy Grundman <andy@hybridized.org>
430 You may distribute this code under the same terms as Perl itself.