diff --git a/build/nightly-build-trigger.yml b/build/nightly-build-trigger.yml index b14db9abad..f8147da05c 100644 --- a/build/nightly-build-trigger.yml +++ b/build/nightly-build-trigger.yml @@ -1,5 +1,7 @@ name: Nightly_$(TeamProject)_$(Build.DefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r) +trigger: none + schedules: - cron: '0 0 * * *' displayName: Daily midnight build diff --git a/src/Umbraco.Core/Configuration/Models/NuCacheSettings.cs b/src/Umbraco.Core/Configuration/Models/NuCacheSettings.cs index b88dbb5d0d..cdf2557763 100644 --- a/src/Umbraco.Core/Configuration/Models/NuCacheSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/NuCacheSettings.cs @@ -14,6 +14,7 @@ public class NuCacheSettings internal const string StaticNuCacheSerializerType = "MessagePack"; internal const int StaticSqlPageSize = 1000; internal const int StaticKitBatchSize = 1; + internal const bool StaticUsePagedSqlQuery = true; /// /// Gets or sets a value defining the BTree block size. @@ -40,4 +41,7 @@ public class NuCacheSettings public int KitBatchSize { get; set; } = StaticKitBatchSize; public bool UnPublishedContentCompression { get; set; } = false; + + [DefaultValue(StaticUsePagedSqlQuery)] + public bool UsePagedSqlQuery { get; set; } = true; } diff --git a/src/Umbraco.Core/PropertyEditors/DefaultPropertyValueConverterAttribute.cs b/src/Umbraco.Core/PropertyEditors/DefaultPropertyValueConverterAttribute.cs index b74d9903cf..a414d76542 100644 --- a/src/Umbraco.Core/PropertyEditors/DefaultPropertyValueConverterAttribute.cs +++ b/src/Umbraco.Core/PropertyEditors/DefaultPropertyValueConverterAttribute.cs @@ -16,11 +16,10 @@ public class DefaultPropertyValueConverterAttribute : Attribute /// a DefaultPropertyValueConverter can be more specific than another one. /// /// - /// An example where this is useful is that both the RelatedLiksEditorValueConverter and the JsonValueConverter + /// An example where this is useful is that both the MultiUrlPickerValueConverter and the JsonValueConverter /// will be returned as value converters for the Related Links Property editor, however the JsonValueConverter - /// is a very generic converter and the RelatedLiksEditorValueConverter is more specific than it, so the - /// RelatedLiksEditorValueConverter - /// can specify that it 'shadows' the JsonValueConverter. + /// is a very generic converter and the MultiUrlPickerValueConverter is more specific than it, so the + /// MultiUrlPickerValueConverter can specify that it 'shadows' the JsonValueConverter. /// public Type[] DefaultConvertersToShadow { get; } } diff --git a/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs b/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs index 75208b2b16..af8c46821f 100644 --- a/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs +++ b/src/Umbraco.PublishedCache.NuCache/Persistence/NuCacheContentRepository.cs @@ -221,19 +221,12 @@ AND cmsContentNu.nodeId IS NULL .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Document)) .Append(SqlOrderByLevelIdSortOrder(SqlContext)); - // Use a more efficient COUNT query - Sql? sqlCountQuery = SqlContentSourcesCount() - .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Document)); - - Sql? sqlCount = - SqlContext.Sql("SELECT COUNT(*) FROM (").Append(sqlCountQuery).Append(") npoco_tbl"); - IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Document); - // We need to page here. We don't want to iterate over every single row in one connection cuz this can cause an SQL Timeout. - // We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that. - foreach (ContentSourceDto row in Database.QueryPaged(_nucacheSettings.Value.SqlPageSize, sql, sqlCount)) + IEnumerable dtos = GetContentNodeDtos(sql); + + foreach (ContentSourceDto row in dtos) { yield return CreateContentNodeKit(row, serializer); } @@ -246,19 +239,12 @@ AND cmsContentNu.nodeId IS NULL .Append(SqlWhereNodeIdX(SqlContext, id)) .Append(SqlOrderByLevelIdSortOrder(SqlContext)); - // Use a more efficient COUNT query - Sql? sqlCountQuery = SqlContentSourcesCount(SqlContentSourcesSelectUmbracoNodeJoin) - .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Document)) - .Append(SqlWhereNodeIdX(SqlContext, id)); - Sql? sqlCount = - SqlContext.Sql("SELECT COUNT(*) FROM (").Append(sqlCountQuery).Append(") npoco_tbl"); - IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Document); - // We need to page here. We don't want to iterate over every single row in one connection cuz this can cause an SQL Timeout. - // We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that. - foreach (ContentSourceDto row in Database.QueryPaged(_nucacheSettings.Value.SqlPageSize, sql, sqlCount)) + IEnumerable dtos = GetContentNodeDtos(sql); + + foreach (ContentSourceDto row in dtos) { yield return CreateContentNodeKit(row, serializer); } @@ -276,19 +262,12 @@ AND cmsContentNu.nodeId IS NULL .WhereIn(x => x.ContentTypeId, ids) .Append(SqlOrderByLevelIdSortOrder(SqlContext)); - // Use a more efficient COUNT query - Sql sqlCountQuery = SqlContentSourcesCount() - .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Document)) - .WhereIn(x => x.ContentTypeId, ids); - Sql? sqlCount = - SqlContext.Sql("SELECT COUNT(*) FROM (").Append(sqlCountQuery).Append(") npoco_tbl"); - IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Document); - // We need to page here. We don't want to iterate over every single row in one connection cuz this can cause an SQL Timeout. - // We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that. - foreach (ContentSourceDto row in Database.QueryPaged(_nucacheSettings.Value.SqlPageSize, sql, sqlCount)) + IEnumerable dtos = GetContentNodeDtos(sql); + + foreach (ContentSourceDto row in dtos) { yield return CreateContentNodeKit(row, serializer); } @@ -319,18 +298,12 @@ AND cmsContentNu.nodeId IS NULL .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Media)) .Append(SqlOrderByLevelIdSortOrder(SqlContext)); - // Use a more efficient COUNT query - Sql? sqlCountQuery = SqlMediaSourcesCount() - .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Media)); - Sql? sqlCount = - SqlContext.Sql("SELECT COUNT(*) FROM (").Append(sqlCountQuery).Append(") npoco_tbl"); - IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Media); - // We need to page here. We don't want to iterate over every single row in one connection cuz this can cause an SQL Timeout. - // We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that. - foreach (ContentSourceDto row in Database.QueryPaged(_nucacheSettings.Value.SqlPageSize, sql, sqlCount)) + IEnumerable dtos = GetContentNodeDtos(sql); + + foreach (ContentSourceDto row in dtos) { yield return CreateMediaNodeKit(row, serializer); } @@ -343,19 +316,12 @@ AND cmsContentNu.nodeId IS NULL .Append(SqlWhereNodeIdX(SqlContext, id)) .Append(SqlOrderByLevelIdSortOrder(SqlContext)); - // Use a more efficient COUNT query - Sql? sqlCountQuery = SqlMediaSourcesCount(SqlContentSourcesSelectUmbracoNodeJoin) - .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Media)) - .Append(SqlWhereNodeIdX(SqlContext, id)); - Sql? sqlCount = - SqlContext.Sql("SELECT COUNT(*) FROM (").Append(sqlCountQuery).Append(") npoco_tbl"); - IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Media); - // We need to page here. We don't want to iterate over every single row in one connection cuz this can cause an SQL Timeout. - // We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that. - foreach (ContentSourceDto row in Database.QueryPaged(_nucacheSettings.Value.SqlPageSize, sql, sqlCount)) + IEnumerable dtos = GetContentNodeDtos(sql); + + foreach (ContentSourceDto row in dtos) { yield return CreateMediaNodeKit(row, serializer); } @@ -373,19 +339,12 @@ AND cmsContentNu.nodeId IS NULL .WhereIn(x => x.ContentTypeId, ids) .Append(SqlOrderByLevelIdSortOrder(SqlContext)); - // Use a more efficient COUNT query - Sql sqlCountQuery = SqlMediaSourcesCount() - .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Media)) - .WhereIn(x => x.ContentTypeId, ids); - Sql? sqlCount = - SqlContext.Sql("SELECT COUNT(*) FROM (").Append(sqlCountQuery).Append(") npoco_tbl"); - IContentCacheDataSerializer serializer = _contentCacheDataSerializerFactory.Create(ContentCacheDataSerializerEntityType.Media); - // We need to page here. We don't want to iterate over every single row in one connection cuz this can cause an SQL Timeout. - // We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that. - foreach (ContentSourceDto row in Database.QueryPaged(_nucacheSettings.Value.SqlPageSize, sql, sqlCount)) + IEnumerable dtos = GetContentNodeDtos(sql); + + foreach (ContentSourceDto row in dtos) { yield return CreateMediaNodeKit(row, serializer); } @@ -1030,4 +989,29 @@ WHERE cmsContentNu.nodeId IN ( return s; } + + private IEnumerable GetContentNodeDtos(Sql sql) + { + // We need to page here. We don't want to iterate over every single row in one connection cuz this can cause an SQL Timeout. + // We also want to read with a db reader and not load everything into memory, QueryPaged lets us do that. + // QueryPaged is very slow on large sites however, so use fetch if UsePagedSqlQuery is disabled. + IEnumerable dtos; + if (_nucacheSettings.Value.UsePagedSqlQuery) + { + // Use a more efficient COUNT query + Sql? sqlCountQuery = SqlContentSourcesCount() + .Append(SqlObjectTypeNotTrashed(SqlContext, Constants.ObjectTypes.Document)); + + Sql? sqlCount = + SqlContext.Sql("SELECT COUNT(*) FROM (").Append(sqlCountQuery).Append(") npoco_tbl"); + + dtos = Database.QueryPaged(_nucacheSettings.Value.SqlPageSize, sql, sqlCount); + } + else + { + dtos = Database.Fetch(sql); + } + + return dtos; + } } diff --git a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs index d3a47157c0..cce95fd609 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs @@ -1,5 +1,6 @@ using System.Globalization; using System.Security.Claims; +using System.Security.Cryptography; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -429,6 +430,8 @@ public class AuthenticationController : UmbracoApiControllerBase } } + await Task.Delay(RandomNumberGenerator.GetInt32(400, 2500)); + return Ok(); } diff --git a/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeIdentityOptions.cs b/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeIdentityOptions.cs index e3f897018a..211528afab 100644 --- a/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeIdentityOptions.cs +++ b/src/Umbraco.Web.BackOffice/Security/ConfigureBackOfficeIdentityOptions.cs @@ -38,6 +38,8 @@ public sealed class ConfigureBackOfficeIdentityOptions : IConfigureOptions + + +