106 lines
2.6 KiB
PHP

<?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\PathExpression;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Exception;
/**
* DQL function for OVERLAPS function in postgresql.
*
* If a value is null in period start, it will be replaced by -infinity.
* If a value is null in period end, it will be replaced by infinity
*/
class OverlapsI extends FunctionNode
{
private $firstPeriodEnd;
private $firstPeriodStart;
private $secondPeriodEnd;
private $secondPeriodStart;
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return sprintf(
'(%s, %s) OVERLAPS (%s, %s)',
$this->makeCase($sqlWalker, $this->firstPeriodStart, 'start'),
$this->makeCase($sqlWalker, $this->firstPeriodEnd, 'end'),
$this->makeCase($sqlWalker, $this->secondPeriodStart, 'start'),
$this->makeCase($sqlWalker, $this->secondPeriodEnd, 'end')
);
}
public function parse(Parser $parser): void
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->firstPeriodStart = $parser->StringPrimary();
$parser->match(Lexer::T_COMMA);
$this->firstPeriodEnd = $parser->StringPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
$parser->match(Lexer::T_COMMA);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->secondPeriodStart = $parser->StringPrimary();
$parser->match(Lexer::T_COMMA);
$this->secondPeriodEnd = $parser->StringPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
protected function makeCase($sqlWalker, $part, string $position): string
{
switch ($position) {
case 'start':
$p = '-infinity';
break;
case 'end':
$p = 'infinity';
break;
default:
throw new Exception('Unexpected position value.');
}
if ($part instanceof PathExpression) {
return sprintf(
"COALESCE(%s, '%s'::date)",
$part->dispatch($sqlWalker),
$p
);
}
return sprintf(
"COALESCE(%s::date, '%s'::date)",
$part->dispatch($sqlWalker),
$p
);
}
}