Moving DB_Files between disparate systems
Social links
View Ashley Pond V's profile on LinkedIn
Miscellaneous

Other pages

Description

This script converts binary DB_File data into plain text for sending accross networks and reconstituting on other systems with the same script. There is usage information and some discussion in the script comments.

In my case, I build parts of my site and its search index from mysql on OS X at home. The search index uses DB_File. I didn’t have mysql on my host originally and didn’t want the headache of syncing the DBs anyway (myisam to innodb, 3.whatever to 4.bleeding). So, the only data-system that needs to go over is the search index. Moving the DB generated with DB_File breaks it since the target system has little other than “nix” in common with my box. This script fixes it for transfer and puts it back the way it needs to be once it gets where it belongs.

Code
#!/usr/bin/perl
#=====================================================================
# DECLARATIONS
#=====================================================================
use warnings;
use strict;

# DB_File is fantastic for speed and simplicity, however, it's not
# even remotely network transparent. This means you can't just copy
# the DB files from one operating system to another and expect them to
# still work.

use DB_File;

# YAML is from our good friend Brian Ingerson. It is for data
# serialization, which means, in this case, stringifying the data so
# that it can be moved as a text file and not a binary with inherit
# system dependencies. I generally use Storable instead of YAML b/c of
# its speed and ease but Storable is even more prone to system and
# versioning problems than DB_File is so it is not suitable for a
# transparent DB transfer application. Data::Dumper is, for the most
# part, but it's not as safe to use as YAML is; eval() security
# issues.

use YAML ();
#=====================================================================
# PROGRAM PROPER
#=====================================================================
my %db;

my $db_file_name = shift || 
    die "Give me a DB or YAML file name to convert!\n";

-e $db_file_name and -r _ or
    die "What do you expect me to do with $db_file_name?\n";

# We try to tie the file as a DB_File. If it works, we convert it to
# YAML. If it doesn't work, we assume it's a YAML file.

if ( tie %db, "DB_File", $db_file_name, O_RDONLY, $DB_HASH ) {

# Strip file extension from name.
    my ( $name ) = $db_file_name =~ /^(.+?)(?:\.\w+)?$/;

# Add our own file extension.
    $name .= '.yml';

# Give the user an update.
    print "converting DB_File $db_file_name to YAML $name\n";

# Check the POD on YAML for DumpFile. We're serializing the data into
# YAML and putting it into the file called $name.

     YAML::DumpFile($name, \%db) ||
        die "Problem with YAML::DumpFile($name...)! $!\n";

} else { # We assume we've been given a YAML file.

    my ( $name ) = $db_file_name =~ /^(.+?)(?:\.yml)?$/;

# But if there's no ".yml" extension we probably shouldn't continue.
    die "Forget this. You didn't give me a DB_File or a YAML file!\n"
        unless $name;

# Add this just so the files are a bit more obvious.
    $name .= '.dbfile';

    tie %db, "DB_File", $name, O_CREAT|O_RDWR, 0644, $DB_HASH
        or die "Couldn't tie DB_Files $name: $!";

    print "converting YAML $db_file_name to DB_File $name\n";

    my $data = YAML::LoadFile($db_file_name);

    my $type = ref $data;

    die "Unsupported type($type). I only covert HASH based DB_Files.\n" 
        if ref $data ne 'HASH';

    while ( my ( $key, $val ) = each %{$data} ) {
        $db{$key} = $val;
    }
    untie %db;
}

exit 0;
#=====================================================================

=head1 db-file-converter

Convert DB_Files to YAML and vice versa.

=head2 Usage

When you need to move a DB_File from one system to another. Eg: You
are running the development and production of a project on different
boxes or systems or under different versions of DB_File.

=over 4

db-file-converter [ DB_Filename | YAML_filename ]

=back

Ta!

=head1 Bugs

Could be... This is a cleaned up version of the one I use so I might
have broken or missed something in the would be fixing.

=head1 Author

It's me! Ashley. Ashley Pond. The fifth.

=head1 Copyright

(c)2003. Same terms as Perl. If you use or modify it keep it under the
Perl or GPL license.

=head1 See Also

YAML, DB_File, Storable, Data::Dumper.

=cut
Serialize binary…
G4:jinx[77]>db-file-converter search_index.db
converting DB_File ddx_search.dbfile to YAML ddx_search.yml
¡Muévase!
G4:jinx[78]>scp ddx_search.yml so_n_so@sedition.com:/some/dir
ddx_search.yml    100% |**********************************| 158 KB 00:00
Reconsitution, on other box where script is also installed
G4:jinx[79]>ssh so_n_so@sedition.com \
   /bin/db-file-converter /some/dir/ddx_search.yml
converting YAML ddx_search.yml to DB_File ddx_search.dbfile

Further

Check out YAML, DB_File, Storable, and Data::Dumper. All fantastic modules covering all the different data situations you’ll commonly get into.

Search these pages via Google
Text, original code, fonts, and graphics ©1990-2008 Ashley Pond V.