diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs index 92d45d3..ecac672 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs @@ -70,8 +70,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS var dbname = SQLDataBaseManagerCore.GetDBName(sqld.SQLCS); ColorConsole.WriteLine($"Database backup process started. DB key:'{key}', name:'{dbname}'...", ConsoleColor.Yellow); if (!string.IsNullOrWhiteSpace(targetfolder)) { sqld.Xml_BackupTargetDirectoryPath = targetfolder; } - if (enabledbbackup) { SQLDataBaseManagerCore.CreateBackup(sqld.Xml_BackupTargetDirectoryPath, sqld.SQLCS, sqld.Xml_BackupFileNameMask, sqld.Xml_CreateZip, timestamp); } - if (enablescriptbackup) { SQLDataBaseManagerCore.BackupSqlScripts(sqld.Xml_BackupTargetDirectoryPath, sqld.Xml_BackupFileNameMask, sqld.SQLCS, sqld.Xml_CreateZip, timestamp); } + if (enabledbbackup) { SQLDataBaseManagerCore.CreateBackup(sqld,null, timestamp); } + if (enablescriptbackup) { SQLDataBaseManagerCore.BackupSqlScripts(sqld, timestamp); } if (enabletabledatabackup) { SQLDataBaseManagerCore.BackupSqlData(sqld, timestamp); } ColorConsole.WriteLine($"Database backup process finished!", ConsoleColor.DarkGreen); } @@ -135,7 +135,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS try { - SQLDataBaseManagerCore.BackupSqlScripts(sqld.Xml_BackupTargetDirectoryPath, sqld.Xml_BackupFileNameMask,sqld.SQLCS,sqld.Xml_CreateZip,TS); + SQLDataBaseManagerCore.BackupSqlScripts(sqld,TS); ColorConsole.WriteLine($"SQLDB code scripts created. Name:{sqld.Xml_Description}", ConsoleColor.Green); } catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } @@ -164,7 +164,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS SQLDataBase ssqldb = p.Parameters as SQLDataBase; try { - SQLDataBaseManagerCore.CreateBackup(ssqldb.Xml_BackupTargetDirectoryPath, ssqldb.SQLCS, ssqldb.Xml_BackupFileNameMask, ssqldb.Xml_CreateZip,TS); + SQLDataBaseManagerCore.CreateBackup(ssqldb,null,TS); ColorConsole.WriteLine($"Database backup created. Name:{ssqldb.DBName}", ConsoleColor.Green); } catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } @@ -212,7 +212,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS if (ms == null) { continue; } selectedbackupfilepath = ms.SelectedParameterList.First().Parameters.ToString(); } - SQLDataBaseManagerCore.RestoreBackup(st.SQLCS, selectedbackupfilepath, targetdirectorypath, restorefromzip, targetdbname); + SQLDataBaseManagerCore.RestoreBackup(st, selectedbackupfilepath, targetdirectorypath, restorefromzip, targetdbname); ColorConsole.WriteLine($"Database '{st.DBName}' restored to '{targetdbname}' into directory '{targetdirectorypath}'.", ConsoleColor.Green); } else @@ -729,13 +729,20 @@ GO public static void RelocatePhysicalFiles(SQLDataBase sqld, string targetdirectory, string restoredbname) { - var dbbackupfilepath = CreateBackup(sqld.Xml_BackupTargetDirectoryPath, sqld.SQLCS, sqld.Xml_BackupFileNameMask, false); + var dbbackupfilepath = CreateBackup(sqld, false,null); if (dbbackupfilepath == null) return; - RestoreBackup(sqld.SQLCS, dbbackupfilepath, targetdirectory, false, restoredbname); + RestoreBackup(sqld, dbbackupfilepath, targetdirectory, false, restoredbname); if (File.Exists(dbbackupfilepath)) { File.Delete(dbbackupfilepath); } } - public static void RestoreBackup(string sqlcs, string sourcesqlbackupfilepath, string targetdbphysicalfilesdirectorypath, bool restorefromZIP = false, string restoretodbname = null) + public static void RestoreBackup(SQLDataBase sqldb, string sourcesqlbackupfilepath, string targetdbphysicalfilesdirectorypath, bool restorefromZIP = false, string restoretodbname = null) { + if (sqldb.Xml_IsRemoteDB) + { + ColorConsole.WriteLine(text: $" {nameof(RestoreBackup)}: data restore is not available for remote SQL Servers! DBname:'{sqldb.DBName}'.", prefix: $"WARNING!", f: ConsoleColor.Yellow); + return; + } + + string sqlcs = sqldb.SQLCS; string backupfilepath; if (restorefromZIP) { @@ -783,60 +790,107 @@ GO if (File.Exists(backupfilepath)) { File.Delete(backupfilepath); } } } - public static string CreateBackup(string backupdirectorypath, string sqlconnectionstring, string backupfilenamemask, bool createzip = false,DateTime? timestamp=null) + + /// + /// Create SQL DB backup + /// + /// az sql db-t leíró descriptor + /// + /// + /// + public static string CreateBackup(SQLDataBase sqld,bool? forcecreatezip, DateTime? timestamp) { + string backupdirectorypath = sqld.Xml_BackupTargetDirectoryPath; + string tranzitdirectorypathlocal = sqld.Xml_TranzitDirectoryPathLocal; + string tranzitdirectorypathnetwork = sqld.Xml_TranzitDirectoryPathNetwork; + bool usetranzit = sqld.Xml_IsRemoteDB; + string sqlconnectionstring = sqld.SQLCS; + string backupfilenamemask = sqld.Xml_BackupFileNameMask; + bool createzip = forcecreatezip ?? sqld.Xml_CreateZip; + //tranzitdirectorypathlocal = @"F:\ALM"; + //tranzitdirectorypathnetwork = @"\\matng-sql01\ALM"; var sqlserver = SQLServerConnect(sqlconnectionstring); + if (sqlserver == null) + { + ColorConsole.WriteLine($"ERROR! Database connection string error. '{sqlconnectionstring}'", ConsoleColor.Red); + return null; + } + string returnfilename = null; - if (sqlserver != null) - { - var dbname = GetDBName(sqlconnectionstring); + var dbname = GetDBName(sqlconnectionstring); - var backupts = (timestamp.HasValue ? timestamp.Value : DateTime.Now).ToString("yyyyMMddHHmmss"); - - string backupfileNameOnly = Path.GetFileNameWithoutExtension(backupfilenamemask); - var vars = new Dictionary(); - vars.Add(nameof(DBSubstitutionName.DATABASE), GetDBName(sqlconnectionstring)); - vars.Add(nameof(DBSubstitutionName.DATASOURCE), GetDataSource(sqlconnectionstring)); - vars.Add(nameof(DBSubstitutionName.DBOTYPE), "DBBACKUP"); - vars.Add(nameof(DBSubstitutionName.DBONAME), ""); - vars.Add(nameof(DBSubstitutionName.DBDATAGROUP), ""); - vars.Add(nameof(DBSubstitutionName.BACKUPTS), backupts); + var backupts = (timestamp.HasValue ? timestamp.Value : DateTime.Now).ToString("yyyyMMddHHmmss"); - backupfileNameOnly = VRH.Common.StringConstructor.ResolveConstructorR(vars, backupfileNameOnly, "{}@@"); - - string backupfilename = backupfileNameOnly + ".bak"; - string backupFullName = Path.Combine(backupdirectorypath, backupfilename); - if (File.Exists(backupFullName)) { File.Delete(backupFullName); } - - var smoBackup = new Backup(); - smoBackup.Action = BackupActionType.Database; - smoBackup.BackupSetDescription = $"Full Backup of {sqlserver.ConnectionContext.DatabaseName}"; - smoBackup.BackupSetName = sqlserver.ConnectionContext.DatabaseName + " Backup"; - smoBackup.Database = sqlserver.ConnectionContext.DatabaseName; - smoBackup.MediaDescription = "Disk"; - smoBackup.Devices.AddDevice(backupFullName, DeviceType.File); - //smoBackup. - smoBackup.PercentComplete += SmoBackup_PercentComplete; - smoBackup.PercentCompleteNotification = 1; - smoBackup.SqlBackupAsync(sqlserver); - Console.WriteLine(""); - smoBackup.Wait(); - Console.WriteLine(""); - - returnfilename = backupFullName; + string backupfileNameOnly = Path.GetFileNameWithoutExtension(backupfilenamemask); + var vars = new Dictionary(); + vars.Add(nameof(DBSubstitutionName.DATABASE), GetDBName(sqlconnectionstring)); + vars.Add(nameof(DBSubstitutionName.DBKEY), sqld.Xml_Key); + vars.Add(nameof(DBSubstitutionName.DATASOURCE), GetDataSource(sqlconnectionstring)); + vars.Add(nameof(DBSubstitutionName.DBOTYPE), "DBBACKUP"); + vars.Add(nameof(DBSubstitutionName.DBONAME), ""); + vars.Add(nameof(DBSubstitutionName.DBDATAGROUP), ""); + vars.Add(nameof(DBSubstitutionName.BACKUPTS), backupts); + + backupfileNameOnly = VRH.Common.StringConstructor.ResolveConstructorR(vars, backupfileNameOnly, "{}@@"); + + string backupfilename = backupfileNameOnly + ".bak"; + string backupFullName = Path.Combine(backupdirectorypath, backupfilename); + string tranzitFullNameLocal= usetranzit ? Path.Combine(tranzitdirectorypathlocal, backupfilename) : null; + string tranzitFullNameNetwork= usetranzit ? Path.Combine(tranzitdirectorypathnetwork, backupfilename) : null; + if (File.Exists(backupFullName)) { File.Delete(backupFullName); } + + + var smoBackup = new Backup(); + smoBackup.Action = BackupActionType.Database; + smoBackup.BackupSetName = sqlserver.ConnectionContext.DatabaseName + " Backup"; + smoBackup.BackupSetDescription = $"Full Backup of {sqlserver.ConnectionContext.DatabaseName}"; + smoBackup.MediaDescription = "Disk"; + Console.WriteLine($"Backup set: {smoBackup.BackupSetName} ({smoBackup.BackupSetDescription}) to media: {smoBackup.MediaDescription}"); + smoBackup.Database = sqlserver.ConnectionContext.DatabaseName; + string dummystring = usetranzit ? " REMOTE SQL SERVER!" : ""; + Console.WriteLine($"Database name: {smoBackup.Database}{dummystring}"); + Console.WriteLine($"Connection string: {sqld.SQLCS}"); + smoBackup.Devices.AddDevice(usetranzit ? tranzitFullNameLocal : backupFullName, DeviceType.File); + Console.WriteLine($"Backup full name:{backupFullName}"); + if (usetranzit) + { + Console.WriteLine($" ...will be created through tranzit: {tranzitFullNameNetwork}"); + } + smoBackup.PercentComplete += SmoBackup_PercentComplete; + smoBackup.PercentCompleteNotification = 1; + smoBackup.SqlBackupAsync(sqlserver); + var startbackup = DateTime.Now; + smoBackup.Wait(); + Console.WriteLine($""); + Console.WriteLine($"Backup completed. Backup time: {(int)(DateTime.Now.Subtract(startbackup).TotalSeconds)}sec."); + if (usetranzit && File.Exists(tranzitFullNameNetwork)) + { + File.Move(tranzitFullNameNetwork, backupFullName); + Console.WriteLine($"Moving backup file..."); + Console.WriteLine($" ...from tranzit location: {tranzitFullNameNetwork}"); + Console.WriteLine($" ...to backup location: {backupFullName}"); + } + returnfilename = backupFullName; + if (File.Exists(backupFullName)) + { if (createzip) { + var startcompressing = DateTime.Now; string ZIPbackupfilename = backupfileNameOnly + ".zip"; string ZIPbackupFullName = Path.Combine(backupdirectorypath, ZIPbackupfilename); if (File.Exists(ZIPbackupFullName)) { File.Delete(ZIPbackupFullName); } - ZipTools.CreateEntriesFromDirectoryContent(backupdirectorypath, ZIPbackupFullName, backupfilename, "","", removearchivedfiles: false, storepathinzip: false); - if (File.Exists(backupFullName)) { File.Delete(backupFullName); } + ZipTools.CreateEntriesFromDirectoryContent(backupdirectorypath, ZIPbackupFullName, backupfilename, "", "", removearchivedfiles: false, storepathinzip: false); + File.Delete(backupFullName); + Console.WriteLine($"Zipping completed. Compressing time: {(int)(DateTime.Now.Subtract(startcompressing).TotalSeconds)}sec."); returnfilename = ZIPbackupFullName; } - ColorConsole.WriteLine($"Database backup created. DB name:'{dbname}'. BAK/ZIP file name:'{Path.GetFileName(returnfilename)}'", ConsoleColor.DarkGreen); + ColorConsole.WriteLine($"SUCCESS! Database backup created. DB name:'{dbname}'. BAK/ZIP file name:'{Path.GetFileName(returnfilename)}'", ConsoleColor.DarkGreen); + } + else + { + ColorConsole.WriteLine($"ERROR! Database backup failed. DB name:'{dbname}'. BAK/ZIP file name:'{Path.GetFileName(returnfilename)}'", ConsoleColor.Red); } - else { ColorConsole.WriteLine($"SQL scripts create: error in db connection string. '{sqlconnectionstring}'", ConsoleColor.DarkGreen); } return returnfilename; } @@ -1074,7 +1128,7 @@ GO #region DBSubstitution public enum DBSubstitutionName { - DATABASE,DATASOURCE,DBOTYPE,DBONAME,DBDATAGROUP,BACKUPTS,SHRINKOPTION,SHRINKFREESPACEPERCENT, + DBKEY,DATABASE,DATASOURCE,DBOTYPE,DBONAME,DBDATAGROUP,BACKUPTS,SHRINKOPTION,SHRINKFREESPACEPERCENT, } #endregion DBSubstitution #region ExecuteSQLScript @@ -1233,8 +1287,17 @@ GO } #endregion ExecuteSQLStoredProcedure #region BackupSqlScripts - public static void BackupSqlScripts(string backupdirectorypath,string backupfilenamemask,string sqlcs,bool createZip, DateTime? timestamp=null) + public static void BackupSqlScripts(SQLDataBase sqld, DateTime? timestamp=null) { + if (sqld.Xml_IsRemoteDB) + { + ColorConsole.WriteLine(text:$" {nameof(BackupSqlScripts)}: scrip backup is not available for remote SQL Servers! DBname:'{sqld.DBName}'.",prefix:$"WARNING!",f: ConsoleColor.Yellow); + return; + } + string backupdirectorypath = sqld.Xml_BackupTargetDirectoryPath; + string backupfilenamemask = sqld.Xml_BackupFileNameMask; + string sqlcs = sqld.SQLCS; + bool createZip = sqld.Xml_CreateZip; var sqlserver = SQLServerConnect(sqlcs); var dbname = GetDBName(sqlcs); if (sqlserver!=null) @@ -1345,6 +1408,11 @@ GO #region BackupSqlData public static void BackupSqlData(SQLDataBase sqld,DateTime? timestamp=null) { + if (sqld.Xml_IsRemoteDB) + { + ColorConsole.WriteLine(text: $" {nameof(BackupSqlData)}: data backup as scripts is not available for remote SQL Servers! DBname:'{sqld.DBName}'.", prefix: $"WARNING!", f:ConsoleColor.Yellow); + return; + } string sqlcs = sqld.SQLCS; var sqlserver = SQLServerConnect(sqlcs); var dbname = GetDBName(sqlcs); @@ -1494,6 +1562,8 @@ GO Xml_BackupFileNameMask = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.BackupFileNameMask), this.RootElement, SQLDataBase.XmlStructure.Attributes.BackupFileNameMask.Values.DEFAULT), Xml_RestoreFileNameMask = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.RestoreFileNameMask), this.RootElement, SQLDataBase.XmlStructure.Attributes.RestoreFileNameMask.Values.DEFAULT), Xml_BackupTargetDirectoryPath = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.BackupTargetDirectoryPath), this.RootElement, SQLDataBase.XmlStructure.Attributes.BackupTargetDirectoryPath.Values.DEFAULT), + Xml_TranzitDirectoryPathLocal = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.TranzitDirectoryPathLocal), this.RootElement, SQLDataBase.XmlStructure.Attributes.TranzitDirectoryPathLocal.Values.DEFAULT), + Xml_TranzitDirectoryPathNetwork = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.TranzitDirectoryPathNetwork), this.RootElement, SQLDataBase.XmlStructure.Attributes.TranzitDirectoryPathNetwork.Values.DEFAULT), Xml_PhysicalFilesDirectoryPath = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.PhysicalFilesDirectoryPath), this.RootElement, SQLDataBase.XmlStructure.Attributes.PhysicalFilesDirectoryPath.Values.DEFAULT), Xml_ScriptCommandTimeout = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.ScriptCommandTimeout), this.RootElement, SQLDataBase.XmlStructure.Attributes.ScriptCommandTimeout.Values.DEFAULT), }; @@ -1521,6 +1591,9 @@ GO public string Xml_BackupFileNameMask; public string Xml_RestoreFileNameMask; public string Xml_BackupTargetDirectoryPath; + public string Xml_TranzitDirectoryPathLocal; + public bool Xml_IsRemoteDB { get { return !string.IsNullOrWhiteSpace(Xml_TranzitDirectoryPathLocal); } } + public string Xml_TranzitDirectoryPathNetwork; public string Xml_SQLConnectionString; public string Xml_PhysicalFilesDirectoryPath; public int Xml_ScriptCommandTimeout; @@ -1552,6 +1625,8 @@ GO Xml_BackupFileNameMask = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.BackupFileNameMask), sqldatabasexml, common.Xml_BackupFileNameMask); Xml_RestoreFileNameMask = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.RestoreFileNameMask), sqldatabasexml, common.Xml_RestoreFileNameMask); Xml_BackupTargetDirectoryPath = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.BackupTargetDirectoryPath), sqldatabasexml, common.Xml_BackupTargetDirectoryPath); + Xml_TranzitDirectoryPathLocal = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.TranzitDirectoryPathLocal), sqldatabasexml, common.Xml_TranzitDirectoryPathLocal); + Xml_TranzitDirectoryPathNetwork = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.TranzitDirectoryPathNetwork), sqldatabasexml, common.Xml_TranzitDirectoryPathNetwork); Xml_SQLConnectionString = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.SQLConnectionString), sqldatabasexml, XmlStructure.SQLDataBase.Attributes.SQLConnectionString.Values.DEFAULT); Xml_CreateZip = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.CreateZip), sqldatabasexml, common.Xml_CreateZip); @@ -1579,6 +1654,8 @@ GO Xml_BackupFileNameMask = sqld.Xml_BackupFileNameMask; Xml_RestoreFileNameMask = sqld.Xml_RestoreFileNameMask; Xml_BackupTargetDirectoryPath = sqld.Xml_BackupTargetDirectoryPath; + Xml_TranzitDirectoryPathLocal = sqld.Xml_TranzitDirectoryPathLocal; + Xml_TranzitDirectoryPathNetwork = sqld.Xml_TranzitDirectoryPathNetwork; Xml_SQLConnectionString = sqld.Xml_SQLConnectionString; Xml_PhysicalFilesDirectoryPath = sqld.Xml_PhysicalFilesDirectoryPath; Xml_SQLDataList = sqld.Xml_SQLDataList.Select(x => new SQLData(x)).ToList(); @@ -1593,6 +1670,8 @@ GO public static class BackupFileNameMask { public static class Values { public const string DEFAULT = ""; } } public static class RestoreFileNameMask { public static class Values { public const string DEFAULT = ""; } } public static class BackupTargetDirectoryPath { public static class Values { public const string DEFAULT = ""; } } + public static class TranzitDirectoryPathLocal { public static class Values { public const string DEFAULT = ""; } } + public static class TranzitDirectoryPathNetwork { public static class Values { public const string DEFAULT = ""; } } public static class PhysicalFilesDirectoryPath { public static class Values { public const string DEFAULT = ""; } } public static class ScriptCommandTimeout { public static class Values { public const int DEFAULT = 10000; } } @@ -1609,6 +1688,8 @@ GO public static class BackupFileNameMask { } public static class RestoreFileNameMask { } public static class BackupTargetDirectoryPath { } + public static class TranzitDirectoryPathLocal { } + public static class TranzitDirectoryPathNetwork { } public static class CreateZip { } public static class PhysicalFilesDirectoryPath { } public static class ScriptCommandTimeout { public static class Values { public const int DEFAULT = 10000; } } diff --git a/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs b/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs index 98a957f..c531fe8 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.25.2.0")] -[assembly: AssemblyFileVersion("1.25.2.0")] +[assembly: AssemblyVersion("1.26.0.0")] +[assembly: AssemblyFileVersion("1.26.0.0")] -- libgit2 0.21.2