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) { |
|||
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) |
||
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) |
||
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) { |
|||
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) |
||
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) |
||
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) |
||
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) |
||
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) |
||
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 implicit for integer PKs, but not when the field is unsigned |
||||
295 | 144 | if ( ! empty($columnDef['autoincrement'])) { |
|||
296 | 39 | return ''; |
|||
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 | View Code Duplication | if (isset($options['primary']) && ! empty($options['primary'])) { |
||
331 | 97 | $keyColumns = array_unique(array_values($options['primary'])); |
|||
332 | 97 | $queryFields.= ', PRIMARY KEY('.implode(', ', $keyColumns).')'; |
|||
333 | } |
||||
334 | |||||
335 | 149 | if (isset($options['foreignKeys'])) { |
|||
336 | 148 | foreach ($options['foreignKeys'] as $foreignKey) { |
|||
337 | 6 | $queryFields.= ', '.$this->getForeignKeyDeclarationSQL($foreignKey); |
|||
338 | } |
||||
339 | } |
||||
340 | |||||
341 | 149 | $query[] = 'CREATE TABLE ' . $name . ' (' . $queryFields . ')'; |
|||
342 | |||||
343 | 149 | if (isset($options['alter']) && true === $options['alter']) { |
|||
344 | 25 | return $query; |
|||
345 | } |
||||
346 | |||||
347 | 137 | View Code Duplication | if (isset($options['indexes']) && ! empty($options['indexes'])) { |
||
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'])) { |
||
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) |
||
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) |
||
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 | 58 | 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 | 58 | . "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 | 6 | public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) |
|||
474 | { |
||||
475 | 6 | $query = parent::getAdvancedForeignKeyOptionsSQL($foreignKey); |
|||
476 | |||||
477 | 6 | $query .= (($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) ? ' ' : ' NOT ') . 'DEFERRABLE'; |
|||
478 | 6 | $query .= ' INITIALLY ' . (($foreignKey->hasOption('deferred') && $foreignKey->getOption('deferred') !== false) ? 'DEFERRED' : 'IMMEDIATE'); |
|||
479 | |||||
480 | 6 | 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 | 153 | public function supportsInlineColumnComments() |
|||
503 | { |
||||
504 | 153 | return true; |
|||
505 | } |
||||
506 | |||||
507 | /** |
||||
508 | * {@inheritDoc} |
||||
509 | */ |
||||
510 | 64 | public function getName() |
|||
511 | { |
||||
512 | 64 | 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 | 49 | protected function getReservedKeywordsClass() |
|||
636 | { |
||||
637 | 49 | return Keywords\SQLiteKeywords::class; |
|||
638 | } |
||||
639 | |||||
640 | /** |
||||
641 | * {@inheritDoc} |
||||
642 | */ |
||||
643 | 25 | protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) |
|||
644 | { |
||||
645 | 25 | 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 | 25 | $sql = []; |
|||
650 | 25 | foreach ($diff->fromTable->getIndexes() as $index) { |
|||
651 | 9 | if ( ! $index->isPrimary()) { |
|||
652 | 9 | $sql[] = $this->getDropIndexSQL($index, $diff->name); |
|||
653 | } |
||||
654 | } |
||||
655 | |||||
656 | 25 | return $sql; |
|||
657 | } |
||||
658 | |||||
659 | /** |
||||
660 | * {@inheritDoc} |
||||
661 | */ |
||||
662 | 25 | protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) |
|||
663 | { |
||||
664 | 25 | 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 | 25 | $sql = []; |
|||
669 | 25 | $tableName = $diff->newName ? $diff->getNewName(): $diff->getName($this); |
|||
670 | 25 | 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 | 25 | 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 | 36 | public function supportsForeignKeyConstraints() |
|||
729 | { |
||||
730 | 36 | 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 | 150 | public function getCreateTableSQL(Table $table, $createFlags = null) |
|||
769 | { |
||||
770 | 150 | $createFlags = null === $createFlags ? self::CREATE_INDEXES | self::CREATE_FOREIGNKEYS : $createFlags; |
|||
771 | |||||
772 | 150 | 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
|
|||||
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 | 34 | public function getAlterTableSQL(TableDiff $diff) |
|||
790 | { |
||||
791 | 34 | $sql = $this->getSimpleAlterTableSQL($diff); |
|||
792 | 34 | if (false !== $sql) { |
|||
793 | 7 | return $sql; |
|||
794 | } |
||||
795 | |||||
796 | 27 | $fromTable = $diff->fromTable; |
|||
797 | 27 | 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 | 25 | $table = clone $fromTable; |
|||
802 | |||||
803 | 25 | $columns = []; |
|||
804 | 25 | $oldColumnNames = []; |
|||
805 | 25 | $newColumnNames = []; |
|||
806 | 25 | $columnSql = []; |
|||
807 | |||||
808 | 25 | foreach ($table->getColumns() as $columnName => $column) { |
|||
809 | 24 | $columnName = strtolower($columnName); |
|||
810 | 24 | $columns[$columnName] = $column; |
|||
811 | 24 | $oldColumnNames[$columnName] = $newColumnNames[$columnName] = $column->getQuotedName($this); |
|||
812 | } |
||||
813 | |||||
814 | 25 | 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 | 5 | unset($columns[$columnName]); |
|||
822 | 5 | unset($oldColumnNames[$columnName]); |
|||
823 | 5 | unset($newColumnNames[$columnName]); |
|||
824 | } |
||||
825 | } |
||||
826 | |||||
827 | 25 | foreach ($diff->renamedColumns as $oldColumnName => $column) { |
|||
828 | 5 | if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { |
|||
829 | continue; |
||||
830 | } |
||||
831 | |||||
832 | 5 | $oldColumnName = strtolower($oldColumnName); |
|||
833 | 5 | if (isset($columns[$oldColumnName])) { |
|||
834 | 5 | unset($columns[$oldColumnName]); |
|||
835 | } |
||||
836 | |||||
837 | 5 | $columns[strtolower($column->getName())] = $column; |
|||
838 | |||||
839 | 5 | if (isset($newColumnNames[$oldColumnName])) { |
|||
840 | 5 | $newColumnNames[$oldColumnName] = $column->getQuotedName($this); |
|||
841 | } |
||||
842 | } |
||||
843 | |||||
844 | 25 | foreach ($diff->changedColumns as $oldColumnName => $columnDiff) { |
|||
845 | 18 | if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { |
|||
846 | continue; |
||||
847 | } |
||||
848 | |||||
849 | 18 | if (isset($columns[$oldColumnName])) { |
|||
850 | 17 | unset($columns[$oldColumnName]); |
|||
851 | } |
||||
852 | |||||
853 | 18 | $columns[strtolower($columnDiff->column->getName())] = $columnDiff->column; |
|||
854 | |||||
855 | 18 | if (isset($newColumnNames[$oldColumnName])) { |
|||
856 | 18 | $newColumnNames[$oldColumnName] = $columnDiff->column->getQuotedName($this); |
|||
857 | } |
||||
858 | } |
||||
859 | |||||
860 | 25 | foreach ($diff->addedColumns as $columnName => $column) { |
|||
861 | 4 | if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { |
|||
862 | continue; |
||||
863 | } |
||||
864 | |||||
865 | 4 | $columns[strtolower($columnName)] = $column; |
|||
866 | } |
||||
867 | |||||
868 | 25 | $sql = []; |
|||
869 | 25 | $tableSql = []; |
|||
870 | 25 | if ( ! $this->onSchemaAlterTable($diff, $tableSql)) { |
|||
871 | 25 | $dataTable = new Table('__temp__'.$table->getName()); |
|||
872 | |||||
873 | 25 | $newTable = new Table($table->getQuotedName($this), $columns, $this->getPrimaryIndexInAlteredTable($diff), $this->getForeignKeysInAlteredTable($diff), 0, $table->getOptions()); |
|||
874 | 25 | $newTable->addOption('alter', true); |
|||
0 ignored issues
–
show
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
Loading history...
|
|||||
875 | |||||
876 | 25 | $sql = $this->getPreAlterTableIndexForeignKeySQL($diff); |
|||
877 | //$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...
|
|||||
878 | 25 | $sql[] = sprintf('CREATE TEMPORARY TABLE %s AS SELECT %s FROM %s', $dataTable->getQuotedName($this), implode(', ', $oldColumnNames), $table->getQuotedName($this)); |
|||
879 | 25 | $sql[] = $this->getDropTableSQL($fromTable); |
|||
880 | |||||
881 | 25 | $sql = array_merge($sql, $this->getCreateTableSQL($newTable)); |
|||
882 | 25 | $sql[] = sprintf('INSERT INTO %s (%s) SELECT %s FROM %s', $newTable->getQuotedName($this), implode(', ', $newColumnNames), implode(', ', $oldColumnNames), $dataTable->getQuotedName($this)); |
|||
883 | 25 | $sql[] = $this->getDropTableSQL($dataTable); |
|||
884 | |||||
885 | 25 | if ($diff->newName && $diff->newName != $diff->name) { |
|||
886 | 3 | $renamedTable = $diff->getNewName(); |
|||
887 | 3 | $sql[] = 'ALTER TABLE '.$newTable->getQuotedName($this).' RENAME TO '.$renamedTable->getQuotedName($this); |
|||
888 | } |
||||
889 | |||||
890 | 25 | $sql = array_merge($sql, $this->getPostAlterTableIndexForeignKeySQL($diff)); |
|||
891 | } |
||||
892 | |||||
893 | 25 | return array_merge($sql, $tableSql, $columnSql); |
|||
894 | } |
||||
895 | |||||
896 | /** |
||||
897 | * @param \Doctrine\DBAL\Schema\TableDiff $diff |
||||
898 | * |
||||
899 | * @return array|bool |
||||
900 | */ |
||||
901 | 34 | private function getSimpleAlterTableSQL(TableDiff $diff) |
|||
902 | { |
||||
903 | // Suppress changes on integer type autoincrement columns. |
||||
904 | 34 | foreach ($diff->changedColumns as $oldColumnName => $columnDiff) { |
|||
905 | 23 | if ( ! $columnDiff->fromColumn instanceof Column || |
|||
906 | 19 | ! $columnDiff->column instanceof Column || |
|||
907 | 19 | ! $columnDiff->column->getAutoincrement() || |
|||
908 | 23 | ! $columnDiff->column->getType() instanceof Types\IntegerType |
|||
909 | ) { |
||||
910 | 18 | continue; |
|||
911 | } |
||||
912 | |||||
913 | 5 | if ( ! $columnDiff->hasChanged('type') && $columnDiff->hasChanged('unsigned')) { |
|||
914 | 1 | unset($diff->changedColumns[$oldColumnName]); |
|||
915 | |||||
916 | 1 | continue; |
|||
917 | } |
||||
918 | |||||
919 | 4 | $fromColumnType = $columnDiff->fromColumn->getType(); |
|||
920 | |||||
921 | 4 | if ($fromColumnType instanceof Types\SmallIntType || $fromColumnType instanceof Types\BigIntType) { |
|||
922 | 4 | unset($diff->changedColumns[$oldColumnName]); |
|||
923 | } |
||||
924 | } |
||||
925 | |||||
926 | 34 | if ( ! empty($diff->renamedColumns) || ! empty($diff->addedForeignKeys) || ! empty($diff->addedIndexes) |
|||
927 | 29 | || ! empty($diff->changedColumns) || ! empty($diff->changedForeignKeys) || ! empty($diff->changedIndexes) |
|||
928 | 13 | || ! empty($diff->removedColumns) || ! empty($diff->removedForeignKeys) || ! empty($diff->removedIndexes) |
|||
929 | 34 | || ! empty($diff->renamedIndexes) |
|||
930 | ) { |
||||
931 | 25 | return false; |
|||
932 | } |
||||
933 | |||||
934 | 9 | $table = new Table($diff->name); |
|||
935 | |||||
936 | 9 | $sql = []; |
|||
937 | 9 | $tableSql = []; |
|||
938 | 9 | $columnSql = []; |
|||
939 | |||||
940 | 9 | foreach ($diff->addedColumns as $column) { |
|||
941 | 3 | if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { |
|||
942 | continue; |
||||
943 | } |
||||
944 | |||||
945 | 3 | $field = array_merge(['unique' => null, 'autoincrement' => null, 'default' => null], $column->toArray()); |
|||
946 | 3 | $type = $field['type']; |
|||
947 | switch (true) { |
||||
948 | 3 | case isset($field['columnDefinition']) || $field['autoincrement'] || $field['unique']: |
|||
949 | 2 | case $type instanceof Types\DateTimeType && $field['default'] == $this->getCurrentTimestampSQL(): |
|||
950 | 2 | case $type instanceof Types\DateType && $field['default'] == $this->getCurrentDateSQL(): |
|||
951 | 1 | case $type instanceof Types\TimeType && $field['default'] == $this->getCurrentTimeSQL(): |
|||
952 | 2 | return false; |
|||
953 | } |
||||
954 | |||||
955 | 1 | $field['name'] = $column->getQuotedName($this); |
|||
956 | 1 | if ($type instanceof Types\StringType && $field['length'] === null) { |
|||
957 | 1 | $field['length'] = 255; |
|||
958 | } |
||||
959 | |||||
960 | 1 | $sql[] = 'ALTER TABLE '.$table->getQuotedName($this).' ADD COLUMN '.$this->getColumnDeclarationSQL($field['name'], $field); |
|||
961 | } |
||||
962 | |||||
963 | 7 | if ( ! $this->onSchemaAlterTable($diff, $tableSql)) { |
|||
964 | 7 | if ($diff->newName !== false) { |
|||
965 | 1 | $newTable = new Identifier($diff->newName); |
|||
966 | 1 | $sql[] = 'ALTER TABLE '.$table->getQuotedName($this).' RENAME TO '.$newTable->getQuotedName($this); |
|||
967 | } |
||||
968 | } |
||||
969 | |||||
970 | 7 | return array_merge($sql, $tableSql, $columnSql); |
|||
971 | } |
||||
972 | |||||
973 | /** |
||||
974 | * @param \Doctrine\DBAL\Schema\TableDiff $diff |
||||
975 | * |
||||
976 | * @return array |
||||
977 | */ |
||||
978 | 25 | private function getColumnNamesInAlteredTable(TableDiff $diff) |
|||
979 | { |
||||
980 | 25 | $columns = []; |
|||
981 | |||||
982 | 25 | foreach ($diff->fromTable->getColumns() as $columnName => $column) { |
|||
983 | 24 | $columns[strtolower($columnName)] = $column->getName(); |
|||
984 | } |
||||
985 | |||||
986 | 25 | foreach ($diff->removedColumns as $columnName => $column) { |
|||
987 | 5 | $columnName = strtolower($columnName); |
|||
988 | 5 | if (isset($columns[$columnName])) { |
|||
989 | 5 | unset($columns[$columnName]); |
|||
990 | } |
||||
991 | } |
||||
992 | |||||
993 | 25 | View Code Duplication | foreach ($diff->renamedColumns as $oldColumnName => $column) { |
||
994 | 5 | $columnName = $column->getName(); |
|||
995 | 5 | $columns[strtolower($oldColumnName)] = $columnName; |
|||
996 | 5 | $columns[strtolower($columnName)] = $columnName; |
|||
997 | } |
||||
998 | |||||
999 | 25 | View Code Duplication | foreach ($diff->changedColumns as $oldColumnName => $columnDiff) { |
||
1000 | 18 | $columnName = $columnDiff->column->getName(); |
|||
1001 | 18 | $columns[strtolower($oldColumnName)] = $columnName; |
|||
1002 | 18 | $columns[strtolower($columnName)] = $columnName; |
|||
1003 | } |
||||
1004 | |||||
1005 | 25 | foreach ($diff->addedColumns as $columnName => $column) { |
|||
1006 | 4 | $columns[strtolower($columnName)] = $columnName; |
|||
1007 | } |
||||
1008 | |||||
1009 | 25 | return $columns; |
|||
1010 | } |
||||
1011 | |||||
1012 | /** |
||||
1013 | * @param \Doctrine\DBAL\Schema\TableDiff $diff |
||||
1014 | * |
||||
1015 | * @return \Doctrine\DBAL\Schema\Index[] |
||||
1016 | */ |
||||
1017 | 25 | private function getIndexesInAlteredTable(TableDiff $diff) |
|||
1018 | { |
||||
1019 | 25 | $indexes = $diff->fromTable->getIndexes(); |
|||
1020 | 25 | $columnNames = $this->getColumnNamesInAlteredTable($diff); |
|||
1021 | |||||
1022 | 25 | foreach ($indexes as $key => $index) { |
|||
1023 | 9 | foreach ($diff->renamedIndexes as $oldIndexName => $renamedIndex) { |
|||
1024 | 4 | if (strtolower($key) === strtolower($oldIndexName)) { |
|||
1025 | 4 | unset($indexes[$key]); |
|||
1026 | } |
||||
1027 | } |
||||
1028 | |||||
1029 | 9 | $changed = false; |
|||
1030 | 9 | $indexColumns = []; |
|||
1031 | 9 | View Code Duplication | foreach ($index->getColumns() as $columnName) { |
||
1032 | 9 | $normalizedColumnName = strtolower($columnName); |
|||
1033 | 9 | if ( ! isset($columnNames[$normalizedColumnName])) { |
|||
1034 | 1 | unset($indexes[$key]); |
|||
1035 | 1 | continue 2; |
|||
1036 | } else { |
||||
1037 | 9 | $indexColumns[] = $columnNames[$normalizedColumnName]; |
|||
1038 | 9 | if ($columnName !== $columnNames[$normalizedColumnName]) { |
|||
1039 | 9 | $changed = true; |
|||
1040 | } |
||||
1041 | } |
||||
1042 | } |
||||
1043 | |||||
1044 | 9 | if ($changed) { |
|||
1045 | 9 | $indexes[$key] = new Index($index->getName(), $indexColumns, $index->isUnique(), $index->isPrimary(), $index->getFlags()); |
|||
1046 | } |
||||
1047 | } |
||||
1048 | |||||
1049 | 25 | foreach ($diff->removedIndexes as $index) { |
|||
1050 | 2 | $indexName = strtolower($index->getName()); |
|||
1051 | 2 | if (strlen($indexName) && isset($indexes[$indexName])) { |
|||
1052 | 2 | unset($indexes[$indexName]); |
|||
1053 | } |
||||
1054 | } |
||||
1055 | |||||
1056 | 25 | foreach (array_merge($diff->changedIndexes, $diff->addedIndexes, $diff->renamedIndexes) as $index) { |
|||
1057 | 4 | $indexName = strtolower($index->getName()); |
|||
1058 | 4 | if (strlen($indexName)) { |
|||
1059 | 4 | $indexes[$indexName] = $index; |
|||
1060 | } else { |
||||
1061 | 4 | $indexes[] = $index; |
|||
1062 | } |
||||
1063 | } |
||||
1064 | |||||
1065 | 25 | return $indexes; |
|||
1066 | } |
||||
1067 | |||||
1068 | /** |
||||
1069 | * @param \Doctrine\DBAL\Schema\TableDiff $diff |
||||
1070 | * |
||||
1071 | * @return array |
||||
1072 | */ |
||||
1073 | 25 | private function getForeignKeysInAlteredTable(TableDiff $diff) |
|||
1074 | { |
||||
1075 | 25 | $foreignKeys = $diff->fromTable->getForeignKeys(); |
|||
1076 | 25 | $columnNames = $this->getColumnNamesInAlteredTable($diff); |
|||
1077 | |||||
1078 | 25 | foreach ($foreignKeys as $key => $constraint) { |
|||
1079 | 3 | $changed = false; |
|||
1080 | 3 | $localColumns = []; |
|||
1081 | 3 | View Code Duplication | foreach ($constraint->getLocalColumns() as $columnName) { |
||
1082 | 3 | $normalizedColumnName = strtolower($columnName); |
|||
1083 | 3 | if ( ! isset($columnNames[$normalizedColumnName])) { |
|||
1084 | 1 | unset($foreignKeys[$key]); |
|||
1085 | 1 | continue 2; |
|||
1086 | } else { |
||||
1087 | 3 | $localColumns[] = $columnNames[$normalizedColumnName]; |
|||
1088 | 3 | if ($columnName !== $columnNames[$normalizedColumnName]) { |
|||
1089 | 3 | $changed = true; |
|||
1090 | } |
||||
1091 | } |
||||
1092 | } |
||||
1093 | |||||
1094 | 3 | if ($changed) { |
|||
1095 | 3 | $foreignKeys[$key] = new ForeignKeyConstraint($localColumns, $constraint->getForeignTableName(), $constraint->getForeignColumns(), $constraint->getName(), $constraint->getOptions()); |
|||
1096 | } |
||||
1097 | } |
||||
1098 | |||||
1099 | 25 | foreach ($diff->removedForeignKeys as $constraint) { |
|||
1100 | 1 | $constraintName = strtolower($constraint->getName()); |
|||
1101 | 1 | if (strlen($constraintName) && isset($foreignKeys[$constraintName])) { |
|||
1102 | 1 | unset($foreignKeys[$constraintName]); |
|||
1103 | } |
||||
1104 | } |
||||
1105 | |||||
1106 | 25 | foreach (array_merge($diff->changedForeignKeys, $diff->addedForeignKeys) as $constraint) { |
|||
1107 | 2 | $constraintName = strtolower($constraint->getName()); |
|||
1108 | 2 | if (strlen($constraintName)) { |
|||
1109 | 1 | $foreignKeys[$constraintName] = $constraint; |
|||
1110 | } else { |
||||
1111 | 2 | $foreignKeys[] = $constraint; |
|||
1112 | } |
||||
1113 | } |
||||
1114 | |||||
1115 | 25 | return $foreignKeys; |
|||
1116 | } |
||||
1117 | |||||
1118 | /** |
||||
1119 | * @param \Doctrine\DBAL\Schema\TableDiff $diff |
||||
1120 | * |
||||
1121 | * @return array |
||||
1122 | */ |
||||
1123 | 25 | private function getPrimaryIndexInAlteredTable(TableDiff $diff) |
|||
1124 | { |
||||
1125 | 25 | $primaryIndex = []; |
|||
1126 | |||||
1127 | 25 | foreach ($this->getIndexesInAlteredTable($diff) as $index) { |
|||
1128 | 9 | if ($index->isPrimary()) { |
|||
1129 | 9 | $primaryIndex = [$index->getName() => $index]; |
|||
1130 | } |
||||
1131 | } |
||||
1132 | |||||
1133 | 25 | return $primaryIndex; |
|||
1134 | } |
||||
1135 | } |
||||
1136 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.