start page | rating of books | rating of authors | reviews | copyrights

Learning Perl

Learning PerlSearch this book
Previous: 17.2 Opening and Closing DBM Hashes Chapter 17
User Database Manipulation
Next: 17.4 Fixed-Length Random Access Databases
 

17.3 Using a DBM Hash

Once the database is opened, accesses to the DBM hash are mapped into references to the database. Changing or adding a value in the hash causes the corresponding entries to be immediately written into the disk files. For example, once %FRED is opened from the earlier example, we can add, delete, or access elements of the database, like this:

$FRED{"fred"} = "bedrock";  # create (or update) an element 

delete $FRED{"barney"};     # remove an element of the database 

foreach $key (keys %FRED) { # step through all values     print "$key has value of $FRED{$key}\n"; }

That last loop has to scan through the entire disk file twice: once to access the keys, and a second time to look up the values from the keys. If you are scanning through a DBM hash, it's generally more disk-efficient to use the each operator, which makes only one pass:

while (($key, $value) = 

each(%FRED)) {     print "$key has value of $value\n"; }

If you are accessing system DBM databases, such as the ones created by sendmail or NIS, you must be aware that dubiously written C programs sometimes tack on a trailing NUL ( \0 ) character to the end of their strings. The DBM library routines do not need this NUL (they handle binary data using a byte count, not a NUL-delimited string), and so the NUL is stored as part of the data. You must therefore append a NUL character to the end of your keys and discard the NUL from the end of the returned values to have the data make sense. For example, to look up merlyn in the aliases database, try something like this:

dbmopen(%ALI, "/etc/aliases", undef) || die "no aliases?"; $value = $ALI{"merlyn\0"};                     # note appended NUL chop($value);                                  # remove appended NUL print "Randal's mail is headed for: $value\n"; # show result

Your version of UNIX may stick the aliases database over in /usr/lib rather than /etc . You'll have to poke around to find out. Newer versions of sendmail are free of the NUL bug.


Previous: 17.2 Opening and Closing DBM Hashes Learning Perl Next: 17.4 Fixed-Length Random Access Databases
17.2 Opening and Closing DBM Hashes Book Index 17.4 Fixed-Length Random Access Databases