Merge 'normalize_connect_info' into 'trunk'
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage.pm
index 735ac65..c9f4383 100644 (file)
@@ -4,12 +4,19 @@ use strict;
 use warnings;
 
 use base qw/DBIx::Class/;
+use mro 'c3';
 
-use Scalar::Util qw/weaken/;
-use Carp::Clan qw/^DBIx::Class/;
+use DBIx::Class::Exception;
+use Scalar::Util();
 use IO::File;
+use DBIx::Class::Storage::TxnScopeGuard;
 
 __PACKAGE__->mk_group_accessors('simple' => qw/debug debugobj schema/);
+__PACKAGE__->mk_group_accessors('inherited' => 'cursor_class');
+
+__PACKAGE__->cursor_class('DBIx::Class::Cursor');
+
+sub cursor { shift->cursor_class(@_); }
 
 package # Hide from PAUSE
     DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION;
@@ -56,20 +63,11 @@ sub new {
   $new->set_schema($schema);
   $new->debugobj(new DBIx::Class::Storage::Statistics());
 
-  my $fh;
+  #my $fh;
 
   my $debug_env = $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG}
                   || $ENV{DBIC_TRACE};
 
-  if (defined($debug_env) && ($debug_env =~ /=(.+)$/)) {
-    $fh = IO::File->new($1, 'w')
-      or $new->throw_exception("Cannot open trace file $1");
-  } else {
-    $fh = IO::File->new('>&STDERR');
-  }
-
-  $fh->autoflush(1);
-  $new->debugfh($fh);
   $new->debug(1) if $debug_env;
 
   $new;
@@ -85,7 +83,7 @@ storage object, such as during L<DBIx::Class::Schema/clone>.
 sub set_schema {
   my ($self, $schema) = @_;
   $self->schema($schema);
-  weaken($self->{schema}) if ref $self->{schema};
+  Scalar::Util::weaken($self->{schema}) if ref $self->{schema};
 }
 
 =head2 connected
@@ -122,8 +120,12 @@ Throws an exception - croaks.
 sub throw_exception {
   my $self = shift;
 
-  $self->schema->throw_exception(@_) if $self->schema;
-  croak @_;
+  if ($self->schema) {
+    $self->schema->throw_exception(@_);
+  }
+  else {
+    DBIx::Class::Exception->throw(@_);
+  }
 }
 
 =head2 txn_do
@@ -251,6 +253,9 @@ sub txn_begin { die "Virtual method!" }
 
 Issues a commit of the current transaction.
 
+It does I<not> perform an actual storage commit unless there's a DBIx::Class
+transaction currently in effect (i.e. you called L</txn_begin>).
+
 =cut
 
 sub txn_commit { die "Virtual method!" }
@@ -265,10 +270,73 @@ which allows the rollback to propagate to the outermost transaction.
 
 sub txn_rollback { die "Virtual method!" }
 
+=head2 svp_begin
+
+Arguments: $savepoint_name?
+
+Created a new savepoint using the name provided as argument. If no name
+is provided, a random name will be used.
+
+=cut
+
+sub svp_begin { die "Virtual method!" }
+
+=head2 svp_release
+
+Arguments: $savepoint_name?
+
+Release the savepoint provided as argument. If none is provided,
+release the savepoint created most recently. This will implicitly
+release all savepoints created after the one explicitly released as well.
+
+=cut
+
+sub svp_release { die "Virtual method!" }
+
+=head2 svp_rollback
+
+Arguments: $savepoint_name?
+
+Rollback to the savepoint provided as argument. If none is provided,
+rollback to the savepoint created most recently. This will implicitly
+release all savepoints created after the savepoint we rollback to.
+
+=cut
+
+sub svp_rollback { die "Virtual method!" }
+
+=for comment
+
+=head2 txn_scope_guard
+
+An alternative way of transaction handling based on
+L<DBIx::Class::Storage::TxnScopeGuard>:
+
+ my $txn_guard = $storage->txn_scope_guard;
+
+ $row->col1("val1");
+ $row->update;
+
+ $txn_guard->commit;
+
+If an exception occurs, or the guard object otherwise leaves the scope
+before C<< $txn_guard->commit >> is called, the transaction will be rolled
+back by an explicit L</txn_rollback> call. In essence this is akin to
+using a L</txn_begin>/L</txn_commit> pair, without having to worry
+about calling L</txn_rollback> at the right places. Note that since there
+is no defined code closure, there will be no retries and other magic upon
+database disconnection. If you need such functionality see L</txn_do>.
+
+=cut
+
+sub txn_scope_guard {
+  return DBIx::Class::Storage::TxnScopeGuard->new($_[0]);
+}
+
 =head2 sql_maker
 
 Returns a C<sql_maker> object - normally an object of class
-C<DBIC::SQL::Abstract>.
+C<DBIx::Class::SQLAHacks>.
 
 =cut
 
@@ -324,14 +392,12 @@ sub debugcb {
     }
 }
 
-=head2 cursor
+=head2 cursor_class
 
 The cursor class for this Storage object.
 
 =cut
 
-sub cursor { die "Virtual method!" }
-
 =head2 deploy
 
 Deploy the tables to storage (CREATE TABLE and friends in a SQL-based
@@ -425,6 +491,11 @@ re-connect on your schema.
 
 Old name for DBIC_TRACE
 
+=head1 SEE ALSO
+
+L<DBIx::Class::Storage::DBI> - reference storage implementation using
+SQL::Abstract and DBI.
+
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>