Tim Bunce wrote on 30 November 2004 23:32
> On Tue, Nov 30, 2004 at 09:38:47PM +0000, Nicholas Clark wrote:
> > On Tue, Nov 30, 2004 at 08:53:51PM +0000, Tim Bunce wrote:
> > 
> > > I don't get it. Can someone give me some small but real examples
> > > of the problem that's being solved here?
> > 
> > The one that I've hit - specifying port and host, Pg vs 
> Mysql (and SQlite):
> > 
> >   if ($dbspec->{driver} eq 'DBI:Pg') {
> >     # Aaargh. Why aren't these things standarised?
> >     $dsn = "DBI:Pg:host=$dbspec->{domain}";
> >     # Aargh. W.T.F. is this case sensitivity here? It fails 
> to connect unless
> >     # the name is all lowercase (as is stored within the 
> non-case preserving
> >     # pg DB)
> >     $dsn .= lc ";dbname=$dbspec->{db_name}" if length 
> $dbspec->{db_name};
> >     $dsn .= ";port=$dbspec->{port}" if defined $dbspec->{port};
> >   } else {
> >     $dsn .= ":port=$dbspec->{port}" if defined $dbspec->{port};
> >   }
> 
> It seems to me that the problem is of your own making.
> Why have separate hash elements for all these things in the 
> first place?

In my case because if I connect to the same database from two different
servers with two different versions of Sybase Open Client then DBD::Sybase
and the underlying drivers need connection strings that are totally
different (and not at all intuitive IMO) but contain basically the same
data. Thus I have an ini file that contains the appropriate info along with
a special entry that determines which style to use. Now only one thing needs
to be changed between the two machines.

This is part of the code that handles building the connection string from
the ini file:


    if (lc($style) eq "short") {
        $fmt="DRIVER={%s};UID=%s;PWD=%s;SRVR=%s;DB=%s";
        @args=qw(driver username password  server dbname);
    } elsif (lc($style) eq "long") {
        $fmt="DRIVER={%s};UID=%s;PWD=%s;NLN=%s;NA=%s;DB=%s";
        @args=qw(driver username password protocol server dbname);

And here is what the inifile looks like:

        [dsn]
        ; this is the setting for GOBS01 PRODUCTION
        style    = short
        driver   = Sybase ASE ODBC Driver
        username = him_or_me
        password = uhuh
        server   = that_server_there
        dbname   = funky_db
        protocol = blahblah

Now if we used two connection strings we have all of that data duplicated in
the two strings, which as we all know is a scenario just crying out for
refactoring. We in fact did do this for some time, but it was always falling
out of synch when the data needed to change and the ops folks were forever
changing the wrong string. 

Ive got other examples of this. If you use DBD::ODBC you need an entirely
different connection string than when using the faster and better
DBD::Sybase which has as I already mentioned different requirements
depending on local features. Since we had some weird compatibilitiy issue
with Sybase Open Client for a while in some places our code had to fallback
to using DBD::ODBC when DBD::Sybase diver was unavailable, resulting in even
more connection string variants.

IMO the idea of this module is great and frankly resolves something that ive
heard many a folk (here and elsewhere) bitch about being one of DBI's few
annoyances. (That and $dbh->selectall_arrayref($query,{Slice=>{}}) ;-)

I will say that I agree entirely with those who argue that DBIx::DBH is a
bad name. IMO DBI itself should have a more transparent way of handling this
so an additional module is not required. Surely there is base information
that pretty well all serious DB's will require to open a connection so
mandating a driver agnostic interface to providing those details and then
letting the driver do the rest would seem to make sense. 

Yves

Reply via email to