Passed
Pull Request — master (#2921)
by Robin
63:46
created

SqlitePlatform::_getCreateTableSQL()   D

Complexity

Conditions 18
Paths 60

Size

Total Lines 44
Code Lines 22

Duplication

Lines 10
Ratio 22.73 %

Code Coverage

Tests 18
CRAP Score 19.9468

Importance

Changes 0
Metric Value
dl 10
loc 44
ccs 18
cts 22
cp 0.8182
rs 4.947
c 0
b 0
f 0
cc 18
eloc 22
nc 60
nop 3
crap 19.9468

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 144
    public function getIntegerTypeDeclarationSQL(array $field)
209
    {
210 144
        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 144
    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
293
    {
294
        // sqlite autoincrement is only possible for the primary key
295 144
        if ( ! empty($columnDef['autoincrement'])) {
296 39
            return ' PRIMARY KEY AUTOINCREMENT';
297
        }
298
299 131
        return ! empty($columnDef['unsigned']) ? ' UNSIGNED' : '';
300
    }
301
302
    /**
303
     * {@inheritDoc}
304
     */
305 6
    public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey)
306
    {
307 6
        return parent::getForeignKeyDeclarationSQL(new ForeignKeyConstraint(
308 6
            $foreignKey->getQuotedLocalColumns($this),
309 6
            str_replace('.', '__', $foreignKey->getQuotedForeignTableName($this)),
310 6
            $foreignKey->getQuotedForeignColumns($this),
311 6
            $foreignKey->getName(),
312 6
            $foreignKey->getOptions()
313
        ));
314
    }
315
316
    /**
317
     * {@inheritDoc}
318
     */
319 149
    protected function _getCreateTableSQL($name, array $columns, array $options = [])
320
    {
321 149
        $name = str_replace('.', '__', $name);
322 149
        $queryFields = $this->getColumnDeclarationListSQL($columns);
323
324 149
        if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
325
            foreach ($options['uniqueConstraints'] as $name => $definition) {
326
                $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition);
327
            }
328
        }
329
330 149
        if (isset($options['primary']) && ! empty($options['primary'])) {
331 97
            $keyColumns = array_unique(array_values($options['primary']));
332 97
            // the primary key is already defined in the column definition for auto increment fields
333
            if (count($keyColumns) > 1 || !$columns[$keyColumns[0]]['autoincrement']) {
334
                $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
335 149
            }
336 148
        }
337 6
338
        if (isset($options['foreignKeys'])) {
339
            foreach ($options['foreignKeys'] as $foreignKey) {
340
                $queryFields.= ', '.$this->getForeignKeyDeclarationSQL($foreignKey);
341 149
            }
342
        }
343 149
344 25
        $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...
345
346
        if (isset($options['alter']) && true === $options['alter']) {
347 137
            return $query;
348 8
        }
349 8
350 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...
351
            foreach ($options['indexes'] as $indexDef) {
352
                $query[] = $this->getCreateIndexSQL($indexDef, $name);
353 137
            }
354
        }
355
356 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...
357
            foreach ($options['unique'] as $indexDef) {
358
                $query[] = $this->getCreateIndexSQL($indexDef, $name);
359 137
            }
360
        }
361
362
        return $query;
363
    }
364
365 80
    /**
366
     * {@inheritDoc}
367 80
     */
368 80
    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
369
    {
370
        return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
371
                : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
372
    }
373
374 2
    /**
375
     * {@inheritdoc}
376 2
     */
377
    protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
378
    {
379
        return 'BLOB';
380
    }
381
382 6
    /**
383
     * {@inheritdoc}
384 6
     */
385
    public function getBinaryMaxLength()
386
    {
387
        return 0;
388
    }
389
390 3
    /**
391
     * {@inheritdoc}
392 3
     */
393
    public function getBinaryDefaultLength()
394
    {
395
        return 0;
396
    }
397
398 45
    /**
399
     * {@inheritDoc}
400 45
     */
401
    public function getClobTypeDeclarationSQL(array $field)
402
    {
403
        return 'CLOB';
404
    }
405
406 1
    /**
407
     * {@inheritDoc}
408 1
     */
409 1
    public function getListTableConstraintsSQL($table)
410
    {
411 1
        $table = str_replace('.', '__', $table);
412
        $table = $this->quoteStringLiteral($table);
413
414
        return "SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name = $table AND sql NOT NULL ORDER BY name";
415
    }
416
417 41
    /**
418
     * {@inheritDoc}
419 41
     */
420 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...
421
    {
422 41
        $table = str_replace('.', '__', $table);
423
        $table = $this->quoteStringLiteral($table);
424
425
        return "PRAGMA table_info($table)";
426
    }
427
428 34
    /**
429
     * {@inheritDoc}
430 34
     */
431 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...
432
    {
433 34
        $table = str_replace('.', '__', $table);
434
        $table = $this->quoteStringLiteral($table);
435
436
        return "PRAGMA index_list($table)";
437
    }
438
439 64
    /**
440
     * {@inheritDoc}
441
     */
442
    public function getListTablesSQL()
443 64
    {
444
        return "SELECT name FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence' AND name != 'geometry_columns' AND name != 'spatial_ref_sys' "
445
             . "UNION ALL SELECT name FROM sqlite_temp_master "
446
             . "WHERE type = 'table' ORDER BY name";
447
    }
448
449 1
    /**
450
     * {@inheritDoc}
451 1
     */
452
    public function getListViewsSQL($database)
453
    {
454
        return "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL";
455
    }
456
457 1
    /**
458
     * {@inheritDoc}
459 1
     */
460
    public function getCreateViewSQL($name, $sql)
461
    {
462
        return 'CREATE VIEW ' . $name . ' AS ' . $sql;
463
    }
464
465 1
    /**
466
     * {@inheritDoc}
467 1
     */
468
    public function getDropViewSQL($name)
469
    {
470
        return 'DROP VIEW '. $name;
471
    }
472
473 6
    /**
474
     * {@inheritDoc}
475 6
     */
476
    public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey)
477 6
    {
478 6
        $query = parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
479
480 6
        $query .= (($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) ? ' ' : ' NOT ') . 'DEFERRABLE';
481
        $query .= ' INITIALLY ' . (($foreignKey->hasOption('deferred') && $foreignKey->getOption('deferred') !== false) ? 'DEFERRED' : 'IMMEDIATE');
482
483
        return $query;
484
    }
485
486 3
    /**
487
     * {@inheritDoc}
488 3
     */
489
    public function supportsIdentityColumns()
490
    {
491
        return true;
492
    }
493
494 1
    /**
495
     * {@inheritDoc}
496 1
     */
497
    public function supportsColumnCollation()
498
    {
499
        return true;
500
    }
501
502 153
    /**
503
     * {@inheritDoc}
504 153
     */
505
    public function supportsInlineColumnComments()
506
    {
507
        return true;
508
    }
509
510 70
    /**
511
     * {@inheritDoc}
512 70
     */
513
    public function getName()
514
    {
515
        return 'sqlite';
516
    }
517
518 12
    /**
519
     * {@inheritDoc}
520 12
     */
521 12
    public function getTruncateTableSQL($tableName, $cascade = false)
522
    {
523 12
        $tableIdentifier = new Identifier($tableName);
524
        $tableName = str_replace('.', '__', $tableIdentifier->getQuotedName($this));
525
526
        return 'DELETE FROM ' . $tableName;
527
    }
528
529
    /**
530
     * User-defined function for Sqlite that is used with PDO::sqliteCreateFunction().
531
     *
532
     * @param integer|float $value
533
     *
534
     * @return float
535
     */
536
    public static function udfSqrt($value)
537
    {
538
        return sqrt($value);
539
    }
540
541
    /**
542
     * User-defined function for Sqlite that implements MOD(a, b).
543
     *
544
     * @param integer $a
545
     * @param integer $b
546
     *
547
     * @return integer
548
     */
549
    public static function udfMod($a, $b)
550
    {
551
        return ($a % $b);
552
    }
553
554
    /**
555
     * @param string  $str
556
     * @param string  $substr
557
     * @param integer $offset
558 1
     *
559
     * @return integer
560
     */
561
    public static function udfLocate($str, $substr, $offset = 0)
562 1
    {
563 1
        // SQL's LOCATE function works on 1-based positions, while PHP's strpos works on 0-based positions.
564
        // So we have to make them compatible if an offset is given.
565
        if ($offset > 0) {
566 1
            $offset -= 1;
567
        }
568 1
569 1
        $pos = strpos($str, $substr, $offset);
570
571
        if ($pos !== false) {
572 1
            return $pos + 1;
573
        }
574
575
        return 0;
576
    }
577
578
    /**
579
     * {@inheritDoc}
580
     */
581
    public function getForUpdateSql()
582
    {
583
        return '';
584
    }
585
586 38
    /**
587
     * {@inheritDoc}
588 38
     */
589
    public function getInlineColumnCommentSQL($comment)
590
    {
591
        return '--' . str_replace("\n", "\n--", $comment) . "\n";
592
    }
593
594 7
    /**
595
     * {@inheritDoc}
596 7
     */
597
    protected function initializeDoctrineTypeMappings()
598
    {
599
        $this->doctrineTypeMapping = [
600
            'boolean'          => 'boolean',
601
            'tinyint'          => 'boolean',
602
            'smallint'         => 'smallint',
603
            'mediumint'        => 'integer',
604
            'int'              => 'integer',
605
            'integer'          => 'integer',
606
            'serial'           => 'integer',
607
            'bigint'           => 'bigint',
608
            'bigserial'        => 'bigint',
609
            'clob'             => 'text',
610
            'tinytext'         => 'text',
611
            'mediumtext'       => 'text',
612
            'longtext'         => 'text',
613
            'text'             => 'text',
614
            'varchar'          => 'string',
615
            'longvarchar'      => 'string',
616
            'varchar2'         => 'string',
617
            'nvarchar'         => 'string',
618
            'image'            => 'string',
619
            'ntext'            => 'string',
620
            'char'             => 'string',
621
            'date'             => 'date',
622
            'datetime'         => 'datetime',
623
            'timestamp'        => 'datetime',
624
            'time'             => 'time',
625
            'float'            => 'float',
626
            'double'           => 'float',
627
            'double precision' => 'float',
628
            'real'             => 'float',
629
            'decimal'          => 'decimal',
630 7
            'numeric'          => 'decimal',
631
            'blob'             => 'blob',
632
        ];
633
    }
634
635 49
    /**
636
     * {@inheritDoc}
637 49
     */
638
    protected function getReservedKeywordsClass()
639
    {
640
        return Keywords\SQLiteKeywords::class;
641
    }
642
643 25
    /**
644
     * {@inheritDoc}
645 25
     */
646
    protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
647
    {
648
        if ( ! $diff->fromTable instanceof Table) {
649 25
            throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema');
650 25
        }
651 9
652 9
        $sql = [];
653
        foreach ($diff->fromTable->getIndexes() as $index) {
654
            if ( ! $index->isPrimary()) {
655
                $sql[] = $this->getDropIndexSQL($index, $diff->name);
656 25
            }
657
        }
658
659
        return $sql;
660
    }
661
662 25
    /**
663
     * {@inheritDoc}
664 25
     */
665
    protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
666
    {
667
        if ( ! $diff->fromTable instanceof Table) {
668 25
            throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema');
669 25
        }
670 25
671 9
        $sql = [];
672 7
        $tableName = $diff->newName ? $diff->getNewName(): $diff->getName($this);
673
        foreach ($this->getIndexesInAlteredTable($diff) as $index) {
674
            if ($index->isPrimary()) {
675 6
                continue;
676
            }
677
678 25
            $sql[] = $this->getCreateIndexSQL($index, $tableName->getQuotedName($this));
679
        }
680
681
        return $sql;
682
    }
683
684 11
    /**
685
     * {@inheritDoc}
686 11
     */
687 3
    protected function doModifyLimitQuery($query, $limit, $offset)
688
    {
689
        if (null === $limit && null !== $offset) {
690 9
            return $query . ' LIMIT -1 OFFSET ' . $offset;
691
        }
692
693
        return parent::doModifyLimitQuery($query, $limit, $offset);
694
    }
695
696 6
    /**
697
     * {@inheritDoc}
698 6
     */
699
    public function getBlobTypeDeclarationSQL(array $field)
700
    {
701
        return 'BLOB';
702
    }
703
704 2
    /**
705
     * {@inheritDoc}
706 2
     */
707
    public function getTemporaryTableName($tableName)
708 2
    {
709
        $tableName = str_replace('.', '__', $tableName);
710
711
        return $tableName;
712
    }
713
714
    /**
715
     * {@inheritDoc}
716
     *
717
     * Sqlite Platform emulates schema by underscoring each dot and generating tables
718
     * into the default database.
719
     *
720
     * This hack is implemented to be able to use SQLite as testdriver when
721
     * using schema supporting databases.
722
     */
723
    public function canEmulateSchemas()
724
    {
725
        return true;
726
    }
727
728 36
    /**
729
     * {@inheritDoc}
730 36
     */
731
    public function supportsForeignKeyConstraints()
732
    {
733
        return false;
734
    }
735
736
    /**
737
     * {@inheritDoc}
738
     */
739
    public function getCreatePrimaryKeySQL(Index $index, $table)
740
    {
741
        throw new DBALException('Sqlite platform does not support alter primary key.');
742
    }
743
744 2
    /**
745
     * {@inheritdoc}
746 2
     */
747
    public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table)
748
    {
749
        throw new DBALException('Sqlite platform does not support alter foreign key.');
750
    }
751
752
    /**
753
     * {@inheritdoc}
754
     */
755
    public function getDropForeignKeySQL($foreignKey, $table)
756
    {
757
        throw new DBALException('Sqlite platform does not support alter foreign key.');
758
    }
759
760 1
    /**
761
     * {@inheritDoc}
762 1
     */
763
    public function getCreateConstraintSQL(Constraint $constraint, $table)
764
    {
765
        throw new DBALException('Sqlite platform does not support alter constraint.');
766
    }
767
768 150
    /**
769
     * {@inheritDoc}
770 150
     */
771
    public function getCreateTableSQL(Table $table, $createFlags = null)
772 150
    {
773
        $createFlags = null === $createFlags ? self::CREATE_INDEXES | self::CREATE_FOREIGNKEYS : $createFlags;
774
775
        return parent::getCreateTableSQL($table, $createFlags);
776
    }
777
778 2
    /**
779
     * {@inheritDoc}
780 2
     */
781 2 View Code Duplication
    public function getListTableForeignKeysSQL($table, $database = null)
0 ignored issues
show
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

781
    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...
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...
782
    {
783 2
        $table = str_replace('.', '__', $table);
784
        $table = $this->quoteStringLiteral($table);
785
786
        return "PRAGMA foreign_key_list($table)";
787
    }
788
789 34
    /**
790
     * {@inheritDoc}
791 34
     */
792 34
    public function getAlterTableSQL(TableDiff $diff)
793 7
    {
794
        $sql = $this->getSimpleAlterTableSQL($diff);
795
        if (false !== $sql) {
796 27
            return $sql;
797 27
        }
798 2
799
        $fromTable = $diff->fromTable;
800
        if ( ! $fromTable instanceof Table) {
801 25
            throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema');
802
        }
803 25
804 25
        $table = clone $fromTable;
805 25
806 25
        $columns = [];
807
        $oldColumnNames = [];
808 25
        $newColumnNames = [];
809 24
        $columnSql = [];
810 24
811 24
        foreach ($table->getColumns() as $columnName => $column) {
812
            $columnName = strtolower($columnName);
813
            $columns[$columnName] = $column;
814 25
            $oldColumnNames[$columnName] = $newColumnNames[$columnName] = $column->getQuotedName($this);
815 5
        }
816
817
        foreach ($diff->removedColumns as $columnName => $column) {
818
            if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
819 5
                continue;
820 5
            }
821 5
822 5
            $columnName = strtolower($columnName);
823 5
            if (isset($columns[$columnName])) {
824
                unset($columns[$columnName]);
825
                unset($oldColumnNames[$columnName]);
826
                unset($newColumnNames[$columnName]);
827 25
            }
828 5
        }
829
830
        foreach ($diff->renamedColumns as $oldColumnName => $column) {
831
            if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
832 5
                continue;
833 5
            }
834 5
835
            $oldColumnName = strtolower($oldColumnName);
836
            if (isset($columns[$oldColumnName])) {
837 5
                unset($columns[$oldColumnName]);
838
            }
839 5
840 5
            $columns[strtolower($column->getName())] = $column;
841
842
            if (isset($newColumnNames[$oldColumnName])) {
843
                $newColumnNames[$oldColumnName] = $column->getQuotedName($this);
844 25
            }
845 18
        }
846
847
        foreach ($diff->changedColumns as $oldColumnName => $columnDiff) {
848
            if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
849 18
                continue;
850 17
            }
851
852
            if (isset($columns[$oldColumnName])) {
853 18
                unset($columns[$oldColumnName]);
854
            }
855 18
856 18
            $columns[strtolower($columnDiff->column->getName())] = $columnDiff->column;
857
858
            if (isset($newColumnNames[$oldColumnName])) {
859
                $newColumnNames[$oldColumnName] = $columnDiff->column->getQuotedName($this);
860 25
            }
861 4
        }
862
863
        foreach ($diff->addedColumns as $columnName => $column) {
864
            if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
865 4
                continue;
866
            }
867
868 25
            $columns[strtolower($columnName)] = $column;
869 25
        }
870 25
871 25
        $sql = [];
872
        $tableSql = [];
873 25
        if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
874 25
            $dataTable = new Table('__temp__'.$table->getName());
875
876 25
            $newTable = new Table($table->getQuotedName($this), $columns, $this->getPrimaryIndexInAlteredTable($diff), $this->getForeignKeysInAlteredTable($diff), 0, $table->getOptions());
877
            $newTable->addOption('alter', true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $value of Doctrine\DBAL\Schema\Table::addOption(). ( Ignorable by Annotation )

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

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

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