1898184e3Ssthen#!perl 2898184e3SsthenBEGIN { 3898184e3Ssthen} 4898184e3Ssthen 5898184e3Ssthenuse strict; 6898184e3Ssthenuse warnings; 7898184e3Ssthen 8898184e3Ssthenuse Test::More; 9898184e3Ssthenuse Config; 10898184e3Ssthen 11898184e3Ssthenour $DBM_Class; 12898184e3Ssthen 13898184e3Ssthenmy ($create, $write); 14898184e3SsthenBEGIN { 15898184e3Ssthen plan(skip_all => "$DBM_Class was not built") 16898184e3Ssthen unless $Config{extensions} =~ /\b$DBM_Class\b/; 17898184e3Ssthen plan(skip_all => "$DBM_Class not compatible with C++") 18898184e3Ssthen if $DBM_Class eq 'ODBM_File' && $Config{d_cplusplus}; 19898184e3Ssthen 20898184e3Ssthen use_ok($DBM_Class); 21898184e3Ssthen 22898184e3Ssthen if ($::Create_and_Write) { 23898184e3Ssthen ($create, $write) = eval $::Create_and_Write; 24898184e3Ssthen isnt($create, undef, "(eval q{$::Create_and_Write})[0]"); 25898184e3Ssthen isnt($write, undef, "(eval q{$::Create_and_Write})[1]"); 26898184e3Ssthen } else { 27898184e3Ssthen #If Fcntl is not available, try 0x202 or 0x102 for O_RDWR|O_CREAT 28898184e3Ssthen use_ok('Fcntl'); 29898184e3Ssthen $create = O_RDWR()|O_CREAT(); 30898184e3Ssthen $write = O_RDWR(); 31898184e3Ssthen } 32898184e3Ssthen} 33898184e3Ssthen 34898184e3Ssthenunlink <Op_dbmx.*>; 35898184e3Ssthen 36898184e3Ssthenumask(0); 37898184e3Ssthenmy %h; 38898184e3Ssthenisa_ok(tie(%h, $DBM_Class, 'Op_dbmx', $create, 0640), $DBM_Class); 39898184e3Ssthen 40898184e3Ssthenmy $Dfile = "Op_dbmx.pag"; 41898184e3Ssthenif (! -e $Dfile) { 42898184e3Ssthen ($Dfile) = <Op_dbmx*>; 43898184e3Ssthen} 44898184e3SsthenSKIP: { 45898184e3Ssthen skip "different file permission semantics on $^O", 1 46256a93a4Safresh1 if $^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'vos'; 47898184e3Ssthen my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, 48898184e3Ssthen $blksize,$blocks) = stat($Dfile); 49898184e3Ssthen is($mode & 0777, 0640); 50898184e3Ssthen} 51898184e3Ssthenmy $i = 0; 52898184e3Ssthenwhile (my ($key,$value) = each(%h)) { 53898184e3Ssthen $i++; 54898184e3Ssthen} 55898184e3Ssthenis($i, 0); 56898184e3Ssthen 57898184e3Ssthen$h{'goner1'} = 'snork'; 58898184e3Ssthen 59898184e3Ssthen$h{'abc'} = 'ABC'; 60898184e3Ssthen$h{'def'} = 'DEF'; 61898184e3Ssthen$h{'jkl','mno'} = "JKL\034MNO"; 62898184e3Ssthen$h{'a',2,3,4,5} = join("\034",'A',2,3,4,5); 63898184e3Ssthen$h{'a'} = 'A'; 64898184e3Ssthen$h{'b'} = 'B'; 65898184e3Ssthen$h{'c'} = 'C'; 66898184e3Ssthen$h{'d'} = 'D'; 67898184e3Ssthen$h{'e'} = 'E'; 68898184e3Ssthen$h{'f'} = 'F'; 69898184e3Ssthen$h{'g'} = 'G'; 70898184e3Ssthen$h{'h'} = 'H'; 71898184e3Ssthen$h{'i'} = 'I'; 72898184e3Ssthen 73898184e3Ssthen$h{'goner2'} = 'snork'; 74898184e3Ssthendelete $h{'goner2'}; 75898184e3Ssthen 76898184e3Ssthenuntie(%h); 77898184e3Ssthenisa_ok(tie(%h, $DBM_Class, 'Op_dbmx', $write, 0640), $DBM_Class); 78898184e3Ssthen 79898184e3Ssthen$h{'j'} = 'J'; 80898184e3Ssthen$h{'k'} = 'K'; 81898184e3Ssthen$h{'l'} = 'L'; 82898184e3Ssthen$h{'m'} = 'M'; 83898184e3Ssthen$h{'n'} = 'N'; 84898184e3Ssthen$h{'o'} = 'O'; 85898184e3Ssthen$h{'p'} = 'P'; 86898184e3Ssthen$h{'q'} = 'Q'; 87898184e3Ssthen$h{'r'} = 'R'; 88898184e3Ssthen$h{'s'} = 'S'; 89898184e3Ssthen$h{'t'} = 'T'; 90898184e3Ssthen$h{'u'} = 'U'; 91898184e3Ssthen$h{'v'} = 'V'; 92898184e3Ssthen$h{'w'} = 'W'; 93898184e3Ssthen$h{'x'} = 'X'; 94898184e3Ssthen$h{'y'} = 'Y'; 95898184e3Ssthen$h{'z'} = 'Z'; 96898184e3Ssthen 97898184e3Ssthen$h{'goner3'} = 'snork'; 98898184e3Ssthen 99898184e3Ssthendelete $h{'goner1'}; 100898184e3Ssthendelete $h{'goner3'}; 101898184e3Ssthen 102898184e3Ssthenmy @keys = keys(%h); 103898184e3Ssthenmy @values = values(%h); 104898184e3Ssthen 105898184e3Ssthenis($#keys, 29); 106898184e3Ssthenis($#values, 29); 107898184e3Ssthen 108898184e3Ssthenwhile (my ($key, $value) = each(%h)) { 109898184e3Ssthen if ($key eq $keys[$i] && $value eq $values[$i] && $key eq lc($value)) { 110898184e3Ssthen $key =~ y/a-z/A-Z/; 111898184e3Ssthen $i++ if $key eq $value; 112898184e3Ssthen } 113898184e3Ssthen} 114898184e3Ssthen 115898184e3Ssthenis($i, 30); 116898184e3Ssthen 117898184e3Ssthen@keys = ('blurfl', keys(%h), 'dyick'); 118898184e3Ssthenis($#keys, 31); 119898184e3Ssthen 120898184e3Ssthen$h{'foo'} = ''; 121898184e3Ssthen$h{''} = 'bar'; 122898184e3Ssthen 123898184e3Ssthenmy $ok = 1; 124898184e3Ssthenfor ($i = 1; $i < 200; $i++) { $h{$i + 0} = $i + 0; } 125898184e3Ssthenfor ($i = 1; $i < 200; $i++) { $ok = 0 unless $h{$i} == $i; } 126898184e3Ssthenis($ok, 1, 'check cache overflow and numeric keys and contents'); 127898184e3Ssthen 128898184e3Ssthenmy ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, 129898184e3Ssthen $blksize,$blocks) = stat($Dfile); 130898184e3Ssthencmp_ok($size, '>', 0); 131898184e3Ssthen 132898184e3Ssthen@h{0..200} = 200..400; 133898184e3Ssthenmy @foo = @h{0..200}; 134898184e3Ssthenis(join(':',200..400), join(':',@foo)); 135898184e3Ssthen 136898184e3Ssthenis($h{'foo'}, ''); 137898184e3Ssthenis($h{''}, 'bar'); 138898184e3Ssthen 139*f2a19305Safresh1if($DBM_Class eq 'SDBM_File' || $DBM_Class eq 'NDBM_File') { 140898184e3Ssthen is(exists $h{goner1}, ''); 141898184e3Ssthen is(exists $h{foo}, 1); 142898184e3Ssthen} 143898184e3Ssthen 144898184e3Ssthenuntie %h; 145898184e3Ssthenunlink <Op_dbmx*>, $Dfile; 146898184e3Ssthen 147898184e3Ssthen{ 148898184e3Ssthen # sub-class test 149898184e3Ssthen 150898184e3Ssthen package Another; 151898184e3Ssthen 152898184e3Ssthen open my $file, '>', 'SubDB.pm' or die "Cannot open SubDB.pm: $!\n"; 153898184e3Ssthen printf $file <<'EOM', $DBM_Class, $DBM_Class, $DBM_Class; 154898184e3Ssthen 155898184e3Ssthen package SubDB; 156898184e3Ssthen 157898184e3Ssthen use strict; 158898184e3Ssthen use warnings; 159898184e3Ssthen 160898184e3Ssthen require Exporter; 161898184e3Ssthen use %s; 1625759b3d2Safresh1 our @ISA=qw(%s); 1635759b3d2Safresh1 our @EXPORT = @%s::EXPORT; 164898184e3Ssthen 165898184e3Ssthen sub STORE { 166898184e3Ssthen my $self = shift; 167898184e3Ssthen my $key = shift; 168898184e3Ssthen my $value = shift; 169898184e3Ssthen $self->SUPER::STORE($key, $value * 2); 170898184e3Ssthen } 171898184e3Ssthen 172898184e3Ssthen sub FETCH { 173898184e3Ssthen my $self = shift; 174898184e3Ssthen my $key = shift; 175898184e3Ssthen $self->SUPER::FETCH($key) - 1; 176898184e3Ssthen } 177898184e3Ssthen 178898184e3Ssthen sub A_new_method 179898184e3Ssthen { 180898184e3Ssthen my $self = shift; 181898184e3Ssthen my $key = shift; 182898184e3Ssthen my $value = $self->FETCH($key); 183898184e3Ssthen return "[[$value]]"; 184898184e3Ssthen } 185898184e3Ssthen 186898184e3Ssthen 1; 187898184e3SsthenEOM 188898184e3Ssthen 189898184e3Ssthen close $file or die "Could not close: $!"; 190898184e3Ssthen 191898184e3Ssthen BEGIN { push @INC, '.'; } 192898184e3Ssthen unlink <dbhash_tmp*>; 193898184e3Ssthen 194898184e3Ssthen main::use_ok('SubDB'); 195898184e3Ssthen my %h; 196898184e3Ssthen my $X; 197898184e3Ssthen eval ' 198898184e3Ssthen $X = tie(%h, "SubDB", "dbhash_tmp", $create, 0640 ); 199898184e3Ssthen '; 200898184e3Ssthen 201898184e3Ssthen main::is($@, ""); 202898184e3Ssthen 203898184e3Ssthen my $ret = eval '$h{"fred"} = 3; return $h{"fred"} '; 204898184e3Ssthen main::is($@, ""); 205898184e3Ssthen main::is($ret, 5); 206898184e3Ssthen 207898184e3Ssthen $ret = eval '$X->A_new_method("fred") '; 208898184e3Ssthen main::is($@, ""); 209898184e3Ssthen main::is($ret, "[[5]]"); 210898184e3Ssthen 211898184e3Ssthen if ($DBM_Class eq 'GDBM_File') { 212898184e3Ssthen $ret = eval 'GDBM_WRCREAT eq main::GDBM_WRCREAT'; 213898184e3Ssthen main::is($@, ""); 214898184e3Ssthen main::is($ret, 1); 215898184e3Ssthen } 216898184e3Ssthen 217898184e3Ssthen undef $X; 218898184e3Ssthen untie(%h); 219898184e3Ssthen unlink "SubDB.pm", <dbhash_tmp*>; 220898184e3Ssthen 221898184e3Ssthen} 222898184e3Ssthen 223898184e3Ssthenuntie %h; 224898184e3Ssthenunlink <Op_dbmx*>, $Dfile; 225898184e3Ssthen 226898184e3Ssthen{ 227898184e3Ssthen # DBM Filter tests 228898184e3Ssthen my (%h, $db); 229898184e3Ssthen my ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 230898184e3Ssthen 231898184e3Ssthen sub checkOutput 232898184e3Ssthen { 233898184e3Ssthen my($fk, $sk, $fv, $sv) = @_; 234898184e3Ssthen local $Test::Builder::Level = $Test::Builder::Level + 1; 235898184e3Ssthen is($fetch_key, $fk); 236898184e3Ssthen is($store_key, $sk); 237898184e3Ssthen is($fetch_value, $fv); 238898184e3Ssthen is($store_value, $sv); 239898184e3Ssthen is($_, 'original'); 240898184e3Ssthen } 241898184e3Ssthen 242898184e3Ssthen unlink <Op_dbmx*>; 243898184e3Ssthen $db = tie %h, $DBM_Class, 'Op_dbmx', $create, 0640; 244898184e3Ssthen isa_ok($db, $DBM_Class); 245898184e3Ssthen 246898184e3Ssthen $db->filter_fetch_key (sub { $fetch_key = $_ }); 247898184e3Ssthen $db->filter_store_key (sub { $store_key = $_ }); 248898184e3Ssthen $db->filter_fetch_value (sub { $fetch_value = $_}); 249898184e3Ssthen $db->filter_store_value (sub { $store_value = $_ }); 250898184e3Ssthen 251898184e3Ssthen $_ = "original"; 252898184e3Ssthen 253898184e3Ssthen $h{"fred"} = "joe"; 254898184e3Ssthen # fk sk fv sv 255898184e3Ssthen checkOutput("", "fred", "", "joe"); 256898184e3Ssthen 257898184e3Ssthen ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 258898184e3Ssthen is($h{"fred"}, "joe"); 259898184e3Ssthen # fk sk fv sv 260898184e3Ssthen checkOutput("", "fred", "joe", ""); 261898184e3Ssthen 262898184e3Ssthen ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 263898184e3Ssthen is($db->FIRSTKEY(), "fred"); 264898184e3Ssthen # fk sk fv sv 265898184e3Ssthen checkOutput("fred", "", "", ""); 266898184e3Ssthen 267898184e3Ssthen # replace the filters, but remember the previous set 268898184e3Ssthen my ($old_fk) = $db->filter_fetch_key 269898184e3Ssthen (sub { $_ = uc $_; $fetch_key = $_ }); 270898184e3Ssthen my ($old_sk) = $db->filter_store_key 271898184e3Ssthen (sub { $_ = lc $_; $store_key = $_ }); 272898184e3Ssthen my ($old_fv) = $db->filter_fetch_value 273898184e3Ssthen (sub { $_ = "[$_]"; $fetch_value = $_ }); 274898184e3Ssthen my ($old_sv) = $db->filter_store_value 275898184e3Ssthen (sub { s/o/x/g; $store_value = $_ }); 276898184e3Ssthen 277898184e3Ssthen ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 278898184e3Ssthen $h{"Fred"} = "Joe"; 279898184e3Ssthen # fk sk fv sv 280898184e3Ssthen checkOutput("", "fred", "", "Jxe"); 281898184e3Ssthen 282898184e3Ssthen ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 283898184e3Ssthen is($h{"Fred"}, "[Jxe]"); 284898184e3Ssthen # fk sk fv sv 285898184e3Ssthen checkOutput("", "fred", "[Jxe]", ""); 286898184e3Ssthen 287898184e3Ssthen ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 288898184e3Ssthen is($db->FIRSTKEY(), "FRED"); 289898184e3Ssthen # fk sk fv sv 290898184e3Ssthen checkOutput("FRED", "", "", ""); 291898184e3Ssthen 292898184e3Ssthen # put the original filters back 293898184e3Ssthen $db->filter_fetch_key ($old_fk); 294898184e3Ssthen $db->filter_store_key ($old_sk); 295898184e3Ssthen $db->filter_fetch_value ($old_fv); 296898184e3Ssthen $db->filter_store_value ($old_sv); 297898184e3Ssthen 298898184e3Ssthen ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 299898184e3Ssthen $h{"fred"} = "joe"; 300898184e3Ssthen checkOutput("", "fred", "", "joe"); 301898184e3Ssthen 302898184e3Ssthen ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 303898184e3Ssthen is($h{"fred"}, "joe"); 304898184e3Ssthen checkOutput("", "fred", "joe", ""); 305898184e3Ssthen 306898184e3Ssthen ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 307898184e3Ssthen is($db->FIRSTKEY(), "fred"); 308898184e3Ssthen checkOutput("fred", "", "", ""); 309898184e3Ssthen 310898184e3Ssthen # delete the filters 311898184e3Ssthen $db->filter_fetch_key (undef); 312898184e3Ssthen $db->filter_store_key (undef); 313898184e3Ssthen $db->filter_fetch_value (undef); 314898184e3Ssthen $db->filter_store_value (undef); 315898184e3Ssthen 316898184e3Ssthen ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 317898184e3Ssthen $h{"fred"} = "joe"; 318898184e3Ssthen checkOutput("", "", "", ""); 319898184e3Ssthen 320898184e3Ssthen ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 321898184e3Ssthen is($h{"fred"}, "joe"); 322898184e3Ssthen checkOutput("", "", "", ""); 323898184e3Ssthen 324898184e3Ssthen ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4; 325898184e3Ssthen is($db->FIRSTKEY(), "fred"); 326898184e3Ssthen checkOutput("", "", "", ""); 327898184e3Ssthen 328898184e3Ssthen undef $db; 329898184e3Ssthen untie %h; 330898184e3Ssthen unlink <Op_dbmx*>; 331898184e3Ssthen} 332898184e3Ssthen 333898184e3Ssthen{ 334898184e3Ssthen # DBM Filter with a closure 335898184e3Ssthen 336898184e3Ssthen my (%h, $db); 337898184e3Ssthen 338898184e3Ssthen unlink <Op_dbmx*>; 339898184e3Ssthen $db = tie %h, $DBM_Class, 'Op_dbmx', $create, 0640; 340898184e3Ssthen isa_ok($db, $DBM_Class); 341898184e3Ssthen 342898184e3Ssthen my %result = (); 343898184e3Ssthen 344898184e3Ssthen sub Closure 345898184e3Ssthen { 346898184e3Ssthen my ($name) = @_; 347898184e3Ssthen my $count = 0; 348898184e3Ssthen my @kept = (); 349898184e3Ssthen 350898184e3Ssthen return sub { ++$count; 351898184e3Ssthen push @kept, $_; 352898184e3Ssthen $result{$name} = "$name - $count: [@kept]"; 353898184e3Ssthen } 354898184e3Ssthen } 355898184e3Ssthen 356898184e3Ssthen $db->filter_store_key(Closure("store key")); 357898184e3Ssthen $db->filter_store_value(Closure("store value")); 358898184e3Ssthen $db->filter_fetch_key(Closure("fetch key")); 359898184e3Ssthen $db->filter_fetch_value(Closure("fetch value")); 360898184e3Ssthen 361898184e3Ssthen $_ = "original"; 362898184e3Ssthen 363898184e3Ssthen $h{"fred"} = "joe"; 364898184e3Ssthen is($result{"store key"}, "store key - 1: [fred]"); 365898184e3Ssthen is($result{"store value"}, "store value - 1: [joe]"); 366898184e3Ssthen is($result{"fetch key"}, undef); 367898184e3Ssthen is($result{"fetch value"}, undef); 368898184e3Ssthen is($_, "original"); 369898184e3Ssthen 370898184e3Ssthen is($db->FIRSTKEY(), "fred"); 371898184e3Ssthen is($result{"store key"}, "store key - 1: [fred]"); 372898184e3Ssthen is($result{"store value"}, "store value - 1: [joe]"); 373898184e3Ssthen is($result{"fetch key"}, "fetch key - 1: [fred]"); 374898184e3Ssthen is($result{"fetch value"}, undef); 375898184e3Ssthen is($_, "original"); 376898184e3Ssthen 377898184e3Ssthen $h{"jim"} = "john"; 378898184e3Ssthen is($result{"store key"}, "store key - 2: [fred jim]"); 379898184e3Ssthen is($result{"store value"}, "store value - 2: [joe john]"); 380898184e3Ssthen is($result{"fetch key"}, "fetch key - 1: [fred]"); 381898184e3Ssthen is($result{"fetch value"}, undef); 382898184e3Ssthen is($_, "original"); 383898184e3Ssthen 384898184e3Ssthen is($h{"fred"}, "joe"); 385898184e3Ssthen is($result{"store key"}, "store key - 3: [fred jim fred]"); 386898184e3Ssthen is($result{"store value"}, "store value - 2: [joe john]"); 387898184e3Ssthen is($result{"fetch key"}, "fetch key - 1: [fred]"); 388898184e3Ssthen is($result{"fetch value"}, "fetch value - 1: [joe]"); 389898184e3Ssthen is($_, "original"); 390898184e3Ssthen 391898184e3Ssthen undef $db; 392898184e3Ssthen untie %h; 393898184e3Ssthen unlink <Op_dbmx*>; 394898184e3Ssthen} 395898184e3Ssthen 396898184e3Ssthen{ 397898184e3Ssthen # DBM Filter recursion detection 398898184e3Ssthen my (%h, $db); 399898184e3Ssthen unlink <Op_dbmx*>; 400898184e3Ssthen 401898184e3Ssthen $db = tie %h, $DBM_Class, 'Op_dbmx', $create, 0640; 402898184e3Ssthen isa_ok($db, $DBM_Class); 403898184e3Ssthen 404898184e3Ssthen $db->filter_store_key (sub { $_ = $h{$_} }); 405898184e3Ssthen 406898184e3Ssthen eval '$h{1} = 1234'; 407898184e3Ssthen like($@, qr/^recursion detected in filter_store_key at/); 408898184e3Ssthen 409898184e3Ssthen undef $db; 410898184e3Ssthen untie %h; 411898184e3Ssthen unlink <Op_dbmx*>; 412898184e3Ssthen} 413898184e3Ssthen 414898184e3Ssthen{ 4155759b3d2Safresh1 # Bug ID 20001013.009 (#4434) 416898184e3Ssthen # 417898184e3Ssthen # test that $hash{KEY} = undef doesn't produce the warning 418898184e3Ssthen # Use of uninitialized value in null operation 419898184e3Ssthen 420898184e3Ssthen unlink <Op_dbmx*>; 421898184e3Ssthen my %h; 422898184e3Ssthen my $a = ""; 423898184e3Ssthen local $SIG{__WARN__} = sub {$a = $_[0]}; 424898184e3Ssthen 425898184e3Ssthen isa_ok(tie(%h, $DBM_Class, 'Op_dbmx', $create, 0640), $DBM_Class); 426898184e3Ssthen $h{ABC} = undef; 427898184e3Ssthen is($a, ""); 428898184e3Ssthen untie %h; 429898184e3Ssthen unlink <Op_dbmx*>; 430898184e3Ssthen} 431898184e3Ssthen 432898184e3Ssthen{ 433898184e3Ssthen # When iterating over a tied hash using "each", the key passed to FETCH 434898184e3Ssthen # will be recycled and passed to NEXTKEY. If a Source Filter modifies the 435898184e3Ssthen # key in FETCH via a filter_fetch_key method we need to check that the 436898184e3Ssthen # modified key doesn't get passed to NEXTKEY. 437898184e3Ssthen # Also Test "keys" & "values" while we are at it. 438898184e3Ssthen 439898184e3Ssthen unlink <Op_dbmx*>; 440898184e3Ssthen my $bad_key = 0; 441898184e3Ssthen my %h = (); 442898184e3Ssthen my $db = tie %h, $DBM_Class, 'Op_dbmx', $create, 0640; 443898184e3Ssthen isa_ok($db, $DBM_Class); 444898184e3Ssthen $db->filter_fetch_key (sub { $_ =~ s/^Beta_/Alpha_/ if defined $_}); 445898184e3Ssthen $db->filter_store_key (sub { $bad_key = 1 if /^Beta_/; $_ =~ s/^Alpha_/Beta_/}); 446898184e3Ssthen 447898184e3Ssthen $h{'Alpha_ABC'} = 2; 448898184e3Ssthen $h{'Alpha_DEF'} = 5; 449898184e3Ssthen 450898184e3Ssthen is($h{'Alpha_ABC'}, 2); 451898184e3Ssthen is($h{'Alpha_DEF'}, 5); 452898184e3Ssthen 453898184e3Ssthen my ($k, $v) = ("", ""); 454898184e3Ssthen while (($k, $v) = each %h) {} 455898184e3Ssthen is($bad_key, 0); 456898184e3Ssthen 457898184e3Ssthen $bad_key = 0; 458898184e3Ssthen foreach $k (keys %h) {} 459898184e3Ssthen is($bad_key, 0); 460898184e3Ssthen 461898184e3Ssthen $bad_key = 0; 462898184e3Ssthen foreach $v (values %h) {} 463898184e3Ssthen is($bad_key, 0); 464898184e3Ssthen 465898184e3Ssthen undef $db; 466898184e3Ssthen untie %h; 467898184e3Ssthen unlink <Op_dbmx*>; 468898184e3Ssthen} 469898184e3Ssthen 470898184e3Ssthen{ 471898184e3Ssthen # Check that DBM Filter can cope with read-only $_ 472898184e3Ssthen 473898184e3Ssthen my %h; 474898184e3Ssthen unlink <Op1_dbmx*>; 475898184e3Ssthen 476898184e3Ssthen my $db = tie %h, $DBM_Class, 'Op1_dbmx', $create, 0640; 477898184e3Ssthen isa_ok($db, $DBM_Class); 478898184e3Ssthen 479898184e3Ssthen $db->filter_fetch_key (sub { }); 480898184e3Ssthen $db->filter_store_key (sub { }); 481898184e3Ssthen $db->filter_fetch_value (sub { }); 482898184e3Ssthen $db->filter_store_value (sub { }); 483898184e3Ssthen 484898184e3Ssthen $_ = "original"; 485898184e3Ssthen 486898184e3Ssthen $h{"fred"} = "joe"; 487898184e3Ssthen is($h{"fred"}, "joe"); 488898184e3Ssthen 489898184e3Ssthen is_deeply([eval { map { $h{$_} } (1, 2, 3) }], [undef, undef, undef]); 490898184e3Ssthen is($@, ''); 491898184e3Ssthen 492898184e3Ssthen 493898184e3Ssthen # delete the filters 494898184e3Ssthen $db->filter_fetch_key (undef); 495898184e3Ssthen $db->filter_store_key (undef); 496898184e3Ssthen $db->filter_fetch_value (undef); 497898184e3Ssthen $db->filter_store_value (undef); 498898184e3Ssthen 499898184e3Ssthen $h{"fred"} = "joe"; 500898184e3Ssthen 501898184e3Ssthen is($h{"fred"}, "joe"); 502898184e3Ssthen 503898184e3Ssthen is($db->FIRSTKEY(), "fred"); 504898184e3Ssthen 505898184e3Ssthen is_deeply([eval { map { $h{$_} } (1, 2, 3) }], [undef, undef, undef]); 506898184e3Ssthen is($@, ''); 507898184e3Ssthen 508898184e3Ssthen undef $db; 509898184e3Ssthen untie %h; 510898184e3Ssthen unlink <Op1_dbmx*>; 511898184e3Ssthen} 512898184e3Ssthen 513898184e3Ssthendone_testing(); 514898184e3Ssthen1; 515