Gauntlet
Gauntlet

Reputation: 141

Subclassing the Perl DBI, overwriting the database handler in the calling script upon disconnection

I have this problem:

pseudocode:

package a;

@ISA = qw(DBI);

package a::db;
@ISA = qw(DBI::db);
    sub prepare{
      #gets a $dbh object, which we can overwrite upon disconnection
      #so that the calling script gets a fresh and working dbh, 
      #through $_[0] = $newdbh;
    }

package a::st;
@ISA = qw(DBI::st);

sub execute{
  #gets a $sth object which we can rescue upon disconnection 
  #before the execute, but the calling script will have a faulty $dbh
}

calling script:

use a;
my $dbh = a->connect;
my $sth = $dbh->prepare("select 1");
$dbh->disconnect; #I detect this in the execute function
$sth->execute; #disconnect detected, reconnect -> reprepare and execute again 
               #(is done in the module a) = we're up and running!

Is there any way to affect the $dbh object without having to call $dbh->prepare again in the calling script?

My problem is also that I want to do this seamlessly because I want to fix the database handling in many projects by just using my new database module.

Is it at all possible?

Or could I maybe make the statement handler from a::prepare part of the ::db package as well? Which in turn would mean that the database handler from a::connect would have to be a statement handler as well, so that when I use connect I get an object with access to both prepare and execute. Then I could modify $_[0] in the a::execute to the new dbh object, which would mean that after the reconnect in the a::execute, the calling script would have a valid $dbh. Tried a lot of ways of doing this but I suspect the inner magic of DBI is making it hard...

Upvotes: 1

Views: 446

Answers (1)

Borodin
Borodin

Reputation: 126732

Subclassing is a way to create a class that behaves identically to another class but with some refinements.

Your a class (could you think of a worse identifier?) doesn't seem to be anything like DBI, and I'm not surprised you're having difficulty expressing what you want in those terms. It sounds like you want an a object to have a DBI connection, not to be one.

So perhaps you could write

package a;

use strict;
use warnings;

use DBI;

sub connect {
  my $self = {};
  $self->{dbh} = DBI->connect(@_);
  $self;
}

Where you go from here I'm not sure, as you've described a proposed solution rather than the problem itself

Upvotes: 1

Related Questions