2020-12-23 11:35:49 +01:00
|
|
|
// Copyright (c) Umbraco.
|
|
|
|
|
// See LICENSE for more details.
|
|
|
|
|
|
|
|
|
|
using System;
|
2017-12-21 15:16:28 +01:00
|
|
|
using System.Linq;
|
2021-08-17 11:13:46 -06:00
|
|
|
using System.Threading.Tasks;
|
2020-09-17 12:52:25 +02:00
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
2017-11-01 10:42:46 +01:00
|
|
|
using Moq;
|
|
|
|
|
using NUnit.Framework;
|
2021-02-09 10:22:42 +01:00
|
|
|
using Umbraco.Cms.Core.Configuration;
|
2021-04-16 11:37:01 +02:00
|
|
|
using Umbraco.Cms.Core.Events;
|
2021-06-09 16:18:15 +10:00
|
|
|
using Umbraco.Cms.Core.Migrations;
|
2021-02-15 11:41:12 +01:00
|
|
|
using Umbraco.Cms.Core.Scoping;
|
2021-02-09 10:22:42 +01:00
|
|
|
using Umbraco.Cms.Core.Services;
|
2021-02-12 12:40:08 +01:00
|
|
|
using Umbraco.Cms.Infrastructure.Migrations;
|
|
|
|
|
using Umbraco.Cms.Infrastructure.Migrations.Install;
|
|
|
|
|
using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
|
2021-02-12 13:36:50 +01:00
|
|
|
using Umbraco.Cms.Infrastructure.Persistence.DatabaseModelDefinitions;
|
|
|
|
|
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
|
2021-02-10 14:45:44 +01:00
|
|
|
using Umbraco.Cms.Tests.Common.Testing;
|
2021-02-11 08:30:27 +01:00
|
|
|
using Umbraco.Cms.Tests.Integration.Testing;
|
2017-11-01 10:42:46 +01:00
|
|
|
|
2021-02-11 08:30:27 +01:00
|
|
|
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Migrations
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
|
|
|
|
[TestFixture]
|
|
|
|
|
[UmbracoTest(Database = UmbracoTestOptions.Database.NewEmptyPerTest)]
|
2020-12-08 09:19:51 +01:00
|
|
|
public class AdvancedMigrationTests : UmbracoIntegrationTest
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
2020-12-08 09:19:51 +01:00
|
|
|
private IUmbracoVersion UmbracoVersion => GetRequiredService<IUmbracoVersion>();
|
2021-04-16 11:37:01 +02:00
|
|
|
private IEventAggregator EventAggregator => GetRequiredService<IEventAggregator>();
|
2021-06-09 16:18:15 +10:00
|
|
|
private IMigrationPlanExecutor MigrationPlanExecutor => GetRequiredService<IMigrationPlanExecutor>();
|
2020-12-08 09:19:51 +01:00
|
|
|
|
2017-11-01 10:42:46 +01:00
|
|
|
[Test]
|
2021-08-18 12:01:56 -06:00
|
|
|
public void CreateTableOfTDto()
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
2020-12-23 11:35:49 +01:00
|
|
|
IMigrationBuilder builder = Mock.Of<IMigrationBuilder>();
|
2017-12-21 15:16:28 +01:00
|
|
|
Mock.Get(builder)
|
2017-12-22 12:29:56 +01:00
|
|
|
.Setup(x => x.Build(It.IsAny<Type>(), It.IsAny<IMigrationContext>()))
|
2017-12-21 15:16:28 +01:00
|
|
|
.Returns<Type, IMigrationContext>((t, c) =>
|
|
|
|
|
{
|
|
|
|
|
if (t != typeof(CreateTableOfTDtoMigration))
|
2020-12-23 11:35:49 +01:00
|
|
|
{
|
2017-12-21 15:16:28 +01:00
|
|
|
throw new NotSupportedException();
|
2020-12-23 11:35:49 +01:00
|
|
|
}
|
|
|
|
|
|
2017-12-21 15:16:28 +01:00
|
|
|
return new CreateTableOfTDtoMigration(c);
|
|
|
|
|
});
|
|
|
|
|
|
2020-12-23 11:35:49 +01:00
|
|
|
using (IScope scope = ScopeProvider.CreateScope())
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
2018-12-06 07:48:26 +01:00
|
|
|
var upgrader = new Upgrader(
|
2018-07-04 15:07:09 +02:00
|
|
|
new MigrationPlan("test")
|
2018-12-04 17:01:33 +01:00
|
|
|
.From(string.Empty)
|
|
|
|
|
.To<CreateTableOfTDtoMigration>("done"));
|
2017-12-22 12:29:56 +01:00
|
|
|
|
2021-08-18 12:01:56 -06:00
|
|
|
upgrader.Execute(MigrationPlanExecutor, ScopeProvider, Mock.Of<IKeyValueService>());
|
2017-11-01 10:42:46 +01:00
|
|
|
|
2021-04-16 11:37:01 +02:00
|
|
|
var helper = new DatabaseSchemaCreator(scope.Database, LoggerFactory.CreateLogger<DatabaseSchemaCreator>(), LoggerFactory, UmbracoVersion, EventAggregator);
|
2020-12-23 11:35:49 +01:00
|
|
|
bool exists = helper.TableExists("umbracoUser");
|
2017-11-01 10:42:46 +01:00
|
|
|
Assert.IsTrue(exists);
|
|
|
|
|
|
|
|
|
|
scope.Complete();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
2021-08-18 12:01:56 -06:00
|
|
|
public void DeleteKeysAndIndexesOfTDto()
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
2020-12-23 11:35:49 +01:00
|
|
|
IMigrationBuilder builder = Mock.Of<IMigrationBuilder>();
|
2017-12-21 15:16:28 +01:00
|
|
|
Mock.Get(builder)
|
2017-12-22 12:29:56 +01:00
|
|
|
.Setup(x => x.Build(It.IsAny<Type>(), It.IsAny<IMigrationContext>()))
|
2017-12-21 15:16:28 +01:00
|
|
|
.Returns<Type, IMigrationContext>((t, c) =>
|
|
|
|
|
{
|
|
|
|
|
switch (t.Name)
|
|
|
|
|
{
|
|
|
|
|
case "CreateTableOfTDtoMigration":
|
|
|
|
|
return new CreateTableOfTDtoMigration(c);
|
|
|
|
|
case "DeleteKeysAndIndexesMigration":
|
|
|
|
|
return new DeleteKeysAndIndexesMigration(c);
|
|
|
|
|
default:
|
|
|
|
|
throw new NotSupportedException();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2020-12-23 11:35:49 +01:00
|
|
|
using (IScope scope = ScopeProvider.CreateScope())
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
2018-12-06 07:48:26 +01:00
|
|
|
var upgrader = new Upgrader(
|
2018-07-04 15:07:09 +02:00
|
|
|
new MigrationPlan("test")
|
2018-12-04 17:01:33 +01:00
|
|
|
.From(string.Empty)
|
|
|
|
|
.To<CreateTableOfTDtoMigration>("a")
|
|
|
|
|
.To<DeleteKeysAndIndexesMigration>("done"));
|
2017-11-01 10:42:46 +01:00
|
|
|
|
2021-08-18 12:01:56 -06:00
|
|
|
upgrader.Execute(MigrationPlanExecutor, ScopeProvider, Mock.Of<IKeyValueService>());
|
2017-11-01 10:42:46 +01:00
|
|
|
scope.Complete();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
2021-08-18 12:01:56 -06:00
|
|
|
public void CreateKeysAndIndexesOfTDto()
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
2020-12-23 11:35:49 +01:00
|
|
|
IMigrationBuilder builder = Mock.Of<IMigrationBuilder>();
|
2017-12-21 15:16:28 +01:00
|
|
|
Mock.Get(builder)
|
2017-12-22 12:29:56 +01:00
|
|
|
.Setup(x => x.Build(It.IsAny<Type>(), It.IsAny<IMigrationContext>()))
|
2017-12-21 15:16:28 +01:00
|
|
|
.Returns<Type, IMigrationContext>((t, c) =>
|
|
|
|
|
{
|
|
|
|
|
switch (t.Name)
|
|
|
|
|
{
|
|
|
|
|
case "CreateTableOfTDtoMigration":
|
|
|
|
|
return new CreateTableOfTDtoMigration(c);
|
|
|
|
|
case "DeleteKeysAndIndexesMigration":
|
|
|
|
|
return new DeleteKeysAndIndexesMigration(c);
|
|
|
|
|
case "CreateKeysAndIndexesOfTDtoMigration":
|
|
|
|
|
return new CreateKeysAndIndexesOfTDtoMigration(c);
|
|
|
|
|
default:
|
|
|
|
|
throw new NotSupportedException();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2020-12-23 11:35:49 +01:00
|
|
|
using (IScope scope = ScopeProvider.CreateScope())
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
2018-12-06 07:48:26 +01:00
|
|
|
var upgrader = new Upgrader(
|
2018-07-04 15:07:09 +02:00
|
|
|
new MigrationPlan("test")
|
2018-12-04 17:01:33 +01:00
|
|
|
.From(string.Empty)
|
|
|
|
|
.To<CreateTableOfTDtoMigration>("a")
|
|
|
|
|
.To<DeleteKeysAndIndexesMigration>("b")
|
|
|
|
|
.To<CreateKeysAndIndexesOfTDtoMigration>("done"));
|
2017-11-01 10:42:46 +01:00
|
|
|
|
2021-08-18 12:01:56 -06:00
|
|
|
upgrader.Execute(MigrationPlanExecutor, ScopeProvider, Mock.Of<IKeyValueService>());
|
2017-11-01 10:42:46 +01:00
|
|
|
scope.Complete();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
2021-08-18 12:01:56 -06:00
|
|
|
public void CreateKeysAndIndexes()
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
2020-12-23 11:35:49 +01:00
|
|
|
IMigrationBuilder builder = Mock.Of<IMigrationBuilder>();
|
2017-12-21 15:16:28 +01:00
|
|
|
Mock.Get(builder)
|
2017-12-22 12:29:56 +01:00
|
|
|
.Setup(x => x.Build(It.IsAny<Type>(), It.IsAny<IMigrationContext>()))
|
2017-12-21 15:16:28 +01:00
|
|
|
.Returns<Type, IMigrationContext>((t, c) =>
|
|
|
|
|
{
|
|
|
|
|
switch (t.Name)
|
|
|
|
|
{
|
|
|
|
|
case "CreateTableOfTDtoMigration":
|
|
|
|
|
return new CreateTableOfTDtoMigration(c);
|
|
|
|
|
case "DeleteKeysAndIndexesMigration":
|
|
|
|
|
return new DeleteKeysAndIndexesMigration(c);
|
|
|
|
|
case "CreateKeysAndIndexesMigration":
|
|
|
|
|
return new CreateKeysAndIndexesMigration(c);
|
|
|
|
|
default:
|
|
|
|
|
throw new NotSupportedException();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2020-12-23 11:35:49 +01:00
|
|
|
using (IScope scope = ScopeProvider.CreateScope())
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
2018-12-06 07:48:26 +01:00
|
|
|
var upgrader = new Upgrader(
|
2018-07-04 15:07:09 +02:00
|
|
|
new MigrationPlan("test")
|
2018-12-04 17:01:33 +01:00
|
|
|
.From(string.Empty)
|
|
|
|
|
.To<CreateTableOfTDtoMigration>("a")
|
|
|
|
|
.To<DeleteKeysAndIndexesMigration>("b")
|
|
|
|
|
.To<CreateKeysAndIndexesMigration>("done"));
|
2017-11-01 10:42:46 +01:00
|
|
|
|
2021-08-18 12:01:56 -06:00
|
|
|
upgrader.Execute(MigrationPlanExecutor, ScopeProvider, Mock.Of<IKeyValueService>());
|
2017-11-01 10:42:46 +01:00
|
|
|
scope.Complete();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-01 15:35:37 +01:00
|
|
|
[Test]
|
2021-08-18 12:01:56 -06:00
|
|
|
public void CreateColumn()
|
2017-11-01 15:35:37 +01:00
|
|
|
{
|
2020-12-23 11:35:49 +01:00
|
|
|
IMigrationBuilder builder = Mock.Of<IMigrationBuilder>();
|
2017-12-21 15:16:28 +01:00
|
|
|
Mock.Get(builder)
|
2017-12-22 12:29:56 +01:00
|
|
|
.Setup(x => x.Build(It.IsAny<Type>(), It.IsAny<IMigrationContext>()))
|
2017-12-21 15:16:28 +01:00
|
|
|
.Returns<Type, IMigrationContext>((t, c) =>
|
|
|
|
|
{
|
|
|
|
|
switch (t.Name)
|
|
|
|
|
{
|
|
|
|
|
case "CreateTableOfTDtoMigration":
|
|
|
|
|
return new CreateTableOfTDtoMigration(c);
|
|
|
|
|
case "CreateColumnMigration":
|
|
|
|
|
return new CreateColumnMigration(c);
|
|
|
|
|
default:
|
|
|
|
|
throw new NotSupportedException();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2020-12-23 11:35:49 +01:00
|
|
|
using (IScope scope = ScopeProvider.CreateScope())
|
2017-11-01 15:35:37 +01:00
|
|
|
{
|
2018-12-06 07:48:26 +01:00
|
|
|
var upgrader = new Upgrader(
|
2018-07-04 15:07:09 +02:00
|
|
|
new MigrationPlan("test")
|
2018-12-04 17:01:33 +01:00
|
|
|
.From(string.Empty)
|
|
|
|
|
.To<CreateTableOfTDtoMigration>("a")
|
|
|
|
|
.To<CreateColumnMigration>("done"));
|
2017-11-01 15:35:37 +01:00
|
|
|
|
2021-08-18 12:01:56 -06:00
|
|
|
upgrader.Execute(MigrationPlanExecutor, ScopeProvider, Mock.Of<IKeyValueService>());
|
2017-11-01 15:35:37 +01:00
|
|
|
scope.Complete();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-01 10:42:46 +01:00
|
|
|
public class CreateTableOfTDtoMigration : MigrationBase
|
|
|
|
|
{
|
|
|
|
|
public CreateTableOfTDtoMigration(IMigrationContext context)
|
|
|
|
|
: base(context)
|
|
|
|
|
{
|
|
|
|
|
}
|
2020-12-23 11:35:49 +01:00
|
|
|
|
2021-06-24 13:35:57 -06:00
|
|
|
protected override void Migrate() =>
|
2020-12-23 11:35:49 +01:00
|
|
|
|
|
|
|
|
// Create User table with keys, indexes, etc.
|
|
|
|
|
Create.Table<UserDto>().Do();
|
2017-11-01 10:42:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class DeleteKeysAndIndexesMigration : MigrationBase
|
|
|
|
|
{
|
|
|
|
|
public DeleteKeysAndIndexesMigration(IMigrationContext context)
|
|
|
|
|
: base(context)
|
2020-12-23 11:35:49 +01:00
|
|
|
{
|
|
|
|
|
}
|
2017-11-01 10:42:46 +01:00
|
|
|
|
2021-06-24 13:35:57 -06:00
|
|
|
protected override void Migrate()
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
2018-06-04 18:12:23 +02:00
|
|
|
// drops User table keys and indexes
|
2020-12-23 11:35:49 +01:00
|
|
|
// Execute.DropKeysAndIndexes("umbracoUser");
|
2017-11-01 10:42:46 +01:00
|
|
|
|
|
|
|
|
// drops *all* tables keys and indexes
|
2019-05-07 19:28:51 +02:00
|
|
|
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToList();
|
2020-12-23 11:35:49 +01:00
|
|
|
foreach (string table in tables)
|
|
|
|
|
{
|
2019-05-28 17:49:50 +02:00
|
|
|
Delete.KeysAndIndexes(table, false, true).Do();
|
2020-12-23 11:35:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (string table in tables)
|
|
|
|
|
{
|
2019-05-28 17:49:50 +02:00
|
|
|
Delete.KeysAndIndexes(table, true, false).Do();
|
2020-12-23 11:35:49 +01:00
|
|
|
}
|
2017-11-01 10:42:46 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class CreateKeysAndIndexesOfTDtoMigration : MigrationBase
|
|
|
|
|
{
|
|
|
|
|
public CreateKeysAndIndexesOfTDtoMigration(IMigrationContext context)
|
|
|
|
|
: base(context)
|
|
|
|
|
{
|
|
|
|
|
}
|
2020-12-23 11:35:49 +01:00
|
|
|
|
2021-06-24 13:35:57 -06:00
|
|
|
protected override void Migrate() =>
|
2020-12-23 11:35:49 +01:00
|
|
|
|
|
|
|
|
// Create User table keys and indexes.
|
|
|
|
|
Create.KeysAndIndexes<UserDto>().Do();
|
2017-11-01 10:42:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class CreateKeysAndIndexesMigration : MigrationBase
|
|
|
|
|
{
|
|
|
|
|
public CreateKeysAndIndexesMigration(IMigrationContext context)
|
|
|
|
|
: base(context)
|
2020-12-23 11:35:49 +01:00
|
|
|
{
|
|
|
|
|
}
|
2017-11-01 10:42:46 +01:00
|
|
|
|
2021-06-24 13:35:57 -06:00
|
|
|
protected override void Migrate()
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
2020-12-23 11:35:49 +01:00
|
|
|
// Creates *all* tables keys and indexes
|
|
|
|
|
foreach (Type x in DatabaseSchemaCreator.OrderedTables)
|
2017-11-01 10:42:46 +01:00
|
|
|
{
|
|
|
|
|
// ok - for tests, restrict to Node
|
2020-12-23 11:35:49 +01:00
|
|
|
if (x != typeof(UserDto))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2017-11-01 10:42:46 +01:00
|
|
|
|
2018-03-21 14:40:59 +01:00
|
|
|
Create.KeysAndIndexes(x).Do();
|
2017-11-01 10:42:46 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-11-01 15:35:37 +01:00
|
|
|
|
|
|
|
|
public class CreateColumnMigration : MigrationBase
|
|
|
|
|
{
|
|
|
|
|
public CreateColumnMigration(IMigrationContext context)
|
|
|
|
|
: base(context)
|
2020-12-23 11:35:49 +01:00
|
|
|
{
|
|
|
|
|
}
|
2017-11-01 15:35:37 +01:00
|
|
|
|
2021-06-24 13:35:57 -06:00
|
|
|
protected override void Migrate()
|
2017-11-01 15:35:37 +01:00
|
|
|
{
|
|
|
|
|
// cannot delete the column without this, of course
|
2019-05-07 19:28:51 +02:00
|
|
|
Delete.KeysAndIndexes("umbracoUser").Do();
|
2017-11-01 15:35:37 +01:00
|
|
|
|
2018-06-04 18:12:23 +02:00
|
|
|
Delete.Column("id").FromTable("umbracoUser").Do();
|
2017-11-01 15:35:37 +01:00
|
|
|
|
2020-12-23 11:35:49 +01:00
|
|
|
TableDefinition table = DefinitionFactory.GetTableDefinition(typeof(UserDto), SqlSyntax);
|
|
|
|
|
ColumnDefinition column = table.Columns.First(x => x.Name == "id");
|
|
|
|
|
string create = SqlSyntax.Format(column); // returns [id] INTEGER NOT NULL IDENTITY(1060,1)
|
2018-06-04 18:12:23 +02:00
|
|
|
Database.Execute($"ALTER TABLE {SqlSyntax.GetQuotedTableName("umbracoUser")} ADD " + create);
|
2017-11-01 15:35:37 +01:00
|
|
|
}
|
|
|
|
|
}
|
2017-11-01 10:42:46 +01:00
|
|
|
}
|
|
|
|
|
}
|