Merge 'try-tiny' into 'trunk'
Rafael Kitover [Tue, 25 May 2010 19:33:37 +0000 (19:33 +0000)]
r24317@hlagh (orig r9367):  tonvoon | 2010-05-14 12:24:35 -0400
Branch for converting eval {} to Try::Tiny

r24319@hlagh (orig r9369):  tonvoon | 2010-05-14 17:25:02 -0400
Conversion of eval => try (part 1)

r24325@hlagh (orig r9375):  tonvoon | 2010-05-14 18:03:03 -0400
Add eval => try

r24326@hlagh (orig r9376):  tonvoon | 2010-05-14 18:22:57 -0400
Another eval => try

r24327@hlagh (orig r9377):  tonvoon | 2010-05-14 18:45:27 -0400
Corrected usage of $@ in catch block

r24328@hlagh (orig r9378):  tonvoon | 2010-05-14 19:29:52 -0400
txn_do's eval => try

r24329@hlagh (orig r9379):  tonvoon | 2010-05-14 19:46:44 -0400
eval => try where tests for $@ done

r24330@hlagh (orig r9380):  tonvoon | 2010-05-14 20:38:43 -0400
All expected evals converted to try, except where no test is done,
runtime evaluation, or base perl (such as "require"). Only one test
failure due to string difference in output

r24346@hlagh (orig r9396):  tonvoon | 2010-05-17 08:52:28 -0400
Fix missing $@ in try::tiny conversion

r24347@hlagh (orig r9397):  tonvoon | 2010-05-17 08:55:13 -0400
Revert to eval instead of try::tiny because no check for $@

r24348@hlagh (orig r9398):  tonvoon | 2010-05-17 08:55:45 -0400
Added myself to contributors

r24349@hlagh (orig r9399):  tonvoon | 2010-05-17 10:23:57 -0400
Fixed exception logic due to not being able to use return with a catch{}

r24350@hlagh (orig r9400):  tonvoon | 2010-05-17 10:31:32 -0400
Removed tab

r24430@hlagh (orig r9424):  ribasushi | 2010-05-25 10:09:39 -0400
More try::tiny conversions
r24432@hlagh (orig r9426):  ribasushi | 2010-05-25 11:40:45 -0400
Try::Tiny conversion finished
r24433@hlagh (orig r9427):  ribasushi | 2010-05-25 11:46:52 -0400
Missed use
r24440@hlagh (orig r9434):  rkitover | 2010-05-25 13:47:25 -0400
fix Oracle
r24441@hlagh (orig r9435):  rkitover | 2010-05-25 14:04:10 -0400
fix odbc/mssql dynamic cursors
r24442@hlagh (orig r9436):  rkitover | 2010-05-25 14:32:41 -0400
fix hang in SQLAnywhere DateTime tests

34 files changed:
Changes
Makefile.PL
lib/DBIx/Class.pm
lib/DBIx/Class/Admin.pm
lib/DBIx/Class/Exception.pm
lib/DBIx/Class/InflateColumn/DateTime.pm
lib/DBIx/Class/Manual/Cookbook.pod
lib/DBIx/Class/Relationship/Base.pm
lib/DBIx/Class/Relationship/BelongsTo.pm
lib/DBIx/Class/Relationship/HasMany.pm
lib/DBIx/Class/Relationship/HasOne.pm
lib/DBIx/Class/ResultSource.pm
lib/DBIx/Class/Row.pm
lib/DBIx/Class/Schema.pm
lib/DBIx/Class/Schema/Versioned.pm
lib/DBIx/Class/Storage.pm
lib/DBIx/Class/Storage/DBI.pm
lib/DBIx/Class/Storage/DBI/ADO.pm
lib/DBIx/Class/Storage/DBI/Cursor.pm
lib/DBIx/Class/Storage/DBI/InterBase.pm
lib/DBIx/Class/Storage/DBI/MSSQL.pm
lib/DBIx/Class/Storage/DBI/ODBC.pm
lib/DBIx/Class/Storage/DBI/ODBC/Microsoft_SQL_Server.pm
lib/DBIx/Class/Storage/DBI/Oracle.pm
lib/DBIx/Class/Storage/DBI/Oracle/Generic.pm
lib/DBIx/Class/Storage/DBI/Replicated.pm
lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm
lib/DBIx/Class/Storage/DBI/Replicated/WithDSN.pm
lib/DBIx/Class/Storage/DBI/SQLAnywhere.pm
lib/DBIx/Class/Storage/DBI/Sybase.pm
lib/DBIx/Class/Storage/DBI/Sybase/ASE.pm
lib/DBIx/Class/Storage/TxnScopeGuard.pm
lib/SQL/Translator/Parser/DBIx/Class.pm
t/inflate/datetime_sybase_asa.t

diff --git a/Changes b/Changes
index e6c97fb..0f93936 100644 (file)
--- a/Changes
+++ b/Changes
@@ -8,6 +8,7 @@ Revision history for DBIx::Class
         - ::Storage::DBI now correctly preserves a parent $dbh from
           terminating children, even during interpreter-global
           out-of-order destruction
+        - All DBIC exception-handling switched to Try::Tiny
         - Add DBIx::Class::FilterColumn for non-ref filtering
         - InflateColumn::DateTime support for MSSQL via DBD::Sybase
         - Millisecond precision support for MSSQL datetimes for
index 3203baf..133007f 100644 (file)
@@ -50,6 +50,7 @@ my $runtime_requires = {
   'Data::Dumper::Concise'    => '1.000',
   'Scope::Guard'             => '0.03',
   'Context::Preserve'        => '0.01',
+  'Try::Tiny'                => '0.04',
 };
 
 # this is so we can order requires alphabetically
index 1a50606..6d86134 100644 (file)
@@ -42,8 +42,11 @@ sub MODIFY_CODE_ATTRIBUTES {
 sub _attr_cache {
   my $self = shift;
   my $cache = $self->can('__attr_cache') ? $self->__attr_cache : {};
-  my $rest = eval { $self->next::method };
-  return $@ ? $cache : { %$cache, %$rest };
+
+  return {
+    %$cache,
+    %{ $self->maybe::next::method || {} },
+  };
 }
 
 1;
@@ -370,6 +373,8 @@ Todd Lipcon
 
 Tom Hukins
 
+tonvoon: Ton Voon <tonvoon@cpan.org>
+
 triode: Pete Gamache <gamache@cpan.org>
 
 typester: Daisuke Murase <typester@cpan.org>
index 284f72d..ac47c61 100644 (file)
@@ -209,8 +209,8 @@ has config => (
 sub _build_config {
   my ($self) = @_;
 
-  eval { require Config::Any }
-    or die ("Config::Any is required to parse the config file.\n");
+  try { require Config::Any }
+    catch { die ("Config::Any is required to parse the config file.\n") };
 
   my $cfg = Config::Any->load_files ( {files => [$self->config_file], use_ext =>1, flatten_to_hash=>1});
 
index e8e9ff7..401bbcd 100644 (file)
@@ -3,8 +3,9 @@ package DBIx::Class::Exception;
 use strict;
 use warnings;
 
-use Carp::Clan qw/^DBIx::Class/;
+use Carp::Clan qw/^DBIx::Class|^Try::Tiny/;
 use Scalar::Util qw/blessed/;
+use Try::Tiny;
 
 use overload
     '""' => sub { shift->{msg} },
@@ -42,7 +43,7 @@ C<$stacktrace> tells it to use L<Carp/longmess> instead of
 L<Carp::Clan/croak>.
 
   DBIx::Class::Exception->throw('Foo');
-  eval { ... }; DBIx::Class::Exception->throw($@) if $@;
+  try { ... } catch { DBIx::Class::Exception->throw(shift) }
 
 =cut
 
@@ -54,9 +55,7 @@ sub throw {
 
     # use Carp::Clan's croak if we're not stack tracing
     if(!$stacktrace) {
-        local $@;
-        eval { croak $msg };
-        $msg = $@
+        try { croak $msg } catch { $msg = shift };
     }
     else {
         $msg = Carp::longmess($msg);
index db899cb..609df1e 100644 (file)
@@ -4,6 +4,7 @@ use strict;
 use warnings;
 use base qw/DBIx::Class/;
 use Carp::Clan qw/^DBIx::Class/;
+use Try::Tiny;
 
 =head1 NAME
 
@@ -167,13 +168,18 @@ sub register_column {
           inflate => sub {
             my ($value, $obj) = @_;
 
-            my $dt = eval { $obj->_inflate_to_datetime( $value, \%info ) };
-            if (my $err = $@ ) {
-              return undef if ($undef_if_invalid);
-              $self->throw_exception ("Error while inflating ${value} for ${column} on ${self}: $err");
-            }
-
-            return $obj->_post_inflate_datetime( $dt, \%info );
+            my $dt = try
+              { $obj->_inflate_to_datetime( $value, \%info ) }
+              catch {
+                $self->throw_exception ("Error while inflating ${value} for ${column} on ${self}: $_")
+                  unless $undef_if_invalid;
+                undef;  # rv
+              };
+
+            return (defined $dt)
+              ? $obj->_post_inflate_datetime( $dt, \%info )
+              : undef
+            ;
           },
           deflate => sub {
             my ($value, $obj) = @_;
index e31245f..e5f2559 100644 (file)
@@ -1244,17 +1244,17 @@ example of the recommended way to use it:
     return $genus->species;
   };
 
+  use Try::Tiny;
   my $rs;
-  eval {
+  try {
     $rs = $schema->txn_do($coderef1);
-  };
-
-  if ($@) {                             # Transaction failed
+  } catch {
+    # Transaction failed
     die "the sky is falling!"           #
-      if ($@ =~ /Rollback failed/);     # Rollback failed
+      if ($_ =~ /Rollback failed/);     # Rollback failed
 
     deal_with_failed_transaction();
-  }
+  };
 
 Note: by default C<txn_do> will re-run the coderef one more time if an
 error occurs due to client disconnection (e.g. the server is bounced).
@@ -1281,8 +1281,10 @@ row.
   my $schema = MySchema->connect("dbi:Pg:dbname=my_db");
 
   # Start a transaction. Every database change from here on will only be 
-  # committed into the database if the eval block succeeds.
-  eval {
+  # committed into the database if the try block succeeds.
+  use Try::Tiny;
+  my $exception;
+  try {
     $schema->txn_do(sub {
       # SQL: BEGIN WORK;
 
@@ -1292,7 +1294,7 @@ row.
       for (1..10) {
 
         # Start a nested transaction, which in fact sets a savepoint.
-        eval {
+        try {
           $schema->txn_do(sub {
             # SQL: SAVEPOINT savepoint_0;
 
@@ -1307,8 +1309,7 @@ row.
               #      WHERE ( id = 42 );
             }
           });
-        };
-        if ($@) {
+        } catch {
           # SQL: ROLLBACK TO SAVEPOINT savepoint_0;
 
           # There was an error while creating a $thing. Depending on the error
@@ -1316,14 +1317,14 @@ row.
           # changes related to the creation of this $thing
 
           # Abort the whole job
-          if ($@ =~ /horrible_problem/) {
+          if ($_ =~ /horrible_problem/) {
             print "something horrible happend, aborting job!";
-            die $@;                # rethrow error
+            die $_;                # rethrow error
           }
 
           # Ignore this $thing, report the error, and continue with the
           # next $thing
-          print "Cannot create thing: $@";
+          print "Cannot create thing: $_";
         }
         # There was no error, so save all changes since the last 
         # savepoint.
@@ -1331,8 +1332,11 @@ row.
         # SQL: RELEASE SAVEPOINT savepoint_0;
       }
     });
-  };
-  if ($@) {
+  } catch {
+    $exception = $_;
+  }
+
+  if ($caught) {
     # There was an error while handling the $job. Rollback all changes
     # since the transaction started, including the already committed
     # ('released') savepoints. There will be neither a new $job nor any
@@ -1340,7 +1344,7 @@ row.
 
     # SQL: ROLLBACK;
 
-    print "ERROR: $@\n";
+    print "ERROR: $exception\n";
   }
   else {
     # There was no error while handling the $job. Commit all changes.
@@ -1354,7 +1358,7 @@ row.
 
 In this example it might be hard to see where the rollbacks, releases and
 commits are happening, but it works just the same as for plain L<<txn_do>>: If
-the C<eval>-block around C<txn_do> fails, a rollback is issued. If the C<eval>
+the C<try>-block around C<txn_do> fails, a rollback is issued. If the C<try>
 succeeds, the transaction is committed (or the savepoint released).
 
 While you can get more fine-grained control using C<svp_begin>, C<svp_release>
index 35ae568..53dc14c 100644 (file)
@@ -5,6 +5,7 @@ use warnings;
 
 use Scalar::Util ();
 use base qw/DBIx::Class/;
+use Try::Tiny;
 
 =head1 NAME
 
@@ -237,15 +238,16 @@ sub related_resultset {
 
     # condition resolution may fail if an incomplete master-object prefetch
     # is encountered - that is ok during prefetch construction (not yet in_storage)
-    my $cond = eval { $source->_resolve_condition( $rel_info->{cond}, $rel, $self ) };
-    if (my $err = $@) {
+    my $cond = try {
+      $source->_resolve_condition( $rel_info->{cond}, $rel, $self )
+    }
+    catch {
       if ($self->in_storage) {
-        $self->throw_exception ($err);
-      }
-      else {
-        $cond = $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION;
+        $self->throw_exception ($_);
       }
-    }
+
+      $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION;  # RV
+    };
 
     if ($cond eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) {
       my $reverse = $source->reverse_relationship_info($rel);
index 471a417..050c1e4 100644 (file)
@@ -6,6 +6,7 @@ package # hide from PAUSE
 
 use strict;
 use warnings;
+use Try::Tiny;
 
 our %_pod_inherit_config = 
   (
@@ -24,10 +25,10 @@ sub belongs_to {
   # no join condition or just a column name
   if (!ref $cond) {
     $class->ensure_class_loaded($f_class);
-    my %f_primaries = map { $_ => 1 } eval { $f_class->_pri_cols };
-    $class->throw_exception(
-      "Can't infer join condition for ${rel} on ${class}: $@"
-    ) if $@;
+    my %f_primaries = map { $_ => 1 } try { $f_class->_pri_cols }
+      catch {
+        $class->throw_exception( "Can't infer join condition for ${rel} on ${class}: $_");
+      };
 
     my ($pri, $too_many) = keys %f_primaries;
     $class->throw_exception(
index 7690af8..d8e651d 100644 (file)
@@ -3,6 +3,7 @@ package # hide from PAUSE
 
 use strict;
 use warnings;
+use Try::Tiny;
 
 our %_pod_inherit_config = 
   (
@@ -14,10 +15,10 @@ sub has_many {
 
   unless (ref $cond) {
     $class->ensure_class_loaded($f_class);
-    my ($pri, $too_many) = eval { $class->_pri_cols };
-    $class->throw_exception(
-      "Can't infer join condition for ${rel} on ${class}: $@"
-    ) if $@;
+    my ($pri, $too_many) = try { $class->_pri_cols } 
+      catch {
+        $class->throw_exception("Can't infer join condition for ${rel} on ${class}: $_");
+      };
 
     $class->throw_exception(
       "has_many can only infer join for a single primary key; ".
@@ -39,7 +40,7 @@ sub has_many {
       $guess = "using our class name '$class' as foreign key";
     }
 
-    my $f_class_loaded = eval { $f_class->columns };
+    my $f_class_loaded = try { $f_class->columns };
     $class->throw_exception(
       "No such column ${f_key} on foreign class ${f_class} ($guess)"
     ) if $f_class_loaded && !$f_class->has_column($f_key);
index 33a0641..dddf4e5 100644 (file)
@@ -4,6 +4,7 @@ package # hide from PAUSE
 use strict;
 use warnings;
 use Carp::Clan qw/^DBIx::Class/;
+use Try::Tiny;
 
 our %_pod_inherit_config = 
   (
@@ -30,7 +31,7 @@ sub _has_one {
       "${class} has none"
     ) if !defined $pri && (!defined $cond || !length $cond);
 
-    my $f_class_loaded = eval { $f_class->columns };
+    my $f_class_loaded = try { $f_class->columns };
     my ($f_key,$too_many,$guess);
     if (defined $cond && length $cond) {
       $f_key = $cond;
@@ -60,10 +61,10 @@ sub _has_one {
 sub _get_primary_key {
   my ( $class, $target_class ) = @_;
   $target_class ||= $class;
-  my ($pri, $too_many) = eval { $target_class->_pri_cols };
-  $class->throw_exception(
-    "Can't infer join condition on ${target_class}: $@"
-  ) if $@;
+  my ($pri, $too_many) = try { $target_class->_pri_cols }
+    catch {
+      $class->throw_exception("Can't infer join condition on ${target_class}: $_");
+    };
 
   $class->throw_exception(
     "might_have/has_one can only infer join for a single primary key; ".
index 1329fe1..6ac8538 100644 (file)
@@ -8,6 +8,7 @@ use DBIx::Class::ResultSourceHandle;
 
 use DBIx::Class::Exception;
 use Carp::Clan qw/^DBIx::Class/;
+use Try::Tiny;
 
 use base qw/DBIx::Class/;
 
@@ -367,9 +368,10 @@ sub column_info {
     $self->{_columns_info_loaded}++;
     my $info = {};
     my $lc_info = {};
-    # eval for the case of storage without table
-    eval { $info = $self->storage->columns_info_for( $self->from ) };
-    unless ($@) {
+
+    # try for the case of storage without table
+    try {
+      $info = $self->storage->columns_info_for( $self->from );
       for my $realcol ( keys %{$info} ) {
         $lc_info->{lc $realcol} = $info->{$realcol};
       }
@@ -379,7 +381,7 @@ sub column_info {
           %{ $info->{$col} || $lc_info->{lc $col} || {} }
         };
       }
-    }
+    };
   }
   return $self->_columns->{$column};
 }
@@ -1022,7 +1024,7 @@ sub add_relationship {
 
   return $self;
 
-  # XXX disabled. doesn't work properly currently. skip in tests.
+# XXX disabled. doesn't work properly currently. skip in tests.
 
   my $f_source = $self->schema->source($f_source_name);
   unless ($f_source) {
@@ -1035,13 +1037,14 @@ sub add_relationship {
   }
   return unless $f_source; # Can't test rel without f_source
 
-  eval { $self->_resolve_join($rel, 'me', {}, []) };
-
-  if ($@) { # If the resolve failed, back out and re-throw the error
-    delete $rels{$rel}; #
+  try { $self->_resolve_join($rel, 'me', {}, []) }
+  catch {
+    # If the resolve failed, back out and re-throw the error
+    delete $rels{$rel};
     $self->_relationships(\%rels);
-    $self->throw_exception("Error creating relationship $rel: $@");
-  }
+    $self->throw_exception("Error creating relationship $rel: $_");
+  };
+
   1;
 }
 
index 310e10e..6678a79 100644 (file)
@@ -7,6 +7,7 @@ use base qw/DBIx::Class/;
 
 use DBIx::Class::Exception;
 use Scalar::Util ();
+use Try::Tiny;
 
 ###
 ### Internal method
@@ -862,7 +863,7 @@ sub set_column {
   my ($self, $column, $new_value) = @_;
 
   # if we can't get an ident condition on first try - mark the object as unidentifiable
-  $self->{_orig_ident} ||= (eval { $self->ident_condition }) || {};
+  $self->{_orig_ident} ||= (try { $self->ident_condition }) || {};
 
   my $old_value = $self->get_column($column);
   $new_value = $self->store_column($column, $new_value);
index cea821a..c6974c1 100644 (file)
@@ -5,6 +5,7 @@ use warnings;
 
 use DBIx::Class::Exception;
 use Carp::Clan qw/^DBIx::Class/;
+use Try::Tiny;
 use Scalar::Util ();
 use File::Spec;
 use Sub::Name ();
@@ -817,10 +818,14 @@ sub connection {
 
   $storage_class = 'DBIx::Class::Storage'.$storage_class
     if $storage_class =~ m/^::/;
-  eval { $self->ensure_class_loaded ($storage_class) };
-  $self->throw_exception(
-    "No arguments to load_classes and couldn't load ${storage_class} ($@)"
-  ) if $@;
+  try {
+    $self->ensure_class_loaded ($storage_class);
+  }
+  catch {
+    $self->throw_exception(
+      "No arguments to load_classes and couldn't load ${storage_class} ($_)"
+    );
+  };
   my $storage = $storage_class->new($self=>$args);
   $storage->connect_info(\@info);
   $self->storage($storage);
@@ -1400,10 +1405,13 @@ more information.
       unless ($INC{"DBIx/Class/CDBICompat.pm"} || $warn++);
 
     my $base = 'DBIx::Class::ResultSetProxy';
-    eval "require ${base};";
-    $self->throw_exception
-      ("No arguments to load_classes and couldn't load ${base} ($@)")
-        if $@;
+    try {
+      eval "require ${base};"
+    }
+    catch {
+      $self->throw_exception
+        ("No arguments to load_classes and couldn't load ${base} ($_)")
+    };
 
     if ($self eq $target) {
       # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
index d192d21..8aa9b6a 100644 (file)
@@ -182,6 +182,7 @@ use base 'DBIx::Class::Schema';
 
 use Carp::Clan qw/^DBIx::Class/;
 use Time::HiRes qw/gettimeofday/;
+use Try::Tiny;
 
 __PACKAGE__->mk_classdata('_filedata');
 __PACKAGE__->mk_classdata('upgrade_directory');
@@ -503,7 +504,7 @@ sub get_db_version
     my ($self, $rs) = @_;
 
     my $vtable = $self->{vschema}->resultset('Table');
-    my $version = eval {
+    my $version = try {
       $vtable->search({}, { order_by => { -desc => 'installed' }, rows => 1 } )
               ->get_column ('version')
                ->next;
@@ -724,12 +725,9 @@ sub _source_exists
 {
     my ($self, $rs) = @_;
 
-    my $c = eval {
-        $rs->search({ 1, 0 })->count;
-    };
-    return 0 if $@ || !defined $c;
+    my $c = try { $rs->search({ 1, 0 })->count };
 
-    return 1;
+    return (defined $c) ? 1 : 0;
 }
 
 1;
index 0def315..c4997d5 100644 (file)
@@ -10,6 +10,7 @@ use DBIx::Class::Exception;
 use Scalar::Util();
 use IO::File;
 use DBIx::Class::Storage::TxnScopeGuard;
+use Try::Tiny;
 
 __PACKAGE__->mk_group_accessors('simple' => qw/debug debugobj schema/);
 __PACKAGE__->mk_group_accessors('inherited' => 'cursor_class');
@@ -158,16 +159,16 @@ For example,
   };
 
   my $rs;
-  eval {
+  try {
     $rs = $schema->txn_do($coderef);
-  };
-
-  if ($@) {                                  # Transaction failed
+  } catch {
+    my $error = shift;
+    # Transaction failed
     die "something terrible has happened!"   #
-      if ($@ =~ /Rollback failed/);          # Rollback failed
+      if ($error =~ /Rollback failed/);          # Rollback failed
 
     deal_with_failed_transaction();
-  }
+  };
 
 In a nested transaction (calling txn_do() from within a txn_do() coderef) only
 the outermost transaction will issue a L</txn_commit>, and txn_do() can be
@@ -195,9 +196,9 @@ sub txn_do {
   $self->txn_begin; # If this throws an exception, no rollback is needed
 
   my $wantarray = wantarray; # Need to save this since the context
-                             # inside the eval{} block is independent
+                             # inside the try{} block is independent
                              # of the context that called txn_do()
-  eval {
+  try {
 
     # Need to differentiate between scalar/list context to allow for
     # returning a list in scalar context to get the size of the list
@@ -212,28 +213,23 @@ sub txn_do {
       $coderef->(@args);
     }
     $self->txn_commit;
-  };
-
-  if ($@) {
-    my $error = $@;
+  }
+  catch {
+    my $error = shift;
 
-    eval {
+    try {
       $self->txn_rollback;
-    };
-
-    if ($@) {
-      my $rollback_error = $@;
+    } catch {
       my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
       $self->throw_exception($error)  # propagate nested rollback
-        if $rollback_error =~ /$exception_class/;
+        if $_ =~ /$exception_class/;
 
       $self->throw_exception(
-        "Transaction aborted: $error. Rollback failed: ${rollback_error}"
+        "Transaction aborted: $error. Rollback failed: $_"
       );
-    } else {
-      $self->throw_exception($error); # txn failed but rollback succeeded
     }
-  }
+    $self->throw_exception($error); # txn failed but rollback succeeded
+  };
 
   return $wantarray ? @return_values : $return_value;
 }
index 09417af..76e9c49 100644 (file)
@@ -15,7 +15,7 @@ use Scalar::Util();
 use List::Util();
 use Data::Dumper::Concise();
 use Sub::Name ();
-
+use Try::Tiny;
 use File::Path ();
 
 __PACKAGE__->mk_group_accessors('simple' =>
@@ -158,8 +158,7 @@ sub DESTROY {
 
   # some databases need this to stop spewing warnings
   if (my $dbh = $self->_dbh) {
-    local $@;
-    eval {
+    try {
       %{ $dbh->{CachedKids} } = ();
       $dbh->disconnect;
     };
@@ -723,39 +722,25 @@ sub dbh_do {
 
   my $dbh = $self->_get_dbh;
 
-  return $self->$code($dbh, @_) if $self->{_in_dbh_do}
-      || $self->{transaction_depth};
+  return $self->$code($dbh, @_)
+    if ( $self->{_in_dbh_do} || $self->{transaction_depth} );
 
   local $self->{_in_dbh_do} = 1;
 
-  my @result;
-  my $want_array = wantarray;
+  my @args = @_;
+  try {
+    return $self->$code ($dbh, @args);
+  } catch {
+    $self->throw_exception($_) if $self->connected;
 
-  eval {
+    # We were not connected - reconnect and retry, but let any
+    #  exception fall right through this time
+    carp "Retrying $code after catching disconnected exception: $_"
+      if $ENV{DBIC_DBIRETRY_DEBUG};
 
-    if($want_array) {
-        @result = $self->$code($dbh, @_);
-    }
-    elsif(defined $want_array) {
-        $result[0] = $self->$code($dbh, @_);
-    }
-    else {
-        $self->$code($dbh, @_);
-    }
+    $self->_populate_dbh;
+    $self->$code($self->_dbh, @args);
   };
-
-  # ->connected might unset $@ - copy
-  my $exception = $@;
-  if(!$exception) { return $want_array ? @result : $result[0] }
-
-  $self->throw_exception($exception) if $self->connected;
-
-  # We were not connected - reconnect and retry, but let any
-  #  exception fall right through this time
-  carp "Retrying $code after catching disconnected exception: $exception"
-    if $ENV{DBIC_DBIRETRY_DEBUG};
-  $self->_populate_dbh;
-  $self->$code($self->_dbh, @_);
 }
 
 # This is basically a blend of dbh_do above and DBIx::Class::Storage::txn_do.
@@ -777,30 +762,32 @@ sub txn_do {
 
   my $tried = 0;
   while(1) {
-    eval {
+    my $exception;
+    my @args = @_;
+    try {
       $self->_get_dbh;
 
       $self->txn_begin;
       if($want_array) {
-          @result = $coderef->(@_);
+          @result = $coderef->(@args);
       }
       elsif(defined $want_array) {
-          $result[0] = $coderef->(@_);
+          $result[0] = $coderef->(@args);
       }
       else {
-          $coderef->(@_);
+          $coderef->(@args);
       }
       $self->txn_commit;
+    } catch {
+      $exception = $_;
     };
 
-    # ->connected might unset $@ - copy
-    my $exception = $@;
-    if(!$exception) { return $want_array ? @result : $result[0] }
+    if(! defined $exception) { return $want_array ? @result : $result[0] }
 
     if($tried++ || $self->connected) {
-      eval { $self->txn_rollback };
-      my $rollback_exception = $@;
-      if($rollback_exception) {
+      my $rollback_exception;
+      try { $self->txn_rollback } catch { $rollback_exception = shift };
+      if(defined $rollback_exception) {
         my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
         $self->throw_exception($exception)  # propagate nested rollback
           if $rollback_exception =~ /$exception_class/;
@@ -1013,10 +1000,7 @@ sub _server_info {
 
     my %info;
 
-    my $server_version = do {
-      local $@; # might be happenin in some sort of destructor
-      eval { $self->_get_server_version };
-    };
+    my $server_version = try { $self->_get_server_version };
 
     if (defined $server_version) {
       $info{dbms_version} = $server_version;
@@ -1173,7 +1157,7 @@ sub _connect {
     $DBI::connect_via = 'connect';
   }
 
-  eval {
+  try {
     if(ref $info[0] eq 'CODE') {
        $dbh = $info[0]->();
     }
@@ -1181,7 +1165,11 @@ sub _connect {
        $dbh = DBI->connect(@info);
     }
 
-    if($dbh && !$self->unsafe) {
+    if (!$dbh) {
+      die $DBI::errstr;
+    }
+
+    unless ($self->unsafe) {
       my $weak_self = $self;
       Scalar::Util::weaken($weak_self);
       $dbh->{HandleError} = sub {
@@ -1198,15 +1186,15 @@ sub _connect {
       $dbh->{RaiseError} = 1;
       $dbh->{PrintError} = 0;
     }
+  }
+  catch {
+    $self->throw_exception("DBI Connection failed: $_")
+  }
+  finally {
+    $DBI::connect_via = $old_connect_via if $old_connect_via;
   };
 
-  $DBI::connect_via = $old_connect_via if $old_connect_via;
-
-  $self->throw_exception("DBI Connection failed: " . ($@||$DBI::errstr))
-    if !$dbh || $@;
-
   $self->_dbh_autocommit($dbh->{AutoCommit});
-
   $dbh;
 }
 
@@ -1354,7 +1342,7 @@ sub _dbh_commit {
 sub txn_rollback {
   my $self = shift;
   my $dbh = $self->_dbh;
-  eval {
+  try {
     if ($self->{transaction_depth} == 1) {
       $self->debugobj->txn_rollback()
         if ($self->debug);
@@ -1372,15 +1360,17 @@ sub txn_rollback {
     else {
       die DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION->new;
     }
-  };
-  if ($@) {
-    my $error = $@;
-    my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
-    $error =~ /$exception_class/ and $self->throw_exception($error);
-    # ensure that a failed rollback resets the transaction depth
-    $self->{transaction_depth} = $self->_dbh_autocommit ? 0 : 1;
-    $self->throw_exception($error);
   }
+  catch {
+    my $exception_class = "DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION";
+
+    if ($_ !~ /$exception_class/) {
+      # ensure that a failed rollback resets the transaction depth
+      $self->{transaction_depth} = $self->_dbh_autocommit ? 0 : 1;
+    }
+
+    $self->throw_exception($_)
+  };
 }
 
 sub _dbh_rollback {
@@ -1522,7 +1512,7 @@ sub insert {
   if ($opts->{returning}) {
     my @ret_cols = @{$opts->{returning}};
 
-    my @ret_vals = eval {
+    my @ret_vals = try {
       local $SIG{__WARN__} = sub {};
       my @r = $sth->fetchrow_array;
       $sth->finish;
@@ -1677,16 +1667,27 @@ sub _execute_array {
     $placeholder_index++;
   }
 
-  my $rv = eval {
-    $self->_dbh_execute_array($sth, $tuple_status, @extra);
+  my ($rv, $err);
+  try {
+    $rv = $self->_dbh_execute_array($sth, $tuple_status, @extra);
+  }
+  catch {
+    $err = shift;
+  }
+  finally {
+    # Statement must finish even if there was an exception.
+    try {
+      $sth->finish
+    }
+    catch {
+      $err = shift unless defined $err 
+    };
   };
-  my $err = $@ || $sth->errstr;
 
-# Statement must finish even if there was an exception.
-  eval { $sth->finish };
-  $err = $@ unless $err;
+  $err = $sth->errstr
+    if (! defined $err and $sth->err);
 
-  if ($err) {
+  if (defined $err) {
     my $i = 0;
     ++$i while $i <= $#$tuple_status && !ref $tuple_status->[$i];
 
@@ -1700,6 +1701,7 @@ sub _execute_array {
       }),
     );
   }
+
   return $rv;
 }
 
@@ -1712,20 +1714,28 @@ sub _dbh_execute_array {
 sub _dbh_execute_inserts_with_no_binds {
   my ($self, $sth, $count) = @_;
 
-  eval {
+  my $err;
+  try {
     my $dbh = $self->_get_dbh;
     local $dbh->{RaiseError} = 1;
     local $dbh->{PrintError} = 0;
 
     $sth->execute foreach 1..$count;
+  }
+  catch {
+    $err = shift;
+  }
+  finally {
+    # Make sure statement is finished even if there was an exception.
+    try {
+      $sth->finish
+    }
+    catch {
+      $err = shift unless defined $err;
+    };
   };
-  my $exception = $@;
-
-# Make sure statement is finished even if there was an exception.
-  eval { $sth->finish };
-  $exception = $@ unless $exception;
 
-  $self->throw_exception($exception) if $exception;
+  $self->throw_exception($err) if defined $err;
 
   return $count;
 }
@@ -2060,7 +2070,8 @@ sub _dbh_columns_info_for {
 
   if ($dbh->can('column_info')) {
     my %result;
-    eval {
+    my $caught;
+    try {
       my ($schema,$tab) = $table =~ /^(.+?)\.(.+)$/ ? ($1,$2) : (undef,$table);
       my $sth = $dbh->column_info( undef,$schema, $tab, '%' );
       $sth->execute();
@@ -2075,8 +2086,10 @@ sub _dbh_columns_info_for {
 
         $result{$col_name} = \%column_info;
       }
+    } catch {
+      $caught = 1;
     };
-    return \%result if !$@ && scalar keys %result;
+    return \%result if !$caught && scalar keys %result;
   }
 
   my %result;
@@ -2126,7 +2139,7 @@ Return the row id of the last insert.
 sub _dbh_last_insert_id {
     my ($self, $dbh, $source, $col) = @_;
 
-    my $id = eval { $dbh->last_insert_id (undef, undef, $source->name, $col) };
+    my $id = try { $dbh->last_insert_id (undef, undef, $source->name, $col) };
 
     return $id if defined $id;
 
@@ -2177,12 +2190,15 @@ sub _placeholders_supported {
 
   # some drivers provide a $dbh attribute (e.g. Sybase and $dbh->{syb_dynamic_supported})
   # but it is inaccurate more often than not
-  eval {
+  return try {
     local $dbh->{PrintError} = 0;
     local $dbh->{RaiseError} = 1;
     $dbh->do('select ?', {}, 1);
+    1;
+  }
+  catch {
+    0;
   };
-  return $@ ? 0 : 1;
 }
 
 # Check if placeholders bound to non-string types throw exceptions
@@ -2191,13 +2207,16 @@ sub _typeless_placeholders_supported {
   my $self = shift;
   my $dbh  = $self->_get_dbh;
 
-  eval {
+  return try {
     local $dbh->{PrintError} = 0;
     local $dbh->{RaiseError} = 1;
     # this specifically tests a bind that is NOT a string
     $dbh->do('select 1 where 1 = ?', {}, 1);
+    1;
+  }
+  catch {
+    0;
   };
-  return $@ ? 0 : 1;
 }
 
 =head2 sqlt_type
@@ -2514,14 +2533,13 @@ sub deploy {
     return if($line =~ /^COMMIT/m);
     return if $line =~ /^\s+$/; # skip whitespace only
     $self->_query_start($line);
-    eval {
+    try {
       # do a dbh_do cycle here, as we need some error checking in
       # place (even though we will ignore errors)
       $self->dbh_do (sub { $_[1]->do($line) });
+    } catch {
+      carp qq{$_ (running "${line}")};
     };
-    if ($@) {
-      carp qq{$@ (running "${line}")};
-    }
     $self->_query_end($line);
   };
   my @statements = $schema->deployment_statements($type, undef, $dir, { %{ $sqltargs || {} }, no_comments => 1 } );
index e457b96..83d2a09 100644 (file)
@@ -2,6 +2,7 @@ package # hide from PAUSE
     DBIx::Class::Storage::DBI::ADO;
 
 use base 'DBIx::Class::Storage::DBI';
+use Try::Tiny;
 
 sub _rebless {
   my $self = shift;
@@ -10,20 +11,18 @@ sub _rebless {
 # XXX This should be using an OpenSchema method of some sort, but I don't know
 # how.
 # Current version is stolen from Sybase.pm
-  my $dbtype = eval {
-    @{$self->_get_dbh
+  try {
+    my $dbtype = @{$self->_get_dbh
       ->selectrow_arrayref(qq{sp_server_info \@attribute_id=1})
-    }[2]
-  };
+    }[2];
 
-  unless ($@) {
     $dbtype =~ s/\W/_/gi;
     my $subclass = "DBIx::Class::Storage::DBI::ADO::${dbtype}";
     if ($self->load_optional_class($subclass) && !$self->isa($subclass)) {
       bless $self, $subclass;
       $self->_rebless;
     }
-  }
+  };
 }
 
 # Here I was just experimenting with ADO cursor types, left in as a comment in
index 875a3cb..352ba08 100644 (file)
@@ -5,6 +5,8 @@ use warnings;
 
 use base qw/DBIx::Class::Cursor/;
 
+use Try::Tiny;
+
 __PACKAGE__->mk_group_accessors('simple' =>
     qw/sth/
 );
@@ -150,7 +152,8 @@ sub reset {
   my ($self) = @_;
 
   # No need to care about failures here
-  eval { $self->sth->finish if $self->sth && $self->sth->{Active} };
+  try { $self->sth->finish }
+    if $self->sth && $self->sth->{Active};
   $self->_soft_reset;
   return undef;
 }
@@ -176,8 +179,8 @@ sub DESTROY {
   my ($self) = @_;
 
   # None of the reasons this would die matter if we're in DESTROY anyways
-  local $@;
-  eval { $self->sth->finish if $self->sth && $self->sth->{Active} };
+  try { $self->sth->finish }
+    if $self->sth && $self->sth->{Active};
 }
 
 1;
index a0f934a..4c4217a 100644 (file)
@@ -5,6 +5,7 @@ use warnings;
 use base qw/DBIx::Class::Storage::DBI/;
 use mro 'c3';
 use List::Util();
+use Try::Tiny;
 
 =head1 NAME
 
@@ -125,11 +126,12 @@ sub _ping {
   local $dbh->{RaiseError} = 1;
   local $dbh->{PrintError} = 0;
 
-  eval {
+  return try {
     $dbh->do('select 1 from rdb$database');
+    1;
+  } catch {
+    0;
   };
-
-  return $@ ? 0 : 1;
 }
 
 # We want dialect 3 for new features and quoting to work, DBD::InterBase uses
index 515ff9b..0b1e57e 100644 (file)
@@ -5,6 +5,7 @@ use warnings;
 
 use base qw/DBIx::Class::Storage::DBI::UniqueIdentifier/;
 use mro 'c3';
+use Try::Tiny;
 
 use List::Util();
 
@@ -23,13 +24,13 @@ sub _set_identity_insert {
   );
 
   my $dbh = $self->_get_dbh;
-  eval { $dbh->do ($sql) };
-  if ($@) {
+  try { $dbh->do ($sql) }
+  catch {
     $self->throw_exception (sprintf "Error executing '%s': %s",
       $sql,
       $dbh->errstr,
     );
-  }
+  };
 }
 
 sub _unset_identity_insert {
@@ -128,7 +129,7 @@ sub _execute {
 
     # this should bring back the result of SELECT SCOPE_IDENTITY() we tacked
     # on in _prep_for_execute above
-    my ($identity) = eval { $sth->fetchrow_array };
+    my ($identity) = try { $sth->fetchrow_array };
 
     # SCOPE_IDENTITY failed, but we can do something else
     if ( (! $identity) && $self->_identity_method) {
@@ -215,9 +216,10 @@ sub sql_maker {
         # stored procedures like xp_msver, or version detection failed for some
         # other reason.
         # So, we use a query to check if RNO is implemented.
-        $have_rno = 1 if (eval { local $@; ($self->_get_dbh
-          ->selectrow_array('SELECT row_number() OVER (ORDER BY rand())')
-          )[0] });
+        try {
+          $self->_get_dbh->selectrow_array('SELECT row_number() OVER (ORDER BY rand())');
+          $have_rno = 1;
+        };
       }
 
       $self->{_sql_maker_opts} = {
@@ -240,11 +242,12 @@ sub _ping {
   local $dbh->{RaiseError} = 1;
   local $dbh->{PrintError} = 0;
 
-  eval {
+  return try {
     $dbh->do('select 1');
+    1;
+  } catch {
+    0;
   };
-
-  return $@ ? 0 : 1;
 }
 
 package # hide from PAUSE
index f8e9209..8f2642c 100644 (file)
@@ -4,21 +4,23 @@ use warnings;
 
 use base qw/DBIx::Class::Storage::DBI/;
 use mro 'c3';
+use Try::Tiny;
 
 sub _rebless {
-    my ($self) = @_;
-
-    my $dbtype = eval { $self->_get_dbh->get_info(17) };
-
-    unless ( $@ ) {
-        # Translate the backend name into a perl identifier
-        $dbtype =~ s/\W/_/gi;
-        my $subclass = "DBIx::Class::Storage::DBI::ODBC::${dbtype}";
-        if ($self->load_optional_class($subclass) && !$self->isa($subclass)) {
-            bless $self, $subclass;
-            $self->_rebless;
-        }
+  my ($self) = @_;
+
+  try {
+    my $dbtype = $self->_get_dbh->get_info(17);
+
+    # Translate the backend name into a perl identifier
+    $dbtype =~ s/\W/_/gi;
+    my $subclass = "DBIx::Class::Storage::DBI::ODBC::${dbtype}";
+
+    if ($self->load_optional_class($subclass) && !$self->isa($subclass)) {
+      bless $self, $subclass;
+      $self->_rebless;
     }
+  };
 }
 
 1;
index f8cfdfc..ff60369 100644 (file)
@@ -7,6 +7,7 @@ use mro 'c3';
 
 use List::Util();
 use Scalar::Util ();
+use Try::Tiny;
 
 __PACKAGE__->mk_group_accessors(simple => qw/
   _using_dynamic_cursors
@@ -84,18 +85,17 @@ sub _set_dynamic_cursors {
   my $self = shift;
   my $dbh  = $self->_get_dbh;
 
-  eval {
+  try {
     local $dbh->{RaiseError} = 1;
     local $dbh->{PrintError} = 0;
     $dbh->do('SELECT @@IDENTITY');
-  };
-  if ($@) {
+  } catch {
     $self->throw_exception (<<'EOF');
 
 Your drivers do not seem to support dynamic cursors (odbc_cursortype => 2),
 if you're using FreeTDS, make sure to set tds_version to 8.0 or greater.
 EOF
-  }
+  };
 
   $self->_using_dynamic_cursors(1);
   $self->_identity_method('@@identity');
index 399eb70..b977ec6 100644 (file)
@@ -5,23 +5,24 @@ use warnings;
 
 use base qw/DBIx::Class::Storage::DBI/;
 use mro 'c3';
+use Try::Tiny;
 
 sub _rebless {
     my ($self) = @_;
 
-    my $version = eval { $self->_get_dbh->get_info(18); };
+    try {
+      my $version = $self->_get_dbh->get_info(18);
 
-    if ( !$@ ) {
-        my ($major, $minor, $patchlevel) = split(/\./, $version);
+      my ($major, $minor, $patchlevel) = split(/\./, $version);
 
-        # Default driver
-        my $class = $major <= 8
-          ? 'DBIx::Class::Storage::DBI::Oracle::WhereJoins'
-          : 'DBIx::Class::Storage::DBI::Oracle::Generic';
+      # Default driver
+      my $class = $major <= 8
+        ? 'DBIx::Class::Storage::DBI::Oracle::WhereJoins'
+        : 'DBIx::Class::Storage::DBI::Oracle::Generic';
 
-        $self->ensure_class_loaded ($class);
-        bless $self, $class;
-    }
+      $self->ensure_class_loaded ($class);
+      bless $self, $class;
+    };
 }
 
 1;
index 0b83e26..dfe9da9 100644 (file)
@@ -4,6 +4,7 @@ use strict;
 use warnings;
 use Scope::Guard ();
 use Context::Preserve ();
+use Try::Tiny;
 
 =head1 NAME
 
@@ -39,7 +40,7 @@ sub deployment_statements {
   $sqltargs->{quote_table_names} = $quote_char ? 1 : 0;
   $sqltargs->{quote_field_names} = $quote_char ? 1 : 0;
 
-  my $oracle_version = eval { $self->_get_dbh->get_info(18) };
+  my $oracle_version = try { $self->_get_dbh->get_info(18) };
 
   $sqltargs->{producer_args}{oracle_version} = $oracle_version;
 
@@ -112,11 +113,12 @@ sub _ping {
   local $dbh->{RaiseError} = 1;
   local $dbh->{PrintError} = 0;
 
-  eval {
+  return try {
     $dbh->do('select 1 from dual');
+    1;
+  } catch {
+    0;
   };
-
-  return $@ ? 0 : 1;
 }
 
 sub _dbh_execute {
@@ -124,33 +126,32 @@ sub _dbh_execute {
   my ($dbh, $op, $extra_bind, $ident, $bind_attributes, @args) = @_;
 
   my $wantarray = wantarray;
-
-  my (@res, $exception, $retried);
-
-  RETRY: {
-    do {
-      eval {
-        if ($wantarray) {
-          @res    = $self->next::method(@_);
-        } else {
-          $res[0] = $self->next::method(@_);
-        }
-      };
-      $exception = $@;
-      if ($exception =~ /ORA-01003/) {
+  my ($retried, @res);
+  my $next = $self->next::can;
+  do {
+    try {
+      if ($wantarray) {
+        @res = $self->$next($dbh, $op, $extra_bind, $ident, $bind_attributes, @args);
+      }
+      else {
+        $res[0] = $self->$next($dbh, $op, $extra_bind, $ident, $bind_attributes, @args);
+      }
+      $retried++;
+    }
+    catch {
+      if (/ORA-01003/) {
         # ORA-01003: no statement parsed (someone changed the table somehow,
         # invalidating your cursor.)
         my ($sql, $bind) = $self->_prep_for_execute($op, $extra_bind, $ident, \@args);
         delete $dbh->{CachedKids}{$sql};
-      } else {
-        last RETRY;
       }
-    } while (not $retried++);
-  }
-
-  $self->throw_exception($exception) if $exception;
+      else {
+        $self->throw_exception($_);
+      }
+    };
+  } while (not $retried++);
 
-  $wantarray ? @res : $res[0]
+  return $wantarray ? @res : $res[0];
 }
 
 =head2 get_autoinc_seq
@@ -165,19 +166,6 @@ sub get_autoinc_seq {
   $self->dbh_do('_dbh_get_autoinc_seq', $source, $col);
 }
 
-=head2 columns_info_for
-
-This wraps the superclass version of this method to force table
-names to uppercase
-
-=cut
-
-sub columns_info_for {
-  my ($self, $table) = @_;
-
-  $self->next::method($table);
-}
-
 =head2 datetime_parser_type
 
 This sets the proper DateTime::Format module for use with
index 930a3be..783d334 100644 (file)
@@ -16,6 +16,7 @@ use MooseX::Types::Moose qw/ClassName HashRef Object/;
 use Scalar::Util 'reftype';
 use Hash::Merge;
 use List::Util qw/min max reduce/;
+use Try::Tiny;
 
 use namespace::clean -except => 'meta';
 
@@ -650,7 +651,7 @@ sub execute_reliably {
   my @result;
   my $want_array = wantarray;
 
-  eval {
+  try {
     if($want_array) {
       @result = $coderef->(@args);
     } elsif(defined $want_array) {
@@ -658,19 +659,14 @@ sub execute_reliably {
     } else {
       $coderef->(@args);
     }
+  } catch {
+    $self->throw_exception("coderef returned an error: $_");
+  } finally {
+    ##Reset to the original state
+    $self->read_handler($current);
   };
 
-  ##Reset to the original state
-  $self->read_handler($current);
-
-  ##Exception testing has to come last, otherwise you might leave the 
-  ##read_handler set to master.
-
-  if($@) {
-    $self->throw_exception("coderef returned an error: $@");
-  } else {
-    return $want_array ? @result : $result[0];
-  }
+  return $want_array ? @result : $result[0];
 }
 
 =head2 set_reliable_storage
index db38c42..7ce7de9 100644 (file)
@@ -8,6 +8,7 @@ use DBI ();
 use Carp::Clan qw/^DBIx::Class/;
 use MooseX::Types::Moose qw/Num Int ClassName HashRef/;
 use DBIx::Class::Storage::DBI::Replicated::Types 'DBICStorageDBI';
+use Try::Tiny;
 
 use namespace::clean -except => 'meta';
 
@@ -293,18 +294,16 @@ Returns 1 on success and undef on failure.
 sub _safely {
   my ($self, $replicant, $name, $code) = @_;
 
-  eval {
-    $code->()
-  };
-  if ($@) {
+  return try {
+    $code->();
+    1;
+  } catch {
     $replicant->debugobj->print(sprintf(
       "Exception trying to $name for replicant %s, error is %s",
-      $replicant->_dbi_connect_info->[0], $@)
+      $replicant->_dbi_connect_info->[0], $_)
     );
-    return undef;
-  }
-
-  return 1;
+    undef;
+  };
 }
 
 =head2 connected_replicants
index 7cab9a9..50f4f8b 100644 (file)
@@ -5,6 +5,7 @@ use Scalar::Util 'reftype';
 requires qw/_query_start/;
 
 use namespace::clean -except => 'meta';
+use Try::Tiny;
 
 =head1 NAME
 
@@ -32,7 +33,7 @@ Add C<DSN: > to debugging output.
 around '_query_start' => sub {
   my ($method, $self, $sql, @bind) = @_;
 
-  my $dsn = eval { $self->dsn } || $self->_dbi_connect_info->[0];
+  my $dsn = (try { $self->dsn }) || $self->_dbi_connect_info->[0];
 
   my($op, $rest) = (($sql=~m/^(\w+)(.+)$/),'NOP', 'NO SQL');
   my $storage_type = $self->can('active') ? 'REPLICANT' : 'MASTER';
@@ -41,7 +42,7 @@ around '_query_start' => sub {
     if ((reftype($dsn)||'') ne 'CODE') {
       "$op [DSN_$storage_type=$dsn]$rest";
     }
-    elsif (my $id = eval { $self->id }) {
+    elsif (my $id = try { $self->id }) {
       "$op [$storage_type=$id]$rest";
     }
     else {
index 16adca4..0837554 100644 (file)
@@ -5,6 +5,7 @@ use warnings;
 use base qw/DBIx::Class::Storage::DBI::UniqueIdentifier/;
 use mro 'c3';
 use List::Util ();
+use Try::Tiny;
 
 __PACKAGE__->mk_group_accessors(simple => qw/
   _identity
@@ -62,8 +63,8 @@ sub insert {
     my $table_name = $source->from;
     $table_name    = $$table_name if ref $table_name;
 
-    my ($identity) = eval {
-      local $@; $dbh->selectrow_array("SELECT GET_IDENTITY('$table_name')")
+    my ($identity) = try {
+      $dbh->selectrow_array("SELECT GET_IDENTITY('$table_name')")
     };
 
     if (defined $identity) {
@@ -114,8 +115,13 @@ sub _sql_maker_opts {
 sub build_datetime_parser {
   my $self = shift;
   my $type = "DateTime::Format::Strptime";
-  eval "use ${type}";
-  $self->throw_exception("Couldn't load ${type}: $@") if $@;
+  try {
+    eval "require ${type}"
+  }
+  catch {
+    $self->throw_exception("Couldn't load ${type}: $_");
+  };
+
   return $type->new( pattern => '%Y-%m-%d %H:%M:%S.%6N' );
 }
 
index 8c5f988..9b1214c 100644 (file)
@@ -2,6 +2,7 @@ package DBIx::Class::Storage::DBI::Sybase;
 
 use strict;
 use warnings;
+use Try::Tiny;
 
 use base qw/DBIx::Class::Storage::DBI/;
 
@@ -22,13 +23,13 @@ L<DBD::Sybase>
 sub _rebless {
   my $self = shift;
 
-  my $dbtype = eval {
-    @{$self->_get_dbh->selectrow_arrayref(qq{sp_server_info \@attribute_id=1})}[2]
+  my $dbtype;
+  try {
+    $dbtype = @{$self->_get_dbh->selectrow_arrayref(qq{sp_server_info \@attribute_id=1})}[2]
+  } catch {
+    $self->throw_exception("Unable to estable connection to determine database type: $_")
   };
 
-  $self->throw_exception("Unable to estable connection to determine database type: $@")
-    if $@;
-
   if ($dbtype) {
     $dbtype =~ s/\W/_/gi;
 
@@ -53,17 +54,17 @@ sub _ping {
 
   if ($dbh->{syb_no_child_con}) {
 # if extra connections are not allowed, then ->ping is reliable
-    my $ping = eval { $dbh->ping };
-    return $@ ? 0 : $ping;
+    return try { $dbh->ping } catch { 0; };
   }
 
-  eval {
+  return try {
 # XXX if the main connection goes stale, does opening another for this statement
 # really determine anything?
     $dbh->do('select 1');
+    1;
+  } catch {
+    0;
   };
-
-  return $@ ? 0 : 1;
 }
 
 sub _set_max_connect {
@@ -110,8 +111,11 @@ back to the C<32768> which is the L<DBD::Sybase> default.
 
 sub set_textsize {
   my $self = shift;
-  my $text_size = shift ||
-    eval { $self->_dbi_connect_info->[-1]->{LongReadLen} } ||
+  my $text_size =
+    shift
+      ||
+    try { $self->_dbi_connect_info->[-1]->{LongReadLen} }
+      ||
     32768; # the DBD::Sybase default
 
   return unless defined $text_size;
index 914b75f..47e0aca 100644 (file)
@@ -13,6 +13,7 @@ use Scalar::Util();
 use List::Util();
 use Sub::Name();
 use Data::Dumper::Concise();
+use Try::Tiny;
 
 __PACKAGE__->mk_group_accessors('simple' =>
     qw/_identity _blob_log_on_update _writer_storage _is_extra_storage
@@ -596,7 +597,8 @@ EOF
       return 0;
   });
 
-  eval {
+  my $exception;
+  try {
     my $bulk = $self->_bulk_storage;
 
     my $guard = $bulk->txn_scope_guard;
@@ -640,9 +642,10 @@ EOF
     );
 
     $bulk->_query_end($sql);
+  } catch {
+    $exception = shift;
   };
 
-  my $exception = $@;
   DBD::Sybase::set_cslib_cb($orig_cslib_cb);
 
   if ($exception =~ /-Y option/) {
@@ -728,9 +731,11 @@ sub _remove_blob_cols_array {
 sub _update_blobs {
   my ($self, $source, $blob_cols, $where) = @_;
 
-  my @primary_cols = eval { $source->_pri_cols };
-  $self->throw_exception("Cannot update TEXT/IMAGE column(s): $@")
-    if $@;
+  my @primary_cols = try
+    { $source->_pri_cols }
+    catch {
+      $self->throw_exception("Cannot update TEXT/IMAGE column(s): $_")
+    };
 
 # check if we're updating a single row by PK
   my $pk_cols_in_where = 0;
@@ -762,9 +767,11 @@ sub _insert_blobs {
   my $table = $source->name;
 
   my %row = %$row;
-  my @primary_cols = eval { $source->_pri_cols} ;
-  $self->throw_exception("Cannot update TEXT/IMAGE column(s): $@")
-    if $@;
+  my @primary_cols = try
+    { $source->_pri_cols }
+    catch {
+      $self->throw_exception("Cannot update TEXT/IMAGE column(s): $_")
+    };
 
   $self->throw_exception('Cannot update TEXT/IMAGE column(s) without primary key values')
     if ((grep { defined $row{$_} } @primary_cols) != @primary_cols);
@@ -779,14 +786,13 @@ sub _insert_blobs {
     my $sth = $cursor->sth;
 
     if (not $sth) {
-
       $self->throw_exception(
           "Could not find row in table '$table' for blob update:\n"
         . Data::Dumper::Concise::Dumper (\%where)
       );
     }
 
-    eval {
+    try {
       do {
         $sth->func('CS_GET', 1, 'ct_data_info') or die $sth->errstr;
       } while $sth->fetch;
@@ -804,19 +810,20 @@ sub _insert_blobs {
       $sth->func($blob, length($blob), 'ct_send_data') or die $sth->errstr;
 
       $sth->func('ct_finish_send') or die $sth->errstr;
-    };
-    my $exception = $@;
-    $sth->finish if $sth;
-    if ($exception) {
+    }
+    catch {
       if ($self->using_freetds) {
         $self->throw_exception (
-          'TEXT/IMAGE operation failed, probably because you are using FreeTDS: '
-          . $exception
+          "TEXT/IMAGE operation failed, probably because you are using FreeTDS: $_"
         );
-      } else {
-        $self->throw_exception($exception);
+      }
+      else {
+        $self->throw_exception($_);
       }
     }
+    finally {
+      $sth->finish if $sth;
+    };
   }
 }
 
index 459931c..2014e1d 100644 (file)
@@ -3,6 +3,7 @@ package DBIx::Class::Storage::TxnScopeGuard;
 use strict;
 use warnings;
 use Carp::Clan qw/^DBIx::Class/;
+use Try::Tiny;
 
 sub new {
   my ($class, $storage) = @_;
@@ -31,10 +32,11 @@ sub DESTROY {
     carp 'A DBIx::Class::Storage::TxnScopeGuard went out of scope without explicit commit or error. Rolling back.'
       unless $exception;
 
-    eval { $storage->txn_rollback };
-    my $rollback_exception = $@;
+    my $rollback_exception;
+    try { $storage->txn_rollback }
+    catch { $rollback_exception = shift };
 
-    if ($rollback_exception && $rollback_exception !~ /DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION/) {
+    if (defined $rollback_exception && $rollback_exception !~ /DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION/) {
       if ($exception) {
         $exception = "Transaction aborted: ${exception} "
           ."Rollback failed: ${rollback_exception}";
index 32fe04f..ca25aa2 100644 (file)
@@ -14,8 +14,9 @@ $DEBUG = 0 unless defined $DEBUG;
 
 use Exporter;
 use SQL::Translator::Utils qw(debug normalize_name);
-use Carp::Clan qw/^SQL::Translator|^DBIx::Class/;
+use Carp::Clan qw/^SQL::Translator|^DBIx::Class|^Try::Tiny/;
 use Scalar::Util ();
+use Try::Tiny;
 
 use base qw(Exporter);
 
@@ -43,8 +44,12 @@ sub parse {
 
     croak 'No DBIx::Class::Schema' unless ($dbicschema);
     if (!ref $dbicschema) {
-      eval "use $dbicschema;";
-      croak "Can't load $dbicschema ($@)" if($@);
+      try {
+        eval "require $dbicschema;"
+      }
+      catch {
+        croak "Can't load $dbicschema ($_)";
+      }
     }
 
     my $schema      = $tr->schema;
index 761234d..88049be 100644 (file)
@@ -3,6 +3,7 @@ use warnings;
 
 use Test::More;
 use Test::Exception;
+use Scope::Guard ();
 use lib qw(t/lib);
 use DBICTest;
 
@@ -27,20 +28,20 @@ my @info = (
   [ $dsn2, $user2, $pass2 ],
 );
 
-my @handles_to_clean;
+my $schema;
 
 foreach my $info (@info) {
   my ($dsn, $user, $pass) = @$info;
 
   next unless $dsn;
 
-  my $schema = DBICTest::Schema->clone;
+  $schema = DBICTest::Schema->clone;
 
   $schema->connection($dsn, $user, $pass, {
     on_connect_call => [ 'datetime_setup' ],
   });
 
-  push @handles_to_clean, $schema->storage->dbh;
+  my $sg = Scope::Guard->new(\&cleanup); 
 
 # coltype, col, date
   my @dt_types = (
@@ -72,7 +73,7 @@ SQL
       ->search({ trackid => $row->trackid }, { select => [$col] })
       ->first
     );
-    is( $row->$col, $dt, 'DateTime roundtrip' );
+    is( $row->$col, $dt, "$type roundtrip" );
 
     is $row->$col->nanosecond, $dt->nanosecond,
         'nanoseconds survived' if 0+$dt->nanosecond;
@@ -82,8 +83,8 @@ SQL
 done_testing;
 
 # clean up our mess
-END {
-  foreach my $dbh (@handles_to_clean) {
+sub cleanup {
+  if (my $dbh = $schema->storage->dbh) {
     eval { $dbh->do("DROP TABLE $_") } for qw/track/;
   }
 }