Skip to content

Commit

Permalink
relationships: fix counting 1:M table with composite primary key
Browse files Browse the repository at this point in the history
  • Loading branch information
hrach committed Sep 13, 2020
1 parent d495ee1 commit d781eb3
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
20 changes: 17 additions & 3 deletions src/Mapper/Dbal/RelationshipMapperOneHasMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Nextras\Orm\Entity\IEntityHasPreloadContainer;
use Nextras\Orm\Entity\Reflection\PropertyMetadata;
use Nextras\Orm\Entity\Reflection\PropertyRelationshipMetadata;
use Nextras\Orm\InvalidStateException;
use Nextras\Orm\Mapper\IRelationshipMapper;


Expand Down Expand Up @@ -218,7 +219,6 @@ protected function executeCounts(DbalCollection $collection, IEntity $parent)

private function fetchCounts(QueryBuilder $builder, array $values)
{
$targetStoragePrimaryKey = $this->targetMapper->getStorageReflection()->getStoragePrimaryKey()[0];
$sourceTable = $builder->getFromAlias();

$builder = clone $builder;
Expand All @@ -228,10 +228,24 @@ private function fetchCounts(QueryBuilder $builder, array $values)
$result = $this->processMultiCountResult($builder, $values);

} else {
$builder->orderBy(null);
$builder->addSelect('COUNT(DISTINCT %column) AS [count]', "{$sourceTable}.{$targetStoragePrimaryKey}");
$targetStoragePrimaryKeys = $this->targetMapper->getStorageReflection()->getStoragePrimaryKey();
$targetColumn = null;
foreach ($targetStoragePrimaryKeys as $targetStoragePrimaryKey) {
if ($targetStoragePrimaryKey === $this->joinStorageKey) {
continue;
}
$targetColumn = "$sourceTable.$targetStoragePrimaryKey";
break;
}

if ($targetColumn === null) {
throw new InvalidStateException('Unable to detect column for count query.');
}

$builder->addSelect('COUNT(DISTINCT %column) AS [count]', $targetColumn);
$builder->andWhere('%column IN %any', "{$sourceTable}.{$this->joinStorageKey}", $values);
$builder->groupBy('%column', "{$sourceTable}.{$this->joinStorageKey}");
$builder->orderBy(null);
$result = $this->connection->queryArgs($builder->getQuerySql(), $builder->getQueryParameters());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ class RelationshipOneHasManyTest extends DataTestCase
}


public function testCountOnCompositePkInTargetTable()
{
// add another tag to have >1 tags followers for tag#2
$tag = $this->orm->tags->getById(1);
$author = $this->orm->authors->getById(2);
$tagFollower = new TagFollower();
$tagFollower->author = $author;
$tagFollower->tag = $tag;
$this->orm->persistAndFlush($tagFollower);
$this->orm->clear();

$tag = $this->orm->tags->getById(1);
Assert::same(2, $tag->tagFollowers->countStored());
}


public function testWithDifferentPrimaryKey()
{
$publisher = $this->orm->publishers->getById(1);
Expand Down

0 comments on commit d781eb3

Please sign in to comment.