Completed
Push — master ( a9ee46...8f8263 )
by Beniamin
02:34
created

QueryCompiler   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 213
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 4
dl 0
loc 213
ccs 70
cts 70
cp 1
rs 9.2
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A compile() 0 4 1
A compileRaw() 0 18 1
A compileReferences() 0 4 1
A compileInsert() 0 8 2
A compileUpdate() 0 8 3
A compileSelect() 0 8 2
A compileSet() 0 8 3
A compileWhere() 0 8 3
A compileGroupBy() 0 10 4
A compileHaving() 0 8 3
A compileOrderBy() 0 8 3
A compileLimit() 0 8 3
A compileInsertValues() 0 10 2
A compileInsertColumns() 0 8 2
1
<?php
2
3
/**
4
 * This file is part of Phuria SQL Builder package.
5
 *
6
 * Copyright (c) 2016 Beniamin Jonatan Šimko
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Phuria\SQLBuilder\QueryCompiler;
13
14
use Phuria\SQLBuilder\Parser\ReferenceParser;
15
use Phuria\SQLBuilder\QueryBuilder\AbstractBuilder;
16
use Phuria\SQLBuilder\QueryBuilder\Clause;
17
use Phuria\SQLBuilder\QueryBuilder\Component;
18
use Phuria\SQLBuilder\QueryBuilder\InsertBuilder;
19
use Phuria\SQLBuilder\QueryBuilder\UpdateBuilder;
20
21
/**
22
 * @author Beniamin Jonatan Šimko <[email protected]>
23
 */
24
class QueryCompiler implements QueryCompilerInterface
25
{
26
    /**
27
     * @var TableCompiler
28
     */
29
    private $tableCompiler;
30
31 32
    public function __construct()
32
    {
33 32
        $this->tableCompiler = new TableCompiler();
34 32
    }
35
36
    /**
37
     * @inheritdoc
38
     */
39 29
    public function compile(AbstractBuilder $qb)
40
    {
41 29
        return $this->compileReferences($this->compileRaw($qb), $qb);
42
    }
43
44
    /**
45
     * @param AbstractBuilder $qb
46
     *
47
     * @return string
48
     */
49 29
    private function compileRaw(AbstractBuilder $qb)
50
    {
51 29
        return implode(' ', array_filter([
52 29
            $this->compileInsert($qb),
53 29
            $this->compileUpdate($qb),
54 29
            $this->compileSelect($qb),
55 29
            $this->tableCompiler->compileRootTables($qb),
56 29
            $this->tableCompiler->compileJoinTables($qb),
57 29
            $this->compileInsertColumns($qb),
58 29
            $this->compileSet($qb),
59 29
            $this->compileWhere($qb),
60 29
            $this->compileInsertValues($qb),
61 29
            $this->compileGroupBy($qb),
62 29
            $this->compileHaving($qb),
63 29
            $this->compileOrderBy($qb),
64 29
            $this->compileLimit($qb)
65 29
        ]));
66
    }
67
68
    /**
69
     * @param string          $rawSQL
70
     * @param AbstractBuilder $qb
71
     *
72
     * @return string
73
     */
74 29
    private function compileReferences($rawSQL, AbstractBuilder $qb)
75
    {
76 29
        return (new ReferenceParser($rawSQL, $qb->getReferenceManager()))->parseSQL();
77
    }
78
79
    /**
80
     * @param AbstractBuilder $qb
81
     *
82
     * @return string
83
     */
84 29
    private function compileInsert(AbstractBuilder $qb)
85
    {
86 29
        if ($qb instanceof InsertBuilder) {
87 1
            return 'INSERT';
88
        }
89
90 28
        return '';
91
    }
92
93
    /**
94
     * @param AbstractBuilder $qb
95
     *
96
     * @return string
97
     */
98 29
    private function compileUpdate(AbstractBuilder $qb)
99
    {
100 29
        if ($qb instanceof UpdateBuilder) {
101 4
            return $qb->isIgnore() ? 'UPDATE IGNORE' : 'UPDATE';
102
        }
103
104 25
        return '';
105
    }
106
107
    /**
108
     * @param AbstractBuilder $qb
109
     *
110
     * @return string
111
     */
112 29
    private function compileSelect(AbstractBuilder $qb)
113
    {
114 29
        if ($qb instanceof Clause\SelectClauseInterface) {
115 24
            return 'SELECT ' . implode(', ', $qb->getSelectClauses());
116
        }
117
118 5
        return '';
119
    }
120
121
    /**
122
     * @param AbstractBuilder $qb
123
     *
124
     * @return string
125
     */
126 29
    private function compileSet(AbstractBuilder $qb)
127
    {
128 29
        if ($qb instanceof Clause\SetClauseInterface && $qb->getSetClauses()) {
129 4
            return 'SET ' . implode(', ', $qb->getSetClauses());
130
        }
131
132 25
        return '';
133
    }
134
135
    /**
136
     * @param AbstractBuilder $qb
137
     *
138
     * @return string
139
     */
140 29
    private function compileWhere(AbstractBuilder $qb)
141
    {
142 29
        if ($qb instanceof Clause\WhereClauseInterface && $qb->getWhereClauses()) {
143 7
            return 'WHERE ' . implode(' AND ', $qb->getWhereClauses());
144
        }
145
146 22
        return '';
147
    }
148
149
    /**
150
     * @param AbstractBuilder $qb
151
     *
152
     * @return string
153
     */
154 29
    private function compileGroupBy(AbstractBuilder $qb)
155
    {
156 29
        if ($qb instanceof Clause\GroupByClauseInterface && $qb->getGroupByClauses()) {
157 4
            $clause = 'GROUP BY ' . implode(', ', $qb->getGroupByClauses());
158
159 4
            return $qb->isGroupByWithRollUp() ? $clause . ' WITH ROLLUP' : $clause;
160
        }
161
162 26
        return '';
163
    }
164
165
    /**
166
     * @param AbstractBuilder $qb
167
     *
168
     * @return string
169
     */
170 29
    private function compileHaving(AbstractBuilder $qb)
171
    {
172 29
        if ($qb instanceof Clause\HavingClauseInterface && $qb->getHavingClauses()) {
173 1
            return 'HAVING ' . implode(' AND ', $qb->getHavingClauses());
174
        }
175
176 28
        return '';
177
    }
178
179
    /**
180
     * @param AbstractBuilder $qb
181
     *
182
     * @return string
183
     */
184 29
    private function compileOrderBy(AbstractBuilder $qb)
185
    {
186 29
        if ($qb instanceof Clause\OrderByClauseInterface && $qb->getOrderByClauses()) {
187 2
            return 'ORDER BY ' . implode(', ', $qb->getOrderByClauses());
188
        }
189
190 27
        return '';
191
    }
192
193
    /**
194
     * @param AbstractBuilder $qb
195
     *
196
     * @return string
197
     */
198 29
    private function compileLimit(AbstractBuilder $qb)
199
    {
200 29
        if ($qb instanceof Clause\LimitClauseInterface && $qb->getLimitClause()) {
201 2
            return 'LIMIT ' . $qb->getLimitClause();
202
        }
203
204 27
        return '';
205
    }
206
207
    /**
208
     * @param AbstractBuilder $qb
209
     *
210
     * @return string
211
     */
212 29
    private function compileInsertValues(AbstractBuilder $qb)
213
    {
214 29
        if ($qb instanceof Component\InsertValuesComponentInterface) {
215 1
            return 'VALUES ' . implode(', ', array_map(function (array $values) {
216 1
                return '('. implode(', ', $values) . ')';
217 1
            }, $qb->getValues()));
218
        }
219
220 28
        return '';
221
    }
222
223
    /**
224
     * @param AbstractBuilder $qb
225
     *
226
     * @return string
227
     */
228 29
    private function compileInsertColumns(AbstractBuilder $qb)
229
    {
230 29
        if ($qb instanceof Clause\InsertColumnsClauseInterface) {
231 1
            return '(' . implode(', ', $qb->getColumns()) . ')';
232
        }
233
234 28
        return '';
235
    }
236
}