trying to subclass DBI

trying to subclass DBI

am 29.12.2005 00:39:39 von s.wernerus

Hi,

I'm new to OO programming, and i'd like to subclass DBI for some purpose.

I made some tests to figure out how it worked. Here is a sample code
that doesn't do anything interesting. It doesn't execute as I
expected:

==================== ==
package MySubDBI;

use strict;

use DBI;
use vars qw(@ISA);
@ISA =3D qw(DBI);

package MySubDBI::db;
use vars qw(@ISA);
@ISA =3D qw(DBI::db);

sub connect {
my ($drh, @args) =3D @_;
my $dbh =3D $drh->SUPER::connect(@args) or return;
$dbh->{private_mysubdbi_test} =3D 'blabla';
print "test0\n";
return $dbh;
}

sub test {
my $dbh =3D shift;
return $dbh->{private_mysubdbi_test};
}

package MySubDBI::st;
use vars qw(@ISA);
@ISA =3D qw(DBI::st);

package Main;

my $dbn =3D "DBI:mysql:database=3D***:host=3D***:port=3D***";

my $dbh =3D MySubDBI->connect( $dbn, '***', '***' );
if ( $dbh ) { print "connection ok\n" } else { print "connection error\n" }

print 'test1: ', $dbh->{private_mysubdbi_test}, "\n";
print 'test2: ', $dbh->test, "\n";
==================== ==

It prints:
connection ok
test1:
test2:

Do you know why it doesn't print the string 'test0' and nothing for
test1 and test2 ?

Re: trying to subclass DBI

am 29.12.2005 22:44:55 von banjo

On 12/28/05, wernerus sebastien wrote:
> ==================== ==
> package MySubDBI;
>
> use strict;
>
> use DBI;
> use vars qw(@ISA);
> @ISA =3D qw(DBI);
>
> package MySubDBI::db;
> use vars qw(@ISA);
> @ISA =3D qw(DBI::db);
>
> sub connect {

The connect method should be in MySubDBI, not MySubDBI::db.

> Do you know why it doesn't print the string 'test0' and nothing for
> test1 and test2 ?

Because it is calling DBI::connect since MySubDBI does not define one.

dd
--
David Dooling

Re: trying to subclass DBI

am 29.12.2005 23:46:49 von Tim.Bunce

The connect() method needs to be in a MySubDBI::dr package (that's dr not db)

Tim.

On Thu, Dec 29, 2005 at 12:39:39AM +0100, wernerus sebastien wrote:
> Hi,
>
> I'm new to OO programming, and i'd like to subclass DBI for some purpose.
>
> I made some tests to figure out how it worked. Here is a sample code
> that doesn't do anything interesting. It doesn't execute as I
> expected:
>
> ======================
> package MySubDBI;
>
> use strict;
>
> use DBI;
> use vars qw(@ISA);
> @ISA = qw(DBI);
>
> package MySubDBI::db;
> use vars qw(@ISA);
> @ISA = qw(DBI::db);
>
> sub connect {
> my ($drh, @args) = @_;
> my $dbh = $drh->SUPER::connect(@args) or return;
> $dbh->{private_mysubdbi_test} = 'blabla';
> print "test0\n";
> return $dbh;
> }
>
> sub test {
> my $dbh = shift;
> return $dbh->{private_mysubdbi_test};
> }
>
> package MySubDBI::st;
> use vars qw(@ISA);
> @ISA = qw(DBI::st);
>
> package Main;
>
> my $dbn = "DBI:mysql:database=***:host=***:port=***";
>
> my $dbh = MySubDBI->connect( $dbn, '***', '***' );
> if ( $dbh ) { print "connection ok\n" } else { print "connection error\n" }
>
> print 'test1: ', $dbh->{private_mysubdbi_test}, "\n";
> print 'test2: ', $dbh->test, "\n";
> ======================
>
> It prints:
> connection ok
> test1:
> test2:
>
> Do you know why it doesn't print the string 'test0' and nothing for
> test1 and test2 ?

Re: trying to subclass DBI

am 30.12.2005 00:24:02 von Tyler

Tim,
My DBI subclass places connect in it's root class
(DBIx::Transaction):

http://search.cpan.org/src/CRAKRJACK/DBIx-Transaction-0.002/ lib/DBIx/Transaction.pm

Is this supposed to work as well, or should I move it into dr? (Is
there a situation/driver where this won't work?)

Thanks,
Tyler


Tim Bunce wrote:
> The connect() method needs to be in a MySubDBI::dr package (that's dr not db)
>
> Tim.
>
> On Thu, Dec 29, 2005 at 12:39:39AM +0100, wernerus sebastien wrote:
> > Hi,
> >
> > I'm new to OO programming, and i'd like to subclass DBI for some purpose.
> >
> > I made some tests to figure out how it worked. Here is a sample code
> > that doesn't do anything interesting. It doesn't execute as I
> > expected:
> >
> > ======================
> > package MySubDBI;
> >
> > use strict;
> >
> > use DBI;
> > use vars qw(@ISA);
> > @ISA = qw(DBI);
> >
> > package MySubDBI::db;
> > use vars qw(@ISA);
> > @ISA = qw(DBI::db);
> >
> > sub connect {
> > my ($drh, @args) = @_;
> > my $dbh = $drh->SUPER::connect(@args) or return;
> > $dbh->{private_mysubdbi_test} = 'blabla';
> > print "test0\n";
> > return $dbh;
> > }
> >
> > sub test {
> > my $dbh = shift;
> > return $dbh->{private_mysubdbi_test};
> > }
> >
> > package MySubDBI::st;
> > use vars qw(@ISA);
> > @ISA = qw(DBI::st);
> >
> > package Main;
> >
> > my $dbn = "DBI:mysql:database=***:host=***:port=***";
> >
> > my $dbh = MySubDBI->connect( $dbn, '***', '***' );
> > if ( $dbh ) { print "connection ok\n" } else { print "connection error\n" }
> >
> > print 'test1: ', $dbh->{private_mysubdbi_test}, "\n";
> > print 'test2: ', $dbh->test, "\n";
> > ======================
> >
> > It prints:
> > connection ok
> > test1:
> > test2:
> >
> > Do you know why it doesn't print the string 'test0' and nothing for
> > test1 and test2 ?
>

Re: trying to subclass DBI

am 30.12.2005 12:58:02 von s.wernerus

Tim, I made the changes you suggested. Here is the code:

-------------------------------
package MySubDBI;

use strict;

use DBI;
use vars qw(@ISA);
@ISA =3D qw(DBI);

package MySubDBI::dr;
use vars qw(@ISA);
@ISA =3D qw(DBI::dr);

sub connect {
my ($drh, @args) =3D @_;
my $dbh =3D $drh->SUPER::connect(@args)
or return;
$dbh->{private_mysubdbi_test} =3D 'blabla';
print "test0\n";
return $dbh;
}

package MySubDBI::db;
use vars qw(@ISA);
@ISA =3D qw(DBI::db);

sub test {
my $dbh =3D shift;
return $dbh->{private_mysubdbi_test};
}

package MySubDBI::st;
use vars qw(@ISA);
@ISA =3D qw(DBI::st);

package Main;

my $dbn =3D "DBI:mysql:database=3D***:host=3D***:port=3D***";

my $dbh =3D MySubDBI->connect( $dbn, '***', '***' );
if ( $dbh ) { print "connection ok\n" } else { print "connection error\n" }

print 'test1: ', $dbh->{private_mysubdbi_test}, "\n";
print 'test2: ', $dbh->test, "\n";
-------------------------------

But it gives exactly the same result, namely:

connection ok
test1:
test2:

Re: trying to subclass DBI

am 30.12.2005 21:09:22 von mlists

wernerus sebastien wrote:
> Tim, I made the changes you suggested. Here is the code:
>
> -------------------------------
> package MySubDBI;

....


> package Main;

try:

package main; #IE lowercase "M", not Main..

Also be sure to:
use strict;
use warnings;
in each package as that will likley tell you what is wrong (assuming it
a programming error and not a subclassing paradigm error which useing
strict and warnings will assist in catching/ruling that out)

Re: trying to subclass DBI

am 30.12.2005 21:21:45 von Tim.Bunce

On Fri, Dec 30, 2005 at 12:58:02PM +0100, wernerus sebastien wrote:
> Tim, I made the changes you suggested. Here is the code:
> -------------------------------

Thanks.

> -------------------------------
>
> But it gives exactly the same result, namely:
> connection ok
> test1:
> test2:

Umm. [...later...] Ah. The current t/30subclass.t test doesn't check
that connect was called, and it isn't. And that's by design (I think :)

To intercept the connect you can override one of these two methods:

- MySubDBI::connect
- MySubDBI::db::connected

Tim.

Re: trying to subclass DBI

am 02.01.2006 14:48:04 von s.wernerus

Ok, your are right. It seems that to override the 'connect' method,
you have to put it in MySubDBI::connect package.

Thank you for your help.

On 12/30/05, Tim Bunce wrote:
> On Fri, Dec 30, 2005 at 12:58:02PM +0100, wernerus sebastien wrote:
> > Tim, I made the changes you suggested. Here is the code:
> > -------------------------------
>
> Thanks.
>
> > -------------------------------
> >
> > But it gives exactly the same result, namely:
> > connection ok
> > test1:
> > test2:
>
> Umm. [...later...] Ah. The current t/30subclass.t test doesn't check
> that connect was called, and it isn't. And that's by design (I think :)
>
> To intercept the connect you can override one of these two methods:
>
> - MySubDBI::connect
> - MySubDBI::db::connected
>
> Tim.
>
>
>