On Tue, Jan 19, 2010 at 09:04:43PM +0000, Martin J. Evans wrote:
> Hi,
> 
> Is there anything special a subclassed DBI module (DBIx::Log4perl in
> this case) needs to do for the clone method?
> 
> The DBI docs currently say "The clone method duplicates the $dbh
> connection by connecting with the same parameters ($dsn, $user,
> $password) as originally used."

    sub clone {
        my ($old_dbh, $attr) = @_;
        my $closure = $old_dbh->{dbi_connect_closure} or return;

That's a closure created by connect() that performs the $drh->connect call.

        unless ($attr) {
            # copy attributes visible in the attribute cache
            keys %$old_dbh;     # reset iterator
            while ( my ($k, $v) = each %$old_dbh ) {
                # ignore non-code refs, i.e., caches, handles, Err etc
                next if ref $v && ref $v ne 'CODE'; # HandleError etc
                $attr->{$k} = $v;
            }
            # explicitly set attributes which are unlikely to be in the
            # attribute cache, i.e., boolean's and some others
            $attr->{$_} = $old_dbh->FETCH($_) for (qw(
                AutoCommit ChopBlanks InactiveDestroy
                LongTruncOk PrintError PrintWarn Profile RaiseError
                ShowErrorStatement TaintIn TaintOut
            ));
        }
        # use Data::Dumper; warn Dumper([$old_dbh, $attr]);
        my $new_dbh = &$closure($old_dbh, $attr);
        unless ($new_dbh) {
            # need to copy err/errstr from driver back into $old_dbh
            my $drh = $old_dbh->{Driver};
            return $old_dbh->set_err($drh->err, $drh->errstr, $drh->state);
        }
        return $new_dbh;
    }

> but I don't see any call to connect when clone is called.

You don't see a call to DBI->connect, but there is a call to
$drh->connect via the closure.

> I presume there is something I need to do - any ideas?

The closure calles the connected() method ad that's a good method to
override to (re)setup any private stuff you need.

Tim.

Reply via email to