3 # $RCSfile: dbm.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:43 $
6 require Config; import Config;
7 if ($Config{'extensions'} !~ /\bGDBM_File\b/) {
8 print "1..0 # Skip: GDBM_File was not built\n";
16 use Test::More tests => 81;
23 isa_ok(tie(%h, 'GDBM_File', 'Op.dbmx', GDBM_WRCREAT, 0640), 'GDBM_File');
25 my $Dfile = "Op.dbmx.pag";
27 ($Dfile) = <Op.dbmx*>;
30 skip " different file permission semantics on $^O", 1
31 if $^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'dos' || $^O eq 'cygwin';
33 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
34 $blksize,$blocks) = stat($Dfile);
35 is($mode & 0777, 0640);
38 while (my ($key,$value) = each(%h)) {
43 $h{'goner1'} = 'snork';
47 $h{'jkl','mno'} = "JKL\034MNO";
48 $h{'a',2,3,4,5} = join("\034",'A',2,3,4,5);
59 $h{'goner2'} = 'snork';
63 isa_ok(tie(%h, 'GDBM_File', 'Op.dbmx', GDBM_WRITER, 0640), 'GDBM_File');
83 $h{'goner3'} = 'snork';
89 my @values = values(%h);
94 while (my ($key,$value) = each(%h)) {
95 if ($key eq $keys[$i] && $value eq $values[$i] && $key eq lc($value)) {
97 $i++ if $key eq $value;
103 @keys = ('blurfl', keys(%h), 'dyick');
110 for ($i = 1; $i < 200; $i++) { $h{$i + 0} = $i + 0; }
111 for ($i = 1; $i < 200; $i++) { $ok = 0 unless $h{$i} == $i; }
112 is($ok, 1, 'check cache overflow and numeric keys and contents');
114 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
115 $blksize,$blocks) = stat($Dfile);
116 cmp_ok($size, '>', 0);
118 @h{0..200} = 200..400;
119 my @foo = @h{0..200};
120 is(join(':',200..400), join(':',@foo));
126 unlink 'Op.dbmx.dir', $Dfile;
133 open(FILE, ">SubDB.pm") or die "Cannot open SubDB.pm: $!\n" ;
139 use vars qw(@ISA @EXPORT) ;
144 @EXPORT = @GDBM_File::EXPORT ;
150 $self->SUPER::STORE($key, $value * 2) ;
156 $self->SUPER::FETCH($key) - 1 ;
163 my $value = $self->FETCH($key) ;
164 return "[[$value]]" ;
172 BEGIN { push @INC, '.'; }
173 unlink <dbhash.tmp*> ;
180 $X = tie(%h, "SubDB","dbhash.tmp", &GDBM_WRCREAT, 0640 );
185 my $ret = eval '$h{"fred"} = 3 ; return $h{"fred"} ' ;
189 $ret = eval ' &GDBM_WRCREAT eq &main::GDBM_WRCREAT ' ;
193 $ret = eval '$X->A_new_method("fred") ' ;
195 main::is($ret, "[[5]]");
199 unlink "SubDB.pm", <dbhash.tmp*> ;
206 my ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
210 my($fk, $sk, $fv, $sv) = @_ ;
212 $fetch_key eq $fk && $store_key eq $sk &&
213 $fetch_value eq $fv && $store_value eq $sv &&
218 $db = tie %h, 'GDBM_File', 'Op.dbmx', GDBM_WRCREAT, 0640;
219 isa_ok($db, 'GDBM_File');
221 $db->filter_fetch_key (sub { $fetch_key = $_ }) ;
222 $db->filter_store_key (sub { $store_key = $_ }) ;
223 $db->filter_fetch_value (sub { $fetch_value = $_}) ;
224 $db->filter_store_value (sub { $store_value = $_ }) ;
230 ok(checkOutput("", "fred", "", "joe"));
232 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
233 is($h{"fred"}, "joe");
235 ok(checkOutput("", "fred", "joe", ""));
237 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
238 is($db->FIRSTKEY(), "fred");
240 ok(checkOutput("fred", "", "", ""));
242 # replace the filters, but remember the previous set
243 my ($old_fk) = $db->filter_fetch_key
244 (sub { $_ = uc $_ ; $fetch_key = $_ }) ;
245 my ($old_sk) = $db->filter_store_key
246 (sub { $_ = lc $_ ; $store_key = $_ }) ;
247 my ($old_fv) = $db->filter_fetch_value
248 (sub { $_ = "[$_]"; $fetch_value = $_ }) ;
249 my ($old_sv) = $db->filter_store_value
250 (sub { s/o/x/g; $store_value = $_ }) ;
252 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
255 ok(checkOutput("", "fred", "", "Jxe"));
257 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
258 is($h{"Fred"}, "[Jxe]");
260 ok(checkOutput("", "fred", "[Jxe]", ""));
262 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
263 is($db->FIRSTKEY(), "FRED");
265 ok(checkOutput("FRED", "", "", ""));
267 # put the original filters back
268 $db->filter_fetch_key ($old_fk);
269 $db->filter_store_key ($old_sk);
270 $db->filter_fetch_value ($old_fv);
271 $db->filter_store_value ($old_sv);
273 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
275 ok(checkOutput("", "fred", "", "joe"));
277 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
278 is($h{"fred"}, "joe");
279 ok(checkOutput("", "fred", "joe", ""));
281 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
282 is($db->FIRSTKEY(), "fred");
283 ok(checkOutput("fred", "", "", ""));
286 $db->filter_fetch_key (undef);
287 $db->filter_store_key (undef);
288 $db->filter_fetch_value (undef);
289 $db->filter_store_value (undef);
291 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
293 ok(checkOutput("", "", "", ""));
295 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
296 is($h{"fred"}, "joe");
297 ok(checkOutput("", "", "", ""));
299 ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ;
300 is($db->FIRSTKEY(), "fred");
301 ok(checkOutput("", "", "", ""));
309 # DBM Filter with a closure
314 $db = tie %h, 'GDBM_File','Op.dbmx', GDBM_WRCREAT, 0640;
315 isa_ok($db, 'GDBM_File');
325 return sub { ++$count ;
327 $result{$name} = "$name - $count: [@kept]" ;
331 $db->filter_store_key(Closure("store key")) ;
332 $db->filter_store_value(Closure("store value")) ;
333 $db->filter_fetch_key(Closure("fetch key")) ;
334 $db->filter_fetch_value(Closure("fetch value")) ;
339 is($result{"store key"}, "store key - 1: [fred]");
340 is($result{"store value"}, "store value - 1: [joe]");
341 is($result{"fetch key"}, undef);
342 is($result{"fetch value"}, undef);
345 is($db->FIRSTKEY(), "fred");
346 is($result{"store key"}, "store key - 1: [fred]");
347 is($result{"store value"}, "store value - 1: [joe]");
348 is($result{"fetch key"}, "fetch key - 1: [fred]");
349 is($result{"fetch value"}, undef);
353 is($result{"store key"}, "store key - 2: [fred jim]");
354 is($result{"store value"}, "store value - 2: [joe john]");
355 is($result{"fetch key"}, "fetch key - 1: [fred]");
356 is($result{"fetch value"}, undef);
359 is($h{"fred"}, "joe");
360 is($result{"store key"}, "store key - 3: [fred jim fred]");
361 is($result{"store value"}, "store value - 2: [joe john]");
362 is($result{"fetch key"}, "fetch key - 1: [fred]");
363 is($result{"fetch value"}, "fetch value - 1: [joe]");
372 # DBM Filter recursion detection
376 $db = tie %h, 'GDBM_File','Op.dbmx', GDBM_WRCREAT, 0640;
377 isa_ok($db, 'GDBM_File');
379 $db->filter_store_key (sub { $_ = $h{$_} }) ;
381 eval '$h{1} = 1234' ;
382 like($@, qr/^recursion detected in filter_store_key at/);
390 # Bug ID 20001013.009
392 # test that $hash{KEY} = undef doesn't produce the warning
393 # Use of uninitialized value in null operation
398 local $SIG{__WARN__} = sub {$a = $_[0]} ;
400 isa_ok(tie(%h, 'GDBM_File', 'Op.dbmx', GDBM_WRCREAT, 0640), 'GDBM_File');
408 # When iterating over a tied hash using "each", the key passed to FETCH
409 # will be recycled and passed to NEXTKEY. If a Source Filter modifies the
410 # key in FETCH via a filter_fetch_key method we need to check that the
411 # modified key doesn't get passed to NEXTKEY.
412 # Also Test "keys" & "values" while we are at it.
417 my $db = tie %h, 'GDBM_File', 'Op.dbmx', GDBM_WRCREAT, 0640;
418 isa_ok($db, 'GDBM_File');
419 $db->filter_fetch_key (sub { $_ =~ s/^Beta_/Alpha_/ if defined $_}) ;
420 $db->filter_store_key (sub { $bad_key = 1 if /^Beta_/ ; $_ =~ s/^Alpha_/Beta_/}) ;
422 $h{'Alpha_ABC'} = 2 ;
423 $h{'Alpha_DEF'} = 5 ;
425 is($h{'Alpha_ABC'}, 2);
426 is($h{'Alpha_DEF'}, 5);
428 my ($k, $v) = ("","");
429 while (($k, $v) = each %h) {}
433 foreach $k (keys %h) {}
437 foreach $v (values %h) {}
446 # Check that DBM Filter can cope with read-only $_
451 my $db = tie %h, 'GDBM_File', 'Op.dbmx', GDBM_WRCREAT, 0640;
452 isa_ok($db, 'GDBM_File');
455 $db->filter_fetch_key (sub { }) ;
456 $db->filter_store_key (sub { }) ;
457 $db->filter_fetch_value (sub { }) ;
458 $db->filter_store_value (sub { }) ;
463 is($h{"fred"}, "joe");
465 eval { my @r= grep { $h{$_} } (1, 2, 3) };
470 $db->filter_fetch_key (undef);
471 $db->filter_store_key (undef);
472 $db->filter_fetch_value (undef);
473 $db->filter_store_value (undef);
477 is($h{"fred"}, "joe");
479 is($db->FIRSTKEY(), "fred");
481 eval { my @r= grep { $h{$_} } (1, 2, 3) };