📄 db-btree.t
字号:
}@srt_2 = sort { $a cmp $b } @Keys ;@srt_3 = sort { length $a <=> length $b } @Keys ; foreach (@Keys) { $h{$_} = 1 ; $g{$_} = 1 ; $k{$_} = 1 ;} sub ArrayCompare{ my($a, $b) = @_ ; return 0 if @$a != @$b ; foreach (1 .. length @$a) { return 0 unless $$a[$_] eq $$b[$_] ; } 1 ;} ok(84, ArrayCompare (\@srt_1, [keys %h]) );ok(85, ArrayCompare (\@srt_2, [keys %g]) );ok(86, ArrayCompare (\@srt_3, [keys %k]) );untie %h ;untie %g ;untie %k ;unlink $Dfile1, $Dfile2, $Dfile3 ;# clear# #####ok(87, tie(%h, 'DB_File', $Dfile1, O_RDWR|O_CREAT, 0640, $DB_BTREE ) );foreach (1 .. 10) { $h{$_} = $_ * 100 }# check that there are 10 elements in the hash$i = 0 ;while (($key,$value) = each(%h)) { $i++;}ok(88, $i == 10);# now clear the hash%h = () ;# check it is empty$i = 0 ;while (($key,$value) = each(%h)) { $i++;}ok(89, $i == 0);untie %h ;unlink $Dfile1 ;{ # check that attempting to tie an array to a DB_BTREE will fail my $filename = "xyz" ; my @x ; eval { tie @x, 'DB_File', $filename, O_RDWR|O_CREAT, 0640, $DB_BTREE ; } ; ok(90, $@ =~ /^DB_File can only tie an associative array to a DB_BTREE database/) ; unlink $filename ;}{ # sub-class test package Another ; use warnings ; use strict ; open(FILE, ">SubDB.pm") or die "Cannot open SubDB.pm: $!\n" ; print FILE <<'EOM' ; package SubDB ; use warnings ; use strict ; our (@ISA, @EXPORT); require Exporter ; use DB_File; @ISA=qw(DB_File); @EXPORT = @DB_File::EXPORT ; sub STORE { my $self = shift ; my $key = shift ; my $value = shift ; $self->SUPER::STORE($key, $value * 2) ; } sub FETCH { my $self = shift ; my $key = shift ; $self->SUPER::FETCH($key) - 1 ; } sub put { my $self = shift ; my $key = shift ; my $value = shift ; $self->SUPER::put($key, $value * 3) ; } sub get { my $self = shift ; $self->SUPER::get($_[0], $_[1]) ; $_[1] -= 2 ; } sub A_new_method { my $self = shift ; my $key = shift ; my $value = $self->FETCH($key) ; return "[[$value]]" ; } 1 ;EOM close FILE ; BEGIN { push @INC, '.'; } eval 'use SubDB ; '; main::ok(91, $@ eq "") ; my %h ; my $X ; eval ' $X = tie(%h, "SubDB","dbbtree.tmp", O_RDWR|O_CREAT, 0640, $DB_BTREE ); ' ; main::ok(92, $@ eq "") ; my $ret = eval '$h{"fred"} = 3 ; return $h{"fred"} ' ; main::ok(93, $@ eq "") ; main::ok(94, $ret == 5) ; my $value = 0; $ret = eval '$X->put("joe", 4) ; $X->get("joe", $value) ; return $value' ; main::ok(95, $@ eq "") ; main::ok(96, $ret == 10) ; $ret = eval ' R_NEXT eq main::R_NEXT ' ; main::ok(97, $@ eq "" ) ; main::ok(98, $ret == 1) ; $ret = eval '$X->A_new_method("joe") ' ; main::ok(99, $@ eq "") ; main::ok(100, $ret eq "[[11]]") ; undef $X; untie(%h); unlink "SubDB.pm", "dbbtree.tmp" ;}{ # DBM Filter tests use warnings ; use strict ; my (%h, $db) ; my ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; unlink $Dfile; sub checkOutput { my($fk, $sk, $fv, $sv) = @_ ; return $fetch_key eq $fk && $store_key eq $sk && $fetch_value eq $fv && $store_value eq $sv && $_ eq 'original' ; } ok(101, $db = tie(%h, 'DB_File', $Dfile, O_RDWR|O_CREAT, 0640, $DB_BTREE ) ); $db->filter_fetch_key (sub { $fetch_key = $_ }) ; $db->filter_store_key (sub { $store_key = $_ }) ; $db->filter_fetch_value (sub { $fetch_value = $_}) ; $db->filter_store_value (sub { $store_value = $_ }) ; $_ = "original" ; $h{"fred"} = "joe" ; # fk sk fv sv ok(102, checkOutput( "", "fred", "", "joe")) ; ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; ok(103, $h{"fred"} eq "joe"); # fk sk fv sv ok(104, checkOutput( "", "fred", "joe", "")) ; ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; ok(105, $db->FIRSTKEY() eq "fred") ; # fk sk fv sv ok(106, checkOutput( "fred", "", "", "")) ; # replace the filters, but remember the previous set my ($old_fk) = $db->filter_fetch_key (sub { $_ = uc $_ ; $fetch_key = $_ }) ; my ($old_sk) = $db->filter_store_key (sub { $_ = lc $_ ; $store_key = $_ }) ; my ($old_fv) = $db->filter_fetch_value (sub { $_ = "[$_]"; $fetch_value = $_ }) ; my ($old_sv) = $db->filter_store_value (sub { s/o/x/g; $store_value = $_ }) ; ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; $h{"Fred"} = "Joe" ; # fk sk fv sv ok(107, checkOutput( "", "fred", "", "Jxe")) ; ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; ok(108, $h{"Fred"} eq "[Jxe]"); # fk sk fv sv ok(109, checkOutput( "", "fred", "[Jxe]", "")) ; ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; ok(110, $db->FIRSTKEY() eq "FRED") ; # fk sk fv sv ok(111, checkOutput( "FRED", "", "", "")) ; # put the original filters back $db->filter_fetch_key ($old_fk); $db->filter_store_key ($old_sk); $db->filter_fetch_value ($old_fv); $db->filter_store_value ($old_sv); ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; $h{"fred"} = "joe" ; ok(112, checkOutput( "", "fred", "", "joe")) ; ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; ok(113, $h{"fred"} eq "joe"); ok(114, checkOutput( "", "fred", "joe", "")) ; ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; ok(115, $db->FIRSTKEY() eq "fred") ; ok(116, checkOutput( "fred", "", "", "")) ; # delete the filters $db->filter_fetch_key (undef); $db->filter_store_key (undef); $db->filter_fetch_value (undef); $db->filter_store_value (undef); ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; $h{"fred"} = "joe" ; ok(117, checkOutput( "", "", "", "")) ; ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; ok(118, $h{"fred"} eq "joe"); ok(119, checkOutput( "", "", "", "")) ; ($fetch_key, $store_key, $fetch_value, $store_value) = ("") x 4 ; ok(120, $db->FIRSTKEY() eq "fred") ; ok(121, checkOutput( "", "", "", "")) ; undef $db ; untie %h; unlink $Dfile;}{ # DBM Filter with a closure use warnings ; use strict ; my (%h, $db) ; unlink $Dfile; ok(122, $db = tie(%h, 'DB_File', $Dfile, O_RDWR|O_CREAT, 0640, $DB_BTREE ) ); my %result = () ; sub Closure { my ($name) = @_ ; my $count = 0 ; my @kept = () ; return sub { ++$count ; push @kept, $_ ; $result{$name} = "$name - $count: [@kept]" ; } } $db->filter_store_key(Closure("store key")) ; $db->filter_store_value(Closure("store value")) ; $db->filter_fetch_key(Closure("fetch key")) ; $db->filter_fetch_value(Closure("fetch value")) ; $_ = "original" ; $h{"fred"} = "joe" ; ok(123, $result{"store key"} eq "store key - 1: [fred]"); ok(124, $result{"store value"} eq "store value - 1: [joe]"); ok(125, ! defined $result{"fetch key"} ); ok(126, ! defined $result{"fetch value"} ); ok(127, $_ eq "original") ; ok(128, $db->FIRSTKEY() eq "fred") ; ok(129, $result{"store key"} eq "store key - 1: [fred]"); ok(130, $result{"store value"} eq "store value - 1: [joe]"); ok(131, $result{"fetch key"} eq "fetch key - 1: [fred]"); ok(132, ! defined $result{"fetch value"} ); ok(133, $_ eq "original") ; $h{"jim"} = "john" ; ok(134, $result{"store key"} eq "store key - 2: [fred jim]"); ok(135, $result{"store value"} eq "store value - 2: [joe john]"); ok(136, $result{"fetch key"} eq "fetch key - 1: [fred]"); ok(137, ! defined $result{"fetch value"} ); ok(138, $_ eq "original") ; ok(139, $h{"fred"} eq "joe"); ok(140, $result{"store key"} eq "store key - 3: [fred jim fred]"); ok(141, $result{"store value"} eq "store value - 2: [joe john]"); ok(142, $result{"fetch key"} eq "fetch key - 1: [fred]"); ok(143, $result{"fetch value"} eq "fetch value - 1: [joe]"); ok(144, $_ eq "original") ; undef $db ; untie %h; unlink $Dfile;} { # DBM Filter recursion detection use warnings ; use strict ; my (%h, $db) ; unlink $Dfile; ok(145, $db = tie(%h, 'DB_File', $Dfile, O_RDWR|O_CREAT, 0640, $DB_BTREE ) ); $db->filter_store_key (sub { $_ = $h{$_} }) ; eval '$h{1} = 1234' ; ok(146, $@ =~ /^recursion detected in filter_store_key at/ ); undef $db ; untie %h; unlink $Dfile;}{ # Examples from the POD my $file = "xyzt" ; { my $redirect = new Redirect $file ; # BTREE example 1 ### use warnings FATAL => qw(all) ; use strict ; use DB_File ; my %h ; sub Compare { my ($key1, $key2) = @_ ; "\L$key1" cmp "\L$key2" ; } # specify the Perl sub that will do the comparison $DB_BTREE->{'compare'} = \&Compare ; unlink "tree" ; tie %h, "DB_File", "tree", O_RDWR|O_CREAT, 0640, $DB_BTREE or die "Cannot open file 'tree': $!\n" ; # Add a key/value pair to the file $h{'Wall'} = 'Larry' ; $h{'Smith'} = 'John' ; $h{'mouse'} = 'mickey' ; $h{'duck'} = 'donald' ; # Delete delete $h{"duck"} ; # Cycle through the keys printing them in order. # Note it is not necessary to sort the keys as # the btree will have kept them in order automatically. foreach (keys %h) { print "$_\n" } untie %h ; unlink "tree" ; } delete $DB_BTREE->{'compare'} ; ok(147, docat_del($file) eq <<'EOM') ;mouseSmithWallEOM { my $redirect = new Redirect $file ; # BTREE example 2 ### use warnings FATAL => qw(all) ; use strict ; use DB_File ; my ($filename, %h); $filename = "tree" ; unlink $filename ; # Enable duplicate records $DB_BTREE->{'flags'} = R_DUP ; tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0640, $DB_BTREE or die "Cannot open $filename: $!\n"; # Add some key/value pairs to the file $h{'Wall'} = 'Larry' ; $h{'Wall'} = 'Brick' ; # Note the duplicate key $h{'Wall'} = 'Brick' ; # Note the duplicate key and value $h{'Smith'} = 'John' ; $h{'mouse'} = 'mickey' ; # iterate through the associative array # and print each key/value pair. foreach (keys %h) { print "$_ -> $h{$_}\n" } untie %h ; unlink $filename ; } ok(148, docat_del($file) eq ($db185mode ? <<'EOM' : <<'EOM') ) ;Smith -> JohnWall -> BrickWall -> BrickWall -> Brickmouse -> mickeyEOMSmith -> JohnWall -> LarryWall -> LarryWall -> Larrymouse -> mickeyEOM { my $redirect = new Redirect $file ; # BTREE example 3 ### use warnings FATAL => qw(all) ; use strict ; use DB_File ; my ($filename, $x, %h, $status, $key, $value); $filename = "tree" ; unlink $filename ; # Enable duplicate records $DB_BTREE->{'flags'} = R_DUP ; $x = tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0640, $DB_BTREE or die "Cannot open $filename: $!\n"; # Add some key/value pairs to the file $h{'Wall'} = 'Larry' ; $h{'Wall'} = 'Brick' ; # Note the duplicate key $h{'Wall'} = 'Brick' ; # Note the duplicate key and value $h{'Smith'} = 'John' ; $h{'mouse'} = 'mickey' ; # iterate through the btree using seq # and print each key/value pair. $key = $value = 0 ; for ($status = $x->seq($key, $value, R_FIRST) ; $status == 0 ; $status = $x->seq($key, $value, R_NEXT) ) { print "$key -> $value\n" } undef $x ; untie %h ; } ok(149, docat_del($file) eq ($db185mode == 1 ? <<'EOM' : <<'EOM') ) ;Smith -> JohnWall -> BrickWall -> BrickWall -> Larrymouse -> mickeyEOMSmith -> JohnWall -> LarryWall -> BrickWall -> Brickmouse -> mickeyEOM { my $redirect = new Redirect $file ; # BTREE example 4 ### use warnings FATAL => qw(all) ; use strict ; use DB_File ; my ($filename, $x, %h); $filename = "tree" ; # Enable duplicate records $DB_BTREE->{'flags'} = R_DUP ; $x = tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0640, $DB_BTREE or die "Cannot open $filename: $!\n"; my $cnt = $x->get_dup("Wall") ; print "Wall occurred $cnt times\n" ; my %hash = $x->get_dup("Wall", 1) ; print "Larry is there\n" if $hash{'Larry'} ; print "There are $hash{'Brick'} Brick Walls\n" ; my @list = sort $x->get_dup("Wall") ; print "Wall => [@list]\n" ; @list = $x->get_dup("Smith") ; print "Smith => [@list]\n" ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -