Retrieves item counts before and after the target for sibling endpoints and returns in API response (#19844)

* Added user start node restrictions to sibling endpoints.

* Further integration tests.

* Tidy up.

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Revert previous update.

* Retrieves item counts before and after the target for sibling endpoints and returns in API response.

* Applied previous update correctly.

* Removed blank line.

* Fix build and test asserts following merge.

* Update OpenApi.json.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: mole <nikolajlauridsen@protonmail.ch>
This commit is contained in:
Andy Butland
2025-08-05 11:14:59 +02:00
committed by GitHub
parent 20254f0bbc
commit fcba10aecf
21 changed files with 526 additions and 115 deletions

View File

@@ -152,7 +152,9 @@ internal sealed class EntityRepository : RepositoryBase, IEntityRepositoryExtend
int before,
int after,
IQuery<IUmbracoEntity>? filter,
Ordering ordering)
Ordering ordering,
out long totalBefore,
out long totalAfter)
{
// Ideally we don't want to have to do a second query for the parent ID, but the siblings query is already messy enough
// without us also having to do a nested query for the parent ID too.
@@ -204,15 +206,21 @@ internal sealed class EntityRepository : RepositoryBase, IEntityRepositoryExtend
// Select the UniqueId of nodes which row number is within the specified range of the target node's row number.
const int BeforeAfterParameterIndex = 3;
var beforeAfterParameterIndex = BeforeAfterParameterIndex + beforeAfterParameterIndexOffset;
var beforeArgumentsArray = beforeArguments.ToArray();
var afterArgumentsArray = afterArguments.ToArray();
Sql<ISqlContext>? mainSql = Sql()
.Select("UniqueId")
.From().AppendSubQuery(rowNumberSql, "NumberedNodes")
.Where($"rn >= ({targetRowSql.SQL}) - @{BeforeAfterParameterIndex + beforeAfterParameterIndexOffset}", beforeArguments.ToArray())
.Where($"rn <= ({targetRowSql.SQL}) + @{BeforeAfterParameterIndex + beforeAfterParameterIndexOffset}", afterArguments.ToArray())
.Where($"rn >= ({targetRowSql.SQL}) - @{beforeAfterParameterIndex}", beforeArgumentsArray)
.Where($"rn <= ({targetRowSql.SQL}) + @{beforeAfterParameterIndex}", afterArgumentsArray)
.OrderBy("rn");
List<Guid>? keys = Database.Fetch<Guid>(mainSql);
totalBefore = GetNumberOfSiblingsOutsideSiblingRange(rowNumberSql, targetRowSql, beforeAfterParameterIndex, beforeArgumentsArray, true);
totalAfter = GetNumberOfSiblingsOutsideSiblingRange(rowNumberSql, targetRowSql, beforeAfterParameterIndex, afterArgumentsArray, false);
if (keys is null || keys.Count == 0)
{
return [];
@@ -221,6 +229,20 @@ internal sealed class EntityRepository : RepositoryBase, IEntityRepositoryExtend
return PerformGetAll(objectType, ordering, sql => sql.WhereIn<NodeDto>(x => x.UniqueId, keys));
}
private long GetNumberOfSiblingsOutsideSiblingRange(
Sql<ISqlContext> rowNumberSql,
Sql<ISqlContext> targetRowSql,
int parameterIndex,
object[] arguments,
bool getBefore)
{
Sql<ISqlContext>? sql = Sql()
.SelectCount()
.From().AppendSubQuery(rowNumberSql, "NumberedNodes")
.Where($"rn {(getBefore ? "<" : ">")} ({targetRowSql.SQL}) {(getBefore ? "-" : "+")} @{parameterIndex}", arguments);
return Database.ExecuteScalar<long>(sql);
}
public IEntitySlim? Get(Guid key, Guid objectTypeId)
{