Re: Trying to track down bug in DBD::Multi

Jens Rehsack <[email protected]>
Newsgroups gmane.comp.lang.perl.modules.dbi.sybase.devel
Message-ID <[email protected]>
2010/8/11 Dan <[email protected]>:
> Hi,

Hi Dan,

> I received a bug report (#60193) regarding the following error with
> DBD::Multi:
>
> DBD::Multi initialisation failed: invalid method name 'versions' at
> /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/DBI/DBD/
> SqlEngine.pm line 88
> at t/dbd-multi-db.t line 10
>
> From what I can tell, that "invalid method name" error originates from
> DBI::install_method:
>
>        Carp::croak("invalid method name '$method'")
>            unless $method =~ m/^([a-z]+_)\w+$/;
>
> From what I can gather, DBI::DBD::SqlEngine is calling DBI-
>>driver_prefix('DBD::multi'), getting back undef, concatenating that
> undef with 'versions', and then making a call to
> DBD::_::common::install_method('DBD::Multi::db', 'versions').   This
> dying because the method name is lacking an underscore.

No, it's dying because install_method allows only method names
with valid driver prefixes. DBD::Multi isn't registered in
$dbd_prefix_registry in DBI.pm, but it probably should be there ;)

I'm sorry, I didn't recognize that DBD::Multi is derived from DBD::File,
this is my fault, I should add a registry key for it.

> Here's a call stack from the perl debugger right before it dies:
>
> . = DBD::_::common::install_method('DBD::Multi::db', 'versions')
> called from file `/usr/local/lib/perl5/site_perl/5.10.1/i386-freebsd/
> DBI/DBD/SqlEngine.pm' line 88
> $ = DBI::DBD::SqlEngine::driver('DBD::Multi', ref(HASH)) called from
> file `/usr/local/lib/perl5/site_perl/5.10.1/i386-freebsd/DBD/File.pm'
> line 73
> $ = DBD::File::driver('DBD::Multi', ref(HASH)) called from file `/usr/
> local/lib/perl5/site_perl/5.10.1/DBD/Multi.pm' line 20
> $ = DBD::Multi::driver('DBD::Multi', ref(HASH)) called from file `/usr/
> local/lib/perl5/site_perl/5.10.1/i386-freebsd/DBI.pm' line 811
> $ = eval {...} called from file `/usr/local/lib/perl5/site_perl/5.10.1/
> i386-freebsd/DBI.pm' line 811
> $ = DBI::install_driver('DBI', 'Multi') called from file `/usr/local/
> lib/perl5/site_perl/5.10.1/i386-freebsd/DBI.pm' line 643
> $ = DBI::connect('DBI', 'DBI:Multi:') called from file `t/dbd-multi-
> dr.t' line 9
>
> This appears to be a chance in functionality of DBD::File that was
> introduced in 1.611_90.   Prior to that, I don't think it attempted to
> inject the versions method.
>
> So, I have two questions:
>
> 1.  Does my analysis seem correct?

Mostly, especially the relevant parts.

> 2.  Any suggestions on the best way to allow DBD::Multi to continue to
> work with both older releases of DBI and also work with revisions >=
> 1.612?

I can do two fixes:
1) DBD::File can skip method injection when no prefix found
2) Add a registry key for DBD::Multi to DBI

But this will keep you failing for DBI between 1.612 and 1.614.

You can add following code to your DBD::Multi::db:

if( DBI->version lt '1.614' ) {
    *version = sub {};
    *get_meta = sub {};
    *set_meta = sub {};
    *clear_meta = sub {};
}

This will lead DBD::File (and DBI::DBD::SqlEngine) to skip the
method injection and installing.

I fear, this won't be the only issues you will encounter when
using old DBD::File based code with DBD::File >= 0.39.
Probably you've recognized (I hope you are subscribed on this
mailing-list) the issues Steffen had while porting DBD::PO to
new DBD::File.

But you do not need any of the features provided by DBD::File
or DBI::DBD::SqlEngine - you can avoid deriving from both and
derive directly from DBD::_::* by calling DBI->setup_driver
somewhere in your DBD::Multi module.

Best regards,
Jens
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.