libdb/lang/perl/BerkeleyDB/t/db-4.8.t
2011-09-13 13:44:24 -04:00

324 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 ;
}