File Coverage

blib/lib/Tie/DBI.pm
Criterion Covered Total %
statement 261 340 76.7
branch 81 166 48.8
condition 16 51 31.3
subroutine 34 46 73.9
pod 7 8 87.5
total 399 611 65.3


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