Completed
Push — master ( b54f87...bde51f )
by Beniamin
04:50
created

QueryCompiler::compileReferences()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 1
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\SelectBuilder;
20
use Phuria\SQLBuilder\QueryBuilder\UpdateBuilder;
21
use Phuria\SQLBuilder\Table\AbstractTable;
22
23
/**
24
 * @author Beniamin Jonatan Šimko <[email protected]>
25
 */
26
class QueryCompiler implements QueryCompilerInterface
27
{
28
    /**
29
     * @inheritdoc
30
     */
31 27
    public function compile(AbstractBuilder $qb)
32
    {
33 27
        return $this->compileReferences($this->compileRaw($qb), $qb);
34
    }
35
36
    /**
37
     * @param AbstractBuilder $qb
38
     *
39
     * @return string
40
     */
41 27
    private function compileRaw(AbstractBuilder $qb)
42
    {
43 27
        return implode(' ', array_filter([
44 27
            $this->compileInsert($qb),
45 27
            $this->compileUpdate($qb),
46 27
            $this->compileSelect($qb),
47 27
            $this->compileRootTables($qb),
48 27
            $this->compileJoinTables($qb),
49 27
            $this->compileInsertColumns($qb),
50 27
            $this->compileSet($qb),
51 27
            $this->compileWhere($qb),
52 27
            $this->compileInsertValues($qb),
53 27
            $this->compileGroupBy($qb),
54 27
            $this->compileHaving($qb),
55 27
            $this->compileOrderBy($qb),
56 27
            $this->compileLimit($qb)
57 27
        ]));
58
    }
59
60
    /**
61
     * @param string          $rawSQL
62
     * @param AbstractBuilder $qb
63
     *
64
     * @return string
65
     */
66 27
    private function compileReferences($rawSQL, AbstractBuilder $qb)
67
    {
68 27
        return (new ReferenceParser($rawSQL, $qb->getReferenceManager()))->parseSQL();
69
    }
70
71
    /**
72
     * @param AbstractBuilder $qb
73
     *
74
     * @return string
75
     */
76 27
    private function compileInsert(AbstractBuilder $qb)
77
    {
78 27
        if ($qb instanceof InsertBuilder) {
79 1
            return 'INSERT';
80
        }
81
82 26
        return '';
83
    }
84
85
    /**
86
     * @param AbstractBuilder $qb
87
     *
88
     * @return string
89
     */
90 27
    private function compileUpdate(AbstractBuilder $qb)
91
    {
92 27
        if ($qb instanceof UpdateBuilder) {
93 4
            return $qb->isIgnore() ? 'UPDATE IGNORE' : 'UPDATE';
94
        }
95
96 23
        return '';
97
    }
98
99
    /**
100
     * @param AbstractBuilder $qb
101
     *
102
     * @return string
103
     */
104 27
    private function compileSelect(AbstractBuilder $qb)
105
    {
106 27
        if ($qb instanceof Clause\SelectClauseInterface) {
107 22
            return 'SELECT ' . implode(', ', $qb->getSelectClauses());
108
        }
109
110 5
        return '';
111
    }
112
113
    /**
114
     * @param AbstractBuilder $qb
115
     *
116
     * @return string
117
     */
118 27
    private function compileSet(AbstractBuilder $qb)
119
    {
120 27
        if ($qb instanceof Clause\SetClauseInterface && $qb->getSetClauses()) {
121 4
            return 'SET ' . implode(', ', $qb->getSetClauses());
122
        }
123
124 23
        return '';
125
    }
126
127
    /**
128
     * @param AbstractBuilder $qb
129
     *
130
     * @return string
131
     */
132 27
    private function compileWhere(AbstractBuilder $qb)
133
    {
134 27
        if ($qb instanceof Clause\WhereClauseInterface && $qb->getWhereClauses()) {
135 7
            return 'WHERE ' . implode(' AND ', $qb->getWhereClauses());
136
        }
137
138 20
        return '';
139
    }
140
141
    /**
142
     * @param AbstractBuilder $qb
143
     *
144
     * @return string
145
     */
146 27
    private function compileGroupBy(AbstractBuilder $qb)
147
    {
148 27
        if ($qb instanceof Clause\GroupByClauseInterface && $qb->getGroupByClauses()) {
149 3
            return 'GROUP BY ' . implode(', ', $qb->getGroupByClauses());
150
        }
151
152 25
        return '';
153
    }
154
155
    /**
156
     * @param AbstractBuilder $qb
157
     *
158
     * @return string
159
     */
160 27
    private function compileHaving(AbstractBuilder $qb)
161
    {
162 27
        if ($qb instanceof Clause\HavingClauseInterface && $qb->getHavingClauses()) {
163 1
            return 'HAVING ' . implode(' AND ', $qb->getHavingClauses());
164
        }
165
166 26
        return '';
167
    }
168
169
    /**
170
     * @param AbstractBuilder $qb
171
     *
172
     * @return string
173
     */
174 27
    private function compileOrderBy(AbstractBuilder $qb)
175
    {
176 27
        if ($qb instanceof Clause\OrderByClauseInterface && $qb->getOrderByClauses()) {
177 2
            return 'ORDER BY ' . implode(', ', $qb->getOrderByClauses());
178
        }
179
180 25
        return '';
181
    }
182
183
    /**
184
     * @param AbstractBuilder $qb
185
     *
186
     * @return string
187
     */
188 27
    private function compileLimit(AbstractBuilder $qb)
189
    {
190 27
        if ($qb instanceof Clause\LimitClauseInterface && $qb->getLimitClause()) {
191 2
            return 'LIMIT ' . $qb->getLimitClause();
192
        }
193
194 25
        return '';
195
    }
196
197
    /**
198
     * @param AbstractBuilder $qb
199
     *
200
     * @return string
201
     */
202 27
    private function compileRootTables(AbstractBuilder $qb)
203
    {
204 27
        $rootTables = '';
205
206 27
        if ($qb instanceof SelectBuilder) {
207 22
            $rootTables .= 'FROM ';
208 22
        }
209
210 27
        if ($qb instanceof Component\TableComponentInterface && $qb->getRootTables()) {
211 26
            $rootTables .= implode(', ', array_map([$this, 'compileTableDeclaration'], $qb->getRootTables()));
212 26
        } else {
213 1
            return '';
214
        }
215
216 26
        return $rootTables;
217
    }
218
219
    /**
220
     * @param AbstractBuilder $qb
221
     *
222
     * @return string
223
     */
224 27
    private function compileJoinTables(AbstractBuilder $qb)
225
    {
226 27
        if ($qb instanceof Component\JoinComponentInterface) {
227 22
            return implode(' ', array_map([$this, 'compileTableDeclaration'], $qb->getJoinTables()));
228
        }
229
230 5
        return '';
231
    }
232
233
    /**
234
     * @param AbstractBuilder $qb
235
     *
236
     * @return string
237
     */
238 27
    private function compileInsertValues(AbstractBuilder $qb)
239
    {
240 27
        if ($qb instanceof Component\InsertValuesComponentInterface) {
241 1
            return 'VALUES ' . implode(', ', array_map(function (array $values) {
242 1
                return '('. implode(', ', $values) . ')';
243 1
            }, $qb->getValues()));
244
        }
245
246 26
        return '';
247
    }
248
249
    /**
250
     * @param AbstractBuilder $qb
251
     *
252
     * @return string
253
     */
254 27
    private function compileInsertColumns(AbstractBuilder $qb)
255
    {
256 27
        if ($qb instanceof Clause\InsertColumnsClauseInterface) {
257 1
            return '(' . implode(', ', $qb->getColumns()) . ')';
258
        }
259
260 26
        return '';
261
    }
262
263
    /**
264
     * @param AbstractTable $table
265
     *
266
     * @return string
267
     */
268 26
    private function compileTableDeclaration(AbstractTable $table)
269
    {
270 26
        $declaration = '';
271
272 26
        if ($table->isJoin()) {
273 3
            $declaration .= $table->getJoinType() . ' ';
274 3
        }
275
276 26
        $declaration .= $table->getTableName();
277
278 26
        if ($alias = $table->getAlias()) {
279 8
            $declaration .= ' AS ' . $alias;
280 8
        }
281
282 26
        if ($joinOn = $table->getJoinOn()) {
283 2
            $declaration .= ' ON ' . $joinOn;
284 2
        }
285
286 26
        return $declaration;
287
    }
288
}