U4-8361 - fixing migrations
This commit is contained in:
@@ -42,9 +42,9 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
//[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoRedirectUrl", ForColumns = "url, createDateUtc")]
|
||||
public string Url { get; set; }
|
||||
|
||||
[Column("hurl")]
|
||||
[Column("urlHash")]
|
||||
[NullSetting(NullSetting = NullSettings.NotNull)]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoRedirectUrl", ForColumns = "hurl, contentKey, createDateUtc")]
|
||||
public string Hurl { get; set; }
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoRedirectUrl", ForColumns = "urlHash, contentKey, createDateUtc")]
|
||||
public string UrlHash { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Alter;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Create;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Delete;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Execute;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
internal class LocalMigrationContext : MigrationContext
|
||||
{
|
||||
private readonly ISqlSyntaxProvider _sqlSyntax;
|
||||
|
||||
public LocalMigrationContext(DatabaseProviders databaseProvider, Database database, ISqlSyntaxProvider sqlSyntax, ILogger logger)
|
||||
: base(databaseProvider, database, logger)
|
||||
{
|
||||
_sqlSyntax = sqlSyntax;
|
||||
}
|
||||
|
||||
public IExecuteBuilder Execute
|
||||
{
|
||||
get { return new ExecuteBuilder(this, _sqlSyntax); }
|
||||
}
|
||||
|
||||
public IDeleteBuilder Delete
|
||||
{
|
||||
get { return new DeleteBuilder(this, _sqlSyntax); }
|
||||
}
|
||||
|
||||
public IAlterSyntaxBuilder Alter
|
||||
{
|
||||
get { return new AlterSyntaxBuilder(this, _sqlSyntax); }
|
||||
}
|
||||
|
||||
public ICreateBuilder Create
|
||||
{
|
||||
get { return new CreateBuilder(this, _sqlSyntax); }
|
||||
}
|
||||
|
||||
public string GetSql()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var sql in Expressions.Select(x => x.Process(Database)))
|
||||
{
|
||||
sb.Append(sql);
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("GO");
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Create;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZero
|
||||
@@ -14,24 +15,31 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZer
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
// don't exeucte if the table is already there
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
if (tables.InvariantContains("umbracoRedirectUrl")) return;
|
||||
// defer, because we are making decisions based upon what's in the database
|
||||
Execute.Code(MigrationCode);
|
||||
}
|
||||
|
||||
Create.Table("umbracoRedirectUrl")
|
||||
private string MigrationCode(Database database)
|
||||
{
|
||||
// don't execute if the table is already there
|
||||
var tables = SqlSyntax.GetTablesInSchema(database).ToArray();
|
||||
if (tables.InvariantContains("umbracoRedirectUrl")) return null;
|
||||
|
||||
var localContext = new LocalMigrationContext(Context.CurrentDatabaseProvider, database, SqlSyntax, Logger);
|
||||
|
||||
localContext.Create.Table("umbracoRedirectUrl")
|
||||
.WithColumn("id").AsInt32().Identity().PrimaryKey("PK_umbracoRedirectUrl")
|
||||
.WithColumn("contentId").AsInt32().NotNullable()
|
||||
.WithColumn("createDateUtc").AsDateTime().NotNullable()
|
||||
.WithColumn("url").AsString(2048).NotNullable();
|
||||
|
||||
//Create.PrimaryKey("PK_umbracoRedirectUrl").OnTable("umbracoRedirectUrl").Columns(new[] { "id" });
|
||||
localContext.Create.Index("IX_umbracoRedirectUrl")
|
||||
.OnTable("umbracoRedirectUrl")
|
||||
.OnColumn("url").Ascending()
|
||||
.OnColumn("createDateUtc").Ascending()
|
||||
.WithOptions().NonClustered();
|
||||
|
||||
Create.Index("IX_umbracoRedirectUrl").OnTable("umbracoRedirectUrl")
|
||||
.OnColumn("url")
|
||||
.Ascending()
|
||||
.OnColumn("createDateUtc")
|
||||
.Ascending()
|
||||
.WithOptions().NonClustered();
|
||||
return localContext.GetSql();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Alter;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Create;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Delete;
|
||||
using Umbraco.Core.Persistence.Migrations.Syntax.Execute;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZero
|
||||
@@ -14,21 +18,37 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZer
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
// defer, because we are making decisions based upon what's in the database
|
||||
Execute.Code(MigrationCode);
|
||||
}
|
||||
|
||||
private string MigrationCode(Database database)
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoRedirectUrl") && x.ColumnName.InvariantEquals("contentKey")))
|
||||
return;
|
||||
return null;
|
||||
|
||||
Execute.Sql("DELETE FROM umbracoRedirectUrl"); // else cannot add non-nullable field
|
||||
var localContext = new LocalMigrationContext(Context.CurrentDatabaseProvider, database, SqlSyntax, Logger);
|
||||
|
||||
Delete.Column("contentId").FromTable("umbracoRedirectUrl");
|
||||
localContext.Execute.Sql("DELETE FROM umbracoRedirectUrl"); // else cannot add non-nullable field
|
||||
|
||||
Alter.Table("umbracoRedirectUrl")
|
||||
.AddColumn("contentKey").AsGuid().NotNullable();
|
||||
localContext.Delete.Column("contentId").FromTable("umbracoRedirectUrl");
|
||||
|
||||
Create.ForeignKey("FK_umbracoRedirectUrl")
|
||||
// SQL CE does not want to alter-add non-nullable columns ;-(
|
||||
// but it's OK to create as nullable then alter, go figure
|
||||
//localContext.Alter.Table("umbracoRedirectUrl")
|
||||
// .AddColumn("contentKey").AsGuid().NotNullable();
|
||||
localContext.Alter.Table("umbracoRedirectUrl")
|
||||
.AddColumn("contentKey").AsGuid().Nullable();
|
||||
localContext.Alter.Table("umbracoRedirectUrl")
|
||||
.AlterColumn("contentKey").AsGuid().NotNullable();
|
||||
|
||||
localContext.Create.ForeignKey("FK_umbracoRedirectUrl")
|
||||
.FromTable("umbracoRedirectUrl").ForeignColumn("contentKey")
|
||||
.ToTable("umbracoNode").PrimaryColumn("uniqueID");
|
||||
|
||||
return localContext.GetSql();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
|
||||
@@ -14,19 +14,32 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZer
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
// defer, because we are making decisions based upon what's in the database
|
||||
Execute.Code(MigrationCode);
|
||||
}
|
||||
private string MigrationCode(Database database)
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoRedirectUrl") && x.ColumnName.InvariantEquals("hurl")))
|
||||
return;
|
||||
return null;
|
||||
|
||||
Execute.Sql("DELETE FROM umbracoRedirectUrl"); // else cannot add non-nullable field
|
||||
var localContext = new LocalMigrationContext(Context.CurrentDatabaseProvider, database, SqlSyntax, Logger);
|
||||
|
||||
Delete.Index("IX_umbracoRedirectUrl").OnTable("umbracoRedirectUrl");
|
||||
localContext.Execute.Sql("DELETE FROM umbracoRedirectUrl"); // else cannot add non-nullable field
|
||||
|
||||
Alter.Table("umbracoRedirectUrl")
|
||||
.AddColumn("hurl").AsString(16).NotNullable();
|
||||
localContext.Delete.Index("IX_umbracoRedirectUrl").OnTable("umbracoRedirectUrl");
|
||||
|
||||
Create.Index("IX_umbracoRedirectUrl").OnTable("umbracoRedirectUrl")
|
||||
// SQL CE does not want to alter-add non-nullable columns ;-(
|
||||
// but it's OK to create as nullable then alter, go figure
|
||||
//localContext.Alter.Table("umbracoRedirectUrl")
|
||||
// .AddColumn("urlHash").AsString(16).NotNullable();
|
||||
localContext.Alter.Table("umbracoRedirectUrl")
|
||||
.AddColumn("hurl").AsString(16).Nullable();
|
||||
localContext.Alter.Table("umbracoRedirectUrl")
|
||||
.AlterColumn("hurl").AsString(16).NotNullable();
|
||||
|
||||
localContext.Create.Index("IX_umbracoRedirectUrl").OnTable("umbracoRedirectUrl")
|
||||
.OnColumn("hurl")
|
||||
.Ascending()
|
||||
.OnColumn("contentKey")
|
||||
@@ -34,6 +47,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZer
|
||||
.OnColumn("createDateUtc")
|
||||
.Descending()
|
||||
.WithOptions().NonClustered();
|
||||
|
||||
return localContext.GetSql();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZero
|
||||
{
|
||||
[Migration("7.5.0", 103, GlobalSettings.UmbracoMigrationName)]
|
||||
public class AddRedirectUrlTable4 : MigrationBase
|
||||
{
|
||||
public AddRedirectUrlTable4(ISqlSyntaxProvider sqlSyntax, ILogger logger)
|
||||
: base(sqlSyntax, logger)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
// defer, because we are making decisions based upon what's in the database
|
||||
Execute.Code(MigrationCode);
|
||||
}
|
||||
private string MigrationCode(Database database)
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoRedirectUrl") && x.ColumnName.InvariantEquals("urlHash")))
|
||||
return null;
|
||||
|
||||
var localContext = new LocalMigrationContext(Context.CurrentDatabaseProvider, database, SqlSyntax, Logger);
|
||||
|
||||
localContext.Execute.Sql("DELETE FROM umbracoRedirectUrl"); // else cannot add non-nullable field
|
||||
|
||||
localContext.Delete.Index("IX_umbracoRedirectUrl").OnTable("umbracoRedirectUrl");
|
||||
|
||||
localContext.Delete.Column("hurl").FromTable("umbracoRedirectUrl");
|
||||
|
||||
// SQL CE does not want to alter-add non-nullable columns ;-(
|
||||
// but it's OK to create as nullable then alter, go figure
|
||||
//localContext.Alter.Table("umbracoRedirectUrl")
|
||||
// .AddColumn("urlHash").AsString(16).NotNullable();
|
||||
localContext.Alter.Table("umbracoRedirectUrl")
|
||||
.AddColumn("urlHash").AsString(16).Nullable();
|
||||
localContext.Alter.Table("umbracoRedirectUrl")
|
||||
.AlterColumn("urlHash").AsString(16).NotNullable();
|
||||
|
||||
localContext.Create.Index("IX_umbracoRedirectUrl").OnTable("umbracoRedirectUrl")
|
||||
.OnColumn("urlHash")
|
||||
.Ascending()
|
||||
.OnColumn("contentKey")
|
||||
.Ascending()
|
||||
.OnColumn("createDateUtc")
|
||||
.Descending()
|
||||
.WithOptions().NonClustered();
|
||||
|
||||
return localContext.GetSql();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ JOIN umbracoNode ON umbracoRedirectUrl.contentKey=umbracoNode.uniqueID");
|
||||
ContentKey = redirectUrl.ContentKey,
|
||||
CreateDateUtc = redirectUrl.CreateDateUtc,
|
||||
Url = redirectUrl.Url,
|
||||
Hurl = HashUrl(redirectUrl.Url)
|
||||
UrlHash = HashUrl(redirectUrl.Url)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -132,8 +132,8 @@ JOIN umbracoNode ON umbracoRedirectUrl.contentKey=umbracoNode.uniqueID");
|
||||
|
||||
public IRedirectUrl Get(string url, Guid contentKey)
|
||||
{
|
||||
var hurl = HashUrl(url);
|
||||
var sql = GetBaseQuery(false).Where<RedirectUrlDto>(x => x.Url == url && x.Hurl == hurl && x.ContentKey == contentKey);
|
||||
var urlHash = HashUrl(url);
|
||||
var sql = GetBaseQuery(false).Where<RedirectUrlDto>(x => x.Url == url && x.UrlHash == urlHash && x.ContentKey == contentKey);
|
||||
var dto = Database.Fetch<RedirectUrlDto>(sql).FirstOrDefault();
|
||||
return dto == null ? null : Map(dto);
|
||||
}
|
||||
@@ -155,9 +155,9 @@ JOIN umbracoNode ON umbracoRedirectUrl.contentKey=umbracoNode.uniqueID");
|
||||
|
||||
public IRedirectUrl GetMostRecentUrl(string url)
|
||||
{
|
||||
var hurl = HashUrl(url);
|
||||
var urlHash = HashUrl(url);
|
||||
var sql = GetBaseQuery(false)
|
||||
.Where<RedirectUrlDto>(x => x.Url == url && x.Hurl == hurl)
|
||||
.Where<RedirectUrlDto>(x => x.Url == url && x.UrlHash == urlHash)
|
||||
.OrderByDescending<RedirectUrlDto>(x => x.CreateDateUtc, SqlSyntax);
|
||||
var dtos = Database.Fetch<RedirectUrlDto>(sql);
|
||||
var dto = dtos.FirstOrDefault();
|
||||
@@ -196,10 +196,10 @@ JOIN umbracoNode ON umbracoRedirectUrl.contentKey=umbracoNode.uniqueID");
|
||||
|
||||
private static string HashUrl(string url)
|
||||
{
|
||||
var h = new MD5CryptoServiceProvider();
|
||||
var i = Encoding.UTF8.GetBytes(url);
|
||||
var o = h.ComputeHash(i);
|
||||
return Encoding.UTF8.GetString(o);
|
||||
var crypto = new MD5CryptoServiceProvider();
|
||||
var inputBytes = Encoding.UTF8.GetBytes(url);
|
||||
var hashedBytes = crypto.ComputeHash(inputBytes);
|
||||
return Encoding.UTF8.GetString(hashedBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,7 +425,9 @@
|
||||
<Compile Include="Persistence\Mappers\AccessMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\DomainMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\MigrationEntryMapper.cs" />
|
||||
<Compile Include="Persistence\Migrations\LocalMigrationContext.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionFourOneZero\AddPreviewXmlTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFiveZero\AddRedirectUrlTable4.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFiveZero\AddRedirectUrlTable3.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFiveZero\AddRedirectUrlTable2.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenFiveZero\EnsureServersLockObject.cs" />
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Semver;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSeven;
|
||||
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZero;
|
||||
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings;
|
||||
|
||||
namespace Umbraco.Tests.Migrations
|
||||
{
|
||||
@@ -90,5 +100,48 @@ namespace Umbraco.Tests.Migrations
|
||||
Assert.AreEqual("[{\"title\":\"\",\"caption\":\"\",\"link\":\"\",\"newWindow\":false,\"type\":\"external\",\"internal\":null,\"edit\":false,\"isInternal\":false}]",
|
||||
data.Text);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Issue8361Test()
|
||||
{
|
||||
var logger = new DebugDiagnosticsLogger();
|
||||
|
||||
//Setup the MigrationRunner
|
||||
var migrationRunner = new MigrationRunner(
|
||||
Mock.Of<IMigrationEntryService>(),
|
||||
logger,
|
||||
new SemVersion(7, 4, 0),
|
||||
new SemVersion(7, 5, 0),
|
||||
GlobalSettings.UmbracoMigrationName,
|
||||
|
||||
//pass in explicit migrations
|
||||
new DeleteRedirectUrlTable(SqlSyntax, logger),
|
||||
new AddRedirectUrlTable(SqlSyntax, logger),
|
||||
new AddRedirectUrlTable2(SqlSyntax, logger),
|
||||
new AddRedirectUrlTable3(SqlSyntax, logger),
|
||||
new AddRedirectUrlTable4(SqlSyntax, logger)
|
||||
);
|
||||
|
||||
var db = new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0", Logger);
|
||||
|
||||
var upgraded = migrationRunner.Execute(db, DatabaseProviders.SqlServerCE, true);
|
||||
Assert.IsTrue(upgraded);
|
||||
}
|
||||
|
||||
[Migration("7.5.0", 99, GlobalSettings.UmbracoMigrationName)]
|
||||
public class DeleteRedirectUrlTable : MigrationBase
|
||||
{
|
||||
public DeleteRedirectUrlTable(ISqlSyntaxProvider sqlSyntax, ILogger logger)
|
||||
: base(sqlSyntax, logger)
|
||||
{ }
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
Delete.Table("umbracoRedirectUrl");
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user