Skip to content

Instantly share code, notes, and snippets.

@philchristensen
Created October 29, 2010 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save philchristensen/653961 to your computer and use it in GitHub Desktop.
Save philchristensen/653961 to your computer and use it in GitHub Desktop.
A tool for syncing local databases with a remote master
#!/usr/bin/env perl
##################################################################
# dbcopy.pl 1.0
#
# Copyright (C) 2008 Phil Christensen
##################################################################
use strict;
use warnings;
use Options;
use File::HomeDir;
use File::Spec;
use Data::Dumper;
my $home = File::HomeDir->my_home;
my $prefs_dir = File::Spec->join($home, '.dbcopy');
sub load_prefs{
my $prefs = {};
unless(-e $prefs_dir){
return $prefs;
}
opendir(PREFS_DIR, $prefs_dir);
foreach my $config (readdir(PREFS_DIR)){
if($config =~ m/\.{1,2}/){
next;
}
my $config_path = File::Spec->join($prefs_dir, $config);
open(CONFIG, $config_path);
my @data = <CONFIG>;
my $data = join('', @data);
close(CONFIG);
no strict;
my $result = eval($data);
use strict;
if(defined($result)){
$prefs->{$config} = $result;
}
}
closedir(PREFS_DIR);
return $prefs;
}
sub save_prefs{
my $prefs = shift;
unless(-e $prefs_dir){
mkdir($prefs_dir);
}
foreach my $config (keys %{$prefs}){
my $config_path = File::Spec->join($prefs_dir, $config);
my $d = Data::Dumper->new([$prefs->{$config}]);
$d->Indent(0)->Purity(1)->Useqq(1);
open(CONFIG, ">$config_path");
print CONFIG $d->Dump();
close(CONFIG);
}
}
sub get_options {
my $prefs = shift;
my $options = new Options(params => [
['host', 'h', '', 'A DB host to ssh to before dumping.'],
['database', 'd', '', 'The name of the database to dump.'],
['password', 'p', '', 'The database password.'],
['user', 'u', 'root', 'The database user.'],
['exclude', 'e', '', 'A table to exclude.'],
['include', 'i', '', 'A table to include.'],
['config', 'c', '', 'The dbcopy configuration to use.']
],
flags =>[
['help', '?', 'Display this usage guide.'],
['all', 'a', 'Ignore saved excludes.']
]);
}
sub main {
my $prefs = load_prefs();
my $options = get_options($prefs);
$options->get_options();
if($options->get_result('help')){
$options->print_usage();
exit();
}
my $config_name = $options->get_result('config');
if($config_name eq '' && $options->{'unrecognized'}){
$config_name = $ARGV[0];
}
my $config;
if($config_name && exists($prefs->{$config_name})){
$config = $prefs->{$config_name};
}
else{
$config = { 'host' => $options->get_result('host'),
'database' => $options->get_result('database'),
'exclude' => ($options->get_result('exclude')),
'include' => ($options->get_result('include')),
'user' => $options->get_result('user'),
'password' => $options->get_result('password')};
}
my $exclude_line = '';
if($config->{'exclude'} && !$options->get_result('all')){
foreach my $table ($config->{'exclude'}){
$exclude_line .= sprintf('--ignore-table=%s.%s ', $config->{'database'}, $table);
}
}
elsif($config->{'include'}){
foreach my $table ($config->{'include'}){
$exclude_line .= "$table ";
}
}
my $command = "ssh %s \"mysqldump -u %s --password=%s %s %s | gzip -c -\" | gunzip -c | mysql -u root %s";
$command = sprintf($command, $config->{'host'}, $config->{'user'}, $config->{'password'}, $exclude_line,
$config->{'database'}, $config->{'database'});
if($config_name){
$prefs->{$config_name} = $config;
save_prefs($prefs);
}
#print "\n\n$command\n\n";
exit(system($command));
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment