Passed
Pull Request — master (#2945)
by Dorian
13:10
created

SqlitePlatform::getForeignKeysInAlteredTable()   D

Complexity

Conditions 13
Paths 198

Size

Total Lines 49
Code Lines 30

Duplication

Lines 49
Ratio 100 %

Code Coverage

Tests 27
CRAP Score 13.0555

Importance

Changes 0
Metric Value
dl 49
loc 49
rs 4.814
c 0
b 0
f 0
ccs 27
cts 29
cp 0.931
cc 13
eloc 30
nc 198
nop 1
crap 13.0555

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\DBAL\Platforms;
21
22
use Doctrine\DBAL\DBALException;
23
use Doctrine\DBAL\Schema\Column;
24
use Doctrine\DBAL\Schema\Constraint;
25
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
26
use Doctrine\DBAL\Schema\Identifier;
27
use Doctrine\DBAL\Schema\Index;
28
use Doctrine\DBAL\Schema\Table;
29
use Doctrine\DBAL\Schema\TableDiff;
30
use Doctrine\DBAL\Types;
31
32
/**
33
 * The SqlitePlatform class describes the specifics and dialects of the SQLite
34
 * database platform.
35
 *
36
 * @since  2.0
37
 * @author Roman Borschel <[email protected]>
38
 * @author Benjamin Eberlei <[email protected]>
39
 * @author Martin Hasoň <[email protected]>
40
 * @todo   Rename: SQLitePlatform
41
 */
42
class SqlitePlatform extends AbstractPlatform
43
{
44
    /**
45
     * {@inheritDoc}
46
     */
47 1
    public function getRegexpExpression()
48
    {
49 1
        return 'REGEXP';
50
    }
51
52
    /**
53
     * {@inheritDoc}
54
     */
55 2
    public function getGuidExpression()
56
    {
57
        return "HEX(RANDOMBLOB(4)) || '-' || HEX(RANDOMBLOB(2)) || '-4' || "
58
            . "SUBSTR(HEX(RANDOMBLOB(2)), 2) || '-' || "
59
            . "SUBSTR('89AB', 1 + (ABS(RANDOM()) % 4), 1) || "
60 2
            . "SUBSTR(HEX(RANDOMBLOB(2)), 2) || '-' || HEX(RANDOMBLOB(6))";
61
    }
62
63
    /**
64
     * {@inheritDoc}
65
     */
66
    public function getNowExpression($type = 'timestamp')
67
    {
68
        switch ($type) {
69
            case 'time':
70
                return 'time(\'now\')';
71
            case 'date':
72
                return 'date(\'now\')';
73
            case 'timestamp':
74
            default:
75
                return 'datetime(\'now\')';
76
        }
77
    }
78
79
    /**
80
     * {@inheritDoc}
81
     */
82 36
    public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false)
83
    {
84 36
        $trimChar = ($char != false) ? (', ' . $char) : '';
85
86 View Code Duplication
        switch ($pos) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
87 36
            case self::TRIM_LEADING:
88 9
                $trimFn = 'LTRIM';
89 9
                break;
90
91 27
            case self::TRIM_TRAILING:
92 9
                $trimFn = 'RTRIM';
93 9
                break;
94
95
            default:
96 18
                $trimFn = 'TRIM';
97
        }
98
99 36
        return $trimFn . '(' . $str . $trimChar . ')';
100
    }
101
102
    /**
103
     * {@inheritDoc}
104
     *
105
     * SQLite only supports the 2 parameter variant of this function
106
     */
107 1 View Code Duplication
    public function getSubstringExpression($value, $position, $length = null)
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...
108
    {
109 1
        if ($length !== null) {
110 1
            return 'SUBSTR(' . $value . ', ' . $position . ', ' . $length . ')';
111
        }
112
113 1
        return 'SUBSTR(' . $value . ', ' . $position . ', LENGTH(' . $value . '))';
114
    }
115
116
    /**
117
     * {@inheritDoc}
118
     */
119 1 View Code Duplication
    public function getLocateExpression($str, $substr, $startPos = false)
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...
120
    {
121 1
        if ($startPos == false) {
122 1
            return 'LOCATE('.$str.', '.$substr.')';
123
        }
124
125 1
        return 'LOCATE('.$str.', '.$substr.', '.$startPos.')';
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131 1
    protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit)
132
    {
133
        switch ($unit) {
134 1
            case self::DATE_INTERVAL_UNIT_SECOND:
135 1
            case self::DATE_INTERVAL_UNIT_MINUTE:
136 1
            case self::DATE_INTERVAL_UNIT_HOUR:
137 1
                return "DATETIME(" . $date . ",'" . $operator . $interval . " " . $unit . "')";
138
139
            default:
140 View Code Duplication
                switch ($unit) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
141 1
                    case self::DATE_INTERVAL_UNIT_WEEK:
142 1
                        $interval *= 7;
143 1
                        $unit = self::DATE_INTERVAL_UNIT_DAY;
144 1
                        break;
145
146 1
                    case self::DATE_INTERVAL_UNIT_QUARTER:
147 1
                        $interval *= 3;
148 1
                        $unit = self::DATE_INTERVAL_UNIT_MONTH;
149 1
                        break;
150
                }
151
152 1
                return "DATE(" . $date . ",'" . $operator . $interval . " " . $unit . "')";
153
        }
154
    }
155
156
    /**
157
     * {@inheritDoc}
158
     */
159 1
    public function getDateDiffExpression($date1, $date2)
160
    {
161 1
        return 'ROUND(JULIANDAY('.$date1 . ')-JULIANDAY('.$date2.'))';
162
    }
163
164
    /**
165
     * {@inheritDoc}
166
     */
167 1 View Code Duplication
    protected function _getTransactionIsolationLevelSQL($level)
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...
168
    {
169
        switch ($level) {
170 1
            case \Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED:
171 1
                return 0;
172 1
            case \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED:
173 1
            case \Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ:
174 1
            case \Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE:
175 1
                return 1;
176
            default:
177
                return parent::_getTransactionIsolationLevelSQL($level);
178
        }
179
    }
180
181
    /**
182
     * {@inheritDoc}
183
     */
184 1
    public function getSetTransactionIsolationSQL($level)
185
    {
186 1
        return 'PRAGMA read_uncommitted = ' . $this->_getTransactionIsolationLevelSQL($level);
187
    }
188
189
    /**
190
     * {@inheritDoc}
191
     */
192 2
    public function prefersIdentityColumns()
193
    {
194 2
        return true;
195
    }
196
197
    /**
198
     * {@inheritDoc}
199
     */
200 16
    public function getBooleanTypeDeclarationSQL(array $field)
201
    {
202 16
        return 'BOOLEAN';
203
    }
204
205
    /**
206
     * {@inheritDoc}
207
     */
208 145
    public function getIntegerTypeDeclarationSQL(array $field)
209
    {
210 145
        return 'INTEGER' . $this->_getCommonIntegerTypeDeclarationSQL($field);
211
    }
212
213
    /**
214
     * {@inheritDoc}
215
     */
216 18 View Code Duplication
    public function getBigIntTypeDeclarationSQL(array $field)
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...
217
    {
218
        //  SQLite autoincrement is implicit for INTEGER PKs, but not for BIGINT fields.
219 18
        if ( ! empty($field['autoincrement'])) {
220 3
            return $this->getIntegerTypeDeclarationSQL($field);
221
        }
222
223 16
        return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
224
    }
225
226
    /**
227
     * {@inheritDoc}
228
     */
229 2 View Code Duplication
    public function getTinyIntTypeDeclarationSql(array $field)
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...
230
    {
231
        //  SQLite autoincrement is implicit for INTEGER PKs, but not for TINYINT fields.
232 2
        if ( ! empty($field['autoincrement'])) {
233 2
            return $this->getIntegerTypeDeclarationSQL($field);
234
        }
235
236 1
        return 'TINYINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
237
    }
238
239
    /**
240
     * {@inheritDoc}
241
     */
242 4 View Code Duplication
    public function getSmallIntTypeDeclarationSQL(array $field)
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...
243
    {
244
        //  SQLite autoincrement is implicit for INTEGER PKs, but not for SMALLINT fields.
245 4
        if ( ! empty($field['autoincrement'])) {
246 3
            return $this->getIntegerTypeDeclarationSQL($field);
247
        }
248
249 2
        return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
250
    }
251
252
    /**
253
     * {@inheritDoc}
254
     */
255 1 View Code Duplication
    public function getMediumIntTypeDeclarationSql(array $field)
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...
256
    {
257
        //  SQLite autoincrement is implicit for INTEGER PKs, but not for MEDIUMINT fields.
258 1
        if ( ! empty($field['autoincrement'])) {
259 1
            return $this->getIntegerTypeDeclarationSQL($field);
260
        }
261
262 1
        return 'MEDIUMINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
263
    }
264
265
    /**
266
     * {@inheritDoc}
267
     */
268 19
    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
269
    {
270 19
        return 'DATETIME';
271
    }
272
273
    /**
274
     * {@inheritDoc}
275
     */
276 18
    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
277
    {
278 18
        return 'DATE';
279
    }
280
281
    /**
282
     * {@inheritDoc}
283
     */
284 18
    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
285
    {
286 18
        return 'TIME';
287
    }
288
289
    /**
290
     * {@inheritDoc}
291
     */
292 145
    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
293
    {
294
        // sqlite autoincrement is implicit for integer PKs, but not when the field is unsigned
295 145
        if ( ! empty($columnDef['autoincrement'])) {
296 39
            return '';
297
        }
298
299 132
        return ! empty($columnDef['unsigned']) ? ' UNSIGNED' : '';
300
    }
301
302
    /**
303
     * {@inheritDoc}
304
     */
305 7
    public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey)
306
    {
307 7
        return parent::getForeignKeyDeclarationSQL(new ForeignKeyConstraint(
308 7
            $foreignKey->getQuotedLocalColumns($this),
309 7
            str_replace('.', '__', $foreignKey->getQuotedForeignTableName($this)),
310 7
            $foreignKey->getQuotedForeignColumns($this),
311 7
            $foreignKey->getName(),
312 7
            $foreignKey->getOptions()
313
        ));
314
    }
315
316
    /**
317
     * {@inheritDoc}
318
     */
319 150
    protected function _getCreateTableSQL($name, array $columns, array $options = [])
320
    {
321 150
        $name = str_replace('.', '__', $name);
322 150
        $queryFields = $this->getColumnDeclarationListSQL($columns);
323
324 150
        if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
325
            foreach ($options['uniqueConstraints'] as $name => $definition) {
326
                $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition);
327
            }
328
        }
329
330 150 View Code Duplication
        if (isset($options['primary']) && ! empty($options['primary'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
331 97
            $keyColumns = array_unique(array_values($options['primary']));
332 97
            $queryFields.= ', PRIMARY KEY('.implode(', ', $keyColumns).')';
333
        }
334
335 150
        if (isset($options['foreignKeys'])) {
336 149
            foreach ($options['foreignKeys'] as $foreignKey) {
337 7
                $queryFields.= ', '.$this->getForeignKeyDeclarationSQL($foreignKey);
338
            }
339
        }
340
341 150
        $query[] = 'CREATE TABLE ' . $name . ' (' . $queryFields . ')';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$query was never initialized. Although not strictly required by PHP, it is generally a good practice to add $query = array(); before regardless.
Loading history...
342
343 150
        if (isset($options['alter']) && true === $options['alter']) {
344 26
            return $query;
345
        }
346
347 137 View Code Duplication
        if (isset($options['indexes']) && ! empty($options['indexes'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
348 8
            foreach ($options['indexes'] as $indexDef) {
349 8
                $query[] = $this->getCreateIndexSQL($indexDef, $name);
350
            }
351
        }
352
353 137 View Code Duplication
        if (isset($options['unique']) && ! empty($options['unique'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
354
            foreach ($options['unique'] as $indexDef) {
355
                $query[] = $this->getCreateIndexSQL($indexDef, $name);
356
            }
357
        }
358
359 137
        return $query;
360
    }
361
362
    /**
363
     * {@inheritDoc}
364
     */
365 80
    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
366
    {
367 80
        return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
368 80
                : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
369
    }
370
371
    /**
372
     * {@inheritdoc}
373
     */
374 2
    protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
375
    {
376 2
        return 'BLOB';
377
    }
378
379
    /**
380
     * {@inheritdoc}
381
     */
382 6
    public function getBinaryMaxLength()
383
    {
384 6
        return 0;
385
    }
386
387
    /**
388
     * {@inheritdoc}
389
     */
390 3
    public function getBinaryDefaultLength()
391
    {
392 3
        return 0;
393
    }
394
395
    /**
396
     * {@inheritDoc}
397
     */
398 45
    public function getClobTypeDeclarationSQL(array $field)
399
    {
400 45
        return 'CLOB';
401
    }
402
403
    /**
404
     * {@inheritDoc}
405
     */
406 1
    public function getListTableConstraintsSQL($table)
407
    {
408 1
        $table = str_replace('.', '__', $table);
409 1
        $table = $this->quoteStringLiteral($table);
410
411 1
        return "SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name = $table AND sql NOT NULL ORDER BY name";
412
    }
413
414
    /**
415
     * {@inheritDoc}
416
     */
417 41 View Code Duplication
    public function getListTableColumnsSQL($table, $currentDatabase = null)
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...
418
    {
419 41
        $table = str_replace('.', '__', $table);
420 41
        $table = $this->quoteStringLiteral($table);
421
422 41
        return "PRAGMA table_info($table)";
423
    }
424
425
    /**
426
     * {@inheritDoc}
427
     */
428 34 View Code Duplication
    public function getListTableIndexesSQL($table, $currentDatabase = null)
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...
429
    {
430 34
        $table = str_replace('.', '__', $table);
431 34
        $table = $this->quoteStringLiteral($table);
432
433 34
        return "PRAGMA index_list($table)";
434
    }
435
436
    /**
437
     * {@inheritDoc}
438
     */
439 64
    public function getListTablesSQL()
440
    {
441
        return "SELECT name FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence' AND name != 'geometry_columns' AND name != 'spatial_ref_sys' "
442
             . "UNION ALL SELECT name FROM sqlite_temp_master "
443 64
             . "WHERE type = 'table' ORDER BY name";
444
    }
445
446
    /**
447
     * {@inheritDoc}
448
     */
449 1
    public function getListViewsSQL($database)
450
    {
451 1
        return "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL";
452
    }
453
454
    /**
455
     * {@inheritDoc}
456
     */
457 1
    public function getCreateViewSQL($name, $sql)
458
    {
459 1
        return 'CREATE VIEW ' . $name . ' AS ' . $sql;
460
    }
461
462
    /**
463
     * {@inheritDoc}
464
     */
465 1
    public function getDropViewSQL($name)
466
    {
467 1
        return 'DROP VIEW '. $name;
468
    }
469
470
    /**
471
     * {@inheritDoc}
472
     */
473 7
    public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey)
474
    {
475 7
        $query = parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
476
477 7
        $query .= (($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) ? ' ' : ' NOT ') . 'DEFERRABLE';
478 7
        $query .= ' INITIALLY ' . (($foreignKey->hasOption('deferred') && $foreignKey->getOption('deferred') !== false) ? 'DEFERRED' : 'IMMEDIATE');
479
480 7
        return $query;
481
    }
482
483
    /**
484
     * {@inheritDoc}
485
     */
486 3
    public function supportsIdentityColumns()
487
    {
488 3
        return true;
489
    }
490
491
    /**
492
     * {@inheritDoc}
493
     */
494 1
    public function supportsColumnCollation()
495
    {
496 1
        return true;
497
    }
498
499
    /**
500
     * {@inheritDoc}
501
     */
502 154
    public function supportsInlineColumnComments()
503
    {
504 154
        return true;
505
    }
506
507
    /**
508
     * {@inheritDoc}
509
     */
510 70
    public function getName()
511
    {
512 70
        return 'sqlite';
513
    }
514
515
    /**
516
     * {@inheritDoc}
517
     */
518 12
    public function getTruncateTableSQL($tableName, $cascade = false)
519
    {
520 12
        $tableIdentifier = new Identifier($tableName);
521 12
        $tableName = str_replace('.', '__', $tableIdentifier->getQuotedName($this));
522
523 12
        return 'DELETE FROM ' . $tableName;
524
    }
525
526
    /**
527
     * User-defined function for Sqlite that is used with PDO::sqliteCreateFunction().
528
     *
529
     * @param integer|float $value
530
     *
531
     * @return float
532
     */
533
    public static function udfSqrt($value)
534
    {
535
        return sqrt($value);
536
    }
537
538
    /**
539
     * User-defined function for Sqlite that implements MOD(a, b).
540
     *
541
     * @param integer $a
542
     * @param integer $b
543
     *
544
     * @return integer
545
     */
546
    public static function udfMod($a, $b)
547
    {
548
        return ($a % $b);
549
    }
550
551
    /**
552
     * @param string  $str
553
     * @param string  $substr
554
     * @param integer $offset
555
     *
556
     * @return integer
557
     */
558 1
    public static function udfLocate($str, $substr, $offset = 0)
559
    {
560
        // SQL's LOCATE function works on 1-based positions, while PHP's strpos works on 0-based positions.
561
        // So we have to make them compatible if an offset is given.
562 1
        if ($offset > 0) {
563 1
            $offset -= 1;
564
        }
565
566 1
        $pos = strpos($str, $substr, $offset);
567
568 1
        if ($pos !== false) {
569 1
            return $pos + 1;
570
        }
571
572 1
        return 0;
573
    }
574
575
    /**
576
     * {@inheritDoc}
577
     */
578
    public function getForUpdateSql()
579
    {
580
        return '';
581
    }
582
583
    /**
584
     * {@inheritDoc}
585
     */
586 38
    public function getInlineColumnCommentSQL($comment)
587
    {
588 38
        return '--' . str_replace("\n", "\n--", $comment) . "\n";
589
    }
590
591
    /**
592
     * {@inheritDoc}
593
     */
594 7
    protected function initializeDoctrineTypeMappings()
595
    {
596 7
        $this->doctrineTypeMapping = [
597
            'boolean'          => 'boolean',
598
            'tinyint'          => 'boolean',
599
            'smallint'         => 'smallint',
600
            'mediumint'        => 'integer',
601
            'int'              => 'integer',
602
            'integer'          => 'integer',
603
            'serial'           => 'integer',
604
            'bigint'           => 'bigint',
605
            'bigserial'        => 'bigint',
606
            'clob'             => 'text',
607
            'tinytext'         => 'text',
608
            'mediumtext'       => 'text',
609
            'longtext'         => 'text',
610
            'text'             => 'text',
611
            'varchar'          => 'string',
612
            'longvarchar'      => 'string',
613
            'varchar2'         => 'string',
614
            'nvarchar'         => 'string',
615
            'image'            => 'string',
616
            'ntext'            => 'string',
617
            'char'             => 'string',
618
            'date'             => 'date',
619
            'datetime'         => 'datetime',
620
            'timestamp'        => 'datetime',
621
            'time'             => 'time',
622
            'float'            => 'float',
623
            'double'           => 'float',
624
            'double precision' => 'float',
625
            'real'             => 'float',
626
            'decimal'          => 'decimal',
627
            'numeric'          => 'decimal',
628
            'blob'             => 'blob',
629
        ];
630 7
    }
631
632
    /**
633
     * {@inheritDoc}
634
     */
635 50
    protected function getReservedKeywordsClass()
636
    {
637 50
        return Keywords\SQLiteKeywords::class;
638
    }
639
640
    /**
641
     * {@inheritDoc}
642
     */
643 26
    protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
644
    {
645 26
        if ( ! $diff->fromTable instanceof Table) {
646
            throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema');
647
        }
648
649 26
        $sql = [];
650 26
        foreach ($diff->fromTable->getIndexes() as $index) {
651 9
            if ( ! $index->isPrimary()) {
652 9
                $sql[] = $this->getDropIndexSQL($index, $diff->name);
653
            }
654
        }
655
656 26
        return $sql;
657
    }
658
659
    /**
660
     * {@inheritDoc}
661
     */
662 26
    protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
663
    {
664 26
        if ( ! $diff->fromTable instanceof Table) {
665
            throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema');
666
        }
667
668 26
        $sql = [];
669 26
        $tableName = $diff->newName ? $diff->getNewName(): $diff->getName($this);
670 26
        foreach ($this->getIndexesInAlteredTable($diff) as $index) {
671 9
            if ($index->isPrimary()) {
672 7
                continue;
673
            }
674
675 6
            $sql[] = $this->getCreateIndexSQL($index, $tableName->getQuotedName($this));
676
        }
677
678 26
        return $sql;
679
    }
680
681
    /**
682
     * {@inheritDoc}
683
     */
684 11
    protected function doModifyLimitQuery($query, $limit, $offset)
685
    {
686 11
        if (null === $limit && null !== $offset) {
687 3
            return $query . ' LIMIT -1 OFFSET ' . $offset;
688
        }
689
690 9
        return parent::doModifyLimitQuery($query, $limit, $offset);
691
    }
692
693
    /**
694
     * {@inheritDoc}
695
     */
696 6
    public function getBlobTypeDeclarationSQL(array $field)
697
    {
698 6
        return 'BLOB';
699
    }
700
701
    /**
702
     * {@inheritDoc}
703
     */
704 2
    public function getTemporaryTableName($tableName)
705
    {
706 2
        $tableName = str_replace('.', '__', $tableName);
707
708 2
        return $tableName;
709
    }
710
711
    /**
712
     * {@inheritDoc}
713
     *
714
     * Sqlite Platform emulates schema by underscoring each dot and generating tables
715
     * into the default database.
716
     *
717
     * This hack is implemented to be able to use SQLite as testdriver when
718
     * using schema supporting databases.
719
     */
720
    public function canEmulateSchemas()
721
    {
722
        return true;
723
    }
724
725
    /**
726
     * {@inheritDoc}
727
     */
728 37
    public function supportsForeignKeyConstraints()
729
    {
730 37
        return false;
731
    }
732
733
    /**
734
     * {@inheritDoc}
735
     */
736
    public function getCreatePrimaryKeySQL(Index $index, $table)
737
    {
738
        throw new DBALException('Sqlite platform does not support alter primary key.');
739
    }
740
741
    /**
742
     * {@inheritdoc}
743
     */
744 2
    public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table)
745
    {
746 2
        throw new DBALException('Sqlite platform does not support alter foreign key.');
747
    }
748
749
    /**
750
     * {@inheritdoc}
751
     */
752
    public function getDropForeignKeySQL($foreignKey, $table)
753
    {
754
        throw new DBALException('Sqlite platform does not support alter foreign key.');
755
    }
756
757
    /**
758
     * {@inheritDoc}
759
     */
760 1
    public function getCreateConstraintSQL(Constraint $constraint, $table)
761
    {
762 1
        throw new DBALException('Sqlite platform does not support alter constraint.');
763
    }
764
765
    /**
766
     * {@inheritDoc}
767
     */
768 151
    public function getCreateTableSQL(Table $table, $createFlags = null)
769
    {
770 151
        $createFlags = null === $createFlags ? self::CREATE_INDEXES | self::CREATE_FOREIGNKEYS : $createFlags;
771
772 151
        return parent::getCreateTableSQL($table, $createFlags);
773
    }
774
775
    /**
776
     * {@inheritDoc}
777
     */
778 2 View Code Duplication
    public function getListTableForeignKeysSQL($table, $database = null)
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...
Unused Code introduced by
The parameter $database is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

778
    public function getListTableForeignKeysSQL($table, /** @scrutinizer ignore-unused */ $database = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
779
    {
780 2
        $table = str_replace('.', '__', $table);
781 2
        $table = $this->quoteStringLiteral($table);
782
783 2
        return "PRAGMA foreign_key_list($table)";
784
    }
785
786
    /**
787
     * {@inheritDoc}
788
     */
789 35
    public function getAlterTableSQL(TableDiff $diff)
790
    {
791 35
        $sql = $this->getSimpleAlterTableSQL($diff);
792 35
        if (false !== $sql) {
793 7
            return $sql;
794
        }
795
796 28
        $fromTable = $diff->fromTable;
797 28
        if ( ! $fromTable instanceof Table) {
798 2
            throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema');
799
        }
800
801 26
        $table = clone $fromTable;
802
803 26
        $columns = [];
804 26
        $oldColumnNames = [];
805 26
        $newColumnNames = [];
806 26
        $columnSql = [];
807
808 26
        foreach ($table->getColumns() as $columnName => $column) {
809 25
            $columnName = strtolower($columnName);
810 25
            $columns[$columnName] = $column;
811 25
            $oldColumnNames[$columnName] = $newColumnNames[$columnName] = $column->getQuotedName($this);
812
        }
813
814 26
        foreach ($diff->removedColumns as $columnName => $column) {
815 5
            if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
816
                continue;
817
            }
818
819 5
            $columnName = strtolower($columnName);
820 5
            if (isset($columns[$columnName])) {
821
                unset(
822 5
                    $columns[$columnName],
823 5
                    $oldColumnNames[$columnName],
824 5
                    $newColumnNames[$columnName]
825
                );
826
            }
827
        }
828
829 26
        foreach ($diff->renamedColumns as $oldColumnName => $column) {
830 5
            if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
831
                continue;
832
            }
833
834 5
            $oldColumnName = strtolower($oldColumnName);
835 5
            if (isset($columns[$oldColumnName])) {
836 5
                unset($columns[$oldColumnName]);
837
            }
838
839 5
            $columns[strtolower($column->getName())] = $column;
840
841 5
            if (isset($newColumnNames[$oldColumnName])) {
842 5
                $newColumnNames[$oldColumnName] = $column->getQuotedName($this);
843
            }
844
        }
845
846 26
        foreach ($diff->changedColumns as $oldColumnName => $columnDiff) {
847 18
            if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
848
                continue;
849
            }
850
851 18
            if (isset($columns[$oldColumnName])) {
852 17
                unset($columns[$oldColumnName]);
853
            }
854
855 18
            $columns[strtolower($columnDiff->column->getName())] = $columnDiff->column;
856
857 18
            if (isset($newColumnNames[$oldColumnName])) {
858 18
                $newColumnNames[$oldColumnName] = $columnDiff->column->getQuotedName($this);
859
            }
860
        }
861
862 26
        foreach ($diff->addedColumns as $columnName => $column) {
863 4
            if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
864
                continue;
865
            }
866
867 4
            $columns[strtolower($columnName)] = $column;
868
        }
869
870 26
        $sql = [];
871 26
        $tableSql = [];
872 26
        if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
873 26
            $dataTable = new Table('__temp__'.$table->getName());
874
875 26
            $newTable = new Table($table->getQuotedName($this), $columns, $this->getPrimaryIndexInAlteredTable($diff), $this->getForeignKeysInAlteredTable($diff), 0, $table->getOptions());
876 26
            $newTable->addOption('alter', true);
877
878 26
            $sql = $this->getPreAlterTableIndexForeignKeySQL($diff);
879
            //$sql = array_merge($sql, $this->getCreateTableSQL($dataTable, 0));
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
880 26
            $sql[] = sprintf('CREATE TEMPORARY TABLE %s AS SELECT %s FROM %s', $dataTable->getQuotedName($this), implode(', ', $oldColumnNames), $table->getQuotedName($this));
881 26
            $sql[] = $this->getDropTableSQL($fromTable);
882
883 26
            $sql = array_merge($sql, $this->getCreateTableSQL($newTable));
884 26
            $sql[] = sprintf('INSERT INTO %s (%s) SELECT %s FROM %s', $newTable->getQuotedName($this), implode(', ', $newColumnNames), implode(', ', $oldColumnNames), $dataTable->getQuotedName($this));
885 26
            $sql[] = $this->getDropTableSQL($dataTable);
886
887 26
            if ($diff->newName && $diff->newName != $diff->name) {
888 3
                $renamedTable = $diff->getNewName();
889 3
                $sql[] = 'ALTER TABLE '.$newTable->getQuotedName($this).' RENAME TO '.$renamedTable->getQuotedName($this);
890
            }
891
892 26
            $sql = array_merge($sql, $this->getPostAlterTableIndexForeignKeySQL($diff));
893
        }
894
895 26
        return array_merge($sql, $tableSql, $columnSql);
896
    }
897
898
    /**
899
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
900
     *
901
     * @return array|bool
902
     */
903 35
    private function getSimpleAlterTableSQL(TableDiff $diff)
904
    {
905
        // Suppress changes on integer type autoincrement columns.
906 35
        foreach ($diff->changedColumns as $oldColumnName => $columnDiff) {
907 23
            if ( ! $columnDiff->fromColumn instanceof Column ||
908 19
                ! $columnDiff->column instanceof Column ||
909 19
                ! $columnDiff->column->getAutoincrement() ||
910 23
                ! $columnDiff->column->getType() instanceof Types\IntegerType
911
            ) {
912 18
                continue;
913
            }
914
915 5
            if ( ! $columnDiff->hasChanged('type') && $columnDiff->hasChanged('unsigned')) {
916 1
                unset($diff->changedColumns[$oldColumnName]);
917
918 1
                continue;
919
            }
920
921 4
            $fromColumnType = $columnDiff->fromColumn->getType();
922
923 4
            if ($fromColumnType instanceof Types\SmallIntType || $fromColumnType instanceof Types\BigIntType) {
924 4
                unset($diff->changedColumns[$oldColumnName]);
925
            }
926
        }
927
928 35
        if ( ! empty($diff->renamedColumns) || ! empty($diff->addedForeignKeys) || ! empty($diff->addedIndexes)
929 30
                || ! empty($diff->changedColumns) || ! empty($diff->changedForeignKeys) || ! empty($diff->changedIndexes)
930 14
                || ! empty($diff->removedColumns) || ! empty($diff->removedForeignKeys) || ! empty($diff->removedIndexes)
931 35
                || ! empty($diff->renamedIndexes) || ! empty($diff->renamedForeignKeys)
932
        ) {
933 26
            return false;
934
        }
935
936 9
        $table = new Table($diff->name);
937
938 9
        $sql = [];
939 9
        $tableSql = [];
940 9
        $columnSql = [];
941
942 9
        foreach ($diff->addedColumns as $column) {
943 3
            if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
944
                continue;
945
            }
946
947 3
            $field = array_merge(['unique' => null, 'autoincrement' => null, 'default' => null], $column->toArray());
948 3
            $type = $field['type'];
949
            switch (true) {
950 3
                case isset($field['columnDefinition']) || $field['autoincrement'] || $field['unique']:
951 2
                case $type instanceof Types\DateTimeType && $field['default'] == $this->getCurrentTimestampSQL():
952 2
                case $type instanceof Types\DateType && $field['default'] == $this->getCurrentDateSQL():
953 1
                case $type instanceof Types\TimeType && $field['default'] == $this->getCurrentTimeSQL():
954 2
                    return false;
955
            }
956
957 1
            $field['name'] = $column->getQuotedName($this);
958 1
            if ($type instanceof Types\StringType && $field['length'] === null) {
959 1
                $field['length'] = 255;
960
            }
961
962 1
            $sql[] = 'ALTER TABLE '.$table->getQuotedName($this).' ADD COLUMN '.$this->getColumnDeclarationSQL($field['name'], $field);
963
        }
964
965 7
        if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
966 7
            if ($diff->newName !== false) {
967 1
                $newTable = new Identifier($diff->newName);
0 ignored issues
show
Bug introduced by
It seems like $diff->newName can also be of type true; however, parameter $identifier of Doctrine\DBAL\Schema\Identifier::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

967
                $newTable = new Identifier(/** @scrutinizer ignore-type */ $diff->newName);
Loading history...
968 1
                $sql[] = 'ALTER TABLE '.$table->getQuotedName($this).' RENAME TO '.$newTable->getQuotedName($this);
969
            }
970
        }
971
972 7
        return array_merge($sql, $tableSql, $columnSql);
973
    }
974
975
    /**
976
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
977
     *
978
     * @return array
979
     */
980 26
    private function getColumnNamesInAlteredTable(TableDiff $diff)
981
    {
982 26
        $columns = [];
983
984 26
        foreach ($diff->fromTable->getColumns() as $columnName => $column) {
985 25
            $columns[strtolower($columnName)] = $column->getName();
986
        }
987
988 26
        foreach ($diff->removedColumns as $columnName => $column) {
989 5
            $columnName = strtolower($columnName);
990 5
            if (isset($columns[$columnName])) {
991 5
                unset($columns[$columnName]);
992
            }
993
        }
994
995 26 View Code Duplication
        foreach ($diff->renamedColumns as $oldColumnName => $column) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
996 5
            $columnName = $column->getName();
997 5
            $columns[strtolower($oldColumnName)] = $columnName;
998 5
            $columns[strtolower($columnName)] = $columnName;
999
        }
1000
1001 26 View Code Duplication
        foreach ($diff->changedColumns as $oldColumnName => $columnDiff) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1002 18
            $columnName = $columnDiff->column->getName();
1003 18
            $columns[strtolower($oldColumnName)] = $columnName;
1004 18
            $columns[strtolower($columnName)] = $columnName;
1005
        }
1006
1007 26
        foreach ($diff->addedColumns as $columnName => $column) {
1008 4
            $columns[strtolower($columnName)] = $columnName;
1009
        }
1010
1011 26
        return $columns;
1012
    }
1013
1014
    /**
1015
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
1016
     *
1017
     * @return \Doctrine\DBAL\Schema\Index[]
1018
     */
1019 26 View Code Duplication
    private function getIndexesInAlteredTable(TableDiff $diff)
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...
1020
    {
1021 26
        $indexes = $diff->fromTable->getIndexes();
1022 26
        $columnNames = $this->getColumnNamesInAlteredTable($diff);
1023
1024 26
        foreach ($indexes as $key => $index) {
1025 9
            foreach ($diff->renamedIndexes as $oldIndexName => $renamedIndex) {
1026 4
                if (strtolower($key) === strtolower($oldIndexName)) {
1027 4
                    unset($indexes[$key]);
1028
                }
1029
            }
1030
1031 9
            $changed = false;
1032 9
            $indexColumns = [];
1033 9
            foreach ($index->getColumns() as $columnName) {
1034 9
                $normalizedColumnName = strtolower($columnName);
1035 9
                if ( ! isset($columnNames[$normalizedColumnName])) {
1036 1
                    unset($indexes[$key]);
1037 1
                    continue 2;
1038
                } else {
1039 9
                    $indexColumns[] = $columnNames[$normalizedColumnName];
1040 9
                    if ($columnName !== $columnNames[$normalizedColumnName]) {
1041 9
                        $changed = true;
1042
                    }
1043
                }
1044
            }
1045
1046 9
            if ($changed) {
1047 9
                $indexes[$key] = new Index($index->getName(), $indexColumns, $index->isUnique(), $index->isPrimary(), $index->getFlags());
1048
            }
1049
        }
1050
1051 26
        foreach ($diff->removedIndexes as $index) {
1052 2
            $indexName = strtolower($index->getName());
1053 2
            if (strlen($indexName) && isset($indexes[$indexName])) {
1054 2
                unset($indexes[$indexName]);
1055
            }
1056
        }
1057
1058 26
        foreach (array_merge($diff->changedIndexes, $diff->addedIndexes, $diff->renamedIndexes) as $index) {
1059 4
            $indexName = strtolower($index->getName());
1060 4
            if (strlen($indexName)) {
1061 4
                $indexes[$indexName] = $index;
1062
            } else {
1063 4
                $indexes[] = $index;
1064
            }
1065
        }
1066
1067 26
        return $indexes;
1068
    }
1069
1070
    /**
1071
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
1072
     *
1073
     * @return array
1074
     */
1075 26 View Code Duplication
    private function getForeignKeysInAlteredTable(TableDiff $diff)
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...
1076
    {
1077 26
        $foreignKeys = $diff->fromTable->getForeignKeys();
1078 26
        $columnNames = $this->getColumnNamesInAlteredTable($diff);
1079
1080 26
        foreach ($foreignKeys as $key => $constraint) {
1081 3
            foreach ($diff->renamedForeignKeys as $oldForeignKeyName => $renamedForeignKey) {
1082
                if (strcasecmp($key, $oldForeignKeyName) === 0) {
1083
                    unset($foreignKeys[$key]);
1084
                }
1085
            }
1086
1087 3
            $changed = false;
1088 3
            $localColumns = [];
1089 3
            foreach ($constraint->getLocalColumns() as $columnName) {
1090 3
                $normalizedColumnName = strtolower($columnName);
1091 3
                if ( ! isset($columnNames[$normalizedColumnName])) {
1092 1
                    unset($foreignKeys[$key]);
1093 1
                    continue 2;
1094
                } else {
1095 3
                    $localColumns[] = $columnNames[$normalizedColumnName];
1096 3
                    if ($columnName !== $columnNames[$normalizedColumnName]) {
1097 3
                        $changed = true;
1098
                    }
1099
                }
1100
            }
1101
1102 3
            if ($changed) {
1103 3
                $foreignKeys[$key] = new ForeignKeyConstraint($localColumns, $constraint->getForeignTableName(), $constraint->getForeignColumns(), $constraint->getName(), $constraint->getOptions());
1104
            }
1105
        }
1106
1107 26
        foreach ($diff->removedForeignKeys as $constraint) {
1108 1
            $constraintName = strtolower($constraint->getName());
1109 1
            if (strlen($constraintName) && isset($foreignKeys[$constraintName])) {
1110 1
                unset($foreignKeys[$constraintName]);
1111
            }
1112
        }
1113
1114 26
        foreach (array_merge($diff->changedForeignKeys, $diff->addedForeignKeys, $diff->renamedForeignKeys) as $constraint) {
1115 3
            $constraintName = strtolower($constraint->getName());
1116 3
            if (strlen($constraintName)) {
1117 2
                $foreignKeys[$constraintName] = $constraint;
1118
            } else {
1119 3
                $foreignKeys[] = $constraint;
1120
            }
1121
        }
1122
1123 26
        return $foreignKeys;
1124
    }
1125
1126
    /**
1127
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
1128
     *
1129
     * @return array
1130
     */
1131 26
    private function getPrimaryIndexInAlteredTable(TableDiff $diff)
1132
    {
1133 26
        $primaryIndex = [];
1134
1135 26
        foreach ($this->getIndexesInAlteredTable($diff) as $index) {
1136 9
            if ($index->isPrimary()) {
1137 9
                $primaryIndex = [$index->getName() => $index];
1138
            }
1139
        }
1140
1141 26
        return $primaryIndex;
1142
    }
1143
}
1144