V14: Migration Cleanup (#15629)

* Remove obsoleted migrations

* Re-add default log queries

* Remove unused PreValueMigratorCollectionBuilder from DI

* Remove unused unit test

* Obsolete unused migrations

* Remove migrations prior to v13 from UmbracoPlan

* Fix whitespace

* Use array instead of IEnumerable

* Remove unused migrations
This commit is contained in:
Mole
2024-01-31 12:45:56 +01:00
committed by GitHub
parent aaf7075313
commit 008083f096
89 changed files with 59 additions and 4386 deletions

View File

@@ -36,7 +36,6 @@ using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Implement;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Core.Templates;
using Umbraco.Cms.Core.Trees;
@@ -54,7 +53,6 @@ using Umbraco.Cms.Infrastructure.Manifest;
using Umbraco.Cms.Infrastructure.Migrations;
using Umbraco.Cms.Infrastructure.Migrations.Install;
using Umbraco.Cms.Infrastructure.Migrations.PostMigrations;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0.DataTypes;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Mappers;
using Umbraco.Cms.Infrastructure.Routing;
@@ -156,8 +154,6 @@ public static partial class UmbracoBuilderExtensions
builder.Services.AddSingleton<IMigrationPlanExecutor, MigrationPlanExecutor>();
builder.Services.AddSingleton<IMigrationBuilder>(factory => new MigrationBuilder(factory));
builder.AddPreValueMigrators();
builder.Services.AddSingleton<IPublishedSnapshotRebuilder, PublishedSnapshotRebuilder>();
// register the published snapshot accessor - the "current" published snapshot is in the umbraco context
@@ -332,13 +328,6 @@ public static partial class UmbracoBuilderExtensions
return builder;
}
private static IUmbracoBuilder AddPreValueMigrators(this IUmbracoBuilder builder)
{
builder.WithCollectionBuilder<PreValueMigratorCollectionBuilder>();
return builder;
}
public static IUmbracoBuilder AddCoreNotifications(this IUmbracoBuilder builder)
{
// add handlers for sending user notifications (i.e. emails)

View File

@@ -8,7 +8,6 @@ using Umbraco.Cms.Core.Configuration;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
@@ -19,6 +18,61 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Install;
/// </summary>
internal class DatabaseDataCreator
{
internal static readonly LogViewerQueryDto[] _defaultLogQueries =
[
new()
{
Name = "Find all logs where the Level is NOT Verbose and NOT Debug",
Query = "Not(@Level='Verbose') and Not(@Level='Debug')",
},
new()
{
Name = "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)",
Query = "Has(@Exception)",
},
new()
{
Name = "Find all logs that have the property 'Duration'",
Query = "Has(Duration)",
},
new()
{
Name = "Find all logs that have the property 'Duration' and the duration is greater than 1000ms",
Query = "Has(Duration) and Duration > 1000",
},
new()
{
Name = "Find all logs that are from the namespace 'Umbraco.Core'",
Query = "StartsWith(SourceContext, 'Umbraco.Core')",
},
new()
{
Name = "Find all logs that use a specific log message template",
Query = "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'",
},
new()
{
Name = "Find logs where one of the items in the SortedComponentTypes property array is equal to",
Query = "SortedComponentTypes[?] = 'Umbraco.Web.Search.ExamineComponent'",
},
new()
{
Name = "Find logs where one of the items in the SortedComponentTypes property array contains",
Query = "Contains(SortedComponentTypes[?], 'DatabaseServer')",
},
new()
{
Name = "Find all logs that the message has localhost in it with SQL like",
Query = "@Message like '%localhost%'",
},
new()
{
Name = "Find all logs that the message that starts with 'end' in it with SQL like",
Query = "@Message like 'end%'",
}
];
private readonly IDatabase _database;
private readonly IDictionary<string, IList<string>> _entitiesToAlwaysCreate = new Dictionary<string, IList<string>>
@@ -2299,11 +2353,9 @@ internal class DatabaseDataCreator
private void CreateLogViewerQueryData()
{
LogViewerQueryDto[] defaultData = MigrateLogViewerQueriesFromFileToDb._defaultLogQueries.ToArray();
for (var i = 0; i < defaultData.Length; i++)
for (var i = 0; i < _defaultLogQueries.Length; i++)
{
LogViewerQueryDto dto = defaultData[i];
LogViewerQueryDto dto = _defaultLogQueries[i];
dto.Id = i + 1;
_database.Insert(Constants.DatabaseSchema.Tables.LogViewerQuery, "id", false, dto);
}

View File

@@ -1,7 +1,5 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_10_7_0;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_14_0_0;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade;
@@ -54,48 +52,6 @@ public class UmbracoPlan : MigrationPlan
From(InitialState);
// To 10.0.0
To<V_10_0_0.AddMemberPropertiesAsColumns>("{B7E0D53C-2B0E-418B-AB07-2DDE486E225F}");
// To 10.2.0
To<V_10_2_0.AddUserGroup2LanguageTable>("{D0B3D29D-F4D5-43E3-BA67-9D49256F3266}");
To<V_10_2_0.AddHasAccessToAllLanguagesColumn>("{79D8217B-5920-4C0E-8E9A-3CF8FA021882}");
// To 10.3.0
To<V_10_3_0.AddBlockGridPartialViews>("{56833770-3B7E-4FD5-A3B6-3416A26A7A3F}");
// To 10.4.0
To<V_10_4_0.AddBlockGridPartialViews>("{3F5D492A-A3DB-43F9-A73E-9FEE3B180E6C}");
// To 10.5.0 / 11.2.0
To<V_10_5_0.AddPrimaryKeyConstrainToContentVersionCleanupDtos>("{83AF7945-DADE-4A02-9041-F3F6EBFAC319}");
// to 10.7.0
To<MigrateTagsFromNVarcharToNText>("{EF93F398-1385-4F07-808A-D3C518984442}");
// To 11.3.0
To<V_11_3_0.AddDomainSortOrder>("{BB3889ED-E2DE-49F2-8F71-5FD8616A2661}");
// To 11.4.0
To<V_11_4_0.AlterKeyValueDataType>("{FFB6B9B0-F1A8-45E9-9CD7-25700577D1CA}");
// to 11.4.3
// This is here twice since it was added in 10, so if you had already upgraded you wouldn't get it
// But we still need the first once, since if you upgraded to 10.7.0 then the "From" state would be unknown otherwise.
// This has it's own key, we essentially consider it a separate migration.
To<MigrateTagsFromNVarcharToNText>("{2CA0C5BB-170B-45E5-8179-E73DA4B41A46}");
// To 12.0.0
To<V_12_0_0.UseNvarcharInsteadOfNText>("{888A0D5D-51E4-4C7E-AA0A-01306523C7FB}");
To<V_12_0_0.ResetCache>("{539F2F83-FBA7-4C48-81A3-75081A56BB9D}");
// To 12.1.0
To<V_12_1_0.TablesIndexesImprovement>("{1187192D-EDB5-4619-955D-91D48D738871}");
To<V_12_1_0.AddOpenIddict>("{47DE85CE-1E16-42A0-8AF6-3EC3BCEF5471}");
// And once more for 12
To<MigrateTagsFromNVarcharToNText>("{2D4C9FBD-08B3-472D-A76C-6ED467A0CD20}");
// To 13.0.0
To<V_13_0_0.AddWebhooks>("{C76D9C9A-635B-4D2C-A301-05642A523E9D}");
To<V_13_0_0.RenameEventNameColumn>("{D5139400-E507-4259-A542-C67358F7E329}");

View File

@@ -1,253 +0,0 @@
using System.Text;
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_10_0_0;
public class AddMemberPropertiesAsColumns : MigrationBase
{
public AddMemberPropertiesAsColumns(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToList();
AddColumnIfNotExists<MemberDto>(columns, "failedPasswordAttempts");
AddColumnIfNotExists<MemberDto>(columns, "isLockedOut");
AddColumnIfNotExists<MemberDto>(columns, "isApproved");
AddColumnIfNotExists<MemberDto>(columns, "lastLoginDate");
AddColumnIfNotExists<MemberDto>(columns, "lastLockoutDate");
AddColumnIfNotExists<MemberDto>(columns, "lastPasswordChangeDate");
Sql<ISqlContext> newestContentVersionQuery = Database.SqlContext.Sql()
.Select(
$"MAX({GetQuotedSelector("cv", "id")}) as {SqlSyntax.GetQuotedColumnName("id")}",
GetQuotedSelector("cv", "nodeId"))
.From<ContentVersionDto>("cv")
.GroupBy(GetQuotedSelector("cv", "nodeId"));
Sql<ISqlContext> passwordAttemptsQuery = Database.SqlContext.Sql()
.Select(GetSubQueryColumns())
.From<PropertyTypeDto>("pt")
.Where($"{GetQuotedSelector("pt", "Alias")} = 'umbracoMemberFailedPasswordAttempts'");
Sql<ISqlContext> memberApprovedQuery = Database.SqlContext.Sql()
.Select(GetSubQueryColumns())
.From<PropertyTypeDto>("pt")
.Where($"{GetQuotedSelector("pt", "Alias")} = 'umbracoMemberApproved'");
Sql<ISqlContext> memberLockedOutQuery = Database.SqlContext.Sql()
.Select(GetSubQueryColumns())
.From<PropertyTypeDto>("pt")
.Where($"{GetQuotedSelector("pt", "Alias")} = 'umbracoMemberLockedOut'");
Sql<ISqlContext> memberLastLockoutDateQuery = Database.SqlContext.Sql()
.Select(GetSubQueryColumns())
.From<PropertyTypeDto>("pt")
.Where($"{GetQuotedSelector("pt", "Alias")} = 'umbracoMemberLastLockoutDate'");
Sql<ISqlContext> memberLastLoginDateQuery = Database.SqlContext.Sql()
.Select(GetSubQueryColumns())
.From<PropertyTypeDto>("pt")
.Where($"{GetQuotedSelector("pt", "Alias")} = 'umbracoMemberLastLogin'");
Sql<ISqlContext> memberLastPasswordChangeDateQuery = Database.SqlContext.Sql()
.Select(GetSubQueryColumns())
.From<PropertyTypeDto>("pt")
.Where($"{GetQuotedSelector("pt", "Alias")} = 'umbracoMemberLastPasswordChangeDate'");
var queryBuilder = new StringBuilder();
queryBuilder.AppendLine($"UPDATE {Constants.DatabaseSchema.Tables.Member}");
queryBuilder.AppendLine("SET");
queryBuilder.AppendLine(
$"\t{Database.SqlContext.SqlSyntax.GetFieldNameForUpdate<MemberDto>(x => x.FailedPasswordAttempts)} = {GetQuotedSelector("umbracoPropertyData", "intValue")},");
queryBuilder.AppendLine(
$"\t{Database.SqlContext.SqlSyntax.GetFieldNameForUpdate<MemberDto>(x => x.IsApproved)} = {GetQuotedSelector("pdmp", "intValue")},");
queryBuilder.AppendLine(
$"\t{Database.SqlContext.SqlSyntax.GetFieldNameForUpdate<MemberDto>(x => x.IsLockedOut)} = {GetQuotedSelector("pdlo", "intValue")},");
queryBuilder.AppendLine(
$"\t{Database.SqlContext.SqlSyntax.GetFieldNameForUpdate<MemberDto>(x => x.LastLockoutDate)} = {GetQuotedSelector("pdlout", "dateValue")},");
queryBuilder.AppendLine(
$"\t{Database.SqlContext.SqlSyntax.GetFieldNameForUpdate<MemberDto>(x => x.LastLoginDate)} = {GetQuotedSelector("pdlin", "dateValue")},");
queryBuilder.Append(
$"\t{Database.SqlContext.SqlSyntax.GetFieldNameForUpdate<MemberDto>(x => x.LastPasswordChangeDate)} = {GetQuotedSelector("pdlpc", "dateValue")}");
Sql<ISqlContext> updateMemberColumnsQuery = Database.SqlContext.Sql(queryBuilder.ToString())
.From<NodeDto>()
.InnerJoin<ContentDto>()
.On<NodeDto, ContentDto>((left, right) => left.NodeId == right.NodeId)
.InnerJoin<ContentTypeDto>()
.On<ContentDto, ContentTypeDto>((left, right) => left.ContentTypeId == right.NodeId)
.InnerJoin(newestContentVersionQuery, "umbracoContentVersion")
.On<NodeDto, ContentVersionDto>((left, right) => left.NodeId == right.NodeId)
.InnerJoin<MemberDto>("m")
.On<ContentDto, MemberDto>((left, right) => left.NodeId == right.NodeId, null, "m")
.LeftJoin(passwordAttemptsQuery, "failedAttemptsType")
.On<ContentDto, FailedAttempts>((left, right) => left.ContentTypeId == right.ContentTypeId)
.LeftJoin<DataTypeDto>()
.On<FailedAttempts, DataTypeDto>((left, right) => left.DataTypeId == right.NodeId)
.LeftJoin<PropertyDataDto>()
.On<PropertyDataDto, FailedAttempts, ContentVersionDto>((left, middle, right) =>
left.PropertyTypeId == middle.Id && left.VersionId == right.Id)
.LeftJoin(memberApprovedQuery, "memberApprovedType")
.On<ContentDto, MemberApproved>((left, right) => left.ContentTypeId == right.ContentTypeId)
.LeftJoin<DataTypeDto>("dtmp")
.On<MemberApproved, DataTypeDto>((left, right) => left.DataTypeId == right.NodeId, null, "dtmp")
.LeftJoin<PropertyDataDto>("pdmp")
.On<PropertyDataDto, MemberApproved, ContentVersionDto>(
(left, middle, right) => left.PropertyTypeId == middle.Id && left.VersionId == right.Id, "pdmp")
.LeftJoin(memberLockedOutQuery, "memberLockedOutType")
.On<ContentDto, MemberLockedOut>((left, right) => left.ContentTypeId == right.ContentTypeId)
.LeftJoin<DataTypeDto>("dtlo")
.On<MemberLockedOut, DataTypeDto>((left, right) => left.DataTypeId == right.NodeId, null, "dtlo")
.LeftJoin<PropertyDataDto>("pdlo")
.On<PropertyDataDto, MemberLockedOut, ContentVersionDto>(
(left, middle, right) => left.PropertyTypeId == middle.Id && left.VersionId == right.Id, "pdlo")
.LeftJoin(memberLastLockoutDateQuery, "lastLockOutDateType")
.On<ContentDto, LastLockoutDate>((left, right) => left.ContentTypeId == right.ContentTypeId)
.LeftJoin<DataTypeDto>("dtlout")
.On<LastLockoutDate, DataTypeDto>((left, right) => left.DataTypeId == right.NodeId, null, "dtlout")
.LeftJoin<PropertyDataDto>("pdlout")
.On<PropertyDataDto, LastLockoutDate, ContentVersionDto>(
(left, middle, right) => left.PropertyTypeId == middle.Id && left.VersionId == right.Id, "pdlout")
.LeftJoin(memberLastLoginDateQuery, "lastLoginDateType")
.On<ContentDto, LastLoginDate>((left, right) => left.ContentTypeId == right.ContentTypeId)
.LeftJoin<DataTypeDto>("dtlin")
.On<LastLoginDate, DataTypeDto>((left, right) => left.DataTypeId == right.NodeId, null, "dtlin")
.LeftJoin<PropertyDataDto>("pdlin")
.On<PropertyDataDto, LastLoginDate, ContentVersionDto>(
(left, middle, right) => left.PropertyTypeId == middle.Id && left.VersionId == right.Id, "pdlin")
.LeftJoin(memberLastPasswordChangeDateQuery, "lastPasswordChangeType")
.On<ContentDto, LastPasswordChange>((left, right) => left.ContentTypeId == right.ContentTypeId)
.LeftJoin<DataTypeDto>("dtlpc")
.On<LastPasswordChange, DataTypeDto>((left, right) => left.DataTypeId == right.NodeId, null, "dtlpc")
.LeftJoin<PropertyDataDto>("pdlpc")
.On<PropertyDataDto, LastPasswordChange, ContentVersionDto>(
(left, middle, right) => left.PropertyTypeId == middle.Id && left.VersionId == right.Id, "pdlpc")
.Where<NodeDto>(x => x.NodeObjectType == Constants.ObjectTypes.Member);
Database.Execute(updateMemberColumnsQuery);
// Removing old property types and values, since these are no longer needed
// Hard coding the aliases, since we want to be able to delete the constants...
string[] propertyTypesToDelete =
{
"umbracoMemberFailedPasswordAttempts",
"umbracoMemberApproved",
"umbracoMemberLockedOut",
"umbracoMemberLastLockoutDate",
"umbracoMemberLastLogin",
"umbracoMemberLastPasswordChangeDate",
};
Sql<ISqlContext> idQuery = Database.SqlContext.Sql().Select<PropertyTypeDto>(x => x.Id)
.From<PropertyTypeDto>()
.WhereIn<PropertyTypeDto>(x => x.Alias, propertyTypesToDelete);
List<int> idsToDelete = Database.Fetch<int>(idQuery);
// Firstly deleting the property data due to FK constraints
Sql<ISqlContext> propertyDataDelete = Database.SqlContext.Sql()
.Delete<PropertyDataDto>()
.WhereIn<PropertyDataDto>(x => x.PropertyTypeId, idsToDelete);
Database.Execute(propertyDataDelete);
// Then we can remove the property
Sql<ISqlContext> propertyTypeDelete = Database.SqlContext.Sql()
.Delete<PropertyTypeDto>()
.WhereIn<PropertyTypeDto>(x => x.Id, idsToDelete);
Database.Execute(propertyTypeDelete);
}
private string GetQuotedSelector(string tableName, string columnName)
=> $"{SqlSyntax.GetQuotedTableName(tableName)}.{SqlSyntax.GetQuotedColumnName(columnName)}";
private object[] GetSubQueryColumns() => new object[]
{
SqlSyntax.GetQuotedColumnName("contentTypeId"), SqlSyntax.GetQuotedColumnName("dataTypeId"),
SqlSyntax.GetQuotedColumnName("id"),
};
[TableName("failedAttemptsType")]
private class FailedAttempts
{
[Column("contentTypeId")]
public int ContentTypeId { get; set; }
[Column("dataTypeId")]
public int DataTypeId { get; set; }
[Column("id")]
public int Id { get; set; }
}
[TableName("memberApprovedType")]
private class MemberApproved
{
[Column("contentTypeId")]
public int ContentTypeId { get; set; }
[Column("dataTypeId")]
public int DataTypeId { get; set; }
[Column("id")]
public int Id { get; set; }
}
[TableName("memberLockedOutType")]
private class MemberLockedOut
{
[Column("contentTypeId")]
public int ContentTypeId { get; set; }
[Column("dataTypeId")]
public int DataTypeId { get; set; }
[Column("id")]
public int Id { get; set; }
}
[TableName("lastLockOutDateType")]
private class LastLockoutDate
{
[Column("contentTypeId")]
public int ContentTypeId { get; set; }
[Column("dataTypeId")]
public int DataTypeId { get; set; }
[Column("id")]
public int Id { get; set; }
}
[TableName("lastLoginDateType")]
private class LastLoginDate
{
[Column("contentTypeId")]
public int ContentTypeId { get; set; }
[Column("dataTypeId")]
public int DataTypeId { get; set; }
[Column("id")]
public int Id { get; set; }
}
[TableName("lastPasswordChangeType")]
private class LastPasswordChange
{
[Column("contentTypeId")]
public int ContentTypeId { get; set; }
[Column("dataTypeId")]
public int DataTypeId { get; set; }
[Column("id")]
public int Id { get; set; }
}
}

View File

@@ -1,22 +0,0 @@
using Umbraco.Cms.Core;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_10_2_0;
public class AddHasAccessToAllLanguagesColumn : MigrationBase
{
public AddHasAccessToAllLanguagesColumn(IMigrationContext context) : base(context)
{
}
protected override void Migrate()
{
if (ColumnExists(Constants.DatabaseSchema.Tables.UserGroup, "hasAccessToAllLanguages") is false)
{
Create.Column("hasAccessToAllLanguages")
.OnTable(Constants.DatabaseSchema.Tables.UserGroup)
.AsBoolean()
.WithDefaultValue(true)
.Do();
}
}
}

View File

@@ -1,23 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_10_2_0;
public class AddUserGroup2LanguageTable : MigrationBase
{
public AddUserGroup2LanguageTable(IMigrationContext context) : base(context)
{
}
protected override void Migrate()
{
IEnumerable<string> tables = SqlSyntax.GetTablesInSchema(Context.Database);
if (tables.InvariantContains(UserGroup2LanguageDto.TableName))
{
return;
}
Create.Table<UserGroup2LanguageDto>().Do();
}
}

View File

@@ -1,31 +0,0 @@
using Umbraco.Cms.Infrastructure.Templates.PartialViews;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_10_3_0;
public class AddBlockGridPartialViews : MigrationBase
{
private readonly IPartialViewPopulator _partialViewPopulator;
private const string FolderPath = "/Views/Partials/blockgrid";
private static readonly string[] _filesToAdd =
{
"areas.cshtml",
"default.cshtml",
"items.cshtml",
};
public AddBlockGridPartialViews(IMigrationContext context, IPartialViewPopulator partialViewPopulator) : base(context)
=> _partialViewPopulator = partialViewPopulator;
protected override void Migrate()
{
var embeddedBasePath = _partialViewPopulator.CoreEmbeddedPath + ".BlockGrid";
foreach (var fileName in _filesToAdd)
{
_partialViewPopulator.CopyPartialViewIfNotExists(
_partialViewPopulator.GetCoreAssembly(),
$"{embeddedBasePath}.{fileName}",
$"{FolderPath}/{fileName}");
}
}
}

View File

@@ -1,29 +0,0 @@
using Umbraco.Cms.Infrastructure.Templates.PartialViews;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_10_4_0;
public class AddBlockGridPartialViews : MigrationBase
{
private readonly IPartialViewPopulator _partialViewPopulator;
private const string FolderPath = "/Views/Partials/blockgrid";
private static readonly string[] _filesToAdd =
{
"area.cshtml",
};
public AddBlockGridPartialViews(IMigrationContext context, IPartialViewPopulator partialViewPopulator) : base(context)
=> _partialViewPopulator = partialViewPopulator;
protected override void Migrate()
{
var embeddedBasePath = _partialViewPopulator.CoreEmbeddedPath + ".BlockGrid";
foreach (var fileName in _filesToAdd)
{
_partialViewPopulator.CopyPartialViewIfNotExists(
_partialViewPopulator.GetCoreAssembly(),
$"{embeddedBasePath}.{fileName}",
$"{FolderPath}/{fileName}");
}
}
}

View File

@@ -1,37 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_10_5_0;
public class AddPrimaryKeyConstrainToContentVersionCleanupDtos : MigrationBase
{
public AddPrimaryKeyConstrainToContentVersionCleanupDtos(IMigrationContext context) : base(context)
{
}
protected override void Migrate()
{
IEnumerable<ContentVersionCleanupPolicyDto>? contentVersionCleanupPolicyDtos = null;
if (TableExists(ContentVersionCleanupPolicyDto.TableName))
{
if (PrimaryKeyExists(ContentVersionCleanupPolicyDto.TableName, "PK_umbracoContentVersionCleanupPolicy"))
{
return;
}
contentVersionCleanupPolicyDtos =
Database
.Fetch<ContentVersionCleanupPolicyDto>()
.OrderByDescending(x => x.Updated)
.DistinctBy(x => x.ContentTypeId);
Delete.Table(ContentVersionCleanupPolicyDto.TableName).Do();
}
Create.Table<ContentVersionCleanupPolicyDto>().Do();
if (contentVersionCleanupPolicyDtos is not null)
{
Database.InsertBatch(contentVersionCleanupPolicyDtos);
}
}
}

View File

@@ -1,46 +0,0 @@
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_10_7_0;
public class MigrateTagsFromNVarcharToNText : MigrationBase
{
public MigrateTagsFromNVarcharToNText(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// Firstly change the storage type for the Umbraco.Tags property editor
Sql<ISqlContext> updateDbTypeForTagsQuery = Database.SqlContext.Sql()
.Update<DataTypeDto>(x => x.Set(dt => dt.DbType, ValueStorageType.Ntext.ToString()))
.Where<DataTypeDto>(dt => dt.EditorAlias == Constants.PropertyEditors.Aliases.Tags);
Database.Execute(updateDbTypeForTagsQuery);
// Then migrate the data from "varcharValue" column to "textValue"
Sql<ISqlContext> tagsDataTypeIdQuery = Database.SqlContext.Sql()
.Select<DataTypeDto>(dt => dt.NodeId)
.From<DataTypeDto>()
.Where<DataTypeDto>(dt => dt.EditorAlias == Constants.PropertyEditors.Aliases.Tags);
Sql<ISqlContext> tagsPropertyTypeIdQuery = Database.SqlContext.Sql()
.Select<PropertyTypeDto>(pt => pt.Id)
.From<PropertyTypeDto>()
.WhereIn<PropertyTypeDto>(pt => pt.DataTypeId, tagsDataTypeIdQuery);
Sql<ISqlContext> updatePropertyDataColumnsQuery = Database.SqlContext.Sql()
.Update<PropertyDataDto>()
.Append("SET textValue = varcharValue, varcharValue = null")
.WhereIn<PropertyDataDto>(pd => pd.PropertyTypeId, tagsPropertyTypeIdQuery)
.Where<PropertyDataDto>(pd => pd.TextValue == null)
.Where<PropertyDataDto>(pd => pd.VarcharValue != null);
Database.Execute(updatePropertyDataColumnsQuery);
}
}

View File

@@ -1,39 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_11_3_0;
public class AddDomainSortOrder : MigrationBase
{
public AddDomainSortOrder(IMigrationContext context)
: base(context)
{ }
protected override void Migrate()
{
if (ColumnExists(DomainDto.TableName, "sortOrder") == false)
{
// Use a custom SQL query to prevent selecting explicit columns (sortOrder doesn't exist yet)
List<DomainDto> domainDtos = Database.Fetch<DomainDto>($"SELECT * FROM {DomainDto.TableName}");
Delete.Table(DomainDto.TableName).Do();
Create.Table<DomainDto>().Do();
foreach (DomainDto domainDto in domainDtos)
{
bool isWildcard = string.IsNullOrWhiteSpace(domainDto.DomainName) || domainDto.DomainName.StartsWith("*");
if (isWildcard)
{
// Set sort order of wildcard domains to -1
domainDto.SortOrder = -1;
}
else
{
// Keep exising sort order by setting it to the id
domainDto.SortOrder = domainDto.Id;
}
}
Database.InsertBatch(domainDtos);
}
}
}

View File

@@ -1,37 +0,0 @@
using System.Reflection;
using NPoco;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_11_4_0;
public class AlterKeyValueDataType : MigrationBase
{
private readonly IMigrationContext _context;
public AlterKeyValueDataType(IMigrationContext context)
: base(context) => _context = context;
protected override void Migrate()
{
// SQLite doesn't need this upgrade
if (_context.Database.DatabaseType.IsSqlite())
{
return;
}
string tableName = KeyValueDto.TableName;
string colName = "value";
// Determine the current datatype of the column within the database
string colDataType = Database.ExecuteScalar<string>($"SELECT TOP(1) CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS" +
$" WHERE TABLE_NAME = '{tableName}' AND COLUMN_NAME = '{colName}'");
// 255 is the old length, -1 indicate MAX length
if (colDataType == "255")
{
// Upgrade to MAX length
Database.Execute($"ALTER TABLE {tableName} ALTER COLUMN {colName} nvarchar(MAX)");
}
}
}

View File

@@ -1,48 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.PublishedCache;
using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_12_0_0;
public class ResetCache : MigrationBase
{
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IPublishedSnapshotService _publishedSnapshotService;
[Obsolete("Use ctor with all params - This will be removed in Umbraco 14.")]
public ResetCache(IMigrationContext context, IHostingEnvironment hostingEnvironment)
: this(context, hostingEnvironment, StaticServiceProvider.Instance.GetRequiredService<IPublishedSnapshotService>())
{
}
public ResetCache(IMigrationContext context, IHostingEnvironment hostingEnvironment, IPublishedSnapshotService publishedSnapshotService)
: base(context)
{
_hostingEnvironment = hostingEnvironment;
_publishedSnapshotService = publishedSnapshotService;
}
protected override void Migrate()
{
RebuildCache = true;
var distCacheFolderAbsolutePath = Path.Combine(_hostingEnvironment.LocalTempPath, "DistCache");
DeleteAllFilesInFolder(distCacheFolderAbsolutePath);
_publishedSnapshotService.ResetLocalDb();
}
private void DeleteAllFilesInFolder(string path)
{
if (Directory.Exists(path) == false)
{
return;
}
var directoryInfo = new DirectoryInfo(path);
foreach (FileInfo file in directoryInfo.GetFiles())
{
file.Delete();
}
}
}

View File

@@ -1,94 +0,0 @@
using System.Linq.Expressions;
using System.Text;
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Migrations.Expressions.Create.Column;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_12_0_0;
public class UseNvarcharInsteadOfNText : MigrationBase
{
public UseNvarcharInsteadOfNText(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// We don't need to run this migration for SQLite, since ntext is not a thing there, text is just text.
if (DatabaseType == DatabaseType.SQLite)
{
return;
}
MigrateNtextColumn<ContentNuDto>("data", Constants.DatabaseSchema.Tables.NodeData, x => x.Data);
MigrateNtextColumn<CacheInstructionDto>("jsonInstruction", Constants.DatabaseSchema.Tables.CacheInstruction, x => x.Instructions, false);
MigrateNtextColumn<DataTypeDto>("config", Constants.DatabaseSchema.Tables.DataType, x => x.Configuration);
MigrateNtextColumn<ExternalLoginDto>("userData", Constants.DatabaseSchema.Tables.ExternalLogin, x => x.UserData);
MigrateNtextColumn<UserDto>("tourData", Constants.DatabaseSchema.Tables.User, x => x.TourData);
MigrateNtextColumn<PropertyDataDto>("textValue", Constants.DatabaseSchema.Tables.PropertyData, x => x.TextValue);
}
private void MigrateNtextColumn<TDto>(string columnName, string tableName, Expression<Func<TDto, object?>> fieldSelector, bool nullable = true)
{
var columnType = ColumnType(tableName, columnName);
if (columnType is null || columnType.Equals("ntext", StringComparison.InvariantCultureIgnoreCase) is false)
{
return;
}
var oldColumnName = $"Old{columnName}";
// Rename the column so we can create the new one and copy over the data.
Rename
.Column(columnName)
.OnTable(tableName)
.To(oldColumnName)
.Do();
// Create new column with the correct type
// This is pretty ugly, but we have to do ti this way because the CacheInstruction.Instruction column doesn't support nullable.
// So we have to populate with some temporary placeholder value before we copy over the actual data.
ICreateColumnOptionBuilder builder = Create
.Column(columnName)
.OnTable(tableName)
.AsCustom("nvarchar(max)");
if (nullable is false)
{
builder
.NotNullable()
.WithDefaultValue("Placeholder");
}
else
{
builder.Nullable();
}
builder.Do();
// Copy over data NPOCO doesn't support this for some reason, so we'll have to do it like so
// While we're add it we'll also set all the old values to be NULL since it's recommended here:
// https://learn.microsoft.com/en-us/sql/t-sql/data-types/ntext-text-and-image-transact-sql?view=sql-server-ver16#remarks
StringBuilder queryBuilder = new StringBuilder()
.AppendLine($"UPDATE {tableName}")
.AppendLine("SET")
.Append($"\t{SqlSyntax.GetFieldNameForUpdate(fieldSelector)} = {SqlSyntax.GetQuotedTableName(tableName)}.{SqlSyntax.GetQuotedColumnName(oldColumnName)}");
if (nullable)
{
queryBuilder.AppendLine($"\n,\t{SqlSyntax.GetQuotedColumnName(oldColumnName)} = NULL");
}
Sql<ISqlContext> copyDataQuery = Database.SqlContext.Sql(queryBuilder.ToString());
Database.Execute(copyDataQuery);
// Delete old column
Delete
.Column(oldColumnName)
.FromTable(tableName)
.Do();
}
}

View File

@@ -1,21 +0,0 @@
using Umbraco.Cms.Persistence.EFCore.Migrations;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_12_1_0;
public class AddOpenIddict : UnscopedMigrationBase
{
private readonly IEFCoreMigrationExecutor _iefCoreMigrationExecutor;
public AddOpenIddict(IMigrationContext context, IEFCoreMigrationExecutor iefCoreMigrationExecutor)
: base(context)
{
_iefCoreMigrationExecutor = iefCoreMigrationExecutor;
}
protected override void Migrate()
{
_iefCoreMigrationExecutor.ExecuteSingleMigrationAsync(EFCoreMigration.InitialCreate).GetAwaiter().GetResult();
_iefCoreMigrationExecutor.ExecuteSingleMigrationAsync(EFCoreMigration.AddOpenIddict).GetAwaiter().GetResult();
}
}

View File

@@ -1,65 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_12_1_0;
public class TablesIndexesImprovement : MigrationBase
{
public TablesIndexesImprovement(IMigrationContext context) : base(context)
{
}
protected override void Migrate()
{
var nodeDtoTrashedIndex = $"IX_{NodeDto.TableName}_ObjectType_trashed_sorted";
DeleteIndex<NodeDto>(nodeDtoTrashedIndex);
CreateIndex<NodeDto>(nodeDtoTrashedIndex);
var redirectUrlCreateDateUtcIndex = $"IX_{RedirectUrlDto.TableName}_culture_hash";
DeleteIndex<RedirectUrlDto>(redirectUrlCreateDateUtcIndex);
CreateIndex<RedirectUrlDto>(redirectUrlCreateDateUtcIndex);
var contentVersionCultureVariationVersionIdIndex = $"IX_{ContentVersionCultureVariationDto.TableName}_VersionId";
DeleteIndex<ContentVersionCultureVariationDto>(contentVersionCultureVariationVersionIdIndex);
CreateIndex<ContentVersionCultureVariationDto>(contentVersionCultureVariationVersionIdIndex);
var contentVersionDtoNodeIdV2Index = $"IX_{ContentVersionDto.TableName}_NodeId";
DeleteIndex<ContentVersionDto>(contentVersionDtoNodeIdV2Index);
CreateIndex<ContentVersionDto>(contentVersionDtoNodeIdV2Index);
var tagRelationshipDtoTagNodeIndex = $"IX_{TagRelationshipDto.TableName}_tagId_nodeId";
DeleteIndex<TagRelationshipDto>(tagRelationshipDtoTagNodeIndex);
CreateIndex<TagRelationshipDto>(tagRelationshipDtoTagNodeIndex);
var tagDtoLanguageGroupIndex = $"IX_{TagDto.TableName}_languageId_group";
DeleteIndex<TagDto>(tagDtoLanguageGroupIndex);
CreateIndex<TagDto>(tagDtoLanguageGroupIndex);
var documentVersionDtoIdPublishedIndex = $"IX_{DocumentVersionDto.TableName}_id_published";
DeleteIndex<DocumentVersionDto>(documentVersionDtoIdPublishedIndex);
CreateIndex<DocumentVersionDto>(documentVersionDtoIdPublishedIndex);
var documentVersionDtoPublishedIndex = $"IX_{DocumentVersionDto.TableName}_published";
DeleteIndex<DocumentVersionDto>(documentVersionDtoPublishedIndex);
CreateIndex<DocumentVersionDto>(documentVersionDtoPublishedIndex);
var logDtoDatestampIndex = $"IX_{LogDto.TableName}_datestamp";
DeleteIndex<LogDto>(logDtoDatestampIndex);
CreateIndex<LogDto>(logDtoDatestampIndex);
var logDtoDatestampHeaderIndex = $"IX_{LogDto.TableName}_datestamp_logheader";
DeleteIndex<LogDto>(logDtoDatestampHeaderIndex);
CreateIndex<LogDto>(logDtoDatestampHeaderIndex);
var propertyDataDtoVersionIdIndex = $"IX_{PropertyDataDto.TableName}_VersionId";
DeleteIndex<PropertyDataDto>(propertyDataDtoVersionIdIndex);
CreateIndex<PropertyDataDto>(propertyDataDtoVersionIdIndex);
var contentNuDtoPublishedIdIndex = $"IX_{ContentNuDto.TableName}_published";
DeleteIndex<ContentNuDto>(contentNuDtoPublishedIdIndex);
CreateIndex<ContentNuDto>(contentNuDtoPublishedIdIndex);
var nodeDtoParentIdNodeObjectTypeIndex = $"IX_{NodeDto.TableName}_parentId_nodeObjectType";
DeleteIndex<NodeDto>(nodeDtoParentIdNodeObjectTypeIndex);
CreateIndex<NodeDto>(nodeDtoParentIdNodeObjectTypeIndex);
}
}

View File

@@ -1,14 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddContentTypeIsElementColumn : MigrationBase
{
public AddContentTypeIsElementColumn(IMigrationContext context)
: base(context)
{
}
protected override void Migrate() => AddColumn<ContentTypeDto>("isElement");
}

View File

@@ -1,45 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddLockObjects : MigrationBase
{
public AddLockObjects(IMigrationContext context)
: base(context)
{
}
internal static void EnsureLockObject(IUmbracoDatabase db, int id, string name)
{
// not if it already exists
var exists = db.Exists<LockDto>(id);
if (exists)
{
return;
}
// be safe: delete old umbracoNode lock objects if any
db.Execute($"DELETE FROM umbracoNode WHERE id={id};");
// then create umbracoLock object
db.Execute($"INSERT umbracoLock (id, name, value) VALUES ({id}, '{name}', 1);");
}
protected override void Migrate()
{
// some may already exist, just ensure everything we need is here
EnsureLockObject(Constants.Locks.Servers, "Servers");
EnsureLockObject(Constants.Locks.ContentTypes, "ContentTypes");
EnsureLockObject(Constants.Locks.ContentTree, "ContentTree");
EnsureLockObject(Constants.Locks.MediaTree, "MediaTree");
EnsureLockObject(Constants.Locks.MemberTree, "MemberTree");
EnsureLockObject(Constants.Locks.MediaTypes, "MediaTypes");
EnsureLockObject(Constants.Locks.MemberTypes, "MemberTypes");
EnsureLockObject(Constants.Locks.Domains, "Domains");
}
private void EnsureLockObject(int id, string name) => EnsureLockObject(Database, id, name);
}

View File

@@ -1,20 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddLogTableColumns : MigrationBase
{
public AddLogTableColumns(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToList();
AddColumnIfNotExists<LogDto>(columns, "entityType");
AddColumnIfNotExists<LogDto>(columns, "parameters");
}
}

View File

@@ -1,21 +0,0 @@
using Umbraco.Cms.Core;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddPackagesSectionAccess : MigrationBase
{
public AddPackagesSectionAccess(IMigrationContext context)
: base(context)
{
}
protected override void Migrate() =>
// Any user group which had access to the Developer section should have access to Packages
Database.Execute($@"
insert into {Constants.DatabaseSchema.Tables.UserGroup2App}
select userGroupId, '{Constants.Applications.Packages}'
from {Constants.DatabaseSchema.Tables.UserGroup2App}
where app='developer'");
}

View File

@@ -1,159 +0,0 @@
using System.Globalization;
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddTypedLabels : MigrationBase
{
public AddTypedLabels(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// insert other label datatypes
void InsertNodeDto(int id, int sortOrder, string uniqueId, string text)
{
var nodeDto = new NodeDto
{
NodeId = id,
Trashed = false,
ParentId = -1,
UserId = -1,
Level = 1,
Path = "-1,-" + id,
SortOrder = sortOrder,
UniqueId = new Guid(uniqueId),
Text = text,
NodeObjectType = Constants.ObjectTypes.DataType,
CreateDate = DateTime.Now,
};
Database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, nodeDto);
}
if (SqlSyntax.SupportsIdentityInsert())
{
Database.Execute(new Sql(
$"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(Constants.DatabaseSchema.Tables.Node)} ON "));
}
InsertNodeDto(Constants.DataTypes.LabelInt, 36, "8e7f995c-bd81-4627-9932-c40e568ec788", "Label (integer)");
InsertNodeDto(Constants.DataTypes.LabelBigint, 36, "930861bf-e262-4ead-a704-f99453565708", "Label (bigint)");
InsertNodeDto(Constants.DataTypes.LabelDateTime, 37, "0e9794eb-f9b5-4f20-a788-93acd233a7e4",
"Label (datetime)");
InsertNodeDto(Constants.DataTypes.LabelTime, 38, "a97cec69-9b71-4c30-8b12-ec398860d7e8", "Label (time)");
InsertNodeDto(Constants.DataTypes.LabelDecimal, 39, "8f1ef1e1-9de4-40d3-a072-6673f631ca64", "Label (decimal)");
if (SqlSyntax.SupportsIdentityInsert())
{
Database.Execute(new Sql(
$"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(Constants.DatabaseSchema.Tables.Node)} OFF "));
}
void InsertDataTypeDto(int id, string dbType, string? configuration = null)
{
var dataTypeDto = new DataTypeDto
{
NodeId = id,
EditorAlias = Constants.PropertyEditors.Aliases.Label,
DbType = dbType,
};
if (configuration != null)
{
dataTypeDto.Configuration = configuration;
}
Database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, dataTypeDto);
}
InsertDataTypeDto(Constants.DataTypes.LabelInt, "Integer", "{\"umbracoDataValueType\":\"INT\"}");
InsertDataTypeDto(Constants.DataTypes.LabelBigint, "Nvarchar", "{\"umbracoDataValueType\":\"BIGINT\"}");
InsertDataTypeDto(Constants.DataTypes.LabelDateTime, "Date", "{\"umbracoDataValueType\":\"DATETIME\"}");
InsertDataTypeDto(Constants.DataTypes.LabelDecimal, "Decimal", "{\"umbracoDataValueType\":\"DECIMAL\"}");
InsertDataTypeDto(Constants.DataTypes.LabelTime, "Date", "{\"umbracoDataValueType\":\"TIME\"}");
// flip known property types
List<PropertyTypeDto>? labelPropertyTypes = Database.Fetch<PropertyTypeDto>(Sql()
.Select<PropertyTypeDto>(x => x.Id, x => x.Alias)
.From<PropertyTypeDto>()
.Where<PropertyTypeDto>(x => x.DataTypeId == Constants.DataTypes.LabelString));
var intPropertyAliases = new[] { Cms.Core.Constants.Conventions.Media.Width, Cms.Core.Constants.Conventions.Media.Height, "umbracoMemberFailedPasswordAttempts" };
var bigintPropertyAliases = new[] { Cms.Core.Constants.Conventions.Media.Bytes };
var dtPropertyAliases = new[] { "umbracoMemberLastLockoutDate", "umbracoMemberLastLogin", "umbracoMemberLastPasswordChangeDate" };
var intPropertyTypes = labelPropertyTypes.Where(pt => intPropertyAliases.Contains(pt.Alias)).Select(pt => pt.Id)
.ToArray();
var bigintPropertyTypes = labelPropertyTypes.Where(pt => bigintPropertyAliases.Contains(pt.Alias))
.Select(pt => pt.Id).ToArray();
var dtPropertyTypes = labelPropertyTypes.Where(pt => dtPropertyAliases.Contains(pt.Alias)).Select(pt => pt.Id)
.ToArray();
Database.Execute(Sql().Update<PropertyTypeDto>(u => u.Set(x => x.DataTypeId, Constants.DataTypes.LabelInt))
.WhereIn<PropertyTypeDto>(x => x.Id, intPropertyTypes));
Database.Execute(Sql().Update<PropertyTypeDto>(u => u.Set(x => x.DataTypeId, Constants.DataTypes.LabelInt))
.WhereIn<PropertyTypeDto>(x => x.Id, intPropertyTypes));
Database.Execute(Sql().Update<PropertyTypeDto>(u => u.Set(x => x.DataTypeId, Constants.DataTypes.LabelBigint))
.WhereIn<PropertyTypeDto>(x => x.Id, bigintPropertyTypes));
Database.Execute(Sql().Update<PropertyTypeDto>(u => u.Set(x => x.DataTypeId, Constants.DataTypes.LabelDateTime))
.WhereIn<PropertyTypeDto>(x => x.Id, dtPropertyTypes));
// update values for known property types
// depending on the size of the site, that *may* take time
// but we want to parse in C# not in the database
List<PropertyDataValue>? values = Database.Fetch<PropertyDataValue>(Sql()
.Select<PropertyDataDto>(x => x.Id, x => x.VarcharValue)
.From<PropertyDataDto>()
.WhereIn<PropertyDataDto>(x => x.PropertyTypeId, intPropertyTypes));
foreach (PropertyDataValue? value in values)
{
Database.Execute(Sql()
.Update<PropertyDataDto>(u => u
.Set(
x => x.IntegerValue,
string.IsNullOrWhiteSpace(value.VarcharValue)
? null
: int.Parse(value.VarcharValue, NumberStyles.Any, CultureInfo.InvariantCulture))
.Set(x => x.TextValue, null)
.Set(x => x.VarcharValue, null))
.Where<PropertyDataDto>(x => x.Id == value.Id));
}
values = Database.Fetch<PropertyDataValue>(Sql().Select<PropertyDataDto>(x => x.Id, x => x.VarcharValue)
.From<PropertyDataDto>().WhereIn<PropertyDataDto>(x => x.PropertyTypeId, dtPropertyTypes));
foreach (PropertyDataValue? value in values)
{
Database.Execute(Sql()
.Update<PropertyDataDto>(u => u
.Set(x => x.DateValue,
string.IsNullOrWhiteSpace(value.VarcharValue)
? null
: DateTime.Parse(value.VarcharValue,
CultureInfo.InvariantCulture,
DateTimeStyles.None))
.Set(x => x.TextValue, null)
.Set(x => x.VarcharValue, null))
.Where<PropertyDataDto>(x => x.Id == value.Id));
}
// anything that's custom... ppl will have to figure it out manually, there isn't much we can do about it
}
// ReSharper disable once ClassNeverInstantiated.Local
// ReSharper disable UnusedAutoPropertyAccessor.Local
private class PropertyDataValue
{
public int Id { get; set; }
public string? VarcharValue { get; set; }
}
// ReSharper restore UnusedAutoPropertyAccessor.Local
}

View File

@@ -1,54 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddVariationTables1A : MigrationBase
{
public AddVariationTables1A(IMigrationContext context)
: base(context)
{
}
// note - original AddVariationTables1 just did
// Create.Table<ContentVersionCultureVariationDto>().Do();
//
// this is taking care of ppl left in this state
protected override void Migrate()
{
// note - original AddVariationTables1 just did
// Create.Table<ContentVersionCultureVariationDto>().Do();
//
// it's been deprecated, not part of the main upgrade path,
// but we need to take care of ppl caught into the state
// was not used
Delete.Column("available").FromTable(Constants.DatabaseSchema.Tables.ContentVersionCultureVariation).Do();
// was not used
Delete.Column("availableDate").FromTable(Constants.DatabaseSchema.Tables.ContentVersionCultureVariation).Do();
// special trick to add the column without constraints and return the sql to add them later
AddColumn<ContentVersionCultureVariationDto>("date", out IEnumerable<string> sqls);
// now we need to update the new column with some values because this column doesn't allow NULL values
Update.Table(ContentVersionCultureVariationDto.TableName).Set(new { date = DateTime.Now }).AllRows().Do();
// now apply constraints (NOT NULL) to new table
foreach (var sql in sqls)
{
Execute.Sql(sql).Do();
}
// name, languageId are now non-nullable
AlterColumn<ContentVersionCultureVariationDto>(
Constants.DatabaseSchema.Tables.ContentVersionCultureVariation,
"name");
AlterColumn<ContentVersionCultureVariationDto>(
Constants.DatabaseSchema.Tables.ContentVersionCultureVariation,
"languageId");
Create.Table<DocumentCultureVariationDto>().Do();
}
}

View File

@@ -1,18 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddVariationTables2 : MigrationBase
{
public AddVariationTables2(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
Create.Table<ContentVersionCultureVariationDto>(true).Do();
Create.Table<DocumentCultureVariationDto>(true).Do();
}
}

View File

@@ -1,20 +0,0 @@
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class ContentVariationMigration : MigrationBase
{
public ContentVariationMigration(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
}
// we *need* to use these private DTOs here, which does *not* have extra properties, which would kill the migration
}

View File

@@ -1,16 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class ConvertRelatedLinksToMultiUrlPicker : MigrationBase
{
public ConvertRelatedLinksToMultiUrlPicker(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
}
}

View File

@@ -1,51 +0,0 @@
using Microsoft.Extensions.Logging;
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0.DataTypes;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class DataTypeMigration : MigrationBase
{
private static readonly ISet<string> _legacyAliases = new HashSet<string>
{
Constants.PropertyEditors.Legacy.Aliases.Date,
Constants.PropertyEditors.Legacy.Aliases.Textbox,
Constants.PropertyEditors.Legacy.Aliases.ContentPicker2,
Constants.PropertyEditors.Legacy.Aliases.MediaPicker2,
Constants.PropertyEditors.Legacy.Aliases.MemberPicker2,
Constants.PropertyEditors.Legacy.Aliases.RelatedLinks2,
Constants.PropertyEditors.Legacy.Aliases.TextboxMultiple,
Constants.PropertyEditors.Legacy.Aliases.MultiNodeTreePicker2,
};
private readonly IConfigurationEditorJsonSerializer _configurationEditorJsonSerializer;
private readonly ILogger<DataTypeMigration> _logger;
private readonly PreValueMigratorCollection _preValueMigrators;
private readonly PropertyEditorCollection _propertyEditors;
public DataTypeMigration(
IMigrationContext context,
PreValueMigratorCollection preValueMigrators,
PropertyEditorCollection propertyEditors,
ILogger<DataTypeMigration> logger,
IConfigurationEditorJsonSerializer configurationEditorJsonSerializer)
: base(context)
{
_preValueMigrators = preValueMigrators;
_propertyEditors = propertyEditors;
_logger = logger;
_configurationEditorJsonSerializer = configurationEditorJsonSerializer;
}
protected override void Migrate()
{
}
}

View File

@@ -1,36 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0.DataTypes;
/// <summary>
/// Defines a service migrating preValues.
/// </summary>
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public interface IPreValueMigrator
{
/// <summary>
/// Determines whether this migrator can migrate a data type.
/// </summary>
/// <param name="editorAlias">The data type editor alias.</param>
bool CanMigrate(string editorAlias);
/// <summary>
/// Gets the v8 codebase data type editor alias.
/// </summary>
/// <param name="editorAlias">The original v7 codebase editor alias.</param>
/// <remarks>
/// <para>
/// This is used to validate that the migrated configuration can be parsed
/// by the new property editor. Return <c>null</c> to bypass this validation,
/// when for instance we know it will fail, and another, later migration will
/// deal with it.
/// </para>
/// </remarks>
string? GetNewAlias(string editorAlias);
/// <summary>
/// Gets the configuration object corresponding to preValue.
/// </summary>
/// <param name="dataTypeId">The data type identifier.</param>
/// <param name="editorAlias">The data type editor alias.</param>
/// <param name="preValues">PreValues.</param>
object GetConfiguration(int dataTypeId, string editorAlias, Dictionary<string, PreValueDto> preValues);
}

View File

@@ -1,24 +0,0 @@
using NPoco;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0.DataTypes;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
[TableName("cmsDataTypePreValues")]
[ExplicitColumns]
public class PreValueDto
{
[Column("id")]
public int Id { get; set; }
[Column("datatypeNodeId")]
public int NodeId { get; set; }
[Column("alias")]
public string Alias { get; set; } = null!;
[Column("sortorder")]
public int SortOrder { get; set; }
[Column("value")]
public string? Value { get; set; }
}

View File

@@ -1,21 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0.DataTypes;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public abstract class PreValueMigratorBase : IPreValueMigrator
{
public abstract bool CanMigrate(string editorAlias);
public virtual string GetNewAlias(string editorAlias)
=> editorAlias;
public abstract object GetConfiguration(int dataTypeId, string editorAlias,
Dictionary<string, PreValueDto> preValues);
protected bool GetBoolValue(Dictionary<string, PreValueDto> preValues, string alias, bool defaultValue = false)
=> preValues.TryGetValue(alias, out PreValueDto? preValue) ? preValue.Value == "1" : defaultValue;
protected decimal GetDecimalValue(Dictionary<string, PreValueDto> preValues, string alias, decimal defaultValue = 0)
=> preValues.TryGetValue(alias, out PreValueDto? preValue) && decimal.TryParse(preValue.Value, out var value)
? value
: defaultValue;
}

View File

@@ -1,27 +0,0 @@
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Composing;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0.DataTypes;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class PreValueMigratorCollection : BuilderCollectionBase<IPreValueMigrator>
{
private readonly ILogger<PreValueMigratorCollection> _logger;
public PreValueMigratorCollection(
Func<IEnumerable<IPreValueMigrator>> items,
ILogger<PreValueMigratorCollection> logger)
: base(items) =>
_logger = logger;
public IPreValueMigrator? GetMigrator(string editorAlias)
{
IPreValueMigrator? migrator = this.FirstOrDefault(x => x.CanMigrate(editorAlias));
if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug))
{
_logger.LogDebug("Getting migrator for \"{EditorAlias}\" = {MigratorType}", editorAlias,
migrator == null ? "<null>" : migrator.GetType().Name);
}
return migrator;
}
}

View File

@@ -1,10 +0,0 @@
using Umbraco.Cms.Core.Composing;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0.DataTypes;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class PreValueMigratorCollectionBuilder : OrderedCollectionBuilderBase<PreValueMigratorCollectionBuilder,
PreValueMigratorCollection, IPreValueMigrator>
{
protected override PreValueMigratorCollectionBuilder This => this;
}

View File

@@ -1,143 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Migrations.PostMigrations;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class DropDownPropertyEditorsMigration : PropertyEditorsMigrationBase
{
private readonly IConfigurationEditorJsonSerializer _configurationEditorJsonSerializer;
private readonly IEditorConfigurationParser _editorConfigurationParser;
private readonly IIOHelper _ioHelper;
public DropDownPropertyEditorsMigration(IMigrationContext context, IIOHelper ioHelper,
IConfigurationEditorJsonSerializer configurationEditorJsonSerializer)
: this(context, ioHelper, configurationEditorJsonSerializer,
StaticServiceProvider.Instance.GetRequiredService<IEditorConfigurationParser>())
{
}
public DropDownPropertyEditorsMigration(
IMigrationContext context,
IIOHelper ioHelper,
IConfigurationEditorJsonSerializer configurationEditorJsonSerializer,
IEditorConfigurationParser editorConfigurationParser)
: base(context)
{
_ioHelper = ioHelper;
_configurationEditorJsonSerializer = configurationEditorJsonSerializer;
_editorConfigurationParser = editorConfigurationParser;
}
protected override void Migrate()
{
var refreshCache = Migrate(GetDataTypes(".DropDown", false));
// if some data types have been updated directly in the database (editing DataTypeDto and/or PropertyDataDto),
// bypassing the services, then we need to rebuild the cache entirely, including the umbracoContentNu table
// This has been removed since this migration should be deleted.
}
private bool Migrate(IEnumerable<DataTypeDto> dataTypes)
{
var refreshCache = false;
ConfigurationEditor? configurationEditor = null;
foreach (DataTypeDto dataType in dataTypes)
{
ValueListConfiguration config = new ValueListConfiguration();
if (!dataType.Configuration.IsNullOrWhiteSpace())
{
// parse configuration, and update everything accordingly
if (configurationEditor == null)
{
configurationEditor = new ValueListConfigurationEditor(_ioHelper, _editorConfigurationParser);
}
try
{
// this migration is obsolete, no reason to refactor this code
// config = (ValueListConfiguration)configurationEditor.FromDatabase(
// dataType.Configuration,
// _configurationEditorJsonSerializer);
}
catch (Exception ex)
{
Logger.LogError(
ex, "Invalid configuration: \"{Configuration}\", cannot convert editor.",
dataType.Configuration);
// reset
config = new ValueListConfiguration();
}
// get property data dtos
List<PropertyDataDto>? propertyDataDtos = Database.Fetch<PropertyDataDto>(Sql()
.Select<PropertyDataDto>()
.From<PropertyDataDto>()
.InnerJoin<PropertyTypeDto>()
.On<PropertyTypeDto, PropertyDataDto>((pt, pd) => pt.Id == pd.PropertyTypeId)
.InnerJoin<DataTypeDto>().On<DataTypeDto, PropertyTypeDto>((dt, pt) => dt.NodeId == pt.DataTypeId)
.Where<PropertyTypeDto>(x => x.DataTypeId == dataType.NodeId));
// update dtos
IEnumerable<PropertyDataDto> updatedDtos =
propertyDataDtos.Where(x => UpdatePropertyDataDto(x, config, true));
// persist changes
foreach (PropertyDataDto? propertyDataDto in updatedDtos)
{
Database.Update(propertyDataDto);
}
}
else
{
// default configuration
config = new ValueListConfiguration();
}
switch (dataType.EditorAlias)
{
case string ea when ea.InvariantEquals("Umbraco.DropDown"):
UpdateDataType(dataType, config, false);
break;
case string ea when ea.InvariantEquals("Umbraco.DropdownlistPublishingKeys"):
UpdateDataType(dataType, config, false);
break;
case string ea when ea.InvariantEquals("Umbraco.DropDownMultiple"):
UpdateDataType(dataType, config, true);
break;
case string ea when ea.InvariantEquals("Umbraco.DropdownlistMultiplePublishKeys"):
UpdateDataType(dataType, config, true);
break;
}
refreshCache = true;
}
return refreshCache;
}
private void UpdateDataType(DataTypeDto dataType, ValueListConfiguration config, bool isMultiple)
{
dataType.DbType = ValueStorageType.Nvarchar.ToString();
dataType.EditorAlias = Constants.PropertyEditors.Aliases.DropDownListFlexible;
// this migration is obsolete, no reason to refactor this code
// var flexConfig = new DropDownFlexibleConfiguration { Items = config.Items, Multiple = isMultiple };
// dataType.Configuration = ConfigurationEditor.ToDatabase(flexConfig, _configurationEditorJsonSerializer);
Database.Update(dataType);
}
}

View File

@@ -1,18 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class DropMigrationsTable : MigrationBase
{
public DropMigrationsTable(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
if (TableExists("umbracoMigration"))
{
Delete.Table("umbracoMigration").Do();
}
}
}

View File

@@ -1,19 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class DropPreValueTable : MigrationBase
{
public DropPreValueTable(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// drop preValues table
if (TableExists("cmsDataTypePreValues"))
{
Delete.Table("cmsDataTypePreValues").Do();
}
}
}

View File

@@ -1,23 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class DropTaskTables : MigrationBase
{
public DropTaskTables(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
if (TableExists("cmsTask"))
{
Delete.Table("cmsTask").Do();
}
if (TableExists("cmsTaskType"))
{
Delete.Table("cmsTaskType").Do();
}
}
}

View File

@@ -1,18 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class DropTemplateDesignColumn : MigrationBase
{
public DropTemplateDesignColumn(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
if (ColumnExists("cmsTemplate", "design"))
{
Delete.Column("design").FromTable("cmsTemplate").Do();
}
}
}

View File

@@ -1,23 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class DropXmlTables : MigrationBase
{
public DropXmlTables(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
if (TableExists("cmsContentXml"))
{
Delete.Table("cmsContentXml").Do();
}
if (TableExists("cmsPreviewXml"))
{
Delete.Table("cmsPreviewXml").Do();
}
}
}

View File

@@ -1,31 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Cms.Infrastructure.Persistence.SqlSyntax;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
/// <summary>
/// Adds a new, self-joined field to umbracoLanguages to hold the fall-back language for
/// a given language.
/// </summary>
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class FallbackLanguage : MigrationBase
{
public FallbackLanguage(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
ColumnInfo[] columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
if (columns.Any(x =>
x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.Language) &&
x.ColumnName.InvariantEquals("fallbackLanguageId")) == false)
{
AddColumn<LanguageDto>("fallbackLanguageId");
}
}
}

View File

@@ -1,20 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class FixLanguageIsoCodeLength : MigrationBase
{
public FixLanguageIsoCodeLength(IMigrationContext context)
: base(context)
{
}
protected override void Migrate() =>
// there is some confusion here when upgrading from v7
// it should be 14 already but that's not always the case
Alter.Table("umbracoLanguage")
.AlterColumn("languageISOCode")
.AsString(14)
.Nullable()
.Do();
}

View File

@@ -1,19 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class LanguageColumns : MigrationBase
{
public LanguageColumns(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
AddColumn<LanguageDto>(Constants.DatabaseSchema.Tables.Language, "isDefaultVariantLang");
AddColumn<LanguageDto>(Constants.DatabaseSchema.Tables.Language, "mandatory");
}
}

View File

@@ -1,14 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class MakeRedirectUrlVariant : MigrationBase
{
public MakeRedirectUrlVariant(IMigrationContext context)
: base(context)
{
}
protected override void Migrate() => AddColumn<RedirectUrlDto>("culture");
}

View File

@@ -1,14 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class MakeTagsVariant : MigrationBase
{
public MakeTagsVariant(IMigrationContext context)
: base(context)
{
}
protected override void Migrate() => AddColumn<TagDto>("languageId");
}

View File

@@ -1,102 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class MergeDateAndDateTimePropertyEditor : MigrationBase
{
private readonly IConfigurationEditorJsonSerializer _configurationEditorJsonSerializer;
private readonly IEditorConfigurationParser _editorConfigurationParser;
private readonly IIOHelper _ioHelper;
// Scheduled for removal in v12
[Obsolete("Please use constructor that takes an IEditorConfigurationParser instead")]
public MergeDateAndDateTimePropertyEditor(IMigrationContext context, IIOHelper ioHelper,
IConfigurationEditorJsonSerializer configurationEditorJsonSerializer)
: this(context, ioHelper, configurationEditorJsonSerializer,
StaticServiceProvider.Instance.GetRequiredService<IEditorConfigurationParser>())
{
}
public MergeDateAndDateTimePropertyEditor(IMigrationContext context, IIOHelper ioHelper,
IConfigurationEditorJsonSerializer configurationEditorJsonSerializer,
IEditorConfigurationParser editorConfigurationParser)
: base(context)
{
_ioHelper = ioHelper;
_configurationEditorJsonSerializer = configurationEditorJsonSerializer;
_editorConfigurationParser = editorConfigurationParser;
}
protected override void Migrate()
{
List<DataTypeDto> dataTypes = GetDataTypes(Constants.PropertyEditors.Legacy.Aliases.Date);
foreach (DataTypeDto dataType in dataTypes)
{
DateTimeConfiguration config = new DateTimeConfiguration();
try
{
// this migration is obsolete, no reason to refactor this code
// config = (DateTimeConfiguration)new CustomDateTimeConfigurationEditor(
// _ioHelper,
// _editorConfigurationParser).FromDatabase(
// dataType.Configuration, _configurationEditorJsonSerializer);
// If the Umbraco.Date type is the default from V7 and it has never been updated, then the
// configuration is empty, and the format stuff is handled by in JS by moment.js. - We can't do that
// after the migration, so we force the format to the default from V7.
if (string.IsNullOrEmpty(dataType.Configuration))
{
config.Format = "YYYY-MM-DD";
}
}
catch (Exception ex)
{
Logger.LogError(
ex,
"Invalid property editor configuration detected: \"{Configuration}\", cannot convert editor, values will be cleared",
dataType.Configuration);
continue;
}
config.OffsetTime = false;
dataType.EditorAlias = Constants.PropertyEditors.Aliases.DateTime;
// this migration is obsolete, no reason to refactor this code
// dataType.Configuration = ConfigurationEditor.ToDatabase(config, _configurationEditorJsonSerializer);
Database.Update(dataType);
}
}
private List<DataTypeDto> GetDataTypes(string editorAlias)
{
// need to convert the old drop down data types to use the new one
List<DataTypeDto>? dataTypes = Database.Fetch<DataTypeDto>(Sql()
.Select<DataTypeDto>()
.From<DataTypeDto>()
.Where<DataTypeDto>(x => x.EditorAlias == editorAlias));
return dataTypes;
}
private class CustomDateTimeConfigurationEditor : ConfigurationEditor<DateTimeConfiguration>
{
public CustomDateTimeConfigurationEditor(
IIOHelper ioHelper,
IEditorConfigurationParser editorConfigurationParser)
: base(ioHelper, editorConfigurationParser)
{
}
}
}

View File

@@ -1,64 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class PropertyEditorsMigration : MigrationBase
{
public PropertyEditorsMigration(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
RenameDataType(
Constants.PropertyEditors.Legacy.Aliases.ContentPicker2,
Constants.PropertyEditors.Aliases.ContentPicker);
RenameDataType(
Constants.PropertyEditors.Legacy.Aliases.MediaPicker2,
Constants.PropertyEditors.Aliases.MediaPicker);
RenameDataType(
Constants.PropertyEditors.Legacy.Aliases.MemberPicker2,
Constants.PropertyEditors.Aliases.MemberPicker);
RenameDataType(
Constants.PropertyEditors.Legacy.Aliases.MultiNodeTreePicker2,
Constants.PropertyEditors.Aliases.MultiNodeTreePicker);
RenameDataType(
Constants.PropertyEditors.Legacy.Aliases.TextboxMultiple,
Constants.PropertyEditors.Aliases.TextArea, false);
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.Textbox, Constants.PropertyEditors.Aliases.TextBox,
false);
}
private void RenameDataType(string fromAlias, string toAlias, bool checkCollision = true)
{
if (checkCollision)
{
var oldCount = Database.ExecuteScalar<int>(Sql()
.SelectCount()
.From<DataTypeDto>()
.Where<DataTypeDto>(x => x.EditorAlias == toAlias));
if (oldCount > 0)
{
// If we throw it means that the upgrade will exit and cannot continue.
// This will occur if a v7 site has the old "Obsolete" property editors that are already named with the `toAlias` name.
// TODO: We should have an additional upgrade step when going from 7 -> 8 like we did with 6 -> 7 that shows a compatibility report,
// this would include this check and then we can provide users with information on what they should do (i.e. before upgrading to v8 they will
// need to migrate these old obsolete editors to non-obsolete editors)
throw new InvalidOperationException(
$"Cannot rename datatype alias \"{fromAlias}\" to \"{toAlias}\" because the target alias is already used." +
"This is generally because when upgrading from a v7 to v8 site, the v7 site contains Data Types that reference old and already Obsolete " +
"Property Editors. Before upgrading to v8, any Data Types using property editors that are named with the prefix '(Obsolete)' must be migrated " +
"to the non-obsolete v7 property editors of the same type.");
}
}
Database.Execute(Sql()
.Update<DataTypeDto>(u => u.Set(x => x.EditorAlias, toAlias))
.Where<DataTypeDto>(x => x.EditorAlias == fromAlias));
}
}

View File

@@ -1,116 +0,0 @@
using System.Globalization;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public abstract class PropertyEditorsMigrationBase : MigrationBase
{
protected PropertyEditorsMigrationBase(IMigrationContext context)
: base(context)
{
}
internal List<DataTypeDto> GetDataTypes(string editorAlias, bool strict = true)
{
Sql<ISqlContext> sql = Sql()
.Select<DataTypeDto>()
.From<DataTypeDto>();
sql = strict
? sql.Where<DataTypeDto>(x => x.EditorAlias == editorAlias)
: sql.Where<DataTypeDto>(x => x.EditorAlias.Contains(editorAlias));
return Database.Fetch<DataTypeDto>(sql);
}
internal bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config, bool isMultiple)
{
// Get the INT ids stored for this property/drop down
int[]? ids = null;
if (!propData.VarcharValue.IsNullOrWhiteSpace())
{
ids = ConvertStringValues(propData.VarcharValue);
}
else if (!propData.TextValue.IsNullOrWhiteSpace())
{
ids = ConvertStringValues(propData.TextValue);
}
else if (propData.IntegerValue.HasValue)
{
ids = new[] { propData.IntegerValue.Value };
}
// if there are INT ids, convert them to values based on the configuration
if (ids == null || ids.Length <= 0)
{
return false;
}
// map ids to values
var values = new List<string>();
var canConvert = true;
foreach (var id in ids)
{
ValueListConfiguration.ValueListItem? val = config.Items.FirstOrDefault(x => x.Id == id);
if (val?.Value != null)
{
values.Add(val.Value);
continue;
}
Logger.LogWarning(
"Could not find PropertyData {PropertyDataId} value '{PropertyValue}' in the datatype configuration: {Values}.",
propData.Id, id, string.Join(", ", config.Items.Select(x => x.Id + ":" + x.Value)));
canConvert = false;
}
if (!canConvert)
{
return false;
}
propData.VarcharValue = isMultiple ? JsonConvert.SerializeObject(values) : values[0];
propData.TextValue = null;
propData.IntegerValue = null;
return true;
}
protected int[]? ConvertStringValues(string? val)
{
var splitVals = val?.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries);
var intVals = splitVals?
.Select(x =>
int.TryParse(x, NumberStyles.Integer, CultureInfo.InvariantCulture, out var i) ? i : int.MinValue)
.Where(x => x != int.MinValue)
.ToArray();
// only return if the number of values are the same (i.e. All INTs)
if (splitVals?.Length == intVals?.Length)
{
return intVals;
}
return null;
}
// dummy editor for deserialization
protected class ValueListConfigurationEditor : ConfigurationEditor<ValueListConfiguration>
{
public ValueListConfigurationEditor(IIOHelper ioHelper, IEditorConfigurationParser editorConfigurationParser)
: base(ioHelper, editorConfigurationParser)
{
}
}
}

View File

@@ -1,123 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Migrations.PostMigrations;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class RadioAndCheckboxPropertyEditorsMigration : PropertyEditorsMigrationBase
{
private readonly IConfigurationEditorJsonSerializer _configurationEditorJsonSerializer;
private readonly IEditorConfigurationParser _editorConfigurationParser;
private readonly IIOHelper _ioHelper;
public RadioAndCheckboxPropertyEditorsMigration(
IMigrationContext context,
IIOHelper ioHelper,
IConfigurationEditorJsonSerializer configurationEditorJsonSerializer)
: this(context, ioHelper, configurationEditorJsonSerializer,
StaticServiceProvider.Instance.GetRequiredService<IEditorConfigurationParser>())
{
}
public RadioAndCheckboxPropertyEditorsMigration(
IMigrationContext context,
IIOHelper ioHelper,
IConfigurationEditorJsonSerializer configurationEditorJsonSerializer,
IEditorConfigurationParser editorConfigurationParser)
: base(context)
{
_ioHelper = ioHelper;
_configurationEditorJsonSerializer = configurationEditorJsonSerializer;
_editorConfigurationParser = editorConfigurationParser;
}
protected override void Migrate()
{
var refreshCache = false;
refreshCache |= Migrate(GetDataTypes(Constants.PropertyEditors.Aliases.RadioButtonList), false);
refreshCache |= Migrate(GetDataTypes(Constants.PropertyEditors.Aliases.CheckBoxList), true);
// if some data types have been updated directly in the database (editing DataTypeDto and/or PropertyDataDto),
// bypassing the services, then we need to rebuild the cache entirely, including the umbracoContentNu table
// This has been removed since this migration should be deleted.
}
private bool Migrate(IEnumerable<DataTypeDto> dataTypes, bool isMultiple)
{
var refreshCache = false;
ConfigurationEditor? configurationEditor = null;
foreach (DataTypeDto dataType in dataTypes)
{
ValueListConfiguration config = new ValueListConfiguration();
if (dataType.Configuration.IsNullOrWhiteSpace())
{
continue;
}
// parse configuration, and update everything accordingly
if (configurationEditor == null)
{
configurationEditor = new ValueListConfigurationEditor(_ioHelper, _editorConfigurationParser);
}
try
{
// this migration is obsolete, no reason to refactor this code
// config = (ValueListConfiguration)configurationEditor.FromDatabase(
// dataType.Configuration,
// _configurationEditorJsonSerializer);
}
catch (Exception ex)
{
Logger.LogError(
ex, "Invalid configuration: \"{Configuration}\", cannot convert editor.",
dataType.Configuration);
continue;
}
// get property data dtos
List<PropertyDataDto>? propertyDataDtos = Database.Fetch<PropertyDataDto>(Sql()
.Select<PropertyDataDto>()
.From<PropertyDataDto>()
.InnerJoin<PropertyTypeDto>()
.On<PropertyTypeDto, PropertyDataDto>((pt, pd) => pt.Id == pd.PropertyTypeId)
.InnerJoin<DataTypeDto>().On<DataTypeDto, PropertyTypeDto>((dt, pt) => dt.NodeId == pt.DataTypeId)
.Where<PropertyTypeDto>(x => x.DataTypeId == dataType.NodeId));
// update dtos
IEnumerable<PropertyDataDto> updatedDtos =
propertyDataDtos.Where(x => UpdatePropertyDataDto(x, config, isMultiple));
// persist changes
foreach (PropertyDataDto? propertyDataDto in updatedDtos)
{
Database.Update(propertyDataDto);
}
UpdateDataType(dataType);
refreshCache = true;
}
return refreshCache;
}
private void UpdateDataType(DataTypeDto dataType)
{
dataType.DbType = ValueStorageType.Nvarchar.ToString();
Database.Update(dataType);
}
}

View File

@@ -1,56 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class RefactorMacroColumns : MigrationBase
{
public RefactorMacroColumns(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
if (ColumnExists(Constants.DatabaseSchema.Tables.Macro, "macroXSLT"))
{
// special trick to add the column without constraints and return the sql to add them later
AddColumn<MacroDto>("macroType", out IEnumerable<string> sqls1);
AddColumn<MacroDto>("macroSource", out IEnumerable<string> sqls2);
// populate the new columns with legacy data
// when the macro type is PartialView, it corresponds to 7, else it is 4 for Unknown
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = '', macroType = 4").Do();
Execute.Sql(
$"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroXSLT, macroType = 4 WHERE macroXSLT != '' AND macroXSLT IS NOT NULL")
.Do();
Execute.Sql(
$"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroScriptAssembly, macroType = 4 WHERE macroScriptAssembly != '' AND macroScriptAssembly IS NOT NULL")
.Do();
Execute.Sql(
$"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroScriptType, macroType = 4 WHERE macroScriptType != '' AND macroScriptType IS NOT NULL")
.Do();
Execute.Sql(
$"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroPython, macroType = 7 WHERE macroPython != '' AND macroPython IS NOT NULL")
.Do();
// now apply constraints (NOT NULL) to new table
foreach (var sql in sqls1)
{
Execute.Sql(sql).Do();
}
foreach (var sql in sqls2)
{
Execute.Sql(sql).Do();
}
// now remove these old columns
Delete.Column("macroXSLT").FromTable(Constants.DatabaseSchema.Tables.Macro).Do();
Delete.Column("macroScriptAssembly").FromTable(Constants.DatabaseSchema.Tables.Macro).Do();
Delete.Column("macroScriptType").FromTable(Constants.DatabaseSchema.Tables.Macro).Do();
Delete.Column("macroPython").FromTable(Constants.DatabaseSchema.Tables.Macro).Do();
}
}
}

View File

@@ -1,100 +0,0 @@
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class RefactorVariantsModel : MigrationBase
{
public RefactorVariantsModel(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
if (ColumnExists(Constants.DatabaseSchema.Tables.ContentVersionCultureVariation, "edited"))
{
Delete.Column("edited").FromTable(Constants.DatabaseSchema.Tables.ContentVersionCultureVariation).Do();
}
// add available column
AddColumn<DocumentCultureVariationDto>("available", out IEnumerable<string> sqls);
// so far, only those cultures that were available had records in the table
Update.Table(DocumentCultureVariationDto.TableName).Set(new { available = true }).AllRows().Do();
foreach (var sql in sqls)
{
Execute.Sql(sql).Do();
}
// add published column
AddColumn<DocumentCultureVariationDto>("published", out sqls);
// make it false by default
Update.Table(DocumentCultureVariationDto.TableName).Set(new { published = false }).AllRows().Do();
// now figure out whether these available cultures are published, too
Sql<ISqlContext> getPublished = Sql()
.Select<NodeDto>(x => x.NodeId)
.AndSelect<ContentVersionCultureVariationDto>(x => x.LanguageId)
.From<NodeDto>()
.InnerJoin<ContentVersionDto>().On<NodeDto, ContentVersionDto>((node, cv) => node.NodeId == cv.NodeId)
.InnerJoin<DocumentVersionDto>()
.On<ContentVersionDto, DocumentVersionDto>((cv, dv) => cv.Id == dv.Id && dv.Published)
.InnerJoin<ContentVersionCultureVariationDto>()
.On<ContentVersionDto, ContentVersionCultureVariationDto>((cv, ccv) => cv.Id == ccv.VersionId);
foreach (TempDto? dto in Database.Fetch<TempDto>(getPublished))
{
Database.Execute(Sql()
.Update<DocumentCultureVariationDto>(u => u.Set(x => x.Published, true))
.Where<DocumentCultureVariationDto>(x => x.NodeId == dto.NodeId && x.LanguageId == dto.LanguageId));
}
foreach (var sql in sqls)
{
Execute.Sql(sql).Do();
}
// so far, it was kinda impossible to make a culture unavailable again,
// so we *should* not have anything published but not available - ignore
// add name column
AddColumn<DocumentCultureVariationDto>("name");
// so far, every record in the table mapped to an available culture
Sql<ISqlContext> getNames = Sql()
.Select<NodeDto>(x => x.NodeId)
.AndSelect<ContentVersionCultureVariationDto>(x => x.LanguageId, x => x.Name)
.From<NodeDto>()
.InnerJoin<ContentVersionDto>()
.On<NodeDto, ContentVersionDto>((node, cv) => node.NodeId == cv.NodeId && cv.Current)
.InnerJoin<ContentVersionCultureVariationDto>()
.On<ContentVersionDto, ContentVersionCultureVariationDto>((cv, ccv) => cv.Id == ccv.VersionId);
foreach (TempDto? dto in Database.Fetch<TempDto>(getNames))
{
Database.Execute(Sql()
.Update<DocumentCultureVariationDto>(u => u.Set(x => x.Name, dto.Name))
.Where<DocumentCultureVariationDto>(x => x.NodeId == dto.NodeId && x.LanguageId == dto.LanguageId));
}
}
// ReSharper disable once ClassNeverInstantiated.Local
// ReSharper disable UnusedAutoPropertyAccessor.Local
private class TempDto
{
public int NodeId { get; set; }
public int LanguageId { get; set; }
public string? Name { get; set; }
}
// ReSharper restore UnusedAutoPropertyAccessor.Local
}

View File

@@ -1,40 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class RenameLabelAndRichTextPropertyEditorAliases : MigrationBase
{
public RenameLabelAndRichTextPropertyEditorAliases(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
MigratePropertyEditorAlias("Umbraco.TinyMCEv3", Constants.PropertyEditors.Aliases.RichText);
MigratePropertyEditorAlias("Umbraco.NoEdit", Constants.PropertyEditors.Aliases.Label);
}
private void MigratePropertyEditorAlias(string oldAlias, string newAlias)
{
List<DataTypeDto> dataTypes = GetDataTypes(oldAlias);
foreach (DataTypeDto dataType in dataTypes)
{
dataType.EditorAlias = newAlias;
Database.Update(dataType);
}
}
private List<DataTypeDto> GetDataTypes(string editorAlias)
{
List<DataTypeDto>? dataTypes = Database.Fetch<DataTypeDto>(Sql()
.Select<DataTypeDto>()
.From<DataTypeDto>()
.Where<DataTypeDto>(x => x.EditorAlias == editorAlias));
return dataTypes;
}
}

View File

@@ -1,49 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class RenameMediaVersionTable : MigrationBase
{
public RenameMediaVersionTable(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
Rename.Table("cmsMedia").To(Constants.DatabaseSchema.Tables.MediaVersion).Do();
// that is not supported on SqlCE
// Rename.Column("versionId").OnTable(Constants.DatabaseSchema.Tables.MediaVersion).To("id").Do();
AddColumn<MediaVersionDto>("id", out IEnumerable<string> sqls);
Database.Execute($@"UPDATE {Constants.DatabaseSchema.Tables.MediaVersion} SET id=v.id
FROM {Constants.DatabaseSchema.Tables.MediaVersion} m
JOIN cmsContentVersion v on m.versionId = v.versionId
JOIN umbracoNode n on v.contentId=n.id
WHERE n.nodeObjectType='{Constants.ObjectTypes.Media}'");
foreach (var sql in sqls)
{
Execute.Sql(sql).Do();
}
AddColumn<MediaVersionDto>("path", out sqls);
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.MediaVersion} SET path=mediaPath").Do();
foreach (var sql in sqls)
{
Execute.Sql(sql).Do();
}
// we had to run sqls to get the NULL constraints, but we need to get rid of most
Delete.KeysAndIndexes(Constants.DatabaseSchema.Tables.MediaVersion).Do();
Delete.Column("mediaPath").FromTable(Constants.DatabaseSchema.Tables.MediaVersion).Do();
Delete.Column("versionId").FromTable(Constants.DatabaseSchema.Tables.MediaVersion).Do();
Delete.Column("nodeId").FromTable(Constants.DatabaseSchema.Tables.MediaVersion).Do();
}
}

View File

@@ -1,14 +0,0 @@
using Umbraco.Cms.Core;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class RenameUmbracoDomainsTable : MigrationBase
{
public RenameUmbracoDomainsTable(IMigrationContext context)
: base(context)
{
}
protected override void Migrate() => Rename.Table("umbracoDomains").To(Constants.DatabaseSchema.Tables.Domain).Do();
}

View File

@@ -1,46 +0,0 @@
using Umbraco.Cms.Core;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class SuperZero : MigrationBase
{
public SuperZero(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
var exists = Database.Fetch<int>("select id from umbracoUser where id=-1;").Count > 0;
if (exists)
{
return;
}
Database.Execute("update umbracoUser set userLogin = userLogin + '__' where id=0");
Database.Execute("set identity_insert umbracoUser on;");
Database.Execute(@"
insert into umbracoUser (id,
userDisabled, userNoConsole, userName, userLogin, userPassword, passwordConfig,
userEmail, userLanguage, securityStampToken, failedLoginAttempts, lastLockoutDate,
lastPasswordChangeDate, lastLoginDate, emailConfirmedDate, invitedDate,
createDate, updateDate, avatar, tourData)
select
-1 id,
userDisabled, userNoConsole, userName, substring(userLogin, 1, len(userLogin) - 2) userLogin, userPassword, passwordConfig,
userEmail, userLanguage, securityStampToken, failedLoginAttempts, lastLockoutDate,
lastPasswordChangeDate, lastLoginDate, emailConfirmedDate, invitedDate,
createDate, updateDate, avatar, tourData
from umbracoUser where id=0;");
Database.Execute("set identity_insert umbracoUser off;");
Database.Execute("update umbracoUser2UserGroup set userId=-1 where userId=0;");
Database.Execute("update umbracoUser2NodeNotify set userId=-1 where userId=0;");
Database.Execute("update umbracoNode set nodeUser=-1 where nodeUser=0;");
Database.Execute("update umbracoUserLogin set userId=-1 where userId=0;");
Database.Execute($"update {Constants.DatabaseSchema.Tables.ContentVersion} set userId=-1 where userId=0;");
Database.Execute("delete from umbracoUser where id=0;");
}
}

View File

@@ -1,58 +0,0 @@
using NPoco;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class TablesForScheduledPublishing : MigrationBase
{
public TablesForScheduledPublishing(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// Get anything currently scheduled
Sql? releaseSql = new Sql()
.Select("nodeId", "releaseDate")
.From("umbracoDocument")
.Where("releaseDate IS NOT NULL");
Dictionary<int, DateTime>? releases = Database.Dictionary<int, DateTime>(releaseSql);
Sql? expireSql = new Sql()
.Select("nodeId", "expireDate")
.From("umbracoDocument")
.Where("expireDate IS NOT NULL");
Dictionary<int, DateTime>? expires = Database.Dictionary<int, DateTime>(expireSql);
// drop old cols
Delete.Column("releaseDate").FromTable("umbracoDocument").Do();
Delete.Column("expireDate").FromTable("umbracoDocument").Do();
// add new table
Create.Table<ContentScheduleDto>(true).Do();
// migrate the schedule
foreach (KeyValuePair<int, DateTime> s in releases)
{
DateTime date = s.Value;
var action = ContentScheduleAction.Release.ToString();
Insert.IntoTable(ContentScheduleDto.TableName)
.Row(new { id = Guid.NewGuid(), nodeId = s.Key, date, action })
.Do();
}
foreach (KeyValuePair<int, DateTime> s in expires)
{
DateTime date = s.Value;
var action = ContentScheduleAction.Expire.ToString();
Insert.IntoTable(ContentScheduleDto.TableName)
.Row(new { id = Guid.NewGuid(), nodeId = s.Key, date, action })
.Do();
}
}
}

View File

@@ -1,23 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class TagsMigration : MigrationBase
{
public TagsMigration(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// alter columns => non-null
AlterColumn<TagDto>(Constants.DatabaseSchema.Tables.Tag, "group");
AlterColumn<TagDto>(Constants.DatabaseSchema.Tables.Tag, "tag");
// kill unused parentId column
Delete.Column("ParentId").FromTable(Constants.DatabaseSchema.Tables.Tag).Do();
}
}

View File

@@ -1,21 +0,0 @@
using Umbraco.Cms.Core;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class TagsMigrationFix : MigrationBase
{
public TagsMigrationFix(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// kill unused parentId column, if it still exists
if (ColumnExists(Constants.DatabaseSchema.Tables.Tag, "ParentId"))
{
Delete.Column("ParentId").FromTable(Constants.DatabaseSchema.Tables.Tag).Do();
}
}
}

View File

@@ -1,55 +0,0 @@
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class UpdateDefaultMandatoryLanguage : MigrationBase
{
public UpdateDefaultMandatoryLanguage(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// add the new languages lock object
AddLockObjects.EnsureLockObject(Database, Constants.Locks.Languages, "Languages");
// get all existing languages
Sql<ISqlContext> selectDtos = Sql()
.Select<LanguageDto>()
.From<LanguageDto>();
List<LanguageDto>? dtos = Database.Fetch<LanguageDto>(selectDtos);
// get the id of the language which is already the default one, if any,
// else get the lowest language id, which will become the default language
var defaultId = int.MaxValue;
foreach (LanguageDto? dto in dtos)
{
if (dto.IsDefault)
{
defaultId = dto.Id;
break;
}
if (dto.Id < defaultId)
{
defaultId = dto.Id;
}
}
// update, so that language with that id is now default and mandatory
Sql<ISqlContext> updateDefault = Sql()
.Update<LanguageDto>(u => u
.Set(x => x.IsDefault, true)
.Set(x => x.IsMandatory, true))
.Where<LanguageDto>(x => x.Id == defaultId);
Database.Execute(updateDefault);
}
}

View File

@@ -1,121 +0,0 @@
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class UpdatePickerIntegerValuesToUdi : MigrationBase
{
public UpdatePickerIntegerValuesToUdi(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
Sql<ISqlContext> sqlDataTypes = Sql()
.Select<DataTypeDto>()
.From<DataTypeDto>()
.Where<DataTypeDto>(x => x.EditorAlias == Constants.PropertyEditors.Aliases.ContentPicker
|| x.EditorAlias == Constants.PropertyEditors.Aliases.MediaPicker
|| x.EditorAlias == Constants.PropertyEditors.Aliases.MultiNodeTreePicker);
var dataTypes = Database.Fetch<DataTypeDto>(sqlDataTypes).ToList();
foreach (DataTypeDto? datatype in dataTypes.Where(x => !x.Configuration.IsNullOrWhiteSpace()))
{
switch (datatype.EditorAlias)
{
case Constants.PropertyEditors.Aliases.ContentPicker:
case Constants.PropertyEditors.Aliases.MediaPicker:
{
JObject? config = JsonConvert.DeserializeObject<JObject>(datatype.Configuration!);
var startNodeId = config!.Value<string>("startNodeId");
if (!startNodeId.IsNullOrWhiteSpace() && int.TryParse(startNodeId, NumberStyles.Integer,
CultureInfo.InvariantCulture, out var intStartNode))
{
Guid? guid = intStartNode <= 0
? null
: Context.Database.ExecuteScalar<Guid?>(
Sql().Select<NodeDto>(x => x.UniqueId).From<NodeDto>()
.Where<NodeDto>(x => x.NodeId == intStartNode));
if (guid.HasValue)
{
var udi = new GuidUdi(
datatype.EditorAlias == Constants.PropertyEditors.Aliases.MediaPicker
? Constants.UdiEntityType.Media
: Constants.UdiEntityType.Document, guid.Value);
config!["startNodeId"] = new JValue(udi.ToString());
}
else
{
config!.Remove("startNodeId");
}
datatype.Configuration = JsonConvert.SerializeObject(config);
Database.Update(datatype);
}
break;
}
case Constants.PropertyEditors.Aliases.MultiNodeTreePicker:
{
JObject? config = JsonConvert.DeserializeObject<JObject>(datatype.Configuration!);
JObject? startNodeConfig = config!.Value<JObject>("startNode");
if (startNodeConfig != null)
{
var startNodeId = startNodeConfig.Value<string>("id");
var objectType = startNodeConfig.Value<string>("type");
if (!objectType.IsNullOrWhiteSpace()
&& !startNodeId.IsNullOrWhiteSpace()
&& int.TryParse(startNodeId, NumberStyles.Integer, CultureInfo.InvariantCulture,
out var intStartNode))
{
Guid? guid = intStartNode <= 0
? null
: Context.Database.ExecuteScalar<Guid?>(
Sql().Select<NodeDto>(x => x.UniqueId).From<NodeDto>()
.Where<NodeDto>(x => x.NodeId == intStartNode));
string? entityType = null;
switch (objectType?.ToLowerInvariant())
{
case "content":
entityType = Constants.UdiEntityType.Document;
break;
case "media":
entityType = Constants.UdiEntityType.Media;
break;
case "member":
entityType = Constants.UdiEntityType.Member;
break;
}
if (entityType != null && guid.HasValue)
{
var udi = new GuidUdi(entityType, guid.Value);
startNodeConfig["id"] = new JValue(udi.ToString());
}
else
{
startNodeConfig.Remove("id");
}
datatype.Configuration = JsonConvert.SerializeObject(config);
Database.Update(datatype);
}
}
break;
}
}
}
}
}

View File

@@ -1,42 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
/// <summary>
/// Creates/Updates non mandatory FK columns to the user table
/// </summary>
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class UserForeignKeys : MigrationBase
{
public UserForeignKeys(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// first allow NULL-able
Alter.Table(ContentVersionCultureVariationDto.TableName).AlterColumn("availableUserId").AsInt32().Nullable()
.Do();
Alter.Table(ContentVersionDto.TableName).AlterColumn("userId").AsInt32().Nullable().Do();
Alter.Table(Constants.DatabaseSchema.Tables.Log).AlterColumn("userId").AsInt32().Nullable().Do();
Alter.Table(NodeDto.TableName).AlterColumn("nodeUser").AsInt32().Nullable().Do();
// then we can update any non existing users to NULL
Execute.Sql(
$"UPDATE {ContentVersionCultureVariationDto.TableName} SET availableUserId = NULL WHERE availableUserId NOT IN (SELECT id FROM {UserDto.TableName})")
.Do();
Execute.Sql(
$"UPDATE {ContentVersionDto.TableName} SET userId = NULL WHERE userId NOT IN (SELECT id FROM {UserDto.TableName})")
.Do();
Execute.Sql(
$"UPDATE {Constants.DatabaseSchema.Tables.Log} SET userId = NULL WHERE userId NOT IN (SELECT id FROM {UserDto.TableName})")
.Do();
Execute.Sql(
$"UPDATE {NodeDto.TableName} SET nodeUser = NULL WHERE nodeUser NOT IN (SELECT id FROM {UserDto.TableName})")
.Do();
// FKs will be created after migrations
}
}

View File

@@ -1,406 +0,0 @@
using System.Diagnostics;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.DatabaseModelDefinitions;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class VariantsMigration : MigrationBase
{
public VariantsMigration(IMigrationContext context)
: base(context)
{
}
// notes
// do NOT use Rename.Column as it's borked on SQLCE - use ReplaceColumn instead
protected override void Migrate()
{
MigratePropertyData();
CreatePropertyDataIndexes();
MigrateContentAndPropertyTypes();
MigrateContent();
MigrateVersions();
if (Database.Fetch<dynamic>(
$@"SELECT {Constants.DatabaseSchema.Tables.ContentVersion}.nodeId, COUNT({Constants.DatabaseSchema.Tables.ContentVersion}.id)
FROM {Constants.DatabaseSchema.Tables.ContentVersion}
JOIN {Constants.DatabaseSchema.Tables.DocumentVersion} ON {Constants.DatabaseSchema.Tables.ContentVersion}.id={Constants.DatabaseSchema.Tables.DocumentVersion}.id
WHERE {Constants.DatabaseSchema.Tables.DocumentVersion}.published=1
GROUP BY {Constants.DatabaseSchema.Tables.ContentVersion}.nodeId
HAVING COUNT({Constants.DatabaseSchema.Tables.ContentVersion}.id) > 1").Any())
{
Debugger.Break();
throw new Exception("Migration failed: duplicate 'published' document versions.");
}
if (Database.Fetch<dynamic>($@"SELECT v1.nodeId, v1.id, COUNT(v2.id)
FROM {Constants.DatabaseSchema.Tables.ContentVersion} v1
LEFT JOIN {Constants.DatabaseSchema.Tables.ContentVersion} v2 ON v1.nodeId=v2.nodeId AND v2.[current]=1
GROUP BY v1.nodeId, v1.id
HAVING COUNT(v2.id) <> 1").Any())
{
Debugger.Break();
throw new Exception("Migration failed: missing or duplicate 'current' content versions.");
}
}
private void MigratePropertyData()
{
// if the table has already been renamed, we're done
if (TableExists(Constants.DatabaseSchema.Tables.PropertyData))
{
return;
}
// add columns
if (!ColumnExists(PreTables.PropertyData, "languageId"))
{
AddColumn<PropertyDataDto>(PreTables.PropertyData, "languageId");
}
if (!ColumnExists(PreTables.PropertyData, "segment"))
{
AddColumn<PropertyDataDto>(PreTables.PropertyData, "segment");
}
// rename columns
if (ColumnExists(PreTables.PropertyData, "dataNtext"))
{
ReplaceColumn<PropertyDataDto>(PreTables.PropertyData, "dataNtext", "textValue");
}
if (ColumnExists(PreTables.PropertyData, "dataNvarchar"))
{
ReplaceColumn<PropertyDataDto>(PreTables.PropertyData, "dataNvarchar", "varcharValue");
}
if (ColumnExists(PreTables.PropertyData, "dataDecimal"))
{
ReplaceColumn<PropertyDataDto>(PreTables.PropertyData, "dataDecimal", "decimalValue");
}
if (ColumnExists(PreTables.PropertyData, "dataInt"))
{
ReplaceColumn<PropertyDataDto>(PreTables.PropertyData, "dataInt", "intValue");
}
if (ColumnExists(PreTables.PropertyData, "dataDate"))
{
ReplaceColumn<PropertyDataDto>(PreTables.PropertyData, "dataDate", "dateValue");
}
// transform column versionId from guid to integer (contentVersion.id)
if (ColumnType(PreTables.PropertyData, "versionId") == "uniqueidentifier")
{
Alter.Table(PreTables.PropertyData).AddColumn("versionId2").AsInt32().Nullable().Do();
Database.Execute($@"UPDATE {PreTables.PropertyData} SET versionId2={PreTables.ContentVersion}.id
FROM {PreTables.ContentVersion}
INNER JOIN {PreTables.PropertyData} ON {PreTables.ContentVersion}.versionId = {PreTables.PropertyData}.versionId");
Delete.Column("versionId").FromTable(PreTables.PropertyData).Do();
ReplaceColumn<PropertyDataDto>(PreTables.PropertyData, "versionId2", "versionId");
}
// drop column
if (ColumnExists(PreTables.PropertyData, "contentNodeId"))
{
Delete.Column("contentNodeId").FromTable(PreTables.PropertyData).Do();
}
// rename table
Rename.Table(PreTables.PropertyData).To(Constants.DatabaseSchema.Tables.PropertyData).Do();
}
private void CreatePropertyDataIndexes()
{
// Creates a temporary index on umbracoPropertyData to speed up other migrations which update property values.
// It will be removed in CreateKeysAndIndexes before the normal indexes for the table are created
TableDefinition tableDefinition = DefinitionFactory.GetTableDefinition(typeof(PropertyDataDto), SqlSyntax);
Execute.Sql(SqlSyntax.FormatPrimaryKey(tableDefinition)).Do();
Create.Index("IX_umbracoPropertyData_Temp").OnTable(PropertyDataDto.TableName)
.WithOptions().Unique()
.WithOptions().NonClustered()
.OnColumn("versionId").Ascending()
.OnColumn("propertyTypeId").Ascending()
.OnColumn("languageId").Ascending()
.OnColumn("segment").Ascending()
.Do();
}
private void MigrateContentAndPropertyTypes()
{
if (!ColumnExists(PreTables.ContentType, "variations"))
{
AddColumn<ContentTypeDto>(PreTables.ContentType, "variations");
}
if (!ColumnExists(PreTables.PropertyType, "variations"))
{
AddColumn<PropertyTypeDto>(PreTables.PropertyType, "variations");
}
}
private void MigrateContent()
{
// if the table has already been renamed, we're done
if (TableExists(Constants.DatabaseSchema.Tables.Content))
{
return;
}
// rename columns
if (ColumnExists(PreTables.Content, "contentType"))
{
ReplaceColumn<ContentDto>(PreTables.Content, "contentType", "contentTypeId");
}
// drop columns
if (ColumnExists(PreTables.Content, "pk"))
{
Delete.Column("pk").FromTable(PreTables.Content).Do();
}
// rename table
Rename.Table(PreTables.Content).To(Constants.DatabaseSchema.Tables.Content).Do();
}
private void MigrateVersions()
{
// if the table has already been renamed, we're done
if (TableExists(Constants.DatabaseSchema.Tables.ContentVersion))
{
return;
}
// if the table already exists, we're done
if (TableExists(Constants.DatabaseSchema.Tables.DocumentVersion))
{
return;
}
// if the table has already been renamed, we're done
if (TableExists(Constants.DatabaseSchema.Tables.Document))
{
return;
}
// do it all at once
// add contentVersion columns
if (!ColumnExists(PreTables.ContentVersion, "text"))
{
AddColumn<ContentVersionDto>(PreTables.ContentVersion, "text");
}
if (!ColumnExists(PreTables.ContentVersion, "current"))
{
AddColumn<ContentVersionDto>(PreTables.ContentVersion, "current", out IEnumerable<string> sqls);
Database.Execute(
$@"UPDATE {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} SET {SqlSyntax.GetQuotedColumnName("current")}=0");
foreach (var sql in sqls)
{
Database.Execute(sql);
}
}
if (!ColumnExists(PreTables.ContentVersion, "userId"))
{
AddColumn<ContentVersionDto>(PreTables.ContentVersion, "userId", out IEnumerable<string> sqls);
Database.Execute($@"UPDATE {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} SET userId=0");
foreach (var sql in sqls)
{
Database.Execute(sql);
}
}
// rename contentVersion contentId column
if (ColumnExists(PreTables.ContentVersion, "ContentId"))
{
ReplaceColumn<ContentVersionDto>(PreTables.ContentVersion, "ContentId", "nodeId");
}
// populate contentVersion text, current and userId columns for documents
Database.Execute(
$@"UPDATE {PreTables.ContentVersion} SET text=d.text, {SqlSyntax.GetQuotedColumnName("current")}=(d.newest & ~d.published), userId=d.documentUser
FROM {PreTables.ContentVersion} v INNER JOIN {PreTables.Document} d ON d.versionId = v.versionId");
// populate contentVersion text and current columns for non-documents, userId is default
Database.Execute(
$@"UPDATE {PreTables.ContentVersion} SET text=n.text, {SqlSyntax.GetQuotedColumnName("current")}=1, userId=0
FROM {PreTables.ContentVersion} cver
JOIN {SqlSyntax.GetQuotedTableName(Constants.DatabaseSchema.Tables.Node)} n ON cver.nodeId=n.id
WHERE cver.versionId NOT IN (SELECT versionId FROM {SqlSyntax.GetQuotedTableName(PreTables.Document)})");
// create table
Create.Table<DocumentVersionDto>(true).Do();
// every document row becomes a document version
Database.Execute(
$@"INSERT INTO {SqlSyntax.GetQuotedTableName(Constants.DatabaseSchema.Tables.DocumentVersion)} (id, templateId, published)
SELECT cver.id, doc.templateId, doc.published
FROM {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} cver
JOIN {SqlSyntax.GetQuotedTableName(PreTables.Document)} doc ON doc.nodeId=cver.nodeId AND doc.versionId=cver.versionId");
// need to add extra rows for where published=newest
// 'cos INSERT above has inserted the 'published' document version
// and v8 always has a 'edited' document version too
Database.Execute($@"
INSERT INTO {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} (nodeId, versionId, versionDate, userId, {SqlSyntax.GetQuotedColumnName("current")}, text)
SELECT doc.nodeId, NEWID(), doc.updateDate, doc.documentUser, 1, doc.text
FROM {SqlSyntax.GetQuotedTableName(PreTables.Document)} doc
JOIN {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} cver ON doc.nodeId=cver.nodeId AND doc.versionId=cver.versionId
WHERE doc.newest=1 AND doc.published=1");
Database.Execute($@"
INSERT INTO {SqlSyntax.GetQuotedTableName(Constants.DatabaseSchema.Tables.DocumentVersion)} (id, templateId, published)
SELECT cverNew.id, doc.templateId, 0
FROM {SqlSyntax.GetQuotedTableName(PreTables.Document)} doc
JOIN {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} cverNew ON doc.nodeId = cverNew.nodeId
WHERE doc.newest=1 AND doc.published=1 AND cverNew.{SqlSyntax.GetQuotedColumnName("current")} = 1");
Database.Execute($@"
INSERT INTO {SqlSyntax.GetQuotedTableName(PropertyDataDto.TableName)} (propertytypeid,languageId,segment,textValue,varcharValue,decimalValue,intValue,dateValue,versionId)
SELECT propertytypeid,languageId,segment,textValue,varcharValue,decimalValue,intValue,dateValue,cverNew.id
FROM {SqlSyntax.GetQuotedTableName(PreTables.Document)} doc
JOIN {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} cver ON doc.nodeId=cver.nodeId AND doc.versionId=cver.versionId
JOIN {SqlSyntax.GetQuotedTableName(PreTables.ContentVersion)} cverNew ON doc.nodeId = cverNew.nodeId
JOIN {SqlSyntax.GetQuotedTableName(PropertyDataDto.TableName)} pd ON pd.versionId=cver.id
WHERE doc.newest=1 AND doc.published=1 AND cverNew.{SqlSyntax.GetQuotedColumnName("current")} = 1");
// reduce document to 1 row per content
Database.Execute($@"DELETE FROM {PreTables.Document}
WHERE versionId NOT IN (SELECT (versionId) FROM {PreTables.ContentVersion} WHERE {SqlSyntax.GetQuotedColumnName("current")} = 1) AND (published<>1 OR newest<>1)");
// ensure that documents with a published version are marked as published
Database.Execute($@"UPDATE {PreTables.Document} SET published=1 WHERE nodeId IN (
SELECT nodeId FROM {PreTables.ContentVersion} cv INNER JOIN {Constants.DatabaseSchema.Tables.DocumentVersion} dv ON dv.id = cv.id WHERE dv.published=1)");
// drop some document columns
Delete.Column("text").FromTable(PreTables.Document).Do();
Delete.Column("templateId").FromTable(PreTables.Document).Do();
Delete.Column("documentUser").FromTable(PreTables.Document).Do();
Delete.DefaultConstraint().OnTable(PreTables.Document).OnColumn("updateDate").Do();
Delete.Column("updateDate").FromTable(PreTables.Document).Do();
Delete.Column("versionId").FromTable(PreTables.Document).Do();
Delete.DefaultConstraint().OnTable(PreTables.Document).OnColumn("newest").Do();
Delete.Column("newest").FromTable(PreTables.Document).Do();
// add and populate edited column
if (!ColumnExists(PreTables.Document, "edited"))
{
AddColumn<DocumentDto>(PreTables.Document, "edited", out IEnumerable<string> sqls);
Database.Execute($"UPDATE {SqlSyntax.GetQuotedTableName(PreTables.Document)} SET edited=~published");
foreach (var sql in sqls)
{
Database.Execute(sql);
}
}
// set 'edited' to true whenever a 'non-published' property data is != a published one
// cannot compare NTEXT values in TSQL
// cannot cast NTEXT to NVARCHAR(MAX) in SQLCE
// ... bah ...
List<dynamic>? temp = Database.Fetch<dynamic>($@"SELECT n.id,
v1.intValue intValue1, v1.decimalValue decimalValue1, v1.dateValue dateValue1, v1.varcharValue varcharValue1, v1.textValue textValue1,
v2.intValue intValue2, v2.decimalValue decimalValue2, v2.dateValue dateValue2, v2.varcharValue varcharValue2, v2.textValue textValue2
FROM {Constants.DatabaseSchema.Tables.Node} n
JOIN {PreTables.ContentVersion} cv1 ON n.id=cv1.nodeId AND cv1.{SqlSyntax.GetQuotedColumnName("current")}=1
JOIN {Constants.DatabaseSchema.Tables.PropertyData} v1 ON cv1.id=v1.versionId
JOIN {PreTables.ContentVersion} cv2 ON n.id=cv2.nodeId
JOIN {Constants.DatabaseSchema.Tables.DocumentVersion} dv ON cv2.id=dv.id AND dv.published=1
JOIN {Constants.DatabaseSchema.Tables.PropertyData} v2 ON cv2.id=v2.versionId
WHERE v1.propertyTypeId=v2.propertyTypeId
AND (v1.languageId=v2.languageId OR (v1.languageId IS NULL AND v2.languageId IS NULL))
AND (v1.segment=v2.segment OR (v1.segment IS NULL AND v2.segment IS NULL))");
var updatedIds = new HashSet<int>();
foreach (dynamic t in temp)
{
if (t.intValue1 != t.intValue2 || t.decimalValue1 != t.decimalValue2 || t.dateValue1 != t.dateValue2 ||
t.varcharValue1 != t.varcharValue2 || t.textValue1 != t.textValue2)
{
if (updatedIds.Add((int)t.id))
{
Database.Execute(
$"UPDATE {SqlSyntax.GetQuotedTableName(PreTables.Document)} SET edited=1 WHERE nodeId=@nodeId",
new { nodeId = t.id });
}
}
}
// drop more columns
Delete.Column("versionId").FromTable(PreTables.ContentVersion).Do();
// rename tables
Rename.Table(PreTables.ContentVersion).To(Constants.DatabaseSchema.Tables.ContentVersion).Do();
Rename.Table(PreTables.Document).To(Constants.DatabaseSchema.Tables.Document).Do();
}
private static class PreTables
{
// ReSharper disable UnusedMember.Local
public const string Lock = "umbracoLock";
public const string Log = "umbracoLog";
public const string Node = "umbracoNode";
public const string NodeData = "cmsContentNu";
public const string NodeXml = "cmsContentXml";
public const string NodePreviewXml = "cmsPreviewXml";
public const string ContentType = "cmsContentType";
public const string ContentChildType = "cmsContentTypeAllowedContentType";
public const string DocumentType = "cmsDocumentType";
public const string ElementTypeTree = "cmsContentType2ContentType";
public const string DataType = "cmsDataType";
public const string DataTypePreValue = "cmsDataTypePreValues";
public const string Template = "cmsTemplate";
public const string Content = "cmsContent";
public const string ContentVersion = "cmsContentVersion";
public const string Document = "cmsDocument";
public const string PropertyType = "cmsPropertyType";
public const string PropertyTypeGroup = "cmsPropertyTypeGroup";
public const string PropertyData = "cmsPropertyData";
public const string RelationType = "umbracoRelationType";
public const string Relation = "umbracoRelation";
public const string Domain = "umbracoDomains";
public const string Language = "umbracoLanguage";
public const string DictionaryEntry = "cmsDictionary";
public const string DictionaryValue = "cmsLanguageText";
public const string User = "umbracoUser";
public const string UserGroup = "umbracoUserGroup";
public const string UserStartNode = "umbracoUserStartNode";
public const string User2UserGroup = "umbracoUser2UserGroup";
public const string User2NodeNotify = "umbracoUser2NodeNotify";
public const string UserGroup2App = "umbracoUserGroup2App";
public const string UserGroup2NodePermission = "umbracoUserGroup2NodePermission";
public const string ExternalLogin = "umbracoExternalLogin";
public const string Macro = "cmsMacro";
public const string MacroProperty = "cmsMacroProperty";
public const string Member = "cmsMember";
public const string MemberType = "cmsMemberType";
public const string Member2MemberGroup = "cmsMember2MemberGroup";
public const string Access = "umbracoAccess";
public const string AccessRule = "umbracoAccessRule";
public const string RedirectUrl = "umbracoRedirectUrl";
public const string CacheInstruction = "umbracoCacheInstruction";
public const string Migration = "umbracoMigration";
public const string Server = "umbracoServer";
public const string Tag = "cmsTags";
public const string TagRelationship = "cmsTagRelationship";
// ReSharper restore UnusedMember.Local
}
}

View File

@@ -1,18 +0,0 @@
using HtmlAgilityPack;
using Umbraco.Cms.Infrastructure.Migrations.PostMigrations;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_0_1;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class ChangeNuCacheJsonFormat : MigrationBase
{
public ChangeNuCacheJsonFormat(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// This has been removed since post migrations are no longer a thing, and this migration should be deleted.
}
}

View File

@@ -1,19 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_10_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddPropertyTypeLabelOnTopColumn : MigrationBase
{
public AddPropertyTypeLabelOnTopColumn(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToList();
AddColumnIfNotExists<PropertyTypeDto>(columns, "labelOnTop");
}
}

View File

@@ -1,44 +0,0 @@
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_15_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddCmsContentNuByteColumn : MigrationBase
{
private const string TempTableName = Constants.DatabaseSchema.TableNamePrefix + "cms" + "ContentNuTEMP";
public AddCmsContentNuByteColumn(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
AlterColumn<ContentNuDto>(Constants.DatabaseSchema.Tables.NodeData, "data");
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToList();
AddColumnIfNotExists<ContentNuDto>(columns, "dataRaw");
}
[TableName(TempTableName)]
[ExplicitColumns]
private class ContentNuDtoTemp
{
[Column("nodeId")]
public int NodeId { get; set; }
[Column("published")]
public bool Published { get; set; }
[Column("data")]
[SpecialDbType(SpecialDbTypes.NTEXT)]
[NullSetting(NullSetting = NullSettings.Null)]
public string? Data { get; set; }
[Column("rv")]
public long Rv { get; set; }
}
}

View File

@@ -1,15 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_15_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class UpdateCmsPropertyGroupIdSeed : MigrationBase
{
public UpdateCmsPropertyGroupIdSeed(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// NOOP - was sql ce only
}
}

View File

@@ -1,74 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Migrations.Expressions.Execute.Expressions;
using Umbraco.Cms.Infrastructure.Persistence.DatabaseModelDefinitions;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_15_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class UpgradedIncludeIndexes : MigrationBase
{
public UpgradedIncludeIndexes(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// Need to drop the FK for the redirect table before modifying the unique id index
Delete.ForeignKey()
.FromTable(Constants.DatabaseSchema.Tables.RedirectUrl)
.ForeignColumn("contentKey")
.ToTable(NodeDto.TableName)
.PrimaryColumn("uniqueID")
.Do();
var nodeDtoIndexes = new[]
{
$"IX_{NodeDto.TableName}_UniqueId", $"IX_{NodeDto.TableName}_ObjectType",
$"IX_{NodeDto.TableName}_Level",
};
DeleteIndexes<NodeDto>(nodeDtoIndexes); // delete existing ones
CreateIndexes<NodeDto>(nodeDtoIndexes); // update/add
// Now re-create the FK for the redirect table
Create.ForeignKey()
.FromTable(Constants.DatabaseSchema.Tables.RedirectUrl)
.ForeignColumn("contentKey")
.ToTable(NodeDto.TableName)
.PrimaryColumn("uniqueID")
.Do();
var contentVersionIndexes = new[]
{
$"IX_{ContentVersionDto.TableName}_NodeId", $"IX_{ContentVersionDto.TableName}_Current",
};
DeleteIndexes<ContentVersionDto>(contentVersionIndexes); // delete existing ones
CreateIndexes<ContentVersionDto>(contentVersionIndexes); // update/add
}
private void DeleteIndexes<T>(params string[] toDelete)
{
TableDefinition tableDef = DefinitionFactory.GetTableDefinition(typeof(T), Context.SqlContext.SqlSyntax);
foreach (var i in toDelete)
{
if (IndexExists(i))
{
Delete.Index(i).OnTable(tableDef.Name).Do();
}
}
}
private void CreateIndexes<T>(params string[] toCreate)
{
TableDefinition tableDef = DefinitionFactory.GetTableDefinition(typeof(T), Context.SqlContext.SqlSyntax);
foreach (var c in toCreate)
{
// get the definition by name
IndexDefinition index = tableDef.Indexes.First(x => x.Name == c);
new ExecuteSqlStatementExpression(Context) { SqlStatement = Context.SqlContext.SqlSyntax.Format(index) }
.Execute();
}
}
}

View File

@@ -1,71 +0,0 @@
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_17_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddPropertyTypeGroupColumns : MigrationBase
{
private readonly IShortStringHelper _shortStringHelper;
public AddPropertyTypeGroupColumns(IMigrationContext context, IShortStringHelper shortStringHelper)
: base(context) => _shortStringHelper = shortStringHelper;
internal IEnumerable<PropertyTypeGroupDto> PopulateAliases(IEnumerable<PropertyTypeGroupDto> dtos)
{
foreach (IGrouping<string?, PropertyTypeGroupDto> dtosPerAlias in dtos.GroupBy(x =>
x.Text?.ToSafeAlias(_shortStringHelper, true)))
{
IEnumerable<IGrouping<string?, PropertyTypeGroupDto>> dtosPerAliasAndText =
dtosPerAlias.GroupBy(x => x.Text);
var numberSuffix = 1;
foreach (IGrouping<string?, PropertyTypeGroupDto> dtosPerText in dtosPerAliasAndText)
{
foreach (PropertyTypeGroupDto dto in dtosPerText)
{
dto.Alias = dtosPerAlias.Key ?? string.Empty;
if (numberSuffix > 1)
{
// More than 1 name found for the alias, so add a suffix
dto.Alias += numberSuffix;
}
yield return dto;
}
numberSuffix++;
}
if (numberSuffix > 2)
{
Logger.LogError(
"Detected the same alias {Alias} for different property group names {Names}, the migration added suffixes, but this might break backwards compatibility.",
dtosPerAlias.Key, dtosPerAliasAndText.Select(x => x.Key));
}
}
}
protected override void Migrate()
{
AddColumn<PropertyTypeGroupDto>("type");
// Add column without constraints
AddColumn<PropertyTypeGroupDto>("alias", out IEnumerable<string> sqls);
// Populate non-null alias column
List<PropertyTypeGroupDto>? dtos = Database.Query<PropertyTypeGroupDto>().Where(x => x.Alias == null).ToList();
foreach (PropertyTypeGroupDto dto in PopulateAliases(dtos))
{
Database.Update(dto, x => new { x.Alias });
}
// Finally add the constraints
foreach (var sql in sqls)
{
Database.Execute(sql);
}
}
}

View File

@@ -1,17 +0,0 @@
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_1_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class ConvertTinyMceAndGridMediaUrlsToLocalLink : MigrationBase
{
private readonly IMediaService _mediaService;
public ConvertTinyMceAndGridMediaUrlsToLocalLink(IMigrationContext context, IMediaService mediaService)
: base(context) => _mediaService = mediaService ?? throw new ArgumentNullException(nameof(mediaService));
protected override void Migrate()
{
}
}

View File

@@ -1,18 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_1_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class FixContentNuCascade : MigrationBase
{
public FixContentNuCascade(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
Delete.KeysAndIndexes<ContentNuDto>().Do();
Create.KeysAndIndexes<ContentNuDto>().Do();
}
}

View File

@@ -1,40 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_1_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class RenameUserLoginDtoDateIndex : MigrationBase
{
public RenameUserLoginDtoDateIndex(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// there has been some confusion with an index name, resulting in
// different names depending on which migration path was followed,
// and discrepancies between an upgraded or an installed database.
// better normalize
if (IndexExists("IX_umbracoUserLogin_lastValidatedUtc"))
{
return;
}
if (IndexExists("IX_userLoginDto_lastValidatedUtc"))
{
Delete
.Index("IX_userLoginDto_lastValidatedUtc")
.OnTable(UserLoginDto.TableName)
.Do();
}
Create
.Index("IX_umbracoUserLogin_lastValidatedUtc")
.OnTable(UserLoginDto.TableName)
.OnColumn("lastValidatedUtc")
.Ascending()
.WithOptions().NonClustered()
.Do();
}
}

View File

@@ -1,16 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_6_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddMainDomLock : MigrationBase
{
public AddMainDomLock(IMigrationContext context)
: base(context)
{
}
protected override void Migrate() => Database.Insert(Constants.DatabaseSchema.Tables.Lock, "id", false,
new LockDto { Id = Constants.Locks.MainDom, Name = "MainDom" });
}

View File

@@ -1,39 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Migrations.Install;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_6_0;
/// <summary>
/// Ensures the new relation types are created
/// </summary>
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddNewRelationTypes : MigrationBase
{
public AddNewRelationTypes(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
CreateRelation(
Constants.Conventions.RelationTypes.RelatedMediaAlias,
Constants.Conventions.RelationTypes.RelatedMediaName);
CreateRelation(
Constants.Conventions.RelationTypes.RelatedDocumentAlias,
Constants.Conventions.RelationTypes.RelatedDocumentName);
}
private void CreateRelation(string alias, string name)
{
Guid uniqueId =
DatabaseDataCreator
.CreateUniqueRelationTypeId(
alias,
name); // this is the same as how it installs so everything is consistent
Insert.IntoTable(Constants.DatabaseSchema.Tables.RelationType)
.Row(new { typeUniqueId = uniqueId, dual = 0, name, alias })
.Do();
}
}

View File

@@ -1,20 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_6_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddPropertyTypeValidationMessageColumns : MigrationBase
{
public AddPropertyTypeValidationMessageColumns(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToList();
AddColumnIfNotExists<PropertyTypeDto>(columns, "mandatoryMessage");
AddColumnIfNotExists<PropertyTypeDto>(columns, "validationRegExpMessage");
}
}

View File

@@ -1,32 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_6_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class MissingContentVersionsIndexes : MigrationBase
{
private const string IndexName = "IX_" + ContentVersionDto.TableName + "_NodeId";
public MissingContentVersionsIndexes(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
// We must check before we create an index because if we are upgrading from v7 we force re-create all
// indexes in the whole DB and then this would throw
if (!IndexExists(IndexName))
{
Create
.Index(IndexName)
.OnTable(ContentVersionDto.TableName)
.OnColumn("nodeId")
.Ascending()
.OnColumn("current")
.Ascending()
.WithOptions().NonClustered()
.Do();
}
}
}

View File

@@ -1,43 +0,0 @@
using Umbraco.Cms.Core;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_6_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class UpdateRelationTypeTable : MigrationBase
{
public UpdateRelationTypeTable(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("parentObjectType").AsGuid().Nullable()
.Do();
Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("childObjectType").AsGuid().Nullable()
.Do();
// TODO: We have to update this field to ensure it's not null, we can just copy across the name since that is not nullable
// drop index before we can alter the column
if (IndexExists("IX_umbracoRelationType_alias"))
{
Delete
.Index("IX_umbracoRelationType_alias")
.OnTable(Constants.DatabaseSchema.Tables.RelationType)
.Do();
}
// change the column to non nullable
Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("alias").AsString(100).NotNullable().Do();
// re-create the index
Create
.Index("IX_umbracoRelationType_alias")
.OnTable(Constants.DatabaseSchema.Tables.RelationType)
.OnColumn("alias")
.Ascending()
.WithOptions().Unique().WithOptions().NonClustered()
.Do();
}
}

View File

@@ -1,32 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_7_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class MissingDictionaryIndex : MigrationBase
{
public MissingDictionaryIndex(IMigrationContext context)
: base(context)
{
}
/// <summary>
/// Adds an index to the foreign key column <c>parent</c> on <c>DictionaryDto</c>'s table
/// if it doesn't already exist
/// </summary>
protected override void Migrate()
{
var indexName = "IX_" + DictionaryDto.TableName + "_Parent";
if (!IndexExists(indexName))
{
Create
.Index(indexName)
.OnTable(DictionaryDto.TableName)
.OnColumn("parent")
.Ascending()
.WithOptions().NonClustered()
.Do();
}
}
}

View File

@@ -1,19 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_9_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class ExternalLoginTableUserData : MigrationBase
{
public ExternalLoginTableUserData(IMigrationContext context)
: base(context)
{
}
/// <summary>
/// Adds new column to the External Login table
/// </summary>
protected override void Migrate() =>
AddColumn<ExternalLoginDto>(Constants.DatabaseSchema.Tables.ExternalLogin, "userData");
}

View File

@@ -1,22 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddPasswordConfigToMemberTable : MigrationBase
{
public AddPasswordConfigToMemberTable(IMigrationContext context)
: base(context)
{
}
/// <summary>
/// Adds new columns to members table
/// </summary>
protected override void Migrate()
{
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToList();
AddColumnIfNotExists<MemberDto>(columns, "passwordConfig");
}
}

View File

@@ -1,134 +0,0 @@
using Microsoft.Extensions.Logging;
using NPoco;
using Umbraco.Cms.Infrastructure.Migrations.Expressions.Execute.Expressions;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Infrastructure.Persistence.DatabaseModelDefinitions;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class DictionaryTablesIndexes : MigrationBase
{
private const string IndexedDictionaryColumn = "key";
private const string IndexedLanguageTextColumn = "languageId";
public DictionaryTablesIndexes(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
var indexDictionaryDto = $"IX_{DictionaryDto.TableName}_{IndexedDictionaryColumn}";
var indexLanguageTextDto = $"IX_{LanguageTextDto.TableName}_{IndexedLanguageTextColumn}";
var dictionaryColumnsToBeIndexed = new[] { IndexedDictionaryColumn };
var langTextColumnsToBeIndexed = new[] { IndexedLanguageTextColumn, "UniqueId" };
var dictionaryTableHasDuplicates = ContainsDuplicates<DictionaryDto>(dictionaryColumnsToBeIndexed);
var langTextTableHasDuplicates = ContainsDuplicates<LanguageTextDto>(langTextColumnsToBeIndexed);
// Check if there are any duplicates before we delete and re-create the indexes since
// if there are duplicates we won't be able to create the new unique indexes
if (!dictionaryTableHasDuplicates)
{
// Delete existing
DeleteIndex<DictionaryDto>(indexDictionaryDto);
}
if (!langTextTableHasDuplicates)
{
// Delete existing
DeleteIndex<LanguageTextDto>(indexLanguageTextDto);
}
// Try to re-create/add
TryAddUniqueConstraint<DictionaryDto>(dictionaryColumnsToBeIndexed, indexDictionaryDto,
dictionaryTableHasDuplicates);
TryAddUniqueConstraint<LanguageTextDto>(langTextColumnsToBeIndexed, indexLanguageTextDto,
langTextTableHasDuplicates);
}
private void DeleteIndex<TDto>(string indexName)
{
TableDefinition tableDef = DefinitionFactory.GetTableDefinition(typeof(TDto), Context.SqlContext.SqlSyntax);
if (IndexExists(indexName))
{
Delete.Index(indexName).OnTable(tableDef.Name).Do();
}
}
private void CreateIndex<TDto>(string indexName)
{
TableDefinition tableDef = DefinitionFactory.GetTableDefinition(typeof(TDto), Context.SqlContext.SqlSyntax);
// get the definition by name
IndexDefinition index = tableDef.Indexes.First(x => x.Name == indexName);
new ExecuteSqlStatementExpression(Context) { SqlStatement = Context.SqlContext.SqlSyntax.Format(index) }
.Execute();
}
private void TryAddUniqueConstraint<TDto>(string[] columns, string index, bool containsDuplicates)
{
TableDefinition tableDef = DefinitionFactory.GetTableDefinition(typeof(TDto), Context.SqlContext.SqlSyntax);
// Check the existing data to ensure the constraint can be successfully applied.
// This seems to be better than relying on catching an exception as this leads to
// transaction errors: "This SqlTransaction has completed; it is no longer usable".
var columnsDescription = string.Join("], [", columns);
if (containsDuplicates)
{
var message = $"Could not create unique constraint on [{tableDef.Name}] due to existing " +
$"duplicate records across the column{(columns.Length > 1 ? "s" : string.Empty)}: [{columnsDescription}].";
LogIncompleteMigrationStep(message);
return;
}
CreateIndex<TDto>(index);
}
private bool ContainsDuplicates<TDto>(string[] columns)
{
// Check for duplicates by comparing the total count of all records with the count of records distinct by the
// provided column. If the former is greater than the latter, there's at least one duplicate record.
var recordCount = GetRecordCount<TDto>();
var distinctRecordCount = GetDistinctRecordCount<TDto>(columns);
return recordCount > distinctRecordCount;
}
private int GetRecordCount<TDto>()
{
Sql<ISqlContext> countQuery = Database.SqlContext.Sql()
.SelectCount()
.From<TDto>();
return Database.ExecuteScalar<int>(countQuery);
}
private int GetDistinctRecordCount<TDto>(string[] columns)
{
string columnSpecification;
columnSpecification = columns.Length == 1
? QuoteColumnName(columns[0])
: $"CONCAT({string.Join(",", columns.Select(QuoteColumnName))})";
Sql<ISqlContext> distinctCountQuery = Database.SqlContext.Sql()
.Select($"COUNT(DISTINCT({columnSpecification}))")
.From<TDto>();
return Database.ExecuteScalar<int>(distinctCountQuery);
}
private void LogIncompleteMigrationStep(string message) =>
Logger.LogError($"Database migration step failed: {message}");
private string StringConvertedAndQuotedColumnName(string column) =>
$"CONVERT(nvarchar(1000),{QuoteColumnName(column)})";
private string QuoteColumnName(string column) => $"[{column}]";
}

View File

@@ -1,71 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class ExternalLoginTableIndexes : MigrationBase
{
public ExternalLoginTableIndexes(IMigrationContext context)
: base(context)
{
}
/// <summary>
/// Adds new indexes to the External Login table
/// </summary>
protected override void Migrate()
{
// Before adding these indexes we need to remove duplicate data.
// Get all logins by latest
var logins = Database.Fetch<ExternalLoginTokenTable.LegacyExternalLoginDto>()
.OrderByDescending(x => x.CreateDate)
.ToList();
var toDelete = new List<int>();
// used to track duplicates so they can be removed
var keys = new HashSet<(string, string)>();
foreach (ExternalLoginTokenTable.LegacyExternalLoginDto login in logins)
{
if (!keys.Add((login.ProviderKey, login.LoginProvider)))
{
// if it already exists we need to remove this one
toDelete.Add(login.Id);
}
}
if (toDelete.Count > 0)
{
Database.DeleteMany<ExternalLoginTokenTable.LegacyExternalLoginDto>().Where(x => toDelete.Contains(x.Id))
.Execute();
}
var indexName1 = "IX_" + ExternalLoginTokenTable.LegacyExternalLoginDto.TableName + "_LoginProvider";
if (!IndexExists(indexName1))
{
Create
.Index(indexName1)
.OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName)
.OnColumn("loginProvider")
.Ascending()
.WithOptions()
.Unique()
.WithOptions()
.NonClustered()
.Do();
}
var indexName2 = "IX_" + ExternalLoginTokenTable.LegacyExternalLoginDto.TableName + "_ProviderKey";
if (!IndexExists(indexName2))
{
Create
.Index(indexName2)
.OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName)
.OnColumn("loginProvider").Ascending()
.OnColumn("providerKey").Ascending()
.WithOptions()
.NonClustered()
.Do();
}
}
}

View File

@@ -1,59 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0;
/// <summary>
/// Fixes up the original <see cref="ExternalLoginTableIndexes" /> for post RC release to ensure that
/// the correct indexes are applied.
/// </summary>
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class ExternalLoginTableIndexesFixup : MigrationBase
{
public ExternalLoginTableIndexesFixup(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
var indexName1 = "IX_" + ExternalLoginTokenTable.LegacyExternalLoginDto.TableName + "_LoginProvider";
var indexName2 = "IX_" + ExternalLoginTokenTable.LegacyExternalLoginDto.TableName + "_ProviderKey";
if (IndexExists(indexName1))
{
// drop it since the previous migration index was wrong, and we
// need to modify a column that belons to it
Delete.Index(indexName1).OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName).Do();
}
if (IndexExists(indexName2))
{
// drop since it's using a column we're about to modify
Delete.Index(indexName2).OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName).Do();
}
// then fixup the length of the loginProvider column
AlterColumn<ExternalLoginTokenTable.LegacyExternalLoginDto>(
ExternalLoginTokenTable.LegacyExternalLoginDto.TableName, "loginProvider");
// create it with the correct definition
Create
.Index(indexName1)
.OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName)
.OnColumn("loginProvider").Ascending()
.OnColumn("userId").Ascending()
.WithOptions()
.Unique()
.WithOptions()
.NonClustered()
.Do();
// re-create the original
Create
.Index(indexName2)
.OnTable(ExternalLoginTokenTable.LegacyExternalLoginDto.TableName)
.OnColumn("loginProvider").Ascending()
.OnColumn("providerKey").Ascending()
.WithOptions()
.NonClustered()
.Do();
}
}

View File

@@ -1,80 +0,0 @@
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations;
using Umbraco.Cms.Infrastructure.Persistence.DatabaseModelDefinitions;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class ExternalLoginTokenTable : MigrationBase
{
public ExternalLoginTokenTable(IMigrationContext context)
: base(context)
{
}
/// <summary>
/// Adds new External Login token table
/// </summary>
protected override void Migrate()
{
IEnumerable<string> tables = SqlSyntax.GetTablesInSchema(Context.Database);
if (tables.InvariantContains(ExternalLoginTokenDto.TableName))
{
return;
}
Create.Table<ExternalLoginTokenDto>().Do();
}
[TableName(TableName)]
[ExplicitColumns]
[PrimaryKey("Id")]
internal class LegacyExternalLoginDto
{
public const string TableName = Constants.DatabaseSchema.Tables.ExternalLogin;
[Column("id")]
[PrimaryKeyColumn]
public int Id { get; set; }
[Obsolete(
"This only exists to ensure you can upgrade using external logins from umbraco version where this was used to the new where it is not used")]
[Column("userId")]
public int? UserId { get; set; }
/// <summary>
/// Used to store the name of the provider (i.e. Facebook, Google)
/// </summary>
[Column("loginProvider")]
[Length(400)]
[NullSetting(NullSetting = NullSettings.NotNull)]
[Index(IndexTypes.UniqueNonClustered, ForColumns = "loginProvider,userOrMemberKey",
Name = "IX_" + TableName + "_LoginProvider")]
public string LoginProvider { get; set; } = null!;
/// <summary>
/// Stores the key the provider uses to lookup the login
/// </summary>
[Column("providerKey")]
[Length(4000)]
[NullSetting(NullSetting = NullSettings.NotNull)]
[Index(IndexTypes.NonClustered, ForColumns = "loginProvider,providerKey",
Name = "IX_" + TableName + "_ProviderKey")]
public string ProviderKey { get; set; } = null!;
[Column("createDate")]
[Constraint(Default = SystemMethods.CurrentDateTime)]
public DateTime CreateDate { get; set; }
/// <summary>
/// Used to store any arbitrary data for the user and external provider - like user tokens returned from the provider
/// </summary>
[Column("userData")]
[NullSetting(NullSetting = NullSettings.Null)]
[SpecialDbType(SpecialDbTypes.NTEXT)]
public string? UserData { get; set; }
}
}

View File

@@ -1,23 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class MemberTableColumns : MigrationBase
{
public MemberTableColumns(IMigrationContext context)
: base(context)
{
}
/// <summary>
/// Adds new columns to members table
/// </summary>
protected override void Migrate()
{
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToList();
AddColumnIfNotExists<MemberDto>(columns, "securityStampToken");
AddColumnIfNotExists<MemberDto>(columns, "emailConfirmedDate");
}
}

View File

@@ -1,105 +0,0 @@
using Newtonsoft.Json;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Infrastructure.Migrations.PostMigrations;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class MigrateLogViewerQueriesFromFileToDb : MigrationBase
{
internal static readonly IEnumerable<LogViewerQueryDto> _defaultLogQueries = new LogViewerQueryDto[]
{
new()
{
Name = "Find all logs where the Level is NOT Verbose and NOT Debug",
Query = "Not(@Level='Verbose') and Not(@Level='Debug')",
},
new()
{
Name = "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)",
Query = "Has(@Exception)",
},
new() { Name = "Find all logs that have the property 'Duration'", Query = "Has(Duration)" },
new()
{
Name = "Find all logs that have the property 'Duration' and the duration is greater than 1000ms",
Query = "Has(Duration) and Duration > 1000",
},
new()
{
Name = "Find all logs that are from the namespace 'Umbraco.Core'",
Query = "StartsWith(SourceContext, 'Umbraco.Core')",
},
new()
{
Name = "Find all logs that use a specific log message template",
Query = "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'",
},
new()
{
Name = "Find logs where one of the items in the SortedComponentTypes property array is equal to",
Query = "SortedComponentTypes[?] = 'Umbraco.Web.Search.ExamineComponent'",
},
new()
{
Name = "Find logs where one of the items in the SortedComponentTypes property array contains",
Query = "Contains(SortedComponentTypes[?], 'DatabaseServer')",
},
new()
{
Name = "Find all logs that the message has localhost in it with SQL like",
Query = "@Message like '%localhost%'",
},
new()
{
Name = "Find all logs that the message that starts with 'end' in it with SQL like",
Query = "@Message like 'end%'"
},
};
private readonly IHostingEnvironment _hostingEnvironment;
public MigrateLogViewerQueriesFromFileToDb(IMigrationContext context, IHostingEnvironment hostingEnvironment)
: base(context) =>
_hostingEnvironment = hostingEnvironment;
internal static string GetLogViewerQueryFile(IHostingEnvironment hostingEnvironment) =>
hostingEnvironment.MapPathContentRoot(
Path.Combine(Constants.SystemDirectories.Config, "logviewer.searches.config.js"));
protected override void Migrate()
{
CreateDatabaseTable();
MigrateFileContentToDB();
}
private void CreateDatabaseTable()
{
IEnumerable<string> tables = SqlSyntax.GetTablesInSchema(Context.Database);
if (!tables.InvariantContains(Constants.DatabaseSchema.Tables.LogViewerQuery))
{
Create.Table<LogViewerQueryDto>().Do();
}
}
private void MigrateFileContentToDB()
{
var logViewerQueryFile = GetLogViewerQueryFile(_hostingEnvironment);
IEnumerable<LogViewerQueryDto>? logQueriesInFile = File.Exists(logViewerQueryFile)
? JsonConvert.DeserializeObject<LogViewerQueryDto[]>(File.ReadAllText(logViewerQueryFile))
: _defaultLogQueries;
LogViewerQueryDto[]? logQueriesInDb = Database.Query<LogViewerQueryDto>().ToArray();
if (logQueriesInDb.Any())
{
return;
}
Database.InsertBulk(logQueriesInFile!);
}
}

View File

@@ -1,20 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class UmbracoServerColumn : MigrationBase
{
public UmbracoServerColumn(IMigrationContext context)
: base(context)
{
}
/// <summary>
/// Adds new columns to members table
/// </summary>
protected override void Migrate() => ReplaceColumn<ServerRegistrationDto>(
Constants.DatabaseSchema.Tables.Server,
"isMaster", "isSchedulingPublisher");
}

View File

@@ -1,22 +0,0 @@
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_2_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddDefaultForNotificationsToggle : MigrationBase
{
public AddDefaultForNotificationsToggle(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
Sql<ISqlContext> updateSQL =
Sql(
$"UPDATE {Constants.DatabaseSchema.Tables.UserGroup} SET userGroupDefaultPermissions = userGroupDefaultPermissions + 'N' WHERE userGroupAlias IN ('admin', 'writer', 'editor')");
Execute.Sql(updateSQL.SQL).Do();
}
}

View File

@@ -1,24 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_3_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class AddTwoFactorLoginTable : MigrationBase
{
public AddTwoFactorLoginTable(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
IEnumerable<string> tables = SqlSyntax.GetTablesInSchema(Context.Database);
if (tables.InvariantContains(TwoFactorLoginDto.TableName))
{
return;
}
Create.Table<TwoFactorLoginDto>().Do();
}
}

View File

@@ -1,65 +0,0 @@
using Umbraco.Cms.Core.Packaging;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_3_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class MovePackageXMLToDb : MigrationBase
{
private readonly PackagesRepository _packagesRepository;
private readonly PackageDefinitionXmlParser _xmlParser;
/// <summary>
/// Initializes a new instance of the <see cref="MovePackageXMLToDb" /> class.
/// </summary>
public MovePackageXMLToDb(IMigrationContext context, PackagesRepository packagesRepository)
: base(context)
{
_packagesRepository = packagesRepository;
_xmlParser = new PackageDefinitionXmlParser();
}
/// <inheritdoc />
protected override void Migrate()
{
CreateDatabaseTable();
MigrateCreatedPackageFilesToDb();
}
private void CreateDatabaseTable()
{
// Add CreatedPackage table in database if it doesn't exist
IEnumerable<string> tables = SqlSyntax.GetTablesInSchema(Context.Database);
if (!tables.InvariantContains(CreatedPackageSchemaDto.TableName))
{
Create.Table<CreatedPackageSchemaDto>().Do();
}
}
private void MigrateCreatedPackageFilesToDb()
{
// Load data from file
IEnumerable<PackageDefinition> packages = _packagesRepository.GetAll().WhereNotNull();
var createdPackageDtos = new List<CreatedPackageSchemaDto>();
foreach (PackageDefinition package in packages)
{
// Create dto from xmlDocument
var dto = new CreatedPackageSchemaDto
{
Name = package.Name,
Value = _xmlParser.ToXml(package).ToString(),
UpdateDate = DateTime.Now,
PackageId = Guid.NewGuid(),
};
createdPackageDtos.Add(dto);
}
_packagesRepository.DeleteLocalRepositoryFiles();
if (createdPackageDtos.Any())
{
// Insert dto into CreatedPackage table
Database.InsertBulk(createdPackageDtos);
}
}
}

View File

@@ -1,64 +0,0 @@
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_3_0;
[Obsolete("This is not used anymore and will be removed in Umbraco 13")]
public class UpdateExternalLoginToUseKeyInsteadOfId : MigrationBase
{
public UpdateExternalLoginToUseKeyInsteadOfId(IMigrationContext context)
: base(context)
{
}
protected override void Migrate()
{
if (!ColumnExists(ExternalLoginDto.TableName, "userOrMemberKey"))
{
var indexNameToRecreate = "IX_" + ExternalLoginDto.TableName + "_LoginProvider";
var indexNameToDelete = "IX_" + ExternalLoginDto.TableName + "_userId";
if (IndexExists(indexNameToRecreate))
{
// drop it since the previous migration index was wrong, and we
// need to modify a column that belons to it
Delete.Index(indexNameToRecreate).OnTable(ExternalLoginDto.TableName).Do();
}
if (IndexExists(indexNameToDelete))
{
// drop it since the previous migration index was wrong, and we
// need to modify a column that belons to it
Delete.Index(indexNameToDelete).OnTable(ExternalLoginDto.TableName).Do();
}
// special trick to add the column without constraints and return the sql to add them later
AddColumn<ExternalLoginDto>("userOrMemberKey", out IEnumerable<string> sqls);
// populate the new columns with the userId as a Guid. Same method as IntExtensions.ToGuid.
Execute.Sql(
$"UPDATE {ExternalLoginDto.TableName} SET userOrMemberKey = CAST(CONVERT(char(8), CONVERT(BINARY(4), userId), 2) + '-0000-0000-0000-000000000000' AS UNIQUEIDENTIFIER)")
.Do();
// now apply constraints (NOT NULL) to new table
foreach (var sql in sqls)
{
Execute.Sql(sql).Do();
}
// now remove these old columns
Delete.Column("userId").FromTable(ExternalLoginDto.TableName).Do();
// create index with the correct definition
Create
.Index(indexNameToRecreate)
.OnTable(ExternalLoginDto.TableName)
.OnColumn("loginProvider").Ascending()
.OnColumn("userOrMemberKey").Ascending()
.WithOptions()
.Unique()
.WithOptions()
.NonClustered()
.Do();
}
}
}

View File

@@ -1,10 +1,7 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
@@ -14,8 +11,7 @@ using Umbraco.Cms.Core.Logging.Viewer;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Persistence.Querying;
using Umbraco.Cms.Core.Persistence.Repositories;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0;
using Umbraco.Cms.Infrastructure.Migrations.Install;
using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement;
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
using File = System.IO.File;
@@ -235,8 +231,7 @@ public class LogviewerTests
internal class TestLogViewerQueryRepository : ILogViewerQueryRepository
{
public TestLogViewerQueryRepository() =>
Store = new List<ILogViewerQuery>(MigrateLogViewerQueriesFromFileToDb._defaultLogQueries
.Select(LogViewerQueryModelFactory.BuildEntity));
Store = new List<ILogViewerQuery>(DatabaseDataCreator._defaultLogQueries.Select(LogViewerQueryModelFactory.BuildEntity));
private IList<ILogViewerQuery> Store { get; }

View File

@@ -1,54 +0,0 @@
using System.Linq;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Infrastructure.Migrations;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_17_0;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Cms.Tests.Common.TestHelpers;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Migrations.Upgrade.V_8_17_0;
[TestFixture]
public class AddPropertyTypeGroupColumnsTests
{
private readonly IShortStringHelper _shortStringHelper =
new DefaultShortStringHelper(Options.Create(new RequestHandlerSettings()));
private readonly ILogger<MigrationContext> _contextLogger = Mock.Of<ILogger<MigrationContext>>();
[Test]
public void CreateColumn()
{
var database = new TestDatabase();
var context = new MigrationContext(new MigrationPlan("test"), database, _contextLogger);
var migration = new AddPropertyTypeGroupColumns(context, _shortStringHelper);
var dtos = new[]
{
new PropertyTypeGroupDto { Id = 0, Text = "Content" }, new PropertyTypeGroupDto { Id = 1, Text = "Content" },
new PropertyTypeGroupDto { Id = 2, Text = "Settings" },
new PropertyTypeGroupDto { Id = 3, Text = "Content " }, // The trailing space is intentional
new PropertyTypeGroupDto { Id = 4, Text = "SEO/OpenGraph" },
new PropertyTypeGroupDto { Id = 5, Text = "Site defaults" },
};
var populatedDtos = migration.PopulateAliases(dtos)
.OrderBy(x => x.Id) // The populated DTOs can be returned in a different order
.ToArray();
// All DTOs should be returned and Id and Text should be unaltered
Assert.That(dtos.Select(x => (x.Id, x.Text)), Is.EquivalentTo(populatedDtos.Select(x => (x.Id, x.Text))));
// Check populated aliases
Assert.That(populatedDtos[0].Alias, Is.EqualTo("content"));
Assert.That(populatedDtos[1].Alias, Is.EqualTo("content"));
Assert.That(populatedDtos[2].Alias, Is.EqualTo("settings"));
Assert.That(populatedDtos[3].Alias, Is.EqualTo("content2"));
Assert.That(populatedDtos[4].Alias, Is.EqualTo("sEOOpenGraph"));
Assert.That(populatedDtos[5].Alias, Is.EqualTo("siteDefaults"));
}
}