function ConnectMySQL([string]$user, [string]$pass, [string]$mySqlServer, [string]$database) { 
    # Load MySQL .NET Connector Objects 
    [void][system.reflection.Assembly]::LoadWithPartialName("MySql.Data") 
 
    # Open Connection 
    $connStr = "server=" + $mySqlServer + ";port=3306;uid=" + $user + ";pwd=" + $pass + ";database="+$database+";Pooling=FALSE" 
    
    $conn = New-Object MySql.Data.MySqlClient.MySqlConnection($connStr);
    $conn.Open();
    Write-Host "Connected to MySQL database $mySqlServer\$database";
 
    return $conn 
}
function Disconnect-MySQL($conn) {
  $conn.Close()
}
function Execute-MySQLNonQuery($conn, [string]$query) { 
  $command = $conn.CreateCommand()                  # Create command object
  $command.CommandText = $query                     # Load query into object
  $RowsInserted = $command.ExecuteNonQuery()        # Execute command
  $command.Dispose()                                # Dispose of command object
  if ($RowsInserted) { 
    return $RowInserted 
  } else { 
    return $false 
  } 
} 


function CreateUser ([string]$serverIp, [string]$admUser, [string]$admPswd,  [string]$newUser,  [string]$newUserPwd){
	Write-Host ($CREATE_USER_START -f $newUser, $serverIp)
	$command = $MYSQL_CREATEUSER -f $newUser, $newUserPwd ; 
	ExecuteMySQLQuery -sqlCommand:$command -mySqlServer:$serverIp -admPswd:$admPswd -admUser:$admUser;
	Write-Host ($CREATE_USER_END -f $newUser, $serverIp) -ForegroundColor Yellow;
}

function ChangeUserPassword([string]$serverIp, [string]$admUser, [string]$admPswd,  [string]$user,  [string]$newUserPwd){
	Write-Host ($CHANGE_PASSWORD_START -f $user)
	$command = $MYSQL_CHANGEPASSWORD -f $user, $newUserPwd ; 
	ExecuteMySQLQuery -sqlCommand:$command -mySqlServer:$serverIp -admPswd:$admPswd -admUser:$admUser;
	Write-Host ($CHANGE_PASSWORD_END -f $user) -ForegroundColor Yellow;
}

function CreateDataBase([string]$serverIp, [string]$admUser, [string]$admPswd, [string]$newDbName, [string]$user){
	<#
	.SYNOPSIS
		Создает новую базу данных и нового пользовотеля с соответствующими правами для этой базы

	.DESCRIPTION

	.PARAMETER serverIp 
		IP адресс SQL сервера
	.PARAMETER $admUser
		Логин пользователя с правами администратора (sysadmin)
	.PARAMETER $admPswd
		Пароль пользователя с правами администратора (sysadmin)
	.PARAMETER $newDbName
		Логин нового пользователя (будет создан) с правами db_owner для новой базы
	.PARAMETER $user
		Пользователь с правами владельца бд
	

	.EXAMPLE 

	.NOTES
	#>
	Write-Host ($CREATE_DB_START -f $newDbName, $serverIp)
	$command = $CREATE_DATABASE -f $newDbName; 
	$command = $command + $MYSQL_GRANTALL -f $newDbName, $user ; 
	ExecuteMySQLQuery -sqlCommand:$command -mySqlServer:$serverIp -admPswd:$admPswd -admUser:$admUser;
	Write-Host ($CREATE_DB_END -f $newDbName, $serverIp) -ForegroundColor Yellow
	
}

function DeleteDataBase([string]$serverIp, [string]$admUser, [string]$admPswd, [string]$dbName){
	Write-Host ($REMOVE_DB_START -f $dbName, $serverIp)
	$command = $REMOVE_DATABASE -f $dbName; 
	ExecuteMySQLQuery -sqlCommand:$command -mySqlServer:$serverIp -admPswd:$admPswd -admUser:$admUser;
	Write-Host ($REMOVE_DB_END -f $dbName) -ForegroundColor Yellow
}

function RemoveUser([string]$serverIp, [string]$admUser, [string]$admPswd, [string]$userName){
	Write-Host ($DELETE_USER_START -f $userName, $serverIp)
	$command = $REMOVE_USER_FROM_DB -f $userName ; 
	ExecuteMySQLQuery -sqlCommand:$command -mySqlServer:$serverIp -admPswd:$admPswd -admUser:$admUser;
	Write-Host ($DELETE_USER_START -f $userName, $serverIp) -ForegroundColor Yellow
}
	
function RevokeAllPrivilegies([string]$serverIp, [string]$admUser, [string]$admPswd, [string]$userName, [string]$dbName){
	Write-Host ($REVOKE_START -f $userName)
	$command = $MYSQL_REVOKE_ALL -f $dbName,$userName ; 
	ExecuteMySQLQuery -sqlCommand:$command -mySqlServer:$serverIp -admPswd:$admPswd -admUser:$admUser;
	Write-Host ($REVOKE_END -f $userName) -ForegroundColor Yellow
}

function GrantAllPrivilegies([string]$serverIp, [string]$admUser, [string]$admPswd, [string]$userName, [string]$dbName){
 	Write-Host ($GRANT_START -f $userName, $dbName)
	$command = $MYSQL_GRANTALL -f $dbName,$userName ; 
	ExecuteMySQLQuery -sqlCommand:$command -mySqlServer:$serverIp -admPswd:$admPswd -admUser:$admUser;
	Write-Host ($GRANT_END -f $userName, $dbName) -ForegroundColor Yellow
}


function BackupDB([string]$admUser, [string]$admPswd, [string]$dbName, [string]$backupFilePath, [string] $pathToMySQLfolder){
	try{
		#$cmd = " & '{0}\mysqldump.exe' --default-character-set=utf8 -u{1} -p{2} --result-file='{3}' {4} > 'temp.txt' " -f $pathToMySQLfolder,$admUser,$admPswd,$backupFilePath,$dbName ;
		#Invoke-Expression $cmd
		 $cmd1 = "cd `"{0}`"" -f $pathToMySQLfolder;
		 $cmd = ".\mysqldump.exe" -f  $pathToMySQLfolder;
		 $argList = "--default-character-set=utf8 -u{0} -p{1} --result-file=`"{2}`" {3}" -f $admUser,$admPswd,$backupFilePath,$dbName;
		 $redirectFileName = "DumpRedirectError{1}.txt" -f  $backupFilePath, [Guid]::NewGuid().ToString();
		 Invoke-Expression $cmd1
		 $process = Start-Process $cmd -ArgumentList $argList -RedirectStandardError $redirectFileName -PassThru -Wait;
	}
	catch
	{	  
		$returnedException = New-Object PSObject;
		Add-Member -InputObject $returnedException -MemberType NoteProperty -Name Message -Value $_.Exception.Message;
		Add-Member -InputObject $returnedException -MemberType NoteProperty -Name ExceptionType -Value $_.Exception.GetType().FullName;
		return $returnedException;
	
	}
	return  $process.ExitCode;
}

function RestoreDB([string]$admUser, [string]$admPswd, [string]$dbName, [string]$backupFilePath, [string] $pathToMySQLfolder)
{
	try
	{
		$cmd1 = "cd `"{0}`"" -f $pathToMySQLfolder;
		$cmd = "cmd.exe"
		$argList = "/c", ("`"mysql.exe -u{0} -p{1} {2} < {3}`"" -f $admUser,$admPswd,$dbName, $backupFilePath);
		$redirectFileName = "RestoreRedirectError{1}.txt" -f  $backupFilePath, [Guid]::NewGuid().ToString();
		Invoke-Expression $cmd1
		
		$process = Start-Process $cmd -ArgumentList $argList -RedirectStandardError $redirectFileName -PassThru -Wait;
	}
	catch
	{	  
		$returnedException = New-Object PSObject;
		Add-Member -InputObject $returnedException -MemberType NoteProperty -Name Message -Value $_.Exception.Message;
		Add-Member -InputObject $returnedException -MemberType NoteProperty -Name ExceptionType -Value $_.Exception.GetType().FullName;
		return $returnedException;
	}
	return  $process.ExitCode;
}

function RemoteBackupDB([string]$admUser, [string]$admPswd, [string]$dbName, [string]$backupFilePath, [string] $pathToMySQLfolder, [string]$serverName){
	Write-Host ($BACKUP_DB_START -f $dbName, $serverName)
	$res = Invoke-Command -ComputerName $serverName -ScriptBlock ${function:BackupDB} -ArgumentList $admUser, $admPswd, $dbName, $backupFilePath, $pathToMySQLfolder;		
	if($res -eq 0)
	{
		Write-Host ($BACKUP_DB_END -f $dbName, $serverName) -ForegroundColor Yellow;
	}
	else
	{
		$ExceptionMessage =   "Не удалоcь создать бэкап базы {0}. Код ошибки {1}" -f 	 $dbName, $res;
		Write-Host ($ExceptionMessage) -ForegroundColor Red;
		throw $ExceptionMessage;
	}
}

function RemoteRestoreDB([string]$admUser, [string]$admPswd, [string]$dbName, [string]$backupFilePath, [string] $pathToMySQLfolder, [string]$serverName){
	Write-Host ($RESTORE_DB_START -f $database)
	$res = Invoke-Command -ComputerName $serverName -ScriptBlock ${function:RestoreDB} -ArgumentList $admUser, $admPswd, $dbName, $backupFilePath, $pathToMySQLfolder;		
	if($res -eq 0)
	{
	Write-Host ($RESTORE_DB_END -f $database) -ForegroundColor Yellow
	}
	else
	{
		$ExceptionMessage =   "Не удалоcь восстановить бэкап базы {0}. Код ошибки {1}" -f 	 $dbName, $res;
		Write-Host ($ExceptionMessage) -ForegroundColor Red;
		throw $ExceptionMessage;
	}
}

function ExecuteMySQLQuery([string]$mySqlServer, [string]$admUser, [string]$admPswd, [string]$sqlCommand){
<#
.SYNOPSIS
Открывает соединение с MySQL сервером, выполняет sql-команду на MySQL сервере, закрывает соединение

.DESCRIPTION

.PARAMETER mySqlServer 
DNS-имя или IP-адрес хоста

.PARAMETER admUser 
Login администратора MySQL

.PARAMETER admPswd 
Пароль администратора MySQL

.PARAMETER sqlCommand 
Sql-команда на выполнение

.EXAMPLE 
ExecuteMySQLQuery "dns1.server.local" root psw "REVOKE INSERT, CREATE ON testdb1.* FROM 'testuser'@'%';";

.NOTES
#>
	$conn = ConnectMySQL -user:$admUser -pass:$admPswd -mySqlServer:$mySqlServer -database:'mysql';
	Execute-MySQLNonQuery -conn:$conn -query:$sqlCommand;
	Disconnect-MySQL -conn:$conn
}

function QueryTablesInDB([string]$mySqlServer, [string]$admUser, [string]$admPswd, [string]$dbName)
{
	$tables = @();
	$conn = ConnectMySQL -user:$admUser -pass:$admPswd -mySqlServer:$mySqlServer -database:'mysql';
	$command = $conn.CreateCommand();
  	$command.CommandText = ($MYSQL_QUERY_ALL_TABLES -f $dbName);
  	$reader = $command.ExecuteReader();
	
	while($reader.Read())
	{
		$tables += $reader["TABLE_NAME"];
	}
	$reader.Close();
  	$command.Dispose();
  	
	Disconnect-MySQL -conn:$conn
}

function RestoreDbSizeQuotaUserPermissions([string]$mySqlServer, [string]$admUser, [string]$admPswd, [string]$userName, [string]$database){
<#
.SYNOPSIS
Восстанавливает разрешения, ранее снятые ввиду сработки квоты по занимаемому месту БД

.DESCRIPTION

.PARAMETER mySqlServer 
DNS-имя или IP-адрес хоста

.PARAMETER admUser 
Login администратора MySQL

.PARAMETER admPswd 
Пароль администратора MySQL

.PARAMETER userName 
Пользователь mySQL, права которого модифицируются

.PARAMETER database 
Имя БД в которой прозводится модификация прав доступа


.EXAMPLE 
RestoreDbSizeQuotaUserPermissions "dns1.server.local" root psw testuser testdb1;

.NOTES
#>
	$command = $MYSQL_GRANT -f $MYSQL_SIZE_QUOTA_PERMISSION_SET, $database, $userName ; 
	ExecuteMySQLQuery $mySqlServer $admUser $admPswd $command;
}

function RemoveDbSizeQuotaUserPermissions([string]$mySqlServer, [string]$admUser, [string]$admPswd, [string]$userName, [string]$database){
<#
.SYNOPSIS
Убирает разрешения пользователя, ввиду сработки квоты по занимаемому месту БД

.DESCRIPTION

.PARAMETER mySqlServer 
DNS-имя или IP-адрес хоста

.PARAMETER admUser 
Login администратора MySQL

.PARAMETER admPswd 
Пароль администратора MySQL

.PARAMETER userName 
Пользователь mySQL, права которого модифицируются

.PARAMETER database 
Имя БД в которой прозводится модификация прав доступа


.EXAMPLE 
RemoveDbSizeQuotaUserPermissions "dns1.server.local" root psw testuser testdb1;

.NOTES
#>

	$command = $MYSQL_REVOKE -f $MYSQL_SIZE_QUOTA_PERMISSION_SET, $database, $userName ; 
	ExecuteMySQLQuery $mySqlServer $admUser $admPswd $command;
}

function SetQuota([string]$mySqlServer, [string]$database, [string]$size)
{
<#
.SYNOPSIS
Устанавливает квоту на папку с БД

.DESCRIPTION

.PARAMETER mySqlServer 
DNS-имя или IP-адрес хоста

.PARAMETER admUser 
Login администратора MySQL

.PARAMETER admPswd 
Пароль администратора MySQL

.PARAMETER userName 
Пользователь mySQL, права которого модифицируются

.PARAMETER database 
Имя БД в которой прозводится модификация прав доступа

.EXAMPLE 
SetQuota 100MB "dns1.server.local" root psw testuser testdb1;

.NOTES
#>
	#$command = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe";
	#$args = ".\mySQLRemoveDbSizeQuotaUserPermissions.ps1 -server $mySqlServer -admUser $admUser -admPsw $admPswd -user $userName -database $database";
	CreateQuota -computer $mySqlServer -path "$PathToDatabases\$database" -size $size;
	#CreateSoftQuotaWithCommand -computer $mySqlServer -path "$PathToDatabases\$database" -size $size -command $command -argsstr $args -workingDirPath $PathToScripts;
}

function ReadBackupPath($server,$backupCatalog)
{
<#
.SYNOPSIS
Считывает и файла с расположением $PATH_TO_BACKUP путь к каталогу бэкапов на указанном IIS-сервере

.DESCRIPTION

.PARAMETER iisserver 
IP-адрес или DNS-имя IIS-сервера

.EXAMPLE 
ReadBackupPath -server 172.21.41.134

.NOTES
#>
	$Root = Invoke-Command -ComputerName $server -ScriptBlock ${function:ReadBackupPathInternal} -ArgumentList $PATH_TO_BACKUP_CONFIG,$backupCatalog;
	return $Root;
}

function ReadBackupPathInternal($ConfigPath, $backupCatalog)
{
	$FileExists = Test-Path -Path $ConfigPath;
	$Root = "";
	if($FileExists)
	{
		$Root = Get-Content -Path $ConfigPath -TotalCount 1;
	}
	if([string]::IsNullOrEmpty($Root))
	{
		$Root = "C:\Backup";
	}
	
	$ResultPath = "$Root\$backupCatalog";
	
	if(!(Test-Path $ResultPath))
	{
		$Folder = New-Item -Path $ResultPath -ItemType "directory";
	}
	return $ResultPath;
}