QueryTrait::find()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Doctrine DBAL Util package.
5
 *
6
 * (c) Jean-Bernard Addor
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 DoctrineDbalUtil\Connection;
13
14
trait QueryTrait
15
{
16
    use ConnectionAbstractTrait;
17
18 View Code Duplication
    public function getWhereAndTraversable($table, array $where)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
19
    // url/show
20
    {
21
        $qb = $this->getConnection()->createQueryBuilder();
22
23
        return $qb
24
            ->select('*')
25
            ->from($table)
26
            ->where(\call_user_func_array([$qb->expr(), 'andX'],
27
                array_map(
28
                    [$qb->expr(), 'eq'],
29
                    array_keys($where),
30
                    array_map([$qb, 'createNamedParameter'], array_values($where))
31
                )
32
            ))
33
            ->execute();
34
        // TODO: check if $stmt should be ->execute() like in getByUnique
35
    }
36
37
    public function findUniqueBy($table, array $where)
38
    {
39
        return $this->getByUnique($table, $where);
40
        // should check for unicity
41
    }
42
43
    public function findFirstBy($table, array $where)
44
    {
45
        return $this->getByUnique($table, $where);
46
        // return first result
47
    }
48
49
    public function findOneBy($table, array $where)
50
    {
51
        return $this->getByUnique($table, $where);
52
        // not clear, should return first result
53
    }
54
55
    public function find($table, array $where)
56
    {
57
        return $this->getByUnique($table, $where);
58
        // should search by id
59
    }
60
61
    public function getByUnique($table, array $where)
62
    {
63
        $qb = $this->getConnection()->createQueryBuilder();
64
65
        $stmt = $qb
66
            ->select('*')
67
            ->from($table)
68
            ->where(\call_user_func_array([$qb->expr(), 'andX'],
69
                array_map(
70
                    [$qb->expr(), 'eq'],
71
                    array_keys($where),
72
                    array_map([$qb, 'createNamedParameter'], array_values($where))
73
                )
74
            ))
75
            ->execute();
76
        if ($stmt->execute()) {
77
            while ($row = $stmt->fetch()) {
78
                return $row;
79
            }
80
        } else {
81
            die('tbS8k: '.basename(__FILE__)); // TODO
82
        }
83
        // TODO: check if something should be ended or close...
84
    }
85
86
    public function insert($table, array $insert)
87
    { // TODO: (SECURITY) assert $insert is an array DONE
88
        $this->getConnection()->insert($table, $insert);
89
        // The construct with the array triggers a prepared statement
90
    }
91
92
    /*
93
    public function insert_default_values($table) {
94
        $this->getConnection()->executeUpdate('INSERT INTO ' . $table . ' DEFAULT VALUES');
95
    }
96
    */
97
98
    public function lastInsertId(string $seqName = null)
99
    { // used?
100
        $this->getConnection()->lastInsertId($seqName);
101
    }
102
103
    public function updateUniqueBy($table, array $id, array $row, array $types = [])
104
    {
105
        return $this->updateByUnique($table, $id, $row, $types);
106
    }
107
108
    public function updateByUnique($table, array $id, array $row, array $types = [])
109
    { // TODO: assert unicity of index
110
        $qb = $this->getConnection()->createQueryBuilder(); // 110
111
        $qb->update($table)->where(\call_user_func_array([$qb->expr(), 'andX'],
112
            array_map(
113
                [$qb->expr(), 'eq'],
114
                array_keys($id),
115
                array_map([$qb, 'createNamedParameter'], array_values($id))
116
            )
117
        ));
118
        foreach ($row as $key => $value) {
119
            $qb->set($key, ':'.$key);
120
            if (\array_key_exists($key, $types)) {
121
                $qb->setParameter(':'.$key, $value, $types[$key]);
122
            } else {
123
                $qb->setParameter(':'.$key, $value);
124
            }
125
        } // 125
126
        $qb->execute();
127
    }
128
129 View Code Duplication
    public function deleteByUnique($table, array $id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
130
    { // TODO: assert unicity of index
131
        $qb = $this->getConnection()->createQueryBuilder();
132
133
        $qb
134
            ->delete($table)
135
            ->where(\call_user_func_array([$qb->expr(), 'andX'],
136
                array_map(
137
                    [$qb->expr(), 'eq'],
138
                    array_keys($id),
139
                    array_map([$qb, 'createNamedParameter'], array_values($id))
140
                )
141
            ))
142
            ->execute()
143
        ;
144
    }
145
146
    public function getManyToManyTraversable($base_table, $base_id, $link_base_id, $link_table, $link_distant_id, $distant_id, $distant_table, array $unique)
147
    // url/show
148
    {
149
        $qb = $this->getConnection()->createQueryBuilder(); // 149
150
        return $qb
151
            ->select('d.*', 'l.*') // TODO: name collision RISK: seems to that data with same column name is taken from second (may be not reliable)
152
            // ->select('d.*') // TODO: name collision RISK: seems to that data with same column name is taken from second (may be not reliable): to try...
153
            ->from($base_table, 'b')
154
            ->innerJoin('b', $link_table, 'l', 'b.'.$base_id.' = l.'.$link_base_id)
155
            ->innerJoin('l', $distant_table, 'd', 'l.'.$link_distant_id.' = d.'.$distant_id)
156
            // ->where('b.id = '.$queryBuilder->createPositionalParameter($id))
157
            ->where(\call_user_func_array([$qb->expr(), 'andX'],
158
                array_map(
159
                    [$qb->expr(), 'eq'],
160
                    array_map(function ($s) {return 'b.'.$s; }, array_keys($unique)),
161
                    array_map([$qb, 'createNamedParameter'], array_values($unique))
162
                )
163
            ))
164
            ->execute()
165
        ;
166
    }
167
168
    public function sqlarray2dbal(array $sqlTree, $qb)
169
    {
170
        // $conn = $this->getConnection();
171
        // $qb = $this->getConnection()->createQueryBuilder();
172
        // $qb = $conn->createQueryBuilder();
173
        // dump($sqlTree);
174
        foreach ($sqlTree as $key => $value) {
175
            /// dump($key, $value);
176
            switch ($key) {
177
                case 'select':
178
                    $qb->select($value);
179
                    break;
180
                case 'from':
181
                    if (1 !== \count($value)):
182
                        0 / 0; // TODO
183
                    endif;
184
                    $qb->from(array_keys($value)[0], array_values($value)[0]);
185
                    break;
186
                case 'where':
187
                    0 / 0; // TODO
188
                    break;
189
                case 'join':
190
                case 'innerJoin':
191
                    foreach ($value as    $key => $jvalue) {
192
                        if (1 !== \count($jvalue['table'])) {
193
                            0 / 0; // TODO
194
                        }
195
                        // dump          ($jvalue['from'], array_keys($jvalue['table'])[0], array_values($jvalue['table'])[0], $jvalue['on']);
196
                        $qb->innerJoin($jvalue['from'], array_keys($jvalue['table'])[0], array_values($jvalue['table'])[0], $jvalue['on']);
197
                    }
198
                    break;
199
                // default:
200
                    // echo "i n'est ni égal à 2, ni à 1, ni à 0";
201
            }
202
        } // 202
203
        return $qb;
204
    }
205
206
    public function getManyToManyWhereQueryBuilder($base_table, $base_id,
207
        $link_base_id, $link_table, $link_distant_id,
208
        $distant_id, $distant_table, array $where)
209
    {
210
        $qb = $this->getConnection()->createQueryBuilder(); // 210
211
        if (false) { // ----------------------------------------------------
212
            $qa0 = [
213
                'select' => 'base.*',
214
                'from' => [
215
                    $base_table => 'base',
216
                    $link_table => 'link',
217
                ],
218
                'where' => [
219
                    'and' => [
220
                        '=' => [
221
                            'base.'.$base_id,
222
                            'link.'.$link_base_id,
223
                        ],
224
                        '<' => [1, 2],
225
                    ],
226
                ],
227
            ];
228
            $qa1 = [
229
                'select' => 'base.*',
230
                'from' => [
231
                    $base_table => 'base',
232
                    'tablex' => ['alias' => 'x'],
233
                    'other' => [
234
                        'alias' => 'o',
235
                        'innerJoin' => [
236
                            'table' => [$link_table => 'link'],
237
                            'on' => [
238
                                '=' => [
239
                                    'base.'.$base_id,
240
                                    'link.'.$link_base_id,
241
                                ],
242
                            ],
243
                        ],
244
                    ],
245
                ],
246
                'innerJoin' => [
247
                    'base' => [
248
                        'table' => [$link_table => 'link'],
249
                        'on' => [
250
                            '=' => [
251
                                'base.'.$base_id,
252
                                'link.'.$link_base_id,
253
                            ],
254
                        ],
255
                    ],
256
                ],
257
                'innerJoin' => [
258
                    'from' => 'base',
259
                    'table' => [$link_table => 'link'],
260
                    'on' => [
261
                        '=' => [
262
                            'base.'.$base_id,
263
                            'link.'.$link_base_id,
264
                        ],
265
                    ],
266
                ],
267
                'where' => [
268
                    'and' => [
269
                        '=' => [1, 2],
270
                        '<' => [1, 2],
271
                    ],
272
                ],
273
            ];
274
            dump($qa0, $qa1);
275
            // TODO: make it constant (maybe for php7)
276
            // http://php.net/manual/en/language.constants.syntax.php
277
            // http://php.net/manual/en/language.oop5.constants.php    Class Constants
278
        } // 278
279
        $result = $this->sqlarray2dbal([
280
                'select' => 'base.*',
281
                'from' => [
282
                    $base_table => 'base',
283
                ],
284
                'innerJoin' => [
285
                    [
286
                        'from' => 'base',
287
                        'table' => [$link_table => 'link'],
288
                        'on' => 'base."'.$base_id.'" = link."'.$link_base_id.'"',
289
                    ],
290
                    [
291
                        'from' => 'link',
292
                        'table' => [$distant_table => 'distant'],
293
                        'on' => 'link."'.$link_distant_id.'" = distant."'.$distant_id.'"',
294
                    ],
295
                ],
296
            ], $qb)
297
            // ->select('base.*')
298
            // ->from($base_table, 'base')
299
            // ->innerJoin('base', '"' . $link_table . '"', 'link', 'base."' . $base_id . '" = link."' . $link_base_id . '"')
300
            // ->innerJoin('link', '"' . $distant_table . '"', 'distant', 'link."' . $link_distant_id . '" = distant."'. $distant_id . '"')
301
            ->where(\call_user_func_array([$qb->expr(), 'andX'],
302
                array_map(
303
                    [$qb->expr(), 'eq'],
304
                    array_map(function ($s) {return 'distant.'.$s; }, array_keys($where)),
305
                    array_map([$qb, 'createNamedParameter'], array_values($where))
306
                )
307
            ))
308
        ;
309
310
        return $result;
311
    }
312
313
    public function getWhereManyToManyToManyQueryBuilder(
314
        $base_table, $base_id, // $t0, $t0_id,...
315
        $base_link_base_id, $base_link_table, $base_link_distant_id,
316
        $distant_link_base_id, $distant_link_table, $distant_link_distant_id,
317
        $distant_id, $distant_table,
318
        array $where // ,
319
        // $orderby=''
320
        ) {
321
        $qb = $this->getConnection()->createQueryBuilder(); // 320
322
        $result = $qb
323
            ->select('distant.*, base."'.$base_id.'" as base_link_id, base_link."'.$base_link_distant_id.'" as distant_link_id')
324
            ->from($base_table, 'base')
325
            ->innerJoin('base', '"'.$base_link_table.'"', 'base_link', 'base."'.$base_id.'" = base_link."'.$base_link_base_id.'"')
326
            ->innerJoin('base_link', '"'.$distant_link_table.'"', 'distant_link', 'base_link."'.$base_link_distant_id.'" = distant_link."'.$distant_link_base_id.'"')
327
            ->innerJoin('distant_link', '"'.$distant_table.'"', 'distant', 'distant_link."'.$distant_link_distant_id.'" = distant."'.$distant_id.'"')
328
            ->where(\call_user_func_array([$qb->expr(), 'andX'],
329
                array_map(
330
                    [$qb->expr(), 'eq'],
331
                    array_map(function ($s) {return 'base.'.$s; }, array_keys($where)),
332
                    array_map([$qb, 'createNamedParameter'], array_values($where))
333
                )
334
            ));
335
        // if ($orderby != ''):
336
        //     $result->orderBy($orderby);
337
        // endif;
338
        return $result;
339
    }
340
341
    public function getMoreManyToManyWhereQueryBuilder($more_table, $more_id, $base_more, $base_table, $base_id, $link_base_id, $link_table, $link_distant_id, $distant_id, $distant_table, array $where)
342
    {
343
        $qb = $this->getConnection()->createQueryBuilder(); // 342
344
        return $qb
345
            ->select('more.*, base.*') // collision risk
346
            ->from($base_table, 'base')
347
            ->innerJoin('base', '"'.$more_table.'"', 'more', 'base."'.$base_more.'" = more."'.$more_id.'"')
348
            ->innerJoin('base', '"'.$link_table.'"', 'link', 'base."'.$base_id.'" = link."'.$link_base_id.'"')
349
            ->innerJoin('link', '"'.$distant_table.'"', 'distant', 'link."'.$link_distant_id.'" = distant."'.$distant_id.'"')
350
            ->where(\call_user_func_array([$qb->expr(), 'andX'],
351
                array_map(
352
                    [$qb->expr(), 'eq'],
353
                    array_map(function ($s) {return 'distant.'.$s; }, array_keys($where)),
354
                    array_map([$qb, 'createNamedParameter'], array_values($where))
355
                )
356
            ))
357
        ;
358
    }
359
360
    public function getUrlIndexQueryBuilder($more_table, $more_id,
361
        $base_more, $base_table, $base_id,
362
        $link_base_id, $link_table, $link_distant_id,
363
        $distant_id, $distant_table, array $where)
364
    {
365
        $qb = $this->getConnection()->createQueryBuilder(); // 364
366
        // return $qb
367
        return $this->sqlarray2dbal([
368
                'select' => 'more.*, base.*',
369
                'from' => [
370
                    $base_table => 'base',
371
                ],
372
                'innerJoin' => [
373
                    [
374
                        'from' => 'base',
375
                        'table' => [$more_table => 'more'],
376
                        'on' => 'base."'.$base_more.'" = more."'.$more_id.'"',
377
                    ],
378
                    [
379
                        'from' => 'base',
380
                        'table' => [$link_table => 'link'],
381
                        'on' => 'base."'.$base_id.'" = link."'.$link_base_id.'"',
382
                    ],
383
                    [
384
                        'from' => 'link',
385
                        'table' => [$distant_table => 'distant'],
386
                        'on' => 'link."'.$link_distant_id.'" = distant."'.$distant_id.'"',
387
                    ],
388
                ],
389
            ], $qb)
390
            // ->select('more.*, base.*, \count(base.uuid=taxo.owned_url_uuid) AS taxocount') // collision risk!
391
            // ->select('more.*, base.*') // collision risk!
392
            // ->from($base_table, 'base')
393
            // ->innerJoin('base', '"' . $more_table . '"', 'more', 'base."' . $base_more . '" = more."' . $more_id . '"')
394
            // ->innerJoin('base', '"' . $link_table . '"', 'link', 'base."' . $base_id . '" = link."' . $link_base_id . '"')
395
            // ->innerJoin('link', '"' . $distant_table . '"', 'distant', 'link."' . $link_distant_id . '" = distant."'. $distant_id . '"')
396
            ->leftJoin('base', '"'.'link_owned_url_taxonomy'.'"', 'taxo', 'base."'.$base_id.'" = taxo."'.'owned_url_uuid'.'"')
397
            ->where(\call_user_func_array([$qb->expr(), 'andX'],
398
                array_map(
399
                    [$qb->expr(), 'eq'],
400
                    array_merge([], array_map(function ($s) {return 'distant.'.$s; }, array_keys($where))),
401
                    array_merge([], array_map([$qb, 'createNamedParameter'], array_values($where)))
402
                )
403
            ))
404
            // ->orderBy('taxocount', 'ASC')
405
        ;
406
    }
407
}
408
409
//^   NOTE: Just because you CAN use quoted identifiers doesn't mean you SHOULD use them. In general, they end up causing way more problems than they solve.
410
//^   Search for "quote" "quoteIdentifier" "quoteSingleIdentifier" "quoteStringLiteral" "getStringLiteralQuoteCharacter" in this page
411
//^   https://www.google.ca/search?q=quote+quoteIdentifier+quoteSingleIdentifier+quoteStringLiteral+getStringLiteralQuoteCharacter+site:www.doctrine-project.org/api/dbal
412
//^   https://www.google.ca/search?q=AbstractPlatform+quote+quoteIdentifier+quoteSingleIdentifier+quoteStringLiteral+getStringLiteralQuoteCharacter+site:www.doctrine-project.org/api/dbal
413
//^   $conn->getDatabasePlatform()->...
414
// Quoting of identifiers is SQL-dialect dependent (and differs between identifiers and literal values)
415
//^ https://stackoverflow.com/questions/22459092/pdo-postgresql-quoted-identifiers-in-where
416
//^ Postgres manual
417
//^ https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html
418
// Quoting of values seems more or less similar in main SQL dialects
419
//^ https://www.w3schools.com/sql/sql_insert.asp
420
//^ https://www.postgresql.org/docs/current/static/dml-insert.html
421