3 # $RCSfile: dbm.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:43 $
6 require Config; import Config;
7 if ($Config{'extensions'} !~ /\bSDBM_File\b/) {
8 print "1..0 # Skip: no SDBM_File\n";
16 use Test::More tests => 81;
19 #If Fcntl is not available, try 0x202 or 0x102 for O_RDWR|O_CREAT
26 isa_ok(tie(%h, 'SDBM_File', 'Op_dbmx', O_RDWR|O_CREAT, 0640), 'SDBM_File');
28 my $Dfile = "Op_dbmx.pag";
30 ($Dfile) = <Op_dbmx*>;
33 skip "different file permission semantics on $^O", 1
34 if $^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'dos' || $^O eq 'cygwin';
35 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
36 $blksize,$blocks) = stat($Dfile);
37 is($mode & 0777, 0640);
40 while (my ($key,$value) = each(%h)) {
45 $h{'goner1'} = 'snork';
49 $h{'jkl','mno'} = "JKL\034MNO";
50 $h{'a',2,3,4,5} = join("\034",'A',2,3,4,5);
61 $h{'goner2'} = 'snork';
65 isa_ok(tie(%h, 'SDBM_File', 'Op_dbmx', O_RDWR, 0640), 'SDBM_File');
85 $h{'goner3'} = 'snork';
91 my @values = values(%h);
96 while (my ($key,$value) = each(%h)) {
97 if ($key eq $keys[$i] && $value eq $values[$i] && $key eq lc($value)) {
99 $i++ if $key eq $value;
105 @keys = ('blurfl', keys(%h), 'dyick');
112 for ($i = 1; $i < 200; $i++) { $h{$i + 0} = $i + 0; }
113 for ($i = 1; $i < 200; $i++) { $ok = 0 unless $h{$i} == $i; }
114 is($ok, 1, 'check cache overflow and numeric keys and contents');
116 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
117 $blksize,$blocks) = stat($Dfile);
118 cmp_ok($size, '>', 0);
120 @h{0..200} = 200..400;
121 my @foo = @h{0..200};
122 is(join(':',200..400), join(':',@foo));
127 is(exists $h{goner1}, '');
128 is(exists $h{foo}, 1);
131 unlink <Op_dbmx*>, $Dfile;
138 open(FILE, ">SubDB.pm") or die "Cannot open SubDB.pm: $!\n" ;
145 use vars qw( @ISA @EXPORT) ;
150 @EXPORT = @SDBM_File::EXPORT if @SDBM_File::EXPORT ;
156 $self->SUPER::STORE($key, $value * 2) ;
162 $self->SUPER::FETCH($key) - 1 ;
169 my $value = $self->FETCH($key) ;
170 return "[[$value]]" ;
176 close FILE or die "Could not close: $!";
178 BEGIN { push @INC, '.'; }
179 unlink <dbhash_tmp*> ;
181 eval 'use SubDB ; use Fcntl ;';
186 $X = tie(%h, "SubDB","dbhash_tmp", O_RDWR|O_CREAT, 0640 );
191 my $ret = eval '$h{"fred"} = 3 ; return $h{"fred"} ' ;
195 $ret = eval '$X->A_new_method("fred") ' ;
197 main::is($ret, "[[5]]");
201 unlink "SubDB.pm", <dbhash_tmp.*> ;
206 unlink <Op_dbmx*>, $Dfile;
211 my ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
215 my($fk, $sk, $fv, $sv) = @_ ;
217 $fetch_key eq $fk && $store_key eq $sk &&
218 $fetch_value eq $fv && $store_value eq $sv &&
223 $db = tie %h, 'SDBM_File', 'Op_dbmx', O_RDWR|O_CREAT, 0640;
224 isa_ok($db, 'SDBM_File');
226 $db->filter_fetch_key (sub { $fetch_key = $_ }) ;
227 $db->filter_store_key (sub { $store_key = $_ }) ;
228 $db->filter_fetch_value (sub { $fetch_value = $_}) ;
229 $db->filter_store_value (sub { $store_value = $_ }) ;
235 ok(checkOutput("", "fred", "", "joe"));
237 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
238 is($h{"fred"}, "joe");
240 ok(checkOutput("", "fred", "joe", ""));
242 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
243 is($db->FIRSTKEY(), "fred");
245 ok(checkOutput("fred", "", "", ""));
247 # replace the filters, but remember the previous set
248 my ($old_fk) = $db->filter_fetch_key
249 (sub { $_ = uc $_ ; $fetch_key = $_ }) ;
250 my ($old_sk) = $db->filter_store_key
251 (sub { $_ = lc $_ ; $store_key = $_ }) ;
252 my ($old_fv) = $db->filter_fetch_value
253 (sub { $_ = "[$_]"; $fetch_value = $_ }) ;
254 my ($old_sv) = $db->filter_store_value
255 (sub { s/o/x/g; $store_value = $_ }) ;
257 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
260 ok(checkOutput("", "fred", "", "Jxe"));
262 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
263 is($h{"Fred"}, "[Jxe]");
265 ok(checkOutput("", "fred", "[Jxe]", ""));
267 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
268 is($db->FIRSTKEY(), "FRED");
270 ok(checkOutput("FRED", "", "", ""));
272 # put the original filters back
273 $db->filter_fetch_key ($old_fk);
274 $db->filter_store_key ($old_sk);
275 $db->filter_fetch_value ($old_fv);
276 $db->filter_store_value ($old_sv);
278 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
280 ok(checkOutput("", "fred", "", "joe"));
282 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
283 is($h{"fred"}, "joe");
284 ok(checkOutput("", "fred", "joe", ""));
286 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
287 is($db->FIRSTKEY(), "fred");
288 ok(checkOutput("fred", "", "", ""));
291 $db->filter_fetch_key (undef);
292 $db->filter_store_key (undef);
293 $db->filter_fetch_value (undef);
294 $db->filter_store_value (undef);
296 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
298 ok(checkOutput("", "", "", ""));
300 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
301 is($h{"fred"}, "joe");
302 ok(checkOutput("", "", "", ""));
304 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
305 is($db->FIRSTKEY(), "fred");
306 ok(checkOutput("", "", "", ""));
314 # DBM Filter with a closure
319 $db = tie %h, 'SDBM_File', 'Op_dbmx', O_RDWR|O_CREAT, 0640;
320 isa_ok($db, 'SDBM_File');
330 return sub { ++$count ;
332 $result{$name} = "$name - $count: [@kept]" ;
336 $db->filter_store_key(Closure("store key")) ;
337 $db->filter_store_value(Closure("store value")) ;
338 $db->filter_fetch_key(Closure("fetch key")) ;
339 $db->filter_fetch_value(Closure("fetch value")) ;
344 is($result{"store key"}, "store key - 1: [fred]");
345 is($result{"store value"}, "store value - 1: [joe]");
346 is($result{"fetch key"}, undef);
347 is($result{"fetch value"}, undef);
350 is($db->FIRSTKEY(), "fred");
351 is($result{"store key"}, "store key - 1: [fred]");
352 is($result{"store value"}, "store value - 1: [joe]");
353 is($result{"fetch key"}, "fetch key - 1: [fred]");
354 is($result{"fetch value"}, undef);
358 is($result{"store key"}, "store key - 2: [fred jim]");
359 is($result{"store value"}, "store value - 2: [joe john]");
360 is($result{"fetch key"}, "fetch key - 1: [fred]");
361 is($result{"fetch value"}, undef);
364 is($h{"fred"}, "joe");
365 is($result{"store key"}, "store key - 3: [fred jim fred]");
366 is($result{"store value"}, "store value - 2: [joe john]");
367 is($result{"fetch key"}, "fetch key - 1: [fred]");
368 is($result{"fetch value"}, "fetch value - 1: [joe]");
377 # DBM Filter recursion detection
381 $db = tie %h, 'SDBM_File', 'Op_dbmx', O_RDWR|O_CREAT, 0640;
382 isa_ok($db, 'SDBM_File');
384 $db->filter_store_key (sub { $_ = $h{$_} }) ;
386 eval '$h{1} = 1234' ;
387 like($@, qr/^recursion detected in filter_store_key at/);
395 # Bug ID 20001013.009
397 # test that $hash{KEY} = undef doesn't produce the warning
398 # Use of uninitialized value in null operation
403 local $SIG{__WARN__} = sub {$a = $_[0]} ;
405 isa_ok(tie(%h, 'SDBM_File', 'Op_dbmx', O_RDWR|O_CREAT, 0640), 'SDBM_File');
413 # When iterating over a tied hash using "each", the key passed to FETCH
414 # will be recycled and passed to NEXTKEY. If a Source Filter modifies the
415 # key in FETCH via a filter_fetch_key method we need to check that the
416 # modified key doesn't get passed to NEXTKEY.
417 # Also Test "keys" & "values" while we are at it.
422 my $db = tie %h, 'SDBM_File','Op_dbmx', O_RDWR|O_CREAT, 0640;
423 isa_ok($db, 'SDBM_File');
424 $db->filter_fetch_key (sub { $_ =~ s/^Beta_/Alpha_/ if defined $_}) ;
425 $db->filter_store_key (sub { $bad_key = 1 if /^Beta_/ ; $_ =~ s/^Alpha_/Beta_/}) ;
427 $h{'Alpha_ABC'} = 2 ;
428 $h{'Alpha_DEF'} = 5 ;
430 is($h{'Alpha_ABC'}, 2);
431 is($h{'Alpha_DEF'}, 5);
433 my ($k, $v) = ("","");
434 while (($k, $v) = each %h) {}
438 foreach $k (keys %h) {}
442 foreach $v (values %h) {}
452 # Check that DBM Filter can cope with read-only $_
457 my $db = tie %h, 'SDBM_File', 'Op1_dbmx', O_RDWR|O_CREAT, 0640;
458 isa_ok($db, 'SDBM_File');
460 $db->filter_fetch_key (sub { }) ;
461 $db->filter_store_key (sub { }) ;
462 $db->filter_fetch_value (sub { }) ;
463 $db->filter_store_value (sub { }) ;
468 is($h{"fred"}, "joe");
470 eval { grep { $h{$_} } (1, 2, 3) };
475 $db->filter_fetch_key (undef);
476 $db->filter_store_key (undef);
477 $db->filter_fetch_value (undef);
478 $db->filter_store_value (undef);
482 is($h{"fred"}, "joe");
484 is($db->FIRSTKEY(), "fred");
486 eval { map { $h{$_} } (1, 2, 3) };