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 = "AedificaDb"; 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"; public static string NLOG_PATH = ""; #endregion Public Fields #region Public Properties /// /// DB Connection string per azioni amministrative /// public static string ADMIN_CONNECTION_STRING { get; set; } = ""; /// /// DB Connection string, per effettuare migration riportare valore connessione admin cablato (server=localhost;port=3306;database=EgtBwDb_000102;) /// public static string CONNECTION_STRING { get; set; } = ""; #endregion Public Properties #region Public Methods /// /// Effettua migrazione esplicita del DB /// /// public static bool CheckMigrateDb() { // esecuzione script di migrations del DB return Controllers.DbController.man.checkMigrateDb(); } /// /// Effettua verifica presenza utente /// /// /// /// /// 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); } /// /// Effettua verifica presenza view prod + relativo utente /// /// /// /// /// public static bool CheckViews(string nKey, string sKey) { // esecuzione script di install locale return Controllers.DbController.man.refreshViews(DATABASE_NAME); } /// /// Effettua DUMP del DB dato utente admin + percorso salvataggio (zip cifrato) /// /// Percorso di salvataggio del dump (*.zip) /// Nome del DB da processare (se vuoto quello di default calcolato) /// Nome o Percorso Eseguibile mysqldump (opzionale) /// Opzioni in fase di export (default: --skip-extended-insert) /// public static bool DataBaseDumpToFile(string zipFilePath, string dbName = "", string mysqlDumpPath = "mysqldump", string exportOpt = "--skip-extended-insert") { 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); } // 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} {dbName} {exportOpt} > {tempSqlPath}"; ExecuteCommand(callScript); // compressione con pwd! using (ZipFile zip = new ZipFile()) { // 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; } /// /// Effettua restore come overwrite del DB di DEFAULT... irreversibile /// /// Percorso di lettura del dump cifrato (*.zip) /// Nome del DB da processare (se vuoto quello di default calcolato) /// Percorso cartella temp x esecuzione /// Nome o Percorso Eseguibile mysql (opzionale) /// Opzioni in fase di import (default: --force) /// 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; } /// /// Esecuzione di un comando esterno /// /// 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(); } /// /// Metodo di init standard per DB in rete con Master_Key /// /// Indirizzo del server (tipicamente indirizzo di rete) /// Numero chiave /// Codice/pwd associato a chiave /// Numero di chiave master con cui è creato il DB 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 = $"AedificaDb_{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"; // 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"; } /// /// Aggiorna conf NLog x target DIR /// /// public static void SetupLogDir(string NLogPath) { NLOG_PATH = NLogPath; } #endregion Public Methods } }