File Coverage

File:blib/lib/Data/Phrasebook/Loader/DBI.pm
Coverage:97.3%

linestmtbranchcondsubpodtimecode
1package Data::Phrasebook::Loader::DBI;
2
2
2
2
441
259
619
use strict;
3
2
2
2
729
160
842
use warnings FATAL => 'all';
4
2
2
2
834
97
726
use base qw( Data::Phrasebook::Loader::Base Data::Phrasebook::Debug );
5
2
2
2
750
378
659
use Carp qw( croak );
6
2
2
2
1094
202
978
use DBI;
7
8our $VERSION = '0.04';
9
10 - 102
=head1 NAME

Data::Phrasebook::Loader::DBI - Absract your phrases with a DBI driver.

=head1 SYNOPSIS

    use Data::Phrasebook;

    my $q = Data::Phrasebook->new(
        class     => 'Fnerk',
        loader    => 'DBI',
        file      => {
            dsn       => 'dbi:mysql:database=test',
            dbuser    => 'user',
            dbpass    => 'pass',
            dbtable   => 'phrasebook',
            dbcolumns => ['keyword','phrase','dictionary'],
        }
    );

    OR

    my $q = Data::Phrasebook->new(
        class     => 'Fnerk',
        loader    => 'DBI',
        file      => {
            dbh       => $dbh,
            dbtable   => 'phrasebook',
            dbcolumns => ['keyword','phrase','dictionary'],
        }
    );

    $q->delimiters( qr{ \[% \s* (\w+) \s* %\] }x );
    my $phrase = $q->fetch($keyword);

=head1 ABSTRACT

This module provides a loader class for phrasebook implementations using DBI.

=head1 DESCRIPTION

This class loader implements phrasebook patterns using DBI.

Phrases can be contained within one or more dictionaries, with each phrase
accessible via a unique key. Phrases may contain placeholders, please see
L<Data::Phrasebook> for an explanation of how to use these. Groups of phrases
are kept in a dictionary. The first dictionary is used as the default, unless
a specific dictionary is requested.

This module provides a base class for phrasebook implementations via a database.
Note that the order of table columns is significant. If there is no dictionary
field, all entries are assumed to be part of the default dictionary.

=head1 INHERITANCE

L<Data::Phrasebook::Loader::DBI> inherits from the base class
L<Data::Phrasebook::Loader::Base>.
See that module for other available methods and documentation.

=head1 METHODS

=head2 load

Given the appropriate settings, connects to the designated database. Note that
for consistency, the connection string and other database specific settings,
are passed via a hashref.

   $loader->load( $file );

The hashref can be either:

   my $file => {
            dsn       => 'dbi:mysql:database=test',
            dbuser    => 'user',
            dbpass    => 'pass',
            dbtable   => 'phrasebook',
            dbcolumns => ['keyword','phrase','dictionary'],
   };

which will create a connection to the specified database. Or:

   my $file => {
            dbh       => $dbh,
            dbtable   => 'phrasebook',
            dbcolumns => ['keyword','phrase','dictionary'],
   };

which will reuse and already established connection.

This method is used internally by L<Data::Phrasebook::Generic>'s
C<data> method, to initialise the data store.

=cut
103
104sub load
105{
106
11
1
25112
    my ($self, $file, $dict) = @_;
107
108
11
1637
        $self->{file} = $file;
109
11
2275
        $self->{dict} = $dict;
110
111
11
2624
        croak "Phrasebook table name missing"
112                unless($self->{file}{dbtable});
113
9
3785
        croak "Phrasebook column names missing"
114                unless($self->{file}{dbcolumns} &&
115
10
3163
                       scalar(@{$self->{file}{dbcolumns}}) >= 2);
116
117
8
2903
        $self->{dbh} = $self->{file}{dbh} if(defined $self->{file}{dbh});
118
119
8
1734
        $self->{dbh} ||= do {
120
4
1112
                croak "No DSN specified for a database connection"
121                        unless($self->{file}{dsn});
122
3
1895
                croak "DB user details missing"
123                        unless($self->{file}{dbuser} && $self->{file}{dbpass});
124
125
1
571
                DBI->connect( $self->{file}{dsn},
126                                                $self->{file}{dbuser}, $self->{file}{dbpass},
127                                                { RaiseError => 1, AutoCommit => 1 });
128        };
129};
130
131 - 137
=head2 get

Returns the phrase stored in the phrasebook, for a given keyword.

   my $value = $loader->get( $key );

=cut
138
139sub get {
140
8
1
26096
    my ($self,$key) = @_;
141
142
8
26365
        my $sql =
143                        'SELECT '.$self->{file}{dbcolumns}[1].
144                        ' FROM '.$self->{file}{dbtable}.
145                        ' WHERE '.$self->{file}{dbcolumns}[0].'=?';
146
8
50958
        $sql .= ' AND '.$self->{file}{dbcolumns}[2].'=?'
147                if($self->{file}{dbcolumns}[2]);
148
149
8
1985
        my $sth = $self->{dbh}->prepare($sql);
150
8
9053
        if($self->{file}{dbcolumns}[2]) {
151
6
1294
                $sth->execute($key,$self->{dict});
152        } else {
153
2
320
                $sth->execute($key);
154        }
155
8
16169
        my @row = $sth->fetchrow_array;
156
8
5874
        $sth->finish;
157
8
4024
        return $row[0];
158}
159
160sub DESTROY {
161
1
332
        my $self = shift;
162
1
142
        $self->{dbh}->disconnect if defined $self->{dbh};
163}
164
1651;
166