HTML CSS PHP PERL

DBM Files

 
Previous Table of Contents Next

DBM Files

One of the simplest ways for your Perl program to remember data in an organized way is through the use of DBM files. A DBM file is a file that's been connected to a Perl hash. To read and write a DBM file, you simply manipulate a hash, just as you've been doing since Hour 7, "Hashes."

To tie your hash to a DBM file, use the Perl function dbmopen, as shown here:


dbmopen(hash, filename, mode)


The dbmopen function connects the hash to a DBM file. The filename you supply actually creates one or two different files on your hard disk with names that are a variation on filename: filename.pag, filename.dir, or filename.db. Perl uses these files to store the hash. These files are not text files, and you should not attempt to use an editor on them. Also, if one of the files is empty, or seems very large relative to the amount of data in it, don't worry about it; that's normal.

The mode is the permissions on the two DBM files that Perl creates. Recall that permissions were discussed in the section "A Crash Course in File Permissions" in Hour 10, "Files and Directories." For Unix, use a sensible set of permissions; they control who can access your DBM file. For example, 0666 allows everyone read and write access to your DBM files. Mode 0644 allows you to read and write the files, but others to read them only. For Windows, you can simply use 0666, because you don't have any file system permissions to worry about.

The dbmopen function returns true the hash has been successfully tied to the DBM file; it returns false otherwise. Now consider this example:


dbmopen(%hash, "dbmfile", 0644) || die "Cannot open DBM dbmfile: $!";


After the preceding statement is executed, the hash %hash is connected to a DBM file called dbmfile. Perl creates a pair of files on your disk, called dbmfile.pag and dbmfile.dir, to keep the hash in. If you assign a value to the hash, as shown here, Perl updates the DBM files with that information:


$hash{feline}="cat";

$hash{canine}="dog";


Fetching information causes Perl to retrieve the key and data from the DBM file, as follows:


print $hash{canine};


To disconnect the hash from the DBM file, use dbmclose with the hash name like this:


dbmclose(%hash);


After you've disconnected from the DBM file, the items that were stored in itthe keys feline and canine with the values associated with themare still in the DBM file, which is the whole point of a DBM file. The key-value pairs stored in a hash tied to a DBM file are retained between invocations of a Perl program.

Functions you would normally perform with a hash can be performed with a hash that's tied to a DBM file. The hash functions keys, values, and delete work normally (exists does not work). You can empty the hashand the DBM fileby assigning the hash to an empty list like this: %hash=(). You can even initialize the hash by assigning it to a list after it's tied to the DBM file with dbmopen.

Important Points to Know

The following are just a few small points you need to know about tying hashes to DBM files:

  • The length of your keys and data is now limited. Normal hashes have (virtually) unlimited key length and value length. Hashes that are tied to a DBM file have a limited key and value length, typically around 1,024 characters for both the key and the value combinedthis is a limitation of DBM files. The total number of keys and values that can be stored has not changed; it is limited only by your file system.

  • The values in the hash before dbmopen are lost, so it's best just to use a fresh hash. Now consider this example:

    
    %h=();
    
    $h{dromedary}="camel";
    
    dbmopen(%h, "database", 0644) || die "Cannot open: $!";
    
    print $h{dromedary};  # Likely will print nothing at all
    
    dbmclose(%h);
    
    

    In the preceding snippet, the value in the hash %hthe key of dromedaryis lost when dbmopen is executed.

  • The values in the hash while it's tied to the DBM filedisappear after dbmclose is performed:

    
    dbmopen(%h, "database", 0644) || die "Cannot open: $!";
    
    $h{bovine}="cow";
    
    dbmclose(%h);
    
    print $h{bovine};    # Likely will print nothing
    
    

    The values in the hash while it is connected to the DBM file are retained in the DBM file. Afterward, the hash itself is empty.

Walking Through DBM-Tied Hashes

Consider for a moment a hash that's been tied to a DBM file. For example, if you write a Perl program to keep appointments, phone numbers, and other information in that hash, after a while the hash can become large. Because the hash's values are retained between runs of your Perl program, they never quite go awayunless you delete them on purpose.

If your DBM file (called records) has collected a lot of information, this snippet might have some problems:


dbmopen(%recs, "records", 0644) || die "Cannot open records: $!";

foreach my $key (keys %recs) {

    print " $key  = $recs{$key}\n";

}

dbmclose(%recs);


There's no problem with the code. The hash %recs is first tied to a DBM file, and then the keys from the hash are extracted with keys %recs. The list of keys is iterated over with foreach my $key, and each key and its value are printed.

If the list of keys in %recs is large, however, the statement keys %recs could take some time to execute. Perl has another function that allows you to iterate over a hash one key at a time; it's called each. The syntax for each is as follows:


 ($key, $val)=each(%hash);


The each function returns a two-element list: a key and a value from thehash. Each successive call to each returns the next key-value pair from the hash. When the keys are exhausted, each returns an empty list. A better way to iterate over a potentially large hash would be to use the following example:


dbmopen(%recs, "records", 0644) || die "Cannot open records: $!";

while( ($key, $value)=each %recs) {

    print " $key  = $value\n";

}

dbmclose(%recs);


By the Way

You don't necessarily have to use each with a hash tied to a DBM file; you can use it with any hash at all.


    Previous Table of Contents Next
    © 2000- NIV