DBIx::Password is supposed to be a module that:
...provides an abstraction layer for password maintenance. It is database independent and only overrides the connect method (so it basically behaves as DBI normally does). You provide a single virtual user name in the connect method and the module determines which database/which user/which password to provide. -- Brian Aker
In this article, I review this module, having used it for 6 months in a production environment.

Security is an unspoken concern

While not explicitly stated, Brian Aker (module author) has intimated in personal conversations that a driving design factor of this module is to keep production database passwords away from people developing software only for the development environment.

Configuration, not connection

Configuration information is scattered, not centralized

My first issue with this module is that connecting to a database is application configuration information. Therefore, using this module, means that application configuration is in at least two places - this module and one other place for other configuration information.

Kitchen sink: does not catalog database connections - it tries to make connections also

DBIx::Password tries to make database connections for you. This is an issue because certain modules, e.g. DBIx::AnyDBD, must be supplied connection information not given a created database handle. I emailed the author patches and he ignored me. A second email elicited a response about not wanting an API method for revealing connection information.

layed configuration/inheritance not possible

DBIx::Password does not offer layered configuration management. There is no way to override some or all of the aspects of a particular database connection registered with DBIx::Password.

For a programming module to offer less power in configuration than a configuration file (which is nothing but a limited programming language) is hard to understand.

connecting to a database via a string

Here is how you connect to a database using DBIx::Password
my $dbh = DBIx::Password->connect($user);

theory

A normal DBI connection has 4 options:
  1. user
  2. pass
  3. dsn
  4. 10 or so possible attributes
What DBIx::Password does is compress all of this information down into a single connection string. This can certainly be convenient, but the practice section will expose the pitfalls of this for application development.

practice

my $dbh = DBIx::Password->connect($user);
Here are my issues with this:
  1. there is no easy way to dynamically choose/drop arguments to a DBI connection. There are at least 10 possible attributes for a DBI database connection. Since DBIx::Password only accepts a single string, you are forced to pre-define and compress every desired combination of 10 attributes into a single string! And then remember your compression algorithm.

    This is similar to the dilemma between using an ORM and writing SQL. SQL may be more direct, convenient and readable, but when programmatically generating queries from CGI form data, the high-level interface to SQL that an ORM provides is valuable.

    Concretely. Let's assume that you want RaiseError on in development and off in production. Now, if you were being programmatic about this, you would simply have a hashref of production arguments and a similar hashref of development arguments (all of which could be over-ridden programmatically at will):

    sub staging_phase { my($self)=@_; my %phase = ( 'bens.laptop' => 'devel', 'devel.xyz.com' => 'devel', 'webadmin.xyz.com' => 'prod', 'staging.xyz.com' => 'prod' , ); my $h = $self->hostname; my $phase = $ENV{STAGE_PHASE} || $phase{$h} or die 'Could not dete +rmine stage phase hostname: $h' ; $self->log->debug( "<staging_phase>$phase</staging_phase>" ) ; $phase; } sub attributes { $attributes { $self->staging_phase } ; } sub connect { DBI->connect($u, $p, $dsn, $self->attributes); }
    But with DBIx::Password, you would be playing string concatenation games:
    DBIx::Password->connect("${user}_${staging_phase}");
    I think it's clear which approach is more scalable, flexible and high-level.

what's the solution?

My initial problems with Brian led to my development of DBIx::Connect. The need for layered configuration information led to my development of Config::DBI. However, by the time it was all over, a conversation with URI Guttman about application configuration convinced me that a Perl module/class is the most flexible and powerful solution for application configuration.

The use of programming objects for powerful configuration is supported by this python whitepaper as well. I echoed his sentiments during my Python days as well.