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.