#!/usr/local/bin/perl
#
# restore.cgi v0.21
#
# This script will parse mysql dump file created by mysqldumo,
# creates modified .sql file (restore.tmp) stripped of INSERT + data lines,
# as well as data file for each tables (TBL.dat), and restore the table using them.
#
# Compared to using original .sql file with INSERT,
# it will finish the job a lot quicker.
#
# Installation:
# Put it in a well protected directory, and set permission of 700 (Not 755)
# Edit and replace configuration section.
#
# To use it via browser: http://example.com/protected/restore.cgi?dump.sql
# As a command or from other script: ./restore.cgi dump.sql
#
# Please read MySQL manual for more info:
# http://dev.mysql.com/doc/mysql/en/mysql.html
#
select(STDOUT);
$| = 1;
print "Content-type: text/plain\n\nRestoring mysql: ";
open(STDERR,">&STDOUT");
######## Setup section ############
my $U = 'USERNAME'; # Username for MySQL
my $P = 'PASSWORD'; # Password for MySQL
my $H = 'mysql0X.powweb.com'; # MySQL server name
my $D = 'DBNAME'; # Database name
my $sqld = "backup.sql"; # Default backup file name
######### End of setup ############
$sqld = $ARGV[0] if $ARGV[0];
print "Dumpfile=$sqld\n\n";
my $dat = '';
my $dat2 = '';
my $pos = 0;
my $blen = 8160;
my $tmpdir = "minisqlimport.tmp";
# Open the dump file
print "Opening $sqld ... ";
open(FH, "$sqld") || die("Failed to open MySql dumpfile: $sqld\n");
print "done.\n";
mkdir("$tmpdir");
chdir("$tmpdir") || die("Failed to chdir into temporary directory: $tmpdir\n");
$restore = "$sqld.r.sql";
# Open temp file that hold mysql commands
print "Opening $restore ...";
open(TMP, ">$restore") || die("Failed to open temp file\n");
print "done.\n\n";
read(FH, $dat, $blen) || die("Dump file format error: empty file\n");
#print "
$dat
\n";
if( $dat =~m#SET NAMES (.*?) #m){
$chardb ="SET character_set_database = '$1';\n";
}
while(1){
$pos = index($dat, "\nINSE"); ### Find \nINSE ###
#print "START pos=$pos\n";
if($pos < 0){ # Get next chunk if not found in the buffer
$datlen = length($dat);
print TMP substr($dat,0, $datlen-4);
read(FH, $dat2, $blen) || last;
$dat = substr($dat,$datlen-4).$dat2;
next;
}else{
print TMP substr($dat,0,$pos+1);
$dat = substr($dat,$pos +1);
} ### \nINSE found ###
if( ($posy = index($dat, "(")) < 0 ){ ### Find ( ###
read(FH, $dat2, $blen) || last;
$posy = index($dat2, "(");
last if $posy < 0;
$posy += length($dat);
$dat .= $dat2;
} ### \nINSEERT .... ( found ###
substr($dat,0,$posy) =~m/^INSERT INTO \`([^\`]+)\` VALUES /;
$t = $1;
print "Table=$t : ";
### Replace 'INSERT INTO' lines with LOAD DATA LOCAL INFINLE ...'
print TMP $chardb;
print TMP "LOAD DATA LOCAL INFILE '$t.dat' INTO TABLE $t FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY \"'\" LINES TERMINATED BY '),(';\n";
### Create a data file for the table removing up to the first (, and last );\n
print "Opening $t.dat ...";
open(FT,">$t.dat") || die("Failed to open for write: $t.dat\n");
print "done.\ndat=".substr($dat,0,80)."\n\n";
$x = 0;
while(index($dat,'I') == 0){ ### Treat all INSERT lines ###
print FT '),(' if $x; # Connect INSERT lines with ),(
$x++;
$pos = index($dat, '('); ### Find ( --- the start of a dataline ###
if($pos < 0){
read(FH, $dat2, $blen) || last;
$pos = index($dat2, "(");
last if $pos < 0;
$pos += length($dat);
$dat .=$dat2;
} #### ( found ###
$dat = substr($dat,$pos+1);
$posy = index($dat, ");\n"); ### Find );\n --- the end of a dataline ###
if( $posy < 0){
while(read(FH, $dat2, $blen)){
$posy = index(substr($dat, length($dat) -2).$dat2, ");\n");
last if $posy >= 0;
print FT $dat;
$dat = $dat2;
} ### Found );\n after multiple attempts ###
$posy -= 2;
if($posy < 0){
print FT substr($dat,0,length($dat)+$posy);
}else{
print FT $dat;
print FT substr($dat2,0,$posy);
}
$dat = substr($dat2, $posy+3);
}else{
print FT substr($dat,0,$posy);
$dat = substr($dat,$posy+3);
} ### Found );\n at the first attempt ###
} ### Data file done ###
close(FT);
}
print TMP $dat;
close(FH);
close(TMP);
print "Finished preparing $restore and data file(s).\nStarting to restore ...\n\n";
#print `cat $restore 2>&1`;
#exit; # If you just want to create data file(s) and $restore, end here.
# Do actual restore using 'mysql' command. Add/Modify options as you want.
# For more detail ==> http://dev.mysql.com/doc/mysql/en/mysql.html
print `time mysql -v -v -v -u$U -p$P -h$H -D$D <$restore 2>&1`;
print "All done\n";
exit 0;
1;