对Perl DBI进行子类化,在断开连接时覆盖调用脚本中的数据库处理程序

时间:2014-06-21 11:08:32

标签: perl dbi

我有这个问题:

伪代码:

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
}

调用脚本:

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!

有没有办法影响$ dbh对象而不必在调用脚本中再次调用$ dbh-> prepare?

我的问题还在于我想要无缝地执行此操作,因为我想通过使用我的新数据库模块来修复许多项目中的数据库处理。

是否可能?

或者我可以从:: db包的:: prepare部分创建语句处理程序吗?这反过来意味着来自:: connect的数据库处理程序也必须是一个语句处理程序,所以当我使用connect时,我得到一个可以访问prepare和execute的对象。然后我可以将a :: execute中的$ _ [0]修改为新的dbh对象,这意味着在a :: execute中重新连接之后,调用脚本将具有有效的$ dbh。尝试了很多这样做的方法,但我怀疑DBI的内在魔力正在使它变得困难......

1 个答案:

答案 0 :(得分:1)

子类化是一种创建类的方法,该类的行为与另一个类相同,但有一些改进。

你的a课程(你能想到一个更糟糕的标识符?)似乎不像DBI那样,我也不会惊讶你难以表达你想要的东西这些条款。听起来你想要一个a对象拥有一个DBI连接,而不是 一个。

所以也许你可以写

package a;

use strict;
use warnings;

use DBI;

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

你离开这里我不确定,因为你已经描述了一个建议的解决方案而不是问题本身