[Chapter 17] 17.3 Using a DBM Hash
Author: Randal Schwartz, Tom Christiansen & Larry Wall
Date: 1999-07-02T01:35:52Z

#

| Chapter 17 User Database Manipulation |

## 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.

17.2 Opening and Closing DBM Hashes |  | 17.4 Fixed-Length Random Access Databases