Passed
Pull Request — 2.8.x (#8025)
by Benjamin
08:29
created

IdentityFunction::getSql()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 44
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 27
dl 0
loc 44
ccs 27
cts 27
cp 1
rs 8.8657
c 0
b 0
f 0
cc 6
nc 10
nop 1
crap 6
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\ORM\Query\AST\Functions;
21
22
use Doctrine\DBAL\Types\Type;
23
use Doctrine\ORM\Query\AST\PathExpression;
24
use Doctrine\ORM\Query\AST\TypedExpression;
25
use Doctrine\ORM\Query\Lexer;
26
use Doctrine\ORM\Query\Parser;
27
use Doctrine\ORM\Query\SqlWalker;
28
use Doctrine\ORM\Query\QueryException;
29
30
/**
31
 * "IDENTITY" "(" SingleValuedAssociationPathExpression {"," string} ")"
32
 *
33
 *
34
 * @link    www.doctrine-project.org
35
 * @since   2.2
36
 * @author  Guilherme Blanco <[email protected]>
37
 * @author  Benjamin Eberlei <[email protected]>
38
 */
39
class IdentityFunction extends FunctionNode implements TypedExpression
40
{
41
    /** @var PathExpression */
42
    public $pathExpression;
43
44
    /** @var string */
45
    public $fieldMapping;
46
47
    /** @var string */
48
    private $type;
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 9
    public function getSql(SqlWalker $sqlWalker)
54
    {
55 9
        $platform       = $sqlWalker->getEntityManager()->getConnection()->getDatabasePlatform();
56 9
        $quoteStrategy  = $sqlWalker->getEntityManager()->getConfiguration()->getQuoteStrategy();
57 9
        $dqlAlias       = $this->pathExpression->identificationVariable;
58 9
        $assocField     = $this->pathExpression->field;
59 9
        $qComp          = $sqlWalker->getQueryComponent($dqlAlias);
60 9
        $class          = $qComp['metadata'];
61 9
        $assoc          = $class->associationMappings[$assocField];
62 9
        $targetEntity   = $sqlWalker->getEntityManager()->getClassMetadata($assoc['targetEntity']);
63 9
        $joinColumn     = reset($assoc['joinColumns']);
64
65 9
        if ($this->fieldMapping !== null) {
66 2
            if ( ! isset($targetEntity->fieldMappings[$this->fieldMapping])) {
67 1
                throw new QueryException(sprintf('Undefined reference field mapping "%s"', $this->fieldMapping));
68
            }
69
70 2
            $field      = $targetEntity->fieldMappings[$this->fieldMapping];
71 2
            $this->type = $field['type'];
72 2
            $joinColumn = null;
73
74 2
            foreach ($assoc['joinColumns'] as $mapping) {
75
76 2
                if ($mapping['referencedColumnName'] === $field['columnName']) {
77 2
                    $joinColumn = $mapping;
78
79 2
                    break;
80
                }
81
            }
82
83 2
            if ($joinColumn === null) {
84 2
                throw new QueryException(sprintf('Unable to resolve the reference field mapping "%s"', $this->fieldMapping));
85
            }
86
        } else {
87 7
            $this->type = $targetEntity->fieldMappings[$targetEntity->getSingleIdentifierFieldName()]['type'];
88
        }
89
90
        // The table with the relation may be a subclass, so get the table name from the association definition
91 9
        $tableName = $sqlWalker->getEntityManager()->getClassMetadata($assoc['sourceEntity'])->getTableName();
92
93 9
        $tableAlias = $sqlWalker->getSQLTableAlias($tableName, $dqlAlias);
94 9
        $columnName  = $quoteStrategy->getJoinColumnName($joinColumn, $targetEntity, $platform);
95
96 9
        return $tableAlias . '.' . $columnName;
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102 9
    public function parse(Parser $parser)
103
    {
104 9
        $parser->match(Lexer::T_IDENTIFIER);
105 9
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
106
107 9
        $this->pathExpression = $parser->SingleValuedAssociationPathExpression();
108
109 9
        if ($parser->getLexer()->isNextToken(Lexer::T_COMMA)) {
110 2
            $parser->match(Lexer::T_COMMA);
111 2
            $parser->match(Lexer::T_STRING);
112
113 2
            $this->fieldMapping = $parser->getLexer()->token['value'];
114
        }
115
116 9
        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
117 9
    }
118
119 6
    public function getReturnType() : Type
120
    {
121 6
        return Type::getType($this->type);
122
    }
123
}
124