> 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