From e3cd19fed5956411bf3901be325d1b965b638d45 Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 12 Dec 2018 13:27:08 +0100 Subject: [PATCH] Fix tags (in)variant --- .../Implement/ContentTypeRepositoryBase.cs | 86 +++++++++++-------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs index a7f8adf482..06fc25937b 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs @@ -772,26 +772,26 @@ AND umbracoNode.id <> @id", // delete existing relations (for target language) // do *not* delete existing tags - var sqlTagToDelete = Sql() + var sqlSelectTagsToDelete = Sql() .Select(x => x.Id) .From() .InnerJoin().On((tag, rel) => tag.Id == rel.TagId); if (contentTypeIds != null) - sqlTagToDelete + sqlSelectTagsToDelete .InnerJoin().On((rel, content) => rel.NodeId == content.NodeId) .WhereIn(x => x.ContentTypeId, contentTypeIds); - sqlTagToDelete + sqlSelectTagsToDelete .WhereIn(x => x.PropertyTypeId, propertyTypeIds) .Where(x => x.LanguageId.SqlNullableEquals(targetLanguageId, -1)); - var sqlDeleteRel = Sql() + var sqlDeleteRelations = Sql() .Delete() - .WhereIn(x => x.TagId, sqlTagToDelete); + .WhereIn(x => x.TagId, sqlSelectTagsToDelete); - sqlDeleteRel.WriteToConsole(); - Database.Execute(sqlDeleteRel); + sqlDeleteRelations.WriteToConsole(); + Database.Execute(sqlDeleteRelations); // do *not* delete the tags - they could be used by other content types / property types /* @@ -802,76 +802,90 @@ AND umbracoNode.id <> @id", */ // copy tags from source language to target language + // target tags may exist already, so we have to check for existence here + // + // select tags to insert: tags pointed to by a relation ship, for proper property/content types, + // and of source language, and where we cannot left join to an existing tag with same text, + // group and languageId var targetLanguageIdS = targetLanguageId.HasValue ? targetLanguageId.ToString() : "NULL"; - var sqlSelect = Sql() + var sqlSelectTagsToInsert = Sql() .Select(x => x.Text, x => x.Group) .Append(", " + targetLanguageIdS) .From(); - sqlSelect + sqlSelectTagsToInsert .InnerJoin().On((tag, rel) => tag.Id == rel.TagId) .LeftJoin("xtags").On((tag, xtag) => tag.Text == xtag.Text && tag.Group == xtag.Group && xtag.LanguageId.SqlNullableEquals(targetLanguageId, -1), aliasRight: "xtags"); if (contentTypeIds != null) - sqlSelect - .InnerJoin().On((rel, content) => rel.NodeId == content.NodeId); - - sqlSelect - .WhereIn(x => x.PropertyTypeId, propertyTypeIds) - .WhereNull(x => x.Id, "xtags"); // ie, not exists - - if (contentTypeIds != null) - sqlSelect + sqlSelectTagsToInsert + .InnerJoin().On((rel, content) => rel.NodeId == content.NodeId) .WhereIn(x => x.ContentTypeId, contentTypeIds); - sqlSelect.Where(x => x.LanguageId.SqlNullableEquals(sourceLanguageId, -1)); + sqlSelectTagsToInsert + .WhereIn(x => x.PropertyTypeId, propertyTypeIds) + .WhereNull(x => x.Id, "xtags") // ie, not exists + .Where(x => x.LanguageId.SqlNullableEquals(sourceLanguageId, -1)); var cols = Sql().Columns(x => x.Text, x => x.Group, x => x.LanguageId); - var sqlInsertTag = Sql($"INSERT INTO {TagDto.TableName} ({cols})").Append(sqlSelect); + var sqlInsertTags = Sql($"INSERT INTO {TagDto.TableName} ({cols})").Append(sqlSelectTagsToInsert); - sqlInsertTag.WriteToConsole(); - Database.Execute(sqlInsertTag); + sqlInsertTags.WriteToConsole(); + Database.Execute(sqlInsertTags); // create relations to new tags + // any existing relations have been deleted above, no need to check for existence here + // + // select node id and property type id from existing relations to tags of source language, + // for proper property/content types, and select new tag id from tags, with matching text, + // and group, but for the target language - var sqlFoo = Sql() + var sqlSelectRelationsToInsert = Sql() .Select(x => x.NodeId, x => x.PropertyTypeId) .AndSelect("otag", x => x.Id) .From() .InnerJoin().On((rel, tag) => rel.TagId == tag.Id) - .InnerJoin("otag").On((tag, otag) => tag.Text == otag.Text && tag.Group == otag.Group && otag.LanguageId.SqlNullableEquals(targetLanguageId, -1), aliasRight: "otag") - .Where(x => x.LanguageId.SqlNullableEquals(sourceLanguageId, -1)); + .InnerJoin("otag").On((tag, otag) => tag.Text == otag.Text && tag.Group == otag.Group && otag.LanguageId.SqlNullableEquals(targetLanguageId, -1), aliasRight: "otag"); - var cols2 = Sql().Columns(x => x.NodeId, x => x.PropertyTypeId, x => x.TagId); - var sqlInsertRel = Sql($"INSERT INTO {TagRelationshipDto.TableName} ({cols2})").Append(sqlFoo); + if (contentTypeIds != null) + sqlSelectRelationsToInsert + .InnerJoin().On((rel, content) => rel.NodeId == content.NodeId) + .WhereIn(x => x.ContentTypeId, contentTypeIds); - sqlInsertRel.WriteToConsole(); - Database.Execute(sqlInsertRel); + sqlSelectRelationsToInsert + .Where(x => x.LanguageId.SqlNullableEquals(sourceLanguageId, -1)) + .WhereIn(x => x.PropertyTypeId, propertyTypeIds); + + var relationColumnsToInsert = Sql().Columns(x => x.NodeId, x => x.PropertyTypeId, x => x.TagId); + var sqlInsertRelations = Sql($"INSERT INTO {TagRelationshipDto.TableName} ({relationColumnsToInsert})").Append(sqlSelectRelationsToInsert); + + sqlInsertRelations.WriteToConsole(); + Database.Execute(sqlInsertRelations); // delete original relations - *not* the tags - all of them // cannot really "go back" with relations, would have to do it with property values - sqlTagToDelete = Sql() + sqlSelectTagsToDelete = Sql() .Select(x => x.Id) .From() .InnerJoin().On((tag, rel) => tag.Id == rel.TagId); if (contentTypeIds != null) - sqlTagToDelete + sqlSelectTagsToDelete .InnerJoin().On((rel, content) => rel.NodeId == content.NodeId) .WhereIn(x => x.ContentTypeId, contentTypeIds); - sqlTagToDelete + sqlSelectTagsToDelete .WhereIn(x => x.PropertyTypeId, propertyTypeIds) .Where(x => !x.LanguageId.SqlNullableEquals(targetLanguageId, -1)); - sqlDeleteRel = Sql() + sqlDeleteRelations = Sql() .Delete() - .WhereIn(x => x.TagId, sqlTagToDelete); + .WhereIn(x => x.TagId, sqlSelectTagsToDelete); - sqlDeleteRel.WriteToConsole(); - Database.Execute(sqlDeleteRel); + sqlDeleteRelations.WriteToConsole(); + Database.Execute(sqlDeleteRelations); // no /*