home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / perl560.zip / t / lib / db-hash.t < prev    next >
Text File  |  1999-08-20  |  16KB  |  686 lines

  1. #!./perl -w
  2.  
  3. BEGIN {
  4.     unshift @INC, '../lib' if -d '../lib' ;
  5.     require Config; import Config;
  6.     if ($Config{'extensions'} !~ /\bDB_File\b/) {
  7.     print "1..0 # Skip: DB_File was not built\n";
  8.     exit 0;
  9.     }
  10. }
  11.  
  12. use DB_File; 
  13. use Fcntl;
  14.  
  15. print "1..109\n";
  16.  
  17. sub ok
  18. {
  19.     my $no = shift ;
  20.     my $result = shift ;
  21.  
  22.     print "not " unless $result ;
  23.     print "ok $no\n" ;
  24. }
  25.  
  26. {
  27.     package Redirect ;
  28.     use Symbol ;
  29.  
  30.     sub new
  31.     {
  32.         my $class = shift ;
  33.         my $filename = shift ;
  34.     my $fh = gensym ;
  35.     open ($fh, ">$filename") || die "Cannot open $filename: $!" ;
  36.     my $real_stdout = select($fh) ;
  37.     return bless [$fh, $real_stdout ] ;
  38.  
  39.     }
  40.     sub DESTROY
  41.     {
  42.         my $self = shift ;
  43.     close $self->[0] ;
  44.     select($self->[1]) ;
  45.     }
  46. }
  47.  
  48. sub docat_del
  49.     my $file = shift;
  50.     local $/ = undef;
  51.     open(CAT,$file) || die "Cannot open $file: $!";
  52.     my $result = <CAT>;
  53.     close(CAT);
  54.     unlink $file ;
  55.     return $result;
  56. }   
  57.  
  58. my $Dfile = "dbhash.tmp";
  59. unlink $Dfile;
  60.  
  61. umask(0);
  62.  
  63. # Check the interface to HASHINFO
  64.  
  65. my $dbh = new DB_File::HASHINFO ;
  66.  
  67. ok(1, ! defined $dbh->{bsize}) ;
  68. ok(2, ! defined $dbh->{ffactor}) ;
  69. ok(3, ! defined $dbh->{nelem}) ;
  70. ok(4, ! defined $dbh->{cachesize}) ;
  71. ok(5, ! defined $dbh->{hash}) ;
  72. ok(6, ! defined $dbh->{lorder}) ;
  73.  
  74. $dbh->{bsize} = 3000 ;
  75. ok(7, $dbh->{bsize} == 3000 );
  76.  
  77. $dbh->{ffactor} = 9000 ;
  78. ok(8, $dbh->{ffactor} == 9000 );
  79.  
  80. $dbh->{nelem} = 400 ;
  81. ok(9, $dbh->{nelem} == 400 );
  82.  
  83. $dbh->{cachesize} = 65 ;
  84. ok(10, $dbh->{cachesize} == 65 );
  85.  
  86. $dbh->{hash} = "abc" ;
  87. ok(11, $dbh->{hash} eq "abc" );
  88.  
  89. $dbh->{lorder} = 1234 ;
  90. ok(12, $dbh->{lorder} == 1234 );
  91.  
  92. # Check that an invalid entry is caught both for store & fetch
  93. eval '$dbh->{fred} = 1234' ;
  94. ok(13, $@ =~ /^DB_File::HASHINFO::STORE - Unknown element 'fred' at/ );
  95. eval 'my $q = $dbh->{fred}' ;
  96. ok(14, $@ =~ /^DB_File::HASHINFO::FETCH - Unknown element 'fred' at/ );
  97.  
  98.  
  99. # Now check the interface to HASH
  100.  
  101. ok(15, $X = tie(%h, 'DB_File',$Dfile, O_RDWR|O_CREAT, 0640, $DB_HASH ) );
  102.  
  103. ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
  104.    $blksize,$blocks) = stat($Dfile);
  105. ok(16, ($mode & 0777) == ($^O eq 'os2' ? 0666 : 0640) || $^O eq 'amigaos' || $^O eq 'MSWin32');
  106.  
  107. while (($key,$value) = each(%h)) {
  108.     $i++;
  109. }
  110. ok(17, !$i );
  111.  
  112. $h{'goner1'} = 'snork';
  113.  
  114. $h{'abc'} = 'ABC';
  115. ok(18, $h{'abc'} eq 'ABC' );
  116. ok(19, !defined $h{'jimmy'} );
  117. ok(20, !exists $h{'jimmy'} );
  118. ok(21, exists $h{'abc'} );
  119.  
  120. $h{'def'} = 'DEF';
  121. $h{'jkl','mno'} = "JKL\034MNO";
  122. $h{'a',2,3,4,5} = join("\034",'A',2,3,4,5);
  123. $h{'a'} = 'A';
  124.  
  125. #$h{'b'} = 'B';
  126. $X->STORE('b', 'B') ;
  127.  
  128. $h{'c'} = 'C';
  129.  
  130. #$h{'d'} = 'D';
  131. $X->put('d', 'D') ;
  132.  
  133. $h{'e'} = 'E';
  134. $h{'f'} = 'F';
  135. $h{'g'} = 'X';
  136. $h{'h'} = 'H';
  137. $h{'i'} = 'I';
  138.  
  139. $h{'goner2'} = 'snork';
  140. delete $h{'goner2'};
  141.  
  142.  
  143. # IMPORTANT - $X must be undefined before the untie otherwise the
  144. #             underlying DB close routine will not get called.
  145. undef $X ;
  146. untie(%h);
  147.  
  148.  
  149. # tie to the same file again, do not supply a type - should default to HASH
  150. ok(22, $X = tie(%h,'DB_File',$Dfile, O_RDWR, 0640) );
  151.  
  152. # Modify an entry from the previous tie
  153. $h{'g'} = 'G';
  154.  
  155. $h{'j'} = 'J';
  156. $h{'k'} = 'K';
  157. $h{'l'} = 'L';
  158. $h{'m'} = 'M';
  159. $h{'n'} = 'N';
  160. $h{'o'} = 'O';
  161. $h{'p'} = 'P';
  162. $h{'q'} = 'Q';
  163. $h{'r'} = 'R';
  164. $h{'s'} = 'S';
  165. $h{'t'} = 'T';
  166. $h{'u'} = 'U';
  167. $h{'v'} = 'V';
  168. $h{'w'} = 'W';
  169. $h{'x'} = 'X';
  170. $h{'y'} = 'Y';
  171. $h{'z'} = 'Z';
  172.  
  173. $h{'goner3'} = 'snork';
  174.  
  175. delete $h{'goner1'};
  176. $X->DELETE('goner3');
  177.  
  178. @keys = keys(%h);
  179. @values = values(%h);
  180.  
  181. ok(23, $#keys == 29 && $#values == 29) ;
  182.  
  183. $i = 0 ;
  184. while (($key,$value) = each(%h)) {
  185.     if ($key eq $keys[$i] && $value eq $values[$i] && $key eq lc($value)) {
  186.     $key =~ y/a-z/A-Z/;
  187.     $i++ if $key eq $value;
  188.     }
  189. }
  190.  
  191. ok(24, $i == 30) ;
  192.  
  193. @keys = ('blurfl', keys(%h), 'dyick');
  194. ok(25, $#keys == 31) ;
  195.  
  196. $h{'foo'} = '';
  197. ok(26, $h{'foo'} eq '' );
  198.  
  199. # Berkeley DB 2 from version 2.4.10 onwards does not allow null keys.
  200. # This feature will be reenabled in a future version of Berkeley DB.
  201. #$h{''} = 'bar';
  202. #ok(27, $h{''} eq 'bar' );
  203. ok(27,1) ;
  204.  
  205. # check cache overflow and numeric keys and contents
  206. $ok = 1;
  207. for ($i = 1; $i < 200; $i++) { $h{$i + 0} = $i + 0; }
  208. for ($i = 1; $i < 200; $i++) { $ok = 0 unless $h{$i} == $i; }
  209. ok(28, $ok );
  210.  
  211. ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
  212.    $blksize,$blocks) = stat($Dfile);
  213. ok(29, $size > 0 );
  214.  
  215. @h{0..200} = 200..400;
  216. @foo = @h{0..200};
  217. ok(30, join(':',200..400) eq join(':',@foo) );
  218.  
  219.  
  220. # Now check all the non-tie specific stuff
  221.  
  222. # Check NOOVERWRITE will make put fail when attempting to overwrite
  223. # an existing record.
  224.  
  225. $status = $X->put( 'x', 'newvalue', R_NOOVERWRITE) ;
  226. ok(31, $status == 1 );
  227.  
  228. # check that the value of the key 'x' has not been changed by the 
  229. # previous test
  230. ok(32, $h{'x'} eq 'X' );
  231.  
  232. # standard put
  233. $status = $X->put('key', 'value') ;
  234. ok(33, $status == 0 );
  235.  
  236. #check that previous put can be retrieved
  237. $value = 0 ;
  238. $status = $X->get('key', $value) ;
  239. ok(34, $status == 0 );
  240. ok(35, $value eq 'value' );
  241.  
  242. # Attempting to delete an existing key should work
  243.  
  244. $status = $X->del('q') ;
  245. ok(36, $status == 0 );
  246.  
  247. # Make sure that the key deleted, cannot be retrieved
  248. $^W = 0 ;
  249. ok(37, $h{'q'} eq undef );
  250. $^W = 1 ;
  251.  
  252. # Attempting to delete a non-existant key should fail
  253.  
  254. $status = $X->del('joe') ;
  255. ok(38, $status == 1 );
  256.  
  257. # Check the get interface
  258.  
  259. # First a non-existing key
  260. $status = $X->get('aaaa', $value) ;
  261. ok(39, $status == 1 );
  262.  
  263. # Next an existing key
  264. $status = $X->get('a', $value) ;
  265. ok(40, $status == 0 );
  266. ok(41, $value eq 'A' );
  267.  
  268. # seq
  269. # ###
  270.  
  271. # ditto, but use put to replace the key/value pair.
  272.  
  273. # use seq to walk backwards through a file - check that this reversed is
  274.  
  275. # check seq FIRST/LAST
  276.  
  277. # sync
  278. # ####
  279.  
  280. $status = $X->sync ;
  281. ok(42, $status == 0 );
  282.  
  283.  
  284. # fd
  285. # ##
  286.  
  287. $status = $X->fd ;
  288. ok(43, $status != 0 );
  289.  
  290. undef $X ;
  291. untie %h ;
  292.  
  293. unlink $Dfile;
  294.  
  295. # clear
  296. # #####
  297.  
  298. ok(44, tie(%h, 'DB_File', $Dfile, O_RDWR|O_CREAT, 0640, $DB_HASH ) );
  299. foreach (1 .. 10)
  300.   { $h{$_} = $_ * 100 }
  301.  
  302. # check that there are 10 elements in the hash
  303. $i = 0 ;
  304. while (($key,$value) = each(%h)) {
  305.     $i++;
  306. }
  307. ok(45, $i == 10);
  308.  
  309. # now clear the hash
  310. %h = () ;
  311.  
  312. # check it is empty
  313. $i = 0 ;
  314. while (($key,$value) = each(%h)) {
  315.     $i++;
  316. }
  317. ok(46, $i == 0);
  318.  
  319. untie %h ;
  320. unlink $Dfile ;
  321.  
  322.  
  323. # Now try an in memory file
  324. ok(47, $X = tie(%h, 'DB_File',undef, O_RDWR|O_CREAT, 0640, $DB_HASH ) );
  325.  
  326. # fd with an in memory file should return fail
  327. $status = $X->fd ;
  328. ok(48, $status == -1 );
  329.  
  330. undef $X ;
  331. untie %h ;
  332.  
  333. {
  334.     # check ability to override the default hashing
  335.     my %x ;
  336.     my $filename = "xyz" ;
  337.     my $hi = new DB_File::HASHINFO ;
  338.     $::count = 0 ;
  339.     $hi->{hash} = sub { ++$::count ; length $_[0] } ;
  340.     ok(49, tie %x, 'DB_File', $filename, O_RDWR|O_CREAT, 0640, $hi ) ;
  341.     $h{"abc"} = 123 ;
  342.     ok(50, $h{"abc"} == 123) ;
  343.     untie %x ;
  344.     unlink $filename ;
  345.     ok(51, $::count >0) ;
  346. }
  347.  
  348. {
  349.     # check that attempting to tie an array to a DB_HASH will fail
  350.  
  351.     my $filename = "xyz" ;
  352.     my @x ;
  353.     eval { tie @x, 'DB_File', $filename, O_RDWR|O_CREAT, 0640, $DB_HASH ; } ;
  354.     ok(52, $@ =~ /^DB_File can only tie an associative array to a DB_HASH database/) ;
  355.     unlink $filename ;
  356. }
  357.  
  358. {
  359.    # sub-class test
  360.  
  361.    package Another ;
  362.  
  363.    use strict ;
  364.  
  365.    open(FILE, ">SubDB.pm") or die "Cannot open SubDB.pm: $!\n" ;
  366.    print FILE <<'EOM' ;
  367.  
  368.    package SubDB ;
  369.  
  370.    use strict ;
  371.    use vars qw( @ISA @EXPORT) ;
  372.  
  373.    require Exporter ;
  374.    use DB_File;
  375.    @ISA=qw(DB_File);
  376.    @EXPORT = @DB_File::EXPORT ;
  377.  
  378.    sub STORE { 
  379.     my $self = shift ;
  380.         my $key = shift ;
  381.         my $value = shift ;
  382.         $self->SUPER::STORE($key, $value * 2) ;
  383.    }
  384.  
  385.    sub FETCH { 
  386.     my $self = shift ;
  387.         my $key = shift ;
  388.         $self->SUPER::FETCH($key) - 1 ;
  389.    }
  390.  
  391.    sub put { 
  392.     my $self = shift ;
  393.         my $key = shift ;
  394.         my $value = shift ;
  395.         $self->SUPER::put($key, $value * 3) ;
  396.    }
  397.  
  398.    sub get { 
  399.     my $self = shift ;
  400.         $self->SUPER::get($_[0], $_[1]) ;
  401.     $_[1] -= 2 ;
  402.    }
  403.  
  404.    sub A_new_method
  405.    {
  406.     my $self = shift ;
  407.         my $key = shift ;
  408.         my $value = $self->FETCH($key) ;
  409.     return "[[$value]]" ;
  410.    }
  411.  
  412.    1 ;
  413. EOM
  414.  
  415.     close FILE ;
  416.  
  417.     BEGIN { push @INC, '.'; }             
  418.     eval 'use SubDB ; ';
  419.     main::ok(53, $@ eq "") ;
  420.     my %h ;
  421.     my $X ;
  422.     eval '
  423.     $X = tie(%h, "SubDB","dbhash.tmp", O_RDWR|O_CREAT, 0640, $DB_HASH );
  424.     ' ;
  425.  
  426.     main::ok(54, $@ eq "") ;
  427.  
  428.     my $ret = eval '$h{"fred"} = 3 ; return $h{"fred"} ' ;
  429.     main::ok(55, $@ eq "") ;
  430.     main::ok(56, $ret == 5) ;
  431.  
  432.     my $value = 0;
  433.     $ret = eval '$X->put("joe", 4) ; $X->get("joe", $value) ; return $value' ;
  434.     main::ok(57, $@ eq "") ;
  435.     main::ok(58, $ret == 10) ;
  436.  
  437.     $ret = eval ' R_NEXT eq main::R_NEXT ' ;
  438.     main::ok(59, $@ eq "" ) ;
  439.     main::ok(60, $ret == 1) ;
  440.  
  441.     $ret = eval '$X->A_new_method("joe") ' ;
  442.     main::ok(61, $@ eq "") ;
  443.     main::ok(62, $ret eq "[[11]]") ;
  444.  
  445.     undef $X;
  446.     untie(%h);
  447.     unlink "SubDB.pm", "dbhash.tmp" ;
  448.  
  449. }
  450.  
  451. {
  452.    # DBM Filter tests
  453.    use strict ;
  454.    my (%h, $db) ;
  455.    my ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  456.    unlink $Dfile;
  457.  
  458.    sub checkOutput
  459.    {
  460.        my($fk, $sk, $fv, $sv) = @_ ;
  461.        return
  462.            $fetch_key eq $fk && $store_key eq $sk && 
  463.        $fetch_value eq $fv && $store_value eq $sv &&
  464.        $_ eq 'original' ;
  465.    }
  466.    
  467.    ok(63, $db = tie(%h, 'DB_File', $Dfile, O_RDWR|O_CREAT, 0640, $DB_HASH ) );
  468.  
  469.    $db->filter_fetch_key   (sub { $fetch_key = $_ }) ;
  470.    $db->filter_store_key   (sub { $store_key = $_ }) ;
  471.    $db->filter_fetch_value (sub { $fetch_value = $_}) ;
  472.    $db->filter_store_value (sub { $store_value = $_ }) ;
  473.  
  474.    $_ = "original" ;
  475.  
  476.    $h{"fred"} = "joe" ;
  477.    #                   fk   sk     fv   sv
  478.    ok(64, checkOutput( "", "fred", "", "joe")) ;
  479.  
  480.    ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  481.    ok(65, $h{"fred"} eq "joe");
  482.    #                   fk    sk     fv    sv
  483.    ok(66, checkOutput( "", "fred", "joe", "")) ;
  484.  
  485.    ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  486.    ok(67, $db->FIRSTKEY() eq "fred") ;
  487.    #                    fk     sk  fv  sv
  488.    ok(68, checkOutput( "fred", "", "", "")) ;
  489.  
  490.    # replace the filters, but remember the previous set
  491.    my ($old_fk) = $db->filter_fetch_key   
  492.                (sub { $_ = uc $_ ; $fetch_key = $_ }) ;
  493.    my ($old_sk) = $db->filter_store_key   
  494.                (sub { $_ = lc $_ ; $store_key = $_ }) ;
  495.    my ($old_fv) = $db->filter_fetch_value 
  496.                (sub { $_ = "[$_]"; $fetch_value = $_ }) ;
  497.    my ($old_sv) = $db->filter_store_value 
  498.                (sub { s/o/x/g; $store_value = $_ }) ;
  499.    
  500.    ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  501.    $h{"Fred"} = "Joe" ;
  502.    #                   fk   sk     fv    sv
  503.    ok(69, checkOutput( "", "fred", "", "Jxe")) ;
  504.  
  505.    ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  506.    ok(70, $h{"Fred"} eq "[Jxe]");
  507.    #                   fk   sk     fv    sv
  508.    ok(71, checkOutput( "", "fred", "[Jxe]", "")) ;
  509.  
  510.    ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  511.    ok(72, $db->FIRSTKEY() eq "FRED") ;
  512.    #                   fk   sk     fv    sv
  513.    ok(73, checkOutput( "FRED", "", "", "")) ;
  514.  
  515.    # put the original filters back
  516.    $db->filter_fetch_key   ($old_fk);
  517.    $db->filter_store_key   ($old_sk);
  518.    $db->filter_fetch_value ($old_fv);
  519.    $db->filter_store_value ($old_sv);
  520.  
  521.    ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  522.    $h{"fred"} = "joe" ;
  523.    ok(74, checkOutput( "", "fred", "", "joe")) ;
  524.  
  525.    ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  526.    ok(75, $h{"fred"} eq "joe");
  527.    ok(76, checkOutput( "", "fred", "joe", "")) ;
  528.  
  529.    ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  530.    ok(77, $db->FIRSTKEY() eq "fred") ;
  531.    ok(78, checkOutput( "fred", "", "", "")) ;
  532.  
  533.    # delete the filters
  534.    $db->filter_fetch_key   (undef);
  535.    $db->filter_store_key   (undef);
  536.    $db->filter_fetch_value (undef);
  537.    $db->filter_store_value (undef);
  538.  
  539.    ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  540.    $h{"fred"} = "joe" ;
  541.    ok(79, checkOutput( "", "", "", "")) ;
  542.  
  543.    ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  544.    ok(80, $h{"fred"} eq "joe");
  545.    ok(81, checkOutput( "", "", "", "")) ;
  546.  
  547.    ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
  548.    ok(82, $db->FIRSTKEY() eq "fred") ;
  549.    ok(83, checkOutput( "", "", "", "")) ;
  550.  
  551.    undef $db ;
  552.    untie %h;
  553.    unlink $Dfile;
  554. }
  555.  
  556. {    
  557.     # DBM Filter with a closure
  558.  
  559.     use strict ;
  560.     my (%h, $db) ;
  561.  
  562.     unlink $Dfile;
  563.     ok(84, $db = tie(%h, 'DB_File', $Dfile, O_RDWR|O_CREAT, 0640, $DB_HASH ) );
  564.  
  565.     my %result = () ;
  566.  
  567.     sub Closure
  568.     {
  569.         my ($name) = @_ ;
  570.     my $count = 0 ;
  571.     my @kept = () ;
  572.  
  573.     return sub { ++$count ; 
  574.              push @kept, $_ ; 
  575.              $result{$name} = "$name - $count: [@kept]" ;
  576.            }
  577.     }
  578.  
  579.     $db->filter_store_key(Closure("store key")) ;
  580.     $db->filter_store_value(Closure("store value")) ;
  581.     $db->filter_fetch_key(Closure("fetch key")) ;
  582.     $db->filter_fetch_value(Closure("fetch value")) ;
  583.  
  584.     $_ = "original" ;
  585.  
  586.     $h{"fred"} = "joe" ;
  587.     ok(85, $result{"store key"} eq "store key - 1: [fred]");
  588.     ok(86, $result{"store value"} eq "store value - 1: [joe]");
  589.     ok(87, ! defined $result{"fetch key"} );
  590.     ok(88, ! defined $result{"fetch value"} );
  591.     ok(89, $_ eq "original") ;
  592.  
  593.     ok(90, $db->FIRSTKEY() eq "fred") ;
  594.     ok(91, $result{"store key"} eq "store key - 1: [fred]");
  595.     ok(92, $result{"store value"} eq "store value - 1: [joe]");
  596.     ok(93, $result{"fetch key"} eq "fetch key - 1: [fred]");
  597.     ok(94, ! defined $result{"fetch value"} );
  598.     ok(95, $_ eq "original") ;
  599.  
  600.     $h{"jim"}  = "john" ;
  601.     ok(96, $result{"store key"} eq "store key - 2: [fred jim]");
  602.     ok(97, $result{"store value"} eq "store value - 2: [joe john]");
  603.     ok(98, $result{"fetch key"} eq "fetch key - 1: [fred]");
  604.     ok(99, ! defined $result{"fetch value"} );
  605.     ok(100, $_ eq "original") ;
  606.  
  607.     ok(101, $h{"fred"} eq "joe");
  608.     ok(102, $result{"store key"} eq "store key - 3: [fred jim fred]");
  609.     ok(103, $result{"store value"} eq "store value - 2: [joe john]");
  610.     ok(104, $result{"fetch key"} eq "fetch key - 1: [fred]");
  611.     ok(105, $result{"fetch value"} eq "fetch value - 1: [joe]");
  612.     ok(106, $_ eq "original") ;
  613.  
  614.     undef $db ;
  615.     untie %h;
  616.     unlink $Dfile;
  617. }        
  618.  
  619. {
  620.    # DBM Filter recursion detection
  621.    use strict ;
  622.    my (%h, $db) ;
  623.    unlink $Dfile;
  624.  
  625.    ok(107, $db = tie(%h, 'DB_File', $Dfile, O_RDWR|O_CREAT, 0640, $DB_HASH ) );
  626.  
  627.    $db->filter_store_key (sub { $_ = $h{$_} }) ;
  628.  
  629.    eval '$h{1} = 1234' ;
  630.    ok(108, $@ =~ /^recursion detected in filter_store_key at/ );
  631.    
  632.    undef $db ;
  633.    untie %h;
  634.    unlink $Dfile;
  635. }
  636.  
  637.  
  638. {
  639.    # Examples from the POD
  640.  
  641.   my $file = "xyzt" ;
  642.   {
  643.     my $redirect = new Redirect $file ;
  644.  
  645.     use strict ;
  646.     use DB_File ;
  647.     use vars qw( %h $k $v ) ;
  648.  
  649.     unlink "fruit" ;
  650.     tie %h, "DB_File", "fruit", O_RDWR|O_CREAT, 0640, $DB_HASH 
  651.         or die "Cannot open file 'fruit': $!\n";
  652.  
  653.     # Add a few key/value pairs to the file
  654.     $h{"apple"} = "red" ;
  655.     $h{"orange"} = "orange" ;
  656.     $h{"banana"} = "yellow" ;
  657.     $h{"tomato"} = "red" ;
  658.  
  659.     # Check for existence of a key
  660.     print "Banana Exists\n\n" if $h{"banana"} ;
  661.  
  662.     # Delete a key/value pair.
  663.     delete $h{"apple"} ;
  664.  
  665.     # print the contents of the file
  666.     while (($k, $v) = each %h)
  667.       { print "$k -> $v\n" }
  668.  
  669.     untie %h ;
  670.  
  671.     unlink "fruit" ;
  672.   }  
  673.  
  674.   ok(109, docat_del($file) eq <<'EOM') ;
  675. Banana Exists
  676.  
  677. orange -> orange
  678. tomato -> red
  679. banana -> yellow
  680. EOM
  681.    
  682. }
  683.  
  684. exit ;
  685.