WhereWriter::writeWhereIns()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 7
rs 9.4286
cc 1
eloc 4
nc 1
nop 2
1
<?php
2
3
namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
4
5
use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
6
use NilPortugues\Sql\QueryBuilder\Syntax\Column;
7
use NilPortugues\Sql\QueryBuilder\Syntax\SyntaxFactory;
8
use NilPortugues\Sql\QueryBuilder\Syntax\Where;
9
10
/**
11
 * Class WhereWriter.
12
 */
13
class WhereWriter extends AbstractBaseWriter
14
{
15
    /**
16
     * @var array
17
     */
18
    protected $matchMode = [
19
        'natural' => '(MATCH({{columnNames}}) AGAINST({{columnValues}}))',
20
        'boolean' => '(MATCH({{columnNames}}) AGAINST({{columnValues}} IN BOOLEAN MODE))',
21
        'query_expansion' => '(MATCH({{columnNames}}) AGAINST({{columnValues}} WITH QUERY EXPANSION))',
22
    ];
23
24
    /**
25
     * @param Where $where
26
     *
27
     * @return string
28
     */
29
    public function writeWhere(Where $where)
30
    {
31
        $clauses = $this->writeWhereClauses($where);
32
        $clauses = \array_filter($clauses);
33
34
        if (empty($clauses)) {
35
            return '';
36
        }
37
38
        return \implode($this->writer->writeConjunction($where->getConjunction()), $clauses);
39
    }
40
41
    /**
42
     * @param Where $where
43
     *
44
     * @return array
45
     */
46
    public function writeWhereClauses(Where $where)
47
    {
48
        $whereArray = [];
49
50
        $this->writeWhereMatches($where, $whereArray);
51
        $this->writeWhereIns($where, $whereArray);
52
        $this->writeWhereNotIns($where, $whereArray);
53
        $this->writeWhereBetweens($where, $whereArray);
54
        $this->writeWhereComparisons($where, $whereArray);
55
        $this->writeWhereIsNulls($where, $whereArray);
56
        $this->writeWhereIsNotNulls($where, $whereArray);
57
        $this->writeWhereBooleans($where, $whereArray);
58
        $this->writeExists($where, $whereArray);
59
        $this->writeNotExists($where, $whereArray);
60
        $this->writeSubWheres($where, $whereArray);
61
62
        return $whereArray;
63
    }
64
65
    /**
66
     * @param Where $where
67
     * @param array $whereArray
68
     *
69
     * @return array
70
     */
71
    protected function writeWhereMatches(Where $where, array &$whereArray)
72
    {
73
        $matches = [];
74
75
        foreach ($where->getMatches() as $values) {
76
            $columns = SyntaxFactory::createColumns($values['columns'], $where->getTable());
77
            $columnNames = $this->getColumnNames($columns);
78
79
            $columnValues = array(\implode(' ', $values['values']));
80
            $columnValues = \implode(', ', $this->writer->writeValues($columnValues));
81
82
            $matches[] = \str_replace(
83
                ['{{columnNames}}', '{{columnValues}}'],
84
                [$columnNames, $columnValues],
85
                $this->matchMode[$values['mode']]
86
            );
87
        }
88
89
        $whereArray = \array_merge($whereArray, $matches);
90
    }
91
92
    /**
93
     * @param $columns
94
     *
95
     * @return string
96
     */
97
    protected function getColumnNames($columns)
98
    {
99
        $columnNames = [];
100
        foreach ($columns as &$column) {
101
            $columnNames[] = $this->columnWriter->writeColumn($column);
102
        }
103
104
        return \implode(', ', $columnNames);
105
    }
106
107
    /**
108
     * @param Where $where
109
     * @param array $whereArray
110
     *
111
     * @return array
112
     */
113
    protected function writeWhereIns(Where $where, array &$whereArray)
114
    {
115
        $whereArray = \array_merge(
116
            $whereArray,
117
            $this->writeWhereIn($where, 'getIns', 'IN')
118
        );
119
    }
120
121
    /**
122
     * @param Where  $where
123
     * @param string $method
124
     * @param string $operation
125
     *
126
     * @return array
127
     */
128
    protected function writeWhereIn(Where $where, $method, $operation)
129
    {
130
        $collection = [];
131
132
        foreach ($where->$method() as $column => $values) {
133
            $newColumn = array($column);
134
            $column = SyntaxFactory::createColumn($newColumn, $where->getTable());
135
            $column = $this->columnWriter->writeColumn($column);
136
137
            $values = $this->writer->writeValues($values);
138
            $values = \implode(', ', $values);
139
140
            $collection[] = "({$column} $operation ({$values}))";
141
        }
142
143
        return $collection;
144
    }
145
146
    /**
147
     * @param Where $where
148
     * @param array $whereArray
149
     *
150
     * @return array
151
     */
152
    protected function writeWhereNotIns(Where $where, array &$whereArray)
153
    {
154
        $whereArray = \array_merge(
155
            $whereArray,
156
            $this->writeWhereIn($where, 'getNotIns', 'NOT IN')
157
        );
158
    }
159
160
    /**
161
     * @param Where $where
162
     * @param array $whereArray
163
     *
164
     * @return array
165
     */
166
    protected function writeWhereBetweens(Where $where, array &$whereArray)
167
    {
168
        $between = $where->getBetweens();
169
        \array_walk(
170
            $between,
171
            function (&$between) {
172
173
                $between = '('
174
                    .$this->columnWriter->writeColumn($between['subject'])
175
                    .' BETWEEN '
176
                    .$this->writer->writePlaceholderValue($between['a'])
177
                    .' AND '
178
                    .$this->writer->writePlaceholderValue($between['b'])
179
                    .')';
180
            }
181
        );
182
183
        $whereArray = \array_merge($whereArray, $between);
184
    }
185
186
    /**
187
     * @param Where $where
188
     * @param array $whereArray
189
     *
190
     * @return array
191
     */
192
    protected function writeWhereComparisons(Where $where, array &$whereArray)
193
    {
194
        $comparisons = $where->getComparisons();
195
        \array_walk(
196
            $comparisons,
197
            function (&$comparison) {
198
199
                if (!is_array($comparison)) {
200
                    return;
201
                }
202
203
                $str = $this->writeWherePartialCondition($comparison['subject']);
204
                $str .= $this->writer->writeConjunction($comparison['conjunction']);
205
                $str .= $this->writeWherePartialCondition($comparison['target']);
206
207
                $comparison = "($str)";
208
            }
209
        );
210
211
        $whereArray = \array_merge($whereArray, $comparisons);
212
    }
213
214
    /**
215
     * @param $subject
216
     *
217
     * @return string
218
     */
219
    protected function writeWherePartialCondition(&$subject)
220
    {
221
        if ($subject instanceof Column) {
222
            $str = $this->columnWriter->writeColumn($subject);
223
        } elseif ($subject instanceof Select) {
224
            $selectWriter = WriterFactory::createSelectWriter($this->writer, $this->placeholderWriter);
225
            $str = '('.$selectWriter->write($subject).')';
226
        } else {
227
            $str = $this->writer->writePlaceholderValue($subject);
228
        }
229
230
        return $str;
231
    }
232
233
    /**
234
     * @param Where $where
235
     * @param array $whereArray
236
     *
237
     * @return array
238
     */
239
    protected function writeWhereIsNulls(Where $where, array &$whereArray)
240
    {
241
        $whereArray = \array_merge(
242
            $whereArray,
243
            $this->writeWhereIsNullable($where, 'getNull', 'writeIsNull')
244
        );
245
    }
246
247
    /**
248
     * @param Where  $where
249
     * @param string $getMethod
250
     * @param string $writeMethod
251
     *
252
     * @return array
253
     */
254
    protected function writeWhereIsNullable(Where $where, $getMethod, $writeMethod)
255
    {
256
        $collection = $where->$getMethod();
257
258
        \array_walk(
259
            $collection,
260
            function (&$collection) use ($writeMethod) {
261
                $collection =
262
                    '('.$this->columnWriter->writeColumn($collection['subject'])
263
                    .$this->writer->$writeMethod().')';
264
            }
265
        );
266
267
        return $collection;
268
    }
269
270
    /**
271
     * @param Where $where
272
     * @param array $whereArray
273
     *
274
     * @return array
275
     */
276
    protected function writeWhereIsNotNulls(Where $where, array &$whereArray)
277
    {
278
        $whereArray = \array_merge(
279
            $whereArray,
280
            $this->writeWhereIsNullable($where, 'getNotNull', 'writeIsNotNull')
281
        );
282
    }
283
284
    /**
285
     * @param Where $where
286
     * @param array $whereArray
287
     *
288
     * @return array
289
     */
290
    protected function writeWhereBooleans(Where $where, array &$whereArray)
291
    {
292
        $booleans = $where->getBooleans();
293
        $placeholderWriter = $this->placeholderWriter;
294
295
        \array_walk(
296
            $booleans,
297
            function (&$boolean) use (&$placeholderWriter) {
298
                $column = $this->columnWriter->writeColumn($boolean['subject']);
299
                $value = $this->placeholderWriter->add($boolean['value']);
300
301
                $boolean = '(ISNULL('.$column.', 0) = '.$value.')';
302
            }
303
        );
304
305
        $whereArray = \array_merge($whereArray, $booleans);
306
    }
307
308
    /**
309
     * @param Where $where
310
     * @param array $whereArray
311
     *
312
     * @return array
313
     */
314
    protected function writeExists(Where $where, array &$whereArray)
315
    {
316
        $whereArray = \array_merge(
317
            $whereArray,
318
            $this->writeExistence($where, 'getExists', 'EXISTS')
319
        );
320
    }
321
322
    /**
323
     * @param Where  $where
324
     * @param string $method
325
     * @param string $operation
326
     *
327
     * @return array
328
     */
329
    protected function writeExistence(Where $where, $method, $operation)
330
    {
331
        $exists = [];
332
333
        foreach ($where->$method() as $select) {
334
            $exists[] = "$operation (".$this->writer->write($select, false).')';
335
        }
336
337
        return $exists;
338
    }
339
340
    /**
341
     * @param Where $where
342
     * @param array $whereArray
343
     *
344
     * @return array
345
     */
346
    protected function writeNotExists(Where $where, array &$whereArray)
347
    {
348
        $whereArray = \array_merge(
349
            $whereArray,
350
            $this->writeExistence($where, 'getNotExists', 'NOT EXISTS')
351
        );
352
    }
353
354
    /**
355
     * @param Where $where
356
     * @param array $whereArray
357
     *
358
     * @return array
359
     */
360
    protected function writeSubWheres(Where $where, array &$whereArray)
361
    {
362
        $subWheres = $where->getSubWheres();
363
364
        \array_walk(
365
            $subWheres,
366
            function (&$subWhere) {
367
                $subWhere = "({$this->writeWhere($subWhere)})";
368
            }
369
        );
370
371
        $whereArray = \array_merge($whereArray, $subWheres);
372
    }
373
}
374