# vim: ts=8 sw=8 tw=0 ai nu noet
#
# PDF::ReportWriter::Datasource::DBI
#
# See COPYRIGHT file for full license
# See 'perldoc PDF::ReportWriter::Datasource' for documentation
#
# $Id: DBI.pm 14 2006-03-27 16:48:43Z cosimo $
package PDF::ReportWriter::Datasource::DBI;
$VERSION = '1.0';
use strict;
use Carp;
use base q(PDF::ReportWriter::Datasource);
# ? Impose a reasonably new version of DBI? (1.3x?)
use DBI;
sub connect
{
my $self = $_[0];
my $ds_def = $self->definition;
my $dsn = $ds_def->{dsn};
my $user = $ds_def->{user} || undef;
my $pass = $ds_def->{pass} || undef;
my $attr = $ds_def->{attr} || {PrintError=>1,RaiseError=>1};
my $dbh = DBI->connect($dsn, $user, $pass, $attr);
if( ! $dbh )
{
croak 'PDF::ReportWriter::Datasource::DBI: could not connect to '.$dsn;
}
return($dbh);
}
sub get_data
{
my $self = $_[0];
my $input_values = $self->{input};
my $ds_def = $self->definition;
my $dsn = $ds_def->{dsn};
# Placeholders ($1, $2, ...) are considered input values
# to be fed in the query when running the report
my $sql = $ds_def->{sql};
# Interpolate all `?' placeholders in SQL query
# (NOTE: this is not necessary if placeholders are a
#$self->replace_input_values(\$sql, $input_values);
# Try to execute the SQL query as is
my $dbh = $self->connect();
my $ok = 0;
my $sth;
my $data;
if( $sth = $dbh->prepare($sql) )
{
# XXX `input_values' should be given according to
# sql query placeholders, or this is going to fail...
if( $ok = $sth->execute(@$input_values) )
{
$data = $sth->fetchall_arrayref();
}
$sth->finish();
}
# Check results
if( ! $ok || $@ )
{
croak 'PDF::ReportWriter::Datasource::DBI: error ' . $dbh->err() . ' executing query (' . $dbh->errstr() . ')';
return undef;
}
return $data;
}
1;
=head1 NAME
PDF::ReportWriter::Datasource::DBI
=head1 DESCRIPTION
Custom Datasource class that allows access to a generic DBI DSN.
=head1 USAGE
Example of code fragment to include in your xml report:
<report>
...
<data>
...
<datasource name="customer">
<type>DBI</type>
<dsn>DBI:Pg:dbname=accounting</dsn>
<user>postgres</user>
<pass>postgres</pass>
<sql>SELECT * FROM customers WHERE id=?</sql>
<attr>
<ChopBlanks>1</ChopBlanks>
<PrintError>1</PrintError>
<RaiseError>1</RaiseError>
</attr>
</datasource>
</data>
...
</report>
=head1 ISSUES
Currently I don't know why with CSV driver this does not work.
Probably it's necessary to tweak the csv_tables or csv_csv structure?
=head1 AUTHORS
=over 4
=item Cosimo Streppone <cosimo@cpan.org>
=back
=cut