> The inner handle carries all the DBI info, including CachedKids.
> So swap_inner_handle is a simple and total brain transplant.


Q: Any chance of getting "$sth->clone"?

>From what I can see in the doc's, the clone method
is specific to database handles (the statement's clone
would account for cached queries). Matching up the 
cached vs. un-cached values is doable, but getting
the bound variables (especially lexicals) correct
is going to seriously difficult.


>> Or is some similar maintainence done automatically by the 
>> swap_inner_handle? 
> 
> swap_inner_handle just does what it says - swaps handles. That's it.
> 
> I suspect what you'll need to do (for maximum transparency) is perform a
> swap_inner_handle on each of the old dbh's kids to replace the now
> defunct sth's with new ones freshly prepared using the new dbh.

The trick will be matching the values of CachedKids 
to those in ChildHandles to cache the proper set of
handles:

      DB<1> x $dbh->{CachedKids}
    0  HASH(0x86900a4)
       ' select now() ' => DBI::st=HASH(0x868ff24)
            empty hash

Otherwise someone using prepare and prepare_cached
on the same sql string would end up with mismatched
statements after the reconnect.


Q: If the cached kids are stored in $new_dbh, wouldn't I
   overwrite the statement handles when I performed the
   $old_dbh->swap_inner_handle( $new_dbh )?

i.e., wouldn't I get a wholesale duplication via:

    # remake all of the old statement handles
    # using the new database handle.

    $new_dbh->prepare( $_->{Statement} )
    for grep { defined } $old_dbh->{ChildHandles};

    # replace the database handle wholesale.

    $old_dbh->swap_inner_handle( $new_dbh );

(ignoring issues with prepare_cached and bound variables
for a moment)?


Or is it necessary to do something like:

    # save the existing statement handles (assuming
    # they don't survive the $dbh->swap_inner_handle.

    my @old_sth  = grep { defined } @{ $old_dbh->{ChildHandles} }; 

    my $old_kidz = $old_dbh->{ CachedKids };

    my %cached   = reverse %$old_kidz;

    # generate a new dbh and install it.  after the swap,
    # the new kids are empty (based on $new_dbh having
    # no prepared statements yet).

    my $new_dbh  = $old_dbh->clone;

    $old_dbh->swap_inner_handle( $new_dbh );

    my $new_kidz = $old_dbh->{ CachedKids };

    # at this point the swap has wiped out the ChildHandles
    # and CachedKids of $old_dbh; now to regenerate them.

    for my $old_sth ( @old_sth )
    {
        my $sql = $old_sth->{ Statement };

        my $new_sth = $new_dbh->prepare( $sql );

        $old_sth->swap_inner_handle( $new_sth );

        # thankfully, this thing is writeable...

        $new_kidz->{ $sql } = $new_sth
        if $cached{ $old_sth };
    }

The only thing this doesn't pull across that I can think
of is the current row state of each handle and the bound
variables. 


Regenerating the cached queries only would simply
require saving the keys and running $old_dbh->prepare_cached( $_ )
for keys %$saved_kidz_hash; the messy part is going to
be making sure I have the un-cached ones handled properly.


Q: From what I can see, $sth->{Type} doesn't give me
   enough information to tell if a particular sth 
   is cached or not. Am I missing something?

> If so then it's kind'a handy that the DBI now has a $h->{ChildHandles}
> attribute.
>
> If you really want to get fancy you could each check $old_sth->rows and
> then fetch that many rows from the new $sth to leave it in the same
> 'place' (hopefully!) as the original. Just how mad do you want to be?

Only risk there is accidentally restarting the query-from-hell,
but that could be avoided with a configuration parmeter
to DBIx::Viagra.

Q: Is there any chance of getting a 'seek' to handle this?


It would look sometehing like:

    $sth->seek( $sth->rows );

and save me from retrieving the entire list of rows into
core on the local side just to discard them.


I'll leave bound variables until after I've had my morning
coffe.

Thankfully I'm doing this in Perl; Heaven help the 
poor slob who tries this in Java...



Aside: How likely to change is dbh->clone as of 1.50?

    The "clone" method was added in DBI 1.33. It is very new and likely
    to change.

thanx

-- 
Steven Lembark                                       85-09 90th Street
Workhorse Computing                                Woodhaven, NY 11421
[EMAIL PROTECTED]                                     1 888 359 3508

Reply via email to