diff --git a/src/Umbraco.Core/Events/MigrationEventArgs.cs b/src/Umbraco.Core/Events/MigrationEventArgs.cs new file mode 100644 index 0000000000..c447ebcd1a --- /dev/null +++ b/src/Umbraco.Core/Events/MigrationEventArgs.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using Umbraco.Core.Persistence.Migrations; + +namespace Umbraco.Core.Events +{ + public class MigrationEventArgs : CancellableObjectEventArgs> + { + /// + /// Constructor accepting multiple migrations that are used in the migration runner + /// + /// + /// + /// + /// + public MigrationEventArgs(IEnumerable eventObject, Version configuredVersion, Version targetVersion, bool canCancel) + : base(eventObject, canCancel) + { + ConfiguredVersion = configuredVersion; + TargetVersion = targetVersion; + } + + /// + /// Constructor accepting multiple migrations that are used in the migration runner + /// + /// + /// + /// + /// + /// + internal MigrationEventArgs(IEnumerable eventObject, MigrationContext migrationContext, Version configuredVersion, Version targetVersion, bool canCancel) + : base(eventObject, canCancel) + { + MigrationContext = migrationContext; + ConfiguredVersion = configuredVersion; + TargetVersion = targetVersion; + } + + /// + /// Constructor accepting multiple migrations that are used in the migration runner + /// + /// + /// + /// + public MigrationEventArgs(IEnumerable eventObject, Version configuredVersion, Version targetVersion) + : base(eventObject) + { + ConfiguredVersion = configuredVersion; + TargetVersion = targetVersion; + } + + /// + /// Returns all migrations that were used in the migration runner + /// + public IEnumerable Migrations + { + get { return EventObject; } + } + + public Version ConfiguredVersion { get; private set; } + + public Version TargetVersion { get; private set; } + + internal MigrationContext MigrationContext { get; private set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Migrations/SqlScripts/SqlCe-SchemaAndData-4110.sql b/src/Umbraco.Tests/Migrations/SqlScripts/SqlCe-SchemaAndData-4110.sql new file mode 100644 index 0000000000..82f4eefcca Binary files /dev/null and b/src/Umbraco.Tests/Migrations/SqlScripts/SqlCe-SchemaAndData-4110.sql differ diff --git a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs new file mode 100644 index 0000000000..a9b80f9b17 --- /dev/null +++ b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs @@ -0,0 +1,73 @@ +using System; +using NUnit.Framework; +using SQLCE4Umbraco; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.Migrations; +using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Web.Strategies.Migrations; +using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings; + +namespace Umbraco.Tests.Migrations.Upgrades +{ + [TestFixture, NUnit.Framework.Ignore] + public class SqlCeDataUpgradeTest : BaseUpgradeTest + { + + [Test, NUnit.Framework.Ignore] + public override void Can_Upgrade_From_470_To_600() + { + var configuredVersion = new Version("4.11.0"); + var targetVersion = new Version("6.0.0"); + var provider = GetDatabaseProvider(); + var db = GetConfiguredDatabase(); + + var fix = new PublishAfterUpgradeToVersionSixth(); + + //Setup the MigrationRunner + var migrationRunner = new MigrationRunner(configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName); + bool upgraded = migrationRunner.Execute(db, provider, true); + + Assert.That(upgraded, Is.True); + + bool hasTabTable = db.TableExist("cmsTab"); + bool hasPropertyTypeGroupTable = db.TableExist("cmsPropertyTypeGroup"); + bool hasAppTreeTable = db.TableExist("umbracoAppTree"); + + fix.Unsubscribe(); + + Assert.That(hasTabTable, Is.False); + Assert.That(hasPropertyTypeGroupTable, Is.True); + Assert.That(hasAppTreeTable, Is.False); + } + + public override void DatabaseSpecificSetUp() + { + } + + public override void DatabaseSpecificTearDown() + { + //legacy API database connection close + SqlCeContextGuardian.CloseBackgroundConnection(); + } + + public override ISqlSyntaxProvider GetSyntaxProvider() + { + return SqlCeSyntax.Provider; + } + + public override UmbracoDatabase GetConfiguredDatabase() + { + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf", "System.Data.SqlServerCe.4.0"); + } + + public override DatabaseProviders GetDatabaseProvider() + { + return DatabaseProviders.SqlServerCE; + } + + public override string GetDatabaseSpecificSqlScript() + { + return SqlScripts.SqlResources.SqlCe_SchemaAndData_4110; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Strategies/Migrations/PublishAfterUpgradeToVersionSixth.cs b/src/Umbraco.Web/Strategies/Migrations/PublishAfterUpgradeToVersionSixth.cs new file mode 100644 index 0000000000..4414589937 --- /dev/null +++ b/src/Umbraco.Web/Strategies/Migrations/PublishAfterUpgradeToVersionSixth.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence; +using Umbraco.Core.Persistence.Migrations; +using Umbraco.Core.Persistence.UnitOfWork; +using umbraco.interfaces; + +namespace Umbraco.Web.Strategies.Migrations +{ + /// + /// This event ensures that upgrades from (configured) versions lower then 6.0.0 + /// have their publish state updated after the database schema has been migrated. + /// + public class PublishAfterUpgradeToVersionSixth : IApplicationStartupHandler + { + public PublishAfterUpgradeToVersionSixth() + { + MigrationRunner.Migrated += MigrationRunner_Migrated; + } + + public void Unsubscribe() + { + MigrationRunner.Migrated -= MigrationRunner_Migrated; + } + + void MigrationRunner_Migrated(MigrationRunner sender, Core.Events.MigrationEventArgs e) + { + var target = new Version(6, 0, 0); + if (e.ConfiguredVersion < target) + { + var sql = new Sql(); + sql.Select("*") + .From() + .InnerJoin() + .On(left => left.VersionId, right => right.VersionId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .InnerJoin() + .On(left => left.NodeId, right => right.NodeId) + .Where(x => x.NodeObjectType == new Guid("C66BA18E-EAF3-4CFF-8A22-41B16D66A972")) + .Where(x => x.Path.StartsWith("-1")); + + var uow = PetaPocoUnitOfWorkProvider.CreateUnitOfWork(); + + var dtos = uow.Database.Fetch(sql); + var toUpdate = new List(); + var versionGroup = dtos.GroupBy(x => x.NodeId); + foreach (var grp in versionGroup) + { + var published = grp.FirstOrDefault(x => x.Published); + var newest = grp.FirstOrDefault(x => x.Newest); + + if (newest != null) + { + double timeDiff = new TimeSpan(newest.UpdateDate.Ticks - newest.ContentVersionDto.VersionDate.Ticks).TotalMilliseconds; + var hasPendingChanges = timeDiff > 2000; + + if (hasPendingChanges == false && published != null) + { + published.Published = false; + toUpdate.Add(published); + newest.Published = true; + toUpdate.Add(newest); + } + } + } + + //Commit the updated entries for the cmsDocument table + using (var transaction = uow.Database.GetTransaction()) + { + //Loop through the toUpdate + foreach (var dto in toUpdate) + { + uow.Database.Update(dto); + } + + transaction.Complete(); + } + } + } + } +} \ No newline at end of file