On Thu, Aug 05, 2004 at 09:42:01AM -0400, [EMAIL PROTECTED] wrote: > All,
Hi Hildo. > We're trying to override the DBI->connect() method for DBD::DB2 to > support longer database names. > > Some background: > - DB2 supports only 8-character database names and aliases > - We plan to have hundreds to thousands of them, so we end up with > non-intelligeble names. > - We have a mapping file that maps logical names (to us, which means > something like NYTD_YOUR_APPLICATION or LNQD_OTHER_APPLICATION) to > one of the 8-character names that DB2 limits us to. > > The first approach we came up with was to define a "Morgan Stanley > DB2" driver, as that would allow us to avoid changing DBD::DB2. > > Hence we wrote DBD::MSDB2, which basically sub-classes DBD::DB2: > > package DBD::MSDB2; > > use DBD::DB2; > use vars qw(@ISA $VERSION); > @ISA = qw(DBD::DB2::dr); > $VERSION = '1.0'; > > # > # Override the 'connect' class method > # > sub connect { > my ($drh, $dbname, $user, $auth, $attr) = @_; > > # Look up the long database name, change $dbname, then... > $drh->SUPER::connect($dbname, $user, $auth, $attr); > } > > and then we try and connect with: > > DBI->connect('dbi:MSDB2:NYTD_YOUR_APPLICATION', $uid, $pwd); > > This leads to the following error: > > DBD::MSDB2 initialisation failed: Can't locate object method "driver" via package > "DBD::MSDB2" (perhaps you forgot to load "DBD::MSDB2"?) at > //ms/dist/perl5/PROJ/DBI/1.42-5.6/lib/perl5/DBI.pm line 727. > > Okay, so change @ISA: > > @ISA = qw(DBD::DB2 DBD::DB2::dr); > > And the next error is: > > Had to create DBD::MSDB2::dr::imp_data_size unexpectedly at > //ms/dist/perl5/PROJ/DBI/1.42-5.6/lib/perl5/DBI.pm line 1061. Use > of uninitialized value in subroutine entry at > //ms/dist/perl5/PROJ/DBI/1.42-5.6/lib/perl5/DBI.pm line 1061. Had > to create DBD::MSDB2::db::imp_data_size unexpectedly at > //ms/dist/perl5/PROJ/DBI/1.42-5.6/lib/perl5/DBI.pm line 1061. Use > of uninitialized value in subroutine entry at > //ms/dist/perl5/PROJ/DBI/1.42-5.6/lib/perl5/DBI.pm line 1061. DBD > driver has not implemented the AutoCommit attribute at > //ms/dist/perl5/PROJ/DBI/1.42-5.6/lib/perl5/DBI.pm line 631. > > Obviously, I'm missing some clues on how to actually do this kind of > thing. Any suggestions? The subclassing of drivers isn't well defined. (You'll find "Simplify layering/subclassing of DBD's" in the plans for DBI v2 :-) DBD::DBM is a subclass of DBD::File so the general code in here http://search.cpan.org/src/TIMB/DBI-1.43/lib/DBD/DBM.pm will help. Specifically the driver() sub. I'd suggest copying DBD::DBM then delete everything in and after sub connect and you'll have a good starting point. You may need a relatively recent DBI. Of course the APIs involved are not well defined or stable - that would require some investment of time and effort to stabilize and document them up... Alternatively, as Darren pointed out, you can subclass the DBI or just write a function to return a $dbh. Or even a wrapper to map database logical names to DBI DNSs. But I imagine you've considered those and you want the driver approach so you can implement it with no application code changes. Tim.