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\Extract;
|
||||
use Chill\MainBundle\Doctrine\DQL\GetJsonFieldByKey;
|
||||
use Chill\MainBundle\Doctrine\DQL\Greatest;
|
||||
use Chill\MainBundle\Doctrine\DQL\JsonAggregate;
|
||||
use Chill\MainBundle\Doctrine\DQL\JsonbArrayLength;
|
||||
use Chill\MainBundle\Doctrine\DQL\JsonbExistsInArray;
|
||||
use Chill\MainBundle\Doctrine\DQL\JsonExtract;
|
||||
use Chill\MainBundle\Doctrine\DQL\Least;
|
||||
use Chill\MainBundle\Doctrine\DQL\OverlapsI;
|
||||
use Chill\MainBundle\Doctrine\DQL\Replace;
|
||||
use Chill\MainBundle\Doctrine\DQL\Similarity;
|
||||
@ -246,6 +248,8 @@ class ChillMainExtension extends Extension implements
|
||||
'JSONB_ARRAY_LENGTH' => JsonbArrayLength::class,
|
||||
'ST_X' => STX::class,
|
||||
'ST_Y' => STY::class,
|
||||
'GREATEST' => Greatest::class,
|
||||
'LEAST' => LEAST::class,
|
||||
],
|
||||
'datetime_functions' => [
|
||||
'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