Fixes MySQL upgrades from < 6.0

This commit is contained in:
Shannon
2014-04-30 19:41:40 +10:00
parent e88e809e29
commit cf2217cfe1
7 changed files with 100 additions and 45 deletions

View File

@@ -65,7 +65,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
return new Version(4, 7, 0);
}
return new Version(4, 9, 0);
return new Version(4, 8, 0);
}
//if the error is for umbracoServer

View File

@@ -16,8 +16,21 @@ namespace Umbraco.Core.Persistence.Migrations
ProductName = product;
}
public MigrationAttribute(string minimumCurrentVersion, string targetVersion, int sortOrder, string product)
{
TargetVersion = new Version(targetVersion);
MinimumCurrentVersion = new Version(minimumCurrentVersion);
SortOrder = sortOrder;
ProductName = product;
}
/// <summary>
/// Gets or sets the target version of this migration.
/// Gets the minimum current version for which this migration is allowed to execute
/// </summary>
public Version MinimumCurrentVersion { get; private set; }
/// <summary>
/// Gets the target version of this migration.
/// </summary>
public Version TargetVersion { get; private set; }

View File

@@ -13,13 +13,13 @@ namespace Umbraco.Core.Persistence.Migrations
/// </summary>
public class MigrationRunner
{
private readonly Version _configuredVersion;
private readonly Version _currentVersion;
private readonly Version _targetVersion;
private readonly string _productName;
public MigrationRunner(Version configuredVersion, Version targetVersion, string productName)
public MigrationRunner(Version currentVersion, Version targetVersion, string productName)
{
_configuredVersion = configuredVersion;
_currentVersion = currentVersion;
_targetVersion = targetVersion;
_productName = productName;
}
@@ -46,20 +46,20 @@ namespace Umbraco.Core.Persistence.Migrations
{
LogHelper.Info<MigrationRunner>("Initializing database migrations");
var foundMigrations = MigrationResolver.Current.Migrations.ToArray();
var foundMigrations = MigrationResolver.Current.Migrations.ToArray();
//filter all non-schema migrations
var migrations = isUpgrade
? OrderedUpgradeMigrations(foundMigrations).ToList()
: OrderedDowngradeMigrations(foundMigrations).ToList();
//SD: Why do we want this?
if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _configuredVersion, _targetVersion, true), this))
if (Migrating.IsRaisedEventCancelled(new MigrationEventArgs(migrations, _currentVersion, _targetVersion, true), this))
return false;
//Loop through migrations to generate sql
var migrationContext = InitializeMigrations(migrations, database, databaseProvider, isUpgrade);
try
{
ExecuteMigrations(migrationContext, database);
@@ -81,13 +81,13 @@ namespace Umbraco.Core.Persistence.Migrations
throw;
}
Migrated.RaiseEvent(new MigrationEventArgs(migrations, migrationContext, _configuredVersion, _targetVersion, false), this);
Migrated.RaiseEvent(new MigrationEventArgs(migrations, migrationContext, _currentVersion, _targetVersion, false), this);
return true;
}
private void ExecuteMigrations(IMigrationContext context, Database database)
{
private void ExecuteMigrations(IMigrationContext context, Database database)
{
//Transactional execution of the sql that was generated from the found migrations
using (var transaction = database.GetTransaction())
{
@@ -108,13 +108,13 @@ namespace Umbraco.Core.Persistence.Migrations
transaction.Complete();
}
}
}
internal MigrationContext InitializeMigrations(List<IMigration> migrations, Database database, DatabaseProviders databaseProvider, bool isUpgrade = true)
{
{
//Loop through migrations to generate sql
var context = new MigrationContext(databaseProvider, database);
foreach (var migration in migrations)
{
var baseMigration = migration as MigrationBase;
@@ -148,35 +148,49 @@ namespace Umbraco.Core.Persistence.Migrations
}
return context;
}
}
/// <summary>
/// Filters and orders migrations based on the migrations listed and the currently configured version and the target installation version
/// </summary>
/// <param name="foundMigrations"></param>
/// <returns></returns>
internal IEnumerable<IMigration> OrderedUpgradeMigrations(IEnumerable<IMigration> foundMigrations)
{
var migrations = (from migration in foundMigrations
let migrationAttributes = migration.GetType().GetCustomAttributes<MigrationAttribute>(false)
from migrationAttribute in migrationAttributes
where migrationAttribute != null
where
migrationAttribute.TargetVersion > _configuredVersion &&
migrationAttribute.TargetVersion <= _targetVersion &&
migrationAttribute.ProductName == _productName
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder ascending
select migration).Distinct();
let migrationAttributes = migration.GetType().GetCustomAttributes<MigrationAttribute>(false)
from migrationAttribute in migrationAttributes
where migrationAttribute != null
where
migrationAttribute.TargetVersion > _currentVersion &&
migrationAttribute.TargetVersion <= _targetVersion &&
migrationAttribute.ProductName == _productName &&
//filter if the migration specifies a minimum current version for which to execute
(migrationAttribute.MinimumCurrentVersion == null || _currentVersion >= migrationAttribute.MinimumCurrentVersion)
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder ascending
select migration).Distinct();
return migrations;
}
/// <summary>
/// Filters and orders migrations based on the migrations listed and the currently configured version and the target installation version
/// </summary>
/// <param name="foundMigrations"></param>
/// <returns></returns>
public IEnumerable<IMigration> OrderedDowngradeMigrations(IEnumerable<IMigration> foundMigrations)
{
var migrations = (from migration in foundMigrations
let migrationAttributes = migration.GetType().GetCustomAttributes<MigrationAttribute>(false)
from migrationAttribute in migrationAttributes
where migrationAttribute != null
where
migrationAttribute.TargetVersion > _configuredVersion &&
migrationAttribute.TargetVersion <= _targetVersion &&
migrationAttribute.ProductName == _productName
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder descending
select migration).Distinct();
let migrationAttributes = migration.GetType().GetCustomAttributes<MigrationAttribute>(false)
from migrationAttribute in migrationAttributes
where migrationAttribute != null
where
migrationAttribute.TargetVersion > _currentVersion &&
migrationAttribute.TargetVersion <= _targetVersion &&
migrationAttribute.ProductName == _productName &&
//filter if the migration specifies a minimum current version for which to execute
(migrationAttribute.MinimumCurrentVersion == null || _currentVersion >= migrationAttribute.MinimumCurrentVersion)
orderby migrationAttribute.TargetVersion, migrationAttribute.SortOrder descending
select migration).Distinct();
return migrations;
}

View File

@@ -5,6 +5,7 @@ using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
{
//see: http://issues.umbraco.org/issue/U4-4430
[Migration("6.2.0", 0, GlobalSettings.UmbracoMigrationName)]
public class AssignMissingPrimaryForMySqlKeys : MigrationBase
@@ -14,15 +15,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
if (Context.CurrentDatabaseProvider == DatabaseProviders.MySql)
{
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("cmsContentType2ContentType") && x.Item3.InvariantEquals("PRIMARY")) == 0)
{
Create.PrimaryKey("PK_cmsContentType2ContentType")
.OnTable("cmsContentType2ContentType")
.Columns(new[] {"parentContentTypeId", "childContentTypeId"});
}
//This should be 2 because this table has 2 keys
if (constraints.Count(x => x.Item1.InvariantEquals("cmsContentTypeAllowedContentType") && x.Item3.InvariantEquals("PRIMARY")) == 0)
{

View File

@@ -0,0 +1,34 @@
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixTwoZero
{
//We have to target this specifically to ensure this DOES NOT execute if upgrading from a version previous to 6.0,
// this is because when the 6.0.0 migrations are executed, this primary key get's created so if this migration is also executed
// we will get exceptions because it is trying to create the PK two times.
[Migration("6.0.0", "6.2.0", 0, GlobalSettings.UmbracoMigrationName)]
public class AssignMissingPrimaryForMySqlKeys2 : MigrationBase
{
public override void Up()
{
if (Context.CurrentDatabaseProvider == DatabaseProviders.MySql)
{
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("cmsContentType2ContentType") && x.Item3.InvariantEquals("PRIMARY")) == 0)
{
Create.PrimaryKey("PK_cmsContentType2ContentType")
.OnTable("cmsContentType2ContentType")
.Columns(new[] {"parentContentTypeId", "childContentTypeId"});
}
}
}
public override void Down()
{
//don't do anything, these keys should have always existed!
}
}
}

View File

@@ -228,6 +228,7 @@
<Compile Include="Persistence\Mappers\MemberGroupMapper.cs" />
<Compile Include="Persistence\Migrations\DataLossException.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixTwoZero\AssignMissingPrimaryForMySqlKeys.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixTwoZero\AssignMissingPrimaryForMySqlKeys2.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixTwoZero\ChangePasswordColumn.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSixTwoZero\UpdateToNewMemberPropertyAliases.cs" />
<Compile Include="Persistence\Querying\SqlStringExtensions.cs" />

View File

@@ -16,7 +16,7 @@ namespace Umbraco.Tests.Migrations
{
var runner = new MigrationRunner(new Version(4, 0, 0), new Version(6, 0, 0), "Test");
var migrations = runner.OrderedUpgradeMigrations(new List<IMigration> {new MultiMigration()});
var migrations = runner.OrderedUpgradeMigrations(new List<IMigration> { new MultiMigration() });
var ctx = runner.InitializeMigrations(
//new List<IMigration> {new DoRunMigration(), new DoNotRunMigration()},
@@ -58,7 +58,7 @@ namespace Umbraco.Tests.Migrations
Assert.AreEqual(1, ctx.Expressions.Count());
}
[Migration("6.0.0", 1, "Test")]
[Migration("5.0.0", 1, "Test")]
private class MultiMigration : MigrationBase