Files
egtbeamwall/EgtBEAMWALL.DataLayer/DbConfig.cs
T
2024-06-28 18:53:03 +02:00

300 lines
14 KiB
C#

using Ionic.Zip;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
namespace EgtBEAMWALL.DataLayer
{
public static class DbConfig
{
#region Public Fields
public static string DATABASE_NAME = "EgtBwDb";
public static int DATABASE_PROCESS_TIMEOUT = 5;
public static string DATABASE_PWD = "viacremasca";
// Database config
public static string DATABASE_SERV = "127.0.0.1";
public static string DATABASE_USER = "EgtUser";
public static string ZIP_PWD = "viacremasca-viacremasca-viacremasca-viacremasca";
#endregion Public Fields
#region Public Properties
/// <summary>
/// DB Connection string per azioni amministrative:
/// aggiunto parametro "allow user variables", da https://forums.mysql.com/read.php?38,609672,610320#msg-610320
/// </summary>
public static string ADMIN_CONNECTION_STRING { get; set; } = "";
/// <summary>
/// DB Connection string, per effettuare migration riportare valore connessione admin cablato
/// DB Manu: server=localhost;port=3306;database=EgtBwDb_000102;uid=root;pwd=Egalware_24068!;
/// DB Sam: server=localhost;port=3306;database=EgtBwDb_000470;uid=root;pwd=Egalware_24068!;
/// DB Lovato: server=localhost;port=3306;database=EgtBwDb_000656;uid=root;pwd=Egalware_24068!;
///
/// DB RETE Lovato: server=mdb.ufficio;port=3306;database=EgtBwDb_000656;uid=steamware;pwd=Egalware_24068!;
/// DB TET corelocal: server=corelocal.egalware.com;port=3306;database=EgtBwDb_000999;uid=steamware;pwd=Egalware_24068!;
/// </summary>
//public static string CONNECTION_STRING { get; set; } = "server=localhost;port=3306;database=EgtBwDb_000470;uid=root;pwd=Egalware_24068!;allow user variables=true";
//public static string CONNECTION_STRING { get; set; } = "server=localhost;port=3306;database=EgtBwDb_000656;uid=root;pwd=Egalware_24068!;allow user variables=true";
//public static string CONNECTION_STRING { get; set; } = "server=corelocal.egalware.com;port=3306;database=EgtBwDb_000656;uid=root;pwd=Egalware_24068!;allow user variables=true";
//public static string CONNECTION_STRING { get; set; } = "server=mdb.ufficio;port=3306;database=EgtBwDb_000656;uid=steamware;pwd=Egalware_24068!;allow user variables=true";
public static string CONNECTION_STRING { get; set; } = "server=localhost;port=3306;database=EgtBwDb_000656;uid=root;pwd=Egalware_24068!;allow user variables=true";
//public static string CONNECTION_STRING { get; set; } = "server=localhost;port=3306;database=EgtBwDb_000102;uid=root;pwd=Egalware_24068!;allow user variables=true";
//public static string CONNECTION_STRING { get; set; } = "server=localhost;port=3306;database=EgtBwDb_000999;uid=root;pwd=Egalware_24068!;allow user variables=true";
//public static string CONNECTION_STRING { get; set; } = "server=corelocal.egalware.com;port=3306;database=EgtBwDb_000999;uid=root;pwd=Egalware_24068!;allow user variables=true";
//public static string CONNECTION_STRING { get; set; } = "server=mdb.ufficio;port=3306;database=EgtBwDb_000999;uid=steamware;pwd=Egalware_24068!;allow user variables=true";
#endregion Public Properties
#region Public Methods
/// <summary>
/// Effettua migrazione esplicita del DB
/// </summary>
/// <returns></returns>
public static bool CheckMigrateDb()
{
// esecuzione script di migrations del DB
return Controllers.DbController.man.checkMigrateDb();
}
/// <summary>
/// Effettua verifica presenza utente
/// </summary>
/// <param name="nKey"></param>
/// <param name="sKey"></param>
/// <param name="isNetwork"></param>
/// <returns></returns>
public static bool CheckUser(string nKey, string sKey, bool isNetwork)
{
// esecuzione script di install locale
return Controllers.DbController.man.checkCreateUser(DATABASE_USER, DATABASE_PWD, isNetwork);
}
/// <summary>
/// Effettua verifica presenza view prod + relativo utente
/// </summary>
/// <param name="nKey"></param>
/// <param name="sKey"></param>
/// <param name="isNetwork"></param>
/// <returns></returns>
public static bool CheckViews(string nKey, string sKey)
{
return false;
// commento, scambiare con migrations da file?!?
//// esecuzione script di install locale
//return Controllers.DbController.man.refreshViews(DATABASE_NAME);
}
/// <summary>
/// Effettua DUMP del DB dato utente admin + percorso salvataggio (zip cifrato)
/// </summary>
/// <param name="zipFilePath">Percorso di salvataggio del dump (*.zip)</param>
/// <param name="dbName">Nome del DB da processare (se vuoto quello di default calcolato)</param>
/// <param name="mysqlDumpPath">Nome o Percorso Eseguibile mysqldump (opzionale)</param>
/// <param name="exportOpt">Opzioni in fase di export | default: --add-drop-database --skip-extended-insert --hex-blob</param>
/// <returns></returns>
public static bool DataBaseDumpToFile(string zipFilePath, string dbName = "", string mysqlDumpPath = "mysqldump", string exportOpt = "--add-drop-database --skip-extended-insert --hex-blob")
{
bool fatto = false;
// fix path eseguibile
if (string.IsNullOrEmpty(mysqlDumpPath))
{
mysqlDumpPath = "mysqldump";
}
if (string.IsNullOrEmpty(dbName))
{
dbName = DATABASE_NAME;
}
// verifica zip finale
if (!zipFilePath.EndsWith(".zip"))
{
zipFilePath = $"{zipFilePath}.zip";
}
// creo nome file per export sql (temporaneo)
string tempSqlPath = zipFilePath.Replace(".zip", ".sql");
// esecuzione script x dump del DB
string dirPath = Path.GetDirectoryName(zipFilePath);
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
// se ci fosse già file elimino (sql/zip)
if (File.Exists(tempSqlPath))
{
File.Delete(tempSqlPath);
}
if (File.Exists(zipFilePath))
{
File.Delete(zipFilePath);
}
// 2024.06.28 aggiunto --hex-blob x dati binary
// creazione SQL, tramite script esterno... importante parametro "--skip-extended-insert" altrimenti problemi con restore (anche se + verboso e lento in backup...)
string callScript = $"\"{mysqlDumpPath}\" -u{DATABASE_USER} -p{DATABASE_PWD} --databases {dbName} {exportOpt} > {tempSqlPath}";
ExecuteCommand(callScript);
// compressione con pwd!
using (ZipFile zip = new ZipFile())
{
// non paiono necessarie x ripristino
//zip.CompressionMethod = CompressionMethod.BZip2;
//zip.UseUnicodeAsNecessary = true;
// aggiungo pwd
zip.Password = ZIP_PWD;
// inserisco file
zip.AddFile(tempSqlPath, "");
zip.Save(zipFilePath);
fatto = true;
}
// elimino file sql temporaneo...
if (File.Exists(tempSqlPath))
{
File.Delete(tempSqlPath);
}
return fatto;
}
/// <summary>
/// Effettua restore come overwrite del DB di DEFAULT... irreversibile
/// </summary>
/// <param name="zipFilePath">Percorso di lettura del dump cifrato (*.zip)</param>
/// <param name="dbName">Nome del DB da processare (se vuoto quello di default calcolato)</param>
/// <param name="tempFolder">Percorso cartella temp x esecuzione</param>
/// <param name="mysqlPath">Nome o Percorso Eseguibile mysql (opzionale)</param>
/// <param name="importOpt">Opzioni in fase di import (default: --force)</param>
/// <returns></returns>
public static bool DataBaseRestoreFromFile(string zipFilePath, string dbName = "", string tempFolder="", string mysqlPath = "mysql", string importOpt = "--force")
{
bool fatto = false;
// fix path eseguibile
if (string.IsNullOrEmpty(mysqlPath))
{
mysqlPath = "mysql";
}
if (string.IsNullOrEmpty(dbName))
{
dbName = DATABASE_NAME;
}
if (string.IsNullOrEmpty(tempFolder))
{
tempFolder = "C:\\Temp";
}
// verifica zip finale
if (!zipFilePath.EndsWith(".zip"))
{
zipFilePath = $"{zipFilePath}.zip";
}
// elimino eventuale temp folder precedente...
if (Directory.Exists(tempFolder))
{
Directory.Delete(tempFolder, true);
}
Directory.CreateDirectory(tempFolder);
// scompatto file zip --> sql
using (ZipFile zip = ZipFile.Read(zipFilePath))
{
zip.Password = ZIP_PWD;
zip.ExtractAll(tempFolder, ExtractExistingFileAction.OverwriteSilently);
}
// verifico che ci sia 1 file sql...
var sqlFiles = Directory.GetFiles(tempFolder, "*.sql");
if (sqlFiles != null && sqlFiles.Length == 1)
{
// verifico nome file per export sql (temporaneo)
string tempSqlPath = sqlFiles.FirstOrDefault();
// chiamo script esterno...
string callScript = $"\"{mysqlPath}\" -u{DATABASE_USER} -p{DATABASE_PWD} {importOpt} {dbName} < {tempSqlPath}";
ExecuteCommand(callScript);
// elimino il file sql importato...
File.Delete(tempSqlPath);
// elimino temp folder...
Directory.Delete(tempFolder, true);
fatto = true;
}
return fatto;
}
/// <summary>
/// Esecuzione di un comando esterno
/// </summary>
/// <param name="command"></param>
public static void ExecuteCommand(string command)
{
int exitCode;
ProcessStartInfo processInfo;
Process process;
processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
// *** Redirect the output ***
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
process = Process.Start(processInfo);
process.WaitForExit();
// *** Read the streams ***
// Warning: This approach can lead to deadlocks, see Edit #2
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
exitCode = process.ExitCode;
Console.WriteLine("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
Console.WriteLine("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
Console.WriteLine("ExitCode: " + exitCode.ToString(), "ExecuteCommand");
process.Close();
}
/// <summary>
/// Metodo di init standard per DB in rete con Master_Key
/// </summary>
/// <param name="server">Indirizzo del server (tipicamente indirizzo di rete)</param>
/// <param name="nKey">Numero chiave</param>
/// <param name="sKey">Codice/pwd associato a chiave</param>
/// <param name="masterKey">Numero di chiave master con cui è creato il DB</param>
public static void InitDb(string server, string nKey, string sKey, string masterKey = "")
{
// se nulla metto amster come nKey...
masterKey = string.IsNullOrEmpty(masterKey) ? nKey : masterKey;
DATABASE_SERV = server;
DATABASE_NAME = $"EgtBwDb_{masterKey}";
DATABASE_USER = $"user_{nKey}";
DATABASE_PWD = $"pwd_{sKey}";
ZIP_PWD = $"{DATABASE_USER}:{DATABASE_PWD}:{DATABASE_USER}:{DATABASE_PWD}";
CONNECTION_STRING = $"server={DATABASE_SERV};port=3306;database={DATABASE_NAME};uid={DATABASE_USER};pwd={DATABASE_PWD};SslMode=None;allow user variables=true";
// stringa admin con utente root egalware...
ADMIN_CONNECTION_STRING = $"server={DATABASE_SERV};port=3306;database=mysql;uid=root;pwd=Egalware_24068!;SslMode=none;CHARSET=utf8;allow user variables=true";
}
/// <summary>
/// Aggiorna conf NLog x target DIR
/// </summary>
/// <param name="logDir"></param>
public static void SetupLogDir(string logDir)
{
string appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string filePath = Path.Combine(appDir, "NLog.config");
// leggo il file NLog
string rawData = File.ReadAllText(filePath);
// sostituzione livello minimo da selezione
rawData = rawData.Replace("${basedir}", logDir);
// ri-scrivo file NLog
File.WriteAllText(filePath, rawData);
}
#endregion Public Methods
}
}