diff --git a/src/SIM.Pipelines/Backup/Backup9Args.cs b/src/SIM.Pipelines/Backup/Backup9Args.cs new file mode 100644 index 00000000..ccdacd34 --- /dev/null +++ b/src/SIM.Pipelines/Backup/Backup9Args.cs @@ -0,0 +1,77 @@ +namespace SIM.Pipelines.Backup +{ + using SIM.Instances; + using SIM.Pipelines.Processors; + using Sitecore.Diagnostics.Base; + using JetBrains.Annotations; + using SIM.Extensions; + using System.Data.SqlClient; + using System.Collections.Generic; + using System.Linq; + + public class Backup9Args : ProcessorArgs + { + #region Fields + + public bool BackupClient { get; } + + public bool BackupDatabases { get; } + + public bool BackupFiles { get; } + + public string BackupName { get; } + + [NotNull] + public string Folder { get; } + + public Instance Instance { get; } + private string _instanceName { get; } + public string _WebRootPath; + public SqlConnectionStringBuilder ConnectionString { get; } + + public readonly ICollection _SelectedDatabases; + + #endregion + + #region Constructors + + public Backup9Args([NotNull] Instance instance, SqlConnectionStringBuilder connectionString, + string backupName = null, + bool backupFiles = false, bool backupClient = false, + bool backupDatabases = false, IEnumerable selectedDatabases = null) + { + Assert.ArgumentNotNull(instance, nameof(instance)); + Assert.ArgumentNotNull(connectionString, nameof(connectionString)); + + Instance = instance; + _instanceName = Instance.Name; + + _WebRootPath = instance.WebRootPath; + BackupName = backupName; + Folder = BackupName != null + ? FileSystem.FileSystem.Local.Directory.Ensure(instance.GetBackupFolder(BackupName)) + : string.Empty; + + BackupFiles = backupFiles; + BackupClient = backupClient; + + ConnectionString = connectionString; + BackupDatabases = backupDatabases; + _SelectedDatabases = selectedDatabases.With(x => x.Select(y => y.ToLower()).ToArray()); + } + + #endregion + + #region Public properties + + public string InstanceName + { + get + { + return _instanceName; + } + } + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Pipelines/Backup/Backup9Processor.cs b/src/SIM.Pipelines/Backup/Backup9Processor.cs new file mode 100644 index 00000000..7d0e535d --- /dev/null +++ b/src/SIM.Pipelines/Backup/Backup9Processor.cs @@ -0,0 +1,54 @@ +namespace SIM.Pipelines.Backup +{ + using SIM.Pipelines.Processors; + using Sitecore.Diagnostics.Base; + using JetBrains.Annotations; + + public abstract class Backup9Processor : Processor + { + #region Methods + + #region Public methods + + public override sealed long EvaluateStepsCount(ProcessorArgs args) + { + return EvaluateStepsCount((BackupArgs)args); + } + + public override bool IsRequireProcessing(ProcessorArgs args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + return IsRequireProcessing((Backup9Args)args); + } + + #endregion + + #region Protected methods + + protected virtual long EvaluateStepsCount(Backup9Args args) + { + return 1; + } + + protected virtual bool IsRequireProcessing([NotNull] Backup9Args args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + return true; + } + + protected override void Process(ProcessorArgs args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + Process((Backup9Args)args); + } + + protected abstract void Process([NotNull] Backup9Args args); + + #endregion + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Pipelines/Backup/BackupDatabases9.cs b/src/SIM.Pipelines/Backup/BackupDatabases9.cs new file mode 100644 index 00000000..7bf0964c --- /dev/null +++ b/src/SIM.Pipelines/Backup/BackupDatabases9.cs @@ -0,0 +1,75 @@ +namespace SIM.Pipelines.Backup +{ + using System.IO; + using System.Linq; + using SIM.Adapters.SqlServer; + using Sitecore.Diagnostics.Base; + using JetBrains.Annotations; + using Sitecore.Diagnostics.Logging; + using System.Data.SqlClient; + + [UsedImplicitly] + public class BackupDatabases9 : Backup9Processor + { + #region Methods + + #region Protected methods + + protected override long EvaluateStepsCount(Backup9Args args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + return args.Instance.AttachedDatabases.Count(); + } + + protected override bool IsRequireProcessing(Backup9Args args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + return args.BackupDatabases; + } + + protected override void Process([NotNull] Backup9Args args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + var selectedDatabases = args._SelectedDatabases; + var attachedDatabases = args.Instance.AttachedDatabases; + var backupDatabasesFolder = FileSystem.FileSystem.Local.Directory.Ensure(Path.Combine(args.Folder, "Databases")); + + foreach (var database in attachedDatabases.Where(database => selectedDatabases.Contains(database.Name.ToLower()))) + { + Backup(database, backupDatabasesFolder, args.ConnectionString); + IncrementProgress(); + } + } + + #endregion + + #region Private methods + + private void Backup([NotNull] Database database, [NotNull] string folder, [NotNull] SqlConnectionStringBuilder connectionString) + { + Assert.ArgumentNotNull(database, nameof(database)); + Assert.ArgumentNotNull(folder, nameof(folder)); + Assert.ArgumentNotNull(connectionString, nameof(connectionString)); + + using (var connection = SqlServerManager.Instance.OpenConnection(connectionString, true)) + { + var databaseName = database.RealName; + var fileName = Path.Combine(folder, database.BackupFilename); + Log.Info($"Backing up the '{databaseName}' database to the '{fileName}' file"); + + var command = $"BACKUP DATABASE [{databaseName}] TO " + + $"DISK = N\'{fileName}\' WITH NOFORMAT, NOINIT, " + + $"NAME = N\'{databaseName} initial backup\', SKIP, NOREWIND, NOUNLOAD, STATS = 10"; + + SqlServerManager.Instance.Execute(connection, command); + } + } + + #endregion + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Pipelines/Backup/BackupFiles9.cs b/src/SIM.Pipelines/Backup/BackupFiles9.cs new file mode 100644 index 00000000..324c8525 --- /dev/null +++ b/src/SIM.Pipelines/Backup/BackupFiles9.cs @@ -0,0 +1,69 @@ +namespace SIM.Pipelines.Backup +{ + using System.IO; + using Sitecore.Diagnostics.Base; + using JetBrains.Annotations; + + #region + + #endregion + + [UsedImplicitly] + public class BackupFiles9 : Backup9Processor + { + #region Protected methods + + protected override long EvaluateStepsCount(Backup9Args args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + return 2; + } + + protected override bool IsRequireProcessing(Backup9Args args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + return args.BackupFiles; + } + + protected override void Process([NotNull] Backup9Args args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + var instance = args.Instance; + var webRootPath = instance.WebRootPath; + if (args.BackupClient) + { + BackupFolder(args, webRootPath, "WebRoot.zip"); + } + else + { + BackupFolder(args, webRootPath, "WebRootNoClient.zip", "sitecore"); + } + + IncrementProgress(); + BackupFolder(args, instance.DataFolderPath, "Data.zip"); + } + + + #endregion + + #region Private methods + + private void BackupFolder([NotNull] Backup9Args args, [NotNull] string path, [NotNull] string fileName, string ignore = null) + { + Assert.ArgumentNotNull(args, nameof(args)); + Assert.ArgumentNotNull(path, nameof(path)); + Assert.ArgumentNotNull(fileName, nameof(fileName)); + + if (FileSystem.FileSystem.Local.Directory.Exists(path)) + { + var backupfile = Path.Combine(args.Folder, fileName); + FileSystem.FileSystem.Local.Zip.CreateZip(path, backupfile, ignore); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Pipelines/ClearBackups/ClearBackupsArgs.cs b/src/SIM.Pipelines/ClearBackups/ClearBackupsArgs.cs new file mode 100644 index 00000000..72e42d66 --- /dev/null +++ b/src/SIM.Pipelines/ClearBackups/ClearBackupsArgs.cs @@ -0,0 +1,55 @@ +namespace SIM.Pipelines.ClearBackups +{ + #region + + using System; + using System.Collections.Generic; + using System.Data.SqlClient; + using SIM.Adapters.MongoDb; + using SIM.Adapters.SqlServer; + using SIM.Instances; + using SIM.Pipelines.Processors; + using Sitecore.Diagnostics.Base; + using JetBrains.Annotations; + + #endregion + + public class ClearBackupsArgs : ProcessorArgs + { + #region Fields + + public Instance Instance { get; } + public IEnumerable SelectedBackups { get; } + #endregion + + #region Constructors + + public ClearBackupsArgs([NotNull] Instance instance, IEnumerable backups=null) + { + SelectedBackups = backups; + Instance = instance; + } + + + public void Initialize() + { + InstanceID = Instance.ID; + InstanceBackupsFolder = Instance.BackupsFolder; + } + + #endregion + + #region Properties + public string InstanceBackupsFolder { get; set; } + + #endregion + + #region Public properties + + public string InstanceName { get; private set; } + + public long InstanceID { get; private set; } + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Pipelines/ClearBackups/ClearBackupsProcessor.cs b/src/SIM.Pipelines/ClearBackups/ClearBackupsProcessor.cs new file mode 100644 index 00000000..3bd502fd --- /dev/null +++ b/src/SIM.Pipelines/ClearBackups/ClearBackupsProcessor.cs @@ -0,0 +1,64 @@ +namespace SIM.Pipelines.ClearBackups +{ + using SIM.Pipelines.Processors; + using Sitecore.Diagnostics.Base; + using JetBrains.Annotations; + using SIM.Pipelines.ClearBackups; + using SIM.Pipelines.Restore; + + #region + + #endregion + + public abstract class ClearBackupsProcessor : Processor + { + #region Methods + + #region Public methods + + public override sealed long EvaluateStepsCount(ProcessorArgs args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + return EvaluateStepsCount((RestoreArgs)args); + } + + public override bool IsRequireProcessing(ProcessorArgs args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + return IsRequireProcessing((RestoreArgs)args); + } + + #endregion + + #region Protected methods + + protected virtual long EvaluateStepsCount([NotNull] ClearBackupsArgs args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + return 1; + } + + protected virtual bool IsRequireProcessing([NotNull] ClearBackupsArgs args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + return true; + } + + + protected override sealed void Process([NotNull] ProcessorArgs args) + { + Assert.ArgumentNotNull(args, nameof(args)); + + Process((ClearBackupsArgs)args); + } + + protected abstract void Process([NotNull] ClearBackupsArgs args); + #endregion + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Pipelines/ClearBackups/RemoveSelectedBackups.cs b/src/SIM.Pipelines/ClearBackups/RemoveSelectedBackups.cs new file mode 100644 index 00000000..888e85d1 --- /dev/null +++ b/src/SIM.Pipelines/ClearBackups/RemoveSelectedBackups.cs @@ -0,0 +1,25 @@ +namespace SIM.Pipelines.ClearBackups +{ + using Sitecore.Diagnostics.Base; + using JetBrains.Annotations; + + #region + + [UsedImplicitly] + public class RemoveSelectedBackups : ClearBackupsProcessor + { + #region Methods + + protected override void Process([NotNull] ClearBackupsArgs args) + { + Assert.ArgumentNotNull(args, nameof(args)); + foreach (var _folderPath in args.SelectedBackups) + { + FileSystem.FileSystem.Local.Directory.DeleteIfExists(_folderPath); + } + } + + #endregion + } + #endregion +} \ No newline at end of file diff --git a/src/SIM.Pipelines/PipelinesConfig.cs b/src/SIM.Pipelines/PipelinesConfig.cs index 7173ae0c..1149d464 100644 --- a/src/SIM.Pipelines/PipelinesConfig.cs +++ b/src/SIM.Pipelines/PipelinesConfig.cs @@ -237,11 +237,18 @@ public static class PipelinesConfig + + + + + + - + + @@ -249,6 +256,11 @@ public static class PipelinesConfig + + + + + diff --git a/src/SIM.Pipelines/SIM.Pipelines.csproj b/src/SIM.Pipelines/SIM.Pipelines.csproj index 1723277e..6aa5f459 100644 --- a/src/SIM.Pipelines/SIM.Pipelines.csproj +++ b/src/SIM.Pipelines/SIM.Pipelines.csproj @@ -88,12 +88,19 @@ Code + + + + + + + diff --git a/src/SIM.Tool.Windows/Images/32/clear_backups.png b/src/SIM.Tool.Windows/Images/32/clear_backups.png new file mode 100644 index 00000000..f3185d4d Binary files /dev/null and b/src/SIM.Tool.Windows/Images/32/clear_backups.png differ diff --git a/src/SIM.Tool.Windows/Images/48/clear_backups.png b/src/SIM.Tool.Windows/Images/48/clear_backups.png new file mode 100644 index 00000000..24e7f08e Binary files /dev/null and b/src/SIM.Tool.Windows/Images/48/clear_backups.png differ diff --git a/src/SIM.Tool.Windows/MainWindowComponents/Buttons/BackupInstance9AndLaterButton.cs b/src/SIM.Tool.Windows/MainWindowComponents/Buttons/BackupInstance9AndLaterButton.cs new file mode 100644 index 00000000..96ce79c1 --- /dev/null +++ b/src/SIM.Tool.Windows/MainWindowComponents/Buttons/BackupInstance9AndLaterButton.cs @@ -0,0 +1,32 @@ +using System.Windows; +using JetBrains.Annotations; +using SIM.Instances; +using SIM.Pipelines.Backup; +using SIM.Tool.Base; +using SIM.Tool.Base.Profiles; +using SIM.Tool.Base.Wizards; +using SIM.Tool.Windows.UserControls.Backup; +using SIM.Tool.Windows.UserControls.SitecoreAuthentication; + +namespace SIM.Tool.Windows.MainWindowComponents.Buttons +{ + [UsedImplicitly] + public class BackupInstance9AndLaterButton : InstanceOnlyButton + { + #region Public methods + + public override void OnClick(Window mainWindow, Instance instance) + { + if (instance != null) + { + int.TryParse(instance.Product.ShortVersion, out int sitecoreVersion); + + var id = MainWindowHelper.GetListItemID(instance.ID); + WizardPipelineManager.Start("backup9AndLater", mainWindow, new BackupArgs(instance, ProfileManager.GetConnectionString()), + null, ignore => MainWindowHelper.MakeInstanceSelected(id), () => new BackupWizard9Args(instance)); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Tool.Windows/MainWindowComponents/Buttons/ClearBackupsInstance9AndLaterButton.cs b/src/SIM.Tool.Windows/MainWindowComponents/Buttons/ClearBackupsInstance9AndLaterButton.cs new file mode 100644 index 00000000..e58a4107 --- /dev/null +++ b/src/SIM.Tool.Windows/MainWindowComponents/Buttons/ClearBackupsInstance9AndLaterButton.cs @@ -0,0 +1,39 @@ +using System; +using System.Data.SqlClient; +using System.Linq; +using System.Data.SqlClient; +using System.Windows; +using JetBrains.Annotations; +using SIM.Core.Common; +using SIM.Instances; +using SIM.IO.Real; +using SIM.Pipelines.Restore; +using SIM.Tool.Base.Pipelines; +using SIM.Tool.Base.Wizards; +//using SIM.Pipelines.ClearBackups; +using SIM.Tool.Base.Profiles; +using SIM.Pipelines.Backup; +using SIM.Tool.Windows.UserControls.Backup; +using Profile = SIM.Core.Common.Profile; +using SIM.Pipelines.ClearBackups; + +namespace SIM.Tool.Windows.MainWindowComponents.Buttons +{ + public class ClearBackupsInstance9AndLaterButton : InstanceOnlyButton + { + #region Public methods + + public override void OnClick(Window mainWindow, Instance instance) + { + if (instance != null) + { + var args = new ClearBackupsArgs(instance); + var id = MainWindowHelper.GetListItemID(instance.ID); + WizardPipelineManager.Start("clearbackups", mainWindow, args, null, + ignore => MainWindowHelper.MakeInstanceSelected(id), + () => new RemoveBackupsWizardArgs(instance)); + } + } + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Tool.Windows/MainWindowComponents/Buttons/RestoreInstanceButton.cs b/src/SIM.Tool.Windows/MainWindowComponents/Buttons/RestoreInstanceButton.cs index 875d7b45..875760de 100644 --- a/src/SIM.Tool.Windows/MainWindowComponents/Buttons/RestoreInstanceButton.cs +++ b/src/SIM.Tool.Windows/MainWindowComponents/Buttons/RestoreInstanceButton.cs @@ -21,7 +21,9 @@ public override void OnClick(Window mainWindow, Instance instance) { var args = new RestoreArgs(instance, new SqlConnectionStringBuilder(Profile.Read(new RealFileSystem()).ConnectionString)); var id = MainWindowHelper.GetListItemID(instance.ID); - WizardPipelineManager.Start("restore", mainWindow, args, null, ignore => MainWindowHelper.MakeInstanceSelected(id), () => new RestoreWizardArgs(instance)); + WizardPipelineManager.Start("restore", mainWindow, args, null, + ignore => MainWindowHelper.MakeInstanceSelected(id), + () => new RestoreWizardArgs(instance)); } } diff --git a/src/SIM.Tool.Windows/MainWindowData.cs b/src/SIM.Tool.Windows/MainWindowData.cs index 4c28f768..83547ad7 100644 --- a/src/SIM.Tool.Windows/MainWindowData.cs +++ b/src/SIM.Tool.Windows/MainWindowData.cs @@ -239,7 +239,7 @@ private static ButtonDefinition GetHotfixButton() } return new ButtonDefinition - { + { Label = "Create Hotfix", Image = "/Images/$sm/vs.png, SIM.Tool.Windows", Handler = new CreateSupportHotfixButton("%APPDATA%\\Sitecore\\HotfixCreator", $"http://dl.sitecore.net/updater/hc/HotfixCreator.application") @@ -694,7 +694,8 @@ private static ButtonDefinition GetPatchButton() } }, GetManageGroupDefinition(), - new GroupDefinition + + new GroupDefinition { Name = "Backup", Handler = new BackupGroup(), @@ -705,28 +706,28 @@ private static ButtonDefinition GetPatchButton() Label = "Backup", Image = "/Images/$lg/floppy_disks.png, SIM.Tool.Windows", Handler = new BackupInstanceButton(), - Buttons = new[] - { - new ButtonDefinition - { - Label = "Backup", - Image = "/Images/$sm/box_into.png, SIM.Tool.Windows", - Handler = new BackupInstanceButton() - }, - new ButtonDefinition - { - Label = "Export", - Image = "/Images/$lg/download.png, SIM.Tool.Windows", - Handler = new ExportInstanceButton() - }, - } }, + + new ButtonDefinition + { + Label = "Backup", + Image = "/Images/$lg/floppy_disks.png, SIM.Tool.Windows", + Handler = new BackupInstance9AndLaterButton(), + }, + new ButtonDefinition { Label = "Restore", Image = "/Images/$lg/box_out.png, SIM.Tool.Windows", Handler = new RestoreInstanceButton() }, + + new ButtonDefinition + { + Label = "Clear", + Image = "/Images/$lg/clear_backups.png, SIM.Tool.Windows", + Handler = new ClearBackupsInstance9AndLaterButton() + }, } }, } @@ -1128,7 +1129,7 @@ private static GroupDefinition GetManageGroupDefinition() }; } - internal static ButtonDefinition[] MenuItems { get; } = + internal static ButtonDefinition[] MenuItems { get; } = { new ButtonDefinition { Label = "Browse Sitecore Container Website", Image = "/Images/$sm/earth2.png, SIM.Tool.Windows", Handler = new BrowseSitecoreContainerWebsiteButton() }, new ButtonDefinition { Label = "Browse Website", Image = "/Images/$sm/earth2.png, SIM.Tool.Windows", Handler = new BrowseHomePageButton() }, @@ -1142,7 +1143,7 @@ private static GroupDefinition GetManageGroupDefinition() new ButtonDefinition { Label = "Sitecore Admin", Image = "/Images/$lg/toolbox.png, SIM.Tool.Windows", Handler = new OpenToolboxButton("bypass") }, new ButtonDefinition { Handler = new LoginAdminButton() }, new ButtonDefinition { Label = "Copy URL", Image = "/Images/$lg/astrologer.png, SIM.Tool.Windows", Handler = new LoginAdminButton("$(clipboard)") }, - }}, + }}, new ButtonDefinition { Label = "Sitecore Admin", Image = "/Images/$lg/toolbox.png, SIM.Tool.Windows", Handler = new OpenToolboxButton() }, new ButtonDefinition { Label = "Open Folder", Image = "/Images/$sm/folder_open.png, SIM.Tool.Windows", Handler = new SitecoreMemberOpenFolderButton("$(website)") }, new ButtonDefinition { Label = "Open Container Folder", Image = "/Images/$sm/folder_open.png, SIM.Tool.Windows", Handler = new OpenContainerFolderButton() }, @@ -1153,9 +1154,6 @@ private static GroupDefinition GetManageGroupDefinition() new ButtonDefinition { Label = "Open web.config file", Image = "/Images/$sm/document_text.png, SIM.Tool.Windows", Handler = new OpenWebConfigButton() }, new ButtonDefinition { Handler = new PublishButton() }, new ButtonDefinition { Label = "Publish Site", Image = "/Images/$sm/publish.png, SIM.Tool.Windows", Handler = new PublishButton() }, - new ButtonDefinition { Handler = new BackupInstanceButton() }, - new ButtonDefinition { Label = "Backup", Image = "/Images/$sm/box_into.png, SIM.Tool.Windows", Handler = new BackupInstanceButton() }, - new ButtonDefinition { Label = "Restore", Image = "/Images/$sm/box_out.png, SIM.Tool.Windows", Handler = new RestoreInstanceButton() }, new ButtonDefinition { Handler = new ExportInstanceButton() }, new ButtonDefinition { Label = "Export", Image = "/Images/$sm/download.png, SIM.Tool.Windows", Handler = new ExportInstanceButton() }, new ButtonDefinition { Handler = new InstallModulesButton() }, diff --git a/src/SIM.Tool.Windows/SIM.Tool.Windows.csproj b/src/SIM.Tool.Windows/SIM.Tool.Windows.csproj index e95f1659..decd6aba 100644 --- a/src/SIM.Tool.Windows/SIM.Tool.Windows.csproj +++ b/src/SIM.Tool.Windows/SIM.Tool.Windows.csproj @@ -157,8 +157,11 @@ + + + @@ -262,13 +265,30 @@ + + BackupDatabases.xaml + + + BackupFileName.xaml + + + BackupFiles.xaml + BackupSettings.xaml + ChooseBackup.xaml + + RemoveBackups.xaml + + + + RestoreBackup.xaml + ConfirmStepUserControl.xaml @@ -659,6 +679,8 @@ + + SettingsSingleFileGenerator Settings.Designer.cs @@ -697,6 +719,34 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Designer + XamlIntelliSenseFileGenerator + + + Designer + XamlIntelliSenseFileGenerator + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + MSBuild:Compile Designer @@ -833,14 +883,6 @@ MSBuild:Compile Designer - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - MSBuild:Compile Designer diff --git a/src/SIM.Tool.Windows/UserControls/Backup/BackupDatabases.xaml b/src/SIM.Tool.Windows/UserControls/Backup/BackupDatabases.xaml new file mode 100644 index 00000000..1d555ddd --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/BackupDatabases.xaml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + Select all + None + + + \ No newline at end of file diff --git a/src/SIM.Tool.Windows/UserControls/Backup/BackupDatabases.xaml.cs b/src/SIM.Tool.Windows/UserControls/Backup/BackupDatabases.xaml.cs new file mode 100644 index 00000000..f5589e5c --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/BackupDatabases.xaml.cs @@ -0,0 +1,119 @@ +namespace SIM.Tool.Windows.UserControls.Backup +{ + using System.Collections.Generic; + using System.ComponentModel; + using System.Linq; + using System.Windows; + using SIM.Tool.Base.Wizards; + + public partial class BackupDatabases : IWizardStep + { + #region Constructors + + public BackupDatabases() + { + InitializeComponent(); + } + + #endregion + + #region Private methods + + void IWizardStep.InitializeStep(WizardArgs wizardArgs) + { + var attachedDatabases = ((BackupWizard9Args)wizardArgs).Instance.AttachedDatabases.ToArray(); + Databases.DataContext = attachedDatabases.Select(database => new BackupDatabase(database.Name, true)).ToList(); + } + + private void NoneHyperlinkClick(object sender, RoutedEventArgs e) + { + foreach (BackupDatabase item in Databases.Items) + { + item.IsChecked = false; + } + } + + bool IWizardStep.SaveChanges(WizardArgs wizardArgs) + { + var args = (BackupWizard9Args)wizardArgs; + args.SelectedDatabases = ((List)Databases.DataContext).Where(database => database.IsChecked).Select(database => database.DatabaseName); + + if (args.SelectedDatabases.Count() > 0) args._BackupDatabase = true; + else args._BackupDatabase = false; + + return true; + } + + private void SelectAllHyperlinkClick(object sender, RoutedEventArgs e) + { + foreach (BackupDatabase item in Databases.Items) + { + item.IsChecked = true; + } + } + + #endregion + + #region Nested type: BackupDatabase + + private sealed class BackupDatabase : INotifyPropertyChanged + { + #region Delegates + + public event PropertyChangedEventHandler PropertyChanged; + + #endregion + + #region Fields + + private bool _IsChecked; + + #endregion + + #region Constructors + + public BackupDatabase(string databaseName, bool isChecked) + { + DatabaseName = databaseName; + IsChecked = isChecked; + } + + #endregion + + #region Public properties + + public string DatabaseName { get; private set; } + + public bool IsChecked + { + get + { + return _IsChecked; + } + + set + { + _IsChecked = value; + IsCheckedPropertyChaged("IsChecked"); + } + } + + #endregion + + #region Private methods + + private void IsCheckedPropertyChaged(string propertyName) + { + var handler = PropertyChanged; + if (handler != null) + { + handler(this, new PropertyChangedEventArgs(propertyName)); + } + } + + #endregion + } + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Tool.Windows/UserControls/Backup/BackupFileName.xaml b/src/SIM.Tool.Windows/UserControls/Backup/BackupFileName.xaml new file mode 100644 index 00000000..fc8af8b7 --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/BackupFileName.xaml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/src/SIM.Tool.Windows/UserControls/Backup/BackupFileName.xaml.cs b/src/SIM.Tool.Windows/UserControls/Backup/BackupFileName.xaml.cs new file mode 100644 index 00000000..359f3375 --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/BackupFileName.xaml.cs @@ -0,0 +1,87 @@ +namespace SIM.Tool.Windows.UserControls.Backup +{ + using System; + using System.IO; + using System.Windows; + using SIM.Tool.Base; + using SIM.Tool.Base.Wizards; + using JetBrains.Annotations; + using System.Text.RegularExpressions; + using System.Windows.Input; + + public partial class BackupFileName : IWizardStep + { + + #region Fields + + private string _BackupName; + + #endregion + + #region Constructors + + public BackupFileName() + { + InitializeComponent(); + BackupName.Text = string.Format("{0:yyyy-MM-dd} at {0:hh-mm-ss}", DateTime.Now); + } + + public void InitializeStep(WizardArgs wizardArgs) + { + _BackupName = BackupName.Text; + } + + #endregion + + #region Public methods + + public bool OnMovingBack(WizardArgs wizardArgs) + { + return true; + } + + public bool OnMovingNext(WizardArgs wizardArgs) + { + var args = (BackupWizard9Args)wizardArgs; + + if (string.IsNullOrEmpty(args.BackupName)) + { + MessageBox.Show("You haven't chosen name of backup"); + return false; + } + + MessageBox.Show(args.BackupName); + return true; + } + + #endregion + + #region Private methods + + private void OnChanged(object sender, RoutedEventArgs e) + { + var name = ((System.Windows.Controls.TextBox)e.Source).Text; + + _BackupName = name; + } + + bool IWizardStep.SaveChanges(WizardArgs wizardArgs) + { + _BackupName = BackupName.Text; + + Regex regex = new Regex("^[a-zA-Z0-9 _.-]*$"); + if (!regex.IsMatch(_BackupName)) + { + MessageBox.Show("Invalid backup name"); + return false; + } + + var args = (BackupWizard9Args)wizardArgs; + args.BackupName = _BackupName; + + return true; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Tool.Windows/UserControls/Backup/BackupFiles.xaml b/src/SIM.Tool.Windows/UserControls/Backup/BackupFiles.xaml new file mode 100644 index 00000000..5552e84b --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/BackupFiles.xaml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/src/SIM.Tool.Windows/UserControls/Backup/BackupFiles.xaml.cs b/src/SIM.Tool.Windows/UserControls/Backup/BackupFiles.xaml.cs new file mode 100644 index 00000000..0b665c8a --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/BackupFiles.xaml.cs @@ -0,0 +1,116 @@ +namespace SIM.Tool.Windows.UserControls.Backup +{ + using System; + using System.IO; + using System.Windows; + using SIM.Tool.Base; + using SIM.Tool.Base.Wizards; + using JetBrains.Annotations; + + public partial class BackupFiles : IWizardStep + { + + #region Fields + + private bool _ExcludeClient; + private bool _Files; + + #endregion + + + #region Constructors + + public BackupFiles() + { + InitializeComponent(); + } + + public void InitializeStep(WizardArgs wizardArgs) + { + Files.IsChecked = false; + ExcludeClient.IsChecked = false; + _Files = false; + } + + #endregion + + #region Public methods + + public bool OnMovingBack(WizardArgs wizardArgs) + { + return true; + } + + public bool OnMovingNext(WizardArgs wizardArgs) + { + var args = (BackupWizard9Args)wizardArgs; + + if ((args._BackupDatabase) || (args._Files)) + { + return true; + } + + MessageBox.Show("You haven't chosen any backup option"); + return false; + } + + #endregion + + + #region Private methods + + private void OnChanged(object sender, RoutedEventArgs e) + { + var name = ((System.Windows.Controls.CheckBox)e.Source).Name; + + switch (name) + { + case "Files": + _Files = true; + break; + + case "ExcludeClient": + _ExcludeClient = true; + _Files = true; + Files.IsChecked = true; + break; + } + } + + private void OnUnchanged(object sender, RoutedEventArgs e) + { + var name = ((System.Windows.Controls.CheckBox)e.Source).Name; + + switch (name) + { + case "Files": + _Files = false; + _ExcludeClient = false; + ExcludeClient.IsChecked = false; + break; + + case "ExcludeClient": + _ExcludeClient = false; + break; + } + } + + bool IWizardStep.SaveChanges(WizardArgs wizardArgs) + { + var args = (BackupWizard9Args)wizardArgs; + + args._Files = _Files; + args._BackupClient = !_ExcludeClient; + + if (args._BackupDatabase || args._Files) + { + return true; + } + + MessageBox.Show("You haven't chosen any backup option"); + return false; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Tool.Windows/UserControls/Backup/BackupSettings.xaml b/src/SIM.Tool.Windows/UserControls/Backup/BackupSettings.xaml index aa05a28c..43ab1684 100644 --- a/src/SIM.Tool.Windows/UserControls/Backup/BackupSettings.xaml +++ b/src/SIM.Tool.Windows/UserControls/Backup/BackupSettings.xaml @@ -10,10 +10,11 @@ - - + - + + + diff --git a/src/SIM.Tool.Windows/UserControls/Backup/BackupSettings.xaml.cs b/src/SIM.Tool.Windows/UserControls/Backup/BackupSettings.xaml.cs index dd16b5d8..1535777b 100644 --- a/src/SIM.Tool.Windows/UserControls/Backup/BackupSettings.xaml.cs +++ b/src/SIM.Tool.Windows/UserControls/Backup/BackupSettings.xaml.cs @@ -1,6 +1,7 @@ namespace SIM.Tool.Windows.UserControls.Backup { using System.Windows; + using SIM.Instances; using SIM.Tool.Base.Wizards; public partial class BackupSettings : IWizardStep, IFlowControl @@ -50,6 +51,10 @@ public bool OnMovingNext(WizardArgs wizardArgs) void IWizardStep.InitializeStep(WizardArgs wizardArgs) { BackupName.Text = ((BackupSettingsWizardArgs)wizardArgs).BackupName; + if (((BackupSettingsWizardArgs)wizardArgs).Instance.Type == Instance.InstanceType.Sitecore8AndEarlier) + { + MongoDatabases.Visibility = Visibility.Visible; + } } private void OnChanged(object sender, RoutedEventArgs e) diff --git a/src/SIM.Tool.Windows/UserControls/Backup/BackupWizard9Args.cs b/src/SIM.Tool.Windows/UserControls/Backup/BackupWizard9Args.cs new file mode 100644 index 00000000..7c661d7d --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/BackupWizard9Args.cs @@ -0,0 +1,66 @@ +namespace SIM.Tool.Windows.UserControls.Backup +{ + using System; + using System.Collections.Generic; + using System.Linq; + using SIM.FileSystem; + using SIM.Instances; + using SIM.Pipelines.Backup; + using SIM.Pipelines.Processors; + using SIM.Tool.Base.Profiles; + using SIM.Tool.Base.Wizards; + + public class BackupWizard9Args : WizardArgs + { + #region Fields + + public Instance Instance { get; } + private string _instanceName { get; } + public bool _BackupDatabase; + public bool _BackupClient; + public bool _Files; + private string _BackupName; + + public bool _WipeSqlServerCredentials; + + #endregion + + #region Constructors + + public BackupWizard9Args(Instance instance) + { + Instance = instance; + _instanceName = instance.Name; + } + + #endregion + + #region Public properties + + public string BackupName { get; set; } + + public string InstanceName + { + get + { + return _instanceName; + } + } + public IEnumerable SelectedDatabases { get; set; } + + #endregion + + #region Public methods + + public override ProcessorArgs ToProcessorArgs() + { + var backupArgs = new Backup9Args(Instance, ProfileManager.GetConnectionString(), + PathUtils.EscapePath(BackupName.Trim(), "."), _Files, _BackupClient, + _BackupDatabase, SelectedDatabases); + + return backupArgs; + } + + #endregion + } +} diff --git a/src/SIM.Tool.Windows/UserControls/Backup/RemoveBackups.xaml b/src/SIM.Tool.Windows/UserControls/Backup/RemoveBackups.xaml new file mode 100644 index 00000000..61d5b426 --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/RemoveBackups.xaml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + Select all + None + + + \ No newline at end of file diff --git a/src/SIM.Tool.Windows/UserControls/Backup/RemoveBackups.xaml.cs b/src/SIM.Tool.Windows/UserControls/Backup/RemoveBackups.xaml.cs new file mode 100644 index 00000000..ce2f7514 --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/RemoveBackups.xaml.cs @@ -0,0 +1,130 @@ +namespace SIM.Tool.Windows.UserControls.Backup +{ + using System.Collections.Generic; + using SIM.Adapters.SqlServer; + using System.Windows; + using SIM.Instances; + using SIM.Tool.Base.Pipelines; + using SIM.Tool.Base.Wizards; + using System.ComponentModel; + using System.Linq; + using Sitecore.Diagnostics.Base; + + #region + + public partial class RemoveBackups : IWizardStep + { + #region Constructors + + public RemoveBackups() + { + InitializeComponent(); + } + + #endregion + + #region IWizardStep Members + + void IWizardStep.InitializeStep(WizardArgs wizardArgs) + { + var attachedBackupes = ((RemoveBackupsWizardArgs)wizardArgs).Instance.Backups.ToArray(); + Backups.DataContext = attachedBackupes.Select(backup => new BackupFolder(backup.FolderPath, false)).ToList(); + } + + private void SelectAllHyperlinkClick(object sender, RoutedEventArgs e) + { + foreach (BackupFolder item in Backups.Items) + { + item.IsChecked = true; + } + } + + private void NoneHyperlinkClick(object sender, RoutedEventArgs e) + { + foreach (BackupFolder item in Backups.Items) + { + item.IsChecked = false; + } + } + + bool IWizardStep.SaveChanges(WizardArgs wizardArgs) + { + var args = (RemoveBackupsWizardArgs)wizardArgs; + var _backups = ((List)Backups.DataContext).Where(backup => backup.IsChecked).Select(backup => backup.FolderPath); + + if (!_backups.Any()) + { + MessageBox.Show("Any backup wasn\'t chosen"); + return false; + } + + args.Backups = _backups; + return true; + } + + #endregion + + #region Nested type: BackupFolder + + private sealed class BackupFolder : INotifyPropertyChanged + { + #region Delegates + + public event PropertyChangedEventHandler PropertyChanged; + + #endregion + + #region Fields + + private bool _IsChecked; + + #endregion + + #region Constructors + + public BackupFolder(string folder, bool isChecked) + { + FolderPath = folder; + IsChecked = isChecked; + } + + #endregion + + #region Public properties + + public string FolderPath { get; private set; } + + public bool IsChecked + { + get + { + return _IsChecked; + } + + set + { + _IsChecked = value; + IsCheckedPropertyChaged("IsChecked"); + } + } + + #endregion + + #region Private methods + + private void IsCheckedPropertyChaged(string propertyName) + { + var handler = PropertyChanged; + if (handler != null) + { + handler(this, new PropertyChangedEventArgs(propertyName)); + } + } + + #endregion + } + + #endregion + } + #endregion +} \ No newline at end of file diff --git a/src/SIM.Tool.Windows/UserControls/Backup/RemoveBackupsWizardArgs.cs b/src/SIM.Tool.Windows/UserControls/Backup/RemoveBackupsWizardArgs.cs new file mode 100644 index 00000000..c24a8b4c --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/RemoveBackupsWizardArgs.cs @@ -0,0 +1,61 @@ +namespace SIM.Tool.Windows.UserControls.Backup +{ + using SIM.Core.Common; + using SIM.FileSystem; + using SIM.Instances; + using SIM.IO.Real; + using SIM.Pipelines.Backup; + using SIM.Pipelines.ClearBackups; + using SIM.Pipelines.Processors; + using SIM.Pipelines.Restore; + using SIM.Tool.Base.Profiles; + using SIM.Tool.Base.Wizards; + using Sitecore.Diagnostics.Base; + using System.Collections.Generic; + using System.Data.SqlClient; + using Profile = Core.Common.Profile; + + public class RemoveBackupsWizardArgs : WizardArgs + { + #region Fields + + public Instance Instance { get; } + private string instanceName { get; } + + #endregion + + #region Constructors + + public RemoveBackupsWizardArgs(Instance instance) + { + Instance = instance; + instanceName = instance.Name; + } + + #endregion + + #region Public properties + + public IEnumerable Backups { get; set; } + + public string InstanceName + { + get + { + return instanceName; + } + } + + #endregion + + #region Public methods + + public override ProcessorArgs ToProcessorArgs() + { + Assert.IsNotNull(Backups, "Any backup wasn\'t chosen"); + return new ClearBackupsArgs(Instance, Backups); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Tool.Windows/UserControls/Backup/RestoreBackup.xaml b/src/SIM.Tool.Windows/UserControls/Backup/RestoreBackup.xaml new file mode 100644 index 00000000..3105a2fd --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/RestoreBackup.xaml @@ -0,0 +1,11 @@ + + + + + + diff --git a/src/SIM.Tool.Windows/UserControls/Backup/RestoreBackup.xaml.cs b/src/SIM.Tool.Windows/UserControls/Backup/RestoreBackup.xaml.cs new file mode 100644 index 00000000..5557b241 --- /dev/null +++ b/src/SIM.Tool.Windows/UserControls/Backup/RestoreBackup.xaml.cs @@ -0,0 +1,51 @@ +namespace SIM.Tool.Windows.UserControls.Backup +{ + using System.Collections.Generic; + using SIM.Instances; + using SIM.Tool.Base.Pipelines; + using SIM.Tool.Base.Wizards; + + #region + + #endregion + + public partial class RestoreBackup : IWizardStep + { + #region Fields + + private readonly List _CheckBoxItems = new List(); + + #endregion + + #region Constructors + + public RestoreBackup() + { + InitializeComponent(); + } + + #endregion + + #region IWizardStep Members + + void IWizardStep.InitializeStep(WizardArgs wizardArgs) + { + var args = (RestoreWizardArgs)wizardArgs; + _CheckBoxItems.Clear(); + + _CheckBoxItems.AddRange(args.Instance.Backups); + + backups.DataContext = _CheckBoxItems; + } + + bool IWizardStep.SaveChanges(WizardArgs wizardArgs) + { + var args = (RestoreWizardArgs)wizardArgs; + args.Backup = backups.SelectedItem as InstanceBackup; + + return true; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/SIM.Tool.Windows/WizardPipelinesConfig.cs b/src/SIM.Tool.Windows/WizardPipelinesConfig.cs index e5248a4e..09f92174 100644 --- a/src/SIM.Tool.Windows/WizardPipelinesConfig.cs +++ b/src/SIM.Tool.Windows/WizardPipelinesConfig.cs @@ -223,12 +223,57 @@ Note that due to the large size of each installation package the whole download type=""SIM.Tool.Windows.UserControls.Backup.BackupSettings, SIM.Tool.Windows"" /> + + + + + + + + + + + + + - + + + + + + + + + + + + + diff --git a/src/SIM.Tool/ButtonsConfiguration/ButtonsConfiguration.json b/src/SIM.Tool/ButtonsConfiguration/ButtonsConfiguration.json index 3423402f..1266e76c 100644 --- a/src/SIM.Tool/ButtonsConfiguration/ButtonsConfiguration.json +++ b/src/SIM.Tool/ButtonsConfiguration/ButtonsConfiguration.json @@ -95,6 +95,12 @@ "ManagedArgsTracerButton" ], "Sitecore9AndLaterButtons": [ + /*Backup*/ + "BackupInstance9AndLaterButton", + /*Restore*/ + "RestoreInstanceButton", + "ClearBackupsInstance9AndLaterButton", + "InstallModulesForSitecore9AndLaterButton", "RefreshButton", "InstallInstanceButton", @@ -134,6 +140,9 @@ ], "Sitecore9AndLaterMemberButtons": [ "RefreshButton", + "BackupInstanceButton", + "BackupInstance9AndLaterButton", + "InstallInstanceButton", "Install9InstanceButton", "ImportInstanceButton", @@ -179,7 +188,8 @@ "PageGroup", "FileSystemGroup", "AppsGroup", - "ManageGroup" + "ManageGroup", + "BackupGroup" ], "Sitecore9AndLaterMemberGroups": [ "FileSystemGroup",