File Coverage

blib/lib/Tie/DBI.pm
Criterion Covered Total %
statement 259 338 76.6
branch 81 166 48.8
condition 16 51 31.3
subroutine 34 46 73.9
pod 7 8 87.5
total 397 609 65.1


line stmt bran cond sub pod time code
1             package Tie::DBI;
2              
3 1     1   955169 use strict;
  1         3  
  1         42  
4 1     1   5 use vars qw($VERSION);
  1         3  
  1         62  
5 1     1   7 use Carp;
  1         6  
  1         85  
6 1     1   11 use DBI;
  1         1  
  1         79  
7             $VERSION = '1.06';
8              
9             BEGIN {
10 1     1   3 eval {
11 1 50       7 require Encode::compat if $] < 5.007001;
12 1         42676 require Encode;
13             };
14             }
15              
16             # Default options for the module
17             my %DefaultOptions = (
18             'user' => '',
19             'password' => '',
20             'AUTOCOMMIT' => 1,
21             'WARN' => 0,
22             'DEBUG' => 0,
23             'CLOBBER' => 0,
24             'CASESENSITIV' => 0,
25             );
26              
27             # DBD drivers that work correctly with bound variables
28             my %CAN_BIND = (
29             'ODBC' => 1,
30             'AnyData' => 1,
31             'mysql' => 1,
32             'mSQL' => 1,
33             'Oracle' => 1,
34             'CSV' => 1,
35             'DBM' => 1,
36             'Sys' => 1,
37             'Pg' => 1,
38             'PO' => 1,
39             'Informix' => 1,
40             'Solid' => 1,
41             );
42             my %CANNOT_LISTFIELDS = (
43             'SQLite' => 1,
44             'Oracle' => 1,
45             'CSV' => 1,
46             'DBM' => 1,
47             'PO' => 1,
48             'AnyData' => 1,
49             'mysqlPP' => 1,
50             );
51             my %CAN_BINDSELECT = (
52             'mysql' => 1,
53             'mSQL' => 1,
54             'CSV' => 1,
55             'Pg' => 1,
56             'Sys' => 1,
57             'DBM' => 1,
58             'AnyData' => 1,
59             'PO' => 1,
60             'Informix' => 1,
61             'Solid' => 1,
62             'ODBC' => 1,
63             );
64             my %BROKEN_INSERT = (
65             'mSQL' => 1,
66             'CSV' => 1,
67             );
68             my %NO_QUOTE = (
69             'Sybase' => { map { $_ => 1 } ( 2, 6 .. 17, 20, 24 ) },
70             );
71             my %DOES_IN = (
72             'mysql' => 1,
73             'Oracle' => 1,
74             'Sybase' => 1,
75             'CSV' => 1,
76             'DBM' => 1, # at least with SQL::Statement
77             'AnyData' => 1,
78             'Sys' => 1,
79             'PO' => 1,
80             );
81              
82             # TIEHASH interface
83             # tie %h,Tie::DBI,[dsn|dbh,table,key],\%options
84             sub TIEHASH {
85 1     1   421024 my $class = shift;
86 1         2 my ( $dsn, $table, $key, $opt );
87 1 50       9 if ( ref( $_[0] ) eq 'HASH' ) {
88 1         2 $opt = shift;
89 1         4 ( $dsn, $table, $key ) = @{$opt}{ 'db', 'table', 'key' };
  1         5  
90             }
91             else {
92 0         0 ( $dsn, $table, $key, $opt ) = @_;
93             }
94              
95 1 50 33     16 croak "Usage tie(%h,Tie::DBI,dsn,table,key,\\%options)\n or tie(%h,Tie::DBI,{db=>\$db,table=>\$table,key=>\$key})"
      33        
96             unless $dsn && $table && $key;
97 1 50       16 my $self = {
98             %DefaultOptions,
99             defined($opt) ? %$opt : ()
100             };
101 1         3 bless $self, $class;
102 1         3 my ( $dbh, $driver );
103              
104 1 50       8 if ( UNIVERSAL::isa( $dsn, 'DBI::db' ) ) {
105 1         4 $dbh = $dsn;
106 1         44 $driver = $dsn->{Driver}{Name};
107 1         16 $dbh->{Warn} = $self->{WARN};
108             }
109             else {
110 0 0       0 $dsn = "dbi:$dsn" unless $dsn =~ /^dbi/;
111 0         0 ($driver) = $dsn =~ /\w+:(\w+)/;
112              
113             # Try to establish connection with data source.
114 0         0 delete $ENV{NLS_LANG}; # this gives us 8 bit characters ??
115              
116 0         0 $dbh = $class->connect(
117             $dsn,
118             $self->{user},
119             $self->{password},
120             {
121             AutoCommit => $self->{AUTOCOMMIT},
122              
123             #ChopBlanks=>1, # Removed per RT 19833 This may break legacy code.
124             PrintError => 0,
125             Warn => $self->{WARN},
126             }
127             );
128 0         0 $self->{needs_disconnect}++;
129 0 0       0 croak "TIEHASH: Can't open $dsn, ", $class->errstr unless $dbh;
130             }
131              
132 1 50       6 if ( $driver eq 'Oracle' ) {
133              
134             #set date format
135 0         0 my $sth = $dbh->prepare("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'");
136 0         0 $sth->execute();
137             }
138              
139             # set up more instance variables
140 1         3 @{$self}{ 'dbh', 'table', 'key', 'driver' } = ( $dbh, $table, $key, $driver );
  1         5  
141 1         4 $self->{BrokenInsert} = $BROKEN_INSERT{$driver};
142 1         4 $self->{CanBind} = $CAN_BIND{$driver};
143 1   33     14 $self->{CanBindSelect} = $self->{CanBind} && $CAN_BINDSELECT{$driver};
144 1         6 $self->{NoQuote} = $NO_QUOTE{$driver};
145 1         3 $self->{DoesIN} = $DOES_IN{$driver};
146 1         4 $self->{CannotListfields} = $CANNOT_LISTFIELDS{$driver};
147              
148 1         9 return $self;
149             }
150              
151             sub DESTROY {
152 1 50 33 1   149 $_[0]->{'dbh'}->disconnect
153             if defined $_[0]->{'dbh'}
154             && $_[0]->{needs_disconnect};
155             }
156              
157             sub FETCH {
158 20     20   714 my ( $s, $key ) = @_;
159              
160             # user could refer to $h{a,b,c}: handle this case
161 20         143 my (@keys) = split( $;, $key );
162 20         34 my ( $tag, $query );
163 20 100       61 if ( @keys > 1 ) { # need an IN clause
164 1         3 my ($count) = scalar(@keys);
165 1         4 $tag = "fetch$count";
166 1 50       5 if ( !$s->{CanBindSelect} ) {
167 1         12 foreach (@keys) { $_ = $s->_quote( $s->{key}, $_ ); }
  2         6  
168             }
169 1 50       8 if ( $s->{DoesIN} ) {
170 0         0 $query = "SELECT $s->{key} FROM $s->{table} WHERE $s->{key} IN (" . join( ",", ('?') x $count ) . ')';
171             }
172             else {
173 1         8 $query = "SELECT $s->{key} FROM $s->{table} WHERE " . join( ' OR ', ("$s->{key}=?") x $count );
174             }
175             }
176             else {
177 19         31 $tag = "fetch1";
178 19 50       116 @keys = $s->_quote( $s->{key}, $key ) unless $s->{CanBindSelect};
179 19         406 $query = "SELECT $s->{key} FROM $s->{table} WHERE $s->{key} = ?";
180             }
181 20   33     75 my $st = $s->_run_query( $tag, $query, @keys ) || croak "FETCH: ", $s->errstr;
182              
183             # slightly more efficient for one key
184 20 100       67 if ( @keys == 1 ) {
185 19         554 my $r = $st->fetch;
186 19         92 $st->finish;
187 19 50       51 return undef unless $r;
188 19         80 my $h = {};
189 19         299 tie %$h, 'Tie::DBI::Record', $s, $r->[0];
190 19         9322 return $h;
191             }
192              
193             # general case -- multiple keys
194 1         3 my ( $r, %got );
195 1         12 while ( $r = $st->fetch ) {
196 2         3 my $h = {};
197 2         18 tie %$h, 'Tie::DBI::Record', $s, $r->[0];
198 2         23 $got{ $r->[0] } = $h;
199             }
200 1         4 $st->finish;
201 1         19 @keys = split( $;, $key );
202 1 50       18 return ( @keys > 1 ) ? [ @got{@keys} ] : $got{ $keys[0] };
203             }
204              
205             sub FIRSTKEY {
206 4     4   28 my $s = shift;
207 4   33     26 my $st = $s->_prepare( 'fetchkeys', "SELECT $s->{key} FROM $s->{table}" )
208             || croak "FIRSTKEY: ", $s->errstr;
209 4 50       330 $st->execute()
210             || croak "FIRSTKEY: ", $s->errstr;
211 4         28 my $ref = $st->fetch;
212 4 100       15 unless ( defined($ref) ) {
213 1         4 $st->finish;
214 1         10 delete $s->{'fetchkeys'}; #freakin' sybase bug
215 1         25 return undef;
216             }
217 3         18 return $ref->[0];
218             }
219              
220             sub NEXTKEY {
221 16     16   67 my $s = shift;
222 16         30 my $st = $s->_prepare( 'fetchkeys', '' );
223              
224             # no statement handler defined, so nothing to iterate over
225 16 0       31 return wantarray ? () : undef unless $st;
    50          
226 16         189 my $r = $st->fetch;
227 16 100       37 if ( !$r ) {
228 3         9 $st->finish;
229 3         8 delete $s->{'fetchkeys'}; #freakin' sybase bug
230 3 50       61 return wantarray ? () : undef;
231             }
232              
233             # Should we do a tie here?
234 13         107 my ( $key, $value ) = ( $r->[0], {} );
235 13 50       66 return wantarray ? ( $key, $value ) : $key;
236             }
237              
238             # Unlike fetch, this never goes to the cache
239             sub EXISTS {
240 2     2   420 my ( $s, $key ) = @_;
241 2 50       21 $key = $s->_quote( $s->{key}, $key ) unless $s->{CanBindSelect};
242 2         18 my $st = $s->_run_query( 'fetch1', "SELECT $s->{key} FROM $s->{table} WHERE $s->{key} = ?", $key );
243 2 50       10 croak $DBI::errstr unless $st;
244 2         23 $st->fetch;
245 2         12 my $rows = $st->rows;
246 2         8 $st->finish;
247 2         33 $rows != 0;
248             }
249              
250             sub CLEAR {
251 1     1   2 my $s = shift;
252 1 50       8 croak "CLEAR: read-only database"
253             unless $s->{CLOBBER} > 2;
254              
255 1         7 my $st = $s->_prepare( 'clear', "delete from $s->{table}" );
256 1 50       47472 $st->execute()
257             || croak "CLEAR: delete statement failed, ", $s->errstr;
258 1         24 $st->finish;
259             }
260              
261             sub DELETE {
262 1     1   429 my ( $s, $key ) = @_;
263 1 50       5 croak "DELETE: read-only database"
264             unless $s->{CLOBBER} > 1;
265 1 50       9 $key = $s->_quote( $s->{key}, $key ) unless $s->{CanBindSelect};
266 1   33     7 my $st = $s->_run_query( 'delete', "delete from $s->{table} where $s->{key} = ?", $key )
267             || croak "DELETE: delete statement failed, ", $s->errstr;
268 1         56 $st->finish;
269              
270             }
271              
272             sub STORE {
273 12     12   1736 my ( $s, $key, $value ) = @_;
274              
275             # There are two cases where this can be called. In the first case, we are
276             # passed a hash reference to field names and their values. In the second
277             # case, we are passed a Tie::DBI::Record, for the purposes of a cloning
278             # operation.
279 12 50       57 croak "STORE: attempt to store non-hash value into record"
280             unless ref($value) eq 'HASH';
281              
282 12 50       48 croak "STORE: read-only database"
283             unless $s->{CLOBBER} > 0;
284              
285 12         16 my (@fields);
286 12         50 my $ok = $s->_fields();
287 12         110 foreach ( sort keys %$value ) {
288 29 100       82 if ( $_ eq $s->{key} ) {
289 5 50       25 carp qq/Ignored attempt to change value of key field "$s->{key}"/ if $s->{WARN};
290 5         9 next;
291             }
292 24 50       65 if ( !$ok->{$_} ) {
293 0 0       0 carp qq/Ignored attempt to set unknown field "$_"/ if $s->{WARN};
294 0         0 next;
295             }
296 24         150 push( @fields, $_ );
297             }
298 12 50       44 return undef unless @fields;
299 12         34 my (@values) = map { $value->{$_} } @fields;
  24         71  
300              
301             # Attempt an insert. If that fails (usually because the key already exists),
302             # perform an update. For this to work correctly, the key field MUST be marked unique
303 12         26 my $result;
304 12 50       46 if ( $s->{BrokenInsert} ) { # check for broken drivers
305 0 0       0 $result =
306             $s->EXISTS($key)
307             ? $s->_update( $key, \@fields, \@values )
308             : $s->_insert( $key, \@fields, \@values );
309             }
310             else {
311 12         24 eval {
312 12         312 local ( $s->{'dbh'}->{PrintError} ) = 0; # suppress warnings
313 12         69 $result = $s->_insert( $key, \@fields, \@values );
314             };
315 12 100       77 $result or $result = $s->_update( $key, \@fields, \@values );
316             }
317 12 50       73 croak "STORE: ", $s->errstr if $s->error;
318              
319             # Neat special case: If we are passed an empty anonymous hash, then
320             # we must tie it to Tie::DBI::Record so that the correct field updating
321             # behavior springs into existence.
322 12 50       416 tie %$value, 'Tie::DBI::Record', $s, $key
323             unless %$value;
324             }
325              
326             sub fields {
327 0     0 0 0 my $s = shift;
328 0         0 return keys %{ $s->_fields() };
  0         0  
329             }
330              
331             sub dbh {
332 0     0 1 0 $_[0]->{'dbh'};
333             }
334              
335             sub commit {
336 0     0 1 0 $_[0]->{'dbh'}->commit();
337             }
338              
339             sub rollback {
340 0     0 1 0 $_[0]->{'dbh'}->rollback();
341             }
342              
343             # The connect() method is responsible for the low-level connect to
344             # the database. It should return a database handle or return undef.
345             # You may want to override this to connect via a subclass of DBI, such
346             # as Apache::DBI.
347             sub connect {
348 0     0 1 0 my ( $class, $dsn, $user, $password, $options ) = @_;
349 0         0 return DBI->connect( $dsn, $user, $password, $options );
350             }
351              
352             # Return a low-level error. You might want to override this
353             # if you use a subclass of DBI
354             sub errstr {
355 0     0 1 0 return $DBI::errstr;
356             }
357              
358             sub error {
359 12     12 1 111 return $DBI::err;
360             }
361              
362             sub select_where {
363 1     1 1 353 my ( $s, $query ) = @_;
364              
365             # get rid of everything but the where clause
366 1         6 $query =~ s/^\s*(select .+)?where\s+//i;
367 1   33     11 my $st = $s->{'dbh'}->prepare("select $s->{key} from $s->{table} where $query")
368             || croak "select_where: ", $s->errstr;
369 1 50       380 $st->execute()
370             || croak "select_where: ", $s->errstr;
371 1         2 my ( $key, @results );
372 1         16 $st->bind_columns( undef, \$key );
373 1         46 while ( $st->fetch ) {
374 2         25 push( @results, $key );
375             }
376 1         4 $st->finish;
377 1         20 return @results;
378             }
379              
380             # ---------------- everything below this line is private --------------------------
381             sub _run_query {
382 64     64   105 my $self = shift;
383 64         162 my ( $tag, $query, @bind_variables ) = @_;
384 64 50       249 if ( $self->{CanBind} ) {
385 0 0 0     0 unless ( !$self->{CanBindSelect} && $query =~ /\bwhere\b/i ) {
386 0         0 my $sth = $self->_prepare( $tag, $query );
387 0 0       0 return unless $sth->execute(@bind_variables);
388 0         0 return $sth;
389             }
390             }
391 64         225 local ($^W) = 0; # kill uninitialized variable warning
392             # if we get here, then we can't bind, so we replace ? with escaped parameters
393 64         245 while ( ( my $pos = index( $query, '?' ) ) >= 0 ) {
394 95         137 my $value = shift(@bind_variables);
395 95 50       582 substr( $query, $pos, 1 ) = ( defined($value) ? ( $self->{CanBind} ? $self->{'dbh'}->quote($value) : $value ) : 'null' );
    50          
396             }
397 64         9549 my $sth = $self->{'dbh'}->prepare($query);
398 64 100 66     813138 return unless $sth && $sth->execute;
399 58         943 return $sth;
400             }
401              
402             sub _fields {
403 35     35   62 my $self = shift;
404 35 100       112 unless ( $self->{'fields'} ) {
405              
406 1         3 my ( $dbh, $table ) = @{$self}{ 'dbh', 'table' };
  1         3  
407              
408 1         3 local ($^W) = 0; # kill uninitialized variable warning
409 1 50       5 my $sth = $dbh->prepare("LISTFIELDS $table") unless ( $self->{CannotListfields} );
410              
411             # doesn't support LISTFIELDS, so try SELECT *
412 1 0 33     6 unless ( !$self->{CannotListfields} && defined($sth) && $sth->execute ) {
      33        
413 1   33     9 $sth = $dbh->prepare("SELECT * FROM $table WHERE 0=1")
414             || croak "_fields() failed during prepare(SELECT) statement: ", $self->errstr;
415 1 50       157 $sth->execute()
416             || croak "_fields() failed during execute(SELECT) statement: ", $self->errstr;
417             }
418              
419             # if we get here, we can fetch the names of the fields
420 1         2 my %fields;
421 1 50       4 if ( $self->{'CASESENSITIV'} ) {
422 0         0 %fields = map { $_ => 1 } @{ $sth->{NAME} };
  0         0  
  0         0  
423             }
424             else {
425 1         2 %fields = map { lc($_) => 1 } @{ $sth->{NAME} };
  4         12  
  1         14  
426             }
427              
428 1         7 $sth->finish;
429 1         4 $self->{'fields'} = \%fields;
430             }
431 35         83 return $self->{'fields'};
432             }
433              
434             sub _types {
435 53     53   88 my $self = shift;
436 53 100       192 return $self->{'types'} if $self->{'types'};
437 1         2 my ( $sth, %types );
438              
439 1 50       6 if ( $self->{'driver'} eq 'Oracle' ) {
440 0         0 $sth = $self->{'dbh'}->prepare( "SELECT column_name,data_type FROM ALL_TAB_COLUMNS WHERE TABLE_NAME = " . $self->{'dbh'}->quote("$self->{table}") );
441 0 0       0 $sth->execute()
442             || croak "_types() failed during execute(SELECT) statement: $DBI::errstr";
443              
444 0         0 while ( my ( $col_name, $col_type ) = $sth->fetchrow() ) {
445 0         0 $types{$col_name} = $col_type;
446             }
447             }
448              
449             else {
450 1   33     14 $sth = $self->{'dbh'}->prepare("SELECT * FROM $self->{table} WHERE 0=1")
451             || croak "_types() failed during prepare(SELECT) statement: $DBI::errstr";
452 1 50       780 $sth->execute()
453             || croak "_types() failed during execute(SELECT) statement: $DBI::errstr";
454 1         17 my $types = $sth->{TYPE};
455 1         11 my $names = $sth->{NAME};
456 1         3 %types = map { shift(@$names) => $_ } @$types;
  4         14  
457             }
458 1         17 return $self->{'types'} = \%types;
459             }
460              
461             sub _fetch_field ($$) {
462 23     23   39 my ( $s, $key, $fields ) = @_;
463 23 50       210 $key = $s->_quote( $s->{key}, $key ) unless $s->{CanBindSelect};
464 23         78 my $valid = $s->_fields();
465 23         98 my @valid_fields = grep( $valid->{$_}, @$fields );
466 23 50       57 return undef unless @valid_fields;
467              
468 23         50 my $f = join( ',', @valid_fields );
469 23   33     122 my $st = $s->_run_query( "fetch$f", "SELECT $f FROM $s->{table} WHERE $s->{key}=?", $key )
470             || croak "_fetch_field: ", $s->errstr;
471              
472 23         46 my ( @r, @results );
473 23         399 while ( @r = $st->fetchrow_array ) {
474 23 50       51 my @i = map { $valid->{$_} ? shift @r : undef } @$fields;
  24         100  
475 23 50       72 if ( $s->{ENCODING} ) {
476 0         0 @i = map { _decode( $s->{ENCODING}, $_ ) } @i;
  0         0  
477             }
478 23 100       184 push( @results, ( @$fields == 1 ) ? $i[0] : [@i] );
479             }
480              
481 23         68 $st->finish;
482 23 50       433 return ( @results > 1 ) ? \@results : $results[0];
483             }
484              
485             sub _insert {
486 12     12   28 my ( $s, $key, $fields, $values ) = @_;
487 12         58 push( @$fields, $s->{key} );
488 12         25 push( @$values, $key );
489 12         52 my @values = $s->_quote_many( $fields, $values );
490 12         164 my (@Qs) = ('?') x @$values;
491 12         25 local ($") = ',';
492 12         109 my $st = $s->_run_query( "insert@$fields", "insert into $s->{table} (@$fields) values (@Qs)", @values );
493 12         33 pop(@$fields);
494 12         31 pop(@$values);
495 12 100       1112 return $st ? $st->rows : 0;
496             }
497              
498             sub _update {
499 6     6   17 my ( $s, $key, $fields, $values ) = @_;
500 6         12 my (@set) = map { "$_=?" } @$fields;
  6         26  
501 6         551 my @values = $s->_quote_many( $fields, $values );
502 6 50       101 $key = $s->_quote( $s->{key}, $key ) unless $s->{CanBindSelect};
503 6         14 local ($") = ',';
504 6         42 my $st = $s->_run_query(
505             "update@$fields",
506             "update $s->{table} set @set where $s->{key}=?", @values, $key
507             );
508 6 50       1147 return unless $st;
509 6         472 return $st->rows;
510             }
511              
512             sub _quote_many {
513 18     18   32 my ( $s, $fields, $values ) = @_;
514              
515 18 50       55 if ( $s->{CanBind} ) {
516 0 0       0 if ( $s->{ENCODING} ) {
517 0         0 return map { _encode( $s->{ENCODING}, $_ ) } @$values;
  0         0  
518             }
519             else {
520 0         0 return @$values;
521             }
522             }
523              
524 18         35 my $noquote = $s->{NoQuote};
525 18 50       45 unless ($noquote) {
526 18 50       43 if ( $s->{ENCODING} ) {
527 0         0 return map { $s->{'dbh'}->quote( _encode( $s->{ENCODING}, $_ ) ) } @$values;
  0         0  
528             }
529             else {
530 18         33 return map { $s->{'dbh'}->quote($_) } @$values;
  42         586  
531             }
532             }
533 0         0 my @values = @$values;
534 0         0 my $types = $s->_types;
535 0         0 for ( my $i = 0; $i < @values; $i++ ) {
536 0 0       0 next if $noquote->{ $types->{ $fields->[$i] } };
537 0 0 0     0 if ( $s->{'driver'} eq 'Oracle' && $types->{ $fields->[$i] } eq 'DATE' ) {
538 0         0 my $epoch_date = str2time( $values[$i] );
539 0         0 my $temp = time2iso($epoch_date);
540 0         0 $temp = $s->{'dbh'}->quote($temp);
541 0         0 $values[$i] = $temp;
542             }
543             else {
544 0         0 $values[$i] = $s->{'dbh'}->quote( $values[$i] );
545             }
546             }
547 0         0 return @values;
548             }
549              
550             sub _quote {
551 53     53   109 my ( $s, $field, $value ) = @_;
552 53         138 my $types = $s->_types;
553 53 50       238 if ( my $noquote = $s->{NoQuote} ) {
554 0 0       0 return $noquote->{ $types->{$field} } ? $value : $s->{'dbh'}->quote($value);
555             }
556              
557 53 50 33     530 if ( $s->{'driver'} eq 'Oracle' && $types->{$field} eq 'DATE' ) {
558 0         0 my $epoch_date = str2time($value);
559 0         0 my $temp = time2iso($epoch_date);
560 0         0 $temp = $s->{'dbh'}->quote($temp);
561              
562             #my $temp = $s->{'dbh'}->quote($value);
563 0         0 $temp = "to_date($temp,'YYYY-MM-DD HH24:MI:SS')";
564 0         0 return $temp;
565             }
566             else {
567 53 50       124 $value = _encode( $s->{ENCODING}, $value ) if $s->{ENCODING};
568 53         325 $value = $s->{'dbh'}->quote($value);
569 53         689 return $value;
570             }
571             }
572              
573             sub _prepare ($$$) {
574 21     21   42 my ( $self, $tag, $q ) = @_;
575 21 100       195 unless ( exists( $self->{$tag} ) ) {
576 5 50       16 return undef unless $q;
577 5 50       14 warn $q, "\n" if $self->{DEBUG};
578 5         62 my $sth = $self->{'dbh'}->prepare($q);
579 5         448 $self->{$tag} = $sth;
580             }
581             else {
582 16 50       38 $self->{$tag}->finish if $q; # in case we forget
583             }
584 21         50 $self->{$tag};
585             }
586              
587             sub _encode {
588 0     0   0 eval { return Encode::encode( $_[0], $_[1] ); };
  0         0  
589             }
590              
591             sub _decode {
592 0     0   0 eval { return Encode::decode( $_[0], $_[1] ); };
  0         0  
593             }
594              
595             package Tie::DBI::Record;
596 1     1   38695 use strict;
  1         3  
  1         58  
597 1     1   6 use vars qw($VERSION);
  1         1  
  1         58  
598 1     1   19 use Carp;
  1         1  
  1         95  
599 1     1   7 use DBI;
  1         2  
  1         761  
600             $VERSION = '0.50';
601              
602             # TIEHASH interface
603             # tie %h,Tie::DBI::Record,dbh,table,record
604             sub TIEHASH {
605 21     21   37 my $class = shift;
606 21         44 my ( $table, $record ) = @_;
607 21         148 return bless {
608             'table' => $table, # table object
609             'record' => $record, # the record we're keyed to
610             }, $class;
611             }
612              
613             sub FETCH {
614 23     23   589 my ( $s, $field ) = @_;
615 23 50       70 return undef unless $s->{'table'};
616 23         214 my (@fields) = split( $;, $field );
617 23         105 return $s->{'table'}->_fetch_field( $s->{'record'}, \@fields );
618             }
619              
620             sub DELETE {
621 1     1   4 my ( $s, $field ) = @_;
622 1         6 $s->STORE( $field, undef );
623             }
624              
625             sub STORE {
626 5     5   14 my ( $s, $field, $value ) = @_;
627 5         43 $s->{'table'}->STORE( $s->{'record'}, { $field => $value } );
628             }
629              
630             # Can't delete the record in this way, but we can
631             # clear out all the fields by setting them to undef.
632             sub CLEAR {
633 0     0   0 my ($s) = @_;
634 0 0       0 croak "CLEAR: read-only database"
635             unless $s->{'table'}->{CLOBBER} > 1;
636 0         0 my %h = map { $_ => undef } keys %{ $s->{'table'}->_fields() };
  0         0  
  0         0  
637 0         0 delete $h{ $s->{'record'} }; # can't remove key field
638 0         0 $s->{'table'}->STORE( $s->{'record'}, \%h );
639             }
640              
641             sub FIRSTKEY {
642 0     0   0 my $s = shift;
643 0         0 my $a = scalar keys %{ $s->{'table'}->_fields() };
  0         0  
644 0         0 each %{ $s->{'table'}->_fields() };
  0         0  
645             }
646              
647             sub NEXTKEY {
648 0     0   0 my $s = shift;
649 0         0 each %{ $s->{'table'}->_fields() };
  0         0  
650             }
651              
652             sub EXISTS {
653 0     0   0 my $s = shift;
654 0         0 return $s->{'table'}->_fields()->{ $_[0] };
655             }
656              
657             sub DESTROY {
658 21     21   2238 my $s = shift;
659 21 50       231 warn "$s->{table}:$s->{value} has been destroyed" if $s->{'table'}->{DEBUG};
660             }
661              
662             =head1 NAME
663              
664             Tie::DBI - Tie hashes to DBI relational databases
665              
666             =head1 SYNOPSIS
667              
668             use Tie::DBI;
669             tie %h,'Tie::DBI','mysql:test','test','id',{CLOBBER=>1};
670              
671             tie %h,'Tie::DBI',{db => 'mysql:test',
672             table => 'test',
673             key => 'id',
674             user => 'nobody',
675             password => 'ghost',
676             CLOBBER => 1};
677              
678             # fetching keys and values
679             @keys = keys %h;
680             @fields = keys %{$h{$keys[0]}};
681             print $h{'id1'}->{'field1'};
682             while (($key,$value) = each %h) {
683             print "Key = $key:\n";
684             foreach (sort keys %$value) {
685             print "\t$_ => $value->{$_}\n";
686             }
687             }
688              
689             # changing data
690             $h{'id1'}->{'field1'} = 'new value';
691             $h{'id1'} = { field1 => 'newer value',
692             field2 => 'even newer value',
693             field3 => "so new it's squeaky clean" };
694              
695             # other functions
696             tied(%h)->commit;
697             tied(%h)->rollback;
698             tied(%h)->select_where('price > 1.20');
699             @fieldnames = tied(%h)->fields;
700             $dbh = tied(%h)->dbh;
701              
702             =head1 DESCRIPTION
703              
704             This module allows you to tie Perl associative arrays (hashes) to SQL
705             databases using the DBI interface. The tied hash is associated with a
706             table in a local or networked database. One column becomes the hash
707             key. Each row of the table becomes an associative array, from which
708             individual fields can be set or retrieved.
709              
710             =head1 USING THE MODULE
711              
712             To use this module, you must have the DBI interface and at least one
713             DBD (database driver) installed. Make sure that your database is up
714             and running, and that you can connect to it and execute queries using
715             DBI.
716              
717             =head2 Creating the tie
718              
719             tie %var,'Tie::DBI',[database,table,keycolumn] [,\%options]
720              
721             Tie a variable to a database by providing the variable name, the tie
722             interface (always "Tie::DBI"), the data source name, the table to tie
723             to, and the column to use as the hash key. You may also pass various
724             flags to the interface in an associative array.
725              
726             =over 4
727              
728             =item database
729              
730             The database may either be a valid DBI-style data source string of the
731             form "dbi:driver:database_name[:other information]", or a database
732             handle that has previously been opened. See the documentation for DBI
733             and your DBD driver for details. Because the initial "dbi" is always
734             present in the data source, Tie::DBI will add it for you if necessary.
735              
736             Note that some drivers (Oracle in particular) have an irritating habit
737             of appending blanks to the end of fixed-length fields. This will
738             screw up Tie::DBI's routines for getting key names. To avoid this you
739             should create the database handle with a B option of TRUE.
740             You should also use a B option of true to avoid complaints
741             during STORE and LISTFIELD calls.
742              
743              
744             =item table
745              
746             The table in the database to bind to. The table must previously have
747             been created with a SQL CREATE statement. This module will not create
748             tables for you or modify the schema of the database.
749              
750             =item key
751              
752             The column to use as the hash key. This column must prevoiusly have
753             been defined when the table was created. In order for this module to
754             work correctly, the key column I be declared unique and not
755             nullable. For best performance, the column should be also be declared
756             a key. These three requirements are automatically satisfied for
757             primary keys.
758              
759             =back
760              
761             It is possible to omit the database, table and keycolumn arguments, in
762             which case the module tries to retrieve the values from the options
763             array. The options array contains a set of option/value pairs. If
764             not provided, defaults are assumed. The options are:
765              
766             =over 4
767              
768             =item user
769              
770             Account name to use for database authentication, if necessary.
771             Default is an empty string (no authentication necessary).
772              
773             =item password
774              
775             Password to use for database authentication, if necessary. Default is
776             an empty string (no authentication necessary).
777              
778             =item db
779              
780             The database to bind to the hash, if not provided in the argument
781             list. It may be a DBI-style data source string, or a
782             previously-opened database handle.
783              
784             =item table
785              
786             The name of the table to bind to the hash, if not provided in the
787             argument list.
788              
789             =item key
790              
791             The name of the column to use as the hash key, if not provided in the
792             argument list.
793              
794             =item CLOBBER (default 0)
795              
796             This controls whether the database is writable via the bound hash. A
797             zero value (the default) makes the database essentially read only. An
798             attempt to store to the hash will result in a fatal error. A CLOBBER
799             value of 1 will allow you to change individual fields in the database,
800             and to insert new records, but not to delete entire records. A
801             CLOBBER value of 2 allows you to delete records, but not to erase the
802             entire table. A CLOBBER value of 3 or higher will allow you to erase
803             the entire table.
804              
805             Operation Clobber Comment
806              
807             $i = $h{strawberries}->{price} 0 All read operations
808             $h{strawberries}->{price} += 5 1 Update fields
809             $h{bananas}={price=>23,quant=>3} 1 Add records
810             delete $h{strawberries} 2 Delete records
811             %h = () 3 Clear entire table
812             undef %h 3 Another clear operation
813              
814             All database operations are contingent upon your access privileges.
815             If your account does not have write permission to the database, hash
816             store operations will fail despite the setting of CLOBBER.
817              
818             =item AUTOCOMMIT (default 1)
819              
820             If set to a true value, the "autocommit" option causes the database
821             driver to commit after every store statement. If set to a false
822             value, this option will not commit to the database until you
823             explicitly call the Tie::DBI commit() method.
824              
825             The autocommit option defaults to true.
826              
827             =item DEBUG (default 0)
828              
829             When the DEBUG option is set to a non-zero value the module will echo
830             the contents of SQL statements and other debugging information to
831             standard error. Higher values of DEBUG result in more verbose (and
832             annoying) output.
833              
834             =item WARN (default 1)
835              
836             If set to a non-zero value, warns of illegal operations, such as
837             attempting to delete the value of the key column. If set to a zero
838             value, these errors will be ignored silently.
839              
840             =item CASESENSITIV (default 0)
841              
842             If set to a non-zero value, all Fieldnames are casesensitiv. Keep
843             in mind, that your database has to support casesensitiv Fields if
844             you want to use it.
845              
846             =back
847              
848             =head1 USING THE TIED ARRAY
849              
850             The tied array represents the database table. Each entry in the hash
851             is a record, keyed on the column chosen in the tie() statement.
852             Ordinarily this will be the table's primary key, although any unique
853             column will do.
854              
855             Fetching an individual record returns a reference to a hash of field
856             names and values. This hash reference is itself a tied object, so
857             that operations on it directly affect the database.
858              
859             =head2 Fetching information
860              
861             In the following examples, we will assume a database table structured
862             like this one:
863              
864             -produce-
865             produce_id price quantity description
866              
867             strawberries 1.20 8 Fresh Maine strawberries
868             apricots 0.85 2 Ripe Norwegian apricots
869             bananas 1.30 28 Sweet Alaskan bananas
870             kiwis 1.50 9 Juicy New York kiwi fruits
871             eggs 1.00 12 Farm-fresh Atlantic eggs
872              
873             We tie the variable %produce to the table in this way:
874              
875             tie %produce,'Tie::DBI',{db => 'mysql:stock',
876             table => 'produce',
877             key => 'produce_id',
878             CLOBBER => 2 # allow most updates
879             };
880              
881             We can get the list of keys this way:
882              
883             print join(",",keys %produce);
884             => strawberries,apricots,bananas,kiwis
885              
886             Or get the price of eggs thusly:
887              
888             $price = $produce{eggs}->{price};
889             print "The price of eggs = $price";
890             => The price of eggs = 1.2
891              
892             String interpolation works as you would expect:
893              
894             print "The price of eggs is still $produce{eggs}->{price}"
895             => The price of eggs is still 1.2
896              
897             Various types of syntactic sugar are allowed. For example, you can
898             refer to $produce{eggs}{price} rather than $produce{eggs}->{price}.
899             Array slices are fully supported as well:
900              
901             ($apricots,$kiwis) = @produce{apricots,kiwis};
902             print "Kiwis are $kiwis->{description};
903             => Kiwis are Juicy New York kiwi fruits
904              
905             ($price,$description) = @{$produce{eggs}}{price,description};
906             => (2.4,'Farm-fresh Atlantic eggs')
907              
908             If you provide the tied hash with a comma-delimited set of record
909             names, and you are B requesting an array slice, then the module
910             does something interesting. It generates a single SQL statement that
911             fetches the records from the database in a single pass (rather than
912             the multiple passes required for an array slice) and returns the
913             result as a reference to an array. For many records, this can be much
914             faster. For example:
915              
916             $result = $produce{apricots,bananas};
917             => ARRAY(0x828a8ac)
918              
919             ($apricots,$bananas) = @$result;
920             print "The price of apricots is $apricots->{price}";
921             => The price of apricots is 0.85
922              
923             Field names work in much the same way:
924              
925             ($price,$quantity) = @{$produce{apricots}{price,quantity}};
926             print "There are $quantity apricots at $price each";
927             => There are 2 apricots at 0.85 each";
928              
929             Note that this takes advantage of a bit of Perl syntactic sugar which
930             automagically treats $h{'a','b','c'} as if the keys were packed
931             together with the $; pack character. Be careful not to fall into this
932             trap:
933              
934              
935             $result = $h{join( ',', 'apricots', 'bananas' )};
936             => undefined
937              
938             What you really want is this:
939              
940             $result = $h{join( $;, 'apricots', 'bananas' )};
941             => ARRAY(0x828a8ac)
942              
943             =head2 Updating information
944              
945             If CLOBBER is set to a non-zero value (and the underlying database
946             privileges allow it), you can update the database with new values.
947             You can operate on entire records at once or on individual fields
948             within a record.
949              
950             To insert a new record or update an existing one, assign a hash
951             reference to the record. For example, you can create a new record in
952             %produce with the key "avocados" in this manner:
953              
954             $produce{avocados} = { price => 2.00,
955             quantity => 8,
956             description => 'Choice Irish avocados' };
957              
958             This will work with any type of hash reference, including records
959             extracted from another table or database.
960              
961             Only keys that correspond to valid fields in the table will be
962             accepted. You will be warned if you attempt to set a field that
963             doesn't exist, but the other fields will be correctly set. Likewise,
964             you will be warned if you attempt to set the key field. These
965             warnings can be turned off by setting the WARN option to a zero value.
966             It is not currently possible to add new columns to the table. You
967             must do this manually with the appropriate SQL commands.
968              
969             The same syntax can be used to update an existing record. The fields
970             given in the hash reference replace those in the record. Fields that
971             aren't explicitly listed in the hash retain their previous values. In
972             the following example, the price and quantity of the "kiwis" record
973             are updated, but the description remains the same:
974              
975             $produce{kiwis} = { price=>1.25,quantity=>20 };
976              
977             You may update existing records on a field-by-field manner in the
978             natural way:
979              
980             $produce{eggs}{price} = 1.30;
981             $produce{eggs}{price} *= 2;
982             print "The price of eggs is now $produce{eggs}{price}";
983             => The price of eggs is now 2.6.
984              
985             Obligingly enough, you can use this syntax to insert new records too,
986             as in $produce{mangoes}{description}="Sun-ripened Idaho mangoes".
987             However, this type of update is inefficient because a separate SQL
988             statement is generated for each field. If you need to update more
989             than one field at a time, use the record-oriented syntax shown
990             earlier. It's much more efficient because it gets the work done with
991             a single SQL command.
992              
993             Insertions and updates may fail for any of a number of reasons, most
994             commonly:
995              
996             =over 4
997              
998             =item 1. You do not have sufficient privileges to update the database
999              
1000             =item 2. The update would violate an integrity constraint, such as
1001             making a non-nullable field null, overflowing a numeric field, storing
1002             a string value in a numeric field, or violating a uniqueness
1003             constraint.
1004              
1005             =back
1006              
1007             The module dies with an error message when it encounters an error
1008             during an update. To trap these erorrs and continue processing, wrap
1009             the update an eval().
1010              
1011             =head2 Other functions
1012              
1013             The tie object supports several useful methods. In order to call
1014             these methods, you must either save the function result from the tie()
1015             call (which returns the object), or call tied() on the tie variable to
1016             recover the object.
1017              
1018             =over 4
1019              
1020             =item connect(), error(), errstr()
1021              
1022             These are low-level class methods. Connect() is responsible for
1023             establishing the connection with the DBI database. Errstr() and
1024             error() return $DBI::errstr and $DBI::error respectively. You may
1025             may override these methods in subclasses if you wish. For example,
1026             replace connect() with this code in order to use persistent database
1027             connections in Apache modules:
1028            
1029             use Apache::DBI; # somewhere in the declarations
1030             sub connect {
1031             my ($class,$dsn,$user,$password,$options) = @_;
1032             return Apache::DBI->connect($dsn,$user,
1033             $password,$options);
1034             }
1035            
1036             =item commit()
1037              
1038             (tied %produce)->commit();
1039              
1040             When using a database with the autocommit option turned off, values
1041             that are stored into the hash will not become permanent until commit()
1042             is called. Otherwise they are lost when the application terminates or
1043             the hash is untied.
1044              
1045             Some SQL databases don't support transactions, in which case you will
1046             see a warning message if you attempt to use this function.
1047              
1048             =item rollback()
1049              
1050             (tied %produce)->rollback();
1051              
1052             When using a database with the autocommit option turned off, this
1053             function will roll back changes to the database to the state they were
1054             in at the last commit(). This function has no effect on database that
1055             don't support transactions.
1056              
1057             =item select_where()
1058            
1059             @keys=(tied %produce)->select_where('price > 1.00 and quantity < 10');
1060              
1061             This executes a limited form of select statement on the tied table and
1062             returns a list of records that satisfy the conditions. The argument
1063             you provide should be the contents of a SQL WHERE clause, minus the
1064             keyword "WHERE" and everything that ordinarily precedes it. Anything
1065             that is legal in the WHERE clause is allowed, including function
1066             calls, ordering specifications, and sub-selects. The keys to those
1067             records that meet the specified conditions are returned as an array,
1068             in the order in which the select statement returned them.
1069            
1070             Don't expect too much from this function. If you want to execute a
1071             complex query, you're better off using the database handle (see below)
1072             to make the SQL query yourself with the DBI interface.
1073              
1074             =item dbh()
1075              
1076             $dbh = (tied %produce)->dbh();
1077            
1078             This returns the tied hash's underlying database handle. You can use
1079             this handle to create and execute your own SQL queries.
1080              
1081             =item CLOBBER, DEBUG, WARN
1082            
1083             You can get and set the values of CLOBBER, DEBUG and WARN by directly
1084             accessing the object's hash:
1085              
1086             (tied %produce)->{DEBUG}++;
1087              
1088             This lets you change the behavior of the tied hash on the fly, such as
1089             temporarily granting your program write permission.
1090              
1091             There are other variables there too, such as the name of the key
1092             column and database table. Change them at your own risk!
1093              
1094             =back
1095              
1096             =head1 PERFORMANCE
1097              
1098             What is the performance hit when you use this module rather than the
1099             direct DBI interface? It can be significant. To measure the
1100             overhead, I used a simple benchmark in which Perl parsed a 6180 word
1101             text file into individual words and stored them into a database,
1102             incrementing the word count with each store. The benchmark then read
1103             out the words and their counts in an each() loop. The database driver
1104             was mySQL, running on a 133 MHz Pentium laptop with Linux 2.0.30. I
1105             compared Tie::RDBM, to DB_File, and to the same task using vanilla DBI
1106             SQL statements. The results are shown below:
1107              
1108             UPDATE FETCH
1109             Tie::DBI 70 s 6.1 s
1110             Vanilla DBI 14 s 2.0 s
1111             DB_File 3 s 1.06 s
1112              
1113             There is about a five-fold penalty for updates, and a three-fold
1114             penalty for fetches when using this interface. Some of the penalty is
1115             due to the overhead for creating sub-objects to handle individual
1116             fields, and some of it is due to the inefficient way the store and
1117             fetch operations are implemented. For example, using the tie
1118             interface, a statement like $h{record}{field}++ requires as much as
1119             four trips to the database: one to verify that the record exists, one
1120             to fetch the field, and one to store the incremented field back. If
1121             the record doesn't already exist, an additional statement is required
1122             to perform the insertion. I have experimented with cacheing schemes
1123             to reduce the number of trips to the database, but the overhead of
1124             maintaining the cache is nearly equal to the performance improvement,
1125             and cacheing raises a number of potential concurrency problems.
1126              
1127             Clearly you would not want to use this interface for applications that
1128             require a large number of updates to be processed rapidly.
1129              
1130             =head1 BUGS
1131              
1132             =head1 BUGS
1133              
1134             The each() call produces a fatal error when used with the Sybase
1135             driver to access Microsoft SQL server. This is because this server
1136             only allows one query to be active at a given time. A workaround is
1137             to use keys() to fetch all the keys yourself. It is not known whether
1138             real Sybase databases suffer from the same problem.
1139              
1140             The delete() operator will not work correctly for setting field values
1141             to null with DBD::CSV or with DBD::Pg. CSV files do not have a good
1142             conception of database nulls. Instead you will set the field to an
1143             empty string. DBD::Pg just seems to be broken in this regard.
1144              
1145             =head1 AUTHOR
1146              
1147             Lincoln Stein, lstein@cshl.org
1148              
1149             =head1 COPYRIGHT
1150              
1151             Copyright (c) 1998, Lincoln D. Stein
1152              
1153             This library is free software; you can redistribute it and/or
1154             modify it under the same terms as Perl itself.
1155              
1156             =head1 AVAILABILITY
1157              
1158             The latest version can be obtained from:
1159            
1160             http://www.genome.wi.mit.edu/~lstein/Tie-DBI/
1161            
1162             =head1 SEE ALSO
1163              
1164             perl(1), DBI(3), Tie::RDBM(3)
1165              
1166             =cut
1167              
1168             1;