#!/usr/bin/perl


$NAMEDATABASE="test" ;			#Name database
$USERDATABASE="postgres";		#User database

$FILEBACKUP="BackUp.sql" ;		#File for backup
$FILEPATCHED="BackUpPatched.sql" ;	#File for patched backup 

$FILELOG="LogPatched.log" ;		#File for patch log



print "firststep. Script for backup from postgresql\@etersoft 8.2.* files and patched for postgresql\@etersoft 8.3.*\n";
NameFromConsole();
CreateBackup();





$FIRSTFINDSTRING = "CREATE TYPE mchar (\n";
$SECONDFINDSTRING = "CREATE TYPE mvarchar (\n";
$ENDFINDSTRING = ");\n";
$LASTFINDSTRING = "REVOKE ALL ON SCHEMA public FROM PUBLIC;\n";

$BEFOREFIRSTNEWSTRING = "CREATE FUNCTION mchartypmod_in(cstring[])\n    RETURNS int4\n    AS '\$libdir/mchar'\n    LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT;\n\nCREATE FUNCTION mchartypmod_out(int4)\n    RETURNS cstring\n    AS '\$libdir/mchar'\n    LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT;\n\n";

$FIRSTNEWSTRING = "CREATE TYPE mchar (\n    INTERNALLENGTH = -1,\n    INPUT = mchar_in,\n    OUTPUT = mchar_out,\n    TYPMOD_IN       = mchartypmod_in,\n    TYPMOD_OUT      = mchartypmod_out,\n    RECEIVE	= mchar_recv,\n    SEND = mchar_send,\n    STORAGE = extended\n);\n\n";

$SECONDNEWSTRING = "CREATE TYPE mvarchar (\n    INTERNALLENGTH = -1,\n    INPUT = mvarchar_in,\n    OUTPUT = mvarchar_out,\n    TYPMOD_IN       = mchartypmod_in,\n    TYPMOD_OUT      = mchartypmod_out,\n    RECEIVE	= mvarchar_recv,\n    SEND = mvarchar_send,\n    STORAGE = extended\n);\n\n";

$LASTSTRING = "CREATE OPERATOR CLASS mchar_case_ops\nFOR TYPE mchar USING btree AS\n        OPERATOR        1       &<  ,\n               OPERATOR        2       &<= ,\n               OPERATOR        3       &=  ,\n               OPERATOR        4       &>= ,\n               OPERATOR        5       &>  ,\n               FUNCTION        1       mchar_case_cmp(mchar, mchar),\n        OPERATOR        1       &<  (mchar, mvarchar),\n               OPERATOR        2       &<= (mchar, mvarchar),\n               OPERATOR        3       &=  (mchar, mvarchar),\n               OPERATOR        4       &>= (mchar, mvarchar),\n               OPERATOR        5       &>  (mchar, mvarchar),\n               FUNCTION        1       mc_mv_case_cmp(mchar, mvarchar);\n\n CREATE OPERATOR CLASS mvarchar_case_ops\nFOR TYPE mvarchar USING btree AS\n        OPERATOR        1       &<  ,\n               OPERATOR        2       &<= ,\n               OPERATOR        3       &=  ,\n               OPERATOR        4       &>= ,\n               OPERATOR        5       &>  ,\n               FUNCTION        1       mvarchar_case_cmp(mvarchar, mvarchar),\n        OPERATOR        1       &<  (mvarchar, mchar),\n               OPERATOR        2       &<= (mvarchar, mchar),\n               OPERATOR        3       &=  (mvarchar, mchar),\n               OPERATOR        4       &>= (mvarchar, mchar),\n               OPERATOR        5       &>  (mvarchar, mchar),\n               FUNCTION        1       mv_mc_case_cmp(mvarchar, mchar);\n\n";


$LINESTRING = "------------------------------------------------------------------------------------------------\n";


print "open file ".$FILEBACKUP." for read backup ... ";
open(FILEIN, $FILEBACKUP) or die print "can't open file".$FILEBACKUP."\n"; 
print "ok.\n";

print "open file ".$FILEPATCHED." for write patched backup ... ";
$FILEPATCHEDCREATE = ">".$FILEPATCHED;
open(FILEOUT, $FILEPATCHEDCREATE) or die print "can't open file".$FILEPATCHED."\n"; 
print "ok.\n";

print "open file ".$FILELOG." for write patched backup ... ";
$FILELOGCREATE  = ">".$FILELOG;
open(FILELOG, $FILELOGCREATE) or die print "can't open file".$FILELOG."\n"; 
print "ok.\n";


$fNotWrite = 0 ;  


$iMustBeFindCut = 3;
$iFindCut = 0;


@iMustBeReplaced [1, 2, 3] = (9,9,0);
$iReplaced = 0;
$NumFind = 0;

$Warnings = 0;

$NumStr = 0;

print "start search ...\n";
print "Must finded ".$iMustBeFindCut." cut\n";
while (<FILEIN>) 
{ 
	$ThisString = $_ ; 
	$NumStr += 1;
	if ($ThisString eq $FIRSTFINDSTRING)
	{
		$NumFind = 1;
		LogFindCut();
		$fNotWrite=1; 
		PrintInFile($BEFOREFIRSTNEWSTRING);
		PrintInFile($FIRSTNEWSTRING);

	} 
	if ($ThisString eq $SECONDFINDSTRING)
	{
		LogFindCut();		
		$NumFind = 2;
		$fNotWrite=1; 
		PrintInFile($SECONDNEWSTRING);
	} 
	if ($ThisString eq $LASTFINDSTRING)
	{
		$NumFind = 3;
		LogFindCut();
		LogNumStringOut();
		PrintInFile($LASTSTRING);
	} 
	if($fNotWrite == 0) 
	{
		print FILEOUT $ThisString
	} 
	else 
	{
		LogNumString();
		if ($ThisString eq $ENDFINDSTRING)
		{ 
			$fNotWrite = 0;
			LogNumStringOut();
			
		} 
	} 
}  

if ($iMustBeFindCut == $iFindCut)
	{
		print "Finded all ";
		if($Warnings > 0)
			{print "with warnings\n";}	
		else
			{print "without warnings!!!\n";}
	}
else
	{print "ERROR!!! Did not find all cuts!\n"}


print $fkols;
close(FILEIN); 
close(FILEOUT); 
exit; 


sub LogFindCut
{
	$iFindCut += 1;
	print "find ".$iFindCut ." cut\n";
	
}

sub LogNumString
{
	if($iReplaced == 0)
	{
		NumSrt();
		print FILELOG "Skip this string:\n".$LINESTRING;
	}
	print FILELOG $ThisString;
	$iReplaced += 1;
}
sub LogNumStringOut
{
	print "   Replaced ".$iReplaced." string must be ".@iMustBeReplaced[$NumFind]." ";
	if($iReplaced == @iMustBeReplaced[$NumFind])
		{print "ok \n";}
	else 
		{
			print "warning \n";
			$Warnings += 1;
		}
	
	$iReplaced = 0;
	
}

sub PrintInFile
{
	print FILEOUT $_[0];
	
	NumSrt();
	print FILELOG "Past this string:\n".$LINESTRING ;
	print FILELOG $_[0];
}
sub NumSrt
{
	print FILELOG "String ".$NumStr." in file ".$FILEBACKUP.". " ;
}

sub NameFromConsole
{
	$statusparam = false;
	$NAMEDATABASECON = shift or $statusparam = 1 ;
	if($NAMEDATABASECON eq "--help") 
	{
		PrintHelp();
		exit;
	}	
	

	if($statusparam)
	{
		PrintHelp();
		print "Now will use all parameters will used default.\n";
		return;
	}
	$NAMEDATABASE = $NAMEDATABASECON;
	$USERDATABASECON = shift or return;
	$USERDATABASE = $USERDATABASECON;
	$FILEBACKUPCON = shift or return;
	$FILEBACKUP = $FILEBACKUPCON;
	$FILEPATCHEDCON = shift or return;
	$FILEPATCHED = $FILEPATCHEDCON;
	$FILELOGCON = shift or return;
	$FILELOG = $FILELOGCON;

}

sub PrintHelp
{
	print "You can use all defaul parameters from top of this file or write it on command line.\n";
	print "\$firststep [name database] [user database] [name file backup] [name file patched backup] [name file log]\n";
	print "\$firststep --help this help\n";
	
	print "For example:\n";
	print "   \$firststep test postgres BackUp.sql BackUpPatched.sql LogPatched.log\n";
	print "or\n";
	print "   \$firststep test postgres\n";
	print "Other parameters will used default.\n\n";

}


sub CreateBackup
{
	print "Create backup with parameters:\n";
		print "Name database:'".$NAMEDATABASE."'\n";
		print "User database:'".$USERDATABASE."'\n";
		print "File for backup:'".$FILEBACKUP."'\n";

	$stringfordump = "pg_dump -F p ".$NAMEDATABASE." > ".$FILEBACKUP." -U ".$USERDATABASE."";
	print $stringfordump."\n";
	system ($stringfordump);
}


