On Wed, Aug 17, 2005 at 07:57:08AM +0200, Alexander Foken wrote:
> Tim Bunce wrote:
> 
> >I just called for suggestions, proposals, and random thoughts.
> >It's my job to mix those in with my own random thoughts and
> >try to distill something reasonably coherent and Practical.
> >
> >Then we'll go round the loop a few (dozen) times kicking the tires
> >and mixing metaphors till enough people are happy enough.
> >(I get the casting vote on behalf of the silent majority :)
>
> Just two ideas from one of the usually silent majority:
> 
> First: There should be a *simple* way for a DBD to inherit from another DBD.

Yes, that's a big part of the plan. Logging and profiling, for example,
may be implemented by a proxy driver that intercepts and forwards calls
to the main driver.

> From what I've learned the last two weeks about the internals of 
> the DBI, this is currently done in a way that is quite different from 
> the way the remainder of Perl does it. I would like to be able to do the 
> following:
> 
>    package DBD::MyBadlyHackedODBC;
>    use base 'DBD::ODBC'; # <--- ordinary Perl inheritance without any DBI 
> "magic"
>    sub someMethodInODBC
>    {
>        my $self=shift;
>        $self->SUPER::someMethodInODBC(reverse @_)
>    }
>    1;
>    my $dbh=DBI->connect('dbi:MyBadlyHackedODBC',...);
> 
> This would allow me to change the behaviour of a DBD for my needs 
> without having to dig through kilobytes of C and XS code.
> 
> DBDs are currently four classes, making this kind of inheritance a 
> little bit harder, because my hacked DBD would have to inherit the base, 
> ::dr, ::db and ::st classes.

Yeap.

> Perhaps a tiny pragmatic module could help: 
> use DBI::base 'DBD::ODBC' (instead of use base 'DBD::ODBC') would create 
> the four classes for my hacked DBD, all inheriting from their 
> corresponding classes. So my code would look like this:
> 
>    package DBD::MyBadlyHackedODBC;
>    use DBI::base 'DBD::ODBC';
>    package DBD::MyBadlyHackedODBC::db;
>    sub prepare
>    {
>        my ($dbh, $statement, $attribs)[EMAIL PROTECTED];
>        $dbh->SUPER::prepare(reverse $statement,$attribs)
>    }
>    1;

Patches welcome!

It certainly can be done: DBD::CSV, for example, is a subclass of DBD::File.

> Second: $h->func(@func_arguments, $func_name) is ugly. The $func_name 
> argument should really be the first argument, not the last. 

That was done for efficiency (back in the days when that mattered more)
so the name could just be popped off the argument stack.

But these days you shouldn't use func() at all - the driver should use
install_method() to register its private methods with the DBI dispatcher
so they can be called directly.

> DBD::Foo::db->install_method($method_name, \%attr); is a step into the 
> right direction, but the driver-specific methods should be available for 
> use right after DBI->connect(), without having to "import" them 
> manually.

The _driver_ is meant to call install_method when it's loaded.
Talk to the driver authors. I'm just the man in the middle.

> The driver-specific prefix is a good thing, it clearly 
> indicates non-portable code: If I write 
> $dbh->pg_polish_harddisk('now','shiny'), why should I have to call 
> DBD::Pg::db->install_method('pg_polish_harddisk') first?

You shouldn't - see above.

Tim.

Reply via email to