V10: fix content version cleanup dto migration (#13788)

* Add DoesPrimaryKeyExist method

* Add primary key name to dto

* Add extension method PrimaryKeyExists

* Dont use sql_master table

* Implement DoesPrimaryKeyExists

* Rename without plural s

* Refactor to get proper primary key name and not column name

* Use primary key name and not column name

* Dont filter tables in memory

* Remove .Where

* Don't select all, select only sql

* throw NotImplementedException by default

* USe virtual instead of abstract to avoid breaking change

* Reinstert primary key attribute

---------

Co-authored-by: Zeegaan <nge@umbraco.dk>
This commit is contained in:
Nikolaj Geisle
2023-02-07 13:46:14 +01:00
parent e3135bd97e
commit 3d47cac9ac
7 changed files with 47 additions and 9 deletions

View File

@@ -272,6 +272,13 @@ where tbl.[name]=@0 and col.[name]=@1;",
return !constraintName.IsNullOrWhiteSpace();
}
public override bool DoesPrimaryKeyExist(IDatabase db, string tableName, string primaryKeyName)
{
IEnumerable<SqlPrimaryKey>? keys = db.Fetch<SqlPrimaryKey>($"select * from sysobjects where xtype='pk' and parent_obj in (select id from sysobjects where name='{tableName}')")
.Where(x => x.Name == primaryKeyName);
return keys.FirstOrDefault() is not null;
}
public override bool DoesTableExist(IDatabase db, string tableName)
{
var result =
@@ -453,4 +460,9 @@ _sqlInspector ??= new SqlInspectionUtilities();
}
#endregion
private class SqlPrimaryKey
{
public string Name { get; set; } = null!;
}
}

View File

@@ -174,6 +174,14 @@ public class SqliteSyntaxProvider : SqlSyntaxProviderBase<SqliteSyntaxProvider>
return false;
}
public override bool DoesPrimaryKeyExist(IDatabase db, string tableName, string primaryKeyName)
{
IEnumerable<string> items = db.Fetch<string>($"select sql from sqlite_master where type = 'table' and name = '{tableName}'")
.Where(x => x.Contains($"CONSTRAINT {primaryKeyName} PRIMARY KEY"));
return items.Any();
}
public override string GetFieldNameForUpdate<TDto>(Expression<Func<TDto, object?>> fieldSelector, string? tableAlias = null)
{
var field = ExpressionHelper.FindProperty(fieldSelector).Item1 as PropertyInfo;

View File

@@ -110,6 +110,11 @@ namespace Umbraco.Cms.Infrastructure.Migrations
return indexes.Any(x => x.Item2.InvariantEquals(indexName));
}
protected bool PrimaryKeyExists(string tableName, string primaryKeyName)
{
return SqlSyntax.DoesPrimaryKeyExist(Context.Database, tableName, primaryKeyName);
}
protected bool ColumnExists(string tableName, string columnName)
{
ColumnInfo[]? columns = SqlSyntax.GetColumnsInSchema(Context.Database).Distinct().ToArray();

View File

@@ -10,18 +10,28 @@ public class AddPrimaryKeyConstrainToContentVersionCleanupDtos : MigrationBase
protected override void Migrate()
{
IEnumerable<ContentVersionCleanupPolicyDto> contentVersionCleanupPolicyDtos =
Database
.Fetch<ContentVersionCleanupPolicyDto>()
.OrderByDescending(x => x.Updated)
.DistinctBy(x => x.ContentTypeId);
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();
Database.InsertBatch(contentVersionCleanupPolicyDtos);
if (contentVersionCleanupPolicyDtos is not null)
{
Database.InsertBatch(contentVersionCleanupPolicyDtos);
}
}
}

View File

@@ -1,4 +1,3 @@
using System.Data;
using NPoco;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations;
@@ -13,7 +12,7 @@ internal class ContentVersionCleanupPolicyDto
public const string TableName = Constants.DatabaseSchema.Tables.ContentVersionCleanupPolicy;
[Column("contentTypeId")]
[PrimaryKeyColumn(AutoIncrement = false)]
[PrimaryKeyColumn(AutoIncrement = false, Name = "PK_umbracoContentVersionCleanupPolicy")]
[ForeignKey(typeof(ContentTypeDto), Column = "nodeId")]
public int ContentTypeId { get; set; }

View File

@@ -188,6 +188,8 @@ public interface ISqlSyntaxProvider
/// </remarks>
bool TryGetDefaultConstraint(IDatabase db, string? tableName, string columnName, [MaybeNullWhen(false)] out string constraintName);
bool DoesPrimaryKeyExist(IDatabase db, string tableName, string primaryKeyName) => throw new NotImplementedException();
string GetFieldNameForUpdate<TDto>(Expression<Func<TDto, object?>> fieldSelector, string? tableAlias = null);
/// <summary>

View File

@@ -209,6 +209,8 @@ public abstract class SqlSyntaxProviderBase<TSyntax> : ISqlSyntaxProvider
public abstract bool TryGetDefaultConstraint(IDatabase db, string? tableName, string columnName, [MaybeNullWhen(false)] out string constraintName);
public virtual bool DoesPrimaryKeyExist(IDatabase db, string tableName, string primaryKeyName) => throw new NotImplementedException();
public virtual string GetFieldNameForUpdate<TDto>(
Expression<Func<TDto, object?>> fieldSelector,
string? tableAlias = null) => this.GetFieldName(fieldSelector, tableAlias);