Passed
Push — main ( 007e1f...4fda4a )
by Martin
02:07
created

Cast::getSql()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6
7
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
8
use Doctrine\ORM\Query\AST\Node;
9
use Doctrine\ORM\Query\Lexer;
10
use Doctrine\ORM\Query\Parser;
11
use Doctrine\ORM\Query\SqlWalker;
12
13
/**
14
 * Implementation of PostgreSql CAST().
15
 *
16
 * @see https://www.postgresql.org/docs/current/sql-createcast.html
17
 * @see https://github.com/beberlei/DoctrineExtensions/blob/f3536d881637f6ddc7ca1d6595d18c15e06eb1d9/src/Query/Mysql/Cast.php
18
 * @since 2.0.0
19
 *
20
 * @author Mathieu Piot <https://github.com/mpiot>
21
 */
22
class Cast extends FunctionNode
23
{
24
    public Node $sourceType;
25
26
    public string $targetType;
27
28
    public function parse(Parser $parser): void
29
    {
30
        $parser->match(Lexer::T_IDENTIFIER);
0 ignored issues
show
Bug introduced by
Doctrine\ORM\Query\Lexer::T_IDENTIFIER of type integer is incompatible with the type Doctrine\ORM\Query\Lexer expected by parameter $token of Doctrine\ORM\Query\Parser::match(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

30
        $parser->match(/** @scrutinizer ignore-type */ Lexer::T_IDENTIFIER);
Loading history...
31
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
32
        $this->sourceType = $parser->SimpleArithmeticExpression();
33
        $parser->match(Lexer::T_AS);
34
        $parser->match(Lexer::T_IDENTIFIER);
35
36
        $lexer = $parser->getLexer();
37
        $token = $lexer->token;
38
        if (!isset($token['value'])) {
39
            return;
40
        }
41
        if (!\is_string($token['value'])) {
42
            return;
43
        }
44
45
        $type = $token['value'];
46
        if ($lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
0 ignored issues
show
Bug introduced by
Doctrine\ORM\Query\Lexer::T_OPEN_PARENTHESIS of type integer is incompatible with the type Doctrine\Common\Lexer\T expected by parameter $type of Doctrine\Common\Lexer\AbstractLexer::isNextToken(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

46
        if ($lexer->isNextToken(/** @scrutinizer ignore-type */ Lexer::T_OPEN_PARENTHESIS)) {
Loading history...
47
            $parser->match(Lexer::T_OPEN_PARENTHESIS);
48
            $parameter = $parser->Literal();
49
            $parameters = [$parameter->value];
50
            if ($lexer->isNextToken(Lexer::T_COMMA)) {
51
                while ($lexer->isNextToken(Lexer::T_COMMA)) {
52
                    $parser->match(Lexer::T_COMMA);
53
                    $parameter = $parser->Literal();
54
                    $parameters[] = $parameter->value;
55
                }
56
            }
57
            $parser->match(Lexer::T_CLOSE_PARENTHESIS);
58
            $type .= '('.\implode(', ', $parameters).')';
59
        }
60
61
        $this->targetType = $type;
62
63
        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
64
    }
65
66
    public function getSql(SqlWalker $sqlWalker): string
67
    {
68
        return \sprintf('cast(%s as %s)', $this->sourceType->dispatch($sqlWalker), $this->targetType);
69
    }
70
}
71