Merge remote-tracking branch 'origin/v8/dev' into v9/feature/merge-v8_29-10-2021
# Conflicts: # src/Umbraco.Core/Persistence/NPocoDatabaseExtensions-Bulk.cs # src/Umbraco.Web.UI.Client/package.json # src/Umbraco.Web.UI.Client/src/views/common/overlays/user/user.html # src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.html # src/Umbraco.Web.UI.Client/src/views/documenttypes/importdocumenttype.html # src/Umbraco.Web.UI/umbraco/config/lang/en.xml # src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml # src/Umbraco.Web.UI/umbraco/config/lang/nl.xml
This commit is contained in:
@@ -53,7 +53,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
|
||||
var entries = new List<IAuditEntry>();
|
||||
|
||||
foreach (var group in ids.InGroupsOf(2000))
|
||||
foreach (var group in ids.InGroupsOf(Constants.Sql.MaxParameterCount))
|
||||
{
|
||||
var sql = Sql()
|
||||
.Select<AuditEntryDto>()
|
||||
|
||||
@@ -657,7 +657,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
// in the table?
|
||||
|
||||
// get all PropertyDataDto for all definitions / versions
|
||||
var allPropertyDataDtos = Database.FetchByGroups<PropertyDataDto, int>(versions, 2000, batch =>
|
||||
var allPropertyDataDtos = Database.FetchByGroups<PropertyDataDto, int>(versions, Constants.Sql.MaxParameterCount, batch =>
|
||||
SqlContext.Sql()
|
||||
.Select<PropertyDataDto>()
|
||||
.From<PropertyDataDto>()
|
||||
@@ -666,7 +666,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
|
||||
// get PropertyDataDto distinct PropertyTypeDto
|
||||
var allPropertyTypeIds = allPropertyDataDtos.Select(x => x.PropertyTypeId).Distinct().ToList();
|
||||
var allPropertyTypeDtos = Database.FetchByGroups<PropertyTypeDto, int>(allPropertyTypeIds, 2000, batch =>
|
||||
var allPropertyTypeDtos = Database.FetchByGroups<PropertyTypeDto, int>(allPropertyTypeIds, Constants.Sql.MaxParameterCount, batch =>
|
||||
SqlContext.Sql()
|
||||
.Select<PropertyTypeDto>(r => r.Select(x => x.DataTypeDto))
|
||||
.From<PropertyTypeDto>()
|
||||
|
||||
@@ -795,7 +795,7 @@ AND umbracoNode.id <> @id",
|
||||
// note: important to use SqlNullableEquals for nullable types, cannot directly compare language identifiers
|
||||
|
||||
var whereInArgsCount = propertyTypeIds.Count + (contentTypeIds?.Count ?? 0);
|
||||
if (whereInArgsCount > 2000)
|
||||
if (whereInArgsCount > Constants.Sql.MaxParameterCount)
|
||||
throw new NotSupportedException("Too many property/content types.");
|
||||
|
||||
// delete existing relations (for target language)
|
||||
@@ -933,7 +933,7 @@ AND umbracoNode.id <> @id",
|
||||
// note: important to use SqlNullableEquals for nullable types, cannot directly compare language identifiers
|
||||
//
|
||||
var whereInArgsCount = propertyTypeIds.Count + (contentTypeIds?.Count ?? 0);
|
||||
if (whereInArgsCount > 2000)
|
||||
if (whereInArgsCount > Constants.Sql.MaxParameterCount)
|
||||
throw new NotSupportedException("Too many property/content types.");
|
||||
|
||||
//first clear out any existing property data that might already exists under the target language
|
||||
@@ -1032,7 +1032,7 @@ AND umbracoNode.id <> @id",
|
||||
//based on the current variance of each item to see if it's 'edited' value should be true/false.
|
||||
|
||||
var whereInArgsCount = propertyTypeIds.Count + (contentTypeIds?.Count ?? 0);
|
||||
if (whereInArgsCount > 2000)
|
||||
if (whereInArgsCount > Constants.Sql.MaxParameterCount)
|
||||
throw new NotSupportedException("Too many property/content types.");
|
||||
|
||||
var propertySql = Sql()
|
||||
@@ -1121,14 +1121,20 @@ AND umbracoNode.id <> @id",
|
||||
}
|
||||
}
|
||||
|
||||
//lookup all matching rows in umbracoDocumentCultureVariation
|
||||
var docCultureVariationsToUpdate = editedLanguageVersions.InGroupsOf(2000)
|
||||
.SelectMany(_ => Database.Fetch<DocumentCultureVariationDto>(
|
||||
Sql().Select<DocumentCultureVariationDto>().From<DocumentCultureVariationDto>()
|
||||
.WhereIn<DocumentCultureVariationDto>(x => x.LanguageId, editedLanguageVersions.Keys.Select(x => x.langId).ToList())
|
||||
.WhereIn<DocumentCultureVariationDto>(x => x.NodeId, editedLanguageVersions.Keys.Select(x => x.nodeId))))
|
||||
//convert to dictionary with the same key type
|
||||
.ToDictionary(x => (x.NodeId, (int?)x.LanguageId), x => x);
|
||||
// lookup all matching rows in umbracoDocumentCultureVariation
|
||||
// fetch in batches to account for maximum parameter count (distinct languages can't exceed 2000)
|
||||
var languageIds = editedLanguageVersions.Keys.Select(x => x.langId).Distinct().ToArray();
|
||||
var nodeIds = editedLanguageVersions.Keys.Select(x => x.nodeId).Distinct();
|
||||
var docCultureVariationsToUpdate = nodeIds.InGroupsOf(Constants.Sql.MaxParameterCount - languageIds.Length)
|
||||
.SelectMany(group =>
|
||||
{
|
||||
var sql = Sql().Select<DocumentCultureVariationDto>().From<DocumentCultureVariationDto>()
|
||||
.WhereIn<DocumentCultureVariationDto>(x => x.LanguageId, languageIds)
|
||||
.WhereIn<DocumentCultureVariationDto>(x => x.NodeId, group);
|
||||
|
||||
return Database.Fetch<DocumentCultureVariationDto>(sql);
|
||||
})
|
||||
.ToDictionary(x => (x.NodeId, (int?)x.LanguageId), x => x); //convert to dictionary with the same key type
|
||||
|
||||
var toUpdate = new List<DocumentCultureVariationDto>();
|
||||
foreach (var ev in editedLanguageVersions)
|
||||
|
||||
@@ -263,13 +263,12 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
|
||||
Func<Guid[], IEnumerable<IEnumerable<IDictionaryItem>>> getItemsFromParents = guids =>
|
||||
{
|
||||
//needs to be in groups of 2000 because we are doing an IN clause and there's a max parameter count that can be used.
|
||||
return guids.InGroupsOf(2000)
|
||||
.Select(@group =>
|
||||
return guids.InGroupsOf(Constants.Sql.MaxParameterCount)
|
||||
.Select(group =>
|
||||
{
|
||||
var sqlClause = GetBaseQuery(false)
|
||||
.Where<DictionaryDto>(x => x.Parent != null)
|
||||
.Where($"{SqlSyntax.GetQuotedColumnName("parent")} IN (@parentIds)", new { parentIds = @group });
|
||||
.WhereIn<DictionaryDto>(x => x.Parent, group);
|
||||
|
||||
var translator = new SqlTranslator<IDictionaryItem>(sqlClause, Query<IDictionaryItem>());
|
||||
var sql = translator.Translate();
|
||||
|
||||
@@ -1390,7 +1390,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
{
|
||||
var result = new Dictionary<int, ContentScheduleCollection>();
|
||||
|
||||
var scheduleDtos = Database.FetchByGroups<ContentScheduleDto, int>(contentIds, 2000, batch => Sql()
|
||||
var scheduleDtos = Database.FetchByGroups<ContentScheduleDto, int>(contentIds, Constants.Sql.MaxParameterCount, batch => Sql()
|
||||
.Select<ContentScheduleDto>()
|
||||
.From<ContentScheduleDto>()
|
||||
.WhereIn<ContentScheduleDto>(x => x.NodeId, batch));
|
||||
@@ -1440,7 +1440,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
if (versions.Count == 0)
|
||||
return new Dictionary<int, List<ContentVariation>>();
|
||||
|
||||
var dtos = Database.FetchByGroups<ContentVersionCultureVariationDto, int>(versions, 2000, batch
|
||||
var dtos = Database.FetchByGroups<ContentVersionCultureVariationDto, int>(versions, Constants.Sql.MaxParameterCount, batch
|
||||
=> Sql()
|
||||
.Select<ContentVersionCultureVariationDto>()
|
||||
.From<ContentVersionCultureVariationDto>()
|
||||
@@ -1469,7 +1469,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
{
|
||||
var ids = temps.Select(x => x.Id);
|
||||
|
||||
var dtos = Database.FetchByGroups<DocumentCultureVariationDto, int>(ids, 2000, batch =>
|
||||
var dtos = Database.FetchByGroups<DocumentCultureVariationDto, int>(ids, Constants.Sql.MaxParameterCount, batch =>
|
||||
Sql()
|
||||
.Select<DocumentCultureVariationDto>()
|
||||
.From<DocumentCultureVariationDto>()
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
{
|
||||
if (ids.Any())
|
||||
{
|
||||
return Database.FetchByGroups<NodeDto, int>(ids, 2000, batch =>
|
||||
return Database.FetchByGroups<NodeDto, int>(ids, Constants.Sql.MaxParameterCount, batch =>
|
||||
GetBaseQuery(false)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId)
|
||||
.WhereIn<NodeDto>(x => x.NodeId, batch))
|
||||
|
||||
@@ -279,7 +279,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
if (v == null) return entitiesList;
|
||||
|
||||
// fetch all variant info dtos
|
||||
var dtos = Database.FetchByGroups<VariantInfoDto, int>(v.Select(x => x.Id), 2000, GetVariantInfos);
|
||||
var dtos = Database.FetchByGroups<VariantInfoDto, int>(v.Select(x => x.Id), Constants.Sql.MaxParameterCount, GetVariantInfos);
|
||||
|
||||
// group by node id (each group contains all languages)
|
||||
var xdtos = dtos.GroupBy(x => x.NodeId).ToDictionary(x => x.Key, x => x);
|
||||
|
||||
@@ -209,16 +209,15 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
|
||||
// can't query more than 2000 ids at a time... but if someone is really querying 2000+ entities,
|
||||
// the additional overhead of fetching them in groups is minimal compared to the lookup time of each group
|
||||
const int maxParams = 2000;
|
||||
if (ids.Length <= maxParams)
|
||||
if (ids.Length <= Constants.Sql.MaxParameterCount)
|
||||
{
|
||||
return CachePolicy.GetAll(ids, PerformGetAll);
|
||||
}
|
||||
|
||||
var entities = new List<TEntity>();
|
||||
foreach (var groupOfIds in ids.InGroupsOf(maxParams))
|
||||
foreach (var group in ids.InGroupsOf(Constants.Sql.MaxParameterCount))
|
||||
{
|
||||
entities.AddRange(CachePolicy.GetAll(groupOfIds.ToArray(), PerformGetAll));
|
||||
entities.AddRange(CachePolicy.GetAll(group.ToArray(), PerformGetAll));
|
||||
}
|
||||
|
||||
return entities;
|
||||
|
||||
@@ -530,16 +530,13 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
var matchedMembers = Get(query).ToArray();
|
||||
|
||||
var membersInGroup = new List<IMember>();
|
||||
//then we need to filter the matched members that are in the role
|
||||
//since the max sql params are 2100 on sql server, we'll reduce that to be safe for potentially other servers and run the queries in batches
|
||||
var inGroups = matchedMembers.InGroupsOf(1000);
|
||||
foreach (var batch in inGroups)
|
||||
{
|
||||
var memberIdBatch = batch.Select(x => x.Id);
|
||||
|
||||
//then we need to filter the matched members that are in the role
|
||||
foreach (var group in matchedMembers.Select(x => x.Id).InGroupsOf(Constants.Sql.MaxParameterCount))
|
||||
{
|
||||
var sql = Sql().SelectAll().From<Member2MemberGroupDto>()
|
||||
.Where<Member2MemberGroupDto>(dto => dto.MemberGroup == memberGroup.Id)
|
||||
.WhereIn<Member2MemberGroupDto>(dto => dto.Member, memberIdBatch);
|
||||
.WhereIn<Member2MemberGroupDto>(dto => dto.Member, group);
|
||||
|
||||
var memberIdsInGroup = Database.Fetch<Member2MemberGroupDto>(sql)
|
||||
.Select(x => x.Member).ToArray();
|
||||
|
||||
@@ -38,44 +38,41 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
/// <param name="entityIds"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This method will not support passing in more than 2000 group Ids
|
||||
/// This method will not support passing in more than 2000 group IDs when also passing in entity IDs.
|
||||
/// </remarks>
|
||||
public EntityPermissionCollection GetPermissionsForEntities(int[] groupIds, params int[] entityIds)
|
||||
{
|
||||
var result = new EntityPermissionCollection();
|
||||
|
||||
foreach (var groupOfGroupIds in groupIds.InGroupsOf(2000))
|
||||
if (entityIds.Length == 0)
|
||||
{
|
||||
//copy local
|
||||
var localIds = groupOfGroupIds.ToArray();
|
||||
|
||||
if (entityIds.Length == 0)
|
||||
foreach (var group in groupIds.InGroupsOf(Constants.Sql.MaxParameterCount))
|
||||
{
|
||||
var sql = Sql()
|
||||
.SelectAll()
|
||||
.From<UserGroup2NodePermissionDto>()
|
||||
.Where<UserGroup2NodePermissionDto>(dto => localIds.Contains(dto.UserGroupId));
|
||||
.Where<UserGroup2NodePermissionDto>(dto => group.Contains(dto.UserGroupId));
|
||||
|
||||
var permissions = AmbientScope.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
foreach (var permission in ConvertToPermissionList(permissions))
|
||||
{
|
||||
result.Add(permission);
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var group in entityIds.InGroupsOf(Constants.Sql.MaxParameterCount - groupIds.Length))
|
||||
{
|
||||
//iterate in groups of 2000 since we don't want to exceed the max SQL param count
|
||||
foreach (var groupOfEntityIds in entityIds.InGroupsOf(2000))
|
||||
var sql = Sql()
|
||||
.SelectAll()
|
||||
.From<UserGroup2NodePermissionDto>()
|
||||
.Where<UserGroup2NodePermissionDto>(dto => groupIds.Contains(dto.UserGroupId) && group.Contains(dto.NodeId));
|
||||
|
||||
var permissions = AmbientScope.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
foreach (var permission in ConvertToPermissionList(permissions))
|
||||
{
|
||||
var ids = groupOfEntityIds;
|
||||
var sql = Sql()
|
||||
.SelectAll()
|
||||
.From<UserGroup2NodePermissionDto>()
|
||||
.Where<UserGroup2NodePermissionDto>(dto => localIds.Contains(dto.UserGroupId) && ids.Contains(dto.NodeId));
|
||||
var permissions = AmbientScope.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
foreach (var permission in ConvertToPermissionList(permissions))
|
||||
{
|
||||
result.Add(permission);
|
||||
}
|
||||
result.Add(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,11 +130,10 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
|
||||
var db = AmbientScope.Database;
|
||||
|
||||
//we need to batch these in groups of 2000 so we don't exceed the max 2100 limit
|
||||
var sql = "DELETE FROM umbracoUserGroup2NodePermission WHERE userGroupId = @groupId AND nodeId in (@nodeIds)";
|
||||
foreach (var idGroup in entityIds.InGroupsOf(2000))
|
||||
foreach (var group in entityIds.InGroupsOf(Constants.Sql.MaxParameterCount))
|
||||
{
|
||||
db.Execute(sql, new { groupId, nodeIds = idGroup });
|
||||
db.Execute(sql, new { groupId, nodeIds = group });
|
||||
}
|
||||
|
||||
var toInsert = new List<UserGroup2NodePermissionDto>();
|
||||
|
||||
@@ -39,8 +39,9 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
|
||||
protected override IEnumerable<IRedirectUrl> PerformGetAll(params Guid[] ids)
|
||||
{
|
||||
if (ids.Length > 2000)
|
||||
throw new NotSupportedException("This repository does not support more than 2000 ids.");
|
||||
if (ids.Length > Constants.Sql.MaxParameterCount)
|
||||
throw new NotSupportedException($"This repository does not support more than {Constants.Sql.MaxParameterCount} ids.");
|
||||
|
||||
var sql = GetBaseQuery(false).WhereIn<RedirectUrlDto>(x => x.Id, ids);
|
||||
var dtos = Database.Fetch<RedirectUrlDto>(sql);
|
||||
return dtos.WhereNotNull().Select(Map);
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
{
|
||||
var dtos = ids.Length == 0
|
||||
? Database.Fetch<TagDto>(Sql().Select<TagDto>().From<TagDto>())
|
||||
: Database.FetchByGroups<TagDto, int>(ids, 2000, batch => Sql().Select<TagDto>().From<TagDto>().WhereIn<TagDto>(x => x.Id, batch));
|
||||
: Database.FetchByGroups<TagDto, int>(ids, Constants.Sql.MaxParameterCount, batch => Sql().Select<TagDto>().From<TagDto>().WhereIn<TagDto>(x => x.Id, batch));
|
||||
|
||||
return dtos.Select(TagFactory.BuildEntity).ToList();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user