Problems setting value in MLDBM created database

E

Eric

We have an existing database named 'DBfile' that was created using
MLDBM. I want to modify the value of 'Cnt' in this database using the
following script:

=============================================
#! /usr/bin/perl

use Data::Dumper;
use Fcntl;
use MLDBM qw(DB_File Storable);

&DBprint("nfs", "32039", '0');

sub DBprint {
my $protocol = shift;
my $bldNum = shift;
my $mntPnt = shift;
my $DBFile = "./DBfile";

tie( %$mntsDB, "MLDBM", $DBFile, O_CREAT|O_RDWR, 0666,
$DB_File::DB_BTREE );

$mntPnt = "mnt".$mntPnt;

print STDOUT "\nBEFORE\n";

print STDOUT (Dumper $mntsDB);

print STDOUT "\nInitial Cnt is: $mntsDB->{$mntPnt}->{Cnt};\n";

my $tmp = $mntsDB->{$mntPnt}->{Cnt};

print STDOUT "\n\$tmp is: $tmp\n";

$tmp{Cnt}[0] = 'foo'; ## key line of code

print STDOUT "\n\$tmp is now: $tmp->{Cnt}[0]\n";

$mntsDB->{$mntPnt}->{Cnt} = $tmp;

print STDOUT "\nCnt is now: $mntsDB->{$mntPnt}->{Cnt};\n";

print STDOUT "\nAFTER\n";

print STDOUT (Dumper $mntsDB);

untie(%$mntsDB);
}
=============================================

But note in the output below that the value is not modified:

=============================================
BEFORE
$VAR1 = {
'mnt0' => {
'Cnt' => 2,
'BldNum' => '32039',
'Protocol' => 'nfs'
}
};

Initial Cnt is: 2;

$tmp is: 2

$tmp is now: foo

Cnt is now: 2;

AFTER
$VAR1 = {
'mnt0' => {
'Cnt' => 2,
'BldNum' => '32039',
'Protocol' => 'nfs'
}
};
=============================================

I read the CPAN page carefully, and although it seems as if this
should work, it does not. The Cnt value is not getting reset to the
value 'foo'.

Does anyone see where I am making my mistake? I noted a key line of
code in the script that I think may be preventing this from working,
although I did try several variations. I'm thinking that maybe I am
getting tangled up in my references.

Thanks.

Eric
 
X

xhoster

Eric said:
We have an existing database named 'DBfile' that was created using
MLDBM. I want to modify the value of 'Cnt' in this database using the
following script:

Does anyone see where I am making my mistake?

Yes. From a programming perspective, you apparently aren't using strict.
From a clpm perspective, you posted code that doesn't compile under
"use strict". Both of those are mistakes in themselves, and are
probably hiding other mistakes from you.

Xho
 
M

Mumia W.

We have an existing database named 'DBfile' that was created using
MLDBM. I want to modify the value of 'Cnt' in this database using the
following script:
[...]

Here is your program modified to work. I've placed a few numbered
comments in the code:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Fcntl;
use DB_File;
# 1: use DB_File to ensure that DB_BTREE is defined.

use MLDBM qw(DB_File Storable);

&DBprint("nfs", "32039", '0');

sub DBprint {
my $protocol = shift;
my $bldNum = shift;
my $mntPnt = shift;
my $DBFile = "./DBfile";
my $mntsDB;

tie( %$mntsDB, "MLDBM", $DBFile, O_RDWR, 0666, $DB_File::DB_BTREE )
or die("Tie failure: $!");
# 2: die() if the tie fails.

$mntPnt = "mnt".$mntPnt;

print STDOUT "\nBEFORE\n";

print STDOUT (Dumper $mntsDB);

print STDOUT "\nInitial Cnt is: $mntsDB->{$mntPnt}->{Cnt};\n";

my $tmp = $mntsDB->{$mntPnt};
# 3: $mntsDB->{$mntPnt}->{Cnt} is a scalar element
# of a hash--not an array.

print STDOUT "\n\$tmp is: $tmp\n";

$tmp->{Cnt} = 'foo'; ## (modified) key line of code

print STDOUT "\n\$tmp is now: $tmp->{Cnt}\n";

# $mntsDB->{$mntPnt}->{Cnt} = $tmp;
$mntsDB->{$mntPnt} = $tmp;
# 4: Aggregates in a DB_File need to be updated all at once.

print STDOUT "\nCnt is now: $mntsDB->{$mntPnt}->{Cnt};\n";

print STDOUT "\nAFTER\n";

print STDOUT (Dumper $mntsDB);

untie(%$mntsDB);
}

__END__

Comment #4 is the most important. I can't remember where I first read
about it, but you can't update a sub-hash within a tied database hash.
The top-level entry must be updated.
 
E

Eric

Mumia W. wrote:
<removed>

Thank you very much for your solution, Munia. I tried it and it does
in fact work.
Comment #4 is the most important. I can't remember where I first read
about it, but you can't update a sub-hash within a tied database hash.
The top-level entry must be updated.

Obviously I had made several mistakes that prevented this from
working, but this one was key.

Eric
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top