2010/8/11 Dan <d...@dwright.org>:
> 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

Reply via email to