Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
hrach committed Dec 7, 2021
1 parent 290cdab commit f074fb4
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 58 deletions.
6 changes: 6 additions & 0 deletions src/Collection/Aggregations/AnyAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ public function aggregateValues(array $values): bool
}


public function getAggregateKey(): string
{
return '_any';
}


public function aggregateExpression(
QueryBuilder $queryBuilder,
DbalExpressionResult $expression
Expand Down
3 changes: 3 additions & 0 deletions src/Collection/Aggregations/IArrayAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ interface IArrayAggregator extends IAggregator
* @return T
*/
function aggregateValues(array $values);


function getAggregateKey(): string;
}
6 changes: 6 additions & 0 deletions src/Collection/Aggregations/NoneAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ public function aggregateValues(array $values): bool
}


public function getAggregateKey(): string
{
return '_none';
}


public function aggregateExpression(
QueryBuilder $queryBuilder,
DbalExpressionResult $expression
Expand Down
63 changes: 45 additions & 18 deletions src/Collection/Functions/ConjunctionOperatorFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,57 @@ public function processArrayExpression(
$aggregator = $newAggregator;
}

/** @var array<array<ArrayPropertyValueReference>> $valueReferences */
$valueReferences = [];
/**
* The following code evaluates all operands of the AND operator and group them by their aggregators.
* If there is an aggregation, operand results to multi-value result.
* Then we apply the operator's function per each value of the for multi-value result of operands with the same
* aggregation.
*/

/** @var array<string, IArrayAggregator> $aggregators */
$aggregators = [];
$values = [];

foreach ($normalized as $arg) {
$callback = $helper->createFilter($arg, $aggregator);
$valueReference = $callback($entity);
$key = $valueReference->aggregator?->aggregationKey ?? '-';
$valueReferences[$key][] = $valueReference;
}

$results = [];
foreach($valueReferences as $key => $subValueReferences) {
/** @var ArrayPropertyValueReference $firstValueReference */
$firstValueReference = reset($valueReferences);
$firstValueReference->
if ($valueReference->aggregator === null) {
if ($valueReference->value == false) {
return new ArrayPropertyValueReference(
false,
null,
null
);
}
} else {
$key = $valueReference->aggregator->getAggregateKey();
$aggregators[$key] = $valueReference->aggregator;
$values[$key][] = $valueReference->value;
}
}

$valueReference = $valueReference->applyAggregator();
if ($valueReference->value == false) { // intentionally ==
return new ArrayPropertyValueReference(
/* $result = */ false,
null,
null
);
foreach (array_keys($aggregators) as $key) {
$valuesBatch = [];
$size = count($values[$key][0]);
for ($i = 0; $i < $size; $i++) {
$operands = [];
foreach ($values[$key] as $value) {
$operands[] = $value[$i];
}
$valuesBatch[] = array_reduce($operands, function ($v, $ac) {
return $v && $ac;
}, true);
}

$aggregator = $aggregators[$key];
$result = $aggregator->aggregateValues($valuesBatch);
if ($result == false) {
return new ArrayPropertyValueReference(
false,
null,
null
);
}
}

return new ArrayPropertyValueReference(
Expand Down
94 changes: 54 additions & 40 deletions tests/cases/integration/Collection/collection.aggregation.join.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace NextrasTests\Orm\Integration\Collection;

use Nextras\Orm\Collection\Aggregations\AnyAggregator;
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 All @@ -20,30 +22,30 @@ require_once __DIR__ . '/../../../bootstrap.php';

class CollectionAggregationJoinTest extends DataTestCase
{
// public function testAny(): void
// {
// $authors = $this->orm->authors->findBy([
// ICollection::AND,
// new AnyAggregator(),
// ['books->title' => 'Book 1'],
// ]);
// Assert::same(1, $authors->count());
// Assert::same(1, $authors->countStored());
// $author = $authors->fetch();
// Assert::notNull($author);
// Assert::same(1, $author->id);
//
// // implicit any
// $authors = $this->orm->authors->findBy([
// ICollection::AND,
// ['books->title' => 'Book 1'],
// ]);
// Assert::same(1, $authors->count());
// Assert::same(1, $authors->countStored());
// $author = $authors->fetch();
// Assert::notNull($author);
// Assert::same(1, $author->id);
// }
public function testAny(): void
{
$authors = $this->orm->authors->findBy([
ICollection::AND,
new AnyAggregator(),
['books->title' => 'Book 1'],
]);
Assert::same(1, $authors->count());
Assert::same(1, $authors->countStored());
$author = $authors->fetch();
Assert::notNull($author);
Assert::same(1, $author->id);

// implicit any
$authors = $this->orm->authors->findBy([
ICollection::AND,
['books->title' => 'Book 1'],
]);
Assert::same(1, $authors->count());
Assert::same(1, $authors->countStored());
$author = $authors->fetch();
Assert::notNull($author);
Assert::same(1, $author->id);
}


public function testAnyDependent()
Expand All @@ -53,31 +55,43 @@ class CollectionAggregationJoinTest extends DataTestCase
* - has title Book 1
* - and is not translated.
*/
dump("-----");
$authors = $this->orm->authors->findBy([
ICollection::AND,
'books->title' => 'Book 1',
'books->translator->id' => null,
]);
$authors->fetchAll();
// Assert::same(0, $authors->count());
// Assert::same(0, $authors->countStored());
Assert::same(0, $authors->count());
Assert::same(0, $authors->countStored());
}


public function testHasValueOrEmptyWithFunctions(): void
{
$books = $this->orm->books->findBy([
ICollection::OR,
['tags->id' => [1]],
[CompareEqualsFunction::class, [CountAggregateFunction::class, 'tags->id'], 0],
]);

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


// public function testNone(): void
// {
// $authors = $this->orm->authors->findBy([
// ICollection::AND,
// new NoneAggregator(),
// ['books->title' => 'Book 1'],
// ]);
// Assert::same(1, $authors->count());
// Assert::same(1, $authors->countStored());
// $author = $authors->fetch();
// Assert::notNull($author);
// Assert::same(2, $author->id);
// }
public function testNone(): void
{
$authors = $this->orm->authors->findBy([
ICollection::AND,
new NoneAggregator(),
['books->title' => 'Book 1'],
]);
Assert::same(1, $authors->count());
Assert::same(1, $authors->countStored());
$author = $authors->fetch();
Assert::notNull($author);
Assert::same(2, $author->id);
}
}


Expand Down

0 comments on commit f074fb4

Please sign in to comment.