File Coverage

blib/lib/DBD/DBM.pm
Criterion Covered Total %
statement 192 244 78.6
branch 74 148 50.0
condition 24 60 40.0
subroutine 25 30 83.3
pod 0 1 0.0
total 315 483 65.2


line stmt bran cond sub pod time code
1             #######################################################################
2             #
3             # DBD::DBM - a DBI driver for DBM files
4             #
5             # Copyright (c) 2004 by Jeff Zucker < jzucker AT cpan.org >
6             # Copyright (c) 2010-2013 by Jens Rehsack & H.Merijn Brand
7             #
8             # All rights reserved.
9             #
10             # You may freely distribute and/or modify this module under the terms
11             # of either the GNU General Public License (GPL) or the Artistic License,
12             # as specified in the Perl README file.
13             #
14             # USERS - see the pod at the bottom of this file
15             #
16             # DBD AUTHORS - see the comments in the code
17             #
18             #######################################################################
19             require 5.008;
20 36     36   54365 use strict;
  36         71  
  36         1329  
21              
22             #################
23             package DBD::DBM;
24             #################
25 36     36   193 use base qw( DBD::File );
  36         67  
  36         13577  
26 36     36   210 use vars qw($VERSION $ATTRIBUTION $drh $methods_already_installed);
  36         64  
  36         6818  
27             $VERSION = '0.08';
28             $ATTRIBUTION = 'DBD::DBM by Jens Rehsack';
29              
30             # no need to have driver() unless you need private methods
31             #
32             sub driver ($;$)
33             {
34 26     26 0 70 my ( $class, $attr ) = @_;
35 26 50       109 return $drh if ($drh);
36              
37             # do the real work in DBD::File
38             #
39 26         72 $attr->{Attribution} = 'DBD::DBM by Jens Rehsack';
40 26         192 $drh = $class->SUPER::driver($attr);
41              
42             # install private methods
43             #
44             # this requires that dbm_ (or foo_) be a registered prefix
45             # but you can write private methods before official registration
46             # by hacking the $dbd_prefix_registry in a private copy of DBI.pm
47             #
48 26 50       99 unless ( $methods_already_installed++ )
49             {
50 26         115 DBD::DBM::st->install_method('dbm_schema');
51             }
52              
53 26         109 return $drh;
54             }
55              
56             sub CLONE
57             {
58 0     0   0 undef $drh;
59             }
60              
61             #####################
62             package DBD::DBM::dr;
63             #####################
64             $DBD::DBM::dr::imp_data_size = 0;
65             @DBD::DBM::dr::ISA = qw(DBD::File::dr);
66              
67             # you could put some :dr private methods here
68              
69             # you may need to over-ride some DBD::File::dr methods here
70             # but you can probably get away with just letting it do the work
71             # in most cases
72              
73             #####################
74             package DBD::DBM::db;
75             #####################
76             $DBD::DBM::db::imp_data_size = 0;
77             @DBD::DBM::db::ISA = qw(DBD::File::db);
78              
79 36     36   225 use Carp qw/carp/;
  36         76  
  36         24629  
80              
81             sub validate_STORE_attr
82             {
83 2968     2968   21634 my ( $dbh, $attrib, $value ) = @_;
84              
85 2968 50 33     9522 if ( $attrib eq "dbm_ext" or $attrib eq "dbm_lockfile" )
86             {
87 0         0 ( my $newattrib = $attrib ) =~ s/^dbm_/f_/g;
88 0 0       0 carp "Attribute '$attrib' is depreciated, use '$newattrib' instead" if ($^W);
89 0         0 $attrib = $newattrib;
90             }
91              
92 2968         6885 return $dbh->SUPER::validate_STORE_attr( $attrib, $value );
93             }
94              
95             sub validate_FETCH_attr
96             {
97 0     0   0 my ( $dbh, $attrib ) = @_;
98              
99 0 0 0     0 if ( $attrib eq "dbm_ext" or $attrib eq "dbm_lockfile" )
100             {
101 0         0 ( my $newattrib = $attrib ) =~ s/^dbm_/f_/g;
102 0 0       0 carp "Attribute '$attrib' is depreciated, use '$newattrib' instead" if ($^W);
103 0         0 $attrib = $newattrib;
104             }
105              
106 0         0 return $dbh->SUPER::validate_FETCH_attr($attrib);
107             }
108              
109             sub set_versions
110             {
111 386     386   2984 my $this = $_[0];
112 386         1119 $this->{dbm_version} = $DBD::DBM::VERSION;
113 386         1050 return $this->SUPER::set_versions();
114             }
115              
116             sub init_valid_attributes
117             {
118 386     386   2800 my $dbh = shift;
119              
120             # define valid private attributes
121             #
122             # attempts to set non-valid attrs in connect() or
123             # with $dbh->{attr} will throw errors
124             #
125             # the attrs here *must* start with dbm_ or foo_
126             #
127             # see the STORE methods below for how to check these attrs
128             #
129             $dbh->{dbm_valid_attrs} = {
130 386         2698 dbm_type => 1, # the global DBM type e.g. SDBM_File
131             dbm_mldbm => 1, # the global MLDBM serializer
132             dbm_cols => 1, # the global column names
133             dbm_version => 1, # verbose DBD::DBM version
134             dbm_store_metadata => 1, # column names, etc.
135             dbm_berkeley_flags => 1, # for BerkeleyDB
136             dbm_valid_attrs => 1, # DBD::DBM::db valid attrs
137             dbm_readonly_attrs => 1, # DBD::DBM::db r/o attrs
138             dbm_meta => 1, # DBD::DBM public access for f_meta
139             dbm_tables => 1, # DBD::DBM public access for f_meta
140             };
141             $dbh->{dbm_readonly_attrs} = {
142 386         1202 dbm_version => 1, # verbose DBD::DBM version
143             dbm_valid_attrs => 1, # DBD::DBM::db valid attrs
144             dbm_readonly_attrs => 1, # DBD::DBM::db r/o attrs
145             dbm_meta => 1, # DBD::DBM public access for f_meta
146             };
147              
148 386         741 $dbh->{dbm_meta} = "dbm_tables";
149              
150 386         1129 return $dbh->SUPER::init_valid_attributes();
151             }
152              
153             sub init_default_attributes
154             {
155 772     772   6715 my ( $dbh, $phase ) = @_;
156              
157 772         2419 $dbh->SUPER::init_default_attributes($phase);
158 772         1267 $dbh->{f_lockfile} = '.lck';
159              
160 772         1665 return $dbh;
161             }
162              
163             sub get_dbm_versions
164             {
165 8     8   22 my ( $dbh, $table ) = @_;
166 8   50     46 $table ||= '';
167              
168 8         13 my $meta;
169 8         19 my $class = $dbh->{ImplementorClass};
170 8         32 $class =~ s/::db$/::Table/;
171 8 50       23 $table and ( undef, $meta ) = $class->get_table_meta( $dbh, $table, 1 );
172 8 50 33     73 $meta or ( $meta = {} and $class->bootstrap_table_meta( $dbh, $meta, $table ) );
173              
174 8         18 my $dver;
175 8         16 my $dtype = $meta->{dbm_type};
176 8         24 eval {
177 8         128 $dver = $meta->{dbm_type}->VERSION();
178              
179             # *) when we're still alive here, everything went ok - no need to check for $@
180 8         36 $dtype .= " ($dver)";
181             };
182 8 50       23 if ( $meta->{dbm_mldbm} )
183             {
184 0         0 $dtype .= ' + MLDBM';
185 0         0 eval {
186 0         0 $dver = MLDBM->VERSION();
187 0         0 $dtype .= " ($dver)"; # (*)
188             };
189 0         0 eval {
190 0         0 my $ser_class = "MLDBM::Serializer::" . $meta->{dbm_mldbm};
191 0         0 my $ser_mod = $ser_class;
192 0         0 $ser_mod =~ s|::|/|g;
193 0         0 $ser_mod .= ".pm";
194 0         0 require $ser_mod;
195 0         0 $dver = $ser_class->VERSION();
196 0         0 $dtype .= ' + ' . $ser_class; # (*)
197 0 0       0 $dver and $dtype .= " ($dver)"; # (*)
198             };
199             }
200 8         60 return sprintf( "%s using %s", $dbh->{dbm_version}, $dtype );
201             }
202              
203             # you may need to over-ride some DBD::File::db methods here
204             # but you can probably get away with just letting it do the work
205             # in most cases
206              
207             #####################
208             package DBD::DBM::st;
209             #####################
210             $DBD::DBM::st::imp_data_size = 0;
211             @DBD::DBM::st::ISA = qw(DBD::File::st);
212              
213             sub FETCH
214             {
215 1796     1796   13303 my ( $sth, $attr ) = @_;
216              
217 1796 100       3182 if ( $attr eq "NULLABLE" )
218             {
219 264         675 my @colnames = $sth->sql_get_colnames();
220              
221             # XXX only BerkeleyDB fails having NULL values for non-MLDBM databases,
222             # none accept it for key - but it requires more knowledge between
223             # queries and tables storage to return fully correct information
224 264 50       1894 $attr eq "NULLABLE" and return [ map { 0 } @colnames ];
  368         910  
225             }
226              
227 1532         3250 return $sth->SUPER::FETCH($attr);
228             } # FETCH
229              
230             sub dbm_schema
231             {
232 0     0   0 my ( $sth, $tname ) = @_;
233 0 0       0 return $sth->set_err( $DBI::stderr, 'No table name supplied!' ) unless $tname;
234             my $tbl_meta = $sth->{Database}->func( $tname, "f_schema", "get_sql_engine_meta" )
235 0 0       0 or return $sth->set_err( $sth->{Database}->err(), $sth->{Database}->errstr() );
236 0         0 return $tbl_meta->{$tname}->{f_schema};
237             }
238             # you could put some :st private methods here
239              
240             # you may need to over-ride some DBD::File::st methods here
241             # but you can probably get away with just letting it do the work
242             # in most cases
243              
244             ############################
245             package DBD::DBM::Statement;
246             ############################
247              
248             @DBD::DBM::Statement::ISA = qw(DBD::File::Statement);
249              
250             ########################
251             package DBD::DBM::Table;
252             ########################
253 36     36   242 use Carp;
  36         60  
  36         1668  
254 36     36   190 use Fcntl;
  36         73  
  36         66580  
255              
256             @DBD::DBM::Table::ISA = qw(DBD::File::Table);
257              
258             my $dirfext = $^O eq 'VMS' ? '.sdbm_dir' : '.dir';
259              
260             my %reset_on_modify = (
261             dbm_type => "dbm_tietype",
262             dbm_mldbm => "dbm_tietype",
263             );
264             __PACKAGE__->register_reset_on_modify( \%reset_on_modify );
265              
266             my %compat_map = (
267             ( map { $_ => "dbm_$_" } qw(type mldbm store_metadata) ),
268             dbm_ext => 'f_ext',
269             dbm_file => 'f_file',
270             dbm_lockfile => ' f_lockfile',
271             );
272             __PACKAGE__->register_compat_map( \%compat_map );
273              
274             sub bootstrap_table_meta
275             {
276 352     352   813 my ( $self, $dbh, $meta, $table ) = @_;
277              
278 352   100     2107 $meta->{dbm_type} ||= $dbh->{dbm_type} || 'SDBM_File';
      66        
279 352 50 0     730 $meta->{dbm_mldbm} ||= $dbh->{dbm_mldbm} if ( $dbh->{dbm_mldbm} );
280 352   33     1366 $meta->{dbm_berkeley_flags} ||= $dbh->{dbm_berkeley_flags};
281              
282             defined $meta->{f_ext}
283 352 100       1187 or $meta->{f_ext} = $dbh->{f_ext};
284 352 100       943 unless ( defined( $meta->{f_ext} ) )
285             {
286 346         463 my $ext;
287 346 50 33     1067 if ( $meta->{dbm_type} eq 'SDBM_File' or $meta->{dbm_type} eq 'ODBM_File' )
    0          
288             {
289 346         532 $ext = '.pag/r';
290             }
291             elsif ( $meta->{dbm_type} eq 'NDBM_File' )
292             {
293             # XXX NDBM_File on FreeBSD (and elsewhere?) may actually be Berkeley
294             # behind the scenes and so create a single .db file.
295 0 0 0     0 if ( $^O =~ /bsd/i or lc($^O) eq 'darwin' )
    0 0        
      0        
296             {
297 0         0 $ext = '.db/r';
298             }
299             elsif ( $^O eq 'SunOS' or $^O eq 'Solaris' or $^O eq 'AIX' )
300             {
301 0         0 $ext = '.pag/r'; # here it's implemented like dbm - just a bit improved
302             }
303             # else wrapped GDBM
304             }
305 346 50       909 defined($ext) and $meta->{f_ext} = $ext;
306             }
307              
308 352         1280 $self->SUPER::bootstrap_table_meta( $dbh, $meta, $table );
309             }
310              
311             sub init_table_meta
312             {
313 238     238   652 my ( $self, $dbh, $meta, $table ) = @_;
314              
315 238         531 $meta->{f_dontopen} = 1;
316              
317 238 100       663 unless ( defined( $meta->{dbm_tietype} ) )
318             {
319 208         389 my $tie_type = $meta->{dbm_type};
320 208 100       3892 $INC{"$tie_type.pm"} or require "$tie_type.pm";
321 208 50       5076 $tie_type eq 'BerkeleyDB' and $tie_type = 'BerkeleyDB::Hash';
322              
323 208 50       506 if ( $meta->{dbm_mldbm} )
324             {
325 0 0       0 $INC{"MLDBM.pm"} or require "MLDBM.pm";
326 0         0 $meta->{dbm_usedb} = $tie_type;
327 0         0 $tie_type = 'MLDBM';
328             }
329              
330 208         446 $meta->{dbm_tietype} = $tie_type;
331             }
332              
333 238 100       606 unless ( defined( $meta->{dbm_store_metadata} ) )
334             {
335 208         375 my $store = $dbh->{dbm_store_metadata};
336 208 50       488 defined($store) or $store = 1;
337 208         371 $meta->{dbm_store_metadata} = $store;
338             }
339              
340 238 100       547 unless ( defined( $meta->{col_names} ) )
341             {
342 220 50       507 defined( $dbh->{dbm_cols} ) and $meta->{col_names} = $dbh->{dbm_cols};
343             }
344              
345 238         1000 $self->SUPER::init_table_meta( $dbh, $meta, $table );
346             }
347              
348             sub open_data
349             {
350 408     408   968 my ( $className, $meta, $attrs, $flags ) = @_;
351 408         1478 $className->SUPER::open_data( $meta, $attrs, $flags );
352              
353 368 100       995 unless ( $flags->{dropMode} )
354             {
355             # TIEING
356             #
357             # XXX allow users to pass in a pre-created tied object
358             #
359 320         513 my @tie_args;
360 320 50       941 if ( $meta->{dbm_type} eq 'BerkeleyDB' )
361             {
362 0         0 my $DB_CREATE = BerkeleyDB::DB_CREATE();
363 0         0 my $DB_RDONLY = BerkeleyDB::DB_RDONLY();
364 0         0 my %tie_flags;
365 0 0       0 if ( my $f = $meta->{dbm_berkeley_flags} )
366             {
367 0 0       0 defined( $f->{DB_CREATE} ) and $DB_CREATE = delete $f->{DB_CREATE};
368 0 0       0 defined( $f->{DB_RDONLY} ) and $DB_RDONLY = delete $f->{DB_RDONLY};
369 0         0 %tie_flags = %$f;
370             }
371 0 0 0     0 my $open_mode = $flags->{lockMode} || $flags->{createMode} ? $DB_CREATE : $DB_RDONLY;
372             @tie_args = (
373             -Filename => $meta->{f_fqbn},
374 0         0 -Flags => $open_mode,
375             %tie_flags
376             );
377             }
378             else
379             {
380 320         545 my $open_mode = O_RDONLY;
381 320 100       734 $flags->{lockMode} and $open_mode = O_RDWR;
382 320 100       738 $flags->{createMode} and $open_mode = O_RDWR | O_CREAT | O_TRUNC;
383              
384 320         937 @tie_args = ( $meta->{f_fqbn}, $open_mode, 0666 );
385             }
386              
387 320 50       755 if ( $meta->{dbm_mldbm} )
388             {
389 0         0 $MLDBM::UseDB = $meta->{dbm_usedb};
390 0         0 $MLDBM::Serializer = $meta->{dbm_mldbm};
391             }
392              
393 320         809 $meta->{hash} = {};
394 320         668 my $tie_class = $meta->{dbm_tietype};
395 320         610 eval { tie %{ $meta->{hash} }, $tie_class, @tie_args };
  320         472  
  320         10408  
396 320 50       1063 $@ and croak "Cannot tie(\%h $tie_class @tie_args): $@";
397 320 50       2848 -f $meta->{f_fqfn} or croak( "No such file: '" . $meta->{f_fqfn} . "'" );
398             }
399              
400 368 100       1124 unless ( $flags->{createMode} )
401             {
402 314         671 my ( $meta_data, $schema, $col_names );
403 314 50       850 if ( $meta->{dbm_store_metadata} )
404             {
405 314         3566 $meta_data = $col_names = $meta->{hash}->{"_metadata \0"};
406 314 100 66     2517 if ( $meta_data and $meta_data =~ m~(.+)~is )
407             {
408 266         917 $schema = $col_names = $1;
409 266         1427 $schema =~ s~.*(.+).*~$1~is;
410 266         1092 $col_names =~ s~.*(.+).*~$1~is;
411             }
412             }
413 314   100     1075 $col_names ||= $meta->{col_names} || [ 'k', 'v' ];
      66        
414 314 100       1526 $col_names = [ split /,/, $col_names ] if ( ref $col_names ne 'ARRAY' );
415 314 100 66     2316 if ( $meta->{dbm_store_metadata} and not $meta->{hash}->{"_metadata \0"} )
416             {
417 48 50       166 $schema or $schema = '';
418             $meta->{hash}->{"_metadata \0"} =
419             ""
420             . "$schema"
421             . ""
422 48         200 . join( ",", @{$col_names} )
  48         237  
423             . ""
424             . "";
425             }
426              
427 314         861 $meta->{schema} = $schema;
428 314         952 $meta->{col_names} = $col_names;
429             }
430             }
431              
432             # you must define drop
433             # it is called from execute of a SQL DROP statement
434             #
435             sub drop ($$)
436             {
437 48     48   482 my ( $self, $data ) = @_;
438 48         424 my $meta = $self->{meta};
439 48 50       261 $meta->{hash} and untie %{ $meta->{hash} };
  48         135  
440 48         333 $self->SUPER::drop($data);
441             # XXX extra_files
442             -f $meta->{f_fqbn} . $dirfext
443             and $meta->{f_ext} eq '.pag/r'
444 48 50 33     1534 and unlink( $meta->{f_fqbn} . $dirfext );
445 48         201 return 1;
446             }
447              
448             # you must define fetch_row, it is called on all fetches;
449             # it MUST return undef when no rows are left to fetch;
450             # checking for $ary[0] is specific to hashes so you'll
451             # probably need some other kind of check for nothing-left.
452             # as Janis might say: "undef's just another word for
453             # nothing left to fetch" :-)
454             #
455             sub fetch_row ($$)
456             {
457 450     450   852 my ( $self, $data ) = @_;
458 450         668 my $meta = $self->{meta};
459             # fetch with %each
460             #
461 450         575 my @ary = each %{ $meta->{hash} };
  450         3737  
462             $meta->{dbm_store_metadata}
463             and $ary[0]
464             and $ary[0] eq "_metadata \0"
465 450 100 66     2463 and @ary = each %{ $meta->{hash} };
  138   100     941  
466              
467 450         937 my ( $key, $val ) = @ary;
468 450 100       908 unless ($key)
469             {
470 122         223 delete $self->{row};
471 122         442 return;
472             }
473 328 50       969 my @row = ( ref($val) eq 'ARRAY' ) ? ( $key, @$val ) : ( $key, $val );
474 328 50       779 $self->{row} = @row ? \@row : undef;
475 328 50       1536 return wantarray ? @row : \@row;
476             }
477              
478             # you must define push_row except insert_new_row and update_specific_row is defined
479             # it is called on inserts and updates as primitive
480             #
481             sub insert_new_row ($$$)
482             {
483 128     128   278 my ( $self, $data, $row_aryref ) = @_;
484 128         244 my $meta = $self->{meta};
485 128         189 my $ncols = scalar( @{ $meta->{col_names} } );
  128         259  
486 128         194 my $nitems = scalar( @{$row_aryref} );
  128         207  
487 128 50       319 $ncols == $nitems
488             or croak "You tried to insert $nitems, but table is created with $ncols columns";
489              
490 128         261 my $key = shift @$row_aryref;
491 128         182 my $exists;
492 128         180 eval { $exists = exists( $meta->{hash}->{$key} ); };
  128         858  
493 128 50       385 $exists and croak "Row with PK '$key' already exists";
494              
495 128 50       2596 $meta->{hash}->{$key} = $meta->{dbm_mldbm} ? $row_aryref : $row_aryref->[0];
496              
497 128         438 return 1;
498             }
499              
500             # this is where you grab the column names from a CREATE statement
501             # if you don't need to do that, it must be defined but can be empty
502             #
503             sub push_names ($$$)
504             {
505 54     54   163 my ( $self, $data, $row_aryref ) = @_;
506 54         112 my $meta = $self->{meta};
507              
508             # some sanity checks ...
509 54         104 my $ncols = scalar(@$row_aryref);
510 54 50       157 $ncols < 2 and croak "At least 2 columns are required for DBD::DBM tables ...";
511             !$meta->{dbm_mldbm}
512 54 50 33     281 and $ncols > 2
513             and croak "Without serializing with MLDBM only 2 columns are supported, you give $ncols";
514 54         118 $meta->{col_names} = $row_aryref;
515 54 50       144 return unless $meta->{dbm_store_metadata};
516              
517 54         105 my $stmt = $data->{sql_stmt};
518 54         86 my $col_names = join( ',', @{$row_aryref} );
  54         167  
519 54         127 my $schema = $data->{Database}->{Statement};
520 54         459 $schema =~ s/^[^\(]+\((.+)\)$/$1/s;
521 54 50       494 $schema = $stmt->schema_str() if ( $stmt->can('schema_str') );
522 54         3249 $meta->{hash}->{"_metadata \0"} =
523             ""
524             . "$schema"
525             . "$col_names"
526             . "";
527             }
528              
529             # fetch_one_row, delete_one_row, update_one_row
530             # are optimized for hash-style lookup without looping;
531             # if you don't need them, omit them, they're optional
532             # but, in that case you may need to define
533             # truncate() and seek(), see below
534             #
535             sub fetch_one_row ($$;$)
536             {
537 136     136   254 my ( $self, $key_only, $key ) = @_;
538 136         213 my $meta = $self->{meta};
539 136 100       422 $key_only and return $meta->{col_names}->[0];
540 16 50       109 exists $meta->{hash}->{$key} or return;
541 16         82 my $val = $meta->{hash}->{$key};
542 16 50       86 $val = ( ref($val) eq 'ARRAY' ) ? $val : [$val];
543 16         52 my $row = [ $key, @$val ];
544 16 50       72 return wantarray ? @{$row} : $row;
  0         0  
545             }
546              
547             sub delete_one_row ($$$)
548             {
549 56     56   146 my ( $self, $data, $aryref ) = @_;
550 56         104 my $meta = $self->{meta};
551 56         813 delete $meta->{hash}->{ $aryref->[0] };
552             }
553              
554             sub update_one_row ($$$)
555             {
556 0     0   0 my ( $self, $data, $aryref ) = @_;
557 0         0 my $meta = $self->{meta};
558 0         0 my $key = shift @$aryref;
559 0 0       0 defined $key or return;
560 0 0       0 my $row = ( ref($aryref) eq 'ARRAY' ) ? $aryref : [$aryref];
561 0 0       0 $meta->{hash}->{$key} = $meta->{dbm_mldbm} ? $row : $row->[0];
562             }
563              
564             sub update_specific_row ($$$$)
565             {
566 56     56   129 my ( $self, $data, $aryref, $origary ) = @_;
567 56         99 my $meta = $self->{meta};
568 56         96 my $key = shift @$origary;
569 56         98 my $newkey = shift @$aryref;
570 56 50       130 return unless ( defined $key );
571 56 50       146 $key eq $newkey or delete $meta->{hash}->{$key};
572 56 50       137 my $row = ( ref($aryref) eq 'ARRAY' ) ? $aryref : [$aryref];
573 56 50       1100 $meta->{hash}->{$newkey} = $meta->{dbm_mldbm} ? $row : $row->[0];
574             }
575              
576             # you may not need to explicitly DESTROY the ::Table
577             # put cleanup code to run when the execute is done
578             #
579             sub DESTROY ($)
580             {
581 368     368   753 my $self = shift;
582 368         665 my $meta = $self->{meta};
583 368 50       943 $meta->{hash} and untie %{ $meta->{hash} };
  368         3500  
584              
585 368         1611 $self->SUPER::DESTROY();
586             }
587              
588             # truncate() and seek() must be defined to satisfy DBI::SQL::Nano
589             # *IF* you define the *_one_row methods above, truncate() and
590             # seek() can be empty or you can use them without actually
591             # truncating or seeking anything but if you don't define the
592             # *_one_row methods, you may need to define these
593              
594             # if you need to do something after a series of
595             # deletes or updates, you can put it in truncate()
596             # which is called at the end of executing
597             #
598             sub truncate ($$)
599             {
600             # my ( $self, $data ) = @_;
601 0     0   0 return 1;
602             }
603              
604             # seek() is only needed if you use IO::File
605             # though it could be used for other non-file operations
606             # that you need to do before "writes" or truncate()
607             #
608             sub seek ($$$$)
609             {
610             # my ( $self, $data, $pos, $whence ) = @_;
611 128     128   241 return 1;
612             }
613              
614             # Th, th, th, that's all folks! See DBD::File and DBD::CSV for other
615             # examples of creating pure perl DBDs. I hope this helped.
616             # Now it's time to go forth and create your own DBD!
617             # Remember to check in with dbi-dev@perl.org before you get too far.
618             # We may be able to make suggestions or point you to other related
619             # projects.
620              
621             1;
622             __END__