Completed
Pull Request — master (#37)
by Oleksii
07:28
created

DoctrineQueryBuilderVisitor::reset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace RulerZ\Compiler\Target\Sql;
4
5
use Doctrine\ORM\QueryBuilder;
6
use Hoa\Ruler\Model as AST;
7
use RulerZ\Model;
8
9
class DoctrineQueryBuilderVisitor extends GenericSqlVisitor
10
{
11
    /**
12
     * The root alias used by the query builder.
13
     */
14
    const ROOT_ALIAS_PLACEHOLDER = '@@_ROOT_ALIAS_@@';
15
16
    /**
17
     * @var array
18
     */
19
    private $detectedJoins = [];
20
21
    /**
22
     * {@inheritdoc}
23
     */
24
    public function compile(Model\Rule $rule)
25
    {
26
        $executor = parent::compile($rule);
27
        $this->reset();
28
29
        return $executor;
30
    }
31
32
    /**
33
     * @inheritDoc
34
     */
35
    public function supports($target, $mode)
36
    {
37
        return $target instanceof QueryBuilder;
38
    }
39
40
    /**
41
     * @inheritDoc
42
     */
43
    protected function getExecutorTraits()
44
    {
45
        return [
46
            '\RulerZ\Executor\DoctrineQueryBuilder\FilterTrait',
47
            '\RulerZ\Executor\DoctrineQueryBuilder\AutoJoinTrait',
48
            '\RulerZ\Executor\Polyfill\FilterBasedSatisfaction',
49
        ];
50
    }
51
52
    /**
53
     * @inheritDoc
54
     */
55
    protected function getCompilationData()
56
    {
57
        return [
58
            'detectedJoins' => $this->detectedJoins,
59
        ];
60
    }
61
62
    /**
63
     * {@inheritDoc}
64
     */
65
    public function visitModel(AST\Model $element, &$handle = null, $eldnah = null)
66
    {
67
        $dql = parent::visitModel($element, $handle, $eldnah);
68
69
        return '"' . $dql . '"';
70
    }
71
72
    /**
73
     * {@inheritDoc}
74
     */
75
    public function visitAccess(AST\Bag\Context $element, &$handle = null, $eldnah = null)
76
    {
77
        $dimensions = $element->getDimensions();
78
79
        // simple column access
80
        if (count($dimensions) === 0) {
81
            return sprintf('%s.%s', self::ROOT_ALIAS_PLACEHOLDER, parent::visitAccess($element, $handle, $eldnah));
82
        }
83
84
        // this is the real column that we are trying to access
85
        $finalColumn = array_pop($dimensions)[1];
86
87
        // and this is a list of tables that need to be joined
88
        $tablesToJoin = array_map(function ($dimension) {
89
            return $dimension[1];
90
        }, $dimensions);
91
        $tablesToJoin = array_merge([$element->getId()], $tablesToJoin);
92
93
        $this->detectedJoins[] = $tablesToJoin;
94
95
        return sprintf('" . $this->getJoinAlias($target, "%s", "%s") . ".%s', end($tablesToJoin), implode('.', $tablesToJoin), $finalColumn);
96
    }
97
98
    /**
99
     * {@inheritDoc}
100
     */
101
    public function visitParameter(Model\Parameter $element, &$handle = null, $eldnah = null)
102
    {
103
        // make it a placeholder
104
        return ':' . $element->getName();
105
    }
106
107
    protected function reset()
108
    {
109
        $this->detectedJoins = [];
110
    }
111
}
112