1b39c5158Smillert# DB_File.pm -- Perl 5 interface to Berkeley DB 2b39c5158Smillert# 36fb12b70Safresh1# Written by Paul Marquess (pmqs@cpan.org) 4b39c5158Smillert# 5*3d61058aSafresh1# Copyright (c) 1995-2023 Paul Marquess. All rights reserved. 6b39c5158Smillert# This program is free software; you can redistribute it and/or 7b39c5158Smillert# modify it under the same terms as Perl itself. 8b39c5158Smillert 9b39c5158Smillert 10b39c5158Smillertpackage DB_File::HASHINFO ; 11b39c5158Smillert 12b8851fccSafresh1require 5.008003; 13b39c5158Smillert 14b39c5158Smillertuse warnings; 15b39c5158Smillertuse strict; 16b39c5158Smillertuse Carp; 17b39c5158Smillertrequire Tie::Hash; 18b39c5158Smillert@DB_File::HASHINFO::ISA = qw(Tie::Hash); 19b39c5158Smillert 20b39c5158Smillertsub new 21b39c5158Smillert{ 22b39c5158Smillert my $pkg = shift ; 23b39c5158Smillert my %x ; 24b39c5158Smillert tie %x, $pkg ; 25b39c5158Smillert bless \%x, $pkg ; 26b39c5158Smillert} 27b39c5158Smillert 28b39c5158Smillert 29b39c5158Smillertsub TIEHASH 30b39c5158Smillert{ 31b39c5158Smillert my $pkg = shift ; 32b39c5158Smillert 33b39c5158Smillert bless { VALID => { 34b39c5158Smillert bsize => 1, 35b39c5158Smillert ffactor => 1, 36b39c5158Smillert nelem => 1, 37b39c5158Smillert cachesize => 1, 38b39c5158Smillert hash => 2, 39b39c5158Smillert lorder => 1, 40b39c5158Smillert }, 41b39c5158Smillert GOT => {} 42b39c5158Smillert }, $pkg ; 43b39c5158Smillert} 44b39c5158Smillert 45b39c5158Smillert 46b39c5158Smillertsub FETCH 47b39c5158Smillert{ 48b39c5158Smillert my $self = shift ; 49b39c5158Smillert my $key = shift ; 50b39c5158Smillert 51b39c5158Smillert return $self->{GOT}{$key} if exists $self->{VALID}{$key} ; 52b39c5158Smillert 53b39c5158Smillert my $pkg = ref $self ; 54b39c5158Smillert croak "${pkg}::FETCH - Unknown element '$key'" ; 55b39c5158Smillert} 56b39c5158Smillert 57b39c5158Smillert 58b39c5158Smillertsub STORE 59b39c5158Smillert{ 60b39c5158Smillert my $self = shift ; 61b39c5158Smillert my $key = shift ; 62b39c5158Smillert my $value = shift ; 63b39c5158Smillert 64b39c5158Smillert my $type = $self->{VALID}{$key}; 65b39c5158Smillert 66b39c5158Smillert if ( $type ) 67b39c5158Smillert { 68b39c5158Smillert croak "Key '$key' not associated with a code reference" 69b39c5158Smillert if $type == 2 && !ref $value && ref $value ne 'CODE'; 70b39c5158Smillert $self->{GOT}{$key} = $value ; 71b39c5158Smillert return ; 72b39c5158Smillert } 73b39c5158Smillert 74b39c5158Smillert my $pkg = ref $self ; 75b39c5158Smillert croak "${pkg}::STORE - Unknown element '$key'" ; 76b39c5158Smillert} 77b39c5158Smillert 78b39c5158Smillertsub DELETE 79b39c5158Smillert{ 80b39c5158Smillert my $self = shift ; 81b39c5158Smillert my $key = shift ; 82b39c5158Smillert 83b39c5158Smillert if ( exists $self->{VALID}{$key} ) 84b39c5158Smillert { 85b39c5158Smillert delete $self->{GOT}{$key} ; 86b39c5158Smillert return ; 87b39c5158Smillert } 88b39c5158Smillert 89b39c5158Smillert my $pkg = ref $self ; 90b39c5158Smillert croak "DB_File::HASHINFO::DELETE - Unknown element '$key'" ; 91b39c5158Smillert} 92b39c5158Smillert 93b39c5158Smillertsub EXISTS 94b39c5158Smillert{ 95b39c5158Smillert my $self = shift ; 96b39c5158Smillert my $key = shift ; 97b39c5158Smillert 98b39c5158Smillert exists $self->{VALID}{$key} ; 99b39c5158Smillert} 100b39c5158Smillert 101b39c5158Smillertsub NotHere 102b39c5158Smillert{ 103b39c5158Smillert my $self = shift ; 104b39c5158Smillert my $method = shift ; 105b39c5158Smillert 106b39c5158Smillert croak ref($self) . " does not define the method ${method}" ; 107b39c5158Smillert} 108b39c5158Smillert 109b39c5158Smillertsub FIRSTKEY { my $self = shift ; $self->NotHere("FIRSTKEY") } 110b39c5158Smillertsub NEXTKEY { my $self = shift ; $self->NotHere("NEXTKEY") } 111b39c5158Smillertsub CLEAR { my $self = shift ; $self->NotHere("CLEAR") } 112b39c5158Smillert 113b39c5158Smillertpackage DB_File::RECNOINFO ; 114b39c5158Smillert 115b39c5158Smillertuse warnings; 116b39c5158Smillertuse strict ; 117b39c5158Smillert 118b39c5158Smillert@DB_File::RECNOINFO::ISA = qw(DB_File::HASHINFO) ; 119b39c5158Smillert 120b39c5158Smillertsub TIEHASH 121b39c5158Smillert{ 122b39c5158Smillert my $pkg = shift ; 123b39c5158Smillert 124b39c5158Smillert bless { VALID => { map {$_, 1} 125b39c5158Smillert qw( bval cachesize psize flags lorder reclen bfname ) 126b39c5158Smillert }, 127b39c5158Smillert GOT => {}, 128b39c5158Smillert }, $pkg ; 129b39c5158Smillert} 130b39c5158Smillert 131b39c5158Smillertpackage DB_File::BTREEINFO ; 132b39c5158Smillert 133b39c5158Smillertuse warnings; 134b39c5158Smillertuse strict ; 135b39c5158Smillert 136b39c5158Smillert@DB_File::BTREEINFO::ISA = qw(DB_File::HASHINFO) ; 137b39c5158Smillert 138b39c5158Smillertsub TIEHASH 139b39c5158Smillert{ 140b39c5158Smillert my $pkg = shift ; 141b39c5158Smillert 142b39c5158Smillert bless { VALID => { 143b39c5158Smillert flags => 1, 144b39c5158Smillert cachesize => 1, 145b39c5158Smillert maxkeypage => 1, 146b39c5158Smillert minkeypage => 1, 147b39c5158Smillert psize => 1, 148b39c5158Smillert compare => 2, 149b39c5158Smillert prefix => 2, 150b39c5158Smillert lorder => 1, 151b39c5158Smillert }, 152b39c5158Smillert GOT => {}, 153b39c5158Smillert }, $pkg ; 154b39c5158Smillert} 155b39c5158Smillert 156b39c5158Smillert 157b39c5158Smillertpackage DB_File ; 158b39c5158Smillert 159b39c5158Smillertuse warnings; 160b39c5158Smillertuse strict; 161b39c5158Smillertour ($VERSION, @ISA, @EXPORT, $AUTOLOAD, $DB_BTREE, $DB_HASH, $DB_RECNO); 162898184e3Ssthenour ($db_version, $use_XSLoader, $splice_end_array_no_length, $splice_end_array, $Error); 163b39c5158Smillertuse Carp; 164b39c5158Smillert 165b46d8ef2Safresh1# Module not thread safe, so don't clone 166b46d8ef2Safresh1sub CLONE_SKIP { 1 } 167b39c5158Smillert 168*3d61058aSafresh1$VERSION = "1.859" ; 169b39c5158Smillert$VERSION = eval $VERSION; # needed for dev releases 170b39c5158Smillert 171b39c5158Smillert{ 17291f110e0Safresh1 local $SIG{__WARN__} = sub {$splice_end_array_no_length = join(" ",@_);}; 173b39c5158Smillert my @a =(1); splice(@a, 3); 174898184e3Ssthen $splice_end_array_no_length = 175898184e3Ssthen ($splice_end_array_no_length =~ /^splice\(\) offset past end of array at /); 176898184e3Ssthen} 177898184e3Ssthen{ 17891f110e0Safresh1 local $SIG{__WARN__} = sub {$splice_end_array = join(" ", @_);}; 179898184e3Ssthen my @a =(1); splice(@a, 3, 1); 180b39c5158Smillert $splice_end_array = 181b39c5158Smillert ($splice_end_array =~ /^splice\(\) offset past end of array at /); 182b39c5158Smillert} 183b39c5158Smillert 184b39c5158Smillert#typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; 185eac174f2Safresh1$DB_BTREE = DB_File::BTREEINFO->new(); 186eac174f2Safresh1$DB_HASH = DB_File::HASHINFO->new(); 187eac174f2Safresh1$DB_RECNO = DB_File::RECNOINFO->new(); 188b39c5158Smillert 189b39c5158Smillertrequire Tie::Hash; 190b39c5158Smillertrequire Exporter; 191b39c5158SmillertBEGIN { 192b39c5158Smillert $use_XSLoader = 1 ; 193b39c5158Smillert { local $SIG{__DIE__} ; eval { require XSLoader } ; } 194b39c5158Smillert 195b39c5158Smillert if ($@) { 196b39c5158Smillert $use_XSLoader = 0 ; 197b39c5158Smillert require DynaLoader; 198b39c5158Smillert @ISA = qw(DynaLoader); 199b39c5158Smillert } 200b39c5158Smillert} 201b39c5158Smillert 202b39c5158Smillertpush @ISA, qw(Tie::Hash Exporter); 203b39c5158Smillert@EXPORT = qw( 204b39c5158Smillert $DB_BTREE $DB_HASH $DB_RECNO 205b39c5158Smillert 206b39c5158Smillert BTREEMAGIC 207b39c5158Smillert BTREEVERSION 208b39c5158Smillert DB_LOCK 209b39c5158Smillert DB_SHMEM 210b39c5158Smillert DB_TXN 211b39c5158Smillert HASHMAGIC 212b39c5158Smillert HASHVERSION 213b39c5158Smillert MAX_PAGE_NUMBER 214b39c5158Smillert MAX_PAGE_OFFSET 215b39c5158Smillert MAX_REC_NUMBER 216b39c5158Smillert RET_ERROR 217b39c5158Smillert RET_SPECIAL 218b39c5158Smillert RET_SUCCESS 219b39c5158Smillert R_CURSOR 220b39c5158Smillert R_DUP 221b39c5158Smillert R_FIRST 222b39c5158Smillert R_FIXEDLEN 223b39c5158Smillert R_IAFTER 224b39c5158Smillert R_IBEFORE 225b39c5158Smillert R_LAST 226b39c5158Smillert R_NEXT 227b39c5158Smillert R_NOKEY 228b39c5158Smillert R_NOOVERWRITE 229b39c5158Smillert R_PREV 230b39c5158Smillert R_RECNOSYNC 231b39c5158Smillert R_SETCURSOR 232b39c5158Smillert R_SNAPSHOT 233b39c5158Smillert __R_UNUSED 234b39c5158Smillert 235b39c5158Smillert); 236b39c5158Smillert 237b39c5158Smillertsub AUTOLOAD { 238b39c5158Smillert my($constname); 239b39c5158Smillert ($constname = $AUTOLOAD) =~ s/.*:://; 240b39c5158Smillert my ($error, $val) = constant($constname); 241b39c5158Smillert Carp::croak $error if $error; 242b39c5158Smillert no strict 'refs'; 243b39c5158Smillert *{$AUTOLOAD} = sub { $val }; 244b39c5158Smillert goto &{$AUTOLOAD}; 245b39c5158Smillert} 246b39c5158Smillert 247b39c5158Smillert 248b39c5158Smillerteval { 249b39c5158Smillert # Make all Fcntl O_XXX constants available for importing 250b39c5158Smillert require Fcntl; 251b39c5158Smillert my @O = grep /^O_/, @Fcntl::EXPORT; 252b39c5158Smillert Fcntl->import(@O); # first we import what we want to export 253b39c5158Smillert push(@EXPORT, @O); 254b39c5158Smillert}; 255b39c5158Smillert 256b39c5158Smillertif ($use_XSLoader) 257b39c5158Smillert { XSLoader::load("DB_File", $VERSION)} 258b39c5158Smillertelse 259eac174f2Safresh1 { DB_File->bootstrap( $VERSION ) } 260b39c5158Smillert 261b39c5158Smillertsub tie_hash_or_array 262b39c5158Smillert{ 263b39c5158Smillert my (@arg) = @_ ; 264b39c5158Smillert my $tieHASH = ( (caller(1))[3] =~ /TIEHASH/ ) ; 265b39c5158Smillert 266b39c5158Smillert use File::Spec; 267b39c5158Smillert $arg[1] = File::Spec->rel2abs($arg[1]) 268b39c5158Smillert if defined $arg[1] ; 269b39c5158Smillert 270b39c5158Smillert $arg[4] = tied %{ $arg[4] } 271b39c5158Smillert if @arg >= 5 && ref $arg[4] && $arg[4] =~ /=HASH/ && tied %{ $arg[4] } ; 272b39c5158Smillert 273b39c5158Smillert $arg[2] = O_CREAT()|O_RDWR() if @arg >=3 && ! defined $arg[2]; 274b39c5158Smillert $arg[3] = 0666 if @arg >=4 && ! defined $arg[3]; 275b39c5158Smillert 276b39c5158Smillert # make recno in Berkeley DB version 2 (or better) work like 277b39c5158Smillert # recno in version 1. 278b39c5158Smillert if ($db_version >= 4 and ! $tieHASH) { 279b39c5158Smillert $arg[2] |= O_CREAT(); 280b39c5158Smillert } 281b39c5158Smillert 282b39c5158Smillert if ($db_version > 1 and defined $arg[4] and $arg[4] =~ /RECNO/ and 283b39c5158Smillert $arg[1] and ! -e $arg[1]) { 284b39c5158Smillert open(FH, ">$arg[1]") or return undef ; 285b39c5158Smillert close FH ; 286b39c5158Smillert chmod $arg[3] ? $arg[3] : 0666 , $arg[1] ; 287b39c5158Smillert } 288b39c5158Smillert 289b39c5158Smillert DoTie_($tieHASH, @arg) ; 290b39c5158Smillert} 291b39c5158Smillert 292b39c5158Smillertsub TIEHASH 293b39c5158Smillert{ 294b39c5158Smillert tie_hash_or_array(@_) ; 295b39c5158Smillert} 296b39c5158Smillert 297b39c5158Smillertsub TIEARRAY 298b39c5158Smillert{ 299b39c5158Smillert tie_hash_or_array(@_) ; 300b39c5158Smillert} 301b39c5158Smillert 302b39c5158Smillertsub CLEAR 303b39c5158Smillert{ 304b39c5158Smillert my $self = shift; 305b39c5158Smillert my $key = 0 ; 306b39c5158Smillert my $value = "" ; 307b39c5158Smillert my $status = $self->seq($key, $value, R_FIRST()); 308b39c5158Smillert my @keys; 309b39c5158Smillert 310b39c5158Smillert while ($status == 0) { 311b39c5158Smillert push @keys, $key; 312b39c5158Smillert $status = $self->seq($key, $value, R_NEXT()); 313b39c5158Smillert } 314b39c5158Smillert foreach $key (reverse @keys) { 315b39c5158Smillert my $s = $self->del($key); 316b39c5158Smillert } 317b39c5158Smillert} 318b39c5158Smillert 319b39c5158Smillertsub EXTEND { } 320b39c5158Smillert 321b39c5158Smillertsub STORESIZE 322b39c5158Smillert{ 323b39c5158Smillert my $self = shift; 324b39c5158Smillert my $length = shift ; 325b39c5158Smillert my $current_length = $self->length() ; 326b39c5158Smillert 327b39c5158Smillert if ($length < $current_length) { 328b39c5158Smillert my $key ; 329b39c5158Smillert for ($key = $current_length - 1 ; $key >= $length ; -- $key) 330b39c5158Smillert { $self->del($key) } 331b39c5158Smillert } 332b39c5158Smillert elsif ($length > $current_length) { 333b39c5158Smillert $self->put($length-1, "") ; 334b39c5158Smillert } 335b39c5158Smillert} 336b39c5158Smillert 337b39c5158Smillert 338b39c5158Smillertsub SPLICE 339b39c5158Smillert{ 340b39c5158Smillert my $self = shift; 341b39c5158Smillert my $offset = shift; 342b39c5158Smillert if (not defined $offset) { 343b39c5158Smillert warnings::warnif('uninitialized', 'Use of uninitialized value in splice'); 344b39c5158Smillert $offset = 0; 345b39c5158Smillert } 346b39c5158Smillert 347898184e3Ssthen my $has_length = @_; 348b39c5158Smillert my $length = @_ ? shift : 0; 349b39c5158Smillert # Carping about definedness comes _after_ the OFFSET sanity check. 350b39c5158Smillert # This is so we get the same error messages as Perl's splice(). 351b39c5158Smillert # 352b39c5158Smillert 353b39c5158Smillert my @list = @_; 354b39c5158Smillert 355b39c5158Smillert my $size = $self->FETCHSIZE(); 356b39c5158Smillert 357b39c5158Smillert # 'If OFFSET is negative then it start that far from the end of 358b39c5158Smillert # the array.' 359b39c5158Smillert # 360b39c5158Smillert if ($offset < 0) { 361b39c5158Smillert my $new_offset = $size + $offset; 362b39c5158Smillert if ($new_offset < 0) { 363b39c5158Smillert die "Modification of non-creatable array value attempted, " 364b39c5158Smillert . "subscript $offset"; 365b39c5158Smillert } 366b39c5158Smillert $offset = $new_offset; 367b39c5158Smillert } 368b39c5158Smillert 369b39c5158Smillert if (not defined $length) { 370b39c5158Smillert warnings::warnif('uninitialized', 'Use of uninitialized value in splice'); 371b39c5158Smillert $length = 0; 372b39c5158Smillert } 373b39c5158Smillert 374b39c5158Smillert if ($offset > $size) { 375b39c5158Smillert $offset = $size; 376b39c5158Smillert warnings::warnif('misc', 'splice() offset past end of array') 377898184e3Ssthen if $has_length ? $splice_end_array : $splice_end_array_no_length; 378b39c5158Smillert } 379b39c5158Smillert 380b39c5158Smillert # 'If LENGTH is omitted, removes everything from OFFSET onward.' 381b39c5158Smillert if (not defined $length) { 382b39c5158Smillert $length = $size - $offset; 383b39c5158Smillert } 384b39c5158Smillert 385b39c5158Smillert # 'If LENGTH is negative, leave that many elements off the end of 386b39c5158Smillert # the array.' 387b39c5158Smillert # 388b39c5158Smillert if ($length < 0) { 389b39c5158Smillert $length = $size - $offset + $length; 390b39c5158Smillert 391b39c5158Smillert if ($length < 0) { 392b39c5158Smillert # The user must have specified a length bigger than the 393b39c5158Smillert # length of the array passed in. But perl's splice() 394b39c5158Smillert # doesn't catch this, it just behaves as for length=0. 395b39c5158Smillert # 396b39c5158Smillert $length = 0; 397b39c5158Smillert } 398b39c5158Smillert } 399b39c5158Smillert 400b39c5158Smillert if ($length > $size - $offset) { 401b39c5158Smillert $length = $size - $offset; 402b39c5158Smillert } 403b39c5158Smillert 404b39c5158Smillert # $num_elems holds the current number of elements in the database. 405b39c5158Smillert my $num_elems = $size; 406b39c5158Smillert 407b39c5158Smillert # 'Removes the elements designated by OFFSET and LENGTH from an 408b39c5158Smillert # array,'... 409b39c5158Smillert # 410b39c5158Smillert my @removed = (); 411b39c5158Smillert foreach (0 .. $length - 1) { 412b39c5158Smillert my $old; 413b39c5158Smillert my $status = $self->get($offset, $old); 414b39c5158Smillert if ($status != 0) { 415b39c5158Smillert my $msg = "error from Berkeley DB on get($offset, \$old)"; 416b39c5158Smillert if ($status == 1) { 417b39c5158Smillert $msg .= ' (no such element?)'; 418b39c5158Smillert } 419b39c5158Smillert else { 420b39c5158Smillert $msg .= ": error status $status"; 421b39c5158Smillert if (defined $! and $! ne '') { 422b39c5158Smillert $msg .= ", message $!"; 423b39c5158Smillert } 424b39c5158Smillert } 425b39c5158Smillert die $msg; 426b39c5158Smillert } 427b39c5158Smillert push @removed, $old; 428b39c5158Smillert 429b39c5158Smillert $status = $self->del($offset); 430b39c5158Smillert if ($status != 0) { 431b39c5158Smillert my $msg = "error from Berkeley DB on del($offset)"; 432b39c5158Smillert if ($status == 1) { 433b39c5158Smillert $msg .= ' (no such element?)'; 434b39c5158Smillert } 435b39c5158Smillert else { 436b39c5158Smillert $msg .= ": error status $status"; 437b39c5158Smillert if (defined $! and $! ne '') { 438b39c5158Smillert $msg .= ", message $!"; 439b39c5158Smillert } 440b39c5158Smillert } 441b39c5158Smillert die $msg; 442b39c5158Smillert } 443b39c5158Smillert 444b39c5158Smillert -- $num_elems; 445b39c5158Smillert } 446b39c5158Smillert 447b39c5158Smillert # ...'and replaces them with the elements of LIST, if any.' 448b39c5158Smillert my $pos = $offset; 449b39c5158Smillert while (defined (my $elem = shift @list)) { 450b39c5158Smillert my $old_pos = $pos; 451b39c5158Smillert my $status; 452b39c5158Smillert if ($pos >= $num_elems) { 453b39c5158Smillert $status = $self->put($pos, $elem); 454b39c5158Smillert } 455b39c5158Smillert else { 456b39c5158Smillert $status = $self->put($pos, $elem, $self->R_IBEFORE); 457b39c5158Smillert } 458b39c5158Smillert 459b39c5158Smillert if ($status != 0) { 460b39c5158Smillert my $msg = "error from Berkeley DB on put($pos, $elem, ...)"; 461b39c5158Smillert if ($status == 1) { 462b39c5158Smillert $msg .= ' (no such element?)'; 463b39c5158Smillert } 464b39c5158Smillert else { 465b39c5158Smillert $msg .= ", error status $status"; 466b39c5158Smillert if (defined $! and $! ne '') { 467b39c5158Smillert $msg .= ", message $!"; 468b39c5158Smillert } 469b39c5158Smillert } 470b39c5158Smillert die $msg; 471b39c5158Smillert } 472b39c5158Smillert 473b39c5158Smillert die "pos unexpectedly changed from $old_pos to $pos with R_IBEFORE" 474b39c5158Smillert if $old_pos != $pos; 475b39c5158Smillert 476b39c5158Smillert ++ $pos; 477b39c5158Smillert ++ $num_elems; 478b39c5158Smillert } 479b39c5158Smillert 480b39c5158Smillert if (wantarray) { 481b39c5158Smillert # 'In list context, returns the elements removed from the 482b39c5158Smillert # array.' 483b39c5158Smillert # 484b39c5158Smillert return @removed; 485b39c5158Smillert } 486b39c5158Smillert elsif (defined wantarray and not wantarray) { 487b39c5158Smillert # 'In scalar context, returns the last element removed, or 488b39c5158Smillert # undef if no elements are removed.' 489b39c5158Smillert # 490b39c5158Smillert if (@removed) { 491b39c5158Smillert my $last = pop @removed; 492b39c5158Smillert return "$last"; 493b39c5158Smillert } 494b39c5158Smillert else { 495b39c5158Smillert return undef; 496b39c5158Smillert } 497b39c5158Smillert } 498b39c5158Smillert elsif (not defined wantarray) { 499b39c5158Smillert # Void context 500b39c5158Smillert } 501b39c5158Smillert else { die } 502b39c5158Smillert} 503b39c5158Smillertsub ::DB_File::splice { &SPLICE } 504b39c5158Smillert 505b39c5158Smillertsub find_dup 506b39c5158Smillert{ 507b39c5158Smillert croak "Usage: \$db->find_dup(key,value)\n" 508b39c5158Smillert unless @_ == 3 ; 509b39c5158Smillert 510b39c5158Smillert my $db = shift ; 511b39c5158Smillert my ($origkey, $value_wanted) = @_ ; 512b39c5158Smillert my ($key, $value) = ($origkey, 0); 513b39c5158Smillert my ($status) = 0 ; 514b39c5158Smillert 515b39c5158Smillert for ($status = $db->seq($key, $value, R_CURSOR() ) ; 516b39c5158Smillert $status == 0 ; 517b39c5158Smillert $status = $db->seq($key, $value, R_NEXT() ) ) { 518b39c5158Smillert 519b39c5158Smillert return 0 if $key eq $origkey and $value eq $value_wanted ; 520b39c5158Smillert } 521b39c5158Smillert 522b39c5158Smillert return $status ; 523b39c5158Smillert} 524b39c5158Smillert 525b39c5158Smillertsub del_dup 526b39c5158Smillert{ 527b39c5158Smillert croak "Usage: \$db->del_dup(key,value)\n" 528b39c5158Smillert unless @_ == 3 ; 529b39c5158Smillert 530b39c5158Smillert my $db = shift ; 531b39c5158Smillert my ($key, $value) = @_ ; 532b39c5158Smillert my ($status) = $db->find_dup($key, $value) ; 533b39c5158Smillert return $status if $status != 0 ; 534b39c5158Smillert 535b39c5158Smillert $status = $db->del($key, R_CURSOR() ) ; 536b39c5158Smillert return $status ; 537b39c5158Smillert} 538b39c5158Smillert 539b39c5158Smillertsub get_dup 540b39c5158Smillert{ 541b39c5158Smillert croak "Usage: \$db->get_dup(key [,flag])\n" 542b39c5158Smillert unless @_ == 2 or @_ == 3 ; 543b39c5158Smillert 544b39c5158Smillert my $db = shift ; 545b39c5158Smillert my $key = shift ; 546b39c5158Smillert my $flag = shift ; 547b39c5158Smillert my $value = 0 ; 548b39c5158Smillert my $origkey = $key ; 549b39c5158Smillert my $wantarray = wantarray ; 550b39c5158Smillert my %values = () ; 551b39c5158Smillert my @values = () ; 552b39c5158Smillert my $counter = 0 ; 553b39c5158Smillert my $status = 0 ; 554b39c5158Smillert 555b39c5158Smillert # iterate through the database until either EOF ($status == 0) 556b39c5158Smillert # or a different key is encountered ($key ne $origkey). 557b39c5158Smillert for ($status = $db->seq($key, $value, R_CURSOR()) ; 558b39c5158Smillert $status == 0 and $key eq $origkey ; 559b39c5158Smillert $status = $db->seq($key, $value, R_NEXT()) ) { 560b39c5158Smillert 561b39c5158Smillert # save the value or count number of matches 562b39c5158Smillert if ($wantarray) { 563b39c5158Smillert if ($flag) 564b39c5158Smillert { ++ $values{$value} } 565b39c5158Smillert else 566b39c5158Smillert { push (@values, $value) } 567b39c5158Smillert } 568b39c5158Smillert else 569b39c5158Smillert { ++ $counter } 570b39c5158Smillert 571b39c5158Smillert } 572b39c5158Smillert 573b39c5158Smillert return ($wantarray ? ($flag ? %values : @values) : $counter) ; 574b39c5158Smillert} 575b39c5158Smillert 576b39c5158Smillert 577898184e3Ssthensub STORABLE_freeze 578898184e3Ssthen{ 579898184e3Ssthen my $type = ref shift; 580898184e3Ssthen croak "Cannot freeze $type object\n"; 581898184e3Ssthen} 582898184e3Ssthen 583898184e3Ssthensub STORABLE_thaw 584898184e3Ssthen{ 585898184e3Ssthen my $type = ref shift; 586898184e3Ssthen croak "Cannot thaw $type object\n"; 587898184e3Ssthen} 588898184e3Ssthen 589898184e3Ssthen 590898184e3Ssthen 591b39c5158Smillert1; 592b39c5158Smillert__END__ 593b39c5158Smillert 594b39c5158Smillert=head1 NAME 595b39c5158Smillert 596b39c5158SmillertDB_File - Perl5 access to Berkeley DB version 1.x 597b39c5158Smillert 598b39c5158Smillert=head1 SYNOPSIS 599b39c5158Smillert 600b39c5158Smillert use DB_File; 601b39c5158Smillert 602b39c5158Smillert [$X =] tie %hash, 'DB_File', [$filename, $flags, $mode, $DB_HASH] ; 603b39c5158Smillert [$X =] tie %hash, 'DB_File', $filename, $flags, $mode, $DB_BTREE ; 604b39c5158Smillert [$X =] tie @array, 'DB_File', $filename, $flags, $mode, $DB_RECNO ; 605b39c5158Smillert 606b39c5158Smillert $status = $X->del($key [, $flags]) ; 607b39c5158Smillert $status = $X->put($key, $value [, $flags]) ; 608b39c5158Smillert $status = $X->get($key, $value [, $flags]) ; 609b39c5158Smillert $status = $X->seq($key, $value, $flags) ; 610b39c5158Smillert $status = $X->sync([$flags]) ; 611b39c5158Smillert $status = $X->fd ; 612b39c5158Smillert 613b39c5158Smillert # BTREE only 614b39c5158Smillert $count = $X->get_dup($key) ; 615b39c5158Smillert @list = $X->get_dup($key) ; 616b39c5158Smillert %list = $X->get_dup($key, 1) ; 617b39c5158Smillert $status = $X->find_dup($key, $value) ; 618b39c5158Smillert $status = $X->del_dup($key, $value) ; 619b39c5158Smillert 620b39c5158Smillert # RECNO only 621b39c5158Smillert $a = $X->length; 622b39c5158Smillert $a = $X->pop ; 623b39c5158Smillert $X->push(list); 624b39c5158Smillert $a = $X->shift; 625b39c5158Smillert $X->unshift(list); 626b39c5158Smillert @r = $X->splice(offset, length, elements); 627b39c5158Smillert 628b39c5158Smillert # DBM Filters 629b39c5158Smillert $old_filter = $db->filter_store_key ( sub { ... } ) ; 630b39c5158Smillert $old_filter = $db->filter_store_value( sub { ... } ) ; 631b39c5158Smillert $old_filter = $db->filter_fetch_key ( sub { ... } ) ; 632b39c5158Smillert $old_filter = $db->filter_fetch_value( sub { ... } ) ; 633b39c5158Smillert 634b39c5158Smillert untie %hash ; 635b39c5158Smillert untie @array ; 636b39c5158Smillert 637b39c5158Smillert=head1 DESCRIPTION 638b39c5158Smillert 639b39c5158SmillertB<DB_File> is a module which allows Perl programs to make use of the 640b39c5158Smillertfacilities provided by Berkeley DB version 1.x (if you have a newer 641b39c5158Smillertversion of DB, see L<Using DB_File with Berkeley DB version 2 or greater>). 642b39c5158SmillertIt is assumed that you have a copy of the Berkeley DB manual pages at 643b39c5158Smillerthand when reading this documentation. The interface defined here 644b39c5158Smillertmirrors the Berkeley DB interface closely. 645b39c5158Smillert 646b39c5158SmillertBerkeley DB is a C library which provides a consistent interface to a 647b39c5158Smillertnumber of database formats. B<DB_File> provides an interface to all 648b39c5158Smillertthree of the database types currently supported by Berkeley DB. 649b39c5158Smillert 650b39c5158SmillertThe file types are: 651b39c5158Smillert 652b39c5158Smillert=over 5 653b39c5158Smillert 654b39c5158Smillert=item B<DB_HASH> 655b39c5158Smillert 656b39c5158SmillertThis database type allows arbitrary key/value pairs to be stored in data 657b39c5158Smillertfiles. This is equivalent to the functionality provided by other 658b39c5158Smillerthashing packages like DBM, NDBM, ODBM, GDBM, and SDBM. Remember though, 659b39c5158Smillertthe files created using DB_HASH are not compatible with any of the 660b39c5158Smillertother packages mentioned. 661b39c5158Smillert 662b39c5158SmillertA default hashing algorithm, which will be adequate for most 663b39c5158Smillertapplications, is built into Berkeley DB. If you do need to use your own 664b39c5158Smillerthashing algorithm it is possible to write your own in Perl and have 665b39c5158SmillertB<DB_File> use it instead. 666b39c5158Smillert 667b39c5158Smillert=item B<DB_BTREE> 668b39c5158Smillert 669b39c5158SmillertThe btree format allows arbitrary key/value pairs to be stored in a 670b39c5158Smillertsorted, balanced binary tree. 671b39c5158Smillert 672b39c5158SmillertAs with the DB_HASH format, it is possible to provide a user defined 673b39c5158SmillertPerl routine to perform the comparison of keys. By default, though, the 674b39c5158Smillertkeys are stored in lexical order. 675b39c5158Smillert 676b39c5158Smillert=item B<DB_RECNO> 677b39c5158Smillert 678b39c5158SmillertDB_RECNO allows both fixed-length and variable-length flat text files 679b39c5158Smillertto be manipulated using the same key/value pair interface as in DB_HASH 680b39c5158Smillertand DB_BTREE. In this case the key will consist of a record (line) 681b39c5158Smillertnumber. 682b39c5158Smillert 683b39c5158Smillert=back 684b39c5158Smillert 685b39c5158Smillert=head2 Using DB_File with Berkeley DB version 2 or greater 686b39c5158Smillert 687b39c5158SmillertAlthough B<DB_File> is intended to be used with Berkeley DB version 1, 688b39c5158Smillertit can also be used with version 2, 3 or 4. In this case the interface is 689b39c5158Smillertlimited to the functionality provided by Berkeley DB 1.x. Anywhere the 690b39c5158Smillertversion 2 or greater interface differs, B<DB_File> arranges for it to work 691b39c5158Smillertlike version 1. This feature allows B<DB_File> scripts that were built 692b39c5158Smillertwith version 1 to be migrated to version 2 or greater without any changes. 693b39c5158Smillert 694b39c5158SmillertIf you want to make use of the new features available in Berkeley DB 69556d68f1eSafresh12.x or greater, use the Perl module L<BerkeleyDB|https://metacpan.org/pod/BerkeleyDB> instead. 696b39c5158Smillert 697b39c5158SmillertB<Note:> The database file format has changed multiple times in Berkeley 698b39c5158SmillertDB version 2, 3 and 4. If you cannot recreate your databases, you 699b39c5158Smillertmust dump any existing databases with either the C<db_dump> or the 700b39c5158SmillertC<db_dump185> utility that comes with Berkeley DB. 701b39c5158SmillertOnce you have rebuilt DB_File to use Berkeley DB version 2 or greater, 702b39c5158Smillertyour databases can be recreated using C<db_load>. Refer to the Berkeley DB 703b39c5158Smillertdocumentation for further details. 704b39c5158Smillert 705b39c5158SmillertPlease read L<"COPYRIGHT"> before using version 2.x or greater of Berkeley 706b39c5158SmillertDB with DB_File. 707b39c5158Smillert 708b39c5158Smillert=head2 Interface to Berkeley DB 709b39c5158Smillert 710b39c5158SmillertB<DB_File> allows access to Berkeley DB files using the tie() mechanism 711b39c5158Smillertin Perl 5 (for full details, see L<perlfunc/tie()>). This facility 712b39c5158Smillertallows B<DB_File> to access Berkeley DB files using either an 713b39c5158Smillertassociative array (for DB_HASH & DB_BTREE file types) or an ordinary 714b39c5158Smillertarray (for the DB_RECNO file type). 715b39c5158Smillert 716b39c5158SmillertIn addition to the tie() interface, it is also possible to access most 717b39c5158Smillertof the functions provided in the Berkeley DB API directly. 718b39c5158SmillertSee L<THE API INTERFACE>. 719b39c5158Smillert 720b39c5158Smillert=head2 Opening a Berkeley DB Database File 721b39c5158Smillert 722b39c5158SmillertBerkeley DB uses the function dbopen() to open or create a database. 723b39c5158SmillertHere is the C prototype for dbopen(): 724b39c5158Smillert 725b39c5158Smillert DB* 726b39c5158Smillert dbopen (const char * file, int flags, int mode, 727b39c5158Smillert DBTYPE type, const void * openinfo) 728b39c5158Smillert 729b39c5158SmillertThe parameter C<type> is an enumeration which specifies which of the 3 730b39c5158Smillertinterface methods (DB_HASH, DB_BTREE or DB_RECNO) is to be used. 731b39c5158SmillertDepending on which of these is actually chosen, the final parameter, 732b39c5158SmillertI<openinfo> points to a data structure which allows tailoring of the 733b39c5158Smillertspecific interface method. 734b39c5158Smillert 735b39c5158SmillertThis interface is handled slightly differently in B<DB_File>. Here is 736b39c5158Smillertan equivalent call using B<DB_File>: 737b39c5158Smillert 738b39c5158Smillert tie %array, 'DB_File', $filename, $flags, $mode, $DB_HASH ; 739b39c5158Smillert 740b39c5158SmillertThe C<filename>, C<flags> and C<mode> parameters are the direct 741b39c5158Smillertequivalent of their dbopen() counterparts. The final parameter $DB_HASH 742b39c5158Smillertperforms the function of both the C<type> and C<openinfo> parameters in 743b39c5158Smillertdbopen(). 744b39c5158Smillert 745b39c5158SmillertIn the example above $DB_HASH is actually a pre-defined reference to a 746b39c5158Smillerthash object. B<DB_File> has three of these pre-defined references. 747b39c5158SmillertApart from $DB_HASH, there is also $DB_BTREE and $DB_RECNO. 748b39c5158Smillert 749b39c5158SmillertThe keys allowed in each of these pre-defined references is limited to 750b39c5158Smillertthe names used in the equivalent C structure. So, for example, the 751b39c5158Smillert$DB_HASH reference will only allow keys called C<bsize>, C<cachesize>, 752b39c5158SmillertC<ffactor>, C<hash>, C<lorder> and C<nelem>. 753b39c5158Smillert 754b39c5158SmillertTo change one of these elements, just assign to it like this: 755b39c5158Smillert 756b39c5158Smillert $DB_HASH->{'cachesize'} = 10000 ; 757b39c5158Smillert 758b39c5158SmillertThe three predefined variables $DB_HASH, $DB_BTREE and $DB_RECNO are 759b39c5158Smillertusually adequate for most applications. If you do need to create extra 760b39c5158Smillertinstances of these objects, constructors are available for each file 761b39c5158Smillerttype. 762b39c5158Smillert 763b39c5158SmillertHere are examples of the constructors and the valid options available 764b39c5158Smillertfor DB_HASH, DB_BTREE and DB_RECNO respectively. 765b39c5158Smillert 766eac174f2Safresh1 $a = DB_File::HASHINFO->new(); 767b39c5158Smillert $a->{'bsize'} ; 768b39c5158Smillert $a->{'cachesize'} ; 769b39c5158Smillert $a->{'ffactor'}; 770b39c5158Smillert $a->{'hash'} ; 771b39c5158Smillert $a->{'lorder'} ; 772b39c5158Smillert $a->{'nelem'} ; 773b39c5158Smillert 774eac174f2Safresh1 $b = DB_File::BTREEINFO->new(); 775b39c5158Smillert $b->{'flags'} ; 776b39c5158Smillert $b->{'cachesize'} ; 777b39c5158Smillert $b->{'maxkeypage'} ; 778b39c5158Smillert $b->{'minkeypage'} ; 779b39c5158Smillert $b->{'psize'} ; 780b39c5158Smillert $b->{'compare'} ; 781b39c5158Smillert $b->{'prefix'} ; 782b39c5158Smillert $b->{'lorder'} ; 783b39c5158Smillert 784eac174f2Safresh1 $c = DB_File::RECNOINFO->new(); 785b39c5158Smillert $c->{'bval'} ; 786b39c5158Smillert $c->{'cachesize'} ; 787b39c5158Smillert $c->{'psize'} ; 788b39c5158Smillert $c->{'flags'} ; 789b39c5158Smillert $c->{'lorder'} ; 790b39c5158Smillert $c->{'reclen'} ; 791b39c5158Smillert $c->{'bfname'} ; 792b39c5158Smillert 793b39c5158SmillertThe values stored in the hashes above are mostly the direct equivalent 794b39c5158Smillertof their C counterpart. Like their C counterparts, all are set to a 795b39c5158Smillertdefault values - that means you don't have to set I<all> of the 796b39c5158Smillertvalues when you only want to change one. Here is an example: 797b39c5158Smillert 798eac174f2Safresh1 $a = DB_File::HASHINFO->new(); 799b39c5158Smillert $a->{'cachesize'} = 12345 ; 800b39c5158Smillert tie %y, 'DB_File', "filename", $flags, 0777, $a ; 801b39c5158Smillert 802b39c5158SmillertA few of the options need extra discussion here. When used, the C 803b39c5158Smillertequivalent of the keys C<hash>, C<compare> and C<prefix> store pointers 804b39c5158Smillertto C functions. In B<DB_File> these keys are used to store references 805b39c5158Smillertto Perl subs. Below are templates for each of the subs: 806b39c5158Smillert 807b39c5158Smillert sub hash 808b39c5158Smillert { 809b39c5158Smillert my ($data) = @_ ; 810b39c5158Smillert ... 811b39c5158Smillert # return the hash value for $data 812b39c5158Smillert return $hash ; 813b39c5158Smillert } 814b39c5158Smillert 815b39c5158Smillert sub compare 816b39c5158Smillert { 817b39c5158Smillert my ($key, $key2) = @_ ; 818b39c5158Smillert ... 819b39c5158Smillert # return 0 if $key1 eq $key2 820b39c5158Smillert # -1 if $key1 lt $key2 821b39c5158Smillert # 1 if $key1 gt $key2 822b39c5158Smillert return (-1 , 0 or 1) ; 823b39c5158Smillert } 824b39c5158Smillert 825b39c5158Smillert sub prefix 826b39c5158Smillert { 827b39c5158Smillert my ($key, $key2) = @_ ; 828b39c5158Smillert ... 829b39c5158Smillert # return number of bytes of $key2 which are 830b39c5158Smillert # necessary to determine that it is greater than $key1 831b39c5158Smillert return $bytes ; 832b39c5158Smillert } 833b39c5158Smillert 834b39c5158SmillertSee L<Changing the BTREE sort order> for an example of using the 835b39c5158SmillertC<compare> template. 836b39c5158Smillert 837b39c5158SmillertIf you are using the DB_RECNO interface and you intend making use of 838b39c5158SmillertC<bval>, you should check out L<The 'bval' Option>. 839b39c5158Smillert 840b39c5158Smillert=head2 Default Parameters 841b39c5158Smillert 842b39c5158SmillertIt is possible to omit some or all of the final 4 parameters in the 843b39c5158Smillertcall to C<tie> and let them take default values. As DB_HASH is the most 844b39c5158Smillertcommon file format used, the call: 845b39c5158Smillert 846b39c5158Smillert tie %A, "DB_File", "filename" ; 847b39c5158Smillert 848b39c5158Smillertis equivalent to: 849b39c5158Smillert 850b39c5158Smillert tie %A, "DB_File", "filename", O_CREAT|O_RDWR, 0666, $DB_HASH ; 851b39c5158Smillert 852b39c5158SmillertIt is also possible to omit the filename parameter as well, so the 853b39c5158Smillertcall: 854b39c5158Smillert 855b39c5158Smillert tie %A, "DB_File" ; 856b39c5158Smillert 857b39c5158Smillertis equivalent to: 858b39c5158Smillert 859b39c5158Smillert tie %A, "DB_File", undef, O_CREAT|O_RDWR, 0666, $DB_HASH ; 860b39c5158Smillert 861b39c5158SmillertSee L<In Memory Databases> for a discussion on the use of C<undef> 862b39c5158Smillertin place of a filename. 863b39c5158Smillert 864b39c5158Smillert=head2 In Memory Databases 865b39c5158Smillert 866b39c5158SmillertBerkeley DB allows the creation of in-memory databases by using NULL 867b39c5158Smillert(that is, a C<(char *)0> in C) in place of the filename. B<DB_File> 868b39c5158Smillertuses C<undef> instead of NULL to provide this functionality. 869b39c5158Smillert 870b39c5158Smillert=head1 DB_HASH 871b39c5158Smillert 872b39c5158SmillertThe DB_HASH file format is probably the most commonly used of the three 873b39c5158Smillertfile formats that B<DB_File> supports. It is also very straightforward 874b39c5158Smillertto use. 875b39c5158Smillert 876b39c5158Smillert=head2 A Simple Example 877b39c5158Smillert 878b39c5158SmillertThis example shows how to create a database, add key/value pairs to the 879b39c5158Smillertdatabase, delete keys/value pairs and finally how to enumerate the 880b39c5158Smillertcontents of the database. 881b39c5158Smillert 882b39c5158Smillert use warnings ; 883b39c5158Smillert use strict ; 884b39c5158Smillert use DB_File ; 885b39c5158Smillert our (%h, $k, $v) ; 886b39c5158Smillert 887b39c5158Smillert unlink "fruit" ; 888b39c5158Smillert tie %h, "DB_File", "fruit", O_RDWR|O_CREAT, 0666, $DB_HASH 889b39c5158Smillert or die "Cannot open file 'fruit': $!\n"; 890b39c5158Smillert 891b39c5158Smillert # Add a few key/value pairs to the file 892b39c5158Smillert $h{"apple"} = "red" ; 893b39c5158Smillert $h{"orange"} = "orange" ; 894b39c5158Smillert $h{"banana"} = "yellow" ; 895b39c5158Smillert $h{"tomato"} = "red" ; 896b39c5158Smillert 897b39c5158Smillert # Check for existence of a key 898b39c5158Smillert print "Banana Exists\n\n" if $h{"banana"} ; 899b39c5158Smillert 900b39c5158Smillert # Delete a key/value pair. 901b39c5158Smillert delete $h{"apple"} ; 902b39c5158Smillert 903b39c5158Smillert # print the contents of the file 904b39c5158Smillert while (($k, $v) = each %h) 905b39c5158Smillert { print "$k -> $v\n" } 906b39c5158Smillert 907b39c5158Smillert untie %h ; 908b39c5158Smillert 909b39c5158Smillerthere is the output: 910b39c5158Smillert 911b39c5158Smillert Banana Exists 912b39c5158Smillert 913b39c5158Smillert orange -> orange 914b39c5158Smillert tomato -> red 915b39c5158Smillert banana -> yellow 916b39c5158Smillert 917b39c5158SmillertNote that the like ordinary associative arrays, the order of the keys 918b39c5158Smillertretrieved is in an apparently random order. 919b39c5158Smillert 920b39c5158Smillert=head1 DB_BTREE 921b39c5158Smillert 922b39c5158SmillertThe DB_BTREE format is useful when you want to store data in a given 923b39c5158Smillertorder. By default the keys will be stored in lexical order, but as you 924b39c5158Smillertwill see from the example shown in the next section, it is very easy to 925b39c5158Smillertdefine your own sorting function. 926b39c5158Smillert 927b39c5158Smillert=head2 Changing the BTREE sort order 928b39c5158Smillert 929b39c5158SmillertThis script shows how to override the default sorting algorithm that 930b39c5158SmillertBTREE uses. Instead of using the normal lexical ordering, a case 931b39c5158Smillertinsensitive compare function will be used. 932b39c5158Smillert 933b39c5158Smillert use warnings ; 934b39c5158Smillert use strict ; 935b39c5158Smillert use DB_File ; 936b39c5158Smillert 937b39c5158Smillert my %h ; 938b39c5158Smillert 939b39c5158Smillert sub Compare 940b39c5158Smillert { 941b39c5158Smillert my ($key1, $key2) = @_ ; 942b39c5158Smillert "\L$key1" cmp "\L$key2" ; 943b39c5158Smillert } 944b39c5158Smillert 945b39c5158Smillert # specify the Perl sub that will do the comparison 946b39c5158Smillert $DB_BTREE->{'compare'} = \&Compare ; 947b39c5158Smillert 948b39c5158Smillert unlink "tree" ; 949b39c5158Smillert tie %h, "DB_File", "tree", O_RDWR|O_CREAT, 0666, $DB_BTREE 950b39c5158Smillert or die "Cannot open file 'tree': $!\n" ; 951b39c5158Smillert 952b39c5158Smillert # Add a key/value pair to the file 953b39c5158Smillert $h{'Wall'} = 'Larry' ; 954b39c5158Smillert $h{'Smith'} = 'John' ; 955b39c5158Smillert $h{'mouse'} = 'mickey' ; 956b39c5158Smillert $h{'duck'} = 'donald' ; 957b39c5158Smillert 958b39c5158Smillert # Delete 959b39c5158Smillert delete $h{"duck"} ; 960b39c5158Smillert 961b39c5158Smillert # Cycle through the keys printing them in order. 962b39c5158Smillert # Note it is not necessary to sort the keys as 963b39c5158Smillert # the btree will have kept them in order automatically. 964b39c5158Smillert foreach (keys %h) 965b39c5158Smillert { print "$_\n" } 966b39c5158Smillert 967b39c5158Smillert untie %h ; 968b39c5158Smillert 969b39c5158SmillertHere is the output from the code above. 970b39c5158Smillert 971b39c5158Smillert mouse 972b39c5158Smillert Smith 973b39c5158Smillert Wall 974b39c5158Smillert 975b39c5158SmillertThere are a few point to bear in mind if you want to change the 976b39c5158Smillertordering in a BTREE database: 977b39c5158Smillert 978b39c5158Smillert=over 5 979b39c5158Smillert 980b39c5158Smillert=item 1. 981b39c5158Smillert 982b39c5158SmillertThe new compare function must be specified when you create the database. 983b39c5158Smillert 984b39c5158Smillert=item 2. 985b39c5158Smillert 986b39c5158SmillertYou cannot change the ordering once the database has been created. Thus 987b39c5158Smillertyou must use the same compare function every time you access the 988b39c5158Smillertdatabase. 989b39c5158Smillert 990b39c5158Smillert=item 3 991b39c5158Smillert 992b39c5158SmillertDuplicate keys are entirely defined by the comparison function. 993b39c5158SmillertIn the case-insensitive example above, the keys: 'KEY' and 'key' 994b39c5158Smillertwould be considered duplicates, and assigning to the second one 995b39c5158Smillertwould overwrite the first. If duplicates are allowed for (with the 996b39c5158SmillertR_DUP flag discussed below), only a single copy of duplicate keys 997b39c5158Smillertis stored in the database --- so (again with example above) assigning 998b39c5158Smillertthree values to the keys: 'KEY', 'Key', and 'key' would leave just 999b39c5158Smillertthe first key: 'KEY' in the database with three values. For some 1000b39c5158Smillertsituations this results in information loss, so care should be taken 1001b39c5158Smillertto provide fully qualified comparison functions when necessary. 1002b39c5158SmillertFor example, the above comparison routine could be modified to 1003b39c5158Smillertadditionally compare case-sensitively if two keys are equal in the 1004b39c5158Smillertcase insensitive comparison: 1005b39c5158Smillert 1006b39c5158Smillert sub compare { 1007b39c5158Smillert my($key1, $key2) = @_; 1008b39c5158Smillert lc $key1 cmp lc $key2 || 1009b39c5158Smillert $key1 cmp $key2; 1010b39c5158Smillert } 1011b39c5158Smillert 1012b39c5158SmillertAnd now you will only have duplicates when the keys themselves 1013b39c5158Smillertare truly the same. (note: in versions of the db library prior to 1014b39c5158Smillertabout November 1996, such duplicate keys were retained so it was 1015b39c5158Smillertpossible to recover the original keys in sets of keys that 1016b39c5158Smillertcompared as equal). 1017b39c5158Smillert 1018b39c5158Smillert 1019b39c5158Smillert=back 1020b39c5158Smillert 1021b39c5158Smillert=head2 Handling Duplicate Keys 1022b39c5158Smillert 1023b39c5158SmillertThe BTREE file type optionally allows a single key to be associated 1024b39c5158Smillertwith an arbitrary number of values. This option is enabled by setting 1025b39c5158Smillertthe flags element of C<$DB_BTREE> to R_DUP when creating the database. 1026b39c5158Smillert 1027b39c5158SmillertThere are some difficulties in using the tied hash interface if you 1028b39c5158Smillertwant to manipulate a BTREE database with duplicate keys. Consider this 1029b39c5158Smillertcode: 1030b39c5158Smillert 1031b39c5158Smillert use warnings ; 1032b39c5158Smillert use strict ; 1033b39c5158Smillert use DB_File ; 1034b39c5158Smillert 1035b39c5158Smillert my ($filename, %h) ; 1036b39c5158Smillert 1037b39c5158Smillert $filename = "tree" ; 1038b39c5158Smillert unlink $filename ; 1039b39c5158Smillert 1040b39c5158Smillert # Enable duplicate records 1041b39c5158Smillert $DB_BTREE->{'flags'} = R_DUP ; 1042b39c5158Smillert 1043b39c5158Smillert tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0666, $DB_BTREE 1044b39c5158Smillert or die "Cannot open $filename: $!\n"; 1045b39c5158Smillert 1046b39c5158Smillert # Add some key/value pairs to the file 1047b39c5158Smillert $h{'Wall'} = 'Larry' ; 1048b39c5158Smillert $h{'Wall'} = 'Brick' ; # Note the duplicate key 1049b39c5158Smillert $h{'Wall'} = 'Brick' ; # Note the duplicate key and value 1050b39c5158Smillert $h{'Smith'} = 'John' ; 1051b39c5158Smillert $h{'mouse'} = 'mickey' ; 1052b39c5158Smillert 1053b39c5158Smillert # iterate through the associative array 1054b39c5158Smillert # and print each key/value pair. 1055b39c5158Smillert foreach (sort keys %h) 1056b39c5158Smillert { print "$_ -> $h{$_}\n" } 1057b39c5158Smillert 1058b39c5158Smillert untie %h ; 1059b39c5158Smillert 1060b39c5158SmillertHere is the output: 1061b39c5158Smillert 1062b39c5158Smillert Smith -> John 1063b39c5158Smillert Wall -> Larry 1064b39c5158Smillert Wall -> Larry 1065b39c5158Smillert Wall -> Larry 1066b39c5158Smillert mouse -> mickey 1067b39c5158Smillert 1068b39c5158SmillertAs you can see 3 records have been successfully created with key C<Wall> 1069b39c5158Smillert- the only thing is, when they are retrieved from the database they 1070b39c5158SmillertI<seem> to have the same value, namely C<Larry>. The problem is caused 1071b39c5158Smillertby the way that the associative array interface works. Basically, when 1072b39c5158Smillertthe associative array interface is used to fetch the value associated 1073b39c5158Smillertwith a given key, it will only ever retrieve the first value. 1074b39c5158Smillert 1075b39c5158SmillertAlthough it may not be immediately obvious from the code above, the 1076b39c5158Smillertassociative array interface can be used to write values with duplicate 1077b39c5158Smillertkeys, but it cannot be used to read them back from the database. 1078b39c5158Smillert 1079b39c5158SmillertThe way to get around this problem is to use the Berkeley DB API method 1080b39c5158Smillertcalled C<seq>. This method allows sequential access to key/value 1081b39c5158Smillertpairs. See L<THE API INTERFACE> for details of both the C<seq> method 1082b39c5158Smillertand the API in general. 1083b39c5158Smillert 1084b39c5158SmillertHere is the script above rewritten using the C<seq> API method. 1085b39c5158Smillert 1086b39c5158Smillert use warnings ; 1087b39c5158Smillert use strict ; 1088b39c5158Smillert use DB_File ; 1089b39c5158Smillert 1090b39c5158Smillert my ($filename, $x, %h, $status, $key, $value) ; 1091b39c5158Smillert 1092b39c5158Smillert $filename = "tree" ; 1093b39c5158Smillert unlink $filename ; 1094b39c5158Smillert 1095b39c5158Smillert # Enable duplicate records 1096b39c5158Smillert $DB_BTREE->{'flags'} = R_DUP ; 1097b39c5158Smillert 1098b39c5158Smillert $x = tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0666, $DB_BTREE 1099b39c5158Smillert or die "Cannot open $filename: $!\n"; 1100b39c5158Smillert 1101b39c5158Smillert # Add some key/value pairs to the file 1102b39c5158Smillert $h{'Wall'} = 'Larry' ; 1103b39c5158Smillert $h{'Wall'} = 'Brick' ; # Note the duplicate key 1104b39c5158Smillert $h{'Wall'} = 'Brick' ; # Note the duplicate key and value 1105b39c5158Smillert $h{'Smith'} = 'John' ; 1106b39c5158Smillert $h{'mouse'} = 'mickey' ; 1107b39c5158Smillert 1108b39c5158Smillert # iterate through the btree using seq 1109b39c5158Smillert # and print each key/value pair. 1110b39c5158Smillert $key = $value = 0 ; 1111b39c5158Smillert for ($status = $x->seq($key, $value, R_FIRST) ; 1112b39c5158Smillert $status == 0 ; 1113b39c5158Smillert $status = $x->seq($key, $value, R_NEXT) ) 1114b39c5158Smillert { print "$key -> $value\n" } 1115b39c5158Smillert 1116b39c5158Smillert undef $x ; 1117b39c5158Smillert untie %h ; 1118b39c5158Smillert 1119b39c5158Smillertthat prints: 1120b39c5158Smillert 1121b39c5158Smillert Smith -> John 1122b39c5158Smillert Wall -> Brick 1123b39c5158Smillert Wall -> Brick 1124b39c5158Smillert Wall -> Larry 1125b39c5158Smillert mouse -> mickey 1126b39c5158Smillert 1127b39c5158SmillertThis time we have got all the key/value pairs, including the multiple 1128b39c5158Smillertvalues associated with the key C<Wall>. 1129b39c5158Smillert 1130b39c5158SmillertTo make life easier when dealing with duplicate keys, B<DB_File> comes with 1131b39c5158Smillerta few utility methods. 1132b39c5158Smillert 1133b39c5158Smillert=head2 The get_dup() Method 1134b39c5158Smillert 1135b39c5158SmillertThe C<get_dup> method assists in 1136b39c5158Smillertreading duplicate values from BTREE databases. The method can take the 1137b39c5158Smillertfollowing forms: 1138b39c5158Smillert 1139b39c5158Smillert $count = $x->get_dup($key) ; 1140b39c5158Smillert @list = $x->get_dup($key) ; 1141b39c5158Smillert %list = $x->get_dup($key, 1) ; 1142b39c5158Smillert 1143b39c5158SmillertIn a scalar context the method returns the number of values associated 1144b39c5158Smillertwith the key, C<$key>. 1145b39c5158Smillert 1146b39c5158SmillertIn list context, it returns all the values which match C<$key>. Note 1147b39c5158Smillertthat the values will be returned in an apparently random order. 1148b39c5158Smillert 1149b39c5158SmillertIn list context, if the second parameter is present and evaluates 1150b39c5158SmillertTRUE, the method returns an associative array. The keys of the 1151b39c5158Smillertassociative array correspond to the values that matched in the BTREE 1152b39c5158Smillertand the values of the array are a count of the number of times that 1153b39c5158Smillertparticular value occurred in the BTREE. 1154b39c5158Smillert 1155b39c5158SmillertSo assuming the database created above, we can use C<get_dup> like 1156b39c5158Smillertthis: 1157b39c5158Smillert 1158b39c5158Smillert use warnings ; 1159b39c5158Smillert use strict ; 1160b39c5158Smillert use DB_File ; 1161b39c5158Smillert 1162b39c5158Smillert my ($filename, $x, %h) ; 1163b39c5158Smillert 1164b39c5158Smillert $filename = "tree" ; 1165b39c5158Smillert 1166b39c5158Smillert # Enable duplicate records 1167b39c5158Smillert $DB_BTREE->{'flags'} = R_DUP ; 1168b39c5158Smillert 1169b39c5158Smillert $x = tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0666, $DB_BTREE 1170b39c5158Smillert or die "Cannot open $filename: $!\n"; 1171b39c5158Smillert 1172b39c5158Smillert my $cnt = $x->get_dup("Wall") ; 1173b39c5158Smillert print "Wall occurred $cnt times\n" ; 1174b39c5158Smillert 1175b39c5158Smillert my %hash = $x->get_dup("Wall", 1) ; 1176b39c5158Smillert print "Larry is there\n" if $hash{'Larry'} ; 1177b39c5158Smillert print "There are $hash{'Brick'} Brick Walls\n" ; 1178b39c5158Smillert 1179b39c5158Smillert my @list = sort $x->get_dup("Wall") ; 1180b39c5158Smillert print "Wall => [@list]\n" ; 1181b39c5158Smillert 1182b39c5158Smillert @list = $x->get_dup("Smith") ; 1183b39c5158Smillert print "Smith => [@list]\n" ; 1184b39c5158Smillert 1185b39c5158Smillert @list = $x->get_dup("Dog") ; 1186b39c5158Smillert print "Dog => [@list]\n" ; 1187b39c5158Smillert 1188b39c5158Smillert 1189b39c5158Smillertand it will print: 1190b39c5158Smillert 1191b39c5158Smillert Wall occurred 3 times 1192b39c5158Smillert Larry is there 1193b39c5158Smillert There are 2 Brick Walls 1194b39c5158Smillert Wall => [Brick Brick Larry] 1195b39c5158Smillert Smith => [John] 1196b39c5158Smillert Dog => [] 1197b39c5158Smillert 1198b39c5158Smillert=head2 The find_dup() Method 1199b39c5158Smillert 1200b39c5158Smillert $status = $X->find_dup($key, $value) ; 1201b39c5158Smillert 1202b39c5158SmillertThis method checks for the existence of a specific key/value pair. If the 1203b39c5158Smillertpair exists, the cursor is left pointing to the pair and the method 1204b39c5158Smillertreturns 0. Otherwise the method returns a non-zero value. 1205b39c5158Smillert 1206b39c5158SmillertAssuming the database from the previous example: 1207b39c5158Smillert 1208b39c5158Smillert use warnings ; 1209b39c5158Smillert use strict ; 1210b39c5158Smillert use DB_File ; 1211b39c5158Smillert 1212b39c5158Smillert my ($filename, $x, %h, $found) ; 1213b39c5158Smillert 1214b39c5158Smillert $filename = "tree" ; 1215b39c5158Smillert 1216b39c5158Smillert # Enable duplicate records 1217b39c5158Smillert $DB_BTREE->{'flags'} = R_DUP ; 1218b39c5158Smillert 1219b39c5158Smillert $x = tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0666, $DB_BTREE 1220b39c5158Smillert or die "Cannot open $filename: $!\n"; 1221b39c5158Smillert 1222b39c5158Smillert $found = ( $x->find_dup("Wall", "Larry") == 0 ? "" : "not") ; 1223b39c5158Smillert print "Larry Wall is $found there\n" ; 1224b39c5158Smillert 1225b39c5158Smillert $found = ( $x->find_dup("Wall", "Harry") == 0 ? "" : "not") ; 1226b39c5158Smillert print "Harry Wall is $found there\n" ; 1227b39c5158Smillert 1228b39c5158Smillert undef $x ; 1229b39c5158Smillert untie %h ; 1230b39c5158Smillert 1231b39c5158Smillertprints this 1232b39c5158Smillert 1233b39c5158Smillert Larry Wall is there 1234b39c5158Smillert Harry Wall is not there 1235b39c5158Smillert 1236b39c5158Smillert 1237b39c5158Smillert=head2 The del_dup() Method 1238b39c5158Smillert 1239b39c5158Smillert $status = $X->del_dup($key, $value) ; 1240b39c5158Smillert 1241b39c5158SmillertThis method deletes a specific key/value pair. It returns 1242b39c5158Smillert0 if they exist and have been deleted successfully. 1243b39c5158SmillertOtherwise the method returns a non-zero value. 1244b39c5158Smillert 1245b39c5158SmillertAgain assuming the existence of the C<tree> database 1246b39c5158Smillert 1247b39c5158Smillert use warnings ; 1248b39c5158Smillert use strict ; 1249b39c5158Smillert use DB_File ; 1250b39c5158Smillert 1251b39c5158Smillert my ($filename, $x, %h, $found) ; 1252b39c5158Smillert 1253b39c5158Smillert $filename = "tree" ; 1254b39c5158Smillert 1255b39c5158Smillert # Enable duplicate records 1256b39c5158Smillert $DB_BTREE->{'flags'} = R_DUP ; 1257b39c5158Smillert 1258b39c5158Smillert $x = tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0666, $DB_BTREE 1259b39c5158Smillert or die "Cannot open $filename: $!\n"; 1260b39c5158Smillert 1261b39c5158Smillert $x->del_dup("Wall", "Larry") ; 1262b39c5158Smillert 1263b39c5158Smillert $found = ( $x->find_dup("Wall", "Larry") == 0 ? "" : "not") ; 1264b39c5158Smillert print "Larry Wall is $found there\n" ; 1265b39c5158Smillert 1266b39c5158Smillert undef $x ; 1267b39c5158Smillert untie %h ; 1268b39c5158Smillert 1269b39c5158Smillertprints this 1270b39c5158Smillert 1271b39c5158Smillert Larry Wall is not there 1272b39c5158Smillert 1273b39c5158Smillert=head2 Matching Partial Keys 1274b39c5158Smillert 1275b39c5158SmillertThe BTREE interface has a feature which allows partial keys to be 1276b39c5158Smillertmatched. This functionality is I<only> available when the C<seq> method 1277b39c5158Smillertis used along with the R_CURSOR flag. 1278b39c5158Smillert 1279b39c5158Smillert $x->seq($key, $value, R_CURSOR) ; 1280b39c5158Smillert 1281b39c5158SmillertHere is the relevant quote from the dbopen man page where it defines 1282b39c5158Smillertthe use of the R_CURSOR flag with seq: 1283b39c5158Smillert 1284b39c5158Smillert Note, for the DB_BTREE access method, the returned key is not 1285b39c5158Smillert necessarily an exact match for the specified key. The returned key 1286b39c5158Smillert is the smallest key greater than or equal to the specified key, 1287b39c5158Smillert permitting partial key matches and range searches. 1288b39c5158Smillert 1289b39c5158SmillertIn the example script below, the C<match> sub uses this feature to find 1290b39c5158Smillertand print the first matching key/value pair given a partial key. 1291b39c5158Smillert 1292b39c5158Smillert use warnings ; 1293b39c5158Smillert use strict ; 1294b39c5158Smillert use DB_File ; 1295b39c5158Smillert use Fcntl ; 1296b39c5158Smillert 1297b39c5158Smillert my ($filename, $x, %h, $st, $key, $value) ; 1298b39c5158Smillert 1299b39c5158Smillert sub match 1300b39c5158Smillert { 1301b39c5158Smillert my $key = shift ; 1302b39c5158Smillert my $value = 0; 1303b39c5158Smillert my $orig_key = $key ; 1304b39c5158Smillert $x->seq($key, $value, R_CURSOR) ; 1305b39c5158Smillert print "$orig_key\t-> $key\t-> $value\n" ; 1306b39c5158Smillert } 1307b39c5158Smillert 1308b39c5158Smillert $filename = "tree" ; 1309b39c5158Smillert unlink $filename ; 1310b39c5158Smillert 1311b39c5158Smillert $x = tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0666, $DB_BTREE 1312b39c5158Smillert or die "Cannot open $filename: $!\n"; 1313b39c5158Smillert 1314b39c5158Smillert # Add some key/value pairs to the file 1315b39c5158Smillert $h{'mouse'} = 'mickey' ; 1316b39c5158Smillert $h{'Wall'} = 'Larry' ; 1317b39c5158Smillert $h{'Walls'} = 'Brick' ; 1318b39c5158Smillert $h{'Smith'} = 'John' ; 1319b39c5158Smillert 1320b39c5158Smillert 1321b39c5158Smillert $key = $value = 0 ; 1322b39c5158Smillert print "IN ORDER\n" ; 1323b39c5158Smillert for ($st = $x->seq($key, $value, R_FIRST) ; 1324b39c5158Smillert $st == 0 ; 1325b39c5158Smillert $st = $x->seq($key, $value, R_NEXT) ) 1326b39c5158Smillert 1327b39c5158Smillert { print "$key -> $value\n" } 1328b39c5158Smillert 1329b39c5158Smillert print "\nPARTIAL MATCH\n" ; 1330b39c5158Smillert 1331b39c5158Smillert match "Wa" ; 1332b39c5158Smillert match "A" ; 1333b39c5158Smillert match "a" ; 1334b39c5158Smillert 1335b39c5158Smillert undef $x ; 1336b39c5158Smillert untie %h ; 1337b39c5158Smillert 1338b39c5158SmillertHere is the output: 1339b39c5158Smillert 1340b39c5158Smillert IN ORDER 1341b39c5158Smillert Smith -> John 1342b39c5158Smillert Wall -> Larry 1343b39c5158Smillert Walls -> Brick 1344b39c5158Smillert mouse -> mickey 1345b39c5158Smillert 1346b39c5158Smillert PARTIAL MATCH 1347b39c5158Smillert Wa -> Wall -> Larry 1348b39c5158Smillert A -> Smith -> John 1349b39c5158Smillert a -> mouse -> mickey 1350b39c5158Smillert 1351b39c5158Smillert=head1 DB_RECNO 1352b39c5158Smillert 1353b39c5158SmillertDB_RECNO provides an interface to flat text files. Both variable and 1354b39c5158Smillertfixed length records are supported. 1355b39c5158Smillert 1356b39c5158SmillertIn order to make RECNO more compatible with Perl, the array offset for 1357b39c5158Smillertall RECNO arrays begins at 0 rather than 1 as in Berkeley DB. 1358b39c5158Smillert 1359b39c5158SmillertAs with normal Perl arrays, a RECNO array can be accessed using 1360b39c5158Smillertnegative indexes. The index -1 refers to the last element of the array, 1361b39c5158Smillert-2 the second last, and so on. Attempting to access an element before 1362b39c5158Smillertthe start of the array will raise a fatal run-time error. 1363b39c5158Smillert 1364b39c5158Smillert=head2 The 'bval' Option 1365b39c5158Smillert 1366b39c5158SmillertThe operation of the bval option warrants some discussion. Here is the 1367b39c5158Smillertdefinition of bval from the Berkeley DB 1.85 recno manual page: 1368b39c5158Smillert 1369b39c5158Smillert The delimiting byte to be used to mark the end of a 1370b39c5158Smillert record for variable-length records, and the pad charac- 1371b39c5158Smillert ter for fixed-length records. If no value is speci- 1372b39c5158Smillert fied, newlines (``\n'') are used to mark the end of 1373b39c5158Smillert variable-length records and fixed-length records are 1374b39c5158Smillert padded with spaces. 1375b39c5158Smillert 1376b39c5158SmillertThe second sentence is wrong. In actual fact bval will only default to 1377b39c5158SmillertC<"\n"> when the openinfo parameter in dbopen is NULL. If a non-NULL 1378b39c5158Smillertopeninfo parameter is used at all, the value that happens to be in bval 1379b39c5158Smillertwill be used. That means you always have to specify bval when making 1380b39c5158Smillertuse of any of the options in the openinfo parameter. This documentation 1381b39c5158Smillerterror will be fixed in the next release of Berkeley DB. 1382b39c5158Smillert 1383b39c5158SmillertThat clarifies the situation with regards Berkeley DB itself. What 1384b39c5158Smillertabout B<DB_File>? Well, the behavior defined in the quote above is 1385b39c5158Smillertquite useful, so B<DB_File> conforms to it. 1386b39c5158Smillert 1387b39c5158SmillertThat means that you can specify other options (e.g. cachesize) and 1388b39c5158Smillertstill have bval default to C<"\n"> for variable length records, and 1389b39c5158Smillertspace for fixed length records. 1390b39c5158Smillert 1391b39c5158SmillertAlso note that the bval option only allows you to specify a single byte 1392b39c5158Smillertas a delimiter. 1393b39c5158Smillert 1394b39c5158Smillert=head2 A Simple Example 1395b39c5158Smillert 1396b39c5158SmillertHere is a simple example that uses RECNO (if you are using a version 1397b39c5158Smillertof Perl earlier than 5.004_57 this example won't work -- see 1398b39c5158SmillertL<Extra RECNO Methods> for a workaround). 1399b39c5158Smillert 1400b39c5158Smillert use warnings ; 1401b39c5158Smillert use strict ; 1402b39c5158Smillert use DB_File ; 1403b39c5158Smillert 1404b39c5158Smillert my $filename = "text" ; 1405b39c5158Smillert unlink $filename ; 1406b39c5158Smillert 1407b39c5158Smillert my @h ; 1408b39c5158Smillert tie @h, "DB_File", $filename, O_RDWR|O_CREAT, 0666, $DB_RECNO 1409b39c5158Smillert or die "Cannot open file 'text': $!\n" ; 1410b39c5158Smillert 1411b39c5158Smillert # Add a few key/value pairs to the file 1412b39c5158Smillert $h[0] = "orange" ; 1413b39c5158Smillert $h[1] = "blue" ; 1414b39c5158Smillert $h[2] = "yellow" ; 1415b39c5158Smillert 1416b39c5158Smillert push @h, "green", "black" ; 1417b39c5158Smillert 1418b39c5158Smillert my $elements = scalar @h ; 1419b39c5158Smillert print "The array contains $elements entries\n" ; 1420b39c5158Smillert 1421b39c5158Smillert my $last = pop @h ; 1422b39c5158Smillert print "popped $last\n" ; 1423b39c5158Smillert 1424b39c5158Smillert unshift @h, "white" ; 1425b39c5158Smillert my $first = shift @h ; 1426b39c5158Smillert print "shifted $first\n" ; 1427b39c5158Smillert 1428b39c5158Smillert # Check for existence of a key 1429b39c5158Smillert print "Element 1 Exists with value $h[1]\n" if $h[1] ; 1430b39c5158Smillert 1431b39c5158Smillert # use a negative index 1432b39c5158Smillert print "The last element is $h[-1]\n" ; 1433b39c5158Smillert print "The 2nd last element is $h[-2]\n" ; 1434b39c5158Smillert 1435b39c5158Smillert untie @h ; 1436b39c5158Smillert 1437b39c5158SmillertHere is the output from the script: 1438b39c5158Smillert 1439b39c5158Smillert The array contains 5 entries 1440b39c5158Smillert popped black 1441b39c5158Smillert shifted white 1442b39c5158Smillert Element 1 Exists with value blue 1443b39c5158Smillert The last element is green 1444b39c5158Smillert The 2nd last element is yellow 1445b39c5158Smillert 1446b39c5158Smillert=head2 Extra RECNO Methods 1447b39c5158Smillert 1448b39c5158SmillertIf you are using a version of Perl earlier than 5.004_57, the tied 1449b39c5158Smillertarray interface is quite limited. In the example script above 1450b39c5158SmillertC<push>, C<pop>, C<shift>, C<unshift> 1451b39c5158Smillertor determining the array length will not work with a tied array. 1452b39c5158Smillert 1453b39c5158SmillertTo make the interface more useful for older versions of Perl, a number 1454b39c5158Smillertof methods are supplied with B<DB_File> to simulate the missing array 1455b39c5158Smillertoperations. All these methods are accessed via the object returned from 1456b39c5158Smillertthe tie call. 1457b39c5158Smillert 1458b39c5158SmillertHere are the methods: 1459b39c5158Smillert 1460b39c5158Smillert=over 5 1461b39c5158Smillert 1462b39c5158Smillert=item B<$X-E<gt>push(list) ;> 1463b39c5158Smillert 1464b39c5158SmillertPushes the elements of C<list> to the end of the array. 1465b39c5158Smillert 1466b39c5158Smillert=item B<$value = $X-E<gt>pop ;> 1467b39c5158Smillert 1468b39c5158SmillertRemoves and returns the last element of the array. 1469b39c5158Smillert 1470b39c5158Smillert=item B<$X-E<gt>shift> 1471b39c5158Smillert 1472b39c5158SmillertRemoves and returns the first element of the array. 1473b39c5158Smillert 1474b39c5158Smillert=item B<$X-E<gt>unshift(list) ;> 1475b39c5158Smillert 1476b39c5158SmillertPushes the elements of C<list> to the start of the array. 1477b39c5158Smillert 1478b39c5158Smillert=item B<$X-E<gt>length> 1479b39c5158Smillert 1480b39c5158SmillertReturns the number of elements in the array. 1481b39c5158Smillert 1482b39c5158Smillert=item B<$X-E<gt>splice(offset, length, elements);> 1483b39c5158Smillert 1484b39c5158SmillertReturns a splice of the array. 1485b39c5158Smillert 1486b39c5158Smillert=back 1487b39c5158Smillert 1488b39c5158Smillert=head2 Another Example 1489b39c5158Smillert 1490b39c5158SmillertHere is a more complete example that makes use of some of the methods 1491b39c5158Smillertdescribed above. It also makes use of the API interface directly (see 1492b39c5158SmillertL<THE API INTERFACE>). 1493b39c5158Smillert 1494b39c5158Smillert use warnings ; 1495b39c5158Smillert use strict ; 1496b39c5158Smillert my (@h, $H, $file, $i) ; 1497b39c5158Smillert use DB_File ; 1498b39c5158Smillert use Fcntl ; 1499b39c5158Smillert 1500b39c5158Smillert $file = "text" ; 1501b39c5158Smillert 1502b39c5158Smillert unlink $file ; 1503b39c5158Smillert 1504b39c5158Smillert $H = tie @h, "DB_File", $file, O_RDWR|O_CREAT, 0666, $DB_RECNO 1505b39c5158Smillert or die "Cannot open file $file: $!\n" ; 1506b39c5158Smillert 1507b39c5158Smillert # first create a text file to play with 1508b39c5158Smillert $h[0] = "zero" ; 1509b39c5158Smillert $h[1] = "one" ; 1510b39c5158Smillert $h[2] = "two" ; 1511b39c5158Smillert $h[3] = "three" ; 1512b39c5158Smillert $h[4] = "four" ; 1513b39c5158Smillert 1514b39c5158Smillert 1515b39c5158Smillert # Print the records in order. 1516b39c5158Smillert # 1517b39c5158Smillert # The length method is needed here because evaluating a tied 1518b39c5158Smillert # array in a scalar context does not return the number of 1519b39c5158Smillert # elements in the array. 1520b39c5158Smillert 1521b39c5158Smillert print "\nORIGINAL\n" ; 1522b39c5158Smillert foreach $i (0 .. $H->length - 1) { 1523b39c5158Smillert print "$i: $h[$i]\n" ; 1524b39c5158Smillert } 1525b39c5158Smillert 1526b39c5158Smillert # use the push & pop methods 1527b39c5158Smillert $a = $H->pop ; 1528b39c5158Smillert $H->push("last") ; 1529b39c5158Smillert print "\nThe last record was [$a]\n" ; 1530b39c5158Smillert 1531b39c5158Smillert # and the shift & unshift methods 1532b39c5158Smillert $a = $H->shift ; 1533b39c5158Smillert $H->unshift("first") ; 1534b39c5158Smillert print "The first record was [$a]\n" ; 1535b39c5158Smillert 1536b39c5158Smillert # Use the API to add a new record after record 2. 1537b39c5158Smillert $i = 2 ; 1538b39c5158Smillert $H->put($i, "Newbie", R_IAFTER) ; 1539b39c5158Smillert 1540b39c5158Smillert # and a new record before record 1. 1541b39c5158Smillert $i = 1 ; 1542b39c5158Smillert $H->put($i, "New One", R_IBEFORE) ; 1543b39c5158Smillert 1544b39c5158Smillert # delete record 3 1545b39c5158Smillert $H->del(3) ; 1546b39c5158Smillert 1547b39c5158Smillert # now print the records in reverse order 1548b39c5158Smillert print "\nREVERSE\n" ; 1549b39c5158Smillert for ($i = $H->length - 1 ; $i >= 0 ; -- $i) 1550b39c5158Smillert { print "$i: $h[$i]\n" } 1551b39c5158Smillert 1552b39c5158Smillert # same again, but use the API functions instead 1553b39c5158Smillert print "\nREVERSE again\n" ; 1554b39c5158Smillert my ($s, $k, $v) = (0, 0, 0) ; 1555b39c5158Smillert for ($s = $H->seq($k, $v, R_LAST) ; 1556b39c5158Smillert $s == 0 ; 1557b39c5158Smillert $s = $H->seq($k, $v, R_PREV)) 1558b39c5158Smillert { print "$k: $v\n" } 1559b39c5158Smillert 1560b39c5158Smillert undef $H ; 1561b39c5158Smillert untie @h ; 1562b39c5158Smillert 1563b39c5158Smillertand this is what it outputs: 1564b39c5158Smillert 1565b39c5158Smillert ORIGINAL 1566b39c5158Smillert 0: zero 1567b39c5158Smillert 1: one 1568b39c5158Smillert 2: two 1569b39c5158Smillert 3: three 1570b39c5158Smillert 4: four 1571b39c5158Smillert 1572b39c5158Smillert The last record was [four] 1573b39c5158Smillert The first record was [zero] 1574b39c5158Smillert 1575b39c5158Smillert REVERSE 1576b39c5158Smillert 5: last 1577b39c5158Smillert 4: three 1578b39c5158Smillert 3: Newbie 1579b39c5158Smillert 2: one 1580b39c5158Smillert 1: New One 1581b39c5158Smillert 0: first 1582b39c5158Smillert 1583b39c5158Smillert REVERSE again 1584b39c5158Smillert 5: last 1585b39c5158Smillert 4: three 1586b39c5158Smillert 3: Newbie 1587b39c5158Smillert 2: one 1588b39c5158Smillert 1: New One 1589b39c5158Smillert 0: first 1590b39c5158Smillert 1591b39c5158SmillertNotes: 1592b39c5158Smillert 1593b39c5158Smillert=over 5 1594b39c5158Smillert 1595b39c5158Smillert=item 1. 1596b39c5158Smillert 1597b39c5158SmillertRather than iterating through the array, C<@h> like this: 1598b39c5158Smillert 1599b39c5158Smillert foreach $i (@h) 1600b39c5158Smillert 1601b39c5158Smillertit is necessary to use either this: 1602b39c5158Smillert 1603b39c5158Smillert foreach $i (0 .. $H->length - 1) 1604b39c5158Smillert 1605b39c5158Smillertor this: 1606b39c5158Smillert 1607b39c5158Smillert for ($a = $H->get($k, $v, R_FIRST) ; 1608b39c5158Smillert $a == 0 ; 1609b39c5158Smillert $a = $H->get($k, $v, R_NEXT) ) 1610b39c5158Smillert 1611b39c5158Smillert=item 2. 1612b39c5158Smillert 1613b39c5158SmillertNotice that both times the C<put> method was used the record index was 1614b39c5158Smillertspecified using a variable, C<$i>, rather than the literal value 1615b39c5158Smillertitself. This is because C<put> will return the record number of the 1616b39c5158Smillertinserted line via that parameter. 1617b39c5158Smillert 1618b39c5158Smillert=back 1619b39c5158Smillert 1620b39c5158Smillert=head1 THE API INTERFACE 1621b39c5158Smillert 1622b39c5158SmillertAs well as accessing Berkeley DB using a tied hash or array, it is also 1623b39c5158Smillertpossible to make direct use of most of the API functions defined in the 1624b39c5158SmillertBerkeley DB documentation. 1625b39c5158Smillert 1626b39c5158SmillertTo do this you need to store a copy of the object returned from the tie. 1627b39c5158Smillert 1628b39c5158Smillert $db = tie %hash, "DB_File", "filename" ; 1629b39c5158Smillert 1630b39c5158SmillertOnce you have done that, you can access the Berkeley DB API functions 1631b39c5158Smillertas B<DB_File> methods directly like this: 1632b39c5158Smillert 1633b39c5158Smillert $db->put($key, $value, R_NOOVERWRITE) ; 1634b39c5158Smillert 1635b39c5158SmillertB<Important:> If you have saved a copy of the object returned from 1636b39c5158SmillertC<tie>, the underlying database file will I<not> be closed until both 1637b39c5158Smillertthe tied variable is untied and all copies of the saved object are 1638b39c5158Smillertdestroyed. 1639b39c5158Smillert 1640b39c5158Smillert use DB_File ; 1641b39c5158Smillert $db = tie %hash, "DB_File", "filename" 1642b39c5158Smillert or die "Cannot tie filename: $!" ; 1643b39c5158Smillert ... 1644b39c5158Smillert undef $db ; 1645b39c5158Smillert untie %hash ; 1646b39c5158Smillert 1647b39c5158SmillertSee L<The untie() Gotcha> for more details. 1648b39c5158Smillert 1649b39c5158SmillertAll the functions defined in L<dbopen> are available except for 1650b39c5158Smillertclose() and dbopen() itself. The B<DB_File> method interface to the 1651b39c5158Smillertsupported functions have been implemented to mirror the way Berkeley DB 1652b39c5158Smillertworks whenever possible. In particular note that: 1653b39c5158Smillert 1654b39c5158Smillert=over 5 1655b39c5158Smillert 1656b39c5158Smillert=item * 1657b39c5158Smillert 1658b39c5158SmillertThe methods return a status value. All return 0 on success. 1659b39c5158SmillertAll return -1 to signify an error and set C<$!> to the exact 1660b39c5158Smillerterror code. The return code 1 generally (but not always) means that the 1661b39c5158Smillertkey specified did not exist in the database. 1662b39c5158Smillert 1663b39c5158SmillertOther return codes are defined. See below and in the Berkeley DB 1664b39c5158Smillertdocumentation for details. The Berkeley DB documentation should be used 1665b39c5158Smillertas the definitive source. 1666b39c5158Smillert 1667b39c5158Smillert=item * 1668b39c5158Smillert 1669b39c5158SmillertWhenever a Berkeley DB function returns data via one of its parameters, 1670b39c5158Smillertthe equivalent B<DB_File> method does exactly the same. 1671b39c5158Smillert 1672b39c5158Smillert=item * 1673b39c5158Smillert 1674b39c5158SmillertIf you are careful, it is possible to mix API calls with the tied 1675b39c5158Smillerthash/array interface in the same piece of code. Although only a few of 1676b39c5158Smillertthe methods used to implement the tied interface currently make use of 1677b39c5158Smillertthe cursor, you should always assume that the cursor has been changed 1678b39c5158Smillertany time the tied hash/array interface is used. As an example, this 1679b39c5158Smillertcode will probably not do what you expect: 1680b39c5158Smillert 1681b39c5158Smillert $X = tie %x, 'DB_File', $filename, O_RDWR|O_CREAT, 0777, $DB_BTREE 1682b39c5158Smillert or die "Cannot tie $filename: $!" ; 1683b39c5158Smillert 1684b39c5158Smillert # Get the first key/value pair and set the cursor 1685b39c5158Smillert $X->seq($key, $value, R_FIRST) ; 1686b39c5158Smillert 1687b39c5158Smillert # this line will modify the cursor 1688b39c5158Smillert $count = scalar keys %x ; 1689b39c5158Smillert 1690b39c5158Smillert # Get the second key/value pair. 1691b39c5158Smillert # oops, it didn't, it got the last key/value pair! 1692b39c5158Smillert $X->seq($key, $value, R_NEXT) ; 1693b39c5158Smillert 1694b39c5158SmillertThe code above can be rearranged to get around the problem, like this: 1695b39c5158Smillert 1696b39c5158Smillert $X = tie %x, 'DB_File', $filename, O_RDWR|O_CREAT, 0777, $DB_BTREE 1697b39c5158Smillert or die "Cannot tie $filename: $!" ; 1698b39c5158Smillert 1699b39c5158Smillert # this line will modify the cursor 1700b39c5158Smillert $count = scalar keys %x ; 1701b39c5158Smillert 1702b39c5158Smillert # Get the first key/value pair and set the cursor 1703b39c5158Smillert $X->seq($key, $value, R_FIRST) ; 1704b39c5158Smillert 1705b39c5158Smillert # Get the second key/value pair. 1706b39c5158Smillert # worked this time. 1707b39c5158Smillert $X->seq($key, $value, R_NEXT) ; 1708b39c5158Smillert 1709b39c5158Smillert=back 1710b39c5158Smillert 1711b39c5158SmillertAll the constants defined in L<dbopen> for use in the flags parameters 1712b39c5158Smillertin the methods defined below are also available. Refer to the Berkeley 1713b39c5158SmillertDB documentation for the precise meaning of the flags values. 1714b39c5158Smillert 1715b39c5158SmillertBelow is a list of the methods available. 1716b39c5158Smillert 1717b39c5158Smillert=over 5 1718b39c5158Smillert 1719b39c5158Smillert=item B<$status = $X-E<gt>get($key, $value [, $flags]) ;> 1720b39c5158Smillert 1721b39c5158SmillertGiven a key (C<$key>) this method reads the value associated with it 1722b39c5158Smillertfrom the database. The value read from the database is returned in the 1723b39c5158SmillertC<$value> parameter. 1724b39c5158Smillert 1725b39c5158SmillertIf the key does not exist the method returns 1. 1726b39c5158Smillert 1727b39c5158SmillertNo flags are currently defined for this method. 1728b39c5158Smillert 1729b39c5158Smillert=item B<$status = $X-E<gt>put($key, $value [, $flags]) ;> 1730b39c5158Smillert 1731b39c5158SmillertStores the key/value pair in the database. 1732b39c5158Smillert 1733b39c5158SmillertIf you use either the R_IAFTER or R_IBEFORE flags, the C<$key> parameter 1734b39c5158Smillertwill have the record number of the inserted key/value pair set. 1735b39c5158Smillert 1736b39c5158SmillertValid flags are R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE and 1737b39c5158SmillertR_SETCURSOR. 1738b39c5158Smillert 1739b39c5158Smillert=item B<$status = $X-E<gt>del($key [, $flags]) ;> 1740b39c5158Smillert 1741b39c5158SmillertRemoves all key/value pairs with key C<$key> from the database. 1742b39c5158Smillert 1743b39c5158SmillertA return code of 1 means that the requested key was not in the 1744b39c5158Smillertdatabase. 1745b39c5158Smillert 1746b39c5158SmillertR_CURSOR is the only valid flag at present. 1747b39c5158Smillert 1748b39c5158Smillert=item B<$status = $X-E<gt>fd ;> 1749b39c5158Smillert 1750b39c5158SmillertReturns the file descriptor for the underlying database. 1751b39c5158Smillert 1752b39c5158SmillertSee L<Locking: The Trouble with fd> for an explanation for why you should 1753b39c5158Smillertnot use C<fd> to lock your database. 1754b39c5158Smillert 1755b39c5158Smillert=item B<$status = $X-E<gt>seq($key, $value, $flags) ;> 1756b39c5158Smillert 1757b39c5158SmillertThis interface allows sequential retrieval from the database. See 1758b39c5158SmillertL<dbopen> for full details. 1759b39c5158Smillert 1760b39c5158SmillertBoth the C<$key> and C<$value> parameters will be set to the key/value 1761b39c5158Smillertpair read from the database. 1762b39c5158Smillert 1763b39c5158SmillertThe flags parameter is mandatory. The valid flag values are R_CURSOR, 1764b39c5158SmillertR_FIRST, R_LAST, R_NEXT and R_PREV. 1765b39c5158Smillert 1766b39c5158Smillert=item B<$status = $X-E<gt>sync([$flags]) ;> 1767b39c5158Smillert 1768b39c5158SmillertFlushes any cached buffers to disk. 1769b39c5158Smillert 1770b39c5158SmillertR_RECNOSYNC is the only valid flag at present. 1771b39c5158Smillert 1772b39c5158Smillert=back 1773b39c5158Smillert 1774b39c5158Smillert=head1 DBM FILTERS 1775b39c5158Smillert 17769f11ffb7Safresh1A DBM Filter is a piece of code that is be used when you I<always> want to 17779f11ffb7Safresh1make the same transformation to all keys and/or values in a DBM database. 17789f11ffb7Safresh1An example is when you need to encode your data in UTF-8 before writing to 17799f11ffb7Safresh1the database and then decode the UTF-8 when reading from the database file. 17809f11ffb7Safresh1 17819f11ffb7Safresh1There are two ways to use a DBM Filter. 17829f11ffb7Safresh1 17839f11ffb7Safresh1=over 5 17849f11ffb7Safresh1 17859f11ffb7Safresh1=item 1. 17869f11ffb7Safresh1 17879f11ffb7Safresh1Using the low-level API defined below. 17889f11ffb7Safresh1 17899f11ffb7Safresh1=item 2. 17909f11ffb7Safresh1 17919f11ffb7Safresh1Using the L<DBM_Filter> module. 17929f11ffb7Safresh1This module hides the complexity of the API defined below and comes 17939f11ffb7Safresh1with a number of "canned" filters that cover some of the common use-cases. 17949f11ffb7Safresh1 17959f11ffb7Safresh1=back 17969f11ffb7Safresh1 17979f11ffb7Safresh1Use of the L<DBM_Filter> module is recommended. 17989f11ffb7Safresh1 17999f11ffb7Safresh1=head2 DBM Filter Low-level API 1800b39c5158Smillert 1801b39c5158SmillertThere are four methods associated with DBM Filters. All work identically, 1802b39c5158Smillertand each is used to install (or uninstall) a single DBM Filter. Each 1803b39c5158Smillertexpects a single parameter, namely a reference to a sub. The only 1804b39c5158Smillertdifference between them is the place that the filter is installed. 1805b39c5158Smillert 1806b39c5158SmillertTo summarise: 1807b39c5158Smillert 1808b39c5158Smillert=over 5 1809b39c5158Smillert 1810b39c5158Smillert=item B<filter_store_key> 1811b39c5158Smillert 1812b39c5158SmillertIf a filter has been installed with this method, it will be invoked 1813b39c5158Smillertevery time you write a key to a DBM database. 1814b39c5158Smillert 1815b39c5158Smillert=item B<filter_store_value> 1816b39c5158Smillert 1817b39c5158SmillertIf a filter has been installed with this method, it will be invoked 1818b39c5158Smillertevery time you write a value to a DBM database. 1819b39c5158Smillert 1820b39c5158Smillert 1821b39c5158Smillert=item B<filter_fetch_key> 1822b39c5158Smillert 1823b39c5158SmillertIf a filter has been installed with this method, it will be invoked 1824b39c5158Smillertevery time you read a key from a DBM database. 1825b39c5158Smillert 1826b39c5158Smillert=item B<filter_fetch_value> 1827b39c5158Smillert 1828b39c5158SmillertIf a filter has been installed with this method, it will be invoked 1829b39c5158Smillertevery time you read a value from a DBM database. 1830b39c5158Smillert 1831b39c5158Smillert=back 1832b39c5158Smillert 1833b39c5158SmillertYou can use any combination of the methods, from none, to all four. 1834b39c5158Smillert 1835b39c5158SmillertAll filter methods return the existing filter, if present, or C<undef> 1836b39c5158Smillertin not. 1837b39c5158Smillert 1838b39c5158SmillertTo delete a filter pass C<undef> to it. 1839b39c5158Smillert 1840b39c5158Smillert=head2 The Filter 1841b39c5158Smillert 1842b39c5158SmillertWhen each filter is called by Perl, a local copy of C<$_> will contain 1843b39c5158Smillertthe key or value to be filtered. Filtering is achieved by modifying 1844b39c5158Smillertthe contents of C<$_>. The return code from the filter is ignored. 1845b39c5158Smillert 1846b39c5158Smillert=head2 An Example -- the NULL termination problem. 1847b39c5158Smillert 1848b39c5158SmillertConsider the following scenario. You have a DBM database 1849b39c5158Smillertthat you need to share with a third-party C application. The C application 1850b39c5158Smillertassumes that I<all> keys and values are NULL terminated. Unfortunately 1851b39c5158Smillertwhen Perl writes to DBM databases it doesn't use NULL termination, so 1852b39c5158Smillertyour Perl application will have to manage NULL termination itself. When 1853b39c5158Smillertyou write to the database you will have to use something like this: 1854b39c5158Smillert 1855b39c5158Smillert $hash{"$key\0"} = "$value\0" ; 1856b39c5158Smillert 1857b39c5158SmillertSimilarly the NULL needs to be taken into account when you are considering 1858b39c5158Smillertthe length of existing keys/values. 1859b39c5158Smillert 1860b39c5158SmillertIt would be much better if you could ignore the NULL terminations issue 1861b39c5158Smillertin the main application code and have a mechanism that automatically 1862b39c5158Smillertadded the terminating NULL to all keys and values whenever you write to 1863b39c5158Smillertthe database and have them removed when you read from the database. As I'm 1864b39c5158Smillertsure you have already guessed, this is a problem that DBM Filters can 1865b39c5158Smillertfix very easily. 1866b39c5158Smillert 1867b39c5158Smillert use warnings ; 1868b39c5158Smillert use strict ; 1869b39c5158Smillert use DB_File ; 1870b39c5158Smillert 1871b39c5158Smillert my %hash ; 1872b39c5158Smillert my $filename = "filt" ; 1873b39c5158Smillert unlink $filename ; 1874b39c5158Smillert 1875b39c5158Smillert my $db = tie %hash, 'DB_File', $filename, O_CREAT|O_RDWR, 0666, $DB_HASH 1876b39c5158Smillert or die "Cannot open $filename: $!\n" ; 1877b39c5158Smillert 1878b39c5158Smillert # Install DBM Filters 1879b39c5158Smillert $db->filter_fetch_key ( sub { s/\0$// } ) ; 1880b39c5158Smillert $db->filter_store_key ( sub { $_ .= "\0" } ) ; 1881b39c5158Smillert $db->filter_fetch_value( sub { s/\0$// } ) ; 1882b39c5158Smillert $db->filter_store_value( sub { $_ .= "\0" } ) ; 1883b39c5158Smillert 1884b39c5158Smillert $hash{"abc"} = "def" ; 1885b39c5158Smillert my $a = $hash{"ABC"} ; 1886b39c5158Smillert # ... 1887b39c5158Smillert undef $db ; 1888b39c5158Smillert untie %hash ; 1889b39c5158Smillert 1890b39c5158SmillertHopefully the contents of each of the filters should be 1891b39c5158Smillertself-explanatory. Both "fetch" filters remove the terminating NULL, 1892b39c5158Smillertand both "store" filters add a terminating NULL. 1893b39c5158Smillert 1894b39c5158Smillert 1895b39c5158Smillert=head2 Another Example -- Key is a C int. 1896b39c5158Smillert 1897b39c5158SmillertHere is another real-life example. By default, whenever Perl writes to 1898b39c5158Smillerta DBM database it always writes the key and value as strings. So when 1899b39c5158Smillertyou use this: 1900b39c5158Smillert 1901b39c5158Smillert $hash{12345} = "something" ; 1902b39c5158Smillert 1903b39c5158Smillertthe key 12345 will get stored in the DBM database as the 5 byte string 1904b39c5158Smillert"12345". If you actually want the key to be stored in the DBM database 1905b39c5158Smillertas a C int, you will have to use C<pack> when writing, and C<unpack> 1906b39c5158Smillertwhen reading. 1907b39c5158Smillert 1908b39c5158SmillertHere is a DBM Filter that does it: 1909b39c5158Smillert 1910b39c5158Smillert use warnings ; 1911b39c5158Smillert use strict ; 1912b39c5158Smillert use DB_File ; 1913b39c5158Smillert my %hash ; 1914b39c5158Smillert my $filename = "filt" ; 1915b39c5158Smillert unlink $filename ; 1916b39c5158Smillert 1917b39c5158Smillert 1918b39c5158Smillert my $db = tie %hash, 'DB_File', $filename, O_CREAT|O_RDWR, 0666, $DB_HASH 1919b39c5158Smillert or die "Cannot open $filename: $!\n" ; 1920b39c5158Smillert 1921b39c5158Smillert $db->filter_fetch_key ( sub { $_ = unpack("i", $_) } ) ; 1922b39c5158Smillert $db->filter_store_key ( sub { $_ = pack ("i", $_) } ) ; 1923b39c5158Smillert $hash{123} = "def" ; 1924b39c5158Smillert # ... 1925b39c5158Smillert undef $db ; 1926b39c5158Smillert untie %hash ; 1927b39c5158Smillert 1928b39c5158SmillertThis time only two filters have been used -- we only need to manipulate 1929b39c5158Smillertthe contents of the key, so it wasn't necessary to install any value 1930b39c5158Smillertfilters. 1931b39c5158Smillert 1932b39c5158Smillert=head1 HINTS AND TIPS 1933b39c5158Smillert 1934b39c5158Smillert 1935b39c5158Smillert=head2 Locking: The Trouble with fd 1936b39c5158Smillert 1937b39c5158SmillertUntil version 1.72 of this module, the recommended technique for locking 1938b39c5158SmillertB<DB_File> databases was to flock the filehandle returned from the "fd" 1939b39c5158Smillertfunction. Unfortunately this technique has been shown to be fundamentally 1940b39c5158Smillertflawed (Kudos to David Harris for tracking this down). Use it at your own 1941b39c5158Smillertperil! 1942b39c5158Smillert 1943b39c5158SmillertThe locking technique went like this. 1944b39c5158Smillert 1945b39c5158Smillert $db = tie(%db, 'DB_File', 'foo.db', O_CREAT|O_RDWR, 0644) 1946b39c5158Smillert || die "dbcreat foo.db $!"; 1947b39c5158Smillert $fd = $db->fd; 1948b39c5158Smillert open(DB_FH, "+<&=$fd") || die "dup $!"; 1949b39c5158Smillert flock (DB_FH, LOCK_EX) || die "flock: $!"; 1950b39c5158Smillert ... 1951b39c5158Smillert $db{"Tom"} = "Jerry" ; 1952b39c5158Smillert ... 1953b39c5158Smillert flock(DB_FH, LOCK_UN); 1954b39c5158Smillert undef $db; 1955b39c5158Smillert untie %db; 1956b39c5158Smillert close(DB_FH); 1957b39c5158Smillert 1958b39c5158SmillertIn simple terms, this is what happens: 1959b39c5158Smillert 1960b39c5158Smillert=over 5 1961b39c5158Smillert 1962b39c5158Smillert=item 1. 1963b39c5158Smillert 1964b39c5158SmillertUse "tie" to open the database. 1965b39c5158Smillert 1966b39c5158Smillert=item 2. 1967b39c5158Smillert 1968b39c5158SmillertLock the database with fd & flock. 1969b39c5158Smillert 1970b39c5158Smillert=item 3. 1971b39c5158Smillert 1972b39c5158SmillertRead & Write to the database. 1973b39c5158Smillert 1974b39c5158Smillert=item 4. 1975b39c5158Smillert 1976b39c5158SmillertUnlock and close the database. 1977b39c5158Smillert 1978b39c5158Smillert=back 1979b39c5158Smillert 1980b39c5158SmillertHere is the crux of the problem. A side-effect of opening the B<DB_File> 1981b39c5158Smillertdatabase in step 2 is that an initial block from the database will get 1982b39c5158Smillertread from disk and cached in memory. 1983b39c5158Smillert 1984b39c5158SmillertTo see why this is a problem, consider what can happen when two processes, 1985b39c5158Smillertsay "A" and "B", both want to update the same B<DB_File> database 1986b39c5158Smillertusing the locking steps outlined above. Assume process "A" has already 1987b39c5158Smillertopened the database and has a write lock, but it hasn't actually updated 1988b39c5158Smillertthe database yet (it has finished step 2, but not started step 3 yet). Now 1989b39c5158Smillertprocess "B" tries to open the same database - step 1 will succeed, 1990b39c5158Smillertbut it will block on step 2 until process "A" releases the lock. The 1991b39c5158Smillertimportant thing to notice here is that at this point in time both 1992b39c5158Smillertprocesses will have cached identical initial blocks from the database. 1993b39c5158Smillert 1994b39c5158SmillertNow process "A" updates the database and happens to change some of the 1995b39c5158Smillertdata held in the initial buffer. Process "A" terminates, flushing 1996b39c5158Smillertall cached data to disk and releasing the database lock. At this point 1997b39c5158Smillertthe database on disk will correctly reflect the changes made by process 1998b39c5158Smillert"A". 1999b39c5158Smillert 2000b39c5158SmillertWith the lock released, process "B" can now continue. It also updates the 2001b39c5158Smillertdatabase and unfortunately it too modifies the data that was in its 2002b39c5158Smillertinitial buffer. Once that data gets flushed to disk it will overwrite 2003b39c5158Smillertsome/all of the changes process "A" made to the database. 2004b39c5158Smillert 2005b39c5158SmillertThe result of this scenario is at best a database that doesn't contain 2006b39c5158Smillertwhat you expect. At worst the database will corrupt. 2007b39c5158Smillert 2008b39c5158SmillertThe above won't happen every time competing process update the same 2009b39c5158SmillertB<DB_File> database, but it does illustrate why the technique should 2010b39c5158Smillertnot be used. 2011b39c5158Smillert 2012b39c5158Smillert=head2 Safe ways to lock a database 2013b39c5158Smillert 2014b39c5158SmillertStarting with version 2.x, Berkeley DB has internal support for locking. 201556d68f1eSafresh1The companion module to this one, L<BerkeleyDB|https://metacpan.org/pod/BerkeleyDB>, provides an interface 2016b39c5158Smillertto this locking functionality. If you are serious about locking 201756d68f1eSafresh1Berkeley DB databases, I strongly recommend using L<BerkeleyDB|https://metacpan.org/pod/BerkeleyDB>. 2018b39c5158Smillert 201956d68f1eSafresh1If using L<BerkeleyDB|https://metacpan.org/pod/BerkeleyDB> isn't an option, there are a number of modules 2020b39c5158Smillertavailable on CPAN that can be used to implement locking. Each one 2021b39c5158Smillertimplements locking differently and has different goals in mind. It is 2022b39c5158Smillerttherefore worth knowing the difference, so that you can pick the right 2023b39c5158Smillertone for your application. Here are the three locking wrappers: 2024b39c5158Smillert 2025b39c5158Smillert=over 5 2026b39c5158Smillert 2027b39c5158Smillert=item B<Tie::DB_Lock> 2028b39c5158Smillert 2029b39c5158SmillertA B<DB_File> wrapper which creates copies of the database file for 2030b39c5158Smillertread access, so that you have a kind of a multiversioning concurrent read 2031b39c5158Smillertsystem. However, updates are still serial. Use for databases where reads 2032b39c5158Smillertmay be lengthy and consistency problems may occur. 2033b39c5158Smillert 2034b39c5158Smillert=item B<Tie::DB_LockFile> 2035b39c5158Smillert 2036b39c5158SmillertA B<DB_File> wrapper that has the ability to lock and unlock the database 2037b39c5158Smillertwhile it is being used. Avoids the tie-before-flock problem by simply 2038b39c5158Smillertre-tie-ing the database when you get or drop a lock. Because of the 2039b39c5158Smillertflexibility in dropping and re-acquiring the lock in the middle of a 2040b39c5158Smillertsession, this can be massaged into a system that will work with long 2041b39c5158Smillertupdates and/or reads if the application follows the hints in the POD 2042b39c5158Smillertdocumentation. 2043b39c5158Smillert 2044b39c5158Smillert=item B<DB_File::Lock> 2045b39c5158Smillert 2046b39c5158SmillertAn extremely lightweight B<DB_File> wrapper that simply flocks a lockfile 2047b39c5158Smillertbefore tie-ing the database and drops the lock after the untie. Allows 2048b39c5158Smillertone to use the same lockfile for multiple databases to avoid deadlock 2049b39c5158Smillertproblems, if desired. Use for databases where updates are reads are 2050b39c5158Smillertquick and simple flock locking semantics are enough. 2051b39c5158Smillert 2052b39c5158Smillert=back 2053b39c5158Smillert 2054b39c5158Smillert=head2 Sharing Databases With C Applications 2055b39c5158Smillert 2056b39c5158SmillertThere is no technical reason why a Berkeley DB database cannot be 2057b39c5158Smillertshared by both a Perl and a C application. 2058b39c5158Smillert 2059b39c5158SmillertThe vast majority of problems that are reported in this area boil down 2060b39c5158Smillertto the fact that C strings are NULL terminated, whilst Perl strings are 2061b39c5158Smillertnot. See L<DBM FILTERS> for a generic way to work around this problem. 2062b39c5158Smillert 2063b39c5158SmillertHere is a real example. Netscape 2.0 keeps a record of the locations you 2064b39c5158Smillertvisit along with the time you last visited them in a DB_HASH database. 2065b39c5158SmillertThis is usually stored in the file F<~/.netscape/history.db>. The key 2066b39c5158Smillertfield in the database is the location string and the value field is the 2067b39c5158Smillerttime the location was last visited stored as a 4 byte binary value. 2068b39c5158Smillert 2069b39c5158SmillertIf you haven't already guessed, the location string is stored with a 2070b39c5158Smillertterminating NULL. This means you need to be careful when accessing the 2071b39c5158Smillertdatabase. 2072b39c5158Smillert 2073b39c5158SmillertHere is a snippet of code that is loosely based on Tom Christiansen's 2074b39c5158SmillertI<ggh> script (available from your nearest CPAN archive in 2075b39c5158SmillertF<authors/id/TOMC/scripts/nshist.gz>). 2076b39c5158Smillert 2077b39c5158Smillert use warnings ; 2078b39c5158Smillert use strict ; 2079b39c5158Smillert use DB_File ; 2080b39c5158Smillert use Fcntl ; 2081b39c5158Smillert 2082b39c5158Smillert my ($dotdir, $HISTORY, %hist_db, $href, $binary_time, $date) ; 2083b39c5158Smillert $dotdir = $ENV{HOME} || $ENV{LOGNAME}; 2084b39c5158Smillert 2085b39c5158Smillert $HISTORY = "$dotdir/.netscape/history.db"; 2086b39c5158Smillert 2087b39c5158Smillert tie %hist_db, 'DB_File', $HISTORY 2088b39c5158Smillert or die "Cannot open $HISTORY: $!\n" ;; 2089b39c5158Smillert 2090b39c5158Smillert # Dump the complete database 2091b39c5158Smillert while ( ($href, $binary_time) = each %hist_db ) { 2092b39c5158Smillert 2093b39c5158Smillert # remove the terminating NULL 2094b39c5158Smillert $href =~ s/\x00$// ; 2095b39c5158Smillert 2096b39c5158Smillert # convert the binary time into a user friendly string 2097b39c5158Smillert $date = localtime unpack("V", $binary_time); 2098b39c5158Smillert print "$date $href\n" ; 2099b39c5158Smillert } 2100b39c5158Smillert 2101b39c5158Smillert # check for the existence of a specific key 2102b39c5158Smillert # remember to add the NULL 2103b39c5158Smillert if ( $binary_time = $hist_db{"http://mox.perl.com/\x00"} ) { 2104b39c5158Smillert $date = localtime unpack("V", $binary_time) ; 2105b39c5158Smillert print "Last visited mox.perl.com on $date\n" ; 2106b39c5158Smillert } 2107b39c5158Smillert else { 2108b39c5158Smillert print "Never visited mox.perl.com\n" 2109b39c5158Smillert } 2110b39c5158Smillert 2111b39c5158Smillert untie %hist_db ; 2112b39c5158Smillert 2113b39c5158Smillert=head2 The untie() Gotcha 2114b39c5158Smillert 2115b39c5158SmillertIf you make use of the Berkeley DB API, it is I<very> strongly 2116b39c5158Smillertrecommended that you read L<perltie/The untie Gotcha>. 2117b39c5158Smillert 2118b39c5158SmillertEven if you don't currently make use of the API interface, it is still 2119b39c5158Smillertworth reading it. 2120b39c5158Smillert 2121b39c5158SmillertHere is an example which illustrates the problem from a B<DB_File> 2122b39c5158Smillertperspective: 2123b39c5158Smillert 2124b39c5158Smillert use DB_File ; 2125b39c5158Smillert use Fcntl ; 2126b39c5158Smillert 2127b39c5158Smillert my %x ; 2128b39c5158Smillert my $X ; 2129b39c5158Smillert 2130b39c5158Smillert $X = tie %x, 'DB_File', 'tst.fil' , O_RDWR|O_TRUNC 2131b39c5158Smillert or die "Cannot tie first time: $!" ; 2132b39c5158Smillert 2133b39c5158Smillert $x{123} = 456 ; 2134b39c5158Smillert 2135b39c5158Smillert untie %x ; 2136b39c5158Smillert 2137b39c5158Smillert tie %x, 'DB_File', 'tst.fil' , O_RDWR|O_CREAT 2138b39c5158Smillert or die "Cannot tie second time: $!" ; 2139b39c5158Smillert 2140b39c5158Smillert untie %x ; 2141b39c5158Smillert 2142b39c5158SmillertWhen run, the script will produce this error message: 2143b39c5158Smillert 2144b39c5158Smillert Cannot tie second time: Invalid argument at bad.file line 14. 2145b39c5158Smillert 2146b39c5158SmillertAlthough the error message above refers to the second tie() statement 2147b39c5158Smillertin the script, the source of the problem is really with the untie() 2148b39c5158Smillertstatement that precedes it. 2149b39c5158Smillert 2150b39c5158SmillertHaving read L<perltie> you will probably have already guessed that the 2151b39c5158Smillerterror is caused by the extra copy of the tied object stored in C<$X>. 2152b39c5158SmillertIf you haven't, then the problem boils down to the fact that the 2153b39c5158SmillertB<DB_File> destructor, DESTROY, will not be called until I<all> 2154b39c5158Smillertreferences to the tied object are destroyed. Both the tied variable, 2155b39c5158SmillertC<%x>, and C<$X> above hold a reference to the object. The call to 2156b39c5158Smillertuntie() will destroy the first, but C<$X> still holds a valid 2157b39c5158Smillertreference, so the destructor will not get called and the database file 2158b39c5158SmillertF<tst.fil> will remain open. The fact that Berkeley DB then reports the 2159b39c5158Smillertattempt to open a database that is already open via the catch-all 2160b39c5158Smillert"Invalid argument" doesn't help. 2161b39c5158Smillert 2162b39c5158SmillertIf you run the script with the C<-w> flag the error message becomes: 2163b39c5158Smillert 2164b39c5158Smillert untie attempted while 1 inner references still exist at bad.file line 12. 2165b39c5158Smillert Cannot tie second time: Invalid argument at bad.file line 14. 2166b39c5158Smillert 2167b39c5158Smillertwhich pinpoints the real problem. Finally the script can now be 2168b39c5158Smillertmodified to fix the original problem by destroying the API object 2169b39c5158Smillertbefore the untie: 2170b39c5158Smillert 2171b39c5158Smillert ... 2172b39c5158Smillert $x{123} = 456 ; 2173b39c5158Smillert 2174b39c5158Smillert undef $X ; 2175b39c5158Smillert untie %x ; 2176b39c5158Smillert 2177b39c5158Smillert $X = tie %x, 'DB_File', 'tst.fil' , O_RDWR|O_CREAT 2178b39c5158Smillert ... 2179b39c5158Smillert 2180b39c5158Smillert 2181b39c5158Smillert=head1 COMMON QUESTIONS 2182b39c5158Smillert 2183b39c5158Smillert=head2 Why is there Perl source in my database? 2184b39c5158Smillert 2185b39c5158SmillertIf you look at the contents of a database file created by DB_File, 2186b39c5158Smillertthere can sometimes be part of a Perl script included in it. 2187b39c5158Smillert 2188b39c5158SmillertThis happens because Berkeley DB uses dynamic memory to allocate 2189b39c5158Smillertbuffers which will subsequently be written to the database file. Being 2190b39c5158Smillertdynamic, the memory could have been used for anything before DB 2191b39c5158Smillertmalloced it. As Berkeley DB doesn't clear the memory once it has been 2192b39c5158Smillertallocated, the unused portions will contain random junk. In the case 2193b39c5158Smillertwhere a Perl script gets written to the database, the random junk will 2194b39c5158Smillertcorrespond to an area of dynamic memory that happened to be used during 2195b39c5158Smillertthe compilation of the script. 2196b39c5158Smillert 2197b39c5158SmillertUnless you don't like the possibility of there being part of your Perl 2198b39c5158Smillertscripts embedded in a database file, this is nothing to worry about. 2199b39c5158Smillert 2200b39c5158Smillert=head2 How do I store complex data structures with DB_File? 2201b39c5158Smillert 2202b39c5158SmillertAlthough B<DB_File> cannot do this directly, there is a module which 2203b39c5158Smillertcan layer transparently over B<DB_File> to accomplish this feat. 2204b39c5158Smillert 2205b39c5158SmillertCheck out the MLDBM module, available on CPAN in the directory 2206b39c5158SmillertF<modules/by-module/MLDBM>. 2207b39c5158Smillert 22089f11ffb7Safresh1=head2 What does "wide character in subroutine entry" mean? 22099f11ffb7Safresh1 22109f11ffb7Safresh1You will usually get this message if you are working with UTF-8 data and 22119f11ffb7Safresh1want to read/write it from/to a Berkeley DB database file. 22129f11ffb7Safresh1 22139f11ffb7Safresh1The easist way to deal with this issue is to use the pre-defined "utf8" 22149f11ffb7Safresh1B<DBM_Filter> (see L<DBM_Filter>) that was designed to deal with this 22159f11ffb7Safresh1situation. 22169f11ffb7Safresh1 22179f11ffb7Safresh1The example below shows what you need if I<both> the key and value are 22189f11ffb7Safresh1expected to be in UTF-8. 22199f11ffb7Safresh1 22209f11ffb7Safresh1 use DB_File; 22219f11ffb7Safresh1 use DBM_Filter; 22229f11ffb7Safresh1 22239f11ffb7Safresh1 my $db = tie %h, 'DB_File', '/tmp/try.db', O_CREAT|O_RDWR, 0666, $DB_BTREE; 22249f11ffb7Safresh1 $db->Filter_Key_Push('utf8'); 22259f11ffb7Safresh1 $db->Filter_Value_Push('utf8'); 22269f11ffb7Safresh1 22279f11ffb7Safresh1 my $key = "\N{LATIN SMALL LETTER A WITH ACUTE}"; 22289f11ffb7Safresh1 my $value = "\N{LATIN SMALL LETTER E WITH ACUTE}"; 22299f11ffb7Safresh1 $h{ $key } = $value; 22309f11ffb7Safresh1 2231b39c5158Smillert=head2 What does "Invalid Argument" mean? 2232b39c5158Smillert 2233b39c5158SmillertYou will get this error message when one of the parameters in the 2234b39c5158SmillertC<tie> call is wrong. Unfortunately there are quite a few parameters to 2235b39c5158Smillertget wrong, so it can be difficult to figure out which one it is. 2236b39c5158Smillert 2237b39c5158SmillertHere are a couple of possibilities: 2238b39c5158Smillert 2239b39c5158Smillert=over 5 2240b39c5158Smillert 2241b39c5158Smillert=item 1. 2242b39c5158Smillert 2243b39c5158SmillertAttempting to reopen a database without closing it. 2244b39c5158Smillert 2245b39c5158Smillert=item 2. 2246b39c5158Smillert 2247b39c5158SmillertUsing the O_WRONLY flag. 2248b39c5158Smillert 2249b39c5158Smillert=back 2250b39c5158Smillert 2251b39c5158Smillert=head2 What does "Bareword 'DB_File' not allowed" mean? 2252b39c5158Smillert 2253b39c5158SmillertYou will encounter this particular error message when you have the 2254b39c5158SmillertC<strict 'subs'> pragma (or the full strict pragma) in your script. 2255b39c5158SmillertConsider this script: 2256b39c5158Smillert 2257b39c5158Smillert use warnings ; 2258b39c5158Smillert use strict ; 2259b39c5158Smillert use DB_File ; 2260b39c5158Smillert my %x ; 2261b39c5158Smillert tie %x, DB_File, "filename" ; 2262b39c5158Smillert 2263b39c5158SmillertRunning it produces the error in question: 2264b39c5158Smillert 2265b39c5158Smillert Bareword "DB_File" not allowed while "strict subs" in use 2266b39c5158Smillert 2267b39c5158SmillertTo get around the error, place the word C<DB_File> in either single or 2268b39c5158Smillertdouble quotes, like this: 2269b39c5158Smillert 2270b39c5158Smillert tie %x, "DB_File", "filename" ; 2271b39c5158Smillert 2272b39c5158SmillertAlthough it might seem like a real pain, it is really worth the effort 2273b39c5158Smillertof having a C<use strict> in all your scripts. 2274b39c5158Smillert 2275b39c5158Smillert=head1 REFERENCES 2276b39c5158Smillert 2277b39c5158SmillertArticles that are either about B<DB_File> or make use of it. 2278b39c5158Smillert 2279b39c5158Smillert=over 5 2280b39c5158Smillert 2281b39c5158Smillert=item 1. 2282b39c5158Smillert 2283b39c5158SmillertI<Full-Text Searching in Perl>, Tim Kientzle (tkientzle@ddj.com), 2284b39c5158SmillertDr. Dobb's Journal, Issue 295, January 1999, pp 34-41 2285b39c5158Smillert 2286b39c5158Smillert=back 2287b39c5158Smillert 2288b39c5158Smillert=head1 HISTORY 2289b39c5158Smillert 2290b39c5158SmillertMoved to the Changes file. 2291b39c5158Smillert 2292b39c5158Smillert=head1 BUGS 2293b39c5158Smillert 2294b39c5158SmillertSome older versions of Berkeley DB had problems with fixed length 2295b39c5158Smillertrecords using the RECNO file format. This problem has been fixed since 2296b39c5158Smillertversion 1.85 of Berkeley DB. 2297b39c5158Smillert 2298b39c5158SmillertI am sure there are bugs in the code. If you do find any, or can 2299b39c5158Smillertsuggest any enhancements, I would welcome your comments. 2300b39c5158Smillert 230156d68f1eSafresh1=head1 SUPPORT 230256d68f1eSafresh1 230356d68f1eSafresh1General feedback/questions/bug reports should be sent to 230456d68f1eSafresh1L<https://github.com/pmqs/DB_File/issues> (preferred) or 230556d68f1eSafresh1L<https://rt.cpan.org/Public/Dist/Display.html?Name=DB_File>. 230656d68f1eSafresh1 2307b39c5158Smillert=head1 AVAILABILITY 2308b39c5158Smillert 2309b39c5158SmillertB<DB_File> comes with the standard Perl source distribution. Look in 2310b39c5158Smillertthe directory F<ext/DB_File>. Given the amount of time between releases 2311b39c5158Smillertof Perl the version that ships with Perl is quite likely to be out of 2312b39c5158Smillertdate, so the most recent version can always be found on CPAN (see 2313b39c5158SmillertL<perlmodlib/CPAN> for details), in the directory 2314b39c5158SmillertF<modules/by-module/DB_File>. 2315b39c5158Smillert 231656d68f1eSafresh1B<DB_File> is designed to work with any version of Berkeley DB, but is limited to the functionality provided by 231756d68f1eSafresh1version 1. If you want to make use of the new features available in Berkeley DB 231856d68f1eSafresh12.x, or greater, use the Perl module L<BerkeleyDB|https://metacpan.org/pod/BerkeleyDB> instead. 2319b39c5158Smillert 232056d68f1eSafresh1The official web site for Berkeley DB is L<http://www.oracle.com/technology/products/berkeley-db/db/index.html>. 2321b39c5158SmillertAll versions of Berkeley DB are available there. 2322b39c5158Smillert 2323b39c5158SmillertAlternatively, Berkeley DB version 1 is available at your nearest CPAN 2324b39c5158Smillertarchive in F<src/misc/db.1.85.tar.gz>. 2325b39c5158Smillert 2326b39c5158Smillert=head1 COPYRIGHT 2327b39c5158Smillert 2328*3d61058aSafresh1Copyright (c) 1995-2023 Paul Marquess. All rights reserved. This program 2329b39c5158Smillertis free software; you can redistribute it and/or modify it under the 2330b39c5158Smillertsame terms as Perl itself. 2331b39c5158Smillert 2332b39c5158SmillertAlthough B<DB_File> is covered by the Perl license, the library it 2333b39c5158Smillertmakes use of, namely Berkeley DB, is not. Berkeley DB has its own 2334e0680481Safresh1copyright and its own license. 2335e0680481Safresh1See L<AGPL|https://www.oracle.com/downloads/licenses/berkeleydb-oslicense.html> for more details. 2336e0680481Safresh1Please take the time to read the Berkeley DB license and decide how it impacts your use of this Perl module. 2337b39c5158Smillert 2338b39c5158Smillert=head1 SEE ALSO 2339b39c5158Smillert 2340b39c5158SmillertL<perl>, L<dbopen(3)>, L<hash(3)>, L<recno(3)>, L<btree(3)>, 23419f11ffb7Safresh1L<perldbmfilter>, L<DBM_Filter> 2342b39c5158Smillert 2343b39c5158Smillert=head1 AUTHOR 2344b39c5158Smillert 2345b39c5158SmillertThe DB_File interface was written by Paul Marquess 2346b39c5158SmillertE<lt>pmqs@cpan.orgE<gt>. 2347b39c5158Smillert 2348b39c5158Smillert=cut 2349