scripts / dbcopy.pl

#!/usr/bin/env perl

use strict;

# dbcopy.pl - a script for easy copying of databases
#
# 2006 (c) Andrei Mikhailenko

# ### ####################################
#
use constant DEFAULT_HOST => 'localhost';
use constant DEFAULT_USER => 'root';
use constant DEFAULT_PWD  => 'DO_NOT_FORGET_TO_SET_THE_PASSWORD';
#
# ### ####################################

use constant TEMP_FILENAME => '~/copy-db-tempfile.sql';

my %args = readArgs();

my $from_db = $args{'from'}  || $args{'f'};
my $to_db   = $args{'to'}    || $args{'t'};
my $table   = $args{'table'} || $args{'T'};
my $clean   = defined $args{'clean'} ? $args{'clean'} : $args{'c'};
# + rename (drop source)
my $host    = $args{'host'}  || $args{'h'} || DEFAULT_HOST;
my $user    = $args{'user'}  || $args{'u'} || DEFAULT_USER;
my $pwd     = $args{'pwd'}   || $args{'p'} || DEFAULT_PWD;
my $dump    = defined $args{'dump'} ? $args{'dump'} : $args{'d'};

$from_db && ( $to_db || $dump ) or
$dump && $to_db
	or showUsage() and exit;

print "Please wait while copying your database:\n";

# сбрасываем исходную базу в дамп:

if ( $from_db )
{
	print "  1. dumping database '$from_db'".
		( $table ? " (table '$table')" : undef ).
		( $dump ? " to '$dump'" : undef ) ."...\n";

	# поддержка перечисления таблиц: -Tfoo,bar,baz
	if ($table =~ /,/) { my @table = split /,/, $table; $table = join ' ', @table }

	my $table_cmd = $table ? ' --tables '. $table : undef;

	system 'mysqldump --routines --host='. $host .' --compress --user='. $user .' --password='. $pwd
		.' --no-create-db '. $from_db . $table_cmd .' > '. ( $dump || TEMP_FILENAME );
}
elsif ( $dump )
{
	print "  1. checking if '$dump' exists...";

	-e $dump
		and print " ok\n"
		or  print " NOT FOUND!\n" && die 'Source sump not found'
}
else
{
	die 'you must provide either --from or --dump option'
}

# восстанавливаем из дампа под другим именем (или именами):

if ( $to_db )
{
	print "  2. restoring:\n";

	my $i = 1;
	my @to_db = split /,/, $to_db;

	foreach my $base ( @to_db )
	{
		print "  2.$i. into '$base'...";

		defined $clean
			and print ' (cleanup first)'
			and system 'mysql -u'. $user .' -p'. $pwd .' -e"DROP DATABASE '. $base .'"';

		print "\n";

		system 'mysql -u'. $user .' -p'. $pwd .' -e"CREATE DATABASE IF NOT EXISTS '. $base .'"';

		system 'mysql --host='. $host .' --compress --user='. $user .' --password='. $pwd
			.' --database='. $base .' < '. ($dump || TEMP_FILENAME);

		$i++;
	}
}
else
{
	print "  2. (no target database specified; skipping)\n"
}

# удаляем промежуточный дамп, если юзер не хочет иного:

defined $dump
	or print "  3. cleanup...\n" and system 'rm -f '. TEMP_FILENAME;

print "Done!\n";

sub showUsage
{
	print "\n";

	print "NAME\n";
	print "  copydb.pl - A command-line tool for easy copying of MySQL databases.\n";
	print "              2006 (c) Andy Mikhailenko\n\n";

	print "SYNOPSIS\n";
	print "  dbcopy --from=db1 --to=db2,db3\n  dbcopy -fdb1 -tdb2,db3\n\n";

	print "OPTIONS\n";

	print "  --from, -f\n\n";
	print "      Source database name.\n\n";

	print "  --to, -t\n\n";
	print "      Target database name. Comma-separated list is acceptable (e.g. --to=db1,db2).\n";
	print "      If a target database does not exist, it will be created.\n\n";

	print "  --table, -T\n\n";
	print "      Table name. Unless given, all tables from the source DB are copied.\n\n";
	print "      Comma-separated list is acceptable (e.g. --table=db1,db2).\n\n";

	print "  --clean, -c\n\n";
	print "      Clean (drop) target database before restoring data into it. (Be careful!)\n\n";

	print "  --dump, -d\n\n";
	print "      Leave the temporary dump (otherwise it would be deleted after restoring data from it).\n";
	print "      If filename is specified, it will be used for the dump file.\n\n";

	print "  --host, -h\n\n";
	print "      Connect to the MySQL server on the given host.\n\n";

	print "  --user, -u\n\n";
	print "      The MySQL username to use when connecting to the server.\n\n";

	print "  --pwd, -p\n\n";
	print "      The password to use when connecting to the server.\n\n";
#	print "--rename, -r
#	Rename database, i.e. delete source after uploading to target.
#	NOTE: it's DANGEROUS - if the target wasn't uploaded due to errors, the source it still deleted.\n";
	# TODO вероятно, force --leavedump в таком случае?
}

sub readArgs
{
	my %arg;

# TODO
#use MRN::Util::ArgsResolver;
#my $h = new MRN::Util::ArgsResolver;
#my %args = $h->resolve( @ARGV );

	foreach ( @ARGV )
	{
		# --foo=bar
		if ( /^\-\-(.+)=(.+)$/ )
		{
			$arg{ $1 } = $2
		}
		# -f[bar]
		elsif ( /^\-([A-Za-z])(.*)$/ )
		{
			$arg{ $1 } = $2
		}
		# --foo
		elsif ( /^\-\-(.+)$/ )
		{
			$arg{ $1 } = ''
		}
	}

	return %arg
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.