Hi,
This is a fairly complex setup to explain so I'll initially try and keep
it simple and can expand it necessary. I'm getting the error
$ perl a.pl
SV = RV(0x9fa6df4) at 0xa4450e8
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0xa4451a8
dbih_getcom handle HASH(0xa4451a8) is not a DBI handle (has no magic) at
/usr/lib/perl5/site_perl/5.8.8/DBIx/Log4perl/db.pm line 61.
I'm using DBI 1.51 and DBD::Oracle 1.17 and DBIx::Log4perl 0.05.
DBIx::log4perl is overriding most methods in DBI.
I'm running a script like this:
use XXX::DB;
use Log::Log4perl qw(get_logger :levels);
Log::Log4perl->init_and_watch("/etc/log4.conf", 60);
my $zzz = XXX::DB->new(
{DSN =>"dbi:Oracle:XE",User=>"xxx", Pass=>"yyy"});
my $dbh = $zzz->connect() or die "$DBD::errstr";
$dbh->selectrow_array("select x_entry_status_id from v_market_entries
where entry_id = ? and market_id = ?", undef, 31, 11);
where XXX:DB just provides some extra methods not in DBI to
avoid differences in DBD::oracle, DBD::DB2 and DBD::mysql and
uses Log::Log4perl::get_logger but it only comes in to this in that it
uses DBIx::Log4perl.
If the script is changed to omit the DBIx::Log4perl it becomes:
use DBI;
my $dbh = DBI->connect("dbi:Oracle:XE", "xxx", "yyy",{RaiseError => 1})
or die "$DBD::errstr";
$dbh->selectrow_array("select entry_status_id from v_market_entries
where x_entry_id = ? and market_id = ?", undef, 31, 11);
The first thing to note is the second script works.
The second thing to note is that the column x_entry_id does NOT exist.
If the selectrow_array SQL is for a column that does exist it
works fine in both scripts.
I've read:
+One more thing to note: you must let the DBI do the handle creation.
+If you want to override the connect() method in your *::dr class then
+it must still call SUPER::connect to get a $dbh to work with.
+Similarly, an overridden prepare() method in *::db must still call
+SUPER::prepare to get a $sth. If you try to create your own handles
+using bless() then you'll find the DBI will reject them with an "is not
+a DBI handle (has no magic)" error.
from the DBI changelog and it would suggest I've done something wrong
when overriding the methods in DBI. However, I believe I've done the
SUPER::connect and SUPER::selectrow_array correctly like this (this
example does omit some extra stuff on the private hash):
sub connect {
my ($drh, $dsn, $user, $pass, $attr) = @_;
my %h = ();
my $dbh = $drh->SUPER::connect($dsn, $user, $pass, $attr);
return $dbh if (!$dbh);
# stuff setting $h{xxx}
$dbh->{private_DBIx_Log4perl} = \%h;
return $dbh;
}
sub selectrow_array {
my ($dbh, @args) = @_;
my $h = $dbh->{private_DBIx_Log4perl};
if (wantarray) {
my @ret = $dbh->SUPER::selectrow_array(@args);
return @ret;
} else {
my $ret = $dbh->SUPER::selectrow_array(@args);
return $ret;
}
}
The comment in the DBI changelog suggests I've done something wrong.
Any ideas? If more info is required I can provide but I didn't want
to make this too convoluted initially.
Thanks.
Martin