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
+
+
+