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.

Reply via email to