From a5bea7fc59596afe19a80065556d2156e874358f Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Thu, 31 Jan 2013 04:26:37 +0600 Subject: [PATCH] Added the ability to automate any c# scripts for an upgrade process. I realize this is superceded already in 6.0 but we need a way to do this in 4.x too especially for this release since we need to run a script to fix some db issues. I've added a framework using an UpgradeScriptManager and another install step + unit tests for some of the UpgradeScriptManager methods. --- .../Configuration/GlobalSettings.cs | 25 ++++ .../Install/UpgradeScriptsTests.cs | 66 +++++++++ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 8 ++ .../install/steps/UpgradeScripts.ascx.cs | 28 ++++ .../steps/UpgradeScripts.ascx.designer.cs | 24 ++++ .../Install/UpgradeScripts/ContentPathFix.cs | 130 ++++++++++++++++++ .../Install/UpgradeScripts/IUpgradeScript.cs | 7 + .../UpgradeScripts/UpgradeScriptManager.cs | 84 +++++++++++ .../UpgradeScripts/UpgradeScriptRegistrar.cs | 28 ++++ .../Install/UpgradeScripts/VersionRange.cs | 40 ++++++ src/Umbraco.Web/Properties/AssemblyInfo.cs | 1 + src/Umbraco.Web/Umbraco.Web.csproj | 10 +- src/Umbraco.Web/WebBootManager.cs | 2 + .../install/default.aspx.cs | 5 +- .../install/steps/Definitions/Database.cs | 23 ++-- .../steps/Definitions/FilePermissions.cs | 3 +- .../steps/Definitions/UpgradeScripts.cs | 78 +++++++++++ .../install/utills/p.aspx.cs | 7 + .../Installer/DefaultInstallerUtility.cs | 42 +----- .../Utility/Installer/VersionSpecs.cs | 44 ++++++ .../umbraco.datalayer.csproj | 1 + 22 files changed, 601 insertions(+), 56 deletions(-) create mode 100644 src/Umbraco.Tests/Install/UpgradeScriptsTests.cs create mode 100644 src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.cs create mode 100644 src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.designer.cs create mode 100644 src/Umbraco.Web/Install/UpgradeScripts/ContentPathFix.cs create mode 100644 src/Umbraco.Web/Install/UpgradeScripts/IUpgradeScript.cs create mode 100644 src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptManager.cs create mode 100644 src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptRegistrar.cs create mode 100644 src/Umbraco.Web/Install/UpgradeScripts/VersionRange.cs create mode 100644 src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/UpgradeScripts.cs create mode 100644 src/umbraco.datalayer/Utility/Installer/VersionSpecs.cs diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index 3c15ce75cf..8728bb30ff 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -181,6 +181,31 @@ namespace Umbraco.Core.Configuration SaveSetting("umbracoConfigurationStatus", value); } } + + /// + /// Returns the configuration status version as a versoin object or null if it cannot parse + /// + /// + internal static Version GetConfigurationVersion() + { + //create a real version out of the one stored in the settings + var configVersion = ConfigurationStatus.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); + if (configVersion.Length == 0) + return null; + + int major; + var minor = 0; + var patch = 0; + int currentPart; + if (configVersion.Length > 0 && int.TryParse(configVersion[0], out currentPart)) + major = currentPart; + else + return null; //couldn't parse, no valid version + if (configVersion.Length > 1 && int.TryParse(configVersion[1], out currentPart)) minor = currentPart; + if (configVersion.Length > 2 && int.TryParse(configVersion[2], out currentPart)) patch = currentPart; + + return new Version(major, minor, patch); + } /// /// Saves a setting into the configuration file. diff --git a/src/Umbraco.Tests/Install/UpgradeScriptsTests.cs b/src/Umbraco.Tests/Install/UpgradeScriptsTests.cs new file mode 100644 index 0000000000..04a3f81dfb --- /dev/null +++ b/src/Umbraco.Tests/Install/UpgradeScriptsTests.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Umbraco.Web.Install.UpgradeScripts; + +namespace Umbraco.Tests.Install +{ + [TestFixture] + public class UpgradeScriptsTests + { + [TearDown] + public void TearDown() + { + UpgradeScriptManager.Clear(); + } + + [TestCase("0.0.0", "6.0.0", "4.10.0", true)] + [TestCase("4.10.0", "6.0.0", "4.10.0", true)] + [TestCase("4.10.0", "4.11.4", "4.10.0", true)] + [TestCase("4.11.0", "4.11.4", "4.10.0", false)] + [TestCase("4.11.0", "6.0.0", "4.10.0", false)] + [TestCase("6.0.0", "6.0.0", "6.0.0", false)] //this is not in range because it is up to 6.0 but not including 6.0 + [TestCase("6.0.0", "6.0.0", "6.0.1", false)] + public void Test_Version_Range(string startVersion, string endVersion, string current, bool inRange) + { + var currVersionParts = current.Split('.').Select(int.Parse).ToArray(); + var currentVersion = new Version(currVersionParts[0], currVersionParts[1], currVersionParts[2]); + + var startVersionParts = startVersion.Split('.').Select(int.Parse).ToArray(); + var endVersionParts = endVersion.Split('.').Select(int.Parse).ToArray(); + + UpgradeScriptManager.AddUpgradeScript( + new VersionRange( + new Version(startVersionParts[0], startVersionParts[1], startVersionParts[2]), + new Version(endVersionParts[0], endVersionParts[1], endVersionParts[2]))); + + Assert.AreEqual(inRange, UpgradeScriptManager.HasScriptsForVersion(currentVersion)); + } + + [Test] + public void Test_Specific_Version() + { + var currentVersion = new Version(4, 10, 0); + + UpgradeScriptManager.AddUpgradeScript( + new VersionRange( + new Version(4, 10, 0))); + + Assert.IsTrue(UpgradeScriptManager.HasScriptsForVersion(currentVersion)); + Assert.IsFalse(UpgradeScriptManager.HasScriptsForVersion(new Version(4, 10, 11))); + Assert.IsFalse(UpgradeScriptManager.HasScriptsForVersion(new Version(4, 11, 0))); + } + + public class UpgradeScript1 : IUpgradeScript + { + public void Execute() + { + Debug.WriteLine("Executing!"); + } + } + + } +} diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index c7bfb8cba0..0634e58db7 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -63,6 +63,7 @@ + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 09d081e51f..b99a660c02 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -289,6 +289,13 @@ loadStarterKits.ascx + + UpgradeScripts.ascx + ASPXCodeBehind + + + UpgradeScripts.ascx + editMacro.aspx @@ -418,6 +425,7 @@ UI.xml + diff --git a/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.cs b/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.cs new file mode 100644 index 0000000000..0d94b30821 --- /dev/null +++ b/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using Umbraco.Core.Configuration; +using umbraco.presentation.install; +using Umbraco.Web.Install.UpgradeScripts; + +namespace Umbraco.Web.UI.Install.Steps +{ + public partial class UpgradeScripts : System.Web.UI.UserControl + { + protected void Page_Load(object sender, EventArgs e) + { + + } + + protected void RunScripts(object sender, EventArgs e) + { + //run the scripts and then go to the next step + UpgradeScriptManager.ExecuteScriptsForVersion(GlobalSettings.GetConfigurationVersion()); + + Helper.RedirectToNextStep(Page); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.designer.cs b/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.designer.cs new file mode 100644 index 0000000000..a55927fd35 --- /dev/null +++ b/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.designer.cs @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Umbraco.Web.UI.Install.Steps { + + + public partial class UpgradeScripts { + + /// + /// btnNext control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.LinkButton btnNext; + } +} diff --git a/src/Umbraco.Web/Install/UpgradeScripts/ContentPathFix.cs b/src/Umbraco.Web/Install/UpgradeScripts/ContentPathFix.cs new file mode 100644 index 0000000000..f52ae5078d --- /dev/null +++ b/src/Umbraco.Web/Install/UpgradeScripts/ContentPathFix.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Umbraco.Core; +using Umbraco.Core.IO; +using umbraco.cms.businesslogic; +using umbraco.cms.businesslogic.web; + +namespace Umbraco.Web.Install.UpgradeScripts +{ + /// + /// An upgrade script to fix a moving issue in 4.10+ + /// http://issues.umbraco.org/issue/U4-1491 + /// + public class ContentPathFix : IUpgradeScript + { + private readonly StringBuilder _report = new StringBuilder(); + + public void Execute() + { + //return; + if (ApplicationContext.Current == null) return; + if (HasBeenFixed()) return; + Fix(); + WriteReport(); + } + + private void Fix() + { + AddReportLine("Starting fix paths script"); + + //fix content + AddReportLine("Fixing content"); + foreach (var d in Document.GetRootDocuments()) + { + FixPathsForChildren(d, content => ((Document)content).Children); + } + AddReportLine("Fixing content recycle bin"); + var contentRecycleBin = new RecycleBin(RecycleBin.RecycleBinType.Content); + foreach (var d in contentRecycleBin.Children) + { + FixPathsForChildren(new Document(d.Id), content => ((Document)content).Children); + } + + //fix media + AddReportLine("Fixing media"); + foreach (var d in global::umbraco.cms.businesslogic.media.Media.GetRootMedias()) + { + FixPathsForChildren(d, media => ((global::umbraco.cms.businesslogic.media.Media)media).Children); + } + AddReportLine("Fixing media recycle bin"); + var mediaRecycleBin = new RecycleBin(RecycleBin.RecycleBinType.Media); + foreach (var d in mediaRecycleBin.Children) + { + FixPathsForChildren(new global::umbraco.cms.businesslogic.media.Media(d.Id), media => ((global::umbraco.cms.businesslogic.media.Media)media).Children); + } + AddReportLine("Complete!"); + } + + /// + /// Returns true if this script has run based on a temp file written to + /// ~/App_Data/TEMP/FixPaths/report.txt + /// + /// + private bool HasBeenFixed() + { + return File.Exists(IOHelper.MapPath("~/App_Data/TEMP/FixPaths/report.txt")); + } + + /// + /// Creates the report + /// + private void WriteReport() + { + var filePath = IOHelper.MapPath("~/App_Data/TEMP/FixPaths/report.txt"); + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + using (var writer = File.CreateText(IOHelper.MapPath("~/App_Data/TEMP/FixPaths/report.txt"))) + { + writer.Write(_report.ToString()); + } + } + + /// + /// Recursively iterates over the children of the document and fixes the path + /// + /// + /// Callback to get the children of the conent item + /// + /// We cannot use GetDescendants() because that is based on the paths of documents and if they are invalid then + /// we cannot use that method. + /// + private void FixPathsForChildren(Content d, Func> getChildren) + { + AddReportLine("Fixing paths for children of " + d.Id); + foreach (var c in getChildren(d)) + { + FixPath(c); + if (c.HasChildren) + { + FixPathsForChildren(c, getChildren); + } + } + } + + /// + /// Check if the path is correct based on the document's parent if it is not correct, then fix it + /// + /// + private void FixPath(CMSNode d) + { + AddReportLine("Checking path for " + d.Id + ". Current = " + d.Path); + //check if the path is correct + var correctpath = d.Parent.Path + "," + d.Id.ToString(); + if (d.Path != correctpath) + { + AddReportLine(" INVALID PATH DETECTED. Path for " + d.Id + " changed to: " + d.Parent.Path + "," + d.Id.ToString()); + d.Path = correctpath; + d.Level = d.Parent.Level + 1; + } + } + + private void AddReportLine(string str) + { + _report.AppendLine(string.Format("{0} - " + str, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"))); + } + + + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Install/UpgradeScripts/IUpgradeScript.cs b/src/Umbraco.Web/Install/UpgradeScripts/IUpgradeScript.cs new file mode 100644 index 0000000000..339dbd4ac2 --- /dev/null +++ b/src/Umbraco.Web/Install/UpgradeScripts/IUpgradeScript.cs @@ -0,0 +1,7 @@ +namespace Umbraco.Web.Install.UpgradeScripts +{ + internal interface IUpgradeScript + { + void Execute(); + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptManager.cs b/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptManager.cs new file mode 100644 index 0000000000..472415598d --- /dev/null +++ b/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptManager.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Umbraco.Core.Configuration; +using umbraco.DataLayer.Utility.Installer; + +namespace Umbraco.Web.Install.UpgradeScripts +{ + /// + /// Class used to register and execute upgrade scripts during install if they are required. + /// + internal static class UpgradeScriptManager + { + /// + /// Returns true if there are scripts to execute for the version + /// + /// + /// + public static bool HasScriptsForVersion(Version version) + { + return Scripts.Any(x => x.Item2.InRange(version)); + } + + /// + /// Executes all of the scripts for a database version + /// + /// + /// + public static void ExecuteScriptsForVersion(Version version) + { + var types = Scripts.Where(x => x.Item2.InRange(version)).Select(x => x.Item1); + foreach (var instance in types.Select(x => x())) + { + instance.Execute(); + } + } + + public static void AddUpgradeScript(Func script, VersionRange version) + { + Scripts.Add(new Tuple, VersionRange>(script, version)); + } + + ///// + ///// Adds a script to execute for a database version + ///// + ///// + ///// + //public static void AddUpgradeScript(string assemblyQualifiedTypeName, VersionRange version) + //{ + // AddUpgradeScript(new Lazy(() => Type.GetType(assemblyQualifiedTypeName)), version); + //} + + ///// + ///// Adds a script to execute for a database version + ///// + ///// + ///// + //public static void AddUpgradeScript(VersionRange version) + //{ + // AddUpgradeScript(new Lazy(() => typeof(T)), version); + //} + + /// + /// Used for testing + /// + internal static void Clear() + { + Scripts.Clear(); + } + + ///// + ///// Adds a script to execute for a database version + ///// + ///// + ///// + //public static void AddUpgradeScript(Lazy type, VersionRange version) + //{ + // Scripts.Add(new Tuple, VersionRange>(type, version)); + //} + + private static readonly List, VersionRange>> Scripts = new List, VersionRange>>(); + //private static readonly List, VersionRange>> Scripts = new List, VersionRange>>(); + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptRegistrar.cs b/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptRegistrar.cs new file mode 100644 index 0000000000..611703b7d8 --- /dev/null +++ b/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptRegistrar.cs @@ -0,0 +1,28 @@ +using System; +using Umbraco.Core; + +namespace Umbraco.Web.Install.UpgradeScripts +{ + internal class UpgradeScriptRegistrar : IApplicationEventHandler + { + public void OnApplicationInitialized(UmbracoApplication httpApplication, ApplicationContext applicationContext) + { + //Add contnet path fixup for any version from 4.10 up to 4.11.4 + UpgradeScriptManager.AddUpgradeScript( + () => new ContentPathFix(), + new VersionRange( + new Version(4, 10), + new Version(4, 11, 4))); + } + + public void OnApplicationStarting(UmbracoApplication httpApplication, ApplicationContext applicationContext) + { + + } + + public void OnApplicationStarted(UmbracoApplication httpApplication, ApplicationContext applicationContext) + { + + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Install/UpgradeScripts/VersionRange.cs b/src/Umbraco.Web/Install/UpgradeScripts/VersionRange.cs new file mode 100644 index 0000000000..adafd7691a --- /dev/null +++ b/src/Umbraco.Web/Install/UpgradeScripts/VersionRange.cs @@ -0,0 +1,40 @@ +using System; + +namespace Umbraco.Web.Install.UpgradeScripts +{ + internal class VersionRange + { + private readonly Version _specificVersion; + private readonly Version _startVersion; + private readonly Version _endVersion; + + public VersionRange(Version specificVersion) + { + _specificVersion = specificVersion; + } + + public VersionRange(Version startVersion, Version endVersion) + { + _startVersion = startVersion; + _endVersion = endVersion; + } + + /// + /// Checks if the versionCheck is in the range (in between) the start and end version + /// + /// + /// + /// + /// For example if our version range is 4.10 -> 4.11.4, we want to return true if the version being checked is: + /// greater than or equal to the start version but less than the end version. + /// + public bool InRange(Version versionCheck) + { + //if it is a specific version + if (_specificVersion != null) + return versionCheck == _specificVersion; + + return versionCheck >= _startVersion && versionCheck < _endVersion; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Properties/AssemblyInfo.cs b/src/Umbraco.Web/Properties/AssemblyInfo.cs index aa897d6340..03623505f9 100644 --- a/src/Umbraco.Web/Properties/AssemblyInfo.cs +++ b/src/Umbraco.Web/Properties/AssemblyInfo.cs @@ -30,3 +30,4 @@ using System.Security; [assembly: InternalsVisibleTo("Umbraco.Tests")] [assembly: InternalsVisibleTo("umbraco.MacroEngines")] [assembly: InternalsVisibleTo("umbraco.webservices")] +[assembly: InternalsVisibleTo("Umbraco.Web.UI")] diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index c7e6b7336b..5c7a263b12 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -252,6 +252,11 @@ + + + + + @@ -329,6 +334,7 @@ ASPXCodeBehind + ASPXCodeBehind @@ -1894,7 +1900,9 @@ ASPXCodeBehind - + + ASPXCodeBehind + diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index b4aed9339d..915144efcf 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Dictionary; using Umbraco.Core.Dynamics; using Umbraco.Core.PropertyEditors; using Umbraco.Web.Dictionary; +using Umbraco.Web.Install.UpgradeScripts; using Umbraco.Web.Media; using Umbraco.Web.Media.ThumbnailProviders; using Umbraco.Web.Models; @@ -90,6 +91,7 @@ namespace Umbraco.Web //add the internal types since we don't want to mark these public ApplicationEventsResolver.Current.AddType(); ApplicationEventsResolver.Current.AddType(); + ApplicationEventsResolver.Current.AddType(); //now we need to call the initialize methods ApplicationEventsResolver.Current.ApplicationEventHandlers diff --git a/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs b/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs index 1bd81f7df3..16ceb1195f 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs @@ -9,7 +9,7 @@ using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Collections.Specialized; -using umbraco.IO; +using Umbraco.Core.IO; using umbraco.cms.businesslogic.installer; using System.Collections.Generic; @@ -36,7 +36,7 @@ namespace umbraco.presentation.install private void loadContent(InstallerStep currentStep) { PlaceHolderStep.Controls.Clear(); - PlaceHolderStep.Controls.Add(new System.Web.UI.UserControl().LoadControl(IOHelper.ResolveUrl(currentStep.UserControl))); + PlaceHolderStep.Controls.Add(LoadControl(IOHelper.ResolveUrl(currentStep.UserControl))); step.Value = currentStep.Alias; currentStepClass = currentStep.Alias; } @@ -136,6 +136,7 @@ namespace umbraco.presentation.install ics.Add(new install.steps.Definitions.Welcome()); ics.Add(new install.steps.Definitions.License()); ics.Add(new install.steps.Definitions.FilePermissions()); + ics.Add(new install.steps.Definitions.UpgradeScripts()); ics.Add(new install.steps.Definitions.Database()); ics.Add(new install.steps.Definitions.DefaultUser()); ics.Add(new install.steps.Definitions.Skinning()); diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs index 9293d0e84b..9c3cadd748 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs @@ -1,9 +1,9 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Web; +using Umbraco.Core.IO; using umbraco.cms.businesslogic.installer; -using umbraco.IO; + using umbraco.DataLayer.Utility.Installer; using umbraco.DataLayer; @@ -18,7 +18,7 @@ namespace umbraco.presentation.install.steps.Definitions public override string Name { - get { return "Database"; } + get { return "Database"; } } public override string UserControl @@ -26,7 +26,7 @@ namespace umbraco.presentation.install.steps.Definitions get { return SystemDirectories.Install + "/steps/database.ascx"; } } - + public override bool MoveToNextStepAutomaticly { get @@ -38,13 +38,14 @@ namespace umbraco.presentation.install.steps.Definitions //here we determine if the installer should skip this step... public override bool Completed() { - bool retval = false; + bool retval; try { - IInstallerUtility m_Installer = BusinessLogic.Application.SqlHelper.Utility.CreateInstaller(); - retval = m_Installer.IsLatestVersion; - m_Installer = null; - } catch { + var installer = BusinessLogic.Application.SqlHelper.Utility.CreateInstaller(); + retval = installer.IsLatestVersion; + } + catch + { // this step might fail due to missing connectionstring return false; } @@ -52,6 +53,6 @@ namespace umbraco.presentation.install.steps.Definitions return retval; } - + } } \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs index ef3827225f..f0f6887ed3 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Web; +using Umbraco.Core.IO; using umbraco.cms.businesslogic.installer; namespace umbraco.presentation.install.steps.Definitions @@ -20,7 +21,7 @@ namespace umbraco.presentation.install.steps.Definitions public override string UserControl { - get { return IO.SystemDirectories.Install + "/steps/validatepermissions.ascx"; } + get { return SystemDirectories.Install + "/steps/validatepermissions.ascx"; } } public override bool HideFromNavigation { diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/UpgradeScripts.cs b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/UpgradeScripts.cs new file mode 100644 index 0000000000..57d4cf9d9b --- /dev/null +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/UpgradeScripts.cs @@ -0,0 +1,78 @@ +using System; +using Umbraco.Core; +using Umbraco.Core.IO; +using Umbraco.Web.Install.UpgradeScripts; +using umbraco.DataLayer.Utility.Installer; +using umbraco.cms.businesslogic.installer; + +namespace umbraco.presentation.install.steps.Definitions +{ + internal class UpgradeScripts : InstallerStep + { + + + + public override string Alias + { + get { return "upgradeScripts"; } + } + + public override bool HideFromNavigation + { + get { return true; } + } + + /// + /// If there are no scripts for this version the skip + /// + /// + public override bool Completed() + { + var canConnect = CanConnectToDb(); + //if we cannot connect to the db, then we cannot run the script and most likely the database doesn't exist yet anyways. + if (!canConnect) return true; //skip + + //if the version is empty then it's probably a new installation, we cannot run scripts + if (GlobalSettings.CurrentVersion.IsNullOrWhiteSpace()) return true; //skip + var currentUmbVersion = Umbraco.Core.Configuration.GlobalSettings.GetConfigurationVersion(); + if (currentUmbVersion == null) + return true; //skip, could not get a version + + //check if we have upgrade script to run for this version + var hasScripts = UpgradeScriptManager.HasScriptsForVersion(currentUmbVersion); + return !hasScripts; + } + + public override string Name + { + get { return "Upgrade scripts"; } + } + + public override string UserControl + { + get { return SystemDirectories.Install + "/steps/UpgradeScripts.ascx"; } + } + + public override bool MoveToNextStepAutomaticly + { + get + { + return true; + } + } + + private bool CanConnectToDb() + { + try + { + var installer = BusinessLogic.Application.SqlHelper.Utility.CreateInstaller(); + var latest = installer.IsLatestVersion; + return true; //if we got this far, we can connect. + } + catch + { + return false; + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs b/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs index 67fb8c6d78..8576f12366 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; +using Umbraco.Web.Install.UpgradeScripts; using umbraco.DataLayer.Utility.Installer; using umbraco.DataLayer; @@ -97,6 +98,8 @@ namespace umbraco.presentation.install.utills Helper.setProgress(100, "Database is up-to-date", ""); + return "upgraded"; + } else { @@ -136,6 +139,7 @@ namespace umbraco.presentation.install.utills installer = null; library.RefreshContent(); + return "upgraded"; } } @@ -146,5 +150,8 @@ namespace umbraco.presentation.install.utills return "no connection;"; } + + + } } \ No newline at end of file diff --git a/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs b/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs index 16c51bae78..b88f7ac157 100644 --- a/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs +++ b/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs @@ -261,45 +261,5 @@ namespace umbraco.DataLayer.Utility.Installer #endregion } - /// - /// A triple (Field, Table, Version) meaning: - /// if a SELECT statement of Field FROM Table succeeds, - /// the database version is at least Version. - /// - /// - /// This also supports checking for a value in a table. - /// - public struct VersionSpecs - { - /// The SQL statament to execute in order to test for the specified version - public readonly string Sql; - - /// An integer identifying the expected row count from the Sql statement - public readonly int ExpectedRows; - - /// The minimum version number of a database that contains the specified field. - public readonly DatabaseVersion Version; - - /// - /// Initializes a new instance of the struct. - /// - /// The sql statement to execute. - /// The version. - public VersionSpecs(string sql, DatabaseVersion version) - : this(sql, -1, version) - { } - - /// - /// Initializes a new instance of the struct. - /// - /// The sql statement to execute. - /// The expected row count. - /// The version. - public VersionSpecs(string sql, int expectedRows, DatabaseVersion version) - { - Sql = sql; - ExpectedRows = expectedRows; - Version = version; - } - } + } diff --git a/src/umbraco.datalayer/Utility/Installer/VersionSpecs.cs b/src/umbraco.datalayer/Utility/Installer/VersionSpecs.cs new file mode 100644 index 0000000000..c1237e1e97 --- /dev/null +++ b/src/umbraco.datalayer/Utility/Installer/VersionSpecs.cs @@ -0,0 +1,44 @@ +namespace umbraco.DataLayer.Utility.Installer +{ + /// + /// A triple (Field, Table, Version) meaning: + /// if a SELECT statement of Field FROM Table succeeds, + /// the database version is at least Version. + /// + /// + /// This also supports checking for a value in a table. + /// + public struct VersionSpecs + { + /// The SQL statament to execute in order to test for the specified version + public readonly string Sql; + + /// An integer identifying the expected row count from the Sql statement + public readonly int ExpectedRows; + + /// The minimum version number of a database that contains the specified field. + public readonly DatabaseVersion Version; + + /// + /// Initializes a new instance of the struct. + /// + /// The sql statement to execute. + /// The version. + public VersionSpecs(string sql, DatabaseVersion version) + : this(sql, -1, version) + { } + + /// + /// Initializes a new instance of the struct. + /// + /// The sql statement to execute. + /// The expected row count. + /// The version. + public VersionSpecs(string sql, int expectedRows, DatabaseVersion version) + { + Sql = sql; + ExpectedRows = expectedRows; + Version = version; + } + } +} \ No newline at end of file diff --git a/src/umbraco.datalayer/umbraco.datalayer.csproj b/src/umbraco.datalayer/umbraco.datalayer.csproj index 73d169333e..6297b07bc4 100644 --- a/src/umbraco.datalayer/umbraco.datalayer.csproj +++ b/src/umbraco.datalayer/umbraco.datalayer.csproj @@ -117,6 +117,7 @@ +