package AppConfig::DBI;

use AppConfig qw(:argcount);
use AppConfig::Std;
use Data::Dumper;
use DBI;


require 5.005_62;
use strict;
use warnings;

require Exporter;

our @ISA = qw(Exporter);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# This allows declaration	use AppConfig::DBI ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw(
	
) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(
	
);
our $VERSION = '0.01';


# Preloaded methods go here.



sub connect_data_for {
    my (undef, $config_name) = @_;

    my $config = AppConfig::Std->new( { CASE=>1 } );
    my $site   = "${config_name}_";

    $config->define("$site$_") for qw(user pass dsn);
    $config->define("${site}attr" => { ARGCOUNT => ARGCOUNT_HASH });

    $config->file($ENV{APPCONFIG_DBI});
    $config->args;

    my %site   = $config->varlist("^$site", 1);

    ($site{dsn}, $site{user}, $site{pass}, $site{attr});
}

sub connect {

    my @connect_data = connect_data_for(@_);

    my $dbh = DBI->connect(@connect_data);

    defined $dbh or 
	die "error on connection to $_[1]: $DBI::errstr";

    $dbh;

}

1;
__END__
# Below is stub documentation for your module. You better edit it!

=head1 NAME

AppConfig::DBI - support for DBI connection (info) via AppConfig 

=head1 SYNOPSIS

 # .cshrc
 setenv APPCONFIG /Users/metaperl/.appconfig # dont forget the dot!!!
 setenv APPCONFIG_DBI "${APPCONFIG}-dbi"

 # .appconfig-dbi
 [basic]
 user	= postgres
 dsn	= dbi:Pg:dbname=mydb
 attr RaiseError =  0
 attr PrintError =  0
 attr Taint      =  1

 # DBIx::AnyDBD usage:
 my @connect_data = AppConfig::DBI->connect_data_for('dev_db');
 my $dbh          = DBIx::AnyDBD->connect(@connect_data, "MyClass");

 # pure DBI usage
 use AppConfig::DBI;

 my $config = shift or die "must give label for config";
 my $dbh    = AppConfig::DBI->connect($config);

 # over-ride .appconfig-dbi from the command line:
 perl dbi-script.pl basic -basic_user tim_bunce -basic_pass dbi_rocks
 perl dbi-script.pl basic -basic_attr "RaiseError=1" -basic_attr "Taint=0"

=head1 DESCRIPTION

This module facilitates DBI-style or DBIx::AnyDBD-style
database connections for sites and applications
which make use of L<AppConfig|AppConfig>
to configure their applications via files
and/or command-line arguments. 

It provides two methods, C<connect> and C<connect_data_for> which 
return a DBI database handle or an array of DBI connection info, 
respectively.

Each of the 4 DBI connection parameters (username, password, dsn, attr)
can be defined via any of the methods supported by AppConfig, meaning
via a configuration file, or simple-style command-line arguments.
AppConfig provides support for both simple and Getopt::Long style,
but Getopt::Long is overkill for a module this simple.

=head1 RELATED MODULES / MOTIVATION FOR THIS ONE

The only module similar to this on CPAN is DBIx::Password. Here are some
points of comparison/contrast.

=over 4

=item * DBI configuration info location

DBIx::Password uses an autogenerated Perl module for its connection 
data storage. AppConfig::DBI uses a Windows INI-style AppConfig file
for its connection information.

The advantage of a config file is that each programmer can have his own
config file whereas it could prove tedious for each programmer to
have his own personal copy of a Perl configuration module.

Not to mention the fact that if each Perl module in your large application
went this route, you would be stuck with n-fold Perl configuration modules
as opposed to one centralized AppConfig file. For example, my module
SQL::Catalog, also uses on-the-fly Config modules and Net::FTP::Common
does as well. 

=item * Routes to configurability and password security

DBIx::Password DBI connection options (username, password, dsn, attr) are 
not over-ridable or settable at the command line. This means passwords must 
be stored in the configuration file and that efforts must be taken to
make a module readable by a program not readable by a human.

In contrast, AppConfig::DBI can add configuration information upon
invocation via the command-line which will overwrite or set arguments which
could have been in the configuration file, which means your passwords need not
be stored on disk at all.

=item * Support for indirect connection

DBIx::Password has one method, C<connect> which returns a C<$dbh>. While
AppConfig::DBI also supplies such a method, it also supplies a 
C<connect_data_for> method which returns an array which can be passed to
any other DBI connection scheme, the must ubiquitous of which is 
DBIx::AnyDBD, which handles connections for you after you give it the
connection data.

I submitted a patch to the author of DBIx::Password to support such
functionality, but it was rejected on the grounds that DBIx::Password is
designed to secure connection data, not make it available in any form
or fashion.

=back

=head2 My CPAN module set will be AppConfig-dependant

From now on, any module of mine which requires configuration info will
use L<AppConfig|AppConfig> to get it. I thought about using XML but a
discussion on Perlmonks.Org and one on p5ee@perl.org both made strong
arguments in favor of AppConfig.

=head2 EXPORT

None by default.

=head1 AUTHOR

T. M. Brannon <tbone@cpan.org>

=head1 SEE ALSO

L<DBIx::Password|DBIx::Password>
L<AppConfig|AppConfig>
L<AppConfig::Std|AppConfig::Std>


=cut
