Author: timbo
Date: Mon Jan  2 06:26:47 2012
New Revision: 15059

Modified:
   dbi/trunk/Changes
   dbi/trunk/DBI.pm
   dbi/trunk/t/30subclass.t

Log:
Fixed $dbh->clone({}) RT73250

Modified: dbi/trunk/Changes
==============================================================================
--- dbi/trunk/Changes   (original)
+++ dbi/trunk/Changes   Mon Jan  2 06:26:47 2012
@@ -12,6 +12,8 @@
   Fixed the definition of ArrayTupleStatus and remove confusion over
     rows affected in list context of execute_array (Martin J. Evans)
   Fixed sql_type_cast example and typo in errors (Martin J. Evans)
+  Fixed Gofer error handling for keeperr methods like ping (Tim Bunce)
+  Fixed $dbh->clone({}) RT73250 (Tim Bunce)
 
   Enhanced and standardized driver trace level mechanism (Tim Bunce)
   Removed old code that was an inneffective attempt to detect
@@ -22,6 +24,7 @@
   Added TXN trace flags and applied CON and TXN to relevant methods (Tim Bunce)
   Added some more fetchall_arrayref(..., $maxrows) tests (Tim Bunce)
   Clarified docs for fetchall_arrayref called on an inactive handle.
+  Clarified docs for clone method (Tim Bunce)
   Reserved spatialite_ as a driver prefix for DBD::Spatialite
   Reserved mo_ as a driver prefix for DBD::MO
   Updated link to the SQL Reunion 95 docs, RT69577 (Ash Daminato)

Modified: dbi/trunk/DBI.pm
==============================================================================
--- dbi/trunk/DBI.pm    (original)
+++ dbi/trunk/DBI.pm    Mon Jan  2 06:26:47 2012
@@ -1511,8 +1511,11 @@
 
     sub clone {
        my ($old_dbh, $attr) = @_;
-       my $closure = $old_dbh->{dbi_connect_closure} or return;
-       unless ($attr) {
+
+       my $closure = $old_dbh->{dbi_connect_closure}
+            or return $old_dbh->set_err($DBI::stderr, "Can't clone handle");
+
+       unless ($attr) { # XXX deprecated, caller should always pass a hash ref
            # copy attributes visible in the attribute cache
            keys %$old_dbh;     # reset iterator
            while ( my ($k, $v) = each %$old_dbh ) {
@@ -1528,6 +1531,7 @@
                ShowErrorStatement TaintIn TaintOut
            ));
        }
+
        # use Data::Dumper; warn Dumper([$old_dbh, $attr]);
        my $new_dbh = &$closure($old_dbh, $attr);
        unless ($new_dbh) {
@@ -1535,6 +1539,7 @@
            my $drh = $old_dbh->{Driver};
            return $old_dbh->set_err($drh->err, $drh->errstr, $drh->state);
        }
+        $new_dbh->{dbi_connect_closure} = $closure;
        return $new_dbh;
     }
 
@@ -4307,31 +4312,26 @@
 
 =head3 C<clone>
 
-  $new_dbh = $dbh->clone();
   $new_dbh = $dbh->clone(\%attr);
 
 The C<clone> method duplicates the $dbh connection by connecting
 with the same parameters ($dsn, $user, $password) as originally used.
 
 The attributes for the cloned connect are the same as those used
-for the original connect, with some other attributes merged over
-them depending on the \%attr parameter.
-
-If \%attr is given then the attributes it contains are merged into
-the original attributes and override any with the same names.
-Effectively the same as doing:
+for the I<original> connect, with any other attributes in C<\%attr>
+merged over them.  Effectively the same as doing:
 
   %attribues_used = ( %original_attributes, %attr );
 
 If \%attr is not given then it defaults to a hash containing all
 the attributes in the attribute cache of $dbh excluding any non-code
 references, plus the main boolean attributes (RaiseError, PrintError,
-AutoCommit, etc.). This behaviour is subject to change.
+AutoCommit, etc.). I<This behaviour is unreliable and so use of clone without
+an argument is deprecated.>
 
 The clone method can be used even if the database handle is disconnected.
 
-The C<clone> method was added in DBI 1.33. It is very new and likely
-to change.
+The C<clone> method was added in DBI 1.33.
 
 =head3 C<data_sources>
 

Modified: dbi/trunk/t/30subclass.t
==============================================================================
--- dbi/trunk/t/30subclass.t    (original)
+++ dbi/trunk/t/30subclass.t    Mon Jan  2 06:26:47 2012
@@ -66,7 +66,7 @@
 # =================================================
 package main;
 
-use Test::More tests => 36;
+use Test::More tests => 43;
 
 BEGIN {
     use_ok( 'DBI' );
@@ -139,13 +139,24 @@
 is($dbh2 != $dbh, 1);
 is($dbh2->{CompatMode}, 1);
 
-my $dbh3 = $dbh->clone;
+my $dbh3 = $dbh->clone({});
 isa_ok( $dbh3, 'MyDBI::db', 'Clone B' );
 is($dbh3 != $dbh, 1);
 is($dbh3 != $dbh2, 1);
 isa_ok( $dbh3, 'MyDBI::db');
 is($dbh3->{CompatMode}, 1);
 
+my $dbh2c = $dbh2->clone;
+isa_ok( $dbh2c, 'MyDBI::db', "Clone of clone A" );
+is($dbh2c != $dbh2, 1);
+is($dbh2c->{CompatMode}, 1);
+
+my $dbh3c = $dbh3->clone({ CompatMode => 0 });
+isa_ok( $dbh3c, 'MyDBI::db', 'Clone of clone B' );
+is((grep { $dbh3c == $_ } $dbh, $dbh2, $dbh3), 0);
+isa_ok( $dbh3c, 'MyDBI::db');
+ok(!$dbh3c->{CompatMode});
+
 $tmp = $dbh->sponge_test_installed_method('foo','bar');
 isa_ok( $tmp, "ARRAY", "installed method" );
 is_deeply( $tmp, [qw( foo bar )] );

Reply via email to