Skip to content

Commit

Permalink
Merge pull request #542 from nextras/joins
Browse files Browse the repository at this point in the history
Merging same JOINs together & introduction of independent JOINs
  • Loading branch information
hrach authored Dec 11, 2021
2 parents a5e48e6 + 408c9d3 commit 26b6d8d
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 4 deletions.
5 changes: 4 additions & 1 deletion src/Collection/Aggregations/AnyAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
*/
class AnyAggregator implements IDbalAggregator, IArrayAggregator
{
/** @var string */
/** @var literal-string */
private $aggregateKey;


/**
* @param literal-string $aggregateKey
*/
public function __construct(string $aggregateKey = 'any')
{
$this->aggregateKey = $aggregateKey;
Expand Down
5 changes: 4 additions & 1 deletion src/Collection/Aggregations/CountAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ class CountAggregator implements IDbalAggregator, IArrayAggregator
/** @var int */
private $atMost;

/** @var string */
/** @var literal-string */
private $aggregateKey;


/**
* @param literal-string $aggregateKey
*/
public function __construct(
int $atLeast,
int $atMost,
Expand Down
3 changes: 3 additions & 0 deletions src/Collection/Aggregations/IAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@

interface IAggregator
{
/**
* @return literal-string
*/
public function getAggregateKey(): string;
}
5 changes: 4 additions & 1 deletion src/Collection/Aggregations/NoneAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
*/
class NoneAggregator implements IDbalAggregator, IArrayAggregator
{
/** @var string */
/** @var literal-string */
private $aggregateKey;


/**
* @param literal-string $aggregateKey
*/
public function __construct(string $aggregateKey = 'none')
{
$this->aggregateKey = $aggregateKey;
Expand Down
2 changes: 1 addition & 1 deletion src/Collection/Functions/BaseAggregateFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public function processQueryBuilderExpression(

public function getAggregateKey(): string
{
return '_' . strtolower($this->sqlFunction);
return '_' . $this->sqlFunction;
}


Expand Down
7 changes: 7 additions & 0 deletions src/Collection/Helpers/DbalQueryBuilderHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Nextras\Dbal\Platforms\Data\Column;
use Nextras\Dbal\QueryBuilder\QueryBuilder;
use Nextras\Orm\Collection\Aggregations\AnyAggregator;
use Nextras\Orm\Collection\Aggregations\IAggregator;
use Nextras\Orm\Collection\Aggregations\IDbalAggregator;
use Nextras\Orm\Collection\Functions\ConjunctionOperatorFunction;
use Nextras\Orm\Collection\Functions\IQueryBuilderFunction;
Expand Down Expand Up @@ -302,6 +303,7 @@ private function processTokens(
$tokens,
$joins,
$property,
$aggregator,
$currentConventions,
$currentMapper,
$currentAlias,
Expand Down Expand Up @@ -366,6 +368,7 @@ private function processRelationship(
array $tokens,
array &$joins,
PropertyMetadata $property,
?IAggregator $aggregator,
IConventions $currentConventions,
DbalMapper $currentMapper,
string $currentAlias,
Expand Down Expand Up @@ -436,6 +439,10 @@ private function processRelationship(
$targetTable = $targetMapper->getTableName();
/** @phpstan-var literal-string $targetAlias */
$targetAlias = self::getAlias($tokens[$tokenIndex], array_slice($tokens, 0, $tokenIndex));
if ($makeDistinct) {
$aggregator = $aggregator ?? new AnyAggregator();
$targetAlias .= '_' . $aggregator->getAggregateKey();
}
$joins[] = new DbalJoinEntry(
"%table",
[$targetTable],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace NextrasTests\Orm\Integration\Collection;
use Nextras\Orm\Collection\Aggregations\AnyAggregator;
use Nextras\Orm\Collection\Aggregations\CountAggregator;
use Nextras\Orm\Collection\Aggregations\NoneAggregator;
use Nextras\Orm\Collection\Functions\CompareEqualsFunction;
use Nextras\Orm\Collection\Functions\CountAggregateFunction;
use Nextras\Orm\Collection\ICollection;
use NextrasTests\Orm\DataTestCase;
use Tester\Assert;
Expand Down Expand Up @@ -82,6 +84,24 @@ class CollectionAggregationJoinTest extends DataTestCase
}


public function testHasValueOrEmptyWithFunctions(): void
{
/*
* Selects books where book:
* - has a tag with id 1
* - or has no tags
*/
$books = $this->orm->books->findBy([
ICollection::OR,
['tags->id' => [1]],
[CompareEqualsFunction::class, [CountAggregateFunction::class, 'tags->id'], 0],
]);

Assert::same(2, $books->count());
Assert::same(2, $books->countStored());
}


public function testNone(): void
{
$authors = $this->orm->authors->findBy([
Expand All @@ -95,6 +115,29 @@ class CollectionAggregationJoinTest extends DataTestCase
Assert::notNull($author);
Assert::same(2, $author->id);
}


public function testIndependentSelects(): void
{
$authors = $this->orm->authors->findBy([
ICollection::AND,
[
ICollection::AND,
new AnyAggregator('any1'),
'books->title' => 'Book 1',
'books->price->cents' => 50,
],
[
ICollection::AND,
new AnyAggregator('any2'),
'books->title' => 'Book 2',
'books->price->cents' => 150,
],
]);

Assert::same(1, $authors->count());
Assert::same(1, $authors->countStored());
}
}


Expand Down

0 comments on commit 26b6d8d

Please sign in to comment.