File Coverage

blib/lib/DBD/DBM.pm
Criterion Covered Total %
statement 192 244 78.6
branch 74 148 50.0
condition 23 60 38.3
subroutine 25 30 83.3
pod 0 1 0.0
total 314 483 65.0


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 32     32   65661 use strict;
  32         53  
  32         1376  
21              
22             #################
23             package DBD::DBM;
24             #################
25 32     32   150 use base qw( DBD::File );
  32         38  
  32         15595  
26 32     32   191 use vars qw($VERSION $ATTRIBUTION $drh $methods_already_installed);
  32         37  
  32         6200  
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 24     24 0 43 my ( $class, $attr ) = @_;
35 24 50       72 return $drh if ($drh);
36              
37             # do the real work in DBD::File
38             #
39 24         54 $attr->{Attribution} = 'DBD::DBM by Jens Rehsack';
40 24         191 $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 24 50       100 unless ( $methods_already_installed++ )
49             {
50 24         107 DBD::DBM::st->install_method('dbm_schema');
51             }
52              
53 24         91 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 32     32   158 use Carp qw/carp/;
  32         45  
  32         23417  
80              
81             sub validate_STORE_attr
82             {
83 2960     2960   17175 my ( $dbh, $attrib, $value ) = @_;
84              
85 2960 50 33     11311 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 2960         7999 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 384     384   2370 my $this = $_[0];
112 384         1090 $this->{dbm_version} = $DBD::DBM::VERSION;
113 384         1335 return $this->SUPER::set_versions();
114             }
115              
116             sub init_valid_attributes
117             {
118 384     384   2365 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 384         3214 $dbh->{dbm_valid_attrs} = {
130             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 384         1375 $dbh->{dbm_readonly_attrs} = {
142             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 384         669 $dbh->{dbm_meta} = "dbm_tables";
149              
150 384         1386 return $dbh->SUPER::init_valid_attributes();
151             }
152              
153             sub init_default_attributes
154             {
155 768     768   6102 my ( $dbh, $phase ) = @_;
156              
157 768         2418 $dbh->SUPER::init_default_attributes($phase);
158 768         1139 $dbh->{f_lockfile} = '.lck';
159              
160 768         1595 return $dbh;
161             }
162              
163             sub get_dbm_versions
164             {
165 8     8   15 my ( $dbh, $table ) = @_;
166 8   50     41 $table ||= '';
167              
168 8         7 my $meta;
169 8         19 my $class = $dbh->{ImplementorClass};
170 8         30 $class =~ s/::db$/::Table/;
171 8 50       28 $table and ( undef, $meta ) = $class->get_table_meta( $dbh, $table, 1 );
172 8 50 33     79 $meta or ( $meta = {} and $class->bootstrap_table_meta( $dbh, $meta, $table ) );
173              
174 8         76 my $dver;
175 8         16 my $dtype = $meta->{dbm_type};
176 8         14 eval {
177 8         138 $dver = $meta->{dbm_type}->VERSION();
178              
179             # *) when we're still alive here, everything went ok - no need to check for $@
180 8         31 $dtype .= " ($dver)";
181             };
182 8 50       40 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         69 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   10182 my ( $sth, $attr ) = @_;
216              
217 1796 100       3310 if ( $attr eq "NULLABLE" )
218             {
219 264         799 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       1887 $attr eq "NULLABLE" and return [ map { 0 } @colnames ];
  368         965  
225             }
226              
227 1532         4658 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 0 0       0 my $tbl_meta = $sth->{Database}->func( $tname, "f_schema", "get_sql_engine_meta" )
235             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 32     32   175 use Carp;
  32         39  
  32         1581  
254 32     32   138 use Fcntl;
  32         53  
  32         63093  
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 344     344   814 my ( $self, $dbh, $meta, $table ) = @_;
277              
278 344   100     2121 $meta->{dbm_type} ||= $dbh->{dbm_type} || 'SDBM_File';
      66        
279 344 50 0     781 $meta->{dbm_mldbm} ||= $dbh->{dbm_mldbm} if ( $dbh->{dbm_mldbm} );
280 344   33     1362 $meta->{dbm_berkeley_flags} ||= $dbh->{dbm_berkeley_flags};
281              
282 344 100       1135 defined $meta->{f_ext}
283             or $meta->{f_ext} = $dbh->{f_ext};
284 344 100       775 unless ( defined( $meta->{f_ext} ) )
285             {
286 340         354 my $ext;
287 340 50 33     1149 if ( $meta->{dbm_type} eq 'SDBM_File' or $meta->{dbm_type} eq 'ODBM_File' )
    0          
288             {
289 340         506 $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 340 50       1006 defined($ext) and $meta->{f_ext} = $ext;
306             }
307              
308 344         1548 $self->SUPER::bootstrap_table_meta( $dbh, $meta, $table );
309             }
310              
311             sub init_table_meta
312             {
313 232     232   463 my ( $self, $dbh, $meta, $table ) = @_;
314              
315 232         531 $meta->{f_dontopen} = 1;
316              
317 232 100       687 unless ( defined( $meta->{dbm_tietype} ) )
318             {
319 204         346 my $tie_type = $meta->{dbm_type};
320 204 100       5380 $INC{"$tie_type.pm"} or require "$tie_type.pm";
321 204 50       5058 $tie_type eq 'BerkeleyDB' and $tie_type = 'BerkeleyDB::Hash';
322              
323 204 50       586 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 204         452 $meta->{dbm_tietype} = $tie_type;
331             }
332              
333 232 100       664 unless ( defined( $meta->{dbm_store_metadata} ) )
334             {
335 204         381 my $store = $dbh->{dbm_store_metadata};
336 204 50       600 defined($store) or $store = 1;
337 204         378 $meta->{dbm_store_metadata} = $store;
338             }
339              
340 232 100       609 unless ( defined( $meta->{col_names} ) )
341             {
342 216 50       609 defined( $dbh->{dbm_cols} ) and $meta->{col_names} = $dbh->{dbm_cols};
343             }
344              
345 232         1021 $self->SUPER::init_table_meta( $dbh, $meta, $table );
346             }
347              
348             sub open_data
349             {
350 400     400   657 my ( $className, $meta, $attrs, $flags ) = @_;
351 400         1587 $className->SUPER::open_data( $meta, $attrs, $flags );
352              
353 360 100       1020 unless ( $flags->{dropMode} )
354             {
355             # TIEING
356             #
357             # XXX allow users to pass in a pre-created tied object
358             #
359 312         423 my @tie_args;
360 312 50       898 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 0         0 @tie_args = (
373             -Filename => $meta->{f_fqbn},
374             -Flags => $open_mode,
375             %tie_flags
376             );
377             }
378             else
379             {
380 312         486 my $open_mode = O_RDONLY;
381 312 100       851 $flags->{lockMode} and $open_mode = O_RDWR;
382 312 100       727 $flags->{createMode} and $open_mode = O_RDWR | O_CREAT | O_TRUNC;
383              
384 312         935 @tie_args = ( $meta->{f_fqbn}, $open_mode, 0666 );
385             }
386              
387 312 50       782 if ( $meta->{dbm_mldbm} )
388             {
389 0         0 $MLDBM::UseDB = $meta->{dbm_usedb};
390 0         0 $MLDBM::Serializer = $meta->{dbm_mldbm};
391             }
392              
393 312         728 $meta->{hash} = {};
394 312         637 my $tie_class = $meta->{dbm_tietype};
395 312         466 eval { tie %{ $meta->{hash} }, $tie_class, @tie_args };
  312         466  
  312         16435  
396 312 50       997 $@ and croak "Cannot tie(\%h $tie_class @tie_args): $@";
397 312 50       4471 -f $meta->{f_fqfn} or croak( "No such file: '" . $meta->{f_fqfn} . "'" );
398             }
399              
400 360 100       1241 unless ( $flags->{createMode} )
401             {
402 308         504 my ( $meta_data, $schema, $col_names );
403 308 50       870 if ( $meta->{dbm_store_metadata} )
404             {
405 308         3756 $meta_data = $col_names = $meta->{hash}->{"_metadata \0"};
406 308 100 66     2903 if ( $meta_data and $meta_data =~ m~(.+)~is )
407             {
408 260         649 $schema = $col_names = $1;
409 260         1494 $schema =~ s~.*(.+).*~$1~is;
410 260         1066 $col_names =~ s~.*(.+).*~$1~is;
411             }
412             }
413 308   100     1091 $col_names ||= $meta->{col_names} || [ 'k', 'v' ];
      66        
414 308 100       1629 $col_names = [ split /,/, $col_names ] if ( ref $col_names ne 'ARRAY' );
415 308 100 66     2745 if ( $meta->{dbm_store_metadata} and not $meta->{hash}->{"_metadata \0"} )
416             {
417 48 50       148 $schema or $schema = '';
418 48         220 $meta->{hash}->{"_metadata \0"} =
419             ""
420             . "$schema"
421             . ""
422 48         212 . join( ",", @{$col_names} )
423             . ""
424             . "";
425             }
426              
427 308         802 $meta->{schema} = $schema;
428 308         1056 $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   84 my ( $self, $data ) = @_;
438 48         99 my $meta = $self->{meta};
439 48 50       151 $meta->{hash} and untie %{ $meta->{hash} };
  48         95  
440 48         305 $self->SUPER::drop($data);
441             # XXX extra_files
442 48 50 33     2629 -f $meta->{f_fqbn} . $dirfext
443             and $meta->{f_ext} eq '.pag/r'
444             and unlink( $meta->{f_fqbn} . $dirfext );
445 48         164 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 444     444   553 my ( $self, $data ) = @_;
458 444         574 my $meta = $self->{meta};
459             # fetch with %each
460             #
461 444         398 my @ary = each %{ $meta->{hash} };
  444         3983  
462 136         1037 $meta->{dbm_store_metadata}
463             and $ary[0]
464             and $ary[0] eq "_metadata \0"
465 444 100 33     2581 and @ary = each %{ $meta->{hash} };
      100        
466              
467 444         1518 my ( $key, $val ) = @ary;
468 444 100       812 unless ($key)
469             {
470 120         257 delete $self->{row};
471 120         446 return;
472             }
473 324 50       915 my @row = ( ref($val) eq 'ARRAY' ) ? ( $key, @$val ) : ( $key, $val );
474 324 50       919 $self->{row} = @row ? \@row : undef;
475 324 50       1579 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 124     124   204 my ( $self, $data, $row_aryref ) = @_;
484 124         256 my $meta = $self->{meta};
485 124         134 my $ncols = scalar( @{ $meta->{col_names} } );
  124         252  
486 124         152 my $nitems = scalar( @{$row_aryref} );
  124         178  
487 124 50       322 $ncols == $nitems
488             or croak "You tried to insert $nitems, but table is created with $ncols columns";
489              
490 124         236 my $key = shift @$row_aryref;
491 124         147 my $exists;
492 124         175 eval { $exists = exists( $meta->{hash}->{$key} ); };
  124         953  
493 124 50       400 $exists and croak "Row with PK '$key' already exists";
494              
495 124 50       3095 $meta->{hash}->{$key} = $meta->{dbm_mldbm} ? $row_aryref : $row_aryref->[0];
496              
497 124         407 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 52     52   94 my ( $self, $data, $row_aryref ) = @_;
506 52         95 my $meta = $self->{meta};
507              
508             # some sanity checks ...
509 52         100 my $ncols = scalar(@$row_aryref);
510 52 50       135 $ncols < 2 and croak "At least 2 columns are required for DBD::DBM tables ...";
511 52 50 33     305 !$meta->{dbm_mldbm}
512             and $ncols > 2
513             and croak "Without serializing with MLDBM only 2 columns are supported, you give $ncols";
514 52         101 $meta->{col_names} = $row_aryref;
515 52 50       148 return unless $meta->{dbm_store_metadata};
516              
517 52         92 my $stmt = $data->{sql_stmt};
518 52         71 my $col_names = join( ',', @{$row_aryref} );
  52         148  
519 52         131 my $schema = $data->{Database}->{Statement};
520 52         433 $schema =~ s/^[^\(]+\((.+)\)$/$1/s;
521 52 50       540 $schema = $stmt->schema_str() if ( $stmt->can('schema_str') );
522 52         3422 $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   173 my ( $self, $key_only, $key ) = @_;
538 136         178 my $meta = $self->{meta};
539 136 100       499 $key_only and return $meta->{col_names}->[0];
540 16 50       135 exists $meta->{hash}->{$key} or return;
541 16         95 my $val = $meta->{hash}->{$key};
542 16 50       78 $val = ( ref($val) eq 'ARRAY' ) ? $val : [$val];
543 16         38 my $row = [ $key, @$val ];
544 16 50       74 return wantarray ? @{$row} : $row;
  0         0  
545             }
546              
547             sub delete_one_row ($$$)
548             {
549 56     56   77 my ( $self, $data, $aryref ) = @_;
550 56         88 my $meta = $self->{meta};
551 56         979 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   89 my ( $self, $data, $aryref, $origary ) = @_;
567 56         86 my $meta = $self->{meta};
568 56         92 my $key = shift @$origary;
569 56         84 my $newkey = shift @$aryref;
570 56 50       135 return unless ( defined $key );
571 56 50       130 $key eq $newkey or delete $meta->{hash}->{$key};
572 56 50       148 my $row = ( ref($aryref) eq 'ARRAY' ) ? $aryref : [$aryref];
573 56 50       1345 $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 360     360   696 my $self = shift;
582 360         722 my $meta = $self->{meta};
583 360 50       1089 $meta->{hash} and untie %{ $meta->{hash} };
  360         4498  
584              
585 360         1695 $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 124     124   228 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__