Recipe 14.3. Converting Between DBM Files
Author: Tom Christiansen & Nathan Torkington
Date: 1999-07-02T01:42:48Z

#

| Chapter 14 Database Access |

## 14.3. Converting Between DBM Files

### Problem

You have a file in one DBM format, but another program expects input in a different DBM format.

### Solution

Reads the keys and values from the initial DBM file and writes them to a new file in the different DBM format as in Example 14.2.

#### Example 14.2: db2gdbm

    #!/usr/bin/perl -w
    # db2gdbm: converts DB to GDBM

    use strict;

    use DB_File;
    use GDBM_File;

    unless (@ARGV == 2) {
        die "usage: db2gdbm infile outfile\n";
    }

    my ($infile, $outfile) = @ARGV;
    my (%db_in, %db_out);

    # open the files
    tie(%db_in, 'DB_File', $infile)
        or die "Can't tie $infile: $!";
    tie(%db_out, 'GDBM_File', $outfile, GDBM_WRCREAT, 0666)
        or die "Can't tie $outfile: $!";

    # copy (don't use %db_out = %db_in because it's slow on big databases)
    while (my($k, $v) = each %db_in) {
        $db_out{$k} = $v;
    }

    # these unties happen automatically at program exit
    untie %db_in;
    untie %db_out;

Call the program as:

    % db2gdbm /tmp/users.db /tmp/users.gdbm

### Discussion

When multiple types of DBM file are used in the same program, you have to use `tie`, not the `dbmopen` interface. That's because with `dbmopen` you can only use one database format, which is why its use is deprecated.

Copying hashes by simple assignment, as in `%new` `=` `%old` , works on DBM files. However, it loads everything into memory first as a list, which doesn't matter with small hashes, but can be prohibitively expensive in the case of DBM files. For database hashes, use `each` to iterate through them instead.

### See Also

The documentation for the standard modules GDBM_File, NDBM_File, SDBM_File, DB_File, also in Chapter 7 of Programming Perl; Recipe 14.1

14.2. Emptying a DBM File |  | 14.4. Merging DBM Files