I'm saying that when you subclass the DBI (not a driver) then
the connect method in your dr subclass is not called.

So if you've used a subclass called MyDBI then your MyDBI::dr::connect
method is not called by MyDBI->connect.

(The drivers own ...::dr::connect method is still being called.)

You need to either do what you want in your MyDBI::connect method
or in your MyDBI::db::connected method.

Tim.


On Tue, Jun 20, 2006 at 06:04:19PM +0100, Martin J. Evans wrote:
> Tim,
> 
> I'm sorry but I obviously being a bit thick here. I'm using DBD::Oracle. Are
> you saying DBD::Oracle::dr::connect is not being called and I
> need to create a DBIx::Log4perl::db::connected method and call
> DBD::Oracle::dr::connect in it and if so how?
> 
> Martin
> --
> Martin J. Evans
> Easysoft Ltd, UK
> http://www.easysoft.com
> 
> 
> On 20-Jun-2006 Tim Bunce wrote:
> > I think a similar issue came up a few months ago.
> > 
> > It turns out that the *::dr::connect method is not called.  
> > There's a comment in t/30subclass.t that says:
> > 
> >     # the MyDBI::dr::connect method is NOT called!
> >     # you can either override MyDBI::connect()
> >     # or use MyDBI::db::connected()
> > 
> > but the DBI docs haven't been updated to match.
> > Sorry about that.
> > 
> > Patches welcome.
> > 
> > Tim.
> > 
> > On Mon, Jun 19, 2006 at 07:51:38PM +0100, Martin J. Evans wrote:
> >> 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
> >> 
> >>                                                                            
> >>   
> 

Reply via email to