Skip to content

Commit

Permalink
Merge pull request #419 from nextras/collection_functions_refactoring
Browse files Browse the repository at this point in the history
Collection functions refactoring
  • Loading branch information
hrach committed May 24, 2020
2 parents 10cf6ba + 7aa81d0 commit 9d8a976
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 41 deletions.
2 changes: 1 addition & 1 deletion doc/collection.texy
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ $orm->books->findAll()->orderBy('title'); // ORDER BY title ASC
$orm->books->findAll()->orderBy('title', ICollection::DESC); // ORDER BY title DESC
\--

The first property argument also accepts a traversing expression. See filtering in this chapter for futher description.
The first property argument also accepts a traversing expression. See filtering in this chapter for further description.

You can add more ordering rules that will be used if the previously defined ordering properties will be evaluated as equal. To do this, call `orderBy` method repeatedly or simple use `orderByMultiple` method and pass array of property names and their sorting direction. The sorting may be reset by `resetOrderBy()` method.

Expand Down
25 changes: 2 additions & 23 deletions src/Collection/Functions/BaseCompareFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
use Nextras\Orm\Entity\IEntity;
use function assert;
use function count;
use function is_array;
use function is_string;


abstract class BaseCompareFunction implements IArrayFunction, IQueryBuilderFunction
Expand Down Expand Up @@ -57,20 +55,7 @@ public function processQueryBuilderExpression(
$value = $args[1];
}

// extract column names for multiOr simplification
$eArgs = $expression->args;
if (
count($eArgs) === 2
&& $eArgs[0] === '%column'
&& is_array($eArgs[1])
&& is_string($eArgs[1][0])
) {
$columns = $eArgs[1];
} else {
$columns = null;
}

return $this->evaluateInDb($expression, $columns, $value);
return $this->evaluateInDb($expression, $value);
}


Expand All @@ -83,12 +68,6 @@ abstract protected function evaluateInPhp($sourceValue, $targetValue): bool;

/**
* @param mixed $value
* @param array|null $columns
* @phpstan-param array<string>|null $columns
*/
abstract protected function evaluateInDb(
DbalExpressionResult $expression,
?array $columns,
$value
): DbalExpressionResult;
abstract protected function evaluateInDb(DbalExpressionResult $expression, $value): DbalExpressionResult;
}
9 changes: 7 additions & 2 deletions src/Collection/Functions/CompareEqualsFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Nextras\Orm\Collection\Helpers\DbalExpressionResult;
use function array_combine;
use function array_map;
use function count;
use function in_array;
use function is_array;

Expand All @@ -24,11 +25,15 @@ protected function evaluateInPhp($sourceValue, $targetValue): bool


/** @inheritDoc */
protected function evaluateInDb(DbalExpressionResult $expression, ?array $columns, $value): DbalExpressionResult
protected function evaluateInDb(DbalExpressionResult $expression, $value): DbalExpressionResult
{
if (is_array($value)) {
if ($value) {
if ($columns !== null) {
// extract column names for multiOr simplification
// array{%column, array<string>}
$args = $expression->args;
if (count($args) === 2 && $args[0] === '%column' && is_array($args[1])) {
$columns = $args[1];
$value = array_map(function ($value) use ($columns) {
return array_combine($columns, $value);
}, $value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected function evaluateInPhp($sourceValue, $targetValue): bool


/** @inheritDoc */
protected function evaluateInDb(DbalExpressionResult $expression, ?array $columns, $value): DbalExpressionResult
protected function evaluateInDb(DbalExpressionResult $expression, $value): DbalExpressionResult
{
return $expression->append(">= %any", $value);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Collection/Functions/CompareGreaterThanFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected function evaluateInPhp($sourceValue, $targetValue): bool


/** @inheritDoc */
protected function evaluateInDb(DbalExpressionResult $expression, ?array $columns, $value): DbalExpressionResult
protected function evaluateInDb(DbalExpressionResult $expression, $value): DbalExpressionResult
{
return $expression->append("> %any", $value);
}
Expand Down
9 changes: 7 additions & 2 deletions src/Collection/Functions/CompareNotEqualsFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Nextras\Orm\Collection\Helpers\DbalExpressionResult;
use function array_combine;
use function array_map;
use function count;
use function in_array;
use function is_array;

Expand All @@ -24,11 +25,15 @@ protected function evaluateInPhp($sourceValue, $targetValue): bool


/** @inheritDoc */
protected function evaluateInDb(DbalExpressionResult $expression, ?array $columns, $value): DbalExpressionResult
protected function evaluateInDb(DbalExpressionResult $expression, $value): DbalExpressionResult
{
if (is_array($value)) {
if ($value) {
if ($columns !== null) {
// extract column names for multiOr simplification
// array{%column, array<string>}
$args = $expression->args;
if (count($args) === 2 && $args[0] === '%column' && is_array($args[1])) {
$columns = $args[1];
$value = array_map(function ($value) use ($columns) {
return array_combine($columns, $value);
}, $value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected function evaluateInPhp($sourceValue, $targetValue): bool


/** @inheritDoc */
protected function evaluateInDb(DbalExpressionResult $expression, ?array $columns, $value): DbalExpressionResult
protected function evaluateInDb(DbalExpressionResult $expression, $value): DbalExpressionResult
{
return $expression->append("<= %any", $value);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Collection/Functions/CompareSmallerThanFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected function evaluateInPhp($sourceValue, $targetValue): bool


/** @inheritDoc */
protected function evaluateInDb(DbalExpressionResult $expression, ?array $columns, $value): DbalExpressionResult
protected function evaluateInDb(DbalExpressionResult $expression, $value): DbalExpressionResult
{
return $expression->append("< %any", $value);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Collection/Functions/IArrayFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

/**
* Collection function implementation for ArrayCollection.
* Processes expression and reuse its result for futher evaluation.
* Processes expression and reuse its result for further evaluation.
*/
interface IArrayFunction
{
Expand Down
20 changes: 12 additions & 8 deletions src/Collection/Helpers/DbalQueryBuilderHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ public function processPropertyExpr(QueryBuilder $builder, $expr): DbalExpressio
{
if (is_array($expr)) {
$function = array_shift($expr);
$collectionFunction = $this->repository->getCollectionFunction($function);
if (!$collectionFunction instanceof IQueryBuilderFunction) {
throw new InvalidArgumentException("Collection function $function has to implement " . IQueryBuilderFunction::class . ' interface.');
}
$collectionFunction = $this->getCollectionFunction($function);
return $collectionFunction->processQueryBuilderExpression($this, $builder, $expr);
}

Expand All @@ -101,10 +98,7 @@ public function processPropertyExpr(QueryBuilder $builder, $expr): DbalExpressio
public function processFilterFunction(QueryBuilder $builder, array $expr): DbalExpressionResult
{
$function = isset($expr[0]) ? array_shift($expr) : ICollection::AND;
$collectionFunction = $this->repository->getCollectionFunction($function);
if (!$collectionFunction instanceof IQueryBuilderFunction) {
throw new InvalidArgumentException("Collection function $function has to implement " . IQueryBuilderFunction::class . ' interface.');
}
$collectionFunction = $this->getCollectionFunction($function);
return $collectionFunction->processQueryBuilderExpression($this, $builder, $expr);
}

Expand Down Expand Up @@ -199,6 +193,16 @@ public function normalizeValue($value, PropertyMetadata $propertyMetadata, IConv
}


private function getCollectionFunction(string $name): IQueryBuilderFunction
{
$collectionFunction = $this->repository->getCollectionFunction($name);
if (!$collectionFunction instanceof IQueryBuilderFunction) {
throw new InvalidArgumentException("Collection function $name has to implement " . IQueryBuilderFunction::class . ' interface.');
}
return $collectionFunction;
}


/**
* @param array<string> $tokens
* @param class-string<\Nextras\Orm\Entity\IEntity>|null $sourceEntity
Expand Down

0 comments on commit 9d8a976

Please sign in to comment.