1 # Copyright (C) 2005 Stanislav Sinyagin
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18 # Stanislav Sinyagin <ssinyagin@yahoo.com>
20 # Package for RDBMS communication management in Torrus
21 # Classes should inherit Torrus::SQL and execute Torrus::SQL->new(),
22 # and then use methods of DBIx::Abstract.
35 my %connectionArgsCache;
37 # Obtain connection attributes for particular class and object subtype.
38 # The attributes are defined in torrus-siteconfig.pl, in a hash
39 # %Torrus::SQL::connections.
40 # For a given Perl class and an optional subtype,
41 # the connection attributes are derived in the following order:
42 # 'Default', 'Default/[subtype]', '[Class]', '[Class]/[subtype]',
44 # For a simple setup, the default attributes are usually defined for
46 # The key attributes are: 'dsn', 'username', and 'password'.
47 # Returns a hash reference with the same keys.
55 my $cachekey = $objClass . ( defined( $subtype )?
'/'.$subtype : '');
56 if( defined( $connectionArgsCache{$cachekey} ) )
58 return $connectionArgsCache{$cachekey};
61 my @lookup = ('Default');
62 if( defined( $subtype ) )
64 push( @lookup, 'Default/' . $subtype );
66 push( @lookup, $objClass );
67 if( defined( $subtype ) )
69 push( @lookup, $objClass . '/' . $subtype, 'All/' . $subtype );
73 for my $attr ( 'dsn', 'username', 'password' )
76 for my $key ( @lookup )
78 if( defined( $Torrus::SQL
::connections
{$key} ) )
80 if( defined( $Torrus::SQL
::connections
{$key}{$attr} ) )
82 $val = $Torrus::SQL
::connections
{$key}{$attr};
86 if( not defined( $val ) )
88 die('Undefined attribute in %Torrus::SQL::connections: ' . $attr);
93 $connectionArgsCache{$cachekey} = $ret;
101 # For those who want direct DBI manipulation, simply call
102 # Class->dbh($subtype) with optional subtype. Then you don't use
103 # any other methods of Torrus::SQL.
110 my $attrs = Torrus
::SQL
->getConnectionArgs( $class, $subtype );
112 my $poolkey = $attrs->{'dsn'} . '//' . $attrs->{'username'} . '//' .
113 $attrs->{'password'};
117 if( exists( $dbhPool{$poolkey} ) )
119 $dbh = $dbhPool{$poolkey};
120 if( not $dbh->ping() )
123 delete $dbhPool{$poolkey};
127 if( not defined( $dbh ) )
129 $dbh = DBI
->connect( $attrs->{'dsn'},
130 $attrs->{'username'},
131 $attrs->{'password'},
133 'AutoCommit' => 0 } );
135 if( not defined( $dbh ) )
137 Error
('Error connecting to DBI source ' . $attrs->{'dsn'} . ': ' .
142 $dbhPool{$poolkey} = $dbh;
152 for my $dbh ( values %dbhPool )
166 $self->{'dbh'} = $class->dbh( $subtype );
167 if( not defined( $self->{'dbh'} ) )
172 $self->{'sql'} = DBIx
::Abstract
->connect( $self->{'dbh'} );
174 $self->{'subtype'} = $subtype;
175 $self->{'classname'} = $class;
177 bless ($self, $class);
187 if( not defined( $self->{'sequence'} ) )
189 my $attrs = Torrus
::SQL
->getConnectionArgs( $self->{'classname'},
190 $self->{'subtype'} );
192 $self->{'sequence'} = DBIx
::Sequence
->new({
193 dbh
=> $self->{'dbh'},
194 allow_id_reuse
=> 1 });
196 return $self->{'sequence'};
204 return $self->sequence()->Next($self->{'classname'});
214 while( defined( my $row = $self->{'sql'}->fetchrow_arrayref() ) )
218 for my $col ( @
{$columns} )
220 $retrecord->{$col} = $row->[$i++];
222 push( @
{$ret}, $retrecord );
234 # indent-tabs-mode: nil
235 # perl-indent-level: 4