Skip to content

Commit

Permalink
Allowed Composite NOT expression
Browse files Browse the repository at this point in the history
  • Loading branch information
Steveb-p authored Oct 2, 2023
1 parent deb0995 commit 62a007a
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 4 deletions.
10 changes: 6 additions & 4 deletions src/lib/Gateway/ExpressionVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
use Doctrine\Common\Collections\Expr\ExpressionVisitor as BaseExpressionVisitor;
use Doctrine\Common\Collections\Expr\Value;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\Expression\CompositeExpression as DBALCompositeExpression;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
use Doctrine\DBAL\Query\QueryBuilder;
use Ibexa\Contracts\CorePersistence\Gateway\DoctrineOneToManyRelationship;
Expand Down Expand Up @@ -197,7 +196,7 @@ public function walkValue(Value $value)
return $value->getValue();
}

public function walkCompositeExpression(CompositeExpression $expr): DBALCompositeExpression
public function walkCompositeExpression(CompositeExpression $expr): string
{
$expressionList = [];
foreach ($expr->getExpressionList() as $child) {
Expand All @@ -206,10 +205,13 @@ public function walkCompositeExpression(CompositeExpression $expr): DBALComposit

switch ($expr->getType()) {
case CompositeExpression::TYPE_AND:
return $this->expr()->and(...$expressionList);
return (string)$this->expr()->and(...$expressionList);

case CompositeExpression::TYPE_OR:
return $this->expr()->or(...$expressionList);
return (string)$this->expr()->or(...$expressionList);

case 'NOT':
return $this->queryBuilder->getConnection()->getDatabasePlatform()->getNotExpression($expressionList[0]);

default:
throw new RuntimeException('Unknown composite ' . $expr->getType());
Expand Down
104 changes: 104 additions & 0 deletions tests/bundle/Gateway/ExpressionVisitorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Bundle\CorePersistence\Gateway;

use Doctrine\Common\Collections\Expr\Comparison;
use Doctrine\Common\Collections\Expr\CompositeExpression;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
use Doctrine\DBAL\Query\QueryBuilder;
use Ibexa\Contracts\CorePersistence\Gateway\DoctrineSchemaMetadataRegistryInterface;
use Ibexa\CorePersistence\Gateway\ExpressionVisitor;
use Ibexa\CorePersistence\Gateway\Parameter;
use PHPUnit\Framework\TestCase;

final class ExpressionVisitorTest extends TestCase
{
private ExpressionVisitor $expressionVisitor;

protected function setUp(): void
{
$connection = $this->createMock(Connection::class);

$connection->method('getExpressionBuilder')
->willReturn(new ExpressionBuilder($connection));

$platform = $this->getMockBuilder(AbstractPlatform::class)
->getMockForAbstractClass();

$connection->method('getDatabasePlatform')
->willReturn($platform);

$this->expressionVisitor = new ExpressionVisitor(
new QueryBuilder($connection),
$this->createMock(DoctrineSchemaMetadataRegistryInterface::class),
'table_name',
'table_alias',
);
}

public function testWalkComparison(): void
{
$result = $this->expressionVisitor->dispatch(new Comparison('field', '=', 'value'));

self::assertSame('table_alias.field = :field_0', $result);
self::assertEquals([
new Parameter(
'field_0',
'value',
0,
),
], $this->expressionVisitor->getParameters());
}

public function testLogicalNot(): void
{
$result = $this->expressionVisitor->dispatch(
new CompositeExpression('NOT', [new Comparison('field', '=', 'value')]),
);

self::assertSame('NOT(table_alias.field = :field_0)', $result);
self::assertEquals([
new Parameter(
'field_0',
'value',
0,
),
], $this->expressionVisitor->getParameters());
}

public function testLogicalAnd(): void
{
$result = $this->expressionVisitor->dispatch(
new CompositeExpression('AND', [
new Comparison('field', '=', 'value'),
new Comparison('field_2', 'IN', 'value_2'),
]),
);

self::assertSame(
'(table_alias.field = :field_0) AND (table_alias.field_2 IN (:field_2_1))',
$result,
);

self::assertEquals([
new Parameter(
'field_0',
'value',
0,
),
new Parameter(
'field_2_1',
'value_2',
0,
),
], $this->expressionVisitor->getParameters());
}
}

0 comments on commit 62a007a

Please sign in to comment.