mirror of
https://github.com/berkeleydb/libdb.git
synced 2024-11-17 09:36:24 +00:00
325 lines
7.7 KiB
Perl
325 lines
7.7 KiB
Perl
|
#!./perl -w
|
||
|
|
||
|
use strict ;
|
||
|
|
||
|
|
||
|
use lib 't' ;
|
||
|
|
||
|
use BerkeleyDB;
|
||
|
use util ;
|
||
|
|
||
|
use Test::More ;
|
||
|
|
||
|
plan(skip_all => "this needs Berkeley DB 4.8.x or better\n")
|
||
|
if $BerkeleyDB::db_version < 4.8;
|
||
|
|
||
|
plan tests => 58;
|
||
|
|
||
|
my $Dfile = "dbhash.tmp";
|
||
|
|
||
|
umask(0);
|
||
|
|
||
|
{
|
||
|
# db->associate_foreign -- DB_FOREIGN_CASCADE
|
||
|
|
||
|
sub sec_key
|
||
|
{
|
||
|
#print "in sec_key\n";
|
||
|
my $pkey = shift ;
|
||
|
my $pdata = shift ;
|
||
|
|
||
|
$_[0] = $pdata ;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
my ($Dfile1, $Dfile2, $Dfile3);
|
||
|
my $lex = new LexFile $Dfile1, $Dfile2, $Dfile3 ;
|
||
|
my %hash ;
|
||
|
my $status;
|
||
|
my ($k, $v, $pk) = ('','','');
|
||
|
|
||
|
# create primary database
|
||
|
ok my $primary = new BerkeleyDB::Hash -Filename => $Dfile1,
|
||
|
-Flags => DB_CREATE ;
|
||
|
|
||
|
# create secondary database
|
||
|
ok my $secondary = new BerkeleyDB::Hash -Filename => $Dfile2,
|
||
|
-Flags => DB_CREATE ;
|
||
|
|
||
|
# associate primary with secondary
|
||
|
ok $primary->associate($secondary, \&sec_key) == 0;
|
||
|
|
||
|
# create secondary database
|
||
|
ok my $foreign = new BerkeleyDB::Hash -Filename => $Dfile3,
|
||
|
-Flags => DB_CREATE ;
|
||
|
|
||
|
# associate primary with secondary
|
||
|
ok $foreign->associate_foreign($secondary, undef, DB_FOREIGN_CASCADE) == 0;
|
||
|
|
||
|
# add data to the primary
|
||
|
my %data = (
|
||
|
"red" => "flag",
|
||
|
"green" => "house",
|
||
|
"blue" => "sea",
|
||
|
) ;
|
||
|
|
||
|
my $ret = 0 ;
|
||
|
while (($k, $v) = each %data) {
|
||
|
my $r = $foreign->db_put($v, 1) ;
|
||
|
#print "put $r $BerkeleyDB::Error\n";
|
||
|
$ret += $r;
|
||
|
}
|
||
|
ok $ret == 0 ;
|
||
|
|
||
|
while (($k, $v) = each %data) {
|
||
|
my $r = $primary->db_put($k, $v) ;
|
||
|
#print "put $r $BerkeleyDB::Error\n";
|
||
|
$ret += $r;
|
||
|
}
|
||
|
ok $ret == 0 ;
|
||
|
|
||
|
# check the records in the secondary
|
||
|
is countRecords($primary), 3 ;
|
||
|
is countRecords($secondary), 3 ;
|
||
|
is countRecords($foreign), 3 ;
|
||
|
|
||
|
# deleting from the foreign will cascade
|
||
|
ok $foreign->db_del("flag") == 0;
|
||
|
is countRecords($primary), 2 ;
|
||
|
is countRecords($secondary), 2 ;
|
||
|
is countRecords($foreign), 2 ;
|
||
|
|
||
|
cmp_ok $foreign->db_get("flag", $v), '==', DB_NOTFOUND;
|
||
|
cmp_ok $secondary->db_get("flag", $v), '==', DB_NOTFOUND;
|
||
|
cmp_ok $primary->db_get("red", $v), '==', DB_NOTFOUND;
|
||
|
|
||
|
# adding to the primary when no foreign key will fail
|
||
|
cmp_ok $primary->db_put("hello", "world"), '==', DB_FOREIGN_CONFLICT;
|
||
|
|
||
|
ok $foreign->db_put("world", "hello") == 0;
|
||
|
|
||
|
ok $primary->db_put("hello", "world") == '0';
|
||
|
|
||
|
is countRecords($primary), 3 ;
|
||
|
is countRecords($secondary), 3 ;
|
||
|
is countRecords($foreign), 3 ;
|
||
|
}
|
||
|
|
||
|
{
|
||
|
# db->associate_foreign -- DB_FOREIGN_ABORT
|
||
|
|
||
|
sub sec_key2
|
||
|
{
|
||
|
#print "in sec_key\n";
|
||
|
my $pkey = shift ;
|
||
|
my $pdata = shift ;
|
||
|
|
||
|
$_[0] = $pdata ;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
my ($Dfile1, $Dfile2, $Dfile3);
|
||
|
my $lex = new LexFile $Dfile1, $Dfile2, $Dfile3 ;
|
||
|
my %hash ;
|
||
|
my $status;
|
||
|
my ($k, $v, $pk) = ('','','');
|
||
|
|
||
|
# create primary database
|
||
|
ok my $primary = new BerkeleyDB::Hash -Filename => $Dfile1,
|
||
|
-Flags => DB_CREATE ;
|
||
|
|
||
|
# create secondary database
|
||
|
ok my $secondary = new BerkeleyDB::Hash -Filename => $Dfile2,
|
||
|
-Flags => DB_CREATE ;
|
||
|
|
||
|
# associate primary with secondary
|
||
|
ok $primary->associate($secondary, \&sec_key2) == 0;
|
||
|
|
||
|
# create secondary database
|
||
|
ok my $foreign = new BerkeleyDB::Hash -Filename => $Dfile3,
|
||
|
-Flags => DB_CREATE ;
|
||
|
|
||
|
# associate primary with secondary
|
||
|
ok $foreign->associate_foreign($secondary, undef, DB_FOREIGN_ABORT) == 0;
|
||
|
|
||
|
# add data to the primary
|
||
|
my %data = (
|
||
|
"red" => "flag",
|
||
|
"green" => "house",
|
||
|
"blue" => "sea",
|
||
|
) ;
|
||
|
|
||
|
my $ret = 0 ;
|
||
|
while (($k, $v) = each %data) {
|
||
|
my $r = $foreign->db_put($v, 1) ;
|
||
|
#print "put $r $BerkeleyDB::Error\n";
|
||
|
$ret += $r;
|
||
|
}
|
||
|
ok $ret == 0 ;
|
||
|
|
||
|
while (($k, $v) = each %data) {
|
||
|
my $r = $primary->db_put($k, $v) ;
|
||
|
#print "put $r $BerkeleyDB::Error\n";
|
||
|
$ret += $r;
|
||
|
}
|
||
|
ok $ret == 0 ;
|
||
|
|
||
|
# check the records in the secondary
|
||
|
is countRecords($primary), 3 ;
|
||
|
is countRecords($secondary), 3 ;
|
||
|
is countRecords($foreign), 3 ;
|
||
|
|
||
|
# deleting from the foreign will fail
|
||
|
cmp_ok $foreign->db_del("flag"), '==', DB_FOREIGN_CONFLICT;
|
||
|
is countRecords($primary), 3 ;
|
||
|
is countRecords($secondary), 3 ;
|
||
|
is countRecords($foreign), 3 ;
|
||
|
|
||
|
}
|
||
|
|
||
|
{
|
||
|
# db->associate_foreign -- DB_FOREIGN_NULLIFY
|
||
|
|
||
|
use constant INVALID => "invalid";
|
||
|
|
||
|
sub sec_key3
|
||
|
{
|
||
|
#print "in sec_key\n";
|
||
|
my $pkey = shift ;
|
||
|
my $pdata = shift ;
|
||
|
|
||
|
if ($pdata eq INVALID)
|
||
|
{
|
||
|
#print "BAD\n";
|
||
|
return DB_DONOTINDEX;
|
||
|
}
|
||
|
|
||
|
$_[0] = $pdata ;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
sub nullify_cb
|
||
|
{
|
||
|
my $key = \$_[0];
|
||
|
my $value = \$_[1];
|
||
|
my $foreignkey = \$_[2];
|
||
|
my $changed = \$_[3] ;
|
||
|
|
||
|
#print "key[$$key], value[$$value], foreign[$$foreignkey], changed[$$changed]\n";
|
||
|
|
||
|
if ($$value eq 'sea')
|
||
|
{
|
||
|
#print "SEA\n";
|
||
|
$$value = INVALID;
|
||
|
$$changed = 1;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
$$changed = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
my ($Dfile1, $Dfile2, $Dfile3);
|
||
|
my $lex = new LexFile $Dfile1, $Dfile2, $Dfile3 ;
|
||
|
my %hash ;
|
||
|
my $status;
|
||
|
my ($k, $v, $pk) = ('','','');
|
||
|
|
||
|
# create primary database
|
||
|
ok my $primary = new BerkeleyDB::Hash -Filename => $Dfile1,
|
||
|
-Flags => DB_CREATE ;
|
||
|
|
||
|
# create secondary database
|
||
|
ok my $secondary = new BerkeleyDB::Hash -Filename => $Dfile2,
|
||
|
-Flags => DB_CREATE ;
|
||
|
|
||
|
# associate primary with secondary
|
||
|
ok $primary->associate($secondary, \&sec_key3) == 0;
|
||
|
|
||
|
# create secondary database
|
||
|
ok my $foreign = new BerkeleyDB::Hash -Filename => $Dfile3,
|
||
|
-Flags => DB_CREATE ;
|
||
|
|
||
|
# associate primary with secondary
|
||
|
cmp_ok $foreign->associate_foreign($secondary, \&nullify_cb, DB_FOREIGN_NULLIFY), '==', 0
|
||
|
or diag "$BerkeleyDB::Error\n";
|
||
|
|
||
|
# add data to the primary
|
||
|
my %data = (
|
||
|
"red" => "flag",
|
||
|
"green" => "house",
|
||
|
"blue" => "sea",
|
||
|
) ;
|
||
|
|
||
|
my $ret = 0 ;
|
||
|
while (($k, $v) = each %data) {
|
||
|
my $r = $foreign->db_put($v, 1) ;
|
||
|
#print "put $r $BerkeleyDB::Error\n";
|
||
|
$ret += $r;
|
||
|
}
|
||
|
ok $ret == 0 ;
|
||
|
|
||
|
while (($k, $v) = each %data) {
|
||
|
my $r = $primary->db_put($k, $v) ;
|
||
|
#print "put $r $BerkeleyDB::Error\n";
|
||
|
$ret += $r;
|
||
|
}
|
||
|
ok $ret == 0 ;
|
||
|
|
||
|
# check the records in the secondary
|
||
|
is countRecords($primary), 3 ;
|
||
|
is countRecords($secondary), 3 ;
|
||
|
is countRecords($foreign), 3, "count is 3" ;
|
||
|
|
||
|
# deleting from the foreign will pass, but the other dbs will not be
|
||
|
# affected
|
||
|
cmp_ok $foreign->db_del("sea"), '==', 0, "delete"
|
||
|
or diag "$BerkeleyDB::Error\n";
|
||
|
is countRecords($primary), 3 ;
|
||
|
is countRecords($secondary), 2 ;
|
||
|
is countRecords($foreign), 2 ;
|
||
|
|
||
|
|
||
|
# deleting from the foreign will pass, but the other dbs will not be
|
||
|
# affected
|
||
|
cmp_ok $foreign->db_del("flag"), '==', 0, "delete"
|
||
|
or diag "$BerkeleyDB::Error\n";
|
||
|
is countRecords($primary), 3 ;
|
||
|
is countRecords($secondary), 2 ;
|
||
|
is countRecords($foreign), 1 ;
|
||
|
|
||
|
}
|
||
|
|
||
|
{
|
||
|
# db->set_bt_compress
|
||
|
|
||
|
my ($Dfile1, $Dfile2, $Dfile3);
|
||
|
my $lex = new LexFile $Dfile1, $Dfile2, $Dfile3 ;
|
||
|
my %hash ;
|
||
|
my $status;
|
||
|
my ($k, $v, $pk) = ('','','');
|
||
|
|
||
|
# create primary database
|
||
|
ok my $primary = new BerkeleyDB::Btree -Filename => $Dfile1,
|
||
|
-set_bt_compress => 1,
|
||
|
-Flags => DB_CREATE ;
|
||
|
|
||
|
# add data to the primary
|
||
|
my %data = (
|
||
|
"red" => "flag",
|
||
|
"green" => "house",
|
||
|
"blue" => "sea",
|
||
|
) ;
|
||
|
|
||
|
my $ret = 0 ;
|
||
|
while (($k, $v) = each %data) {
|
||
|
my $r = $primary->db_put($k, $v);
|
||
|
#print "put $r $BerkeleyDB::Error\n";
|
||
|
$ret += $r;
|
||
|
}
|
||
|
ok $ret == 0 ;
|
||
|
|
||
|
# check the records in the secondary
|
||
|
is countRecords($primary), 3 ;
|
||
|
}
|