Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -32145,7 +32145,7 @@ parameters:
-
message: '#^Cannot access property \$id on Ibexa\\Contracts\\Core\\Repository\\Values\\Content\\Location\|null\.$#'
identifier: property.nonObject
count: 11
count: 9
path: tests/integration/Core/Repository/LocationServiceTest.php

-
Expand Down Expand Up @@ -32352,12 +32352,6 @@ parameters:
count: 1
path: tests/integration/Core/Repository/LocationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\LocationServiceTest\:\:testGetSubtreeSize\(\) should return Ibexa\\Contracts\\Core\\Repository\\Values\\Content\\Location but returns Ibexa\\Contracts\\Core\\Repository\\Values\\Content\\Location\|null\.$#'
identifier: return.type
count: 1
path: tests/integration/Core/Repository/LocationServiceTest.php

-
message: '#^Method Ibexa\\Tests\\Integration\\Core\\Repository\\LocationServiceTest\:\:testHideLocation\(\) has no return type specified\.$#'
identifier: missingType.return
Expand Down Expand Up @@ -32610,12 +32604,6 @@ parameters:
count: 1
path: tests/integration/Core/Repository/LocationServiceTest.php

-
message: '#^Parameter \#1 \$location of method Ibexa\\Contracts\\Core\\Repository\\LocationService\:\:getSubtreeSize\(\) expects Ibexa\\Contracts\\Core\\Repository\\Values\\Content\\Location, Ibexa\\Contracts\\Core\\Repository\\Values\\Content\\Location\|null given\.$#'
identifier: argument.type
count: 2
path: tests/integration/Core/Repository/LocationServiceTest.php

-
message: '#^Parameter \#1 \$location of method Ibexa\\Contracts\\Core\\Repository\\LocationService\:\:moveSubtree\(\) expects Ibexa\\Contracts\\Core\\Repository\\Values\\Content\\Location, Ibexa\\Contracts\\Core\\Repository\\Values\\Content\\Location\|null given\.$#'
identifier: argument.type
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/Persistence/Content/Location/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public function loadParentLocationsForDraftContent($contentId);
*/
public function copySubtree($sourceId, $destinationParentId);

public function getSubtreeSize(string $path): int;
public function getSubtreeSize(string $path, ?int $limit = null): int;

/**
* Moves location identified by $sourceId into new parent identified by $destinationParentId.
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/Persistence/Filter/Content/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ interface Handler
*/
public function find(Filter $filter): iterable;

public function count(Filter $filter): int;
public function count(Filter $filter, ?int $limit = null): int;
}
2 changes: 1 addition & 1 deletion src/contracts/Persistence/Filter/Location/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ interface Handler
*/
public function find(Filter $filter): iterable;

public function count(Filter $filter): int;
public function count(Filter $filter, ?int $limit = null): int;
}
16 changes: 16 additions & 0 deletions src/contracts/Persistence/Filter/Query/CountQueryBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Contracts\Core\Persistence\Filter\Query;

use Doctrine\DBAL\Query\QueryBuilder;

interface CountQueryBuilder
{
public function wrap(QueryBuilder $queryBuilder, string $countableField, ?int $limit = null): QueryBuilder;
}
5 changes: 4 additions & 1 deletion src/contracts/Repository/ContentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,10 @@ public function find(Filter $filter, ?array $languages = null): ContentList;
* If skipped, by default, unless SiteAccessAware layer has been disabled, languages set
* for a SiteAccess in a current context will be used.
*
* @param int|null $limit If set, the count will be limited to first $limit items found.
* In some cases it can significantly speed up a count operation for more complex filters.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* In some cases it can significantly speed up a count operation for more complex filters.
* In some cases it can significantly speed up a count operation for more complex filters.

*
* @phpstan-return int<0, max>
*/
public function count(Filter $filter, ?array $languages = null): int;
public function count(Filter $filter, ?array $languages = null, ?int $limit = null): int;
}
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ public function find(Filter $filter, ?array $languages = null): ContentList
return $this->innerService->find($filter, $languages);
}

public function count(Filter $filter, ?array $languages = null): int
public function count(Filter $filter, ?array $languages = null, ?int $limit = null): int
{
return $this->innerService->count($filter, $languages);
return $this->innerService->count($filter, $languages, $limit);
}
}
12 changes: 6 additions & 6 deletions src/contracts/Repository/Decorator/LocationServiceDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ public function loadParentLocationsForDraftContent(
return $this->innerService->loadParentLocationsForDraftContent($versionInfo, $prioritizedLanguages);
}

public function getLocationChildCount(Location $location): int
public function getLocationChildCount(Location $location, ?int $limit = null): int
{
return $this->innerService->getLocationChildCount($location);
return $this->innerService->getLocationChildCount($location, $limit);
}

public function getSubtreeSize(Location $location): int
public function getSubtreeSize(Location $location, ?int $limit = null): int
{
return $this->innerService->getSubtreeSize($location);
return $this->innerService->getSubtreeSize($location, $limit);
}

public function createLocation(
Expand Down Expand Up @@ -159,8 +159,8 @@ public function find(Filter $filter, ?array $languages = null): LocationList
return $this->innerService->find($filter, $languages);
}

public function count(Filter $filter, ?array $languages = null): int
public function count(Filter $filter, ?array $languages = null, ?int $limit = null): int
{
return $this->innerService->count($filter, $languages);
return $this->innerService->count($filter, $languages, $limit);
}
}
11 changes: 8 additions & 3 deletions src/contracts/Repository/LocationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,20 @@ public function loadParentLocationsForDraftContent(VersionInfo $versionInfo, ?ar
* Returns the number of children which are readable by the current user of a location object.
*
* @param \Ibexa\Contracts\Core\Repository\Values\Content\Location $location
* @param int|null $limit If set, the count will be limited to first $limit items found.
*
* @return int
*/
public function getLocationChildCount(Location $location): int;
public function getLocationChildCount(Location $location, ?int $limit = null): int;

/**
* Return the subtree size of a given location.
*
* Warning! This method is not permission aware by design.
*
* @param int|null $limit
*/
public function getSubtreeSize(Location $location): int;
public function getSubtreeSize(Location $location, ?int $limit = null): int;

/**
* Creates the new $location in the content repository for the given content.
Expand Down Expand Up @@ -280,6 +283,8 @@ public function find(Filter $filter, ?array $languages = null): LocationList;
* @param array<int, string>|null $languages a list of language codes to be added as additional constraints.
* If skipped, by default, unless SiteAccessAware layer has been disabled, languages set
* for a SiteAccess in a current context will be used.
* @param int|null $limit If set, the count will be limited to first $limit items found.
* In some cases it can significantly speed up a count operation for more complex filters.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* In some cases it can significantly speed up a count operation for more complex filters.
* In some cases it can significantly speed up a count operation for more complex filters.

*/
public function count(Filter $filter, ?array $languages = null): int;
public function count(Filter $filter, ?array $languages = null, ?int $limit = null): int;
}
5 changes: 3 additions & 2 deletions src/lib/Persistence/Cache/LocationHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,14 @@ public function copySubtree($sourceId, $destinationParentId, $newOwnerId = null)
return $this->persistenceHandler->locationHandler()->copySubtree($sourceId, $destinationParentId, $newOwnerId);
}

public function getSubtreeSize(string $path): int
public function getSubtreeSize(string $path, ?int $limit = null): int
{
$this->logger->logCall(__METHOD__, [
'path' => $path,
'limit' => $limit,
]);

return $this->persistenceHandler->locationHandler()->getSubtreeSize($path);
return $this->persistenceHandler->locationHandler()->getSubtreeSize($path, $limit);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/lib/Persistence/Legacy/Content/Location/Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ abstract public function getSubtreeNodeIdToContentIdMap(int $sourceId): array;
*/
abstract public function getSubtreeChildrenDraftContentIds(int $sourceId): array;

abstract public function getSubtreeSize(string $path): int;
abstract public function getSubtreeSize(string $path, ?int $limit = null): int;

/**
* Returns data for the first level children of the location identified by given $locationId.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Ibexa\Contracts\Core\Persistence\Content\Location;
use Ibexa\Contracts\Core\Persistence\Content\Location\CreateStruct;
use Ibexa\Contracts\Core\Persistence\Content\Location\UpdateStruct;
use Ibexa\Contracts\Core\Persistence\Filter\Query\CountQueryBuilder;
use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
use Ibexa\Contracts\Core\Repository\Values\Content\Query\CriterionInterface;
use Ibexa\Core\Base\Exceptions\DatabaseException;
Expand Down Expand Up @@ -44,7 +45,8 @@ public function __construct(
private readonly Connection $connection,
private readonly MaskGenerator $languageMaskGenerator,
private readonly CriteriaConverter $trashCriteriaConverter,
private readonly SortClauseConverter $trashSortClauseConverter
private readonly SortClauseConverter $trashSortClauseConverter,
private readonly CountQueryBuilder $countQueryBuilder
) {
}

Expand Down Expand Up @@ -249,7 +251,10 @@ public function getSubtreeChildrenDraftContentIds(int $sourceId): array
return $query->executeQuery()->fetchFirstColumn();
}

public function getSubtreeSize(string $path): int
/**
* @phpstan-param positive-int $limit
*/
public function getSubtreeSize(string $path, ?int $limit = null): int
{
$query = $this->createNodeQueryBuilder(['COUNT(node_id)']);
$query->andWhere(
Expand All @@ -261,6 +266,12 @@ public function getSubtreeSize(string $path): int
)
);

$query = $this->countQueryBuilder->wrap(
$query,
't.node_id',
$limit
);

return (int) $query->executeQuery()->fetchOne();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ public function getSubtreeChildrenDraftContentIds(int $sourceId): array
}
}

public function getSubtreeSize(string $path): int
public function getSubtreeSize(string $path, ?int $limit = null): int
{
try {
return $this->innerGateway->getSubtreeSize($path);
return $this->innerGateway->getSubtreeSize($path, $limit);
} catch (DBALException | PDOException $e) {
throw DatabaseException::wrap($e);
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib/Persistence/Legacy/Content/Location/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,9 @@ public function copySubtree($sourceId, $destinationParentId, $newOwnerId = null)
return $copiedSubtreeRootLocation;
}

public function getSubtreeSize(string $path): int
public function getSubtreeSize(string $path, ?int $limit = null): int
{
return $this->locationGateway->getSubtreeSize($path);
return $this->locationGateway->getSubtreeSize($path, $limit);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Doctrine\DBAL\FetchMode;
use Ibexa\Contracts\Core\Persistence\Filter\CriterionVisitor;
use Ibexa\Contracts\Core\Persistence\Filter\Doctrine\FilteringQueryBuilder;
use Ibexa\Contracts\Core\Persistence\Filter\Query\CountQueryBuilder;
use Ibexa\Contracts\Core\Persistence\Filter\SortClauseVisitor;
use Ibexa\Contracts\Core\Repository\Values\Filter\FilteringCriterion;
use Ibexa\Core\Persistence\Legacy\Content\Gateway as ContentGateway;
Expand Down Expand Up @@ -57,17 +58,27 @@ final class DoctrineGateway implements Gateway
public function __construct(
private readonly Connection $connection,
private readonly CriterionVisitor $criterionVisitor,
private readonly SortClauseVisitor $sortClauseVisitor
private readonly SortClauseVisitor $sortClauseVisitor,
private readonly CountQueryBuilder $countQueryBuilder
) {
}

public function count(FilteringCriterion $criterion): int
/**
* @phpstan-param positive-int $limit
*/
public function count(FilteringCriterion $criterion, ?int $limit = null): int
{
$query = $this->buildQuery(
['COUNT(DISTINCT content.id)'],
$criterion
);

$query = $this->countQueryBuilder->wrap(
$query,
'content.id',
$limit
);

return (int)$query->executeQuery()->fetch(FetchMode::COLUMN);
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib/Persistence/Legacy/Filter/Gateway/Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
interface Gateway
{
/**
* Return number of matched rows for the given Criteria (a total count w/o pagination constraints).
* Return number of matched rows for the given Criteria (a total count w/o pagination constraints, Unless a limit is passed).
*/
public function count(FilteringCriterion $criterion): int;
public function count(FilteringCriterion $criterion, ?int $limit = null): int;

/**
* Return iterator for raw Repository data for the given Query result filtered by the given Criteria,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Doctrine\DBAL\FetchMode;
use Ibexa\Contracts\Core\Persistence\Filter\CriterionVisitor;
use Ibexa\Contracts\Core\Persistence\Filter\Doctrine\FilteringQueryBuilder;
use Ibexa\Contracts\Core\Persistence\Filter\Query\CountQueryBuilder;
use Ibexa\Contracts\Core\Persistence\Filter\SortClauseVisitor;
use Ibexa\Contracts\Core\Repository\Values\Filter\FilteringCriterion;
use Ibexa\Core\Persistence\Legacy\Content\Gateway as ContentGateway;
Expand All @@ -26,16 +27,26 @@
public function __construct(
private Connection $connection,
private CriterionVisitor $criterionVisitor,
private SortClauseVisitor $sortClauseVisitor
private SortClauseVisitor $sortClauseVisitor,
private CountQueryBuilder $countQueryBuilder
) {
}

public function count(FilteringCriterion $criterion): int
/**
* @phpstan-param positive-int $limit
*/
public function count(FilteringCriterion $criterion, ?int $limit = null): int
{
$query = $this->buildQuery($criterion);

$query->select('COUNT(DISTINCT location.node_id)');

$query = $this->countQueryBuilder->wrap(
$query,
'location.node_id',
$limit
);

return (int)$query->executeQuery()->fetch(FetchMode::COLUMN);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ function (array $row): ContentItem {
return $list;
}

public function count(Filter $filter): int
public function count(Filter $filter, ?int $limit = null): int
{
return $this->gateway->count($filter->getCriterion());
return $this->gateway->count($filter->getCriterion(), $limit);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ function (array $row): LocationWithContentInfo {
return $list;
}

public function count(Filter $filter): int
public function count(Filter $filter, ?int $limit = null): int
{
return $this->gateway->count($filter->getCriterion());
return $this->gateway->count($filter->getCriterion(), $limit);
}
}
Loading
Loading