diff --git a/.github/ISSUE_TEMPLATE/1_Bug.md b/.github/ISSUE_TEMPLATE/1_Bug.md
index a1e33e3854..619452f700 100644
--- a/.github/ISSUE_TEMPLATE/1_Bug.md
+++ b/.github/ISSUE_TEMPLATE/1_Bug.md
@@ -12,7 +12,7 @@ thoroughly. Then, proceed by filling out the rest of the details in the issue
template below. The more details you can give us, the easier it will be for us
to determine the cause of a problem.
-See: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/.github/CONTRIBUTING.md
+See: https://github.com/umbraco/Umbraco-CMS/blob/v8/dev/.github/CONTRIBUTING.md
-->
diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec
index f3f8f47b57..fce15eb487 100644
--- a/build/NuSpecs/UmbracoCms.Core.nuspec
+++ b/build/NuSpecs/UmbracoCms.Core.nuspec
@@ -14,6 +14,7 @@
Contains the core assemblies needed to run Umbraco Cms
en-US
umbraco
+
@@ -44,7 +45,7 @@
-
+
@@ -52,9 +53,9 @@
-
+
-
+
diff --git a/build/NuSpecs/UmbracoCms.Web.nuspec b/build/NuSpecs/UmbracoCms.Web.nuspec
index 3c8fed78f5..4aa354eba2 100644
--- a/build/NuSpecs/UmbracoCms.Web.nuspec
+++ b/build/NuSpecs/UmbracoCms.Web.nuspec
@@ -14,6 +14,7 @@
Contains the core assemblies needed to run Umbraco Cms
en-US
umbraco
+
@@ -43,7 +44,7 @@
-
+
@@ -53,12 +54,12 @@
-
-
-
+
+
+
-
-
+
+
diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec
index 5cdacca419..b7bfaaff5b 100644
--- a/build/NuSpecs/UmbracoCms.nuspec
+++ b/build/NuSpecs/UmbracoCms.nuspec
@@ -14,6 +14,7 @@
Installs Umbraco Cms in your Visual Studio ASP.NET project
en-US
umbraco
+
@@ -25,7 +26,7 @@
not want this to happen as the alpha of the next major is, really, the next major already.
-->
-
+
diff --git a/build/NuSpecs/tools/Views.Web.config.install.xdt b/build/NuSpecs/tools/Views.Web.config.install.xdt
index 4d660301a8..828bb8612f 100644
--- a/build/NuSpecs/tools/Views.Web.config.install.xdt
+++ b/build/NuSpecs/tools/Views.Web.config.install.xdt
@@ -8,7 +8,7 @@
-
+
@@ -18,13 +18,13 @@
-
+
diff --git a/build/NuSpecs/tools/install.ps1 b/build/NuSpecs/tools/install.ps1
index 1411cb5c97..0be28f9467 100644
--- a/build/NuSpecs/tools/install.ps1
+++ b/build/NuSpecs/tools/install.ps1
@@ -18,9 +18,20 @@ if ($project) {
# Copy umbraco and umbraco_files from package to project folder
$umbracoFolder = Join-Path $projectPath "Umbraco"
- New-Item -ItemType Directory -Force -Path $umbracoFolder
+ New-Item -ItemType Directory -Force -Path $umbracoFolder
$umbracoFolderSource = Join-Path $installPath "UmbracoFiles\Umbraco"
- robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log
+
+ Write-Host "copying files to $umbracoFolder ..."
+ # see https://support.microsoft.com/en-us/help/954404/return-codes-that-are-used-by-the-robocopy-utility-in-windows-server-2
+ robocopy $umbracoFolderSource $umbracoFolder /is /it /e
+ if (($lastexitcode -eq 1) -or ($lastexitcode -eq 3) -or ($lastexitcode -eq 5) -or ($lastexitcode -eq 7))
+ {
+ write-host "Copy succeeded!"
+ }
+ else
+ {
+ write-host "Copy failed with exit code:" $lastexitcode
+ }
$copyWebconfig = $true
$destinationWebConfig = Join-Path $projectPath "Web.config"
@@ -40,7 +51,11 @@ if ($project) {
}
}
}
- Catch { }
+ Catch
+ {
+ Write-Host "An error occurred:"
+ Write-Host $_
+ }
}
if($copyWebconfig -eq $true)
@@ -74,7 +89,9 @@ if ($project) {
}
Catch
{
- # Not a big problem if this fails, let it go
+ # Not a big problem if this fails, let it go
+ # Write-Host "An error occurred:"
+ # Write-Host $_
}
}
diff --git a/build/build.ps1 b/build/build.ps1
index 55b686c98e..e4994d2c4a 100644
--- a/build/build.ps1
+++ b/build/build.ps1
@@ -15,7 +15,7 @@
[Parameter(Mandatory=$false)]
[Alias("doc")]
[switch] $docfx = $false,
-
+
# keep the build directories, don't clear them
[Parameter(Mandatory=$false)]
[Alias("c")]
@@ -392,13 +392,13 @@
&$this.BuildEnv.NuGet Pack "$nuspecs\UmbracoCms.Core.nuspec" `
-Properties BuildTmp="$($this.BuildTemp)" `
-Version "$($this.Version.Semver.ToString())" `
- -Symbols -SymbolPackageFormat snupkg -Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmscore.log"
+ -Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmscore.log"
if (-not $?) { throw "Failed to pack NuGet UmbracoCms.Core." }
&$this.BuildEnv.NuGet Pack "$nuspecs\UmbracoCms.Web.nuspec" `
-Properties BuildTmp="$($this.BuildTemp)" `
-Version "$($this.Version.Semver.ToString())" `
- -Symbols -SymbolPackageFormat snupkg -Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmsweb.log"
+ -Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmsweb.log"
if (-not $?) { throw "Failed to pack NuGet UmbracoCms.Web." }
&$this.BuildEnv.NuGet Pack "$nuspecs\UmbracoCms.nuspec" `
@@ -429,37 +429,37 @@
Write-Host "Prepare Azure Gallery"
$this.CopyFile("$($this.SolutionRoot)\build\Azure\azuregalleryrelease.ps1", $this.BuildOutput)
})
-
+
$ubuild.DefineMethod("PrepareCSharpDocs",
{
Write-Host "Prepare C# Documentation"
-
+
$src = "$($this.SolutionRoot)\src"
$tmp = $this.BuildTemp
$out = $this.BuildOutput
$DocFxJson = Join-Path -Path $src "\ApiDocs\docfx.json"
$DocFxSiteOutput = Join-Path -Path $tmp "\_site\*.*"
-
+
#restore nuget packages
$this.RestoreNuGet()
# run DocFx
$DocFx = $this.BuildEnv.DocFx
-
+
& $DocFx metadata $DocFxJson
& $DocFx build $DocFxJson
# zip it
& $this.BuildEnv.Zip a -tzip -r "$out\csharp-docs.zip" $DocFxSiteOutput
})
-
+
$ubuild.DefineMethod("PrepareAngularDocs",
{
Write-Host "Prepare Angular Documentation"
-
+
$src = "$($this.SolutionRoot)\src"
$out = $this.BuildOutput
-
+
$this.CompileBelle()
"Moving to Umbraco.Web.UI.Client folder"
diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs
index 9ed398d52f..a4e859988e 100644
--- a/src/SolutionInfo.cs
+++ b/src/SolutionInfo.cs
@@ -18,5 +18,5 @@ using System.Resources;
[assembly: AssemblyVersion("8.0.0")]
// these are FYI and changed automatically
-[assembly: AssemblyFileVersion("8.1.0")]
-[assembly: AssemblyInformationalVersion("8.1.0")]
+[assembly: AssemblyFileVersion("8.2.0")]
+[assembly: AssemblyInformationalVersion("8.2.0")]
diff --git a/src/Umbraco.Core/AsyncLock.cs b/src/Umbraco.Core/AsyncLock.cs
index 158b132f26..6dd866705e 100644
--- a/src/Umbraco.Core/AsyncLock.cs
+++ b/src/Umbraco.Core/AsyncLock.cs
@@ -67,31 +67,34 @@ namespace Umbraco.Core
: new NamedSemaphoreReleaser(_semaphore2);
}
- public Task LockAsync()
- {
- var wait = _semaphore != null
- ? _semaphore.WaitAsync()
- : _semaphore2.WaitOneAsync();
+ //NOTE: We don't use the "Async" part of this lock at all
+ //TODO: Remove this and rename this class something like SystemWideLock, then we can re-instate this logic if we ever need an Async lock again
- return wait.IsCompleted
- ? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
- : wait.ContinueWith((_, state) => (((AsyncLock) state).CreateReleaser()),
- this, CancellationToken.None,
- TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
- }
+ //public Task LockAsync()
+ //{
+ // var wait = _semaphore != null
+ // ? _semaphore.WaitAsync()
+ // : _semaphore2.WaitOneAsync();
- public Task LockAsync(int millisecondsTimeout)
- {
- var wait = _semaphore != null
- ? _semaphore.WaitAsync(millisecondsTimeout)
- : _semaphore2.WaitOneAsync(millisecondsTimeout);
+ // return wait.IsCompleted
+ // ? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
+ // : wait.ContinueWith((_, state) => (((AsyncLock) state).CreateReleaser()),
+ // this, CancellationToken.None,
+ // TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
+ //}
- return wait.IsCompleted
- ? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
- : wait.ContinueWith((_, state) => (((AsyncLock)state).CreateReleaser()),
- this, CancellationToken.None,
- TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
- }
+ //public Task LockAsync(int millisecondsTimeout)
+ //{
+ // var wait = _semaphore != null
+ // ? _semaphore.WaitAsync(millisecondsTimeout)
+ // : _semaphore2.WaitOneAsync(millisecondsTimeout);
+
+ // return wait.IsCompleted
+ // ? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
+ // : wait.ContinueWith((_, state) => (((AsyncLock)state).CreateReleaser()),
+ // this, CancellationToken.None,
+ // TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
+ //}
public IDisposable Lock()
{
diff --git a/src/Umbraco.Core/Compose/AuditEventsComponent.cs b/src/Umbraco.Core/Compose/AuditEventsComponent.cs
index 15fdfeacff..453fd6314a 100644
--- a/src/Umbraco.Core/Compose/AuditEventsComponent.cs
+++ b/src/Umbraco.Core/Compose/AuditEventsComponent.cs
@@ -44,21 +44,22 @@ namespace Umbraco.Core.Compose
public void Terminate()
{ }
+ internal static IUser UnknownUser => new User { Id = Constants.Security.UnknownUserId, Name = Constants.Security.UnknownUserName, Email = "" };
+
private IUser CurrentPerformingUser
{
get
{
var identity = Thread.CurrentPrincipal?.GetUmbracoIdentity();
- return identity == null
- ? new User { Id = 0, Name = "SYSTEM", Email = "" }
- : _userService.GetUserById(Convert.ToInt32(identity.Id));
+ var user = identity == null ? null : _userService.GetUserById(Convert.ToInt32(identity.Id));
+ return user ?? UnknownUser;
}
}
private IUser GetPerformingUser(int userId)
{
var found = userId >= 0 ? _userService.GetUserById(userId) : null;
- return found ?? new User {Id = 0, Name = "SYSTEM", Email = ""};
+ return found ?? UnknownUser;
}
private string PerformingIp
diff --git a/src/Umbraco.Core/Composing/TypeLoader.cs b/src/Umbraco.Core/Composing/TypeLoader.cs
index af9277fce9..fe7a561eca 100644
--- a/src/Umbraco.Core/Composing/TypeLoader.cs
+++ b/src/Umbraco.Core/Composing/TypeLoader.cs
@@ -42,8 +42,8 @@ namespace Umbraco.Core.Composing
private string _currentAssembliesHash;
private IEnumerable _assemblies;
private bool _reportedChange;
- private static string _localTempPath;
- private static string _fileBasePath;
+ private readonly string _localTempPath;
+ private string _fileBasePath;
///
/// Initializes a new instance of the class.
diff --git a/src/Umbraco.Core/CompositionExtensions.cs b/src/Umbraco.Core/CompositionExtensions.cs
index 828a577c34..5dd33c2a60 100644
--- a/src/Umbraco.Core/CompositionExtensions.cs
+++ b/src/Umbraco.Core/CompositionExtensions.cs
@@ -4,6 +4,7 @@ using Umbraco.Core.Composing;
using Umbraco.Core.Dictionary;
using Umbraco.Core.IO;
using Umbraco.Core.Logging.Viewer;
+using Umbraco.Core.Manifest;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PackageActions;
using Umbraco.Core.Persistence.Mappers;
@@ -66,9 +67,16 @@ namespace Umbraco.Core
/// Gets the validators collection builder.
///
/// The composition.
- internal static ManifestValueValidatorCollectionBuilder Validators(this Composition composition)
+ internal static ManifestValueValidatorCollectionBuilder ManifestValueValidators(this Composition composition)
=> composition.WithCollectionBuilder();
+ ///
+ /// Gets the manifest filter collection builder.
+ ///
+ /// The composition.
+ public static ManifestFilterCollectionBuilder ManifestFilters(this Composition composition)
+ => composition.WithCollectionBuilder();
+
///
/// Gets the components collection builder.
///
diff --git a/src/Umbraco.Core/ConfigsExtensions.cs b/src/Umbraco.Core/ConfigsExtensions.cs
index 6fdf7ea3b9..d1672c6c7f 100644
--- a/src/Umbraco.Core/ConfigsExtensions.cs
+++ b/src/Umbraco.Core/ConfigsExtensions.cs
@@ -7,6 +7,7 @@ using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
+using Umbraco.Core.Manifest;
namespace Umbraco.Core
{
@@ -41,7 +42,12 @@ namespace Umbraco.Core
configs.Add(() => new CoreDebug());
// GridConfig depends on runtime caches, manifest parsers... and cannot be available during composition
- configs.Add(factory => new GridConfig(factory.GetInstance(), factory.GetInstance(), configDir, factory.GetInstance().Debug));
+ configs.Add(factory => new GridConfig(
+ factory.GetInstance(),
+ factory.GetInstance(),
+ configDir,
+ factory.GetInstance(),
+ factory.GetInstance().Debug));
}
}
}
diff --git a/src/Umbraco.Core/Configuration/Grid/GridConfig.cs b/src/Umbraco.Core/Configuration/Grid/GridConfig.cs
index b2dae09fc9..9aead74886 100644
--- a/src/Umbraco.Core/Configuration/Grid/GridConfig.cs
+++ b/src/Umbraco.Core/Configuration/Grid/GridConfig.cs
@@ -1,14 +1,15 @@
using System.IO;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
+using Umbraco.Core.Manifest;
namespace Umbraco.Core.Configuration.Grid
{
class GridConfig : IGridConfig
{
- public GridConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, bool isDebug)
+ public GridConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, ManifestParser manifestParser, bool isDebug)
{
- EditorsConfig = new GridEditorsConfig(logger, appCaches, configFolder, isDebug);
+ EditorsConfig = new GridEditorsConfig(logger, appCaches, configFolder, manifestParser, isDebug);
}
public IGridEditorsConfig EditorsConfig { get; }
diff --git a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs
index 0e7ef62c58..d434da8c70 100644
--- a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs
+++ b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs
@@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
-using Newtonsoft.Json.Linq;
using Umbraco.Core.Cache;
-using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Umbraco.Core.Manifest;
using Umbraco.Core.PropertyEditors;
@@ -15,13 +13,15 @@ namespace Umbraco.Core.Configuration.Grid
private readonly ILogger _logger;
private readonly AppCaches _appCaches;
private readonly DirectoryInfo _configFolder;
+ private readonly ManifestParser _manifestParser;
private readonly bool _isDebug;
- public GridEditorsConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, bool isDebug)
+ public GridEditorsConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, ManifestParser manifestParser, bool isDebug)
{
_logger = logger;
_appCaches = appCaches;
_configFolder = configFolder;
+ _manifestParser = manifestParser;
_isDebug = isDebug;
}
@@ -31,9 +31,6 @@ namespace Umbraco.Core.Configuration.Grid
{
List GetResult()
{
- // TODO: should use the common one somehow! + ignoring _appPlugins here!
- var parser = new ManifestParser(_appCaches, Current.ManifestValidators, _logger);
-
var editors = new List();
var gridConfig = Path.Combine(_configFolder.FullName, "grid.editors.config.js");
if (File.Exists(gridConfig))
@@ -42,7 +39,7 @@ namespace Umbraco.Core.Configuration.Grid
try
{
- editors.AddRange(parser.ParseGridEditors(sourceString));
+ editors.AddRange(_manifestParser.ParseGridEditors(sourceString));
}
catch (Exception ex)
{
@@ -51,7 +48,7 @@ namespace Umbraco.Core.Configuration.Grid
}
// add manifest editors, skip duplicates
- foreach (var gridEditor in parser.Manifest.GridEditors)
+ foreach (var gridEditor in _manifestParser.Manifest.GridEditors)
{
if (editors.Contains(gridEditor) == false) editors.Add(gridEditor);
}
diff --git a/src/Umbraco.Core/Constants-DataTypes.cs b/src/Umbraco.Core/Constants-DataTypes.cs
index f2b31be28f..673da8f9a3 100644
--- a/src/Umbraco.Core/Constants-DataTypes.cs
+++ b/src/Umbraco.Core/Constants-DataTypes.cs
@@ -1,27 +1,375 @@
-namespace Umbraco.Core
+using System;
+
+namespace Umbraco.Core
{
public static partial class Constants
{
public static class DataTypes
{
- public const int LabelString = -92;
+ //NOTE: unfortunately due to backwards compat we can't move/rename these, with the addition of the GUID
+ //constants, it would make more sense to have these suffixed with "ID" or in a Subclass called "INT", for
+ //now all we can do is make a subclass called Guids to put the GUID IDs.
+
+ public const int LabelString = System.DefaultLabelDataTypeId;
public const int LabelInt = -91;
public const int LabelBigint = -93;
public const int LabelDateTime = -94;
public const int LabelTime = -98;
public const int LabelDecimal = -99;
+ public const int Textarea = -89;
public const int Textbox = -88;
+ public const int RichtextEditor = -87;
public const int Boolean = -49;
public const int DateTime = -36;
public const int DropDownSingle = -39;
public const int DropDownMultiple = -42;
+ public const int Upload = -90;
public const int DefaultContentListView = -95;
public const int DefaultMediaListView = -96;
public const int DefaultMembersListView = -97;
+ public const int ImageCropper = 1043;
public const int Tags = 1041;
+
+ public static class ReservedPreValueKeys
+ {
+ public const string IgnoreUserStartNodes = "ignoreUserStartNodes";
+ }
+
+ ///
+ /// Defines the identifiers for Umbraco data types as constants for easy centralized access/management.
+ ///
+ public static class Guids
+ {
+
+ ///
+ /// Guid for Content Picker as string
+ ///
+ public const string ContentPicker = "FD1E0DA5-5606-4862-B679-5D0CF3A52A59";
+
+ ///
+ /// Guid for Content Picker
+ ///
+ public static readonly Guid ContentPickerGuid = new Guid(ContentPicker);
+
+
+ ///
+ /// Guid for Member Picker as string
+ ///
+ public const string MemberPicker = "1EA2E01F-EBD8-4CE1-8D71-6B1149E63548";
+
+ ///
+ /// Guid for Member Picker
+ ///
+ public static readonly Guid MemberPickerGuid = new Guid(MemberPicker);
+
+
+ ///
+ /// Guid for Media Picker as string
+ ///
+ public const string MediaPicker = "135D60E0-64D9-49ED-AB08-893C9BA44AE5";
+
+ ///
+ /// Guid for Media Picker
+ ///
+ public static readonly Guid MediaPickerGuid = new Guid(MediaPicker);
+
+
+ ///
+ /// Guid for Multiple Media Picker as string
+ ///
+ public const string MultipleMediaPicker = "9DBBCBBB-2327-434A-B355-AF1B84E5010A";
+
+ ///
+ /// Guid for Multiple Media Picker
+ ///
+ public static readonly Guid MultipleMediaPickerGuid = new Guid(MultipleMediaPicker);
+
+
+ ///
+ /// Guid for Related Links as string
+ ///
+ public const string RelatedLinks = "B4E3535A-1753-47E2-8568-602CF8CFEE6F";
+
+ ///
+ /// Guid for Related Links
+ ///
+ public static readonly Guid RelatedLinksGuid = new Guid(RelatedLinks);
+
+
+ ///
+ /// Guid for Member as string
+ ///
+ public const string Member = "d59be02f-1df9-4228-aa1e-01917d806cda";
+
+ ///
+ /// Guid for Member
+ ///
+ public static readonly Guid MemberGuid = new Guid(Member);
+
+
+ ///
+ /// Guid for Image Cropper as string
+ ///
+ public const string ImageCropper = "1df9f033-e6d4-451f-b8d2-e0cbc50a836f";
+
+ ///
+ /// Guid for Image Cropper
+ ///
+ public static readonly Guid ImageCropperGuid = new Guid(ImageCropper);
+
+
+ ///
+ /// Guid for Tags as string
+ ///
+ public const string Tags = "b6b73142-b9c1-4bf8-a16d-e1c23320b549";
+
+ ///
+ /// Guid for Tags
+ ///
+ public static readonly Guid TagsGuid = new Guid(Tags);
+
+
+ ///
+ /// Guid for List View - Content as string
+ ///
+ public const string ListViewContent = "C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4";
+
+ ///
+ /// Guid for List View - Content
+ ///
+ public static readonly Guid ListViewContentGuid = new Guid(ListViewContent);
+
+
+ ///
+ /// Guid for List View - Media as string
+ ///
+ public const string ListViewMedia = "3A0156C4-3B8C-4803-BDC1-6871FAA83FFF";
+
+ ///
+ /// Guid for List View - Media
+ ///
+ public static readonly Guid ListViewMediaGuid = new Guid(ListViewMedia);
+
+
+ ///
+ /// Guid for List View - Members as string
+ ///
+ public const string ListViewMembers = "AA2C52A0-CE87-4E65-A47C-7DF09358585D";
+
+ ///
+ /// Guid for List View - Members
+ ///
+ public static readonly Guid ListViewMembersGuid = new Guid(ListViewMembers);
+
+
+ ///
+ /// Guid for Date Picker with time as string
+ ///
+ public const string DatePickerWithTime = "e4d66c0f-b935-4200-81f0-025f7256b89a";
+
+ ///
+ /// Guid for Date Picker with time
+ ///
+ public static readonly Guid DatePickerWithTimeGuid = new Guid(DatePickerWithTime);
+
+
+ ///
+ /// Guid for Approved Color as string
+ ///
+ public const string ApprovedColor = "0225af17-b302-49cb-9176-b9f35cab9c17";
+
+ ///
+ /// Guid for Approved Color
+ ///
+ public static readonly Guid ApprovedColorGuid = new Guid(ApprovedColor);
+
+
+ ///
+ /// Guid for Dropdown multiple as string
+ ///
+ public const string DropdownMultiple = "f38f0ac7-1d27-439c-9f3f-089cd8825a53";
+
+ ///
+ /// Guid for Dropdown multiple
+ ///
+ public static readonly Guid DropdownMultipleGuid = new Guid(DropdownMultiple);
+
+
+ ///
+ /// Guid for Radiobox as string
+ ///
+ public const string Radiobox = "bb5f57c9-ce2b-4bb9-b697-4caca783a805";
+
+ ///
+ /// Guid for Radiobox
+ ///
+ public static readonly Guid RadioboxGuid = new Guid(Radiobox);
+
+
+ ///
+ /// Guid for Date Picker as string
+ ///
+ public const string DatePicker = "5046194e-4237-453c-a547-15db3a07c4e1";
+
+ ///
+ /// Guid for Date Picker
+ ///
+ public static readonly Guid DatePickerGuid = new Guid(DatePicker);
+
+
+ ///
+ /// Guid for Dropdown as string
+ ///
+ public const string Dropdown = "0b6a45e7-44ba-430d-9da5-4e46060b9e03";
+
+ ///
+ /// Guid for Dropdown
+ ///
+ public static readonly Guid DropdownGuid = new Guid(Dropdown);
+
+
+ ///
+ /// Guid for Checkbox list as string
+ ///
+ public const string CheckboxList = "fbaf13a8-4036-41f2-93a3-974f678c312a";
+
+ ///
+ /// Guid for Checkbox list
+ ///
+ public static readonly Guid CheckboxListGuid = new Guid(CheckboxList);
+
+
+ ///
+ /// Guid for Checkbox as string
+ ///
+ public const string Checkbox = "92897bc6-a5f3-4ffe-ae27-f2e7e33dda49";
+
+ ///
+ /// Guid for Checkbox
+ ///
+ public static readonly Guid CheckboxGuid = new Guid(Checkbox);
+
+
+ ///
+ /// Guid for Numeric as string
+ ///
+ public const string Numeric = "2e6d3631-066e-44b8-aec4-96f09099b2b5";
+
+ ///
+ /// Guid for Dropdown
+ ///
+ public static readonly Guid NumericGuid = new Guid(Numeric);
+
+
+ ///
+ /// Guid for Richtext editor as string
+ ///
+ public const string RichtextEditor = "ca90c950-0aff-4e72-b976-a30b1ac57dad";
+
+ ///
+ /// Guid for Richtext editor
+ ///
+ public static readonly Guid RichtextEditorGuid = new Guid(RichtextEditor);
+
+
+ ///
+ /// Guid for Textstring as string
+ ///
+ public const string Textstring = "0cc0eba1-9960-42c9-bf9b-60e150b429ae";
+
+ ///
+ /// Guid for Textstring
+ ///
+ public static readonly Guid TextstringGuid = new Guid(Textstring);
+
+
+ ///
+ /// Guid for Textarea as string
+ ///
+ public const string Textarea = "c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3";
+
+ ///
+ /// Guid for Dropdown
+ ///
+ public static readonly Guid TextareaGuid = new Guid(Textarea);
+
+
+ ///
+ /// Guid for Upload as string
+ ///
+ public const string Upload = "84c6b441-31df-4ffe-b67e-67d5bc3ae65a";
+
+ ///
+ /// Guid for Upload
+ ///
+ public static readonly Guid UploadGuid = new Guid(Upload);
+
+
+ ///
+ /// Guid for Label as string
+ ///
+ public const string LabelString = "f0bc4bfb-b499-40d6-ba86-058885a5178c";
+
+ ///
+ /// Guid for Label string
+ ///
+ public static readonly Guid LabelStringGuid = new Guid(LabelString);
+
+ ///
+ /// Guid for Label as int
+ ///
+ public const string LabelInt = "8e7f995c-bd81-4627-9932-c40e568ec788";
+
+ ///
+ /// Guid for Label int
+ ///
+ public static readonly Guid LabelIntGuid = new Guid(LabelInt);
+
+ ///
+ /// Guid for Label as big int
+ ///
+ public const string LabelBigInt = "930861bf-e262-4ead-a704-f99453565708";
+
+ ///
+ /// Guid for Label big int
+ ///
+ public static readonly Guid LabelBigIntGuid = new Guid(LabelBigInt);
+
+ ///
+ /// Guid for Label as date time
+ ///
+ public const string LabelDateTime = "0e9794eb-f9b5-4f20-a788-93acd233a7e4";
+
+ ///
+ /// Guid for Label date time
+ ///
+ public static readonly Guid LabelDateTimeGuid = new Guid(LabelDateTime);
+
+ ///
+ /// Guid for Label as time
+ ///
+ public const string LabelTime = "a97cec69-9b71-4c30-8b12-ec398860d7e8";
+
+ ///
+ /// Guid for Label time
+ ///
+ public static readonly Guid LabelTimeGuid = new Guid(LabelTime);
+
+ ///
+ /// Guid for Label as decimal
+ ///
+ public const string LabelDecimal = "8f1ef1e1-9de4-40d3-a072-6673f631ca64";
+
+ ///
+ /// Guid for Label decimal
+ ///
+ public static readonly Guid LabelDecimalGuid = new Guid(LabelDecimal);
+
+
+ }
}
}
}
diff --git a/src/Umbraco.Core/Constants-Icons.cs b/src/Umbraco.Core/Constants-Icons.cs
index d3e8b4ad3b..05213ed1c4 100644
--- a/src/Umbraco.Core/Constants-Icons.cs
+++ b/src/Umbraco.Core/Constants-Icons.cs
@@ -5,39 +5,89 @@
public static class Icons
{
///
- /// System contenttype icon
+ /// System default icon
///
- public const string ContentType = "icon-arrangement";
+ public const string DefaultIcon = Content;
///
- /// System datatype icon
+ /// System content icon
+ ///
+ public const string Content = "icon-document";
+
+ ///
+ /// System content type icon
+ ///
+ public const string ContentType = "icon-item-arrangement";
+
+ ///
+ /// System data type icon
///
public const string DataType = "icon-autofill";
///
- /// System property editor icon
+ /// System list view icon
///
- public const string PropertyEditor = "icon-autofill";
+ public const string ListView = "icon-thumbnail-list";
///
/// System macro icon
///
public const string Macro = "icon-settings-alt";
+ ///
+ /// System media file icon
+ ///
+ public const string MediaFile = "icon-document";
+
+ ///
+ /// System media folder icon
+ ///
+ public const string MediaFolder = "icon-folder";
+
+ ///
+ /// System media image icon
+ ///
+ public const string MediaImage = "icon-picture";
+
+ ///
+ /// System media type icon
+ ///
+ public const string MediaType = "icon-thumbnails";
+
///
/// System member icon
///
public const string Member = "icon-user";
///
- /// System member icon
+ /// System member group icon
+ ///
+ public const string MemberGroup = "icon-users-alt";
+
+ ///
+ /// System member type icon
///
public const string MemberType = "icon-users";
+ ///
+ /// System property editor icon
+ ///
+ public const string PropertyEditor = "icon-autofill";
+
///
/// System member icon
///
public const string Template = "icon-layout";
+
+ ///
+ /// System user icon
+ ///
+ public const string User = "icon-user";
+
+ ///
+ /// System user group icon
+ ///
+ public const string UserGroup = "icon-users";
}
}
}
diff --git a/src/Umbraco.Core/Constants-PropertyEditors.cs b/src/Umbraco.Core/Constants-PropertyEditors.cs
index f9b298e586..cc461a5775 100644
--- a/src/Umbraco.Core/Constants-PropertyEditors.cs
+++ b/src/Umbraco.Core/Constants-PropertyEditors.cs
@@ -14,6 +14,23 @@ namespace Umbraco.Core
///
public const string InternalGenericPropertiesPrefix = "_umb_";
+ public static class Legacy
+ {
+ public static class Aliases
+ {
+ public const string Textbox = "Umbraco.Textbox";
+ public const string Date = "Umbraco.Date";
+ public const string ContentPicker2 = "Umbraco.ContentPicker2";
+ public const string MediaPicker2 = "Umbraco.MediaPicker2";
+ public const string MemberPicker2 = "Umbraco.MemberPicker2";
+ public const string MultiNodeTreePicker2 = "Umbraco.MultiNodeTreePicker2";
+ public const string TextboxMultiple = "Umbraco.TextboxMultiple";
+ public const string RelatedLinks2 = "Umbraco.RelatedLinks2";
+ public const string RelatedLinks = "Umbraco.RelatedLinks";
+
+ }
+ }
+
///
/// Defines Umbraco built-in property editor aliases.
///
@@ -191,6 +208,24 @@ namespace Umbraco.Core
/// Must be a valid value.
public const string DataValueType = "umbracoDataValueType";
}
+
+ ///
+ /// Defines Umbraco's built-in property editor groups.
+ ///
+ public static class Groups
+ {
+ public const string Common = "Common";
+
+ public const string Lists = "Lists";
+
+ public const string Media = "Media";
+
+ public const string People = "People";
+
+ public const string Pickers = "Pickers";
+
+ public const string RichContent = "Rich Content";
+ }
}
}
}
diff --git a/src/Umbraco.Core/Constants-Security.cs b/src/Umbraco.Core/Constants-Security.cs
index 80f18eb2e0..27d6716000 100644
--- a/src/Umbraco.Core/Constants-Security.cs
+++ b/src/Umbraco.Core/Constants-Security.cs
@@ -15,13 +15,18 @@ namespace Umbraco.Core
public const int SuperUserId = -1;
///
- /// The id for the 'unknown' user
+ /// The id for the 'unknown' user.
///
///
/// This is a user row that exists in the DB only for referential integrity but the user is never returned from any of the services
///
public const int UnknownUserId = 0;
+ ///
+ /// The name of the 'unknown' user.
+ ///
+ public const string UnknownUserName = "SYTEM";
+
public const string AdminGroupAlias = "admin";
public const string SensitiveDataGroupAlias = "sensitiveData";
public const string TranslatorGroupAlias = "translator";
diff --git a/src/Umbraco.Core/ContentVariationExtensions.cs b/src/Umbraco.Core/ContentVariationExtensions.cs
index d25997b5f0..9fdc5f0b90 100644
--- a/src/Umbraco.Core/ContentVariationExtensions.cs
+++ b/src/Umbraco.Core/ContentVariationExtensions.cs
@@ -66,44 +66,44 @@ namespace Umbraco.Core
///
/// Determines whether the content type is invariant.
///
- public static bool VariesByNothing(this PublishedContentType contentType) => contentType.Variations.VariesByNothing();
+ public static bool VariesByNothing(this IPublishedContentType contentType) => contentType.Variations.VariesByNothing();
///
/// Determines whether the content type varies by culture.
///
/// And then it could also vary by segment.
- public static bool VariesByCulture(this PublishedContentType contentType) => contentType.Variations.VariesByCulture();
+ public static bool VariesByCulture(this IPublishedContentType contentType) => contentType.Variations.VariesByCulture();
///
/// Determines whether the content type varies by segment.
///
/// And then it could also vary by culture.
- public static bool VariesBySegment(this PublishedContentType contentType) => contentType.Variations.VariesBySegment();
+ public static bool VariesBySegment(this IPublishedContentType contentType) => contentType.Variations.VariesBySegment();
///
/// Determines whether the content type varies by culture and segment.
///
- public static bool VariesByCultureAndSegment(this PublishedContentType contentType) => contentType.Variations.VariesByCultureAndSegment();
+ public static bool VariesByCultureAndSegment(this IPublishedContentType contentType) => contentType.Variations.VariesByCultureAndSegment();
///
/// Determines whether the property type is invariant.
///
- public static bool VariesByNothing(this PublishedPropertyType propertyType) => propertyType.Variations.VariesByNothing();
+ public static bool VariesByNothing(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesByNothing();
///
/// Determines whether the property type varies by culture.
///
- public static bool VariesByCulture(this PublishedPropertyType propertyType) => propertyType.Variations.VariesByCulture();
+ public static bool VariesByCulture(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesByCulture();
///
/// Determines whether the property type varies by segment.
///
- public static bool VariesBySegment(this PublishedPropertyType propertyType) => propertyType.Variations.VariesBySegment();
+ public static bool VariesBySegment(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesBySegment();
///
/// Determines whether the property type varies by culture and segment.
///
- public static bool VariesByCultureAndSegment(this PublishedPropertyType propertyType) => propertyType.Variations.VariesByCultureAndSegment();
+ public static bool VariesByCultureAndSegment(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesByCultureAndSegment();
///
/// Determines whether a variation is invariant.
diff --git a/src/Umbraco.Core/EnumerableExtensions.cs b/src/Umbraco.Core/EnumerableExtensions.cs
index 3719bb0750..59f5937874 100644
--- a/src/Umbraco.Core/EnumerableExtensions.cs
+++ b/src/Umbraco.Core/EnumerableExtensions.cs
@@ -10,6 +10,8 @@ namespace Umbraco.Core
///
public static class EnumerableExtensions
{
+ internal static bool IsCollectionEmpty(this IReadOnlyCollection list) => list == null || list.Count == 0;
+
internal static bool HasDuplicates(this IEnumerable items, bool includeNull)
{
var hs = new HashSet();
@@ -112,7 +114,6 @@ namespace Umbraco.Core
}
}
-
///
/// Returns true if all items in the other collection exist in this collection
///
diff --git a/src/Umbraco.Core/Logging/Viewer/ILogViewer.cs b/src/Umbraco.Core/Logging/Viewer/ILogViewer.cs
index 4aaf6d25f2..b39a3f38df 100644
--- a/src/Umbraco.Core/Logging/Viewer/ILogViewer.cs
+++ b/src/Umbraco.Core/Logging/Viewer/ILogViewer.cs
@@ -26,26 +26,26 @@ namespace Umbraco.Core.Logging.Viewer
/// A count of number of errors
/// By counting Warnings with Exceptions, Errors & Fatal messages
///
- int GetNumberOfErrors(DateTimeOffset startDate, DateTimeOffset endDate);
+ int GetNumberOfErrors(LogTimePeriod logTimePeriod);
///
/// Returns a number of the different log level entries
///
- LogLevelCounts GetLogLevelCounts(DateTimeOffset startDate, DateTimeOffset endDate);
+ LogLevelCounts GetLogLevelCounts(LogTimePeriod logTimePeriod);
///
/// Returns a list of all unique message templates and their counts
///
- IEnumerable GetMessageTemplates(DateTimeOffset startDate, DateTimeOffset endDate);
+ IEnumerable GetMessageTemplates(LogTimePeriod logTimePeriod);
bool CanHandleLargeLogs { get; }
- bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate);
+ bool CheckCanOpenLogs(LogTimePeriod logTimePeriod);
///
/// Returns the collection of logs
///
- PagedResult GetLogs(DateTimeOffset startDate, DateTimeOffset endDate,
+ PagedResult GetLogs(LogTimePeriod logTimePeriod,
int pageNumber = 1,
int pageSize = 100,
Direction orderDirection = Direction.Descending,
diff --git a/src/Umbraco.Core/Logging/Viewer/JsonLogViewer.cs b/src/Umbraco.Core/Logging/Viewer/JsonLogViewer.cs
index 9e6d911489..bbe2f3704d 100644
--- a/src/Umbraco.Core/Logging/Viewer/JsonLogViewer.cs
+++ b/src/Umbraco.Core/Logging/Viewer/JsonLogViewer.cs
@@ -26,7 +26,7 @@ namespace Umbraco.Core.Logging.Viewer
public override bool CanHandleLargeLogs => false;
- public override bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate)
+ public override bool CheckCanOpenLogs(LogTimePeriod logTimePeriod)
{
//Log Directory
var logDirectory = _logsPath;
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Logging.Viewer
//foreach full day in the range - see if we can find one or more filenames that end with
//yyyyMMdd.json - Ends with due to MachineName in filenames - could be 1 or more due to load balancing
- for (var day = startDate.Date; day.Date <= endDate.Date; day = day.AddDays(1))
+ for (var day = logTimePeriod.StartTime.Date; day.Date <= logTimePeriod.EndTime.Date; day = day.AddDays(1))
{
//Filename ending to search for (As could be multiple)
var filesToFind = GetSearchPattern(day);
@@ -57,7 +57,7 @@ namespace Umbraco.Core.Logging.Viewer
return $"*{day:yyyyMMdd}*.json";
}
- protected override IReadOnlyList GetLogs(DateTimeOffset startDate, DateTimeOffset endDate, ILogFilter filter, int skip, int take)
+ protected override IReadOnlyList GetLogs(LogTimePeriod logTimePeriod, ILogFilter filter, int skip, int take)
{
var logs = new List();
@@ -68,7 +68,7 @@ namespace Umbraco.Core.Logging.Viewer
//foreach full day in the range - see if we can find one or more filenames that end with
//yyyyMMdd.json - Ends with due to MachineName in filenames - could be 1 or more due to load balancing
- for (var day = startDate.Date; day.Date <= endDate.Date; day = day.AddDays(1))
+ for (var day = logTimePeriod.StartTime.Date; day.Date <= logTimePeriod.EndTime.Date; day = day.AddDays(1))
{
//Filename ending to search for (As could be multiple)
var filesToFind = GetSearchPattern(day);
diff --git a/src/Umbraco.Core/Logging/Viewer/LogTimePeriod.cs b/src/Umbraco.Core/Logging/Viewer/LogTimePeriod.cs
new file mode 100644
index 0000000000..0f41faef0a
--- /dev/null
+++ b/src/Umbraco.Core/Logging/Viewer/LogTimePeriod.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Umbraco.Core.Logging.Viewer
+{
+ public class LogTimePeriod
+ {
+ public LogTimePeriod(DateTime startTime, DateTime endTime)
+ {
+ StartTime = startTime;
+ EndTime = endTime;
+ }
+
+ public DateTime StartTime { get; }
+ public DateTime EndTime { get; }
+ }
+}
diff --git a/src/Umbraco.Core/Logging/Viewer/LogViewerSourceBase.cs b/src/Umbraco.Core/Logging/Viewer/LogViewerSourceBase.cs
index 3578a56e74..acb2f5dbf9 100644
--- a/src/Umbraco.Core/Logging/Viewer/LogViewerSourceBase.cs
+++ b/src/Umbraco.Core/Logging/Viewer/LogViewerSourceBase.cs
@@ -27,9 +27,9 @@ namespace Umbraco.Core.Logging.Viewer
///
/// Get all logs from your chosen data source back as Serilog LogEvents
///
- protected abstract IReadOnlyList GetLogs(DateTimeOffset startDate, DateTimeOffset endDate, ILogFilter filter, int skip, int take);
+ protected abstract IReadOnlyList GetLogs(LogTimePeriod logTimePeriod, ILogFilter filter, int skip, int take);
- public abstract bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate);
+ public abstract bool CheckCanOpenLogs(LogTimePeriod logTimePeriod);
public virtual IReadOnlyList GetSavedSearches()
{
@@ -82,24 +82,24 @@ namespace Umbraco.Core.Logging.Viewer
return searches;
}
- public int GetNumberOfErrors(DateTimeOffset startDate, DateTimeOffset endDate)
+ public int GetNumberOfErrors(LogTimePeriod logTimePeriod)
{
var errorCounter = new ErrorCounterFilter();
- GetLogs(startDate, endDate, errorCounter, 0, int.MaxValue);
+ GetLogs(logTimePeriod, errorCounter, 0, int.MaxValue);
return errorCounter.Count;
}
- public LogLevelCounts GetLogLevelCounts(DateTimeOffset startDate, DateTimeOffset endDate)
+ public LogLevelCounts GetLogLevelCounts(LogTimePeriod logTimePeriod)
{
var counter = new CountingFilter();
- GetLogs(startDate, endDate, counter, 0, int.MaxValue);
+ GetLogs(logTimePeriod, counter, 0, int.MaxValue);
return counter.Counts;
}
- public IEnumerable GetMessageTemplates(DateTimeOffset startDate, DateTimeOffset endDate)
+ public IEnumerable GetMessageTemplates(LogTimePeriod logTimePeriod)
{
var messageTemplates = new MessageTemplateFilter();
- GetLogs(startDate, endDate, messageTemplates, 0, int.MaxValue);
+ GetLogs(logTimePeriod, messageTemplates, 0, int.MaxValue);
var templates = messageTemplates.Counts.
Select(x => new LogTemplate { MessageTemplate = x.Key, Count = x.Value })
@@ -108,14 +108,14 @@ namespace Umbraco.Core.Logging.Viewer
return templates;
}
- public PagedResult GetLogs(DateTimeOffset startDate, DateTimeOffset endDate,
+ public PagedResult GetLogs(LogTimePeriod logTimePeriod,
int pageNumber = 1, int pageSize = 100,
Direction orderDirection = Direction.Descending,
string filterExpression = null,
string[] logLevels = null)
{
var expression = new ExpressionFilter(filterExpression);
- var filteredLogs = GetLogs(startDate, endDate, expression, 0, int.MaxValue);
+ var filteredLogs = GetLogs(logTimePeriod, expression, 0, int.MaxValue);
//This is user used the checkbox UI to toggle which log levels they wish to see
//If an empty array or null - its implied all levels to be viewed
diff --git a/src/Umbraco.Core/MainDom.cs b/src/Umbraco.Core/MainDom.cs
index ca875c2167..d1012fb669 100644
--- a/src/Umbraco.Core/MainDom.cs
+++ b/src/Umbraco.Core/MainDom.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Web.Hosting;
@@ -113,7 +114,7 @@ namespace Umbraco.Core
lock (_locko)
{
- _logger.Debug("Signaled {Signaled} ({SignalSource})", _signaled ? "(again)" : string.Empty, source);
+ _logger.Debug("Signaled ({Signaled}) ({SignalSource})", _signaled ? "again" : "first", source);
if (_signaled) return;
if (_isMainDom == false) return; // probably not needed
_signaled = true;
@@ -171,6 +172,7 @@ namespace Umbraco.Core
// if more than 1 instance reach that point, one will get the lock
// and the other one will timeout, which is accepted
+ //TODO: This can throw a TimeoutException - in which case should this be in a try/finally to ensure the signal is always reset?
_asyncLocker = _asyncLock.Lock(LockTimeoutMilliseconds);
_isMainDom = true;
@@ -181,6 +183,9 @@ namespace Umbraco.Core
// which is accepted
_signal.Reset();
+
+ //WaitOneAsync (ext method) will wait for a signal without blocking the main thread, the waiting is done on a background thread
+
_signal.WaitOneAsync()
.ContinueWith(_ => OnSignal("signal"));
diff --git a/src/Umbraco.Core/Manifest/IManifestFilter.cs b/src/Umbraco.Core/Manifest/IManifestFilter.cs
new file mode 100644
index 0000000000..505f13d385
--- /dev/null
+++ b/src/Umbraco.Core/Manifest/IManifestFilter.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Core.Manifest
+{
+ ///
+ /// Provides filtering for package manifests.
+ ///
+ public interface IManifestFilter
+ {
+ ///
+ /// Filters package manifests.
+ ///
+ /// The package manifests.
+ ///
+ /// It is possible to remove, change, or add manifests.
+ ///
+ void Filter(List manifests);
+ }
+}
diff --git a/src/Umbraco.Core/Manifest/ManifestFilterCollection.cs b/src/Umbraco.Core/Manifest/ManifestFilterCollection.cs
new file mode 100644
index 0000000000..febdb7e356
--- /dev/null
+++ b/src/Umbraco.Core/Manifest/ManifestFilterCollection.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using Umbraco.Core.Composing;
+
+namespace Umbraco.Core.Manifest
+{
+ ///
+ /// Contains the manifest filters.
+ ///
+ public class ManifestFilterCollection : BuilderCollectionBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ManifestFilterCollection(IEnumerable items)
+ : base(items)
+ { }
+
+ ///
+ /// Filters package manifests.
+ ///
+ /// The package manifests.
+ public void Filter(List manifests)
+ {
+ foreach (var filter in this)
+ filter.Filter(manifests);
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Manifest/ManifestFilterCollectionBuilder.cs b/src/Umbraco.Core/Manifest/ManifestFilterCollectionBuilder.cs
new file mode 100644
index 0000000000..4d98700f93
--- /dev/null
+++ b/src/Umbraco.Core/Manifest/ManifestFilterCollectionBuilder.cs
@@ -0,0 +1,12 @@
+using Umbraco.Core.Composing;
+
+namespace Umbraco.Core.Manifest
+{
+ public class ManifestFilterCollectionBuilder : OrderedCollectionBuilderBase
+ {
+ protected override ManifestFilterCollectionBuilder This => this;
+
+ // do NOT cache this, it's only used once
+ protected override Lifetime CollectionLifetime => Lifetime.Transient;
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs
index dc40cd90a2..efd9e92b1f 100644
--- a/src/Umbraco.Core/Manifest/ManifestParser.cs
+++ b/src/Umbraco.Core/Manifest/ManifestParser.cs
@@ -22,24 +22,26 @@ namespace Umbraco.Core.Manifest
private readonly IAppPolicyCache _cache;
private readonly ILogger _logger;
private readonly ManifestValueValidatorCollection _validators;
+ private readonly ManifestFilterCollection _filters;
private string _path;
///
/// Initializes a new instance of the class.
///
- public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ILogger logger)
- : this(appCaches, validators, "~/App_Plugins", logger)
+ public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger)
+ : this(appCaches, validators, filters, "~/App_Plugins", logger)
{ }
///
/// Initializes a new instance of the class.
///
- private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, string path, ILogger logger)
+ private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string path, ILogger logger)
{
if (appCaches == null) throw new ArgumentNullException(nameof(appCaches));
_cache = appCaches.RuntimeCache;
_validators = validators ?? throw new ArgumentNullException(nameof(validators));
+ _filters = filters ?? throw new ArgumentNullException(nameof(filters));
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullOrEmptyException(nameof(path));
Path = path;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
@@ -78,6 +80,7 @@ namespace Umbraco.Core.Manifest
if (string.IsNullOrWhiteSpace(text))
continue;
var manifest = ParseManifest(text);
+ manifest.Source = path;
manifests.Add(manifest);
}
catch (Exception e)
@@ -86,6 +89,8 @@ namespace Umbraco.Core.Manifest
}
}
+ _filters.Filter(manifests);
+
return manifests;
}
diff --git a/src/Umbraco.Core/Manifest/PackageManifest.cs b/src/Umbraco.Core/Manifest/PackageManifest.cs
index 475ee8a7f8..e50eb69467 100644
--- a/src/Umbraco.Core/Manifest/PackageManifest.cs
+++ b/src/Umbraco.Core/Manifest/PackageManifest.cs
@@ -9,6 +9,16 @@ namespace Umbraco.Core.Manifest
///
public class PackageManifest
{
+ ///
+ /// Gets the source path of the manifest.
+ ///
+ ///
+ /// Gets the full absolute file path of the manifest,
+ /// using system directory separators.
+ ///
+ [JsonIgnore]
+ public string Source { get; set; }
+
///
/// Gets or sets the scripts listed in the manifest.
///
diff --git a/src/Umbraco.Core/Mapping/UmbracoMapper.cs b/src/Umbraco.Core/Mapping/UmbracoMapper.cs
index 2d495b38b5..8915ebcf74 100644
--- a/src/Umbraco.Core/Mapping/UmbracoMapper.cs
+++ b/src/Umbraco.Core/Mapping/UmbracoMapper.cs
@@ -191,7 +191,7 @@ namespace Umbraco.Core.Mapping
private TTarget Map(object source, Type sourceType, MapperContext context)
{
if (source == null)
- throw new ArgumentNullException(nameof(source));
+ return default;
var targetType = typeof(TTarget);
diff --git a/src/Umbraco.Core/Migrations/Expressions/Create/KeysAndIndexes/CreateKeysAndIndexesBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Create/KeysAndIndexes/CreateKeysAndIndexesBuilder.cs
index b11ef7e2c8..6bf450a9b8 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Create/KeysAndIndexes/CreateKeysAndIndexesBuilder.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Create/KeysAndIndexes/CreateKeysAndIndexesBuilder.cs
@@ -25,11 +25,25 @@ namespace Umbraco.Core.Migrations.Expressions.Create.KeysAndIndexes
var syntax = _context.SqlContext.SqlSyntax;
var tableDefinition = DefinitionFactory.GetTableDefinition(TypeOfDto, syntax);
+ // note: of course we are creating the keys and indexes as per the DTO, so
+ // changing the DTO may break old migrations - or, better, these migrations
+ // should capture a copy of the DTO class that will not change
+
ExecuteSql(syntax.FormatPrimaryKey(tableDefinition));
foreach (var sql in syntax.Format(tableDefinition.Indexes))
ExecuteSql(sql);
foreach (var sql in syntax.Format(tableDefinition.ForeignKeys))
ExecuteSql(sql);
+
+ // note: we do *not* create the DF_ default constraints
+ /*
+ foreach (var column in tableDefinition.Columns)
+ {
+ var sql = syntax.FormatDefaultConstraint(column);
+ if (!sql.IsNullOrWhiteSpace())
+ ExecuteSql(sql);
+ }
+ */
}
private void ExecuteSql(string sql)
diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/DefaultConstraint/DeleteDefaultConstraintBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/DefaultConstraint/DeleteDefaultConstraintBuilder.cs
index 373b375fa8..92bc11b04d 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Delete/DefaultConstraint/DeleteDefaultConstraintBuilder.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Delete/DefaultConstraint/DeleteDefaultConstraintBuilder.cs
@@ -10,9 +10,13 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.DefaultConstraint
IDeleteDefaultConstraintOnTableBuilder,
IDeleteDefaultConstraintOnColumnBuilder
{
- public DeleteDefaultConstraintBuilder(DeleteDefaultConstraintExpression expression)
+ private readonly IMigrationContext _context;
+
+ public DeleteDefaultConstraintBuilder(IMigrationContext context, DeleteDefaultConstraintExpression expression)
: base(expression)
- { }
+ {
+ _context = context;
+ }
///
public IDeleteDefaultConstraintOnColumnBuilder OnTable(string tableName)
@@ -25,6 +29,9 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.DefaultConstraint
public IExecutableBuilder OnColumn(string columnName)
{
Expression.ColumnName = columnName;
+ Expression.HasDefaultConstraint = _context.SqlContext.SqlSyntax.TryGetDefaultConstraint(_context.Database, Expression.TableName, columnName, out var constraintName);
+ Expression.ConstraintName = constraintName ?? string.Empty;
+
return new ExecutableBuilder(Expression);
}
}
diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/DeleteBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/DeleteBuilder.cs
index d081305cde..9a4f437f62 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Delete/DeleteBuilder.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Delete/DeleteBuilder.cs
@@ -1,4 +1,4 @@
-using NPoco;
+using Umbraco.Core.Exceptions;
using Umbraco.Core.Migrations.Expressions.Common;
using Umbraco.Core.Migrations.Expressions.Delete.Column;
using Umbraco.Core.Migrations.Expressions.Delete.Constraint;
@@ -29,9 +29,19 @@ namespace Umbraco.Core.Migrations.Expressions.Delete
}
///
- public IExecutableBuilder KeysAndIndexes(string tableName = null)
+ public IExecutableBuilder KeysAndIndexes(bool local = true, bool foreign = true)
{
- return new DeleteKeysAndIndexesBuilder(_context) { TableName = tableName };
+ var syntax = _context.SqlContext.SqlSyntax;
+ var tableDefinition = DefinitionFactory.GetTableDefinition(typeof(TDto), syntax);
+ return KeysAndIndexes(tableDefinition.Name, local, foreign);
+ }
+
+ ///
+ public IExecutableBuilder KeysAndIndexes(string tableName, bool local = true, bool foreign = true)
+ {
+ if (tableName.IsNullOrWhiteSpace())
+ throw new ArgumentNullOrEmptyException(nameof(tableName));
+ return new DeleteKeysAndIndexesBuilder(_context) { TableName = tableName, DeleteLocal = local, DeleteForeign = foreign };
}
///
@@ -100,7 +110,7 @@ namespace Umbraco.Core.Migrations.Expressions.Delete
public IDeleteDefaultConstraintOnTableBuilder DefaultConstraint()
{
var expression = new DeleteDefaultConstraintExpression(_context);
- return new DeleteDefaultConstraintBuilder(expression);
+ return new DeleteDefaultConstraintBuilder(_context, expression);
}
}
}
diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteDefaultConstraintExpression.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteDefaultConstraintExpression.cs
index 8b0b20c0e2..b73d3f0d13 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteDefaultConstraintExpression.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Delete/Expressions/DeleteDefaultConstraintExpression.cs
@@ -10,12 +10,17 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions
public virtual string TableName { get; set; }
public virtual string ColumnName { get; set; }
+ public virtual string ConstraintName { get; set; }
+ public virtual bool HasDefaultConstraint { get; set; }
protected override string GetSql()
{
- return string.Format(SqlSyntax.DeleteDefaultConstraint,
- SqlSyntax.GetQuotedTableName(TableName),
- SqlSyntax.GetQuotedColumnName(ColumnName));
+ return HasDefaultConstraint
+ ? string.Format(SqlSyntax.DeleteDefaultConstraint,
+ SqlSyntax.GetQuotedTableName(TableName),
+ SqlSyntax.GetQuotedColumnName(ColumnName),
+ SqlSyntax.GetQuotedName(ConstraintName))
+ : string.Empty;
}
}
}
diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/IDeleteBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/IDeleteBuilder.cs
index 07faf5028e..84e44d0d93 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Delete/IDeleteBuilder.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Delete/IDeleteBuilder.cs
@@ -19,9 +19,14 @@ namespace Umbraco.Core.Migrations.Expressions.Delete
IExecutableBuilder Table(string tableName);
///
- /// Specifies the table to delete keys and indexes for.
+ /// Builds a Delete Keys and Indexes expression, and executes.
///
- IExecutableBuilder KeysAndIndexes(string tableName = null);
+ IExecutableBuilder KeysAndIndexes(bool local = true, bool foreign = true);
+
+ ///
+ /// Builds a Delete Keys and Indexes expression, and executes.
+ ///
+ IExecutableBuilder KeysAndIndexes(string tableName, bool local = true, bool foreign = true);
///
/// Specifies the column to delete.
diff --git a/src/Umbraco.Core/Migrations/Expressions/Delete/KeysAndIndexes/DeleteKeysAndIndexesBuilder.cs b/src/Umbraco.Core/Migrations/Expressions/Delete/KeysAndIndexes/DeleteKeysAndIndexesBuilder.cs
index 1c595d9103..9b13457b76 100644
--- a/src/Umbraco.Core/Migrations/Expressions/Delete/KeysAndIndexes/DeleteKeysAndIndexesBuilder.cs
+++ b/src/Umbraco.Core/Migrations/Expressions/Delete/KeysAndIndexes/DeleteKeysAndIndexesBuilder.cs
@@ -18,34 +18,38 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.KeysAndIndexes
public string TableName { get; set; }
+ public bool DeleteLocal { get; set; }
+
+ public bool DeleteForeign { get; set; }
+
///
public void Do()
{
- if (TableName == null)
- {
- // drop keys
- var keys = _context.SqlContext.SqlSyntax.GetConstraintsPerTable(_context.Database).DistinctBy(x => x.Item2).ToArray();
- foreach (var key in keys.Where(x => x.Item2.StartsWith("FK_")))
- Delete.ForeignKey(key.Item2).OnTable(key.Item1).Do();
- foreach (var key in keys.Where(x => x.Item2.StartsWith("PK_")))
- Delete.PrimaryKey(key.Item2).FromTable(key.Item1).Do();
+ _context.BuildingExpression = false;
- // drop indexes
- var indexes = _context.SqlContext.SqlSyntax.GetDefinedIndexesDefinitions(_context.Database).DistinctBy(x => x.IndexName).ToArray();
- foreach (var index in indexes)
- Delete.Index(index.IndexName).OnTable(index.TableName).Do();
+ // drop keys
+ if (DeleteLocal || DeleteForeign)
+ {
+ // table, constraint
+ var tableKeys = _context.SqlContext.SqlSyntax.GetConstraintsPerTable(_context.Database).DistinctBy(x => x.Item2).ToList();
+ if (DeleteForeign)
+ {
+ foreach (var key in tableKeys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("FK_")))
+ Delete.ForeignKey(key.Item2).OnTable(key.Item1).Do();
+ }
+ if (DeleteLocal)
+ {
+ foreach (var key in tableKeys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("PK_")))
+ Delete.PrimaryKey(key.Item2).FromTable(key.Item1).Do();
+
+ // note: we do *not* delete the DEFAULT constraints
+ }
}
- else
- {
- // drop keys
- var keys = _context.SqlContext.SqlSyntax.GetConstraintsPerTable(_context.Database).DistinctBy(x => x.Item2).ToArray();
- foreach (var key in keys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("FK_")))
- Delete.ForeignKey(key.Item2).OnTable(key.Item1).Do();
- foreach (var key in keys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("PK_")))
- Delete.PrimaryKey(key.Item2).FromTable(key.Item1).Do();
- // drop indexes
- var indexes = _context.SqlContext.SqlSyntax.GetDefinedIndexesDefinitions(_context.Database).DistinctBy(x => x.IndexName).ToArray();
+ // drop indexes
+ if (DeleteLocal)
+ {
+ var indexes = _context.SqlContext.SqlSyntax.GetDefinedIndexesDefinitions(_context.Database).DistinctBy(x => x.IndexName).ToList();
foreach (var index in indexes.Where(x => x.TableName == TableName))
Delete.Index(index.IndexName).OnTable(index.TableName).Do();
}
diff --git a/src/Umbraco.Core/Migrations/IMigrationContext.cs b/src/Umbraco.Core/Migrations/IMigrationContext.cs
index 2baadc79eb..c76de8dfb3 100644
--- a/src/Umbraco.Core/Migrations/IMigrationContext.cs
+++ b/src/Umbraco.Core/Migrations/IMigrationContext.cs
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Migrations
bool BuildingExpression { get; set; }
///
- /// Adds a post-migrations.
+ /// Adds a post-migration.
///
void AddPostMigration()
where TMigration : IMigration;
diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs b/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs
index 5c4defab0c..d86c682bd5 100644
--- a/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs
+++ b/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs
@@ -389,7 +389,7 @@ namespace Umbraco.Core.Migrations.Install
private DatabaseSchemaResult ValidateSchema(IScope scope)
{
- if (_databaseFactory.Configured == false)
+ if (_databaseFactory.Initialized == false)
return new DatabaseSchemaResult(_databaseFactory.SqlContext.SqlSyntax);
if (_databaseSchemaValidationResult != null)
@@ -513,7 +513,7 @@ namespace Umbraco.Core.Migrations.Install
private Attempt CheckReadyForInstall()
{
- if (_databaseFactory.Configured == false)
+ if (_databaseFactory.CanConnect == false)
{
return Attempt.Fail(new Result
{
@@ -539,7 +539,7 @@ namespace Umbraco.Core.Migrations.Install
{
Message =
"The database configuration failed with the following message: " + ex.Message +
- "\n Please check log file for additional information (can be found in '/App_Data/Logs/UmbracoTraceLog.txt')",
+ "\n Please check log file for additional information (can be found in '/App_Data/Logs/')",
Success = false,
Percentage = "90"
};
diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs
index 1de983636b..dd5c17713a 100644
--- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs
+++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs
@@ -101,33 +101,33 @@ namespace Umbraco.Core.Migrations.Install
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -1, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1", SortOrder = 0, UniqueId = new Guid("916724a5-173d-4619-b97e-b9de133dd6f5"), Text = "SYSTEM DATA: umbraco master root", NodeObjectType = Constants.ObjectTypes.SystemRoot, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -20, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,-20", SortOrder = 0, UniqueId = new Guid("0F582A79-1E41-4CF0-BFA0-76340651891A"), Text = "Recycle Bin", NodeObjectType = Constants.ObjectTypes.ContentRecycleBin, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -21, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,-21", SortOrder = 0, UniqueId = new Guid("BF7C7CBC-952F-4518-97A2-69E9C7B33842"), Text = "Recycle Bin", NodeObjectType = Constants.ObjectTypes.MediaRecycleBin, CreateDate = DateTime.Now });
- InsertDataTypeNodeDto(Constants.DataTypes.LabelString, 35, "f0bc4bfb-b499-40d6-ba86-058885a5178c", "Label");
- InsertDataTypeNodeDto(Constants.DataTypes.LabelInt, 36, "8e7f995c-bd81-4627-9932-c40e568ec788", "Label (integer)");
- InsertDataTypeNodeDto(Constants.DataTypes.LabelBigint, 36, "930861bf-e262-4ead-a704-f99453565708", "Label (bigint)");
- InsertDataTypeNodeDto(Constants.DataTypes.LabelDateTime, 37, "0e9794eb-f9b5-4f20-a788-93acd233a7e4", "Label (datetime)");
- InsertDataTypeNodeDto(Constants.DataTypes.LabelTime, 38, "a97cec69-9b71-4c30-8b12-ec398860d7e8", "Label (time)");
- InsertDataTypeNodeDto(Constants.DataTypes.LabelDecimal, 39, "8f1ef1e1-9de4-40d3-a072-6673f631ca64", "Label (decimal)");
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -90, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-90", SortOrder = 34, UniqueId = new Guid("84c6b441-31df-4ffe-b67e-67d5bc3ae65a"), Text = "Upload", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -89, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-89", SortOrder = 33, UniqueId = new Guid("c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3"), Text = "Textarea", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -88, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-88", SortOrder = 32, UniqueId = new Guid("0cc0eba1-9960-42c9-bf9b-60e150b429ae"), Text = "Textstring", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -87, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-87", SortOrder = 4, UniqueId = new Guid("ca90c950-0aff-4e72-b976-a30b1ac57dad"), Text = "Richtext editor", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -51, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-51", SortOrder = 2, UniqueId = new Guid("2e6d3631-066e-44b8-aec4-96f09099b2b5"), Text = "Numeric", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -49, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-49", SortOrder = 2, UniqueId = new Guid("92897bc6-a5f3-4ffe-ae27-f2e7e33dda49"), Text = "True/false", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -43, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-43", SortOrder = 2, UniqueId = new Guid("fbaf13a8-4036-41f2-93a3-974f678c312a"), Text = "Checkbox list", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownSingle, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownSingle}", SortOrder = 2, UniqueId = new Guid("0b6a45e7-44ba-430d-9da5-4e46060b9e03"), Text = "Dropdown", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = new Guid("5046194e-4237-453c-a547-15db3a07c4e1"), Text = "Date Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -40, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-40", SortOrder = 2, UniqueId = new Guid("bb5f57c9-ce2b-4bb9-b697-4caca783a805"), Text = "Radiobox", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownMultiple, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownMultiple}", SortOrder = 2, UniqueId = new Guid("f38f0ac7-1d27-439c-9f3f-089cd8825a53"), Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = new Guid("0225af17-b302-49cb-9176-b9f35cab9c17"), Text = "Approved Color", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -36, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-36", SortOrder = 2, UniqueId = new Guid("e4d66c0f-b935-4200-81f0-025f7256b89a"), Text = "Date Picker with time", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultContentListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultContentListView}", SortOrder = 2, UniqueId = new Guid("C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMediaListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMediaListView}", SortOrder = 2, UniqueId = new Guid("3A0156C4-3B8C-4803-BDC1-6871FAA83FFF"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Media", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMembersListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMembersListView}", SortOrder = 2, UniqueId = new Guid("AA2C52A0-CE87-4E65-A47C-7DF09358585D"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Members", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ InsertDataTypeNodeDto(Constants.DataTypes.LabelString, 35, Constants.DataTypes.Guids.LabelString, "Label (string)");
+ InsertDataTypeNodeDto(Constants.DataTypes.LabelInt, 36, Constants.DataTypes.Guids.LabelInt, "Label (integer)");
+ InsertDataTypeNodeDto(Constants.DataTypes.LabelBigint, 36, Constants.DataTypes.Guids.LabelBigInt, "Label (bigint)");
+ InsertDataTypeNodeDto(Constants.DataTypes.LabelDateTime, 37, Constants.DataTypes.Guids.LabelDateTime, "Label (datetime)");
+ InsertDataTypeNodeDto(Constants.DataTypes.LabelTime, 38, Constants.DataTypes.Guids.LabelTime, "Label (time)");
+ InsertDataTypeNodeDto(Constants.DataTypes.LabelDecimal, 39, Constants.DataTypes.Guids.LabelDecimal, "Label (decimal)");
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Upload, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Upload}", SortOrder = 34, UniqueId = Constants.DataTypes.Guids.UploadGuid, Text = "Upload", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textarea, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textarea}", SortOrder = 33, UniqueId = Constants.DataTypes.Guids.TextareaGuid, Text = "Textarea", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textbox, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textbox}", SortOrder = 32, UniqueId = Constants.DataTypes.Guids.TextstringGuid, Text = "Textstring", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.RichtextEditor, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.RichtextEditor}", SortOrder = 4, UniqueId = Constants.DataTypes.Guids.RichtextEditorGuid, Text = "Richtext editor", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -51, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-51", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.NumericGuid, Text = "Numeric", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Boolean, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Boolean}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.CheckboxGuid, Text = "True/false", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -43, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-43", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.CheckboxListGuid, Text = "Checkbox list", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownSingle, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownSingle}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DropdownGuid, Text = "Dropdown", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DatePickerGuid, Text = "Date Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -40, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-40", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.RadioboxGuid, Text = "Radiobox", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownMultiple, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownMultiple}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DropdownMultipleGuid, Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ApprovedColorGuid, Text = "Approved Color", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DateTime, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DateTime}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DatePickerWithTimeGuid, Text = "Date Picker with time", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultContentListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultContentListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewContentGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMediaListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMediaListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewMediaGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Media", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMembersListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMembersListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewMembersGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Members", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1031, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1031", SortOrder = 2, UniqueId = new Guid("f38bd2d7-65d0-48e6-95dc-87ce06ec2d3d"), Text = Constants.Conventions.MediaTypes.Folder, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1032, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1032", SortOrder = 2, UniqueId = new Guid("cc07b313-0843-4aa8-bbda-871c8da728c8"), Text = Constants.Conventions.MediaTypes.Image, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1033, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1033", SortOrder = 2, UniqueId = new Guid("4c52d8ab-54e6-40cd-999c-7a5f24903e4d"), Text = Constants.Conventions.MediaTypes.File, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1041, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1041", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
- _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1043, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1043", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Tags, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Tags}", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
+ _database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.ImageCropper, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.ImageCropper}", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.DefaultAlias, NodeObjectType = Constants.ObjectTypes.MemberType, CreateDate = DateTime.Now });
//New UDI pickers with newer Ids
@@ -155,10 +155,10 @@ namespace Umbraco.Core.Migrations.Install
private void CreateContentTypeData()
{
- _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = "icon-folder", Thumbnail = "icon-folder", IsContainer = false, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
- _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture", AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
- _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document", AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
- _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = "icon-user", Thumbnail = "icon-user", Variations = (byte) ContentVariation.Nothing });
+ _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = Constants.Icons.MediaFolder, Thumbnail = Constants.Icons.MediaFolder, IsContainer = false, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
+ _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = Constants.Icons.MediaImage, Thumbnail = Constants.Icons.MediaImage, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
+ _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = Constants.Icons.MediaFile, Thumbnail = Constants.Icons.MediaFile, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
+ _database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = Constants.Icons.Member, Thumbnail = Constants.Icons.Member, Variations = (byte) ContentVariation.Nothing });
}
private void CreateUserData()
@@ -210,19 +210,19 @@ namespace Umbraco.Core.Migrations.Install
private void CreatePropertyTypeData()
{
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = 1043, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = Constants.DataTypes.ImageCropper, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 7, UniqueId = 7.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Width, Name = "Width", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 8, UniqueId = 8.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Height, Name = "Height", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 9, UniqueId = 9.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 10, UniqueId = 10.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = -90, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = Constants.DataTypes.Upload, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 25, UniqueId = 25.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 26, UniqueId = 26.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing });
//membership property types
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = -89, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = Constants.DataTypes.Textarea, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 29, UniqueId = 29.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.FailedPasswordAttempts, Name = Constants.Conventions.Member.FailedPasswordAttemptsLabel, SortOrder = 1, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 30, UniqueId = 30.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsApproved, Name = Constants.Conventions.Member.IsApprovedLabel, SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
- _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 31, UniqueId = 31.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsLockedOut, Name = Constants.Conventions.Member.IsLockedOutLabel, SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 30, UniqueId = 30.ToGuid(), DataTypeId = Constants.DataTypes.Boolean, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsApproved, Name = Constants.Conventions.Member.IsApprovedLabel, SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
+ _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 31, UniqueId = 31.ToGuid(), DataTypeId = Constants.DataTypes.Boolean, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsLockedOut, Name = Constants.Conventions.Member.IsLockedOutLabel, SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 32, UniqueId = 32.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLockoutDate, Name = Constants.Conventions.Member.LastLockoutDateLabel, SortOrder = 4, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 33, UniqueId = 33.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLoginDate, Name = Constants.Conventions.Member.LastLoginDateLabel, SortOrder = 5, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 34, UniqueId = 34.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastPasswordChangeDate, Name = Constants.Conventions.Member.LastPasswordChangeDateLabel, SortOrder = 6, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
@@ -266,30 +266,30 @@ namespace Umbraco.Core.Migrations.Install
const string layouts = "[" + cardLayout + "," + listLayout + "]";
// TODO: Check which of the DataTypeIds below doesn't exist in umbracoNode, which results in a foreign key constraint errors.
- _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -49, EditorAlias = Constants.PropertyEditors.Aliases.Boolean, DbType = "Integer" });
+ _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Boolean, EditorAlias = Constants.PropertyEditors.Aliases.Boolean, DbType = "Integer" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -51, EditorAlias = Constants.PropertyEditors.Aliases.Integer, DbType = "Integer" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -87, EditorAlias = Constants.PropertyEditors.Aliases.TinyMce, DbType = "Ntext",
Configuration = "{\"value\":\",code,undo,redo,cut,copy,mcepasteword,stylepicker,bold,italic,bullist,numlist,outdent,indent,mcelink,unlink,mceinsertanchor,mceimage,umbracomacro,mceinserttable,umbracoembed,mcecharmap,|1|1,2,3,|0|500,400|1049,|true|\"}" });
- _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -88, EditorAlias = Constants.PropertyEditors.Aliases.TextBox, DbType = "Nvarchar" });
- _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -89, EditorAlias = Constants.PropertyEditors.Aliases.TextArea, DbType = "Ntext" });
- _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -90, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar" });
+ _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Textbox, EditorAlias = Constants.PropertyEditors.Aliases.TextBox, DbType = "Nvarchar" });
+ _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Textarea, EditorAlias = Constants.PropertyEditors.Aliases.TextArea, DbType = "Ntext" });
+ _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Upload, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar" });
InsertDataTypeDto(Constants.DataTypes.LabelString, Constants.PropertyEditors.Aliases.Label, "Nvarchar", "{\"umbracoDataValueType\":\"STRING\"}");
InsertDataTypeDto(Constants.DataTypes.LabelInt, Constants.PropertyEditors.Aliases.Label, "Integer", "{\"umbracoDataValueType\":\"INT\"}");
InsertDataTypeDto(Constants.DataTypes.LabelBigint, Constants.PropertyEditors.Aliases.Label, "Nvarchar", "{\"umbracoDataValueType\":\"BIGINT\"}");
InsertDataTypeDto(Constants.DataTypes.LabelDateTime, Constants.PropertyEditors.Aliases.Label, "Date", "{\"umbracoDataValueType\":\"DATETIME\"}");
InsertDataTypeDto(Constants.DataTypes.LabelDecimal, Constants.PropertyEditors.Aliases.Label, "Decimal", "{\"umbracoDataValueType\":\"DECIMAL\"}");
InsertDataTypeDto(Constants.DataTypes.LabelTime, Constants.PropertyEditors.Aliases.Label, "Date", "{\"umbracoDataValueType\":\"TIME\"}");
- _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -36, EditorAlias = Constants.PropertyEditors.Aliases.DateTime, DbType = "Date" });
+ _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DateTime, EditorAlias = Constants.PropertyEditors.Aliases.DateTime, DbType = "Date" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -37, EditorAlias = Constants.PropertyEditors.Aliases.ColorPicker, DbType = "Nvarchar" });
InsertDataTypeDto(Constants.DataTypes.DropDownSingle, Constants.PropertyEditors.Aliases.DropDownListFlexible, "Nvarchar", "{\"multiple\":false}");
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -40, EditorAlias = Constants.PropertyEditors.Aliases.RadioButtonList, DbType = "Nvarchar" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -41, EditorAlias = "Umbraco.DateTime", DbType = "Date", Configuration = "{\"format\":\"YYYY-MM-DD\"}" });
InsertDataTypeDto(Constants.DataTypes.DropDownMultiple, Constants.PropertyEditors.Aliases.DropDownListFlexible, "Nvarchar", "{\"multiple\":true}");
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -43, EditorAlias = Constants.PropertyEditors.Aliases.CheckBoxList, DbType = "Nvarchar" });
- _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1041, EditorAlias = Constants.PropertyEditors.Aliases.Tags, DbType = "Ntext",
+ _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Tags, EditorAlias = Constants.PropertyEditors.Aliases.Tags, DbType = "Ntext",
Configuration = "{\"group\":\"default\", \"storageType\":\"Json\"}"
});
- _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1043, EditorAlias = Constants.PropertyEditors.Aliases.ImageCropper, DbType = "Ntext" });
+ _database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.ImageCropper, EditorAlias = Constants.PropertyEditors.Aliases.ImageCropper, DbType = "Ntext" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultContentListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar",
Configuration = "{\"pageSize\":100, \"orderBy\":\"updateDate\", \"orderDirection\":\"desc\", \"layouts\":" + layouts + ", \"includeProperties\":[{\"alias\":\"updateDate\",\"header\":\"Last edited\",\"isSystem\":1},{\"alias\":\"owner\",\"header\":\"Updated by\",\"isSystem\":1}]}" });
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultMediaListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar",
diff --git a/src/Umbraco.Core/Migrations/MigrationContext.cs b/src/Umbraco.Core/Migrations/MigrationContext.cs
index a8d052036c..0bb2bc11ae 100644
--- a/src/Umbraco.Core/Migrations/MigrationContext.cs
+++ b/src/Umbraco.Core/Migrations/MigrationContext.cs
@@ -41,6 +41,7 @@ namespace Umbraco.Core.Migrations
public void AddPostMigration()
where TMigration : IMigration
{
+ // just adding - will be de-duplicated when executing
PostMigrations.Add(typeof(TMigration));
}
}
diff --git a/src/Umbraco.Core/Migrations/MigrationExpressionBase.cs b/src/Umbraco.Core/Migrations/MigrationExpressionBase.cs
index 8b5d9cc78c..be06a32ec7 100644
--- a/src/Umbraco.Core/Migrations/MigrationExpressionBase.cs
+++ b/src/Umbraco.Core/Migrations/MigrationExpressionBase.cs
@@ -92,6 +92,7 @@ namespace Umbraco.Core.Migrations
if (_executed)
throw new InvalidOperationException("This expression has already been executed.");
_executed = true;
+ Context.BuildingExpression = false;
if (sql == null)
{
diff --git a/src/Umbraco.Core/Migrations/MigrationPlan.cs b/src/Umbraco.Core/Migrations/MigrationPlan.cs
index 4be4ae7d30..37d1a03a5a 100644
--- a/src/Umbraco.Core/Migrations/MigrationPlan.cs
+++ b/src/Umbraco.Core/Migrations/MigrationPlan.cs
@@ -240,7 +240,8 @@ namespace Umbraco.Core.Migrations
if (finalState == null)
finalState = kvp.Key;
else
- throw new Exception("Multiple final states have been detected.");
+ throw new InvalidOperationException($"Multiple final states have been detected in the plan (\"{finalState}\", \"{kvp.Key}\")."
+ + " Make sure the plan contains only one final state.");
}
// now check for loops
@@ -254,7 +255,8 @@ namespace Umbraco.Core.Migrations
while (nextTransition != null && !verified.Contains(nextTransition.SourceState))
{
if (visited.Contains(nextTransition.SourceState))
- throw new Exception("A loop has been detected.");
+ throw new InvalidOperationException($"A loop has been detected in the plan around state \"{nextTransition.SourceState}\"."
+ + " Make sure the plan does not contain circular transition paths.");
visited.Add(nextTransition.SourceState);
nextTransition = _transitions[nextTransition.TargetState];
}
@@ -264,6 +266,14 @@ namespace Umbraco.Core.Migrations
_finalState = finalState;
}
+ ///
+ /// Throws an exception when the initial state is unknown.
+ ///
+ protected virtual void ThrowOnUnknownInitialState(string state)
+ {
+ throw new InvalidOperationException($"The migration plan does not support migrating from state \"{state}\".");
+ }
+
///
/// Executes the plan.
///
@@ -287,13 +297,15 @@ namespace Umbraco.Core.Migrations
logger.Info("At {OrigState}", string.IsNullOrWhiteSpace(origState) ? "origin": origState);
if (!_transitions.TryGetValue(origState, out var transition))
- throw new Exception($"Unknown state \"{origState}\".");
+ ThrowOnUnknownInitialState(origState);
var context = new MigrationContext(scope.Database, logger);
context.PostMigrations.AddRange(_postMigrationTypes);
while (transition != null)
{
+ logger.Info("Execute {MigrationType}", transition.MigrationType.Name);
+
var migration = migrationBuilder.Build(transition.MigrationType, context);
migration.Migrate();
@@ -302,6 +314,8 @@ namespace Umbraco.Core.Migrations
logger.Info("At {OrigState}", origState);
+ // throw a raw exception here: this should never happen as the plan has
+ // been validated - this is just a paranoid safety test
if (!_transitions.TryGetValue(origState, out transition))
throw new Exception($"Unknown state \"{origState}\".");
}
@@ -322,7 +336,8 @@ namespace Umbraco.Core.Migrations
logger.Info("Done (pending scope completion).");
- // safety check
+ // safety check - again, this should never happen as the plan has been validated,
+ // and this is just a paranoid safety test
if (origState != _finalState)
throw new Exception($"Internal error, reached state {origState} which is not final state {_finalState}");
diff --git a/src/Umbraco.Core/Migrations/Upgrade/Common/CreateKeysAndIndexes.cs b/src/Umbraco.Core/Migrations/Upgrade/Common/CreateKeysAndIndexes.cs
new file mode 100644
index 0000000000..29006c8811
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/Common/CreateKeysAndIndexes.cs
@@ -0,0 +1,21 @@
+using Umbraco.Core.Migrations.Install;
+
+namespace Umbraco.Core.Migrations.Upgrade.Common
+{
+ public class CreateKeysAndIndexes : MigrationBase
+ {
+ public CreateKeysAndIndexes(IMigrationContext context)
+ : base(context)
+ { }
+
+ public override void Migrate()
+ {
+ // remove those that may already have keys
+ Delete.KeysAndIndexes(Constants.DatabaseSchema.Tables.KeyValue).Do();
+
+ // re-create *all* keys and indexes
+ foreach (var x in DatabaseSchemaCreator.OrderedTables)
+ Create.KeysAndIndexes(x).Do();
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/Common/DeleteKeysAndIndexes.cs b/src/Umbraco.Core/Migrations/Upgrade/Common/DeleteKeysAndIndexes.cs
new file mode 100644
index 0000000000..9e4af17c09
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/Common/DeleteKeysAndIndexes.cs
@@ -0,0 +1,75 @@
+namespace Umbraco.Core.Migrations.Upgrade.Common
+{
+ public class DeleteKeysAndIndexes : MigrationBase
+ {
+ public DeleteKeysAndIndexes(IMigrationContext context)
+ : base(context)
+ { }
+
+ public override void Migrate()
+ {
+ // all v7.14 tables
+ var tables = new[]
+ {
+ "cmsContent",
+ "cmsContentType",
+ "cmsContentType2ContentType",
+ "cmsContentTypeAllowedContentType",
+ "cmsContentVersion",
+ "cmsContentXml",
+ "cmsDataType",
+ "cmsDataTypePreValues",
+ "cmsDictionary",
+ "cmsDocument",
+ "cmsDocumentType",
+ "cmsLanguageText",
+ "cmsMacro",
+ "cmsMacroProperty",
+ "cmsMedia",
+ "cmsMember",
+ "cmsMember2MemberGroup",
+ "cmsMemberType",
+ "cmsPreviewXml",
+ "cmsPropertyData",
+ "cmsPropertyType",
+ "cmsPropertyTypeGroup",
+ "cmsTagRelationship",
+ "cmsTags",
+ "cmsTask",
+ "cmsTaskType",
+ "cmsTemplate",
+ "umbracoAccess",
+ "umbracoAccessRule",
+ "umbracoAudit",
+ "umbracoCacheInstruction",
+ "umbracoConsent",
+ "umbracoDomains",
+ "umbracoExternalLogin",
+ "umbracoLanguage",
+ "umbracoLock",
+ "umbracoLog",
+ "umbracoMigration",
+ "umbracoNode",
+ "umbracoRedirectUrl",
+ "umbracoRelation",
+ "umbracoRelationType",
+ "umbracoServer",
+ "umbracoUser",
+ "umbracoUser2NodeNotify",
+ "umbracoUser2UserGroup",
+ "umbracoUserGroup",
+ "umbracoUserGroup2App",
+ "umbracoUserGroup2NodePermission",
+ "umbracoUserLogin",
+ "umbracoUserStartNode",
+ };
+
+ // delete *all* keys and indexes - because of FKs
+ // on known v7 tables only
+ foreach (var table in tables)
+ Delete.KeysAndIndexes(table, false, true).Do();
+ foreach (var table in tables)
+ Delete.KeysAndIndexes(table, true, false).Do();
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
index cf06a16d31..e8fd3414ec 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
@@ -2,8 +2,7 @@
using System.Configuration;
using Semver;
using Umbraco.Core.Configuration;
-using Umbraco.Core.Migrations.Upgrade.V_7_12_0;
-using Umbraco.Core.Migrations.Upgrade.V_7_14_0;
+using Umbraco.Core.Migrations.Upgrade.Common;
using Umbraco.Core.Migrations.Upgrade.V_8_0_0;
using Umbraco.Core.Migrations.Upgrade.V_8_0_1;
using Umbraco.Core.Migrations.Upgrade.V_8_1_0;
@@ -15,6 +14,9 @@ namespace Umbraco.Core.Migrations.Upgrade
///
public class UmbracoPlan : MigrationPlan
{
+ private const string InitPrefix = "{init-";
+ private const string InitSuffix = "}";
+
///
/// Initializes a new instance of the class.
///
@@ -24,6 +26,27 @@ namespace Umbraco.Core.Migrations.Upgrade
DefinePlan();
}
+ ///
+ /// Gets the initial state corresponding to a version.
+ ///
+ private static string GetInitState(SemVersion version)
+ => InitPrefix + version + InitSuffix;
+
+ ///
+ /// Tries to extract a version from an initial state.
+ ///
+ private static bool TryGetInitStateVersion(string state, out string version)
+ {
+ if (state.StartsWith(InitPrefix) && state.EndsWith(InitSuffix))
+ {
+ version = state.TrimStart(InitPrefix).TrimEnd(InitSuffix);
+ return true;
+ }
+
+ version = null;
+ return false;
+ }
+
///
///
/// The default initial state in plans is string.Empty.
@@ -41,23 +64,37 @@ namespace Umbraco.Core.Migrations.Upgrade
if (!SemVersion.TryParse(ConfigurationManager.AppSettings[Constants.AppSettings.ConfigurationStatus], out var currentVersion))
throw new InvalidOperationException($"Could not get current version from web.config {Constants.AppSettings.ConfigurationStatus} appSetting.");
- // we currently support upgrading from 7.10.0 and later
- if (currentVersion < new SemVersion(7, 10))
- throw new InvalidOperationException($"Version {currentVersion} cannot be migrated to {UmbracoVersion.SemanticVersion}.");
-
// cannot go back in time
if (currentVersion > UmbracoVersion.SemanticVersion)
throw new InvalidOperationException($"Version {currentVersion} cannot be downgraded to {UmbracoVersion.SemanticVersion}.");
- // upgrading from version 7 => initial state is eg "{init-7.10.0}"
- // anything else is not supported - ie if 8 and above, we should have an initial state already
- if (currentVersion.Major != 7)
- throw new InvalidOperationException($"Version {currentVersion} is not supported by the migration plan.");
+ // only from 7.14.0 and above
+ var minVersion = new SemVersion(7, 14);
+ if (currentVersion < minVersion)
+ throw new InvalidOperationException($"Version {currentVersion} cannot be migrated to {UmbracoVersion.SemanticVersion}."
+ + $" Please upgrade first to at least {minVersion}.");
- return "{init-" + currentVersion + "}";
+ // Force versions between 7.14.*-7.15.* into into 7.14 initial state. Because there is no db-changes,
+ // and we don't want users to workaround my putting in version 7.14.0 them self.
+ if (minVersion <= currentVersion && currentVersion < new SemVersion(7, 16))
+ return GetInitState(minVersion);
+
+ // initial state is eg "{init-7.14.0}"
+ return GetInitState(currentVersion);
}
}
+ protected override void ThrowOnUnknownInitialState(string state)
+ {
+ if (TryGetInitStateVersion(state, out var initVersion))
+ {
+ throw new InvalidOperationException($"Version {UmbracoVersion.SemanticVersion} does not support migrating from {initVersion}."
+ + $" Please verify which versions support migrating from {initVersion}.");
+ }
+
+ base.ThrowOnUnknownInitialState(state);
+ }
+
// define the plan
protected void DefinePlan()
{
@@ -70,21 +107,23 @@ namespace Umbraco.Core.Migrations.Upgrade
//
// If the new migration causes a merge conflict, because someone else also added another
// new migration, you NEED to fix the conflict by providing one default path, and paths
- // out of the conflict states (see example below).
+ // out of the conflict states (see examples below).
//
// * Porting from version 7:
// Append the ported migration to the main chain, using a new guid (same as above).
- // Create a new special chain from the {init-...} state to the main chain (see example
- // below).
+ // Create a new special chain from the {init-...} state to the main chain.
- // plan starts at 7.10.0 (anything before 7.10.0 is not supported)
- // upgrades from 7 to 8, and then takes care of all eventual upgrades
+ // plan starts at 7.14.0 (anything before 7.14.0 is not supported)
//
- From("{init-7.10.0}");
+ From(GetInitState(new SemVersion(7, 14, 0)));
+
+ // begin migrating from v7 - remove all keys and indexes
+ To("{B36B9ABD-374E-465B-9C5F-26AB0D39326F}");
+
To("{7C447271-CA3F-4A6A-A913-5D77015655CB}");
To("{CBFF58A2-7B50-4F75-8E98-249920DB0F37}");
- To("{3D18920C-E84D-405C-A06A-B7CEE52FE5DD}");
+ To("{5CB66059-45F4-48BA-BCBD-C5035D79206B}");
To("{FB0A5429-587E-4BD0-8A67-20F0E7E62FF7}");
To("{F0C42457-6A3B-4912-A7EA-F27ED85A2092}");
To("{8640C9E4-A1C0-4C59-99BB-609B4E604981}");
@@ -95,91 +134,55 @@ namespace Umbraco.Core.Migrations.Upgrade
ToWithReplace("{941B2ABA-2D06-4E04-81F5-74224F1DB037}", "{76DF5CD7-A884-41A5-8DC6-7860D95B1DF5}"); // kill AddVariationTable1
To("{A7540C58-171D-462A-91C5-7A9AA5CB8BFD}");
- Merge().To("{3E44F712-E2E3-473A-AE49-5D7F8E67CE3F}") // shannon added that one
- .With().To("{65D6B71C-BDD5-4A2E-8D35-8896325E9151}") // stephan added that one
+ Merge()
+ .To("{3E44F712-E2E3-473A-AE49-5D7F8E67CE3F}")
+ .With()
+ .To("{65D6B71C-BDD5-4A2E-8D35-8896325E9151}")
.As("{4CACE351-C6B9-4F0C-A6BA-85A02BBD39E4}");
To("{1350617A-4930-4D61-852F-E3AA9E692173}");
- To("{39E5B1F7-A50B-437E-B768-1723AEC45B65}"); // from 7.12.0
-
- Merge()
- .To("{0541A62B-EF87-4CA2-8225-F0EB98ECCC9F}") // from 7.12.0
- .To("{EB34B5DC-BB87-4005-985E-D983EA496C38}") // from 7.12.0
- .To("{517CE9EA-36D7-472A-BF4B-A0D6FB1B8F89}") // from 7.12.0
- .To("{BBD99901-1545-40E4-8A5A-D7A675C7D2F2}") // from 7.12.0
- .With()
- .To("{CF51B39B-9B9A-4740-BB7C-EAF606A7BFBF}") // andy added that one
- .As("{8B14CEBD-EE47-4AAD-A841-93551D917F11}");
-
- ToWithReplace("{2C87AA47-D1BC-4ECB-8A73-2D8D1046C27F}", "{5F4597F4-A4E0-4AFE-90B5-6D2F896830EB}"); // merge
- ToWithReplace("{B19BF0F2-E1C6-4AEB-A146-BC559D97A2C6}", "{290C18EE-B3DE-4769-84F1-1F467F3F76DA}"); // merge
+ To("{CF51B39B-9B9A-4740-BB7C-EAF606A7BFBF}");
+ To("{5F4597F4-A4E0-4AFE-90B5-6D2F896830EB}");
+ To("{290C18EE-B3DE-4769-84F1-1F467F3F76DA}");
To("{6A2C7C1B-A9DB-4EA9-B6AB-78E7D5B722A7}");
- To("{77874C77-93E5-4488-A404-A630907CEEF0}");
To("{8804D8E8-FE62-4E3A-B8A2-C047C2118C38}");
To("{23275462-446E-44C7-8C2C-3B8C1127B07D}");
To("{6B251841-3069-4AD5-8AE9-861F9523E8DA}");
To("{EE429F1B-9B26-43CA-89F8-A86017C809A3}");
To("{08919C4B-B431-449C-90EC-2B8445B5C6B1}");
To("{7EB0254C-CB8B-4C75-B15B-D48C55B449EB}");
- To("{648A2D5F-7467-48F8-B309-E99CEEE00E2A}"); // fixed version
To("{C39BF2A7-1454-4047-BBFE-89E40F66ED63}");
To("{64EBCE53-E1F0-463A-B40B-E98EFCCA8AE2}");
To("{0009109C-A0B8-4F3F-8FEB-C137BBDDA268}");
- To("{8A027815-D5CD-4872-8B88-9A51AB5986A6}"); // from 7.14.0
To("{ED28B66A-E248-4D94-8CDB-9BDF574023F0}");
To("{38C809D5-6C34-426B-9BEA-EFD39162595C}");
To("{6017F044-8E70-4E10-B2A3-336949692ADD}");
- To("{98339BEF-E4B2-48A8-B9D1-D173DC842BBE}");
Merge()
.To("{CDBEDEE4-9496-4903-9CF2-4104E00FF960}")
.With()
- .To("{940FD19A-00A8-4D5C-B8FF-939143585726}")
+ .To("{940FD19A-00A8-4D5C-B8FF-939143585726}")
.As("{0576E786-5C30-4000-B969-302B61E90CA3}");
+ To("{48AD6CCD-C7A4-4305-A8AB-38728AD23FC5}");
+
+ // finish migrating from v7 - recreate all keys and indexes
+ To("{3F9764F5-73D0-4D45-8804-1240A66E43A2}");
+
To("{E0CBE54D-A84F-4A8F-9B13-900945FD7ED9}");
To("{78BAF571-90D0-4D28-8175-EF96316DA789}");
+ // release-8.0.0
+
+ // to 8.0.1...
To("{80C0A0CB-0DD5-4573-B000-C4B7C313C70D}");
+ // release-8.0.1
+
+ // to 8.1.0...
To("{B69B6E8C-A769-4044-A27E-4A4E18D1645A}");
+ To("{0372A42B-DECF-498D-B4D1-6379E907EB94}");
+ To("{5B1E0D93-F5A3-449B-84BA-65366B84E2D4}");
//FINAL
-
-
-
-
- // and then, need to support upgrading from more recent 7.x
- //
- From("{init-7.10.1}").To("{init-7.10.0}"); // same as 7.10.0
- From("{init-7.10.2}").To("{init-7.10.0}"); // same as 7.10.0
- From("{init-7.10.3}").To("{init-7.10.0}"); // same as 7.10.0
- From("{init-7.10.4}").To("{init-7.10.0}"); // same as 7.10.0
- From("{init-7.10.5}").To("{init-7.10.0}"); // same as 7.10.0
- From("{init-7.11.0}").To("{init-7.10.0}"); // same as 7.10.0
- From("{init-7.11.1}").To("{init-7.10.0}"); // same as 7.10.0
- From("{init-7.11.2}").To("{init-7.10.0}"); // same as 7.10.0
-
- // 7.12.0 has migrations, define a custom chain which copies the chain
- // going from {init-7.10.0} to former final (1350617A) , and then goes straight to
- // main chain, skipping the migrations
- //
- From("{init-7.12.0}");
- // clone start / clone stop / target
- ToWithClone("{init-7.10.0}", "{1350617A-4930-4D61-852F-E3AA9E692173}", "{BBD99901-1545-40E4-8A5A-D7A675C7D2F2}");
-
- From("{init-7.12.1}").To("{init-7.10.0}"); // same as 7.12.0
- From("{init-7.12.2}").To("{init-7.10.0}"); // same as 7.12.0
- From("{init-7.12.3}").To("{init-7.10.0}"); // same as 7.12.0
- From("{init-7.12.4}").To("{init-7.10.0}"); // same as 7.12.0
- From("{init-7.13.0}").To("{init-7.10.0}"); // same as 7.12.0
- From("{init-7.13.1}").To("{init-7.10.0}"); // same as 7.12.0
-
- // 7.14.0 has migrations, handle it...
- // clone going from 7.10 to 1350617A (the last one before we started to merge 7.12 migrations), then
- // clone going from CF51B39B (after 7.12 migrations) to 0009109C (the last one before we started to merge 7.12 migrations),
- // ending in 8A027815 (after 7.14 migrations)
- From("{init-7.14.0}")
- .ToWithClone("{init-7.10.0}", "{1350617A-4930-4D61-852F-E3AA9E692173}", "{9109B8AF-6B34-46EE-9484-7434196D0C79}")
- .ToWithClone("{CF51B39B-9B9A-4740-BB7C-EAF606A7BFBF}", "{0009109C-A0B8-4F3F-8FEB-C137BBDDA268}", "{8A027815-D5CD-4872-8B88-9A51AB5986A6}");
}
}
}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_10_0/RenamePreviewFolder.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_10_0/RenamePreviewFolder.cs
deleted file mode 100644
index 48e6d0085d..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_10_0/RenamePreviewFolder.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.IO;
-using Umbraco.Core.IO;
-using File = System.IO.File;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_10_0
-{
- ///
- /// Renames the preview folder containing static HTML files to ensure it does not interfere with the MVC route
- /// that is now supposed to render these views dynamically. We don't want to delete as people may have made
- /// customizations to these files that would need to be migrated to the new .cshtml view files.
- ///
- public class RenamePreviewFolder : MigrationBase
- {
- public RenamePreviewFolder(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var previewFolderPath = IOHelper.MapPath(SystemDirectories.Umbraco + "/preview");
- if (Directory.Exists(previewFolderPath))
- {
- var newPath = previewFolderPath.Replace("preview", "preview.old");
- if (Directory.Exists(newPath) == false)
- {
- Directory.Move(previewFolderPath, newPath);
- var readmeText =
- $"Static HTML files used for preview and canvas editing functionality no longer live in this directory.\r\n" +
- $"Instead they have been recreated as MVC views and can now be found in '~/Umbraco/Views/Preview'.\r\n" +
- $"See issue: http://issues.umbraco.org/issue/U4-11090";
- File.WriteAllText(Path.Combine(newPath, "readme.txt"), readmeText);
- }
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/AddRelationTypeForMediaFolderOnDelete.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/AddRelationTypeForMediaFolderOnDelete.cs
deleted file mode 100644
index f34ed9fb68..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/AddRelationTypeForMediaFolderOnDelete.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
-{
- public class AddRelationTypeForMediaFolderOnDelete : MigrationBase
- {
-
- public AddRelationTypeForMediaFolderOnDelete(IMigrationContext context) : base(context)
- {
- }
-
- public override void Migrate()
- {
- var relationTypeCount = Context.Database.ExecuteScalar("SELECT COUNT(*) FROM umbracoRelationType WHERE alias=@alias",
- new { alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias });
-
- if (relationTypeCount > 0)
- return;
-
- var uniqueId = (Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias + "____" + Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName).ToGuid();
- Insert.IntoTable("umbracoRelationType").Row(new
- {
- typeUniqueId = uniqueId,
- alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias,
- name = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName,
- childObjectType = Constants.ObjectTypes.MediaType,
- parentObjectType = Constants.ObjectTypes.MediaType,
- dual = false
- }).Do();
- }
-
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/IncreaseLanguageIsoCodeColumnLength.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/IncreaseLanguageIsoCodeColumnLength.cs
deleted file mode 100644
index fc7a21f4fa..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/IncreaseLanguageIsoCodeColumnLength.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.DatabaseModelDefinitions;
-using Umbraco.Core.Persistence.SqlSyntax;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
-{
- public class IncreaseLanguageIsoCodeColumnLength : MigrationBase
- {
- public IncreaseLanguageIsoCodeColumnLength(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- // Some people seem to have a constraint in their DB instead of an index, we'd need to drop that one
- // See: https://our.umbraco.com/forum/using-umbraco-and-getting-started/93282-upgrade-from-711-to-712-fails
- var constraints = SqlSyntax.GetConstraintsPerTable(Context.Database).Distinct().ToArray();
- if (constraints.Any(x => x.Item2.InvariantEquals("IX_umbracoLanguage_languageISOCode")))
- {
- Delete.UniqueConstraint("IX_umbracoLanguage_languageISOCode").FromTable("umbracoLanguage").Do();
- }
-
- //Now check for indexes of that name and drop that if it exists
- var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
- if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoLanguage_languageISOCode")))
- {
- Delete.Index("IX_umbracoLanguage_languageISOCode").OnTable("umbracoLanguage").Do();
- }
-
- Alter.Table("umbracoLanguage")
- .AlterColumn("languageISOCode")
- .AsString(14)
- .Nullable()
- .Do();
-
- Create.Index("IX_umbracoLanguage_languageISOCode")
- .OnTable("umbracoLanguage")
- .OnColumn("languageISOCode")
- .Ascending()
- .WithOptions()
- .Unique()
- .Do();
- }
-
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/RenameTrueFalseField.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/RenameTrueFalseField.cs
deleted file mode 100644
index 4022739ece..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/RenameTrueFalseField.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using Umbraco.Core.Logging;
-using Umbraco.Core.Persistence.Dtos;
-using Umbraco.Core.Persistence.SqlSyntax;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
-{
- public class RenameTrueFalseField : MigrationBase
- {
- public RenameTrueFalseField(IMigrationContext context) : base(context)
- {
- }
-
- public override void Migrate()
- {
- //rename the existing true/false field
- Update.Table(NodeDto.TableName).Set(new { text = "Checkbox" }).Where(new { id = Constants.DataTypes.Boolean }).Do();
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/SetDefaultTagsStorageType.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/SetDefaultTagsStorageType.cs
deleted file mode 100644
index c8d65961f4..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/SetDefaultTagsStorageType.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using Umbraco.Core.Models;
-using Umbraco.Core.Persistence;
-using Umbraco.Core.Persistence.Dtos;
-using Umbraco.Core.PropertyEditors;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
-{
- ///
- /// Set the default storageType for the tags datatype to "CSV" to ensure backwards compatibility since the default is going to be JSON in new versions.
- ///
- public class SetDefaultTagsStorageType : MigrationBase
- {
- public SetDefaultTagsStorageType(IMigrationContext context)
- : base(context)
- { }
-
- // dummy editor for deserialization
- private class TagConfigurationEditor : ConfigurationEditor
- { }
-
- public override void Migrate()
- {
- // get all Umbraco.Tags datatypes
- var dataTypeDtos = Database.Fetch(Context.SqlContext.Sql()
- .Select()
- .From()
- .Where(x => x.EditorAlias == Constants.PropertyEditors.Aliases.Tags));
-
- // get a dummy editor for deserialization
- var editor = new TagConfigurationEditor();
-
- foreach (var dataTypeDto in dataTypeDtos)
- {
- // need to check storageType on raw dictionary, as TagConfiguration would have a default value
- var dictionary = JsonConvert.DeserializeObject(dataTypeDto.Configuration);
-
- // if missing, use TagConfiguration to properly update the configuration
- // due to ... reasons ... the key can start with a lower or upper 'S'
- if (!dictionary.ContainsKey("storageType") && !dictionary.ContainsKey("StorageType"))
- {
- var configuration = (TagConfiguration)editor.FromDatabase(dataTypeDto.Configuration);
- configuration.StorageType = TagsStorageType.Csv;
- dataTypeDto.Configuration = ConfigurationEditor.ToDatabase(configuration);
- Database.Update(dataTypeDto);
- }
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/UpdateUmbracoConsent.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/UpdateUmbracoConsent.cs
deleted file mode 100644
index 7596e3d7dd..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_12_0/UpdateUmbracoConsent.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
-{
public class UpdateUmbracoConsent : MigrationBase
{
- public UpdateUmbracoConsent(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
{
Alter.Table(Constants.DatabaseSchema.Tables.Consent).AlterColumn("comment").AsString().Nullable().Do();
}
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_14_0/UpdateMemberGroupPickerData.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_14_0/UpdateMemberGroupPickerData.cs
deleted file mode 100644
index c70f42076f..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_14_0/UpdateMemberGroupPickerData.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-namespace Umbraco.Core.Migrations.Upgrade.V_7_14_0
-{
- ///
- /// Migrates member group picker properties from NVarchar to NText. See https://github.com/umbraco/Umbraco-CMS/issues/3268.
- ///
- public class UpdateMemberGroupPickerData : MigrationBase
- {
- ///
- /// Migrates member group picker properties from NVarchar to NText. See https://github.com/umbraco/Umbraco-CMS/issues/3268.
- ///
- public UpdateMemberGroupPickerData(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- Database.Execute($@"UPDATE umbracoPropertyData SET textValue = varcharValue, varcharValue = NULL
- WHERE textValue IS NULL AND id IN (
- SELECT id FROM umbracoPropertyData WHERE propertyTypeId in (
- SELECT id from cmsPropertyType where dataTypeId IN (
- SELECT nodeId FROM umbracoDataType WHERE propertyEditorAlias = '{Constants.PropertyEditors.Aliases.MemberGroupPicker}'
- )
- )
- )");
-
- Database.Execute($"UPDATE umbracoDataType SET dbType = 'Ntext' WHERE propertyEditorAlias = '{Constants.PropertyEditors.Aliases.MemberGroupPicker}'");
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/AddRedirectUrlTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/AddRedirectUrlTable.cs
deleted file mode 100644
index 7040874a74..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/AddRedirectUrlTable.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System.Linq;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_5_0
-{
- public class AddRedirectUrlTable : MigrationBase
- {
- public AddRedirectUrlTable(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var database = Database;
- var umbracoRedirectUrlTableName = "umbracoRedirectUrl";
-
- var tables = SqlSyntax.GetTablesInSchema(database).ToArray();
-
- if (tables.InvariantContains(umbracoRedirectUrlTableName))
- {
- var columns = SqlSyntax.GetColumnsInSchema(database).ToArray();
- if (columns.Any(x => x.TableName.InvariantEquals(umbracoRedirectUrlTableName) && x.ColumnName.InvariantEquals("id") && x.DataType == "uniqueidentifier"))
- return;
- Delete.Table(umbracoRedirectUrlTableName).Do();
- }
-
- Create.Table(umbracoRedirectUrlTableName)
- .WithColumn("id").AsGuid().NotNullable().PrimaryKey("PK_" + umbracoRedirectUrlTableName)
- .WithColumn("createDateUtc").AsDateTime().NotNullable()
- .WithColumn("url").AsString(2048).NotNullable()
- .WithColumn("contentKey").AsGuid().NotNullable()
- .WithColumn("urlHash").AsString(40).NotNullable()
- .Do();
-
- Create.Index("IX_" + umbracoRedirectUrlTableName).OnTable(umbracoRedirectUrlTableName)
- .OnColumn("urlHash")
- .Ascending()
- .OnColumn("contentKey")
- .Ascending()
- .OnColumn("createDateUtc")
- .Descending()
- .WithOptions().NonClustered()
- .Do();
-
- Create.ForeignKey("FK_" + umbracoRedirectUrlTableName)
- .FromTable(umbracoRedirectUrlTableName).ForeignColumn("contentKey")
- .ToTable("umbracoNode").PrimaryColumn("uniqueID")
- .Do();
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/RemoveStylesheetDataAndTablesAgain.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/RemoveStylesheetDataAndTablesAgain.cs
deleted file mode 100644
index d27ed11a21..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/RemoveStylesheetDataAndTablesAgain.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-using System.Linq;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_5_0
-{
- ///
- /// This is here to re-remove these tables, we dropped them in 7.3 but new installs created them again so we're going to re-drop them
- ///
- public class RemoveStylesheetDataAndTablesAgain : MigrationBase
- {
- public RemoveStylesheetDataAndTablesAgain(IMigrationContext context)
- : base(context)
- {
- }
-
- public override void Migrate()
- {
- // these have been obsoleted, need to copy the values here
- var stylesheetPropertyObjectType = new Guid("5555da4f-a123-42b2-4488-dcdfb25e4111");
- var stylesheetObjectType = new Guid("9F68DA4F-A3A8-44C2-8226-DCBD125E4840");
-
- //Clear all stylesheet data if the tables exist
- var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
- if (tables.InvariantContains("cmsStylesheetProperty"))
- {
- Delete.FromTable("cmsStylesheetProperty").AllRows().Do();
- Delete.FromTable("umbracoNode").Row(new { nodeObjectType = stylesheetPropertyObjectType }).Do();
-
- Delete.Table("cmsStylesheetProperty").Do();
- }
- if (tables.InvariantContains("cmsStylesheet"))
- {
- Delete.FromTable("cmsStylesheet").AllRows().Do();
- Delete.FromTable("umbracoNode").Row(new { nodeObjectType = stylesheetObjectType }).Do();
-
- Delete.Table("cmsStylesheet").Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/UpdateUniqueIndexOnPropertyData.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/UpdateUniqueIndexOnPropertyData.cs
deleted file mode 100644
index 8c688cfd28..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_5_0/UpdateUniqueIndexOnPropertyData.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence;
-using Umbraco.Core.Persistence.SqlSyntax;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_5_0
-{
- ///
- /// See: http://issues.umbraco.org/issue/U4-8522
- ///
- public class UpdateUniqueIndexOnPropertyData : MigrationBase
- {
- public UpdateUniqueIndexOnPropertyData(IMigrationContext context)
- : base(context)
- {
- }
-
- public override void Migrate()
- {
- //Clear all stylesheet data if the tables exist
- //tuple = tablename, indexname, columnname, unique
- var indexes = SqlSyntax.GetDefinedIndexes(Context.Database).ToArray();
- var found = indexes.FirstOrDefault(
- x => x.Item1.InvariantEquals("cmsPropertyData")
- && x.Item2.InvariantEquals("IX_cmsPropertyData_1")
- //we're searching for the old index which is not unique
- && x.Item4 == false);
-
- if (found != null)
- {
- Database.Execute("DELETE FROM cmsPropertyData WHERE id NOT IN (SELECT MIN(id) FROM cmsPropertyData GROUP BY nodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL)");
-
- //we need to re create this index
- Delete.Index("IX_cmsPropertyData_1").OnTable("cmsPropertyData").Do();
- Create.Index("IX_cmsPropertyData_1").OnTable("cmsPropertyData")
- .OnColumn("nodeId").Ascending()
- .OnColumn("versionId").Ascending()
- .OnColumn("propertytypeid").Ascending()
- .WithOptions().NonClustered()
- .WithOptions().Unique()
- .Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_5_5/UpdateAllowedMediaTypesAtRoot.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_5_5/UpdateAllowedMediaTypesAtRoot.cs
deleted file mode 100644
index 362b8e251c..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_5_5/UpdateAllowedMediaTypesAtRoot.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Umbraco.Core.Migrations.Upgrade.V_7_5_5
-{
- ///
- /// See: http://issues.umbraco.org/issue/U4-4196
- ///
- public class UpdateAllowedMediaTypesAtRoot : MigrationBase
- {
- public UpdateAllowedMediaTypesAtRoot(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- Database.Execute("UPDATE cmsContentType SET allowAtRoot = 1 WHERE nodeId = 1032 OR nodeId = 1033");
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToCmsMemberLoginName.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToCmsMemberLoginName.cs
deleted file mode 100644
index a223d76a07..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToCmsMemberLoginName.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.SqlSyntax;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- public class AddIndexToCmsMemberLoginName : MigrationBase
- {
- public AddIndexToCmsMemberLoginName(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var database = Database;
-
- //Now we need to check if we can actually d6 this because we won't be able to if there's data in there that is too long
- //http://issues.umbraco.org/issue/U4-9758
-
- var colLen = database.ExecuteScalar("select max(datalength(LoginName)) from cmsMember");
-
- if (colLen < 900 == false && colLen != null)
- {
- return;
- }
-
- var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
-
- //make sure it doesn't already exist
- if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsMember_LoginName")) == false)
- {
- //we can apply the index
- Create.Index("IX_cmsMember_LoginName").OnTable("cmsMember")
- .OnColumn("LoginName")
- .Ascending()
- .WithOptions()
- .NonClustered()
- .Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToUmbracoNodePath.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToUmbracoNodePath.cs
deleted file mode 100644
index 191f410b47..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToUmbracoNodePath.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.SqlSyntax;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- public class AddIndexToUmbracoNodePath : MigrationBase
- {
- public AddIndexToUmbracoNodePath(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
-
- //make sure it doesn't already exist
- if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodePath")) == false)
- {
- Create.Index("IX_umbracoNodePath").OnTable("umbracoNode")
- .OnColumn("path")
- .Ascending()
- .WithOptions()
- .NonClustered()
- .Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToUser2NodePermission.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToUser2NodePermission.cs
deleted file mode 100644
index 87b392b09c..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexToUser2NodePermission.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.SqlSyntax;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- public class AddIndexToUser2NodePermission : MigrationBase
- {
- public AddIndexToUser2NodePermission(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
-
- //make sure it doesn't already exist
- if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoUser2NodePermission_nodeId")) == false)
- {
- Create.Index("IX_umbracoUser2NodePermission_nodeId").OnTable("umbracoUser2NodePermission")
- .OnColumn("nodeId")
- .Ascending()
- .WithOptions()
- .NonClustered()
- .Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexesToUmbracoRelationTables.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexesToUmbracoRelationTables.cs
deleted file mode 100644
index 9042ae105e..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddIndexesToUmbracoRelationTables.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-using System;
-using System.Linq;
-using Umbraco.Core.Persistence.SqlSyntax;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- public class AddIndexesToUmbracoRelationTables : MigrationBase
- {
- public AddIndexesToUmbracoRelationTables(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database).ToArray();
-
- //make sure it doesn't already exist
- if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoRelation_parentChildType")) == false)
- {
- //This will remove any corrupt/duplicate data in the relation table before the index is applied
- //Ensure this executes in a deferred block which will be done inside of the migration transaction
- var database = Database;
-
- //We need to check if this index has corrupted data and then clear that data
- var duplicates = database.Fetch("SELECT parentId,childId,relType FROM umbracoRelation GROUP BY parentId,childId,relType HAVING COUNT(*) > 1");
- if (duplicates.Count > 0)
- {
- //need to fix this there cannot be duplicates so we'll take the latest entries, it's really not going to matter though
- foreach (var duplicate in duplicates)
- {
- var ids = database.Fetch("SELECT id FROM umbracoRelation WHERE parentId=@parentId AND childId=@childId AND relType=@relType ORDER BY datetime DESC",
- new { parentId = duplicate.parentId, childId = duplicate.childId, relType = duplicate.relType });
-
- if (ids.Count == 1)
- {
- //this is just a safety check, this should absolutely never happen
- throw new InvalidOperationException("Duplicates were detected but could not be discovered");
- }
-
- //delete the others
- ids = ids.Skip(0).ToList();
-
- //iterate in groups of 2000 to avoid the max sql parameter limit
- foreach (var idGroup in ids.InGroupsOf(2000))
- {
- database.Execute("DELETE FROM umbracoRelation WHERE id IN (@ids)", new { ids = idGroup });
- }
- }
- }
-
- //unique index to prevent duplicates - and for better perf
- Create.Index("IX_umbracoRelation_parentChildType").OnTable("umbracoRelation")
- .OnColumn("parentId").Ascending()
- .OnColumn("childId").Ascending()
- .OnColumn("relType").Ascending()
- .WithOptions()
- .Unique()
- .Do();
- }
-
- //need indexes on alias and name for relation type since these are queried against
-
- //make sure it doesn't already exist
- if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoRelationType_alias")) == false)
- {
- Create.Index("IX_umbracoRelationType_alias").OnTable("umbracoRelationType")
- .OnColumn("alias")
- .Ascending()
- .WithOptions()
- .NonClustered()
- .Do();
- }
- if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoRelationType_name")) == false)
- {
- Create.Index("IX_umbracoRelationType_name").OnTable("umbracoRelationType")
- .OnColumn("name")
- .Ascending()
- .WithOptions()
- .NonClustered()
- .Do();
- }
-
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddLockObjects.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddLockObjects.cs
deleted file mode 100644
index 2cc62cd2f9..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddLockObjects.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- public class AddLockObjects : MigrationBase
- {
- public AddLockObjects(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- EnsureLockObject(Constants.Locks.Servers, "Servers");
- }
-
- private void EnsureLockObject(int id, string name)
- {
- var db = Database;
- var exists = db.Exists(id);
- if (exists) return;
- // be safe: delete old umbracoNode lock objects if any
- db.Execute("DELETE FROM umbracoNode WHERE id=@id;", new { id });
- // then create umbracoLock object
- db.Execute("INSERT umbracoLock (id, name, value) VALUES (@id, @name, 1);", new { id, name });
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddLockTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddLockTable.cs
deleted file mode 100644
index 369bda0758..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddLockTable.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Linq;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- public class AddLockTable : MigrationBase
- {
- public AddLockTable(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
- if (tables.InvariantContains("umbracoLock") == false)
- {
- Create.Table("umbracoLock")
- .WithColumn("id").AsInt32().PrimaryKey("PK_umbracoLock")
- .WithColumn("value").AsInt32().NotNullable()
- .WithColumn("name").AsString(64).NotNullable()
- .Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddMacroUniqueIdColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddMacroUniqueIdColumn.cs
deleted file mode 100644
index 82888ab970..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddMacroUniqueIdColumn.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using System;
-using System.Linq;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- public class AddMacroUniqueIdColumn : MigrationBase
- {
- public AddMacroUniqueIdColumn(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
-
- if (columns.Any(x => x.TableName.InvariantEquals("cmsMacro") && x.ColumnName.InvariantEquals("uniqueId")) == false)
- {
- Create.Column("uniqueId").OnTable("cmsMacro").AsGuid().Nullable().Do();
- UpdateMacroGuids();
- Alter.Table("cmsMacro").AlterColumn("uniqueId").AsGuid().NotNullable().Do();
- Create.Index("IX_cmsMacro_UniqueId").OnTable("cmsMacro").OnColumn("uniqueId")
- .Ascending()
- .WithOptions().NonClustered()
- .WithOptions().Unique()
- .Do();
-
- }
-
- if (columns.Any(x => x.TableName.InvariantEquals("cmsMacroProperty") && x.ColumnName.InvariantEquals("uniquePropertyId")) == false)
- {
- Create.Column("uniquePropertyId").OnTable("cmsMacroProperty").AsGuid().Nullable().Do();
- UpdateMacroPropertyGuids();
- Alter.Table("cmsMacroProperty").AlterColumn("uniquePropertyId").AsGuid().NotNullable().Do();
- Create.Index("IX_cmsMacroProperty_UniquePropertyId").OnTable("cmsMacroProperty").OnColumn("uniquePropertyId")
- .Ascending()
- .WithOptions().NonClustered()
- .WithOptions().Unique()
- .Do();
- }
- }
-
- private void UpdateMacroGuids()
- {
- var database = Database;
-
- var updates = database.Query("SELECT id, macroAlias FROM cmsMacro")
- .Select(macro => Tuple.Create((int) macro.id, ("macro____" + (string) macro.macroAlias).ToGuid()))
- .ToList();
-
- foreach (var update in updates)
- database.Execute("UPDATE cmsMacro set uniqueId=@guid WHERE id=@id", new { guid = update.Item2, id = update.Item1 });
- }
-
- private void UpdateMacroPropertyGuids()
- {
- var database = Database;
-
- var updates = database.Query(@"SELECT cmsMacroProperty.id id, macroPropertyAlias propertyAlias, cmsMacro.macroAlias macroAlias
-FROM cmsMacroProperty
-JOIN cmsMacro ON cmsMacroProperty.macro=cmsMacro.id")
- .Select(prop => Tuple.Create((int) prop.id, ("macro____" + (string) prop.macroAlias + "____" + (string) prop.propertyAlias).ToGuid()))
- .ToList();
-
- foreach (var update in updates)
- database.Execute("UPDATE cmsMacroProperty set uniquePropertyId=@guid WHERE id=@id", new { guid = update.Item2, id = update.Item1 });
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddRelationTypeUniqueIdColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddRelationTypeUniqueIdColumn.cs
deleted file mode 100644
index e166a4582d..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/AddRelationTypeUniqueIdColumn.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System;
-using System.Linq;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- public class AddRelationTypeUniqueIdColumn : MigrationBase
- {
- public AddRelationTypeUniqueIdColumn(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
-
- if (columns.Any(x => x.TableName.InvariantEquals("umbracoRelationType") && x.ColumnName.InvariantEquals("typeUniqueId")) == false)
- {
- Create.Column("typeUniqueId").OnTable("umbracoRelationType").AsGuid().Nullable().Do();
- UpdateRelationTypeGuids();
- Alter.Table("umbracoRelationType").AlterColumn("typeUniqueId").AsGuid().NotNullable().Do();
- Create.Index("IX_umbracoRelationType_UniqueId").OnTable("umbracoRelationType").OnColumn("typeUniqueId")
- .Ascending()
- .WithOptions().NonClustered()
- .WithOptions().Unique()
- .Do();
- }
- }
-
- private void UpdateRelationTypeGuids()
- {
- var database = Database;
- var updates = database.Query("SELECT id, alias, name FROM umbracoRelationType")
- .Select(relationType => Tuple.Create((int) relationType.id, ("relationType____" + (string) relationType.alias + "____" + (string) relationType.name).ToGuid()))
- .ToList();
-
- foreach (var update in updates)
- database.Execute("UPDATE umbracoRelationType set typeUniqueId=@guid WHERE id=@id", new { guid = update.Item2, id = update.Item1 });
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/NormalizeTemplateGuids.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/NormalizeTemplateGuids.cs
deleted file mode 100644
index 9e8c739104..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/NormalizeTemplateGuids.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-using System.Linq;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- public class NormalizeTemplateGuids : MigrationBase
- {
- public NormalizeTemplateGuids(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var database = Database;
-
- // we need this migration because ppl running pre-7.6 on Cloud and Courier have templates in different
- // environments having different GUIDs (Courier does not sync template GUIDs) and we need to normalize
- // these GUIDs so templates with the same alias on different environments have the same GUID.
- // however, if already running a prerelease version of 7.6, we do NOT want to normalize the GUIDs as quite
- // probably, we are already running Deploy and the GUIDs are OK. assuming noone is running a prerelease
- // of 7.6 on Courier.
- // so... testing if we already have a 7.6.0 version installed. not pretty but...?
- //
- var version = database.FirstOrDefault("SELECT version FROM umbracoMigration WHERE name=@name ORDER BY version DESC", new { name = Constants.System.UmbracoUpgradePlanName });
- if (version != null && version.StartsWith("7.6.0")) return;
-
- var updates = database.Query(@"SELECT umbracoNode.id, cmsTemplate.alias FROM umbracoNode
-JOIN cmsTemplate ON umbracoNode.id=cmsTemplate.nodeId
-WHERE nodeObjectType = @guid", new { guid = Constants.ObjectTypes.TemplateType })
- .Select(template => Tuple.Create((int) template.id, ("template____" + (string) template.alias).ToGuid()))
- .ToList();
-
- foreach (var update in updates)
- database.Execute("UPDATE umbracoNode set uniqueId=@guid WHERE id=@id", new { guid = update.Item2, id = update.Item1 });
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/ReduceLoginNameColumnsSize.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/ReduceLoginNameColumnsSize.cs
deleted file mode 100644
index 1af21617f3..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/ReduceLoginNameColumnsSize.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.SqlSyntax;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- public class ReduceLoginNameColumnsSize : MigrationBase
- {
- public ReduceLoginNameColumnsSize(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- //Now we need to check if we can actually d6 this because we won't be able to if there's data in there that is too long
- //http://issues.umbraco.org/issue/U4-9758
-
- var database = Database;
- var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(database);
-
- var colLen = database.ExecuteScalar("select max(datalength(LoginName)) from cmsMember");
-
- if (colLen < 900 == false) return;
-
- //if an index exists on this table we need to drop it. Normally we'd check via index name but in some odd cases (i.e. Our)
- //the index name is something odd (starts with "mi_"). In any case, the index cannot exist if we want to alter the column
- //so we'll drop whatever index is there and add one with the correct name after.
- var loginNameIndex = dbIndexes.FirstOrDefault(x => x.TableName.InvariantEquals("cmsMember") && x.ColumnName.InvariantEquals("LoginName"));
- if (loginNameIndex != null)
- {
- Delete.Index(loginNameIndex.IndexName).OnTable("cmsMember").Do();
- }
-
- //we can apply the col length change
- Alter.Table("cmsMember")
- .AlterColumn("LoginName")
- .AsString(225)
- .NotNullable()
- .Do();
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/RemovePropertyDataIdIndex.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/RemovePropertyDataIdIndex.cs
deleted file mode 100644
index 804714d1ff..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/RemovePropertyDataIdIndex.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System.Linq;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- ///
- /// See: http://issues.umbraco.org/issue/U4-9188
- ///
- public class UpdateUniqueIndexOnPropertyData : MigrationBase
- {
- public UpdateUniqueIndexOnPropertyData(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- //tuple = tablename, indexname, columnname, unique
- var indexes = SqlSyntax.GetDefinedIndexes(Context.Database).ToArray();
- var found = indexes.FirstOrDefault(
- x => x.Item1.InvariantEquals("cmsPropertyData")
- && x.Item2.InvariantEquals("IX_cmsPropertyData"));
-
- if (found != null)
- {
- //drop the index
- Delete.Index("IX_cmsPropertyData").OnTable("cmsPropertyData").Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/RemoveUmbracoDeployTables.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/RemoveUmbracoDeployTables.cs
deleted file mode 100644
index 744b441b32..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_6_0/RemoveUmbracoDeployTables.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System.Linq;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
-{
- public class RemoveUmbracoDeployTables : MigrationBase
- {
- public RemoveUmbracoDeployTables(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
-
- // there are two versions of umbracoDeployDependency,
- // 1. one created by 7.4 and never used, we need to remove it (has a sourceId column)
- // 2. one created by Deploy itself, we need to keep it (has a sourceUdi column)
- if (tables.InvariantContains("umbracoDeployDependency"))
- {
- var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
- if (columns.Any(x => x.TableName.InvariantEquals("umbracoDeployDependency") && x.ColumnName.InvariantEquals("sourceId")))
- Delete.Table("umbracoDeployDependency").Do();
- }
-
- // always remove umbracoDeployChecksum
- if (tables.InvariantContains("umbracoDeployChecksum"))
- Delete.Table("umbracoDeployChecksum").Do();
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddIndexToDictionaryKeyColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddIndexToDictionaryKeyColumn.cs
deleted file mode 100644
index b366c7dab9..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddIndexToDictionaryKeyColumn.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.SqlSyntax;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
-{
- public class AddIndexToDictionaryKeyColumn : MigrationBase
- {
- public AddIndexToDictionaryKeyColumn(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var database = Database;
- //Now we need to check if we can actually do this because we won't be able to if there's data in there that is too long
- var colLen = database.ExecuteScalar(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key")));
-
- if (colLen < 900 == false && colLen != null)
- {
- return;
- }
-
- var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
-
- //make sure it doesn't already exist
- if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsDictionary_key")) == false)
- {
- //we can apply the index
- Create.Index("IX_cmsDictionary_key").OnTable("cmsDictionary")
- .OnColumn("key")
- .Ascending()
- .WithOptions()
- .NonClustered()
- .Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddUserGroupTables.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddUserGroupTables.cs
deleted file mode 100644
index edd78e6c84..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddUserGroupTables.cs
+++ /dev/null
@@ -1,357 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Linq;
-using Umbraco.Core.Persistence;
-using Umbraco.Core.Persistence.Dtos;
-using ColumnInfo = Umbraco.Core.Persistence.SqlSyntax.ColumnInfo;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
-{
- public class AddUserGroupTables : MigrationBase
- {
- private readonly string _collateSyntax;
-
- public AddUserGroupTables(IMigrationContext context)
- : base(context)
- {
- //For some of the migration data inserts we require to use a special MSSQL collate expression since
- //some databases may have a custom collation specified and if that is the case, when we compare strings
- //in dynamic SQL it will try to compare strings in different collations and this will yield errors.
- _collateSyntax = "COLLATE DATABASE_DEFAULT";
- }
-
- public override void Migrate()
- {
- var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToList();
- var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
- var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
-
- //In some very rare cases, there might already be user group tables that we'll need to remove first
- //but of course we don't want to remove the tables we will be creating below if they already exist so
- //need to do some checks first since these old rare tables have a different schema
- RemoveOldTablesIfExist(tables, columns);
-
- if (AddNewTables(tables))
- {
- MigrateUserPermissions();
- MigrateUserTypesToGroups();
- DeleteOldTables(tables, constraints);
- SetDefaultIcons();
- }
- else
- {
- //if we aren't adding the tables, make sure that the umbracoUserGroup table has the correct FKs - these
- //were added after the beta release so we need to do some cleanup
- //if the FK doesn't exist
- if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUserGroup")
- && x.Item2.InvariantEquals("startContentId")
- && x.Item3.InvariantEquals("FK_startContentId_umbracoNode_id")) == false)
- {
- //before we add any foreign key we need to make sure there's no stale data in there which would have happened in the beta
- //release if a start node was assigned and then that start node was deleted.
- Database.Execute(@"UPDATE umbracoUserGroup SET startContentId = NULL WHERE startContentId NOT IN (SELECT id FROM umbracoNode)");
-
- Create.ForeignKey("FK_startContentId_umbracoNode_id")
- .FromTable("umbracoUserGroup")
- .ForeignColumn("startContentId")
- .ToTable("umbracoNode")
- .PrimaryColumn("id")
- .OnDelete(Rule.None)
- .OnUpdate(Rule.None)
- .Do();
- }
-
- if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUserGroup")
- && x.Item2.InvariantEquals("startMediaId")
- && x.Item3.InvariantEquals("FK_startMediaId_umbracoNode_id")) == false)
- {
- //before we add any foreign key we need to make sure there's no stale data in there which would have happened in the beta
- //release if a start node was assigned and then that start node was deleted.
- Database.Execute(@"UPDATE umbracoUserGroup SET startMediaId = NULL WHERE startMediaId NOT IN (SELECT id FROM umbracoNode)");
-
- Create.ForeignKey("FK_startMediaId_umbracoNode_id")
- .FromTable("umbracoUserGroup")
- .ForeignColumn("startMediaId")
- .ToTable("umbracoNode")
- .PrimaryColumn("id")
- .OnDelete(Rule.None)
- .OnUpdate(Rule.None)
- .Do();
- }
- }
- }
-
- ///
- /// In some very rare cases, there might already be user group tables that we'll need to remove first
- /// but of course we don't want to remove the tables we will be creating below if they already exist so
- /// need to do some checks first since these old rare tables have a different schema
- ///
- ///
- ///
- private void RemoveOldTablesIfExist(List tables, ColumnInfo[] columns)
- {
- if (tables.Contains("umbracoUser2userGroup", StringComparer.InvariantCultureIgnoreCase))
- {
- //this column doesn't exist in the 7.7 schema, so if it's there, then this is a super old table
- var foundOldColumn = columns
- .FirstOrDefault(x =>
- x.ColumnName.Equals("user", StringComparison.InvariantCultureIgnoreCase)
- && x.TableName.Equals("umbracoUser2userGroup", StringComparison.InvariantCultureIgnoreCase));
- if (foundOldColumn != null)
- {
- Delete.Table("umbracoUser2userGroup").Do();
- //remove from the tables list since this will be re-checked in further logic
- tables.Remove("umbracoUser2userGroup");
- }
- }
-
- if (tables.Contains("umbracoUserGroup", StringComparer.InvariantCultureIgnoreCase))
- {
- //The new schema has several columns, the super old one for this table only had 2 so if it's 2 get rid of it
- var countOfCols = columns
- .Count(x => x.TableName.Equals("umbracoUserGroup", StringComparison.InvariantCultureIgnoreCase));
- if (countOfCols == 2)
- {
- Delete.Table("umbracoUserGroup").Do();
- //remove from the tables list since this will be re-checked in further logic
- tables.Remove("umbracoUserGroup");
- }
- }
- }
-
- private void SetDefaultIcons()
- {
- Database.Execute($"UPDATE umbracoUserGroup SET icon = \'\' WHERE userGroupAlias = \'{Constants.Security.AdminGroupAlias}\'");
- Database.Execute("UPDATE umbracoUserGroup SET icon = \'icon-edit\' WHERE userGroupAlias = \'writer\'");
- Database.Execute("UPDATE umbracoUserGroup SET icon = \'icon-tools\' WHERE userGroupAlias = \'editor\'");
- Database.Execute("UPDATE umbracoUserGroup SET icon = \'icon-globe\' WHERE userGroupAlias = \'translator\'");
- }
-
- private bool AddNewTables(List tables)
- {
- var updated = false;
- if (tables.InvariantContains("umbracoUserGroup") == false)
- {
- Create.Table().Do();
- updated = true;
- }
-
- if (tables.InvariantContains("umbracoUser2UserGroup") == false)
- {
- Create.Table().Do();
- updated = true;
- }
-
- if (tables.InvariantContains("umbracoUserGroup2App") == false)
- {
- Create.Table().Do();
- updated = true;
- }
-
- if (tables.InvariantContains("umbracoUserGroup2NodePermission") == false)
- {
- Create.Table().Do();
- updated = true;
- }
-
- return updated;
- }
-
- private void MigrateUserTypesToGroups()
- {
- // Create a user group for each user type
- Database.Execute(@"INSERT INTO umbracoUserGroup (userGroupAlias, userGroupName, userGroupDefaultPermissions)
- SELECT userTypeAlias, userTypeName, userTypeDefaultPermissions
- FROM umbracoUserType");
-
- // Add each user to the group created from their type
- Database.Execute(string.Format(@"INSERT INTO umbracoUser2UserGroup (userId, userGroupId)
- SELECT u.id, ug.id
- FROM umbracoUser u
- INNER JOIN umbracoUserType ut ON ut.id = u.userType
- INNER JOIN umbracoUserGroup ug ON ug.userGroupAlias {0} = ut.userTypeAlias {0}", _collateSyntax));
-
- // Add the built-in administrator account to all apps
- // this will lookup all of the apps that the admin currently has access to in order to assign the sections
- // instead of use statically assigning since there could be extra sections we don't know about.
- Database.Execute(@"INSERT INTO umbracoUserGroup2app (userGroupId,app)
- SELECT ug.id, app
- FROM umbracoUserGroup ug
- INNER JOIN umbracoUser2UserGroup u2ug ON u2ug.userGroupId = ug.id
- INNER JOIN umbracoUser u ON u.id = u2ug.userId
- INNER JOIN umbracoUser2app u2a ON u2a." + SqlSyntax.GetQuotedColumnName("user") + @" = u.id
- WHERE u.id = 0");
-
- // Add the default section access to the other built-in accounts
- // writer:
- Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId, app)
- SELECT ug.id, 'content' as app
- FROM umbracoUserGroup ug
- WHERE ug.userGroupAlias {0} = 'writer' {0}", _collateSyntax));
- // editor
- Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId, app)
- SELECT ug.id, 'content' as app
- FROM umbracoUserGroup ug
- WHERE ug.userGroupAlias {0} = 'editor' {0}", _collateSyntax));
- Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId, app)
- SELECT ug.id, 'media' as app
- FROM umbracoUserGroup ug
- WHERE ug.userGroupAlias {0} = 'editor' {0}", _collateSyntax));
- // translator
- Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId, app)
- SELECT ug.id, 'translation' as app
- FROM umbracoUserGroup ug
- WHERE ug.userGroupAlias {0} = 'translator' {0}", _collateSyntax));
-
- //We need to lookup all distinct combinations of section access and create a group for each distinct collection
- //and assign groups accordingly. We'll perform the lookup 'now' to then create the queued SQL migrations.
- var userAppsData = Context.Database.Query(@"SELECT u.id, u2a.app FROM umbracoUser u
- INNER JOIN umbracoUser2app u2a ON u2a." + SqlSyntax.GetQuotedColumnName("user") + @" = u.id
- ORDER BY u.id, u2a.app");
- var usersWithApps = new Dictionary>();
- foreach (var userApps in userAppsData)
- {
- if (usersWithApps.TryGetValue(userApps.id, out List apps) == false)
- {
- apps = new List {userApps.app};
- usersWithApps.Add(userApps.id, apps);
- }
- else
- {
- apps.Add(userApps.app);
- }
- }
- //At this stage we have a dictionary of users with a collection of their apps which are sorted
- //and we need to determine the unique/distinct app collections for each user to create groups with.
- //We can do this by creating a hash value of all of the app values and since they are already sorted we can get a distinct
- //collection by this hash.
- var distinctApps = usersWithApps
- .Select(x => new {appCollection = x.Value, appsHash = string.Join("", x.Value).GenerateHash()})
- .DistinctBy(x => x.appsHash)
- .ToArray();
- //Now we need to create user groups for each of these distinct app collections, and then assign the corresponding users to those groups
- for (var i = 0; i < distinctApps.Length; i++)
- {
- //create the group
- var alias = "MigratedSectionAccessGroup_" + (i + 1);
- Insert.IntoTable("umbracoUserGroup").Row(new
- {
- userGroupAlias = "MigratedSectionAccessGroup_" + (i + 1),
- userGroupName = "Migrated Section Access Group " + (i + 1)
- }).Do();
- //now assign the apps
- var distinctApp = distinctApps[i];
- foreach (var app in distinctApp.appCollection)
- {
- Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId, app)
- SELECT ug.id, '" + app + @"' as app
- FROM umbracoUserGroup ug
- WHERE ug.userGroupAlias {0} = '" + alias + "' {0}", _collateSyntax));
- }
- //now assign the corresponding users to this group
- foreach (var userWithApps in usersWithApps)
- {
- //check if this user's groups hash matches the current groups hash
- var hash = string.Join("", userWithApps.Value).GenerateHash();
- if (hash == distinctApp.appsHash)
- {
- //it matches so assign the user to this group
- Database.Execute(string.Format(@"INSERT INTO umbracoUser2UserGroup (userId, userGroupId)
- SELECT " + userWithApps.Key + @", ug.id
- FROM umbracoUserGroup ug
- WHERE ug.userGroupAlias {0} = '" + alias + "' {0}", _collateSyntax));
- }
- }
- }
-
- // Rename some groups for consistency (plural form)
- Database.Execute("UPDATE umbracoUserGroup SET userGroupName = 'Writers' WHERE userGroupAlias = 'writer'");
- Database.Execute("UPDATE umbracoUserGroup SET userGroupName = 'Translators' WHERE userGroupAlias = 'translator'");
-
- //Ensure all built in groups have a start node of -1
- Database.Execute("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'editor'");
- Database.Execute("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'editor'");
- Database.Execute("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'writer'");
- Database.Execute("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'writer'");
- Database.Execute("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'translator'");
- Database.Execute("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'translator'");
- Database.Execute("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'admin'");
- Database.Execute("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'admin'");
- }
-
- private void MigrateUserPermissions()
- {
- // Create user group records for all non-admin users that have specific permissions set
- Database.Execute(@"INSERT INTO umbracoUserGroup(userGroupAlias, userGroupName)
- SELECT 'permissionGroupFor' + userLogin, 'Migrated Permission Group for ' + userLogin
- FROM umbracoUser
- WHERE (id IN (
- SELECT userid
- FROM umbracoUser2NodePermission
- ))
- AND id > 0");
-
- // Associate those groups with the users
- Database.Execute(string.Format(@"INSERT INTO umbracoUser2UserGroup (userId, userGroupId)
- SELECT u.id, ug.id
- FROM umbracoUser u
- INNER JOIN umbracoUserGroup ug ON ug.userGroupAlias {0} = 'permissionGroupFor' + userLogin {0}", _collateSyntax));
-
- // Create node permissions on the groups
- Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2NodePermission (userGroupId,nodeId,permission)
- SELECT ug.id, nodeId, permission
- FROM umbracoUserGroup ug
- INNER JOIN umbracoUser2UserGroup u2ug ON u2ug.userGroupId = ug.id
- INNER JOIN umbracoUser u ON u.id = u2ug.userId
- INNER JOIN umbracoUser2NodePermission u2np ON u2np.userId = u.id
- WHERE ug.userGroupAlias {0} NOT IN (
- SELECT userTypeAlias {0}
- FROM umbracoUserType
- )", _collateSyntax));
-
- // Create app permissions on the groups
- Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId,app)
- SELECT ug.id, app
- FROM umbracoUserGroup ug
- INNER JOIN umbracoUser2UserGroup u2ug ON u2ug.userGroupId = ug.id
- INNER JOIN umbracoUser u ON u.id = u2ug.userId
- INNER JOIN umbracoUser2app u2a ON u2a." + SqlSyntax.GetQuotedColumnName("user") + @" = u.id
- WHERE ug.userGroupAlias {0} NOT IN (
- SELECT userTypeAlias {0}
- FROM umbracoUserType
- )", _collateSyntax));
- }
-
- private void DeleteOldTables(List tables, Tuple[] constraints)
- {
- if (tables.InvariantContains("umbracoUser2App"))
- {
- Delete.Table("umbracoUser2App").Do();
- }
-
- if (tables.InvariantContains("umbracoUser2NodePermission"))
- {
- Delete.Table("umbracoUser2NodePermission").Do();
- }
-
- if (tables.InvariantContains("umbracoUserType") && tables.InvariantContains("umbracoUser"))
- {
- //Delete the FK if it exists before dropping the column
- if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_umbracoUser_umbracoUserType_id")))
- {
- Delete.ForeignKey("FK_umbracoUser_umbracoUserType_id").OnTable("umbracoUser").Do();
- }
-
- //This is the super old constraint name of the FK for user type so check this one too
- if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_user_userType")))
- {
- Delete.ForeignKey("FK_user_userType").OnTable("umbracoUser").Do();
- }
-
- Delete.Column("userType").FromTable("umbracoUser").Do();
- Delete.Table("umbracoUserType").Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddUserStartNodeTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddUserStartNodeTable.cs
deleted file mode 100644
index 54545e06d3..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/AddUserStartNodeTable.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
-{
- public class AddUserStartNodeTable : MigrationBase
- {
- public AddUserStartNodeTable(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
-
- if (tables.InvariantContains("umbracoUserStartNode")) return;
-
- Create.Table().Do();
-
- MigrateUserStartNodes();
-
- //now remove the old columns
-
- Delete.Column("startStructureID").FromTable("umbracoUser").Do();
- Delete.Column("startMediaID").FromTable("umbracoUser").Do();
- }
-
- private void MigrateUserStartNodes()
- {
- Database.Execute(@"INSERT INTO umbracoUserStartNode (userId, startNode, startNodeType)
- SELECT id, startStructureID, 1
- FROM umbracoUser
- WHERE startStructureID IS NOT NULL AND startStructureID > 0 AND startStructureID IN (SELECT id FROM umbracoNode WHERE nodeObjectType='" + Constants.ObjectTypes.Document + "')");
-
- Database.Execute(@"INSERT INTO umbracoUserStartNode (userId, startNode, startNodeType)
- SELECT id, startMediaID, 2
- FROM umbracoUser
- WHERE startMediaID IS NOT NULL AND startMediaID > 0 AND startMediaID IN (SELECT id FROM umbracoNode WHERE nodeObjectType='" + Constants.ObjectTypes.Media + "')");
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/EnsureContentTemplatePermissions.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/EnsureContentTemplatePermissions.cs
deleted file mode 100644
index 1f7e2faf33..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/EnsureContentTemplatePermissions.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence;
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
-{
- ///
- /// Ensures the built-in user groups have the blueprint permission by default on upgrade
- ///
- public class EnsureContentTemplatePermissions : MigrationBase
- {
- public EnsureContentTemplatePermissions(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var database = Database;
- var userGroups = database.Fetch(
- Context.SqlContext.Sql().Select("*")
- .From()
- .Where(x => x.Alias == "admin" || x.Alias == "editor"));
-
- foreach (var userGroup in userGroups)
- {
- if (userGroup.DefaultPermissions.Contains('�') == false)
- {
- userGroup.DefaultPermissions += "�";
- Update.Table("umbracoUserGroup")
- .Set(new { userGroupDefaultPermissions = userGroup.DefaultPermissions })
- .Where(new { id = userGroup.Id })
- .Do();
- }
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/ReduceDictionaryKeyColumnsSize.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/ReduceDictionaryKeyColumnsSize.cs
deleted file mode 100644
index 17dd3064eb..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/ReduceDictionaryKeyColumnsSize.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.SqlSyntax;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
-{
- public class ReduceDictionaryKeyColumnsSize : MigrationBase
- {
- public ReduceDictionaryKeyColumnsSize(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- //Now we need to check if we can actually do this because we won't be able to if there's data in there that is too long
-
- var database = Database;
- var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(database);
-
- var colLen = database.ExecuteScalar(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key")));
-
- if (colLen < 900 == false) return;
-
- //if it exists we need to drop it first
- if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsDictionary_key")))
- {
- Delete.Index("IX_cmsDictionary_key").OnTable("cmsDictionary").Do();
- }
-
- //we can apply the col length change
- Alter.Table("cmsDictionary")
- .AlterColumn("key")
- .AsString(450)
- .NotNullable()
- .Do();
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/UpdateUserTables.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/UpdateUserTables.cs
deleted file mode 100644
index 509b3f91dd..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_7_0/UpdateUserTables.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System.Linq;
-using System.Web.Security;
-using Newtonsoft.Json;
-using Umbraco.Core.Persistence.DatabaseModelDefinitions;
-using Umbraco.Core.Security;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
-{
- public class UpdateUserTables : MigrationBase
- {
- public UpdateUserTables(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- //Don't execute if the column is already there
- var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
-
- if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("createDate")) == false)
- Create.Column("createDate").OnTable("umbracoUser").AsDateTime().NotNullable().WithDefault(SystemMethods.CurrentDateTime).Do();
-
- if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("updateDate")) == false)
- Create.Column("updateDate").OnTable("umbracoUser").AsDateTime().NotNullable().WithDefault(SystemMethods.CurrentDateTime).Do();
-
- if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("emailConfirmedDate")) == false)
- Create.Column("emailConfirmedDate").OnTable("umbracoUser").AsDateTime().Nullable().Do();
-
- if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("invitedDate")) == false)
- Create.Column("invitedDate").OnTable("umbracoUser").AsDateTime().Nullable().Do();
-
- if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("avatar")) == false)
- Create.Column("avatar").OnTable("umbracoUser").AsString(500).Nullable().Do();
-
- if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("passwordConfig")) == false)
- {
- Create.Column("passwordConfig").OnTable("umbracoUser").AsString(500).Nullable().Do();
- //Check if we have a known config, we only want to store config for hashing
- var membershipProvider = MembershipProviderExtensions.GetUsersMembershipProvider();
- if (membershipProvider.PasswordFormat == MembershipPasswordFormat.Hashed)
- {
- var json = JsonConvert.SerializeObject(new { hashAlgorithm = Membership.HashAlgorithmType });
- Database.Execute("UPDATE umbracoUser SET passwordConfig = '" + json + "'");
- }
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddIndexToPropertyTypeAliasColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddIndexToPropertyTypeAliasColumn.cs
deleted file mode 100644
index ddb084a609..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddIndexToPropertyTypeAliasColumn.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.SqlSyntax;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
-{
- internal class AddIndexToPropertyTypeAliasColumn : MigrationBase
- {
- public AddIndexToPropertyTypeAliasColumn(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
-
- //make sure it doesn't already exist
- if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsPropertyTypeAlias")) == false)
- {
- //we can apply the index
- Create.Index("IX_cmsPropertyTypeAlias").OnTable(Constants.DatabaseSchema.Tables.PropertyType)
- .OnColumn("Alias")
- .Ascending().WithOptions().NonClustered()
- .Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddInstructionCountColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddInstructionCountColumn.cs
deleted file mode 100644
index 0ce2c91f2e..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddInstructionCountColumn.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
-{
- internal class AddInstructionCountColumn : MigrationBase
- {
- public AddInstructionCountColumn(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
-
- if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.CacheInstruction) && x.ColumnName.InvariantEquals("instructionCount")) == false)
- AddColumn("instructionCount");
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddMediaVersionTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddMediaVersionTable.cs
deleted file mode 100644
index b4c0062770..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddMediaVersionTable.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using Umbraco.Core.Persistence;
-using Umbraco.Core.Persistence.Dtos;
-using Umbraco.Core.Persistence.Factories;
-using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
-{
- internal class AddMediaVersionTable : MigrationBase
- {
- public AddMediaVersionTable(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
-
- if (tables.InvariantContains(Constants.DatabaseSchema.Tables.MediaVersion)) return;
-
- Create.Table().Do();
- MigrateMediaPaths();
- }
-
- private void MigrateMediaPaths()
- {
- // this may not be the most efficient way to do it, compared to how it's done in v7, but this
- // migration should only run for v8 sites that are being developed, before v8 is released, so
- // no big sites and performances don't matter here - keep it simple
-
- var sql = Sql()
- .Select(x => x.VarcharValue, x => x.TextValue)
- .AndSelect(x => Alias(x.Id, "versionId"))
- .From()
- .InnerJoin().On((left, right) => left.PropertyTypeId == right.Id)
- .InnerJoin().On((left, right) => left.VersionId == right.Id)
- .InnerJoin().On((left, right) => left.NodeId == right.NodeId)
- .Where(x => x.Alias == "umbracoFile")
- .Where(x => x.NodeObjectType == Constants.ObjectTypes.Media);
-
- var paths = new List();
-
- //using QUERY = a db cursor, we won't load this all into memory first, just row by row
- foreach (var row in Database.Query(sql))
- {
- // if there's values then ensure there's a media path match and extract it
- string mediaPath = null;
- if (
- (row.varcharValue != null && ContentBaseFactory.TryMatch((string) row.varcharValue, out mediaPath))
- || (row.textValue != null && ContentBaseFactory.TryMatch((string) row.textValue, out mediaPath)))
- {
- paths.Add(new MediaVersionDto
- {
- Id = (int) row.versionId,
- Path = mediaPath
- });
- }
- }
-
- // bulk insert
- Database.BulkInsertRecords(paths);
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddTourDataUserColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddTourDataUserColumn.cs
deleted file mode 100644
index cd2678205f..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddTourDataUserColumn.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.DatabaseAnnotations;
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
-{
- internal class AddTourDataUserColumn : MigrationBase
- {
- public AddTourDataUserColumn(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
-
- if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.User) && x.ColumnName.InvariantEquals("tourData")) == false)
- AddColumn("tourData");
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddUserLoginTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddUserLoginTable.cs
deleted file mode 100644
index 7a55362072..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_8_0/AddUserLoginTable.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
-{
- internal class AddUserLoginTable : MigrationBase
- {
- public AddUserLoginTable(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
-
- if (tables.InvariantContains(Constants.DatabaseSchema.Tables.UserLogin) == false)
- {
- Create.Table().Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddIsSensitiveMemberTypeColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddIsSensitiveMemberTypeColumn.cs
deleted file mode 100644
index 2b5f481769..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddIsSensitiveMemberTypeColumn.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
-{
- internal class AddIsSensitiveMemberTypeColumn : MigrationBase
- {
- public AddIsSensitiveMemberTypeColumn(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
-
- if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.MemberPropertyType) && x.ColumnName.InvariantEquals("isSensitive")) == false)
- AddColumn("isSensitive");
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddUmbracoAuditTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddUmbracoAuditTable.cs
deleted file mode 100644
index e7880dfc73..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddUmbracoAuditTable.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
-{
- internal class AddUmbracoAuditTable : MigrationBase
- {
- public AddUmbracoAuditTable(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
-
- if (tables.InvariantContains(Constants.DatabaseSchema.Tables.AuditEntry))
- return;
-
- Create.Table().Do();
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddUmbracoConsentTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddUmbracoConsentTable.cs
deleted file mode 100644
index e3656f69ac..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/AddUmbracoConsentTable.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Linq;
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
-{
- internal class AddUmbracoConsentTable : MigrationBase
- {
- public AddUmbracoConsentTable(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
-
- if (tables.InvariantContains(Constants.DatabaseSchema.Tables.Consent))
- return;
-
- Create.Table().Do();
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/CreateSensitiveDataUserGroup.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/CreateSensitiveDataUserGroup.cs
deleted file mode 100644
index ce656aa0c1..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_7_9_0/CreateSensitiveDataUserGroup.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using Umbraco.Core.Persistence;
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
-{
- internal class CreateSensitiveDataUserGroup : MigrationBase
- {
- public CreateSensitiveDataUserGroup(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var sql = Sql()
- .SelectCount()
- .From()
- .Where(x => x.Alias == Constants.Security.SensitiveDataGroupAlias);
-
- var exists = Database.ExecuteScalar(sql) > 0;
- if (exists) return;
-
- var groupId = Database.Insert(Constants.DatabaseSchema.Tables.UserGroup, "id", new UserGroupDto { StartMediaId = -1, StartContentId = -1, Alias = Constants.Security.SensitiveDataGroupAlias, Name = "Sensitive data", DefaultPermissions = "", CreateDate = DateTime.Now, UpdateDate = DateTime.Now, Icon = "icon-lock" });
- Database.Insert(new User2UserGroupDto { UserGroupId = Convert.ToInt32(groupId), UserId = Constants.Security.SuperUserId }); // add super to sensitive data
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentNuTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentNuTable.cs
index efa54a0f59..5342755ebf 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentNuTable.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentNuTable.cs
@@ -1,6 +1,7 @@
using System.Data;
using System.Linq;
using Umbraco.Core.Persistence.DatabaseAnnotations;
+using Umbraco.Core.Persistence.Dtos;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
{
@@ -12,31 +13,10 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
public override void Migrate()
{
- var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
+ var tables = SqlSyntax.GetTablesInSchema(Context.Database);
if (tables.InvariantContains("cmsContentNu")) return;
- var textType = SqlSyntax.GetSpecialDbType(SpecialDbTypes.NTEXT);
-
- Create.Table("cmsContentNu")
- .WithColumn("nodeId").AsInt32().NotNullable()
- .WithColumn("published").AsBoolean().NotNullable()
- .WithColumn("data").AsCustom(textType).NotNullable()
- .WithColumn("rv").AsInt64().NotNullable().WithDefaultValue(0)
- .Do();
-
- Create.PrimaryKey("PK_cmsContentNu")
- .OnTable("cmsContentNu")
- .Columns(new[] { "nodeId", "published" })
- .Do();
-
- Create.ForeignKey("FK_cmsContentNu_umbracoNode_id")
- .FromTable("cmsContentNu")
- .ForeignColumn("nodeId")
- .ToTable("umbracoNode")
- .PrimaryColumn("id")
- .OnDelete(Rule.Cascade)
- .OnUpdate(Rule.None)
- .Do();
+ Create.Table(true).Do();
}
}
}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddLockTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddLockTable.cs
deleted file mode 100644
index aa14bc81c8..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddLockTable.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Linq;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
-{
- public class AddLockTable : MigrationBase
- {
- public AddLockTable(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
- if (tables.InvariantContains("umbracoLock") == false)
- {
- Create.Table("umbracoLock")
- .WithColumn("id").AsInt32().PrimaryKey("PK_umbracoLock")
- .WithColumn("value").AsInt32().NotNullable()
- .WithColumn("name").AsString(64).NotNullable()
- .Do();
- }
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddUserLoginDtoDateIndex.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddUserLoginDtoDateIndex.cs
deleted file mode 100644
index 0ccc2d93ff..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddUserLoginDtoDateIndex.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
-{
- public class AddUserLoginDtoDateIndex : MigrationBase
- {
- public AddUserLoginDtoDateIndex(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- if (!IndexExists("IX_umbracoUserLogin_lastValidatedUtc"))
- Create.Index("IX_umbracoUserLogin_lastValidatedUtc")
- .OnTable(UserLoginDto.TableName)
- .OnColumn("lastValidatedUtc")
- .Ascending()
- .WithOptions().NonClustered()
- .Do();
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddVariationTables2.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddVariationTables2.cs
index c6cad2eac1..4044b5a173 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddVariationTables2.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddVariationTables2.cs
@@ -11,8 +11,8 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
public override void Migrate()
{
- Create.Table().Do();
- Create.Table().Do();
+ Create.Table(true).Do();
+ Create.Table(true).Do();
}
}
}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/ConvertRelatedLinksToMultiUrlPicker.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/ConvertRelatedLinksToMultiUrlPicker.cs
index ed1c08f0f8..4802750f4b 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/ConvertRelatedLinksToMultiUrlPicker.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/ConvertRelatedLinksToMultiUrlPicker.cs
@@ -19,8 +19,8 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
var sqlDataTypes = Sql()
.Select()
.From()
- .Where(x => x.EditorAlias == "Umbraco.RelatedLinks"
- || x.EditorAlias == "Umbraco.RelatedLinks2");
+ .Where(x => x.EditorAlias == Constants.PropertyEditors.Legacy.Aliases.RelatedLinks
+ || x.EditorAlias == Constants.PropertyEditors.Legacy.Aliases.RelatedLinks2);
var dataTypes = Database.Fetch(sqlDataTypes);
var dataTypeIds = dataTypes.Select(x => x.NodeId).ToList();
@@ -50,10 +50,10 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
var properties = Database.Fetch(sqlPropertyData);
// Create a Multi URL Picker datatype for the converted RelatedLinks data
-
+
foreach (var property in properties)
{
- var value = property.Value.ToString();
+ var value = property.Value?.ToString();
if (string.IsNullOrWhiteSpace(value))
continue;
@@ -89,7 +89,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
Name = relatedLink.Caption,
Target = relatedLink.NewWindow ? "_blank" : null,
Udi = udi,
- // Should only have a URL if it's an external link otherwise it wil be a UDI
+ // Should only have a URL if it's an external link otherwise it wil be a UDI
Url = relatedLink.IsInternal == false ? relatedLink.Link : null
};
@@ -103,7 +103,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
Database.Update(property);
}
-
+
}
}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs
index d7180385f0..7b2daa99ef 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypeMigration.cs
@@ -1,28 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Reflection;
using Newtonsoft.Json;
-using NPoco;
-using Umbraco.Core.Migrations.Install;
+using Umbraco.Core.Composing;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Querying;
+using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
{
public class DataTypeMigration : MigrationBase
{
- public DataTypeMigration(IMigrationContext context)
+ private readonly PreValueMigratorCollection _preValueMigrators;
+ private readonly PropertyEditorCollection _propertyEditors;
+ private readonly ILogger _logger;
+
+ private static readonly ISet LegacyAliases = new HashSet()
+ {
+ Constants.PropertyEditors.Legacy.Aliases.Date,
+ Constants.PropertyEditors.Legacy.Aliases.Textbox,
+ Constants.PropertyEditors.Legacy.Aliases.ContentPicker2,
+ Constants.PropertyEditors.Legacy.Aliases.MediaPicker2,
+ Constants.PropertyEditors.Legacy.Aliases.MemberPicker2,
+ Constants.PropertyEditors.Legacy.Aliases.RelatedLinks2,
+ Constants.PropertyEditors.Legacy.Aliases.TextboxMultiple,
+ Constants.PropertyEditors.Legacy.Aliases.MultiNodeTreePicker2,
+ };
+
+ public DataTypeMigration(IMigrationContext context, PreValueMigratorCollection preValueMigrators, PropertyEditorCollection propertyEditors, ILogger logger)
: base(context)
- { }
+ {
+ _preValueMigrators = preValueMigrators;
+ _propertyEditors = propertyEditors;
+ _logger = logger;
+ }
public override void Migrate()
{
- // delete *all* keys and indexes - because of FKs
- Delete.KeysAndIndexes().Do();
-
// drop and create columns
Delete.Column("pk").FromTable("cmsDataType").Do();
@@ -31,21 +49,17 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
// create column
AddColumn(Constants.DatabaseSchema.Tables.DataType, "config");
- Execute.Sql(Sql().Update(u => u.Set(x => x.Configuration, string.Empty)).SQL).Do();
-
- // re-create *all* keys and indexes
- foreach (var x in DatabaseSchemaCreator.OrderedTables)
- Create.KeysAndIndexes(x).Do();
+ Execute.Sql(Sql().Update(u => u.Set(x => x.Configuration, string.Empty))).Do();
// renames
Execute.Sql(Sql()
.Update(u => u.Set(x => x.EditorAlias, "Umbraco.ColorPicker"))
- .Where(x => x.EditorAlias == "Umbraco.ColorPickerAlias").SQL).Do();
+ .Where(x => x.EditorAlias == "Umbraco.ColorPickerAlias")).Do();
// from preValues to configuration...
var sql = Sql()
.Select()
- .AndSelect(x => x.Alias, x => x.SortOrder, x => x.Value)
+ .AndSelect(x => x.Id, x => x.Alias, x => x.SortOrder, x => x.Value)
.From()
.InnerJoin().On((left, right) => left.NodeId == right.NodeId)
.OrderBy(x => x.NodeId)
@@ -60,43 +74,52 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
.From()
.Where(x => x.NodeId == group.Key)).First();
- var aliases = group.Select(x => x.Alias).Distinct().ToArray();
- if (aliases.Length == 1 && string.IsNullOrWhiteSpace(aliases[0]))
+ // migrate the preValues to configuration
+ var migrator = _preValueMigrators.GetMigrator(dataType.EditorAlias) ?? new DefaultPreValueMigrator();
+ var config = migrator.GetConfiguration(dataType.NodeId, dataType.EditorAlias, group.ToDictionary(x => x.Alias, x => x));
+ var json = JsonConvert.SerializeObject(config);
+
+ // validate - and kill the migration if it fails
+ var newAlias = migrator.GetNewAlias(dataType.EditorAlias);
+ if (newAlias == null)
{
- // array-based prevalues
- var values = new Dictionary { ["values"] = group.OrderBy(x => x.SortOrder).Select(x => x.Value).ToArray() };
- dataType.Configuration = JsonConvert.SerializeObject(values);
+ if (!LegacyAliases.Contains(dataType.EditorAlias))
+ {
+ _logger.Warn(
+ "Skipping validation of configuration for data type {NodeId} : {EditorAlias}."
+ + " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
+ dataType.NodeId, dataType.EditorAlias);
+ }
+ }
+ else if (!_propertyEditors.TryGet(newAlias, out var propertyEditor))
+ {
+ if (!LegacyAliases.Contains(newAlias))
+ {
+ _logger.Warn("Skipping validation of configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})"
+ + " because no property editor with that alias was found."
+ + " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
+ dataType.NodeId, newAlias, dataType.EditorAlias);
+ }
}
else
{
- // assuming we don't want to fall back to array
- if (aliases.Length != group.Count() || aliases.Any(string.IsNullOrWhiteSpace))
- throw new InvalidOperationException($"Cannot migrate datatype w/ id={dataType.NodeId} preValues: duplicate or null/empty alias.");
-
- // dictionary-base prevalues
- var values = group.ToDictionary(x => x.Alias, x => x.Value);
- dataType.Configuration = JsonConvert.SerializeObject(values);
+ var configEditor = propertyEditor.GetConfigurationEditor();
+ try
+ {
+ var _ = configEditor.FromDatabase(json);
+ }
+ catch (Exception e)
+ {
+ _logger.Warn(e, "Failed to validate configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})."
+ + " Please fix the configuration and ensure it is valid. The site may fail to start and / or load data types and run.",
+ dataType.NodeId, newAlias, dataType.EditorAlias);
+ }
}
+ // update
+ dataType.Configuration = JsonConvert.SerializeObject(config);
Database.Update(dataType);
}
}
-
- [TableName("cmsDataTypePreValues")]
- [ExplicitColumns]
- public class PreValueDto
- {
- [Column("datatypeNodeId")]
- public int NodeId { get; set; }
-
- [Column("alias")]
- public string Alias { get; set; }
-
- [Column("sortorder")]
- public int SortOrder { get; set; }
-
- [Column("value")]
- public string Value { get; set; }
- }
}
}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/ContentPickerPreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/ContentPickerPreValueMigrator.cs
new file mode 100644
index 0000000000..f445742aa9
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/ContentPickerPreValueMigrator.cs
@@ -0,0 +1,20 @@
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ class ContentPickerPreValueMigrator : DefaultPreValueMigrator
+ {
+ public override bool CanMigrate(string editorAlias)
+ => editorAlias == Constants.PropertyEditors.Legacy.Aliases.ContentPicker2;
+
+ public override string GetNewAlias(string editorAlias)
+ => null;
+
+ protected override object GetPreValueValue(PreValueDto preValue)
+ {
+ if (preValue.Alias == "showOpenButton" ||
+ preValue.Alias == "ignoreUserStartNodes")
+ return preValue.Value == "1";
+
+ return base.GetPreValueValue(preValue);
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/DecimalPreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/DecimalPreValueMigrator.cs
new file mode 100644
index 0000000000..8dc0f1dcd5
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/DecimalPreValueMigrator.cs
@@ -0,0 +1,20 @@
+using Newtonsoft.Json;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ class DecimalPreValueMigrator : DefaultPreValueMigrator
+ {
+ public override bool CanMigrate(string editorAlias)
+ => editorAlias == "Umbraco.Decimal";
+
+ protected override object GetPreValueValue(PreValueDto preValue)
+ {
+ if (preValue.Alias == "min" ||
+ preValue.Alias == "step" ||
+ preValue.Alias == "max")
+ return decimal.TryParse(preValue.Value, out var d) ? (decimal?) d : null;
+
+ return preValue.Value.DetectIsJson() ? JsonConvert.DeserializeObject(preValue.Value) : preValue.Value;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/DefaultPreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/DefaultPreValueMigrator.cs
new file mode 100644
index 0000000000..7112679de2
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/DefaultPreValueMigrator.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ class DefaultPreValueMigrator : IPreValueMigrator
+ {
+ public virtual bool CanMigrate(string editorAlias)
+ => true;
+
+ public virtual string GetNewAlias(string editorAlias)
+ => editorAlias;
+
+ public object GetConfiguration(int dataTypeId, string editorAlias, Dictionary preValues)
+ {
+ var preValuesA = preValues.Values.ToList();
+ var aliases = preValuesA.Select(x => x.Alias).Distinct().ToArray();
+ if (aliases.Length == 1 && string.IsNullOrWhiteSpace(aliases[0]))
+ {
+ // array-based prevalues
+ return new Dictionary { ["values"] = preValuesA.OrderBy(x => x.SortOrder).Select(x => x.Value).ToArray() };
+ }
+
+ // assuming we don't want to fall back to array
+ if (aliases.Length != preValuesA.Count || aliases.Any(string.IsNullOrWhiteSpace))
+ throw new InvalidOperationException($"Cannot migrate datatype w/ id={dataTypeId} preValues: duplicate or null/empty alias.");
+
+ // dictionary-base prevalues
+ return GetPreValues(preValuesA).ToDictionary(x => x.Alias, GetPreValueValue);
+ }
+
+ protected virtual IEnumerable GetPreValues(IEnumerable preValues)
+ => preValues;
+
+ protected virtual object GetPreValueValue(PreValueDto preValue)
+ {
+ return preValue.Value.DetectIsJson() ? JsonConvert.DeserializeObject(preValue.Value) : preValue.Value;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/DropDownFlexiblePreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/DropDownFlexiblePreValueMigrator.cs
new file mode 100644
index 0000000000..35ca574bab
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/DropDownFlexiblePreValueMigrator.cs
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+using System.Linq;
+using Umbraco.Core.PropertyEditors;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ class DropDownFlexiblePreValueMigrator : IPreValueMigrator
+ {
+ public bool CanMigrate(string editorAlias)
+ => editorAlias == "Umbraco.DropDown.Flexible";
+
+ public virtual string GetNewAlias(string editorAlias)
+ => null;
+
+ public object GetConfiguration(int dataTypeId, string editorAlias, Dictionary preValues)
+ {
+ var config = new DropDownFlexibleConfiguration();
+ foreach (var preValue in preValues.Values)
+ {
+ if (preValue.Alias == "multiple")
+ {
+ config.Multiple = (preValue.Value == "1");
+ }
+ else
+ {
+ config.Items.Add(new ValueListConfiguration.ValueListItem { Id = preValue.Id, Value = preValue.Value });
+ }
+ }
+ return config;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/IPreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/IPreValueMigrator.cs
new file mode 100644
index 0000000000..01e0ed3875
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/IPreValueMigrator.cs
@@ -0,0 +1,36 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ ///
+ /// Defines a service migrating preValues.
+ ///
+ public interface IPreValueMigrator
+ {
+ ///
+ /// Determines whether this migrator can migrate a data type.
+ ///
+ /// The data type editor alias.
+ bool CanMigrate(string editorAlias);
+
+ ///
+ /// Gets the v8 codebase data type editor alias.
+ ///
+ /// The original v7 codebase editor alias.
+ ///
+ /// This is used to validate that the migrated configuration can be parsed
+ /// by the new property editor. Return null to bypass this validation,
+ /// when for instance we know it will fail, and another, later migration will
+ /// deal with it.
+ ///
+ string GetNewAlias(string editorAlias);
+
+ ///
+ /// Gets the configuration object corresponding to preValue.
+ ///
+ /// The data type identifier.
+ /// The data type editor alias.
+ /// PreValues.
+ object GetConfiguration(int dataTypeId, string editorAlias, Dictionary preValues);
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/ListViewPreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/ListViewPreValueMigrator.cs
new file mode 100644
index 0000000000..d8daf9b5e6
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/ListViewPreValueMigrator.cs
@@ -0,0 +1,25 @@
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ class ListViewPreValueMigrator : DefaultPreValueMigrator
+ {
+ public override bool CanMigrate(string editorAlias)
+ => editorAlias == "Umbraco.ListView";
+
+ protected override IEnumerable GetPreValues(IEnumerable preValues)
+ {
+ return preValues.Where(preValue => preValue.Alias != "displayAtTabNumber");
+ }
+
+ protected override object GetPreValueValue(PreValueDto preValue)
+ {
+ if (preValue.Alias == "pageSize")
+ return int.TryParse(preValue.Value, out var i) ? (int?)i : null;
+
+ return preValue.Value.DetectIsJson() ? JsonConvert.DeserializeObject(preValue.Value) : preValue.Value;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/MediaPickerPreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/MediaPickerPreValueMigrator.cs
new file mode 100644
index 0000000000..922d886595
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/MediaPickerPreValueMigrator.cs
@@ -0,0 +1,37 @@
+using System.Linq;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ class MediaPickerPreValueMigrator : DefaultPreValueMigrator //PreValueMigratorBase
+ {
+ private readonly string[] _editors =
+ {
+ Constants.PropertyEditors.Legacy.Aliases.MediaPicker2,
+ Constants.PropertyEditors.Aliases.MediaPicker
+ };
+
+ public override bool CanMigrate(string editorAlias)
+ => _editors.Contains(editorAlias);
+
+ public override string GetNewAlias(string editorAlias)
+ => Constants.PropertyEditors.Aliases.MediaPicker;
+
+ // you wish - but MediaPickerConfiguration lives in Umbraco.Web
+ /*
+ public override object GetConfiguration(int dataTypeId, string editorAlias, Dictionary preValues)
+ {
+ return new MediaPickerConfiguration { ... };
+ }
+ */
+
+ protected override object GetPreValueValue(PreValueDto preValue)
+ {
+ if (preValue.Alias == "multiPicker" ||
+ preValue.Alias == "onlyImages" ||
+ preValue.Alias == "disableFolderSelect")
+ return preValue.Value == "1";
+
+ return base.GetPreValueValue(preValue);
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/NestedContentPreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/NestedContentPreValueMigrator.cs
new file mode 100644
index 0000000000..22c87f8503
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/NestedContentPreValueMigrator.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ class NestedContentPreValueMigrator : DefaultPreValueMigrator //PreValueMigratorBase
+ {
+ public override bool CanMigrate(string editorAlias)
+ => editorAlias == "Umbraco.NestedContent";
+
+ // you wish - but NestedContentConfiguration lives in Umbraco.Web
+ /*
+ public override object GetConfiguration(int dataTypeId, string editorAlias, Dictionary preValues)
+ {
+ return new NestedContentConfiguration { ... };
+ }
+ */
+
+ protected override object GetPreValueValue(PreValueDto preValue)
+ {
+ if (preValue.Alias == "confirmDeletes" ||
+ preValue.Alias == "showIcons" ||
+ preValue.Alias == "hideLabel")
+ return preValue.Value == "1";
+
+ if (preValue.Alias == "minItems" ||
+ preValue.Alias == "maxItems")
+ return int.TryParse(preValue.Value, out var i) ? (int?)i : null;
+
+ return preValue.Value.DetectIsJson() ? JsonConvert.DeserializeObject(preValue.Value) : preValue.Value;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueDto.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueDto.cs
new file mode 100644
index 0000000000..b6ab622510
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueDto.cs
@@ -0,0 +1,24 @@
+using NPoco;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ [TableName("cmsDataTypePreValues")]
+ [ExplicitColumns]
+ public class PreValueDto
+ {
+ [Column("id")]
+ public int Id { get; set; }
+
+ [Column("datatypeNodeId")]
+ public int NodeId { get; set; }
+
+ [Column("alias")]
+ public string Alias { get; set; }
+
+ [Column("sortorder")]
+ public int SortOrder { get; set; }
+
+ [Column("value")]
+ public string Value { get; set; }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorBase.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorBase.cs
new file mode 100644
index 0000000000..62e2b2347b
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorBase.cs
@@ -0,0 +1,20 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ public abstract class PreValueMigratorBase : IPreValueMigrator
+ {
+ public abstract bool CanMigrate(string editorAlias);
+
+ public virtual string GetNewAlias(string editorAlias)
+ => editorAlias;
+
+ public abstract object GetConfiguration(int dataTypeId, string editorAlias, Dictionary preValues);
+
+ protected bool GetBoolValue(Dictionary preValues, string alias, bool defaultValue = false)
+ => preValues.TryGetValue(alias, out var preValue) ? preValue.Value == "1" : defaultValue;
+
+ protected decimal GetDecimalValue(Dictionary preValues, string alias, decimal defaultValue = 0)
+ => preValues.TryGetValue(alias, out var preValue) && decimal.TryParse(preValue.Value, out var value) ? value : defaultValue;
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorCollection.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorCollection.cs
new file mode 100644
index 0000000000..06f5d45deb
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorCollection.cs
@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+using System.Linq;
+using Umbraco.Core.Composing;
+using Umbraco.Core.Logging;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ public class PreValueMigratorCollection : BuilderCollectionBase
+ {
+ private readonly ILogger _logger;
+
+ public PreValueMigratorCollection(IEnumerable items, ILogger logger)
+ : base(items)
+ {
+ _logger = logger;
+ _logger.Debug(GetType(), "Migrators: " + string.Join(", ", items.Select(x => x.GetType().Name)));
+ }
+
+ public IPreValueMigrator GetMigrator(string editorAlias)
+ {
+ var migrator = this.FirstOrDefault(x => x.CanMigrate(editorAlias));
+ _logger.Debug(GetType(), "Getting migrator for \"{EditorAlias}\" = {MigratorType}", editorAlias, migrator == null ? "" : migrator.GetType().Name);
+ return migrator;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorCollectionBuilder.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorCollectionBuilder.cs
new file mode 100644
index 0000000000..3859e63767
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorCollectionBuilder.cs
@@ -0,0 +1,9 @@
+using Umbraco.Core.Composing;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ public class PreValueMigratorCollectionBuilder : OrderedCollectionBuilderBase
+ {
+ protected override PreValueMigratorCollectionBuilder This => this;
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorComposer.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorComposer.cs
new file mode 100644
index 0000000000..8dfa464508
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/PreValueMigratorComposer.cs
@@ -0,0 +1,26 @@
+using Umbraco.Core.Composing;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+[RuntimeLevel(MinLevel = RuntimeLevel.Upgrade, MaxLevel = RuntimeLevel.Upgrade)] // only on upgrades
+public class PreValueMigratorComposer : ICoreComposer
+{
+ public void Compose(Composition composition)
+ {
+ // do NOT add DefaultPreValueMigrator to this list!
+ // it will be automatically used if nothing matches
+
+ composition.WithCollectionBuilder()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append()
+ .Append();
+ }
+}
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/RenamingPreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/RenamingPreValueMigrator.cs
new file mode 100644
index 0000000000..c04e7c8fda
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/RenamingPreValueMigrator.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Linq;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ class RenamingPreValueMigrator : DefaultPreValueMigrator
+ {
+ private readonly string[] _editors =
+ {
+ "Umbraco.NoEdit"
+ };
+
+ public override bool CanMigrate(string editorAlias)
+ => _editors.Contains(editorAlias);
+
+ public override string GetNewAlias(string editorAlias)
+ {
+ switch (editorAlias)
+ {
+ case "Umbraco.NoEdit":
+ return Constants.PropertyEditors.Aliases.Label;
+ default:
+ throw new Exception("panic");
+ }
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/RichTextPreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/RichTextPreValueMigrator.cs
new file mode 100644
index 0000000000..3670c52c64
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/RichTextPreValueMigrator.cs
@@ -0,0 +1,21 @@
+using Newtonsoft.Json;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ class RichTextPreValueMigrator : DefaultPreValueMigrator
+ {
+ public override bool CanMigrate(string editorAlias)
+ => editorAlias == "Umbraco.TinyMCEv3";
+
+ public override string GetNewAlias(string editorAlias)
+ => Constants.PropertyEditors.Aliases.TinyMce;
+
+ protected override object GetPreValueValue(PreValueDto preValue)
+ {
+ if (preValue.Alias == "hideLabel")
+ return preValue.Value == "1";
+
+ return preValue.Value.DetectIsJson() ? JsonConvert.DeserializeObject(preValue.Value) : preValue.Value;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/UmbracoSliderPreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/UmbracoSliderPreValueMigrator.cs
new file mode 100644
index 0000000000..dc6de5e493
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/UmbracoSliderPreValueMigrator.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+using Umbraco.Core.PropertyEditors;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ class UmbracoSliderPreValueMigrator : PreValueMigratorBase
+ {
+ public override bool CanMigrate(string editorAlias)
+ => editorAlias == "Umbraco.Slider";
+
+ public override object GetConfiguration(int dataTypeId, string editorAlias, Dictionary preValues)
+ {
+ return new SliderConfiguration
+ {
+ EnableRange = GetBoolValue(preValues, "enableRange"),
+ InitialValue = GetDecimalValue(preValues, "initVal1"),
+ InitialValue2 = GetDecimalValue(preValues, "initVal2"),
+ MaximumValue = GetDecimalValue(preValues, "maxVal"),
+ MinimumValue = GetDecimalValue(preValues, "minVal"),
+ StepIncrements = GetDecimalValue(preValues, "step")
+ };
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/ValueListPreValueMigrator.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/ValueListPreValueMigrator.cs
new file mode 100644
index 0000000000..07fefc8e85
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DataTypes/ValueListPreValueMigrator.cs
@@ -0,0 +1,33 @@
+using System.Collections.Generic;
+using System.Linq;
+using Umbraco.Core.PropertyEditors;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
+{
+ class ValueListPreValueMigrator : IPreValueMigrator
+ {
+ private readonly string[] _editors =
+ {
+ "Umbraco.RadioButtonList",
+ "Umbraco.CheckBoxList",
+ "Umbraco.DropDown",
+ "Umbraco.DropdownlistPublishingKeys",
+ "Umbraco.DropDownMultiple",
+ "Umbraco.DropdownlistMultiplePublishKeys"
+ };
+
+ public bool CanMigrate(string editorAlias)
+ => _editors.Contains(editorAlias);
+
+ public virtual string GetNewAlias(string editorAlias)
+ => null;
+
+ public object GetConfiguration(int dataTypeId, string editorAlias, Dictionary preValues)
+ {
+ var config = new ValueListConfiguration();
+ foreach (var preValue in preValues.Values)
+ config.Items.Add(new ValueListConfiguration.ValueListItem { Id = preValue.Id, Value = preValue.Value });
+ return config;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs
index ed2990aff7..d30719231a 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropDownPropertyEditorsMigration.cs
@@ -1,39 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using Umbraco.Core.Cache;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Logging;
+using Umbraco.Core.Migrations.PostMigrations;
using Umbraco.Core.Models;
-using Umbraco.Core.Sync;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
{
- public class DropDownPropertyEditorsMigration : MigrationBase
+ public class DropDownPropertyEditorsMigration : PropertyEditorsMigrationBase
{
- private readonly CacheRefresherCollection _cacheRefreshers;
- private readonly IServerMessenger _serverMessenger;
-
- public DropDownPropertyEditorsMigration(IMigrationContext context, CacheRefresherCollection cacheRefreshers, IServerMessenger serverMessenger)
+ public DropDownPropertyEditorsMigration(IMigrationContext context)
: base(context)
- {
- _cacheRefreshers = cacheRefreshers;
- _serverMessenger = serverMessenger;
- }
-
- // dummy editor for deserialization
- private class ValueListConfigurationEditor : ConfigurationEditor
{ }
public override void Migrate()
{
- //need to convert the old drop down data types to use the new one
- var dataTypes = Database.Fetch(Sql()
- .Select()
- .From()
- .Where(x => x.EditorAlias.Contains(".DropDown")));
+ var refreshCache = Migrate(GetDataTypes(".DropDown", false));
+
+ // if some data types have been updated directly in the database (editing DataTypeDto and/or PropertyDataDto),
+ // bypassing the services, then we need to rebuild the cache entirely, including the umbracoContentNu table
+ if (refreshCache)
+ Context.AddPostMigration();
+ }
+
+ private bool Migrate(IEnumerable dataTypes)
+ {
+ var refreshCache = false;
+ ConfigurationEditor configurationEditor = null;
foreach (var dataType in dataTypes)
{
@@ -42,14 +38,16 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
if (!dataType.Configuration.IsNullOrWhiteSpace())
{
// parse configuration, and update everything accordingly
+ if (configurationEditor == null)
+ configurationEditor = new ValueListConfigurationEditor();
try
{
- config = (ValueListConfiguration) new ValueListConfigurationEditor().FromDatabase(dataType.Configuration);
+ config = (ValueListConfiguration) configurationEditor.FromDatabase(dataType.Configuration);
}
catch (Exception ex)
{
Logger.Error(
- ex, "Invalid drop down configuration detected: \"{Configuration}\", cannot convert editor, values will be cleared",
+ ex, "Invalid configuration: \"{Configuration}\", cannot convert editor.",
dataType.Configuration);
// reset
@@ -65,7 +63,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
.Where(x => x.DataTypeId == dataType.NodeId));
// update dtos
- var updatedDtos = propertyDataDtos.Where(x => UpdatePropertyDataDto(x, config));
+ var updatedDtos = propertyDataDtos.Where(x => UpdatePropertyDataDto(x, config, true));
// persist changes
foreach (var propertyDataDto in updatedDtos)
@@ -77,7 +75,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
config = new ValueListConfiguration();
}
- var requiresCacheRebuild = false;
switch (dataType.EditorAlias)
{
case string ea when ea.InvariantEquals("Umbraco.DropDown"):
@@ -85,29 +82,25 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
break;
case string ea when ea.InvariantEquals("Umbraco.DropdownlistPublishingKeys"):
UpdateDataType(dataType, config, false);
- requiresCacheRebuild = true;
break;
case string ea when ea.InvariantEquals("Umbraco.DropDownMultiple"):
UpdateDataType(dataType, config, true);
break;
case string ea when ea.InvariantEquals("Umbraco.DropdownlistMultiplePublishKeys"):
UpdateDataType(dataType, config, true);
- requiresCacheRebuild = true;
break;
}
- if (requiresCacheRebuild)
- {
- var dataTypeCacheRefresher = _cacheRefreshers[Guid.Parse("35B16C25-A17E-45D7-BC8F-EDAB1DCC28D2")];
- _serverMessenger.PerformRefreshAll(dataTypeCacheRefresher);
- }
+ refreshCache = true;
}
+
+ return refreshCache;
}
private void UpdateDataType(DataTypeDto dataType, ValueListConfiguration config, bool isMultiple)
{
- dataType.EditorAlias = Constants.PropertyEditors.Aliases.DropDownListFlexible;
dataType.DbType = ValueStorageType.Nvarchar.ToString();
+ dataType.EditorAlias = Constants.PropertyEditors.Aliases.DropDownListFlexible;
var flexConfig = new DropDownFlexibleConfiguration
{
@@ -118,68 +111,5 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
Database.Update(dataType);
}
-
- private bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config)
- {
- //Get the INT ids stored for this property/drop down
- int[] ids = null;
- if (!propData.VarcharValue.IsNullOrWhiteSpace())
- {
- ids = ConvertStringValues(propData.VarcharValue);
- }
- else if (!propData.TextValue.IsNullOrWhiteSpace())
- {
- ids = ConvertStringValues(propData.TextValue);
- }
- else if (propData.IntegerValue.HasValue)
- {
- ids = new[] { propData.IntegerValue.Value };
- }
-
- //if there are INT ids, convert them to values based on the configured pre-values
- if (ids != null && ids.Length > 0)
- {
- //map the ids to values
- var vals = new List();
- var canConvert = true;
- foreach (var id in ids)
- {
- var val = config.Items.FirstOrDefault(x => x.Id == id);
- if (val != null)
- vals.Add(val.Value);
- else
- {
- Logger.Warn(
- "Could not find associated data type configuration for stored Id {DataTypeId}", id);
- canConvert = false;
- }
- }
- if (canConvert)
- {
- propData.VarcharValue = string.Join(",", vals);
- propData.TextValue = null;
- propData.IntegerValue = null;
- return true;
- }
- }
-
- return false;
- }
-
- private int[] ConvertStringValues(string val)
- {
- var splitVals = val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
-
- var intVals = splitVals
- .Select(x => int.TryParse(x, out var i) ? i : int.MinValue)
- .Where(x => x != int.MinValue)
- .ToArray();
-
- //only return if the number of values are the same (i.e. All INTs)
- if (splitVals.Length == intVals.Length)
- return intVals;
-
- return null;
- }
}
}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropMigrationsTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropMigrationsTable.cs
index 26668361bd..def6a93400 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropMigrationsTable.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropMigrationsTable.cs
@@ -8,7 +8,8 @@
public override void Migrate()
{
- Delete.Table("umbracoMigration").Do();
+ if (TableExists("umbracoMigration"))
+ Delete.Table("umbracoMigration").Do();
}
}
}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs
index fa6e47fac7..918510d13c 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/DropPreValueTable.cs
@@ -3,8 +3,7 @@
public class DropPreValueTable : MigrationBase
{
public DropPreValueTable(IMigrationContext context) : base(context)
- {
- }
+ { }
public override void Migrate()
{
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/FixLanguageIsoCodeLength.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/FixLanguageIsoCodeLength.cs
new file mode 100644
index 0000000000..8de06c9a6f
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/FixLanguageIsoCodeLength.cs
@@ -0,0 +1,21 @@
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
+{
+ public class FixLanguageIsoCodeLength : MigrationBase
+ {
+ public FixLanguageIsoCodeLength(IMigrationContext context)
+ : base(context)
+ { }
+
+ public override void Migrate()
+ {
+ // there is some confusion here when upgrading from v7
+ // it should be 14 already but that's not always the case
+
+ Alter.Table("umbracoLanguage")
+ .AlterColumn("languageISOCode")
+ .AsString(14)
+ .Nullable()
+ .Do();
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/FixLockTablePrimaryKey.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/FixLockTablePrimaryKey.cs
deleted file mode 100644
index fbb233927b..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/FixLockTablePrimaryKey.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Linq;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
-{
- public class FixLockTablePrimaryKey : MigrationBase
- {
- public FixLockTablePrimaryKey(IMigrationContext context)
- : base(context)
- { }
-
- public override void Migrate()
- {
- // at some point, the KeyValueService dropped the PK and failed to re-create it,
- // so the PK is gone - make sure we have one, and create if needed
-
- var constraints = SqlSyntax.GetConstraintsPerTable(Database);
- var exists = constraints.Any(x => x.Item2 == "PK_umbracoLock");
-
- if (!exists)
- Create.PrimaryKey("PK_umbracoLock").OnTable(Constants.DatabaseSchema.Tables.Lock).Column("id").Do();
- }
- }
-}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MakeRedirectUrlVariant.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MakeRedirectUrlVariant.cs
index 2e366c7c14..651c95e6bd 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MakeRedirectUrlVariant.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MakeRedirectUrlVariant.cs
@@ -11,19 +11,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
public override void Migrate()
{
AddColumn("culture");
-
- Delete.Index("IX_umbracoRedirectUrl").OnTable(Constants.DatabaseSchema.Tables.RedirectUrl).Do();
- Create.Index("IX_umbracoRedirectUrl").OnTable(Constants.DatabaseSchema.Tables.RedirectUrl)
- .OnColumn("urlHash")
- .Ascending()
- .OnColumn("contentKey")
- .Ascending()
- .OnColumn("culture")
- .Ascending()
- .OnColumn("createDateUtc")
- .Ascending()
- .WithOptions().Unique()
- .Do();
}
}
}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MakeTagsVariant.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MakeTagsVariant.cs
index 9ccd6d5e76..c898187884 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MakeTagsVariant.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MakeTagsVariant.cs
@@ -11,17 +11,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
public override void Migrate()
{
AddColumn("languageId");
-
- Delete.Index($"IX_{Constants.DatabaseSchema.Tables.Tag}").OnTable(Constants.DatabaseSchema.Tables.Tag).Do();
- Create.Index($"IX_{Constants.DatabaseSchema.Tables.Tag}").OnTable(Constants.DatabaseSchema.Tables.Tag)
- .OnColumn("group")
- .Ascending()
- .OnColumn("tag")
- .Ascending()
- .OnColumn("languageId")
- .Ascending()
- .WithOptions().Unique()
- .Do();
}
}
}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MergeDateAndDateTimePropertyEditor.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MergeDateAndDateTimePropertyEditor.cs
index a434b9f1c1..0d451e8460 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MergeDateAndDateTimePropertyEditor.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/MergeDateAndDateTimePropertyEditor.cs
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
public override void Migrate()
{
- var dataTypes = GetDataTypes("Umbraco.Date");
+ var dataTypes = GetDataTypes(Constants.PropertyEditors.Legacy.Aliases.Date);
foreach (var dataType in dataTypes)
{
@@ -25,6 +25,14 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
{
config = (DateTimeConfiguration) new CustomDateTimeConfigurationEditor().FromDatabase(
dataType.Configuration);
+
+ // If the Umbraco.Date type is the default from V7 and it has never been updated, then the
+ // configuration is empty, and the format stuff is handled by in JS by moment.js. - We can't do that
+ // after the migration, so we force the format to the default from V7.
+ if (string.IsNullOrEmpty(dataType.Configuration))
+ {
+ config.Format = "YYYY-MM-DD";
+ };
}
catch (Exception ex)
{
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/PropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/PropertyEditorsMigration.cs
index 064ffc7228..89a8f010ec 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/PropertyEditorsMigration.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/PropertyEditorsMigration.cs
@@ -12,12 +12,12 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
public override void Migrate()
{
- RenameDataType(Constants.PropertyEditors.Aliases.ContentPicker + "2", Constants.PropertyEditors.Aliases.ContentPicker);
- RenameDataType(Constants.PropertyEditors.Aliases.MediaPicker + "2", Constants.PropertyEditors.Aliases.MediaPicker);
- RenameDataType(Constants.PropertyEditors.Aliases.MemberPicker + "2", Constants.PropertyEditors.Aliases.MemberPicker);
- RenameDataType(Constants.PropertyEditors.Aliases.MultiNodeTreePicker + "2", Constants.PropertyEditors.Aliases.MultiNodeTreePicker);
- RenameDataType("Umbraco.TextboxMultiple", Constants.PropertyEditors.Aliases.TextArea, false);
- RenameDataType("Umbraco.Textbox", Constants.PropertyEditors.Aliases.TextBox, false);
+ RenameDataType(Constants.PropertyEditors.Legacy.Aliases.ContentPicker2, Constants.PropertyEditors.Aliases.ContentPicker);
+ RenameDataType(Constants.PropertyEditors.Legacy.Aliases.MediaPicker2, Constants.PropertyEditors.Aliases.MediaPicker);
+ RenameDataType(Constants.PropertyEditors.Legacy.Aliases.MemberPicker2, Constants.PropertyEditors.Aliases.MemberPicker);
+ RenameDataType(Constants.PropertyEditors.Legacy.Aliases.MultiNodeTreePicker2, Constants.PropertyEditors.Aliases.MultiNodeTreePicker);
+ RenameDataType(Constants.PropertyEditors.Legacy.Aliases.TextboxMultiple, Constants.PropertyEditors.Aliases.TextArea, false);
+ RenameDataType(Constants.PropertyEditors.Legacy.Aliases.Textbox, Constants.PropertyEditors.Aliases.TextBox, false);
}
private void RenameDataType(string fromAlias, string toAlias, bool checkCollision = true)
@@ -30,7 +30,20 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
.Where(x => x.EditorAlias == toAlias));
if (oldCount > 0)
- throw new InvalidOperationException($"Cannot rename datatype alias \"{fromAlias}\" to \"{toAlias}\" because the target alias is already used.");
+ {
+ // If we throw it means that the upgrade will exit and cannot continue.
+ // This will occur if a v7 site has the old "Obsolete" property editors that are already named with the `toAlias` name.
+ // TODO: We should have an additional upgrade step when going from 7 -> 8 like we did with 6 -> 7 that shows a compatibility report,
+ // this would include this check and then we can provide users with information on what they should do (i.e. before upgrading to v8 they will
+ // need to migrate these old obsolete editors to non-obsolete editors)
+
+ throw new InvalidOperationException(
+ $"Cannot rename datatype alias \"{fromAlias}\" to \"{toAlias}\" because the target alias is already used." +
+ $"This is generally because when upgrading from a v7 to v8 site, the v7 site contains Data Types that reference old and already Obsolete " +
+ $"Property Editors. Before upgrading to v8, any Data Types using property editors that are named with the prefix '(Obsolete)' must be migrated " +
+ $"to the non-obsolete v7 property editors of the same type.");
+ }
+
}
Database.Execute(Sql()
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/PropertyEditorsMigrationBase.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/PropertyEditorsMigrationBase.cs
new file mode 100644
index 0000000000..605f8a9eed
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/PropertyEditorsMigrationBase.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Persistence;
+using Umbraco.Core.Persistence.Dtos;
+using Umbraco.Core.PropertyEditors;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
+{
+ public abstract class PropertyEditorsMigrationBase : MigrationBase
+ {
+ protected PropertyEditorsMigrationBase(IMigrationContext context)
+ : base(context)
+ { }
+
+ internal List GetDataTypes(string editorAlias, bool strict = true)
+ {
+ var sql = Sql()
+ .Select()
+ .From();
+
+ sql = strict
+ ? sql.Where(x => x.EditorAlias == editorAlias)
+ : sql.Where(x => x.EditorAlias.Contains(editorAlias));
+
+ return Database.Fetch(sql);
+ }
+
+ protected int[] ConvertStringValues(string val)
+ {
+ var splitVals = val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+
+ var intVals = splitVals
+ .Select(x => int.TryParse(x, out var i) ? i : int.MinValue)
+ .Where(x => x != int.MinValue)
+ .ToArray();
+
+ //only return if the number of values are the same (i.e. All INTs)
+ if (splitVals.Length == intVals.Length)
+ return intVals;
+
+ return null;
+ }
+
+ internal bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config, bool isMultiple)
+ {
+ //Get the INT ids stored for this property/drop down
+ int[] ids = null;
+ if (!propData.VarcharValue.IsNullOrWhiteSpace())
+ {
+ ids = ConvertStringValues(propData.VarcharValue);
+ }
+ else if (!propData.TextValue.IsNullOrWhiteSpace())
+ {
+ ids = ConvertStringValues(propData.TextValue);
+ }
+ else if (propData.IntegerValue.HasValue)
+ {
+ ids = new[] { propData.IntegerValue.Value };
+ }
+
+ // if there are INT ids, convert them to values based on the configuration
+ if (ids == null || ids.Length <= 0) return false;
+
+ // map ids to values
+ var values = new List();
+ var canConvert = true;
+
+ foreach (var id in ids)
+ {
+ var val = config.Items.FirstOrDefault(x => x.Id == id);
+ if (val != null)
+ {
+ values.Add(val.Value);
+ continue;
+ }
+
+ Logger.Warn(GetType(), "Could not find PropertyData {PropertyDataId} value '{PropertyValue}' in the datatype configuration: {Values}.",
+ propData.Id, id, string.Join(", ", config.Items.Select(x => x.Id + ":" + x.Value)));
+ canConvert = false;
+ }
+
+ if (!canConvert) return false;
+
+ propData.VarcharValue = isMultiple ? JsonConvert.SerializeObject(values) : values[0];
+ propData.TextValue = null;
+ propData.IntegerValue = null;
+ return true;
+ }
+
+ // dummy editor for deserialization
+ protected class ValueListConfigurationEditor : ConfigurationEditor
+ { }
+ }
+}
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RadioAndCheckboxAndDropdownPropertyEditorsMigration.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RadioAndCheckboxAndDropdownPropertyEditorsMigration.cs
deleted file mode 100644
index 1944c8079f..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RadioAndCheckboxAndDropdownPropertyEditorsMigration.cs
+++ /dev/null
@@ -1,183 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Newtonsoft.Json;
-using Umbraco.Core.Logging;
-using Umbraco.Core.Migrations.PostMigrations;
-using Umbraco.Core.Models;
-using Umbraco.Core.Persistence;
-using Umbraco.Core.Persistence.Dtos;
-using Umbraco.Core.PropertyEditors;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
-{
- public class RadioAndCheckboxAndDropdownPropertyEditorsMigration : MigrationBase
- {
- public RadioAndCheckboxAndDropdownPropertyEditorsMigration(IMigrationContext context)
- : base(context)
- {
- }
-
- public override void Migrate()
- {
- var refreshCache = false;
-
- refreshCache |= Migrate(Constants.PropertyEditors.Aliases.RadioButtonList, (dto, configuration) => UpdateRadioOrCheckboxPropertyDataDto(dto, configuration, true));
- refreshCache |= Migrate(Constants.PropertyEditors.Aliases.CheckBoxList, (dto, configuration) => UpdateRadioOrCheckboxPropertyDataDto(dto, configuration, false));
- refreshCache |= Migrate(Constants.PropertyEditors.Aliases.DropDownListFlexible, UpdateDropDownPropertyDataDto);
-
- if (refreshCache)
- {
- Context.AddPostMigration();
- }
- }
-
- private bool Migrate(string editorAlias, Func updateRadioPropertyDataFunc)
- {
- var refreshCache = false;
- var dataTypes = GetDataTypes(editorAlias);
-
- foreach (var dataType in dataTypes)
- {
- ValueListConfiguration config;
-
- if (dataType.Configuration.IsNullOrWhiteSpace())
- continue;
-
- // parse configuration, and update everything accordingly
- try
- {
- config = (ValueListConfiguration) new ValueListConfigurationEditor().FromDatabase(
- dataType.Configuration);
- }
- catch (Exception ex)
- {
- Logger.Error(
- ex,
- "Invalid property editor configuration detected: \"{Configuration}\", cannot convert editor, values will be cleared",
- dataType.Configuration);
-
- continue;
- }
-
- // get property data dtos
- var propertyDataDtos = Database.Fetch(Sql()
- .Select()
- .From