# DB_File.pm -- Perl 5 interface to Berkeley DB
#
# written by Paul Marquess (Paul.Marquess@btinternet.com)
-# last modified 26th April 2001
-# version 1.77
+# last modified 22nd October 2002
+# version 1.806
#
-# Copyright (c) 1995-2001 Paul Marquess. All rights reserved.
+# Copyright (c) 1995-2002 Paul Marquess. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
package DB_File::HASHINFO ;
-require 5.003 ;
+require 5.00404;
use warnings;
use strict;
{
my $pkg = shift ;
- bless { VALID => { map {$_, 1}
- qw( bsize ffactor nelem cachesize hash lorder)
+ bless { VALID => {
+ bsize => 1,
+ ffactor => 1,
+ nelem => 1,
+ cachesize => 1,
+ hash => 2,
+ lorder => 1,
},
GOT => {}
}, $pkg ;
my $key = shift ;
my $value = shift ;
- if ( exists $self->{VALID}{$key} )
+ my $type = $self->{VALID}{$key};
+
+ if ( $type )
{
+ croak "Key '$key' not associated with a code reference"
+ if $type == 2 && !ref $value && ref $value ne 'CODE';
$self->{GOT}{$key} = $value ;
return ;
}
{
my $pkg = shift ;
- bless { VALID => { map {$_, 1}
- qw( flags cachesize maxkeypage minkeypage psize
- compare prefix lorder )
+ bless { VALID => {
+ flags => 1,
+ cachesize => 1,
+ maxkeypage => 1,
+ minkeypage => 1,
+ psize => 1,
+ compare => 2,
+ prefix => 2,
+ lorder => 1,
},
GOT => {},
}, $pkg ;
use warnings;
use strict;
-use vars qw($VERSION @ISA @EXPORT $AUTOLOAD $DB_BTREE $DB_HASH $DB_RECNO
- $db_version $use_XSLoader
- ) ;
+our ($VERSION, @ISA, @EXPORT, $AUTOLOAD, $DB_BTREE, $DB_HASH, $DB_RECNO);
+our ($db_version, $use_XSLoader, $splice_end_array);
use Carp;
-$VERSION = "1.77" ;
+$VERSION = "1.806" ;
+
+{
+ local $SIG{__WARN__} = sub {$splice_end_array = "@_";};
+ my @a =(1); splice(@a, 3);
+ $splice_end_array =
+ ($splice_end_array =~ /^splice\(\) offset past end of array at /);
+}
#typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
$DB_BTREE = new DB_File::BTREEINFO ;
use AutoLoader;
BEGIN {
$use_XSLoader = 1 ;
- eval { require XSLoader } ;
+ { local $SIG{__DIE__} ; eval { require XSLoader } ; }
if ($@) {
$use_XSLoader = 0 ;
sub AUTOLOAD {
my($constname);
($constname = $AUTOLOAD) =~ s/.*:://;
- my $val = constant($constname, @_ ? $_[0] : 0);
- if ($! != 0) {
- if ($! =~ /Invalid/ || $!{EINVAL}) {
- $AutoLoader::AUTOLOAD = $AUTOLOAD;
- goto &AutoLoader::AUTOLOAD;
- }
- else {
- my($pack,$file,$line) = caller;
- croak "Your vendor has not defined DB macro $constname, used at $file line $line.
-";
- }
- }
- eval "sub $AUTOLOAD { $val }";
- goto &$AUTOLOAD;
-}
+ my ($error, $val) = constant($constname);
+ Carp::croak $error if $error;
+ no strict 'refs';
+ *{$AUTOLOAD} = sub { $val };
+ goto &{$AUTOLOAD};
+}
eval {
$arg[4] = tied %{ $arg[4] }
if @arg >= 5 && ref $arg[4] && $arg[4] =~ /=HASH/ && tied %{ $arg[4] } ;
+ $arg[2] = O_CREAT()|O_RDWR() if @arg >=3 && ! defined $arg[2];
+ $arg[3] = 0666 if @arg >=4 && ! defined $arg[3];
+
# make recno in Berkeley DB version 2 work like recno in version 1.
if ($db_version > 1 and defined $arg[4] and $arg[4] =~ /RECNO/ and
$arg[1] and ! -e $arg[1]) {
my $self = shift;
my $offset = shift;
if (not defined $offset) {
- carp 'Use of uninitialized value in splice';
+ warnings::warnif('uninitialized', 'Use of uninitialized value in splice');
$offset = 0;
}
$offset = $new_offset;
}
- if ($offset > $size) {
- $offset = $size;
- }
-
if (not defined $length) {
- carp 'Use of uninitialized value in splice';
+ warnings::warnif('uninitialized', 'Use of uninitialized value in splice');
$length = 0;
}
+ if ($offset > $size) {
+ $offset = $size;
+ warnings::warnif('misc', 'splice() offset past end of array')
+ if $splice_end_array;
+ }
+
# 'If LENGTH is omitted, removes everything from OFFSET onward.'
if (not defined $length) {
$length = $size - $offset;
B<DB_File> is a module which allows Perl programs to make use of the
facilities provided by Berkeley DB version 1.x (if you have a newer
-version of DB, see L<Using DB_File with Berkeley DB version 2 or 3>).
+version of DB, see L<Using DB_File with Berkeley DB version 2 or greater>).
It is assumed that you have a copy of the Berkeley DB manual pages at
hand when reading this documentation. The interface defined here
mirrors the Berkeley DB interface closely.
=back
-=head2 Using DB_File with Berkeley DB version 2 or 3
+=head2 Using DB_File with Berkeley DB version 2 or greater
Although B<DB_File> is intended to be used with Berkeley DB version 1,
-it can also be used with version 2 or 3. In this case the interface is
+it can also be used with version 2, 3 or 4. In this case the interface is
limited to the functionality provided by Berkeley DB 1.x. Anywhere the
-version 2 or 3 interface differs, B<DB_File> arranges for it to work
+version 2 or greater interface differs, B<DB_File> arranges for it to work
like version 1. This feature allows B<DB_File> scripts that were built
-with version 1 to be migrated to version 2 or 3 without any changes.
+with version 1 to be migrated to version 2 or greater without any changes.
If you want to make use of the new features available in Berkeley DB
2.x or greater, use the Perl module B<BerkeleyDB> instead.
-B<Note:> The database file format has changed in both Berkeley DB
-version 2 and 3. If you cannot recreate your databases, you must dump
-any existing databases with either the C<db_dump> or the C<db_dump185>
-utility that comes with Berkeley DB.
-Once you have rebuilt DB_File to use Berkeley DB version 2 or 3, your
-databases can be recreated using C<db_load>. Refer to the Berkeley DB
+B<Note:> The database file format has changed multiple times in Berkeley
+DB version 2, 3 and 4. If you cannot recreate your databases, you
+must dump any existing databases with either the C<db_dump> or the
+C<db_dump185> utility that comes with Berkeley DB.
+Once you have rebuilt DB_File to use Berkeley DB version 2 or greater,
+your databases can be recreated using C<db_load>. Refer to the Berkeley DB
documentation for further details.
-Please read L<"COPYRIGHT"> before using version 2.x or 3.x of Berkeley
+Please read L<"COPYRIGHT"> before using version 2.x or greater of Berkeley
DB with DB_File.
=head2 Interface to Berkeley DB
use warnings ;
use strict ;
use DB_File ;
- use vars qw( %h $k $v ) ;
+ our (%h, $k, $v) ;
unlink "fruit" ;
tie %h, "DB_File", "fruit", O_RDWR|O_CREAT, 0666, $DB_HASH
you must use the same compare function every time you access the
database.
+=item 3
+
+Duplicate keys are entirely defined by the comparison function.
+In the case-insensitive example above, the keys: 'KEY' and 'key'
+would be considered duplicates, and assigning to the second one
+would overwrite the first. If duplicates are allowed for (with the
+R_DUPS flag discussed below), only a single copy of duplicate keys
+is stored in the database --- so (again with example above) assigning
+three values to the keys: 'KEY', 'Key', and 'key' would leave just
+the first key: 'KEY' in the database with three values. For some
+situations this results in information loss, so care should be taken
+to provide fully qualified comparison functions when necessary.
+For example, the above comparison routine could be modified to
+additionally compare case-sensitively if two keys are equal in the
+case insensitive comparison:
+
+ sub compare {
+ my($key1, $key2) = @_;
+ lc $key1 cmp lc $key2 ||
+ $key1 cmp $key2;
+ }
+
+And now you will only have duplicates when the keys themselves
+are truly the same. (note: in versions of the db library prior to
+about November 1996, such duplicate keys were retained so it was
+possible to recover the original keys in sets of keys that
+compared as equal).
+
+
=back
=head2 Handling Duplicate Keys
use strict ;
use DB_File ;
- use vars qw($filename %h ) ;
+ my ($filename, %h) ;
$filename = "tree" ;
unlink $filename ;
use strict ;
use DB_File ;
- use vars qw($filename $x %h $status $key $value) ;
+ my ($filename, $x, %h, $status, $key, $value) ;
$filename = "tree" ;
unlink $filename ;
use strict ;
use DB_File ;
- use vars qw($filename $x %h ) ;
+ my ($filename, $x, %h) ;
$filename = "tree" ;
use strict ;
use DB_File ;
- use vars qw($filename $x %h $found) ;
+ my ($filename, $x, %h, $found) ;
- my $filename = "tree" ;
+ $filename = "tree" ;
# Enable duplicate records
$DB_BTREE->{'flags'} = R_DUP ;
use strict ;
use DB_File ;
- use vars qw($filename $x %h $found) ;
+ my ($filename, $x, %h, $found) ;
- my $filename = "tree" ;
+ $filename = "tree" ;
# Enable duplicate records
$DB_BTREE->{'flags'} = R_DUP ;
use DB_File ;
use Fcntl ;
- use vars qw($filename $x %h $st $key $value) ;
+ my ($filename, $x, %h, $st, $key, $value) ;
sub match
{
space for fixed length records.
Also note that the bval option only allows you to specify a single byte
-as a delimeter.
+as a delimiter.
=head2 A Simple Example
=item B<$X-E<gt>splice(offset, length, elements);>
-Returns a splice of the the array.
+Returns a splice of the array.
=back
use warnings ;
use strict ;
- use vars qw(@h $H $file $i) ;
+ my (@h, $H, $file, $i) ;
use DB_File ;
use Fcntl ;
use DB_File ;
use Fcntl ;
- use vars qw( $dotdir $HISTORY %hist_db $href $binary_time $date ) ;
+ my ($dotdir, $HISTORY, %hist_db, $href, $binary_time, $date) ;
$dotdir = $ENV{HOME} || $ENV{LOGNAME};
$HISTORY = "$dotdir/.netscape/history.db";
use warnings ;
use strict ;
use DB_File ;
- use vars qw(%x) ;
+ my %x ;
tie %x, DB_File, "filename" ;
Running it produces the error in question:
=head1 COPYRIGHT
-Copyright (c) 1995-2001 Paul Marquess. All rights reserved. This program
+Copyright (c) 1995-2002 Paul Marquess. All rights reserved. This program
is free software; you can redistribute it and/or modify it under the
same terms as Perl itself.