Skip to content

Commit

Permalink
Merge 31e2f7b into e84281b
Browse files Browse the repository at this point in the history
  • Loading branch information
hrach committed Sep 13, 2020
2 parents e84281b + 31e2f7b commit 38dadfa
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 18 deletions.
20 changes: 17 additions & 3 deletions src/Mapper/Dbal/RelationshipMapperOneHasMany.php
Expand Up @@ -13,6 +13,7 @@
use Nextras\Orm\Entity\IEntityHasPreloadContainer;
use Nextras\Orm\Entity\Reflection\PropertyMetadata;
use Nextras\Orm\Entity\Reflection\PropertyRelationshipMetadata;
use Nextras\Orm\Exception\InvalidStateException;
use Nextras\Orm\Mapper\IRelationshipMapper;
use function array_merge;
use function array_unique;
Expand Down Expand Up @@ -239,7 +240,6 @@ protected function executeCounts(DbalCollection $collection, IEntity $parent): a
*/
private function fetchCounts(QueryBuilder $builder, array $values): array
{
$targetStoragePrimaryKey = $this->targetMapper->getConventions()->getStoragePrimaryKey()[0];
$sourceTable = $builder->getFromAlias();

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

} else {
$builder->orderBy(null);
$builder->addSelect('COUNT(DISTINCT %column) AS [count]', "{$sourceTable}.{$targetStoragePrimaryKey}");
$targetStoragePrimaryKeys = $this->targetMapper->getConventions()->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
46 changes: 31 additions & 15 deletions tests/cases/integration/Relationships/relationships.oneHasMany.phpt
Expand Up @@ -36,29 +36,45 @@ class RelationshipOneHasManyTest extends DataTestCase
$collection = $author->books->toCollection()->findBy(['title!=' => 'Book 1']);
Assert::equal(1, $collection->count());
Assert::equal(1, $collection->countStored());
$fetchted = $collection->fetch();
Assert::notNull($fetchted);
Assert::equal('Book 2', $fetchted->title);
$fetched = $collection->fetch();
Assert::notNull($fetched);
Assert::equal('Book 2', $fetched->title);

$collection = $author->books->toCollection()->findBy(['title!=' => 'Book 3']);
Assert::equal(2, $collection->count());
Assert::equal(2, $collection->countStored());
$fetchted = $collection->fetch();
Assert::notNull($fetchted);
Assert::equal('Book 2', $fetchted->title);
$fetchted = $collection->fetch();
Assert::notNull($fetchted);
Assert::equal('Book 1', $fetchted->title);
$fetched = $collection->fetch();
Assert::notNull($fetched);
Assert::equal('Book 2', $fetched->title);
$fetched = $collection->fetch();
Assert::notNull($fetched);
Assert::equal('Book 1', $fetched->title);

$collection = $author->books->toCollection()->resetOrderBy()->findBy(['title!=' => 'Book 3'])->orderBy('id');
Assert::equal(2, $collection->count());
Assert::equal(2, $collection->countStored());
$fetchted = $collection->fetch();
Assert::notNull($fetchted);
Assert::equal('Book 1', $fetchted->title);
$fetchted = $collection->fetch();
Assert::notNull($fetchted);
Assert::equal('Book 2', $fetchted->title);
$fetched = $collection->fetch();
Assert::notNull($fetched);
Assert::equal('Book 1', $fetched->title);
$fetched = $collection->fetch();
Assert::notNull($fetched);
Assert::equal('Book 2', $fetched->title);
}


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

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


Expand Down

0 comments on commit 38dadfa

Please sign in to comment.