From 55190b731850410d7bbc9ad67983dbdec717cffb Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 18 Nov 2014 15:59:15 +1100 Subject: [PATCH] Fixes: U4-5707 Cannot upgrade 6.2.2 site to 7.2 --- .../AlterTagRelationsTable.cs | 30 ++---- .../AssignMissingKeysAndIndexes.cs | 93 +++++++++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 5 +- 3 files changed, 105 insertions(+), 23 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AssignMissingKeysAndIndexes.cs diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs index a9d4a148c8..31cfeb7997 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AlterTagRelationsTable.cs @@ -31,15 +31,14 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven Alter.Table("cmsTagRelationship").AddColumn("propertyTypeId").AsInt32().Nullable(); //drop the foreign key on umbracoNode. Must drop foreign key first before primary key can be removed in MySql. - if (Context.CurrentDatabaseProvider != DatabaseProviders.SqlServer) + if (Context.CurrentDatabaseProvider == DatabaseProviders.MySql) { Delete.ForeignKey().FromTable("cmsTagRelationship").ForeignColumn("nodeId").ToTable("umbracoNode").PrimaryColumn("id"); } else { - //If we are on SQLServer, we need to delete constraints by name, older versions of umbraco did not name these key constraints - // consistently so we need to look up the constraint name to delete, this only pertains to SQL Server and this issue: - // http://issues.umbraco.org/issue/U4-4133 + //Before we try to delete this constraint, we'll see if it exists first, some older schemas never had it and some older schema's had this named + // differently than the default. var constraint = constraints .SingleOrDefault(x => x.Item1 == "cmsTagRelationship" && x.Item2 == "nodeId" && x.Item3.InvariantStartsWith("PK_") == false); @@ -62,7 +61,12 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven } else { - Delete.PrimaryKey("PK_cmsTagRelationship").FromTable("cmsTagRelationship"); + //lookup the PK by name + var pkName = constraints.FirstOrDefault(x => x.Item1.InvariantEquals("cmsTagRelationship") && x.Item3.InvariantStartsWith("PK_")); + if (pkName != null) + { + Delete.PrimaryKey(pkName.Item3).FromTable("cmsTagRelationship"); + } } } @@ -137,22 +141,6 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven .OnDelete(Rule.None) .OnUpdate(Rule.None); - //Some very old schemas don't have an index on the cmsContent.nodeId column, I'm not actually sure when it was added but - // it is absolutely required to exist in order to add this foreign key, so we'll need to check it's existence - // this came to light from this issue: http://issues.umbraco.org/issue/U4-4133 - var dbIndexes = SqlSyntaxContext.SqlSyntaxProvider.GetDefinedIndexes(Context.Database) - .Select(x => new DbIndexDefinition() - { - TableName = x.Item1, - IndexName = x.Item2, - ColumnName = x.Item3, - IsUnique = x.Item4 - }).ToArray(); - if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsContent")) == false) - { - Create.Index("IX_cmsContent").OnTable("cmsContent").OnColumn("nodeId").Ascending().WithOptions().Unique(); - } - //now we need to add a foreign key to the nodeId column to cmsContent (intead of the original umbracoNode) Create.ForeignKey("FK_cmsTagRelationship_cmsContent") .FromTable("cmsTagRelationship") diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AssignMissingKeysAndIndexes.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AssignMissingKeysAndIndexes.cs new file mode 100644 index 0000000000..7be58853c9 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSeven/AssignMissingKeysAndIndexes.cs @@ -0,0 +1,93 @@ +using System.Data; +using System.Linq; +using Umbraco.Core.Configuration; +using Umbraco.Core.Persistence.DatabaseModelDefinitions; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven +{ + /// + /// I'm not actually sure how this is possible but I've come across one install that was missing these PKs + /// and it wasn't a MySQL install. + /// see: http://issues.umbraco.org/issue/U4-5707 + /// + [Migration("7.0.0", 0, GlobalSettings.UmbracoMigrationName)] + public class AssignMissingKeysAndIndexes : MigrationBase + { + public override void Up() + { + + //Some very old schemas don't have an index on the cmsContent.nodeId column, I'm not actually sure when it was added but + // it is absolutely required to exist in order to have it as a foreign key reference, so we'll need to check it's existence + // this came to light from this issue: http://issues.umbraco.org/issue/U4-4133 + var dbIndexes = SqlSyntaxContext.SqlSyntaxProvider.GetDefinedIndexes(Context.Database) + .Select(x => new DbIndexDefinition() + { + TableName = x.Item1, + IndexName = x.Item2, + ColumnName = x.Item3, + IsUnique = x.Item4 + }).ToArray(); + if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsContent")) == false) + { + Create.Index("IX_cmsContent").OnTable("cmsContent").OnColumn("nodeId").Ascending().WithOptions().Unique(); + } + + if (Context.CurrentDatabaseProvider == DatabaseProviders.SqlServer + || Context.CurrentDatabaseProvider == DatabaseProviders.SqlServerCE) + { + var constraints = SqlSyntaxContext.SqlSyntaxProvider.GetConstraintsPerColumn(Context.Database).Distinct().ToArray(); + + //This should be 2 because this table has 2 keys + if (constraints.Count(x => x.Item1.InvariantEquals("cmsPreviewXml") && x.Item3.InvariantStartsWith("PK_")) == 0) + { + Create.PrimaryKey("PK_cmsContentPreviewXml") + .OnTable("cmsPreviewXml") + .Columns(new[] { "nodeId", "versionId" }); + } + + if (constraints.Count(x => x.Item1.InvariantEquals("cmsTags") && x.Item3.InvariantStartsWith("PK_")) == 0) + { + Create.PrimaryKey("PK_cmsTags") + .OnTable("cmsTags") + .Columns(new[] { "id" }); + } + + if (constraints.Count(x => x.Item1.InvariantEquals("cmsStylesheetProperty") && x.Item3.InvariantStartsWith("PK_")) == 0) + { + Create.PrimaryKey("PK_cmsStylesheetProperty") + .OnTable("cmsStylesheetProperty") + .Columns(new[] { "nodeId" }); + } + + if (constraints.Count(x => x.Item1.InvariantEquals("cmsStylesheet") && x.Item3.InvariantStartsWith("PK_")) == 0) + { + Create.PrimaryKey("PK_cmsStylesheet") + .OnTable("cmsStylesheet") + .Columns(new[] { "nodeId" }); + + Create.ForeignKey("FK_cmsStylesheet_umbracoNode_id").FromTable("cmsStylesheet").ForeignColumn("nodeId") + .ToTable("umbracoNode").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None); + } + + if (constraints.Count(x => x.Item1.InvariantEquals("cmsMember") && x.Item3.InvariantStartsWith("PK_")) == 0) + { + Create.PrimaryKey("PK_cmsMember") + .OnTable("cmsMember") + .Columns(new[] { "nodeId" }); + + Create.ForeignKey("FK_cmsMember_umbracoNode_id").FromTable("cmsMember").ForeignColumn("nodeId") + .ToTable("umbracoNode").PrimaryColumn("id").OnDeleteOrUpdate(Rule.None); + + Create.ForeignKey("FK_cmsMember_cmsContent_nodeId").FromTable("cmsMember").ForeignColumn("nodeId") + .ToTable("cmsContent").PrimaryColumn("nodeId").OnDeleteOrUpdate(Rule.None); + } + } + } + + public override void Down() + { + //don't do anything, these keys should have always existed! + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 685ca50c9a..c760c4ddb7 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -1,4 +1,4 @@ - + Debug @@ -106,7 +106,7 @@ True ..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll - + False @@ -394,6 +394,7 @@ +