mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
DX: Add DQL function LEAST and GREATEST
This commit is contained in:
parent
c22135f101
commit
c1df8084a6
@ -25,10 +25,12 @@ use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface;
|
|||||||
use Chill\MainBundle\Doctrine\DQL\Age;
|
use Chill\MainBundle\Doctrine\DQL\Age;
|
||||||
use Chill\MainBundle\Doctrine\DQL\Extract;
|
use Chill\MainBundle\Doctrine\DQL\Extract;
|
||||||
use Chill\MainBundle\Doctrine\DQL\GetJsonFieldByKey;
|
use Chill\MainBundle\Doctrine\DQL\GetJsonFieldByKey;
|
||||||
|
use Chill\MainBundle\Doctrine\DQL\Greatest;
|
||||||
use Chill\MainBundle\Doctrine\DQL\JsonAggregate;
|
use Chill\MainBundle\Doctrine\DQL\JsonAggregate;
|
||||||
use Chill\MainBundle\Doctrine\DQL\JsonbArrayLength;
|
use Chill\MainBundle\Doctrine\DQL\JsonbArrayLength;
|
||||||
use Chill\MainBundle\Doctrine\DQL\JsonbExistsInArray;
|
use Chill\MainBundle\Doctrine\DQL\JsonbExistsInArray;
|
||||||
use Chill\MainBundle\Doctrine\DQL\JsonExtract;
|
use Chill\MainBundle\Doctrine\DQL\JsonExtract;
|
||||||
|
use Chill\MainBundle\Doctrine\DQL\Least;
|
||||||
use Chill\MainBundle\Doctrine\DQL\OverlapsI;
|
use Chill\MainBundle\Doctrine\DQL\OverlapsI;
|
||||||
use Chill\MainBundle\Doctrine\DQL\Replace;
|
use Chill\MainBundle\Doctrine\DQL\Replace;
|
||||||
use Chill\MainBundle\Doctrine\DQL\Similarity;
|
use Chill\MainBundle\Doctrine\DQL\Similarity;
|
||||||
@ -246,6 +248,8 @@ class ChillMainExtension extends Extension implements
|
|||||||
'JSONB_ARRAY_LENGTH' => JsonbArrayLength::class,
|
'JSONB_ARRAY_LENGTH' => JsonbArrayLength::class,
|
||||||
'ST_X' => STX::class,
|
'ST_X' => STX::class,
|
||||||
'ST_Y' => STY::class,
|
'ST_Y' => STY::class,
|
||||||
|
'GREATEST' => Greatest::class,
|
||||||
|
'LEAST' => LEAST::class,
|
||||||
],
|
],
|
||||||
'datetime_functions' => [
|
'datetime_functions' => [
|
||||||
'EXTRACT' => Extract::class,
|
'EXTRACT' => Extract::class,
|
||||||
|
57
src/Bundle/ChillMainBundle/Doctrine/DQL/Greatest.php
Normal file
57
src/Bundle/ChillMainBundle/Doctrine/DQL/Greatest.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Doctrine\DQL;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||||
|
use Doctrine\ORM\Query\AST\Node;
|
||||||
|
use Doctrine\ORM\Query\Lexer;
|
||||||
|
use Doctrine\ORM\Query\Parser;
|
||||||
|
use Doctrine\ORM\Query\SqlWalker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Postgresql GREATEST function.
|
||||||
|
*
|
||||||
|
* Borrowed from https://github.com/beberlei/DoctrineExtensions/blob/master/src/Query/Postgresql/Greatest.php
|
||||||
|
* (https://github.com/beberlei/DoctrineExtensions/blob/master/LICENSE) and
|
||||||
|
* https://gist.github.com/olimsaidov/4bbd530b1b645ce75e1bbb781b5dd91f
|
||||||
|
*/
|
||||||
|
class Greatest extends FunctionNode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array|Node[]
|
||||||
|
*/
|
||||||
|
private array $exprs = [];
|
||||||
|
|
||||||
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
return 'GREATEST(' . implode(', ', array_map(static function (Node $expr) use ($sqlWalker) {
|
||||||
|
return $expr->dispatch($sqlWalker);
|
||||||
|
}, $this->exprs)) . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parse(Parser $parser)
|
||||||
|
{
|
||||||
|
$this->exprs = [];
|
||||||
|
|
||||||
|
$lexer = $parser->getLexer();
|
||||||
|
$parser->match(Lexer::T_IDENTIFIER);
|
||||||
|
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||||
|
$this->exprs[] = $parser->ArithmeticPrimary();
|
||||||
|
|
||||||
|
while (Lexer::T_COMMA === $lexer->lookahead['type']) {
|
||||||
|
$parser->match(Lexer::T_COMMA);
|
||||||
|
$this->exprs[] = $parser->ArithmeticPrimary();
|
||||||
|
}
|
||||||
|
|
||||||
|
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
|
}
|
57
src/Bundle/ChillMainBundle/Doctrine/DQL/Least.php
Normal file
57
src/Bundle/ChillMainBundle/Doctrine/DQL/Least.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Doctrine\DQL;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||||
|
use Doctrine\ORM\Query\AST\Node;
|
||||||
|
use Doctrine\ORM\Query\Lexer;
|
||||||
|
use Doctrine\ORM\Query\Parser;
|
||||||
|
use Doctrine\ORM\Query\SqlWalker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Postgresql LEAST function.
|
||||||
|
*
|
||||||
|
* Borrowed from https://github.com/beberlei/DoctrineExtensions/blob/master/src/Query/Postgresql/Least.php
|
||||||
|
* (https://github.com/beberlei/DoctrineExtensions/blob/master/LICENSE) and
|
||||||
|
* https://gist.github.com/olimsaidov/4bbd530b1b645ce75e1bbb781b5dd91f
|
||||||
|
*/
|
||||||
|
class Least extends FunctionNode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array|Node[]
|
||||||
|
*/
|
||||||
|
private array $exprs = [];
|
||||||
|
|
||||||
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
return 'LEAST(' . implode(', ', array_map(static function (Node $expr) use ($sqlWalker) {
|
||||||
|
return $expr->dispatch($sqlWalker);
|
||||||
|
}, $this->exprs)) . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parse(Parser $parser)
|
||||||
|
{
|
||||||
|
$this->exprs = [];
|
||||||
|
|
||||||
|
$lexer = $parser->getLexer();
|
||||||
|
$parser->match(Lexer::T_IDENTIFIER);
|
||||||
|
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||||
|
$this->exprs[] = $parser->ArithmeticPrimary();
|
||||||
|
|
||||||
|
while (Lexer::T_COMMA === $lexer->lookahead['type']) {
|
||||||
|
$parser->match(Lexer::T_COMMA);
|
||||||
|
$this->exprs[] = $parser->ArithmeticPrimary();
|
||||||
|
}
|
||||||
|
|
||||||
|
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Tests\Doctrine\DQL;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Address;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\DBAL\Types\Types;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class GreatestTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
private EntityManagerInterface $entityManager;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
|
||||||
|
$this->entityManager = self::$container->get(EntityManagerInterface::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGreatestInDQL()
|
||||||
|
{
|
||||||
|
$dql = 'SELECT GREATEST(a.validFrom, a.validTo, :now) AS g FROM ' . Address::class . ' a WHERE a.validTo < :now and a.validFrom < :now';
|
||||||
|
|
||||||
|
$actual = $this->entityManager
|
||||||
|
->createQuery($dql)
|
||||||
|
->setParameter('now', $now = new DateTimeImmutable('now'), Types::DATE_IMMUTABLE)
|
||||||
|
->setMaxResults(3)
|
||||||
|
->getResult();
|
||||||
|
|
||||||
|
$this->assertIsArray($actual);
|
||||||
|
$this->assertEquals($now->format('Y-m-d'), $actual[0]['g']);
|
||||||
|
}
|
||||||
|
}
|
48
src/Bundle/ChillMainBundle/Tests/Doctrine/DQL/LeastTest.php
Normal file
48
src/Bundle/ChillMainBundle/Tests/Doctrine/DQL/LeastTest.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Tests\Doctrine\DQL;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Address;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\DBAL\Types\Types;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class LeastTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
private EntityManagerInterface $entityManager;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
|
||||||
|
$this->entityManager = self::$container->get(EntityManagerInterface::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGreatestInDQL()
|
||||||
|
{
|
||||||
|
$dql = 'SELECT LEAST(a.validFrom, a.validTo, :now) AS g FROM ' . Address::class . ' a WHERE a.validTo < :now and a.validFrom < :now';
|
||||||
|
|
||||||
|
$actual = $this->entityManager
|
||||||
|
->createQuery($dql)
|
||||||
|
->setParameter('now', $now = new DateTimeImmutable('now'), Types::DATE_IMMUTABLE)
|
||||||
|
->setMaxResults(3)
|
||||||
|
->getResult();
|
||||||
|
|
||||||
|
$this->assertIsArray($actual);
|
||||||
|
$this->assertNotEquals($now->format('Y-m-d'), $actual[0]['g']);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user