Total Complexity | 121 |
Total Lines | 850 |
Duplicated Lines | 7.06 % |
Coverage | 89.69% |
Changes | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like DB2Platform often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use DB2Platform, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
30 | class DB2Platform extends AbstractPlatform |
||
31 | { |
||
32 | /** |
||
33 | * {@inheritdoc} |
||
34 | */ |
||
35 | 2 | public function getBinaryMaxLength() |
|
36 | { |
||
37 | 2 | return 32704; |
|
38 | } |
||
39 | |||
40 | /** |
||
41 | * {@inheritdoc} |
||
42 | */ |
||
43 | 2 | public function getBinaryDefaultLength() |
|
44 | { |
||
45 | 2 | return 1; |
|
46 | } |
||
47 | |||
48 | /** |
||
49 | * {@inheritDoc} |
||
50 | */ |
||
51 | 2 | public function getBlobTypeDeclarationSQL(array $field) |
|
52 | { |
||
53 | // todo blob(n) with $field['length']; |
||
|
|||
54 | 2 | return 'BLOB(1M)'; |
|
55 | } |
||
56 | |||
57 | /** |
||
58 | * {@inheritDoc} |
||
59 | */ |
||
60 | 5 | public function initializeDoctrineTypeMappings() |
|
61 | { |
||
62 | 5 | $this->doctrineTypeMapping = [ |
|
63 | 'smallint' => 'smallint', |
||
64 | 'bigint' => 'bigint', |
||
65 | 'integer' => 'integer', |
||
66 | 'time' => 'time', |
||
67 | 'date' => 'date', |
||
68 | 'varchar' => 'string', |
||
69 | 'character' => 'string', |
||
70 | 'varbinary' => 'binary', |
||
71 | 'binary' => 'binary', |
||
72 | 'clob' => 'text', |
||
73 | 'blob' => 'blob', |
||
74 | 'decimal' => 'decimal', |
||
75 | 'double' => 'float', |
||
76 | 'real' => 'float', |
||
77 | 'timestamp' => 'datetime', |
||
78 | ]; |
||
79 | 5 | } |
|
80 | |||
81 | /** |
||
82 | * {@inheritdoc} |
||
83 | */ |
||
84 | 42 | public function isCommentedDoctrineType(Type $doctrineType) |
|
85 | { |
||
86 | 42 | if ($doctrineType->getName() === Type::BOOLEAN) { |
|
87 | // We require a commented boolean type in order to distinguish between boolean and smallint |
||
88 | // as both (have to) map to the same native type. |
||
89 | 1 | return true; |
|
90 | } |
||
91 | |||
92 | 41 | return parent::isCommentedDoctrineType($doctrineType); |
|
93 | } |
||
94 | |||
95 | /** |
||
96 | * {@inheritDoc} |
||
97 | */ |
||
98 | 15 | protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) |
|
99 | { |
||
100 | 15 | return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') |
|
101 | 15 | : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); |
|
102 | } |
||
103 | |||
104 | /** |
||
105 | * {@inheritdoc} |
||
106 | */ |
||
107 | 1 | protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) |
|
108 | { |
||
109 | 1 | return $fixed ? 'BINARY(' . ($length ?: 255) . ')' : 'VARBINARY(' . ($length ?: 255) . ')'; |
|
110 | } |
||
111 | |||
112 | /** |
||
113 | * {@inheritDoc} |
||
114 | */ |
||
115 | 3 | public function getClobTypeDeclarationSQL(array $field) |
|
116 | { |
||
117 | // todo clob(n) with $field['length']; |
||
118 | 3 | return 'CLOB(1M)'; |
|
119 | } |
||
120 | |||
121 | /** |
||
122 | * {@inheritDoc} |
||
123 | */ |
||
124 | 3 | public function getName() |
|
125 | { |
||
126 | 3 | return 'db2'; |
|
127 | } |
||
128 | |||
129 | /** |
||
130 | * {@inheritDoc} |
||
131 | */ |
||
132 | 2 | public function getBooleanTypeDeclarationSQL(array $columnDef) |
|
133 | { |
||
134 | 2 | return 'SMALLINT'; |
|
135 | } |
||
136 | |||
137 | /** |
||
138 | * {@inheritDoc} |
||
139 | */ |
||
140 | 12 | public function getIntegerTypeDeclarationSQL(array $columnDef) |
|
141 | { |
||
142 | 12 | return 'INTEGER' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef); |
|
143 | } |
||
144 | |||
145 | /** |
||
146 | * {@inheritDoc} |
||
147 | */ |
||
148 | 1 | public function getBigIntTypeDeclarationSQL(array $columnDef) |
|
149 | { |
||
150 | 1 | return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef); |
|
151 | } |
||
152 | |||
153 | /** |
||
154 | * {@inheritDoc} |
||
155 | */ |
||
156 | 1 | public function getSmallIntTypeDeclarationSQL(array $columnDef) |
|
157 | { |
||
158 | 1 | return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef); |
|
159 | } |
||
160 | |||
161 | /** |
||
162 | * {@inheritDoc} |
||
163 | */ |
||
164 | 12 | protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) |
|
165 | { |
||
166 | 12 | $autoinc = ''; |
|
167 | 12 | if ( ! empty($columnDef['autoincrement'])) { |
|
168 | 2 | $autoinc = ' GENERATED BY DEFAULT AS IDENTITY'; |
|
169 | } |
||
170 | |||
171 | 12 | return $autoinc; |
|
172 | } |
||
173 | |||
174 | /** |
||
175 | * {@inheritdoc} |
||
176 | */ |
||
177 | 1 | public function getBitAndComparisonExpression($value1, $value2) |
|
178 | { |
||
179 | 1 | return 'BITAND(' . $value1 . ', ' . $value2 . ')'; |
|
180 | } |
||
181 | |||
182 | /** |
||
183 | * {@inheritdoc} |
||
184 | */ |
||
185 | 1 | public function getBitOrComparisonExpression($value1, $value2) |
|
186 | { |
||
187 | 1 | return 'BITOR(' . $value1 . ', ' . $value2 . ')'; |
|
188 | } |
||
189 | |||
190 | /** |
||
191 | * {@inheritdoc} |
||
192 | */ |
||
193 | 1 | protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) |
|
194 | { |
||
195 | View Code Duplication | switch ($unit) { |
|
196 | 1 | case self::DATE_INTERVAL_UNIT_WEEK: |
|
197 | 1 | $interval *= 7; |
|
198 | 1 | $unit = self::DATE_INTERVAL_UNIT_DAY; |
|
199 | 1 | break; |
|
200 | |||
201 | 1 | case self::DATE_INTERVAL_UNIT_QUARTER: |
|
202 | 1 | $interval *= 3; |
|
203 | 1 | $unit = self::DATE_INTERVAL_UNIT_MONTH; |
|
204 | 1 | break; |
|
205 | } |
||
206 | |||
207 | 1 | return $date . ' ' . $operator . ' ' . $interval . ' ' . $unit; |
|
208 | } |
||
209 | |||
210 | /** |
||
211 | * {@inheritdoc} |
||
212 | */ |
||
213 | 1 | public function getDateDiffExpression($date1, $date2) |
|
214 | { |
||
215 | 1 | return 'DAYS(' . $date1 . ') - DAYS(' . $date2 . ')'; |
|
216 | } |
||
217 | |||
218 | /** |
||
219 | * {@inheritDoc} |
||
220 | */ |
||
221 | 1 | public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) |
|
222 | { |
||
223 | 1 | if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] == true) { |
|
224 | 1 | return "TIMESTAMP(0) WITH DEFAULT"; |
|
225 | } |
||
226 | |||
227 | 1 | return 'TIMESTAMP(0)'; |
|
228 | } |
||
229 | |||
230 | /** |
||
231 | * {@inheritDoc} |
||
232 | */ |
||
233 | 1 | public function getDateTypeDeclarationSQL(array $fieldDeclaration) |
|
234 | { |
||
235 | 1 | return 'DATE'; |
|
236 | } |
||
237 | |||
238 | /** |
||
239 | * {@inheritDoc} |
||
240 | */ |
||
241 | 1 | public function getTimeTypeDeclarationSQL(array $fieldDeclaration) |
|
242 | { |
||
243 | 1 | return 'TIME'; |
|
244 | } |
||
245 | |||
246 | /** |
||
247 | * {@inheritdoc} |
||
248 | */ |
||
249 | 2 | public function getTruncateTableSQL($tableName, $cascade = false) |
|
250 | { |
||
251 | 2 | $tableIdentifier = new Identifier($tableName); |
|
252 | |||
253 | 2 | return 'TRUNCATE ' . $tableIdentifier->getQuotedName($this) . ' IMMEDIATE'; |
|
254 | } |
||
255 | |||
256 | /** |
||
257 | * This code fragment is originally from the Zend_Db_Adapter_Db2 class, but has been edited. |
||
258 | * |
||
259 | * @license New BSD License |
||
260 | * |
||
261 | * @param string $table |
||
262 | * @param string $database |
||
263 | * |
||
264 | * @return string |
||
265 | */ |
||
266 | 1 | public function getListTableColumnsSQL($table, $database = null) |
|
267 | { |
||
268 | 1 | $table = $this->quoteStringLiteral($table); |
|
269 | |||
270 | // We do the funky subquery and join syscat.columns.default this crazy way because |
||
271 | // as of db2 v10, the column is CLOB(64k) and the distinct operator won't allow a CLOB, |
||
272 | // it wants shorter stuff like a varchar. |
||
273 | return " |
||
274 | SELECT |
||
275 | cols.default, |
||
276 | subq.* |
||
277 | FROM ( |
||
278 | SELECT DISTINCT |
||
279 | c.tabschema, |
||
280 | c.tabname, |
||
281 | c.colname, |
||
282 | c.colno, |
||
283 | c.typename, |
||
284 | c.nulls, |
||
285 | c.length, |
||
286 | c.scale, |
||
287 | c.identity, |
||
288 | tc.type AS tabconsttype, |
||
289 | c.remarks AS comment, |
||
290 | k.colseq, |
||
291 | CASE |
||
292 | WHEN c.generated = 'D' THEN 1 |
||
293 | ELSE 0 |
||
294 | END AS autoincrement |
||
295 | FROM syscat.columns c |
||
296 | LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc |
||
297 | ON (k.tabschema = tc.tabschema |
||
298 | AND k.tabname = tc.tabname |
||
299 | AND tc.type = 'P')) |
||
300 | ON (c.tabschema = k.tabschema |
||
301 | AND c.tabname = k.tabname |
||
302 | AND c.colname = k.colname) |
||
303 | 1 | WHERE UPPER(c.tabname) = UPPER(" . $table . ") |
|
304 | ORDER BY c.colno |
||
305 | ) subq |
||
306 | JOIN syscat.columns cols |
||
307 | ON subq.tabschema = cols.tabschema |
||
308 | AND subq.tabname = cols.tabname |
||
309 | AND subq.colno = cols.colno |
||
310 | ORDER BY subq.colno |
||
311 | "; |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * {@inheritDoc} |
||
316 | */ |
||
317 | public function getListTablesSQL() |
||
318 | { |
||
319 | return "SELECT NAME FROM SYSIBM.SYSTABLES WHERE TYPE = 'T'"; |
||
320 | } |
||
321 | |||
322 | /** |
||
323 | * {@inheritDoc} |
||
324 | */ |
||
325 | public function getListViewsSQL($database) |
||
326 | { |
||
327 | return "SELECT NAME, TEXT FROM SYSIBM.SYSVIEWS"; |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * {@inheritDoc} |
||
332 | */ |
||
333 | 1 | public function getListTableIndexesSQL($table, $currentDatabase = null) |
|
334 | { |
||
335 | 1 | $table = $this->quoteStringLiteral($table); |
|
336 | |||
337 | return "SELECT idx.INDNAME AS key_name, |
||
338 | idxcol.COLNAME AS column_name, |
||
339 | CASE |
||
340 | WHEN idx.UNIQUERULE = 'P' THEN 1 |
||
341 | ELSE 0 |
||
342 | END AS primary, |
||
343 | CASE |
||
344 | WHEN idx.UNIQUERULE = 'D' THEN 1 |
||
345 | ELSE 0 |
||
346 | END AS non_unique |
||
347 | FROM SYSCAT.INDEXES AS idx |
||
348 | JOIN SYSCAT.INDEXCOLUSE AS idxcol |
||
349 | ON idx.INDSCHEMA = idxcol.INDSCHEMA AND idx.INDNAME = idxcol.INDNAME |
||
350 | 1 | WHERE idx.TABNAME = UPPER(" . $table . ") |
|
351 | ORDER BY idxcol.COLSEQ ASC"; |
||
352 | } |
||
353 | |||
354 | /** |
||
355 | * {@inheritDoc} |
||
356 | */ |
||
357 | 1 | public function getListTableForeignKeysSQL($table) |
|
358 | { |
||
359 | 1 | $table = $this->quoteStringLiteral($table); |
|
360 | |||
361 | return "SELECT fkcol.COLNAME AS local_column, |
||
362 | fk.REFTABNAME AS foreign_table, |
||
363 | pkcol.COLNAME AS foreign_column, |
||
364 | fk.CONSTNAME AS index_name, |
||
365 | CASE |
||
366 | WHEN fk.UPDATERULE = 'R' THEN 'RESTRICT' |
||
367 | ELSE NULL |
||
368 | END AS on_update, |
||
369 | CASE |
||
370 | WHEN fk.DELETERULE = 'C' THEN 'CASCADE' |
||
371 | WHEN fk.DELETERULE = 'N' THEN 'SET NULL' |
||
372 | WHEN fk.DELETERULE = 'R' THEN 'RESTRICT' |
||
373 | ELSE NULL |
||
374 | END AS on_delete |
||
375 | FROM SYSCAT.REFERENCES AS fk |
||
376 | JOIN SYSCAT.KEYCOLUSE AS fkcol |
||
377 | ON fk.CONSTNAME = fkcol.CONSTNAME |
||
378 | AND fk.TABSCHEMA = fkcol.TABSCHEMA |
||
379 | AND fk.TABNAME = fkcol.TABNAME |
||
380 | JOIN SYSCAT.KEYCOLUSE AS pkcol |
||
381 | ON fk.REFKEYNAME = pkcol.CONSTNAME |
||
382 | AND fk.REFTABSCHEMA = pkcol.TABSCHEMA |
||
383 | AND fk.REFTABNAME = pkcol.TABNAME |
||
384 | 1 | WHERE fk.TABNAME = UPPER(" . $table . ") |
|
385 | ORDER BY fkcol.COLSEQ ASC"; |
||
386 | } |
||
387 | |||
388 | /** |
||
389 | * {@inheritDoc} |
||
390 | */ |
||
391 | 1 | public function getCreateViewSQL($name, $sql) |
|
392 | { |
||
393 | 1 | return "CREATE VIEW ".$name." AS ".$sql; |
|
394 | } |
||
395 | |||
396 | /** |
||
397 | * {@inheritDoc} |
||
398 | */ |
||
399 | 1 | public function getDropViewSQL($name) |
|
402 | } |
||
403 | |||
404 | /** |
||
405 | * {@inheritDoc} |
||
406 | */ |
||
407 | 1 | public function getCreateDatabaseSQL($database) |
|
408 | { |
||
409 | 1 | return "CREATE DATABASE ".$database; |
|
410 | } |
||
411 | |||
412 | /** |
||
413 | * {@inheritDoc} |
||
414 | */ |
||
415 | 1 | public function getDropDatabaseSQL($database) |
|
416 | { |
||
417 | 1 | return "DROP DATABASE " . $database; |
|
418 | } |
||
419 | |||
420 | /** |
||
421 | * {@inheritDoc} |
||
422 | */ |
||
423 | 1 | public function supportsCreateDropDatabase() |
|
424 | { |
||
425 | 1 | return false; |
|
426 | } |
||
427 | |||
428 | /** |
||
429 | * {@inheritDoc} |
||
430 | */ |
||
431 | 1 | public function supportsReleaseSavepoints() |
|
432 | { |
||
433 | 1 | return false; |
|
434 | } |
||
435 | |||
436 | /** |
||
437 | * {@inheritdoc} |
||
438 | */ |
||
439 | 13 | public function supportsCommentOnStatement() |
|
440 | { |
||
441 | 13 | return true; |
|
442 | } |
||
443 | |||
444 | /** |
||
445 | * {@inheritDoc} |
||
446 | */ |
||
447 | 2 | public function getCurrentDateSQL() |
|
448 | { |
||
449 | 2 | return 'CURRENT DATE'; |
|
450 | } |
||
451 | |||
452 | /** |
||
453 | * {@inheritDoc} |
||
454 | */ |
||
455 | 1 | public function getCurrentTimeSQL() |
|
456 | { |
||
457 | 1 | return 'CURRENT TIME'; |
|
458 | } |
||
459 | |||
460 | /** |
||
461 | * {@inheritDoc} |
||
462 | */ |
||
463 | 2 | public function getCurrentTimestampSQL() |
|
464 | { |
||
465 | 2 | return "CURRENT TIMESTAMP"; |
|
466 | } |
||
467 | |||
468 | /** |
||
469 | * {@inheritDoc} |
||
470 | */ |
||
471 | 1 | public function getIndexDeclarationSQL($name, Index $index) |
|
472 | { |
||
473 | // Index declaration in statements like CREATE TABLE is not supported. |
||
474 | 1 | throw DBALException::notSupported(__METHOD__); |
|
475 | } |
||
476 | |||
477 | /** |
||
478 | * {@inheritDoc} |
||
479 | */ |
||
480 | 12 | protected function _getCreateTableSQL($tableName, array $columns, array $options = []) |
|
481 | { |
||
482 | 12 | $indexes = []; |
|
483 | 12 | if (isset($options['indexes'])) { |
|
484 | 12 | $indexes = $options['indexes']; |
|
485 | } |
||
486 | 12 | $options['indexes'] = []; |
|
487 | |||
488 | 12 | $sqls = parent::_getCreateTableSQL($tableName, $columns, $options); |
|
489 | |||
490 | 12 | foreach ($indexes as $definition) { |
|
491 | 4 | $sqls[] = $this->getCreateIndexSQL($definition, $tableName); |
|
492 | } |
||
493 | 12 | return $sqls; |
|
494 | } |
||
495 | |||
496 | /** |
||
497 | * {@inheritDoc} |
||
498 | */ |
||
499 | 24 | public function getAlterTableSQL(TableDiff $diff) |
|
500 | { |
||
501 | 24 | $sql = []; |
|
502 | 24 | $columnSql = []; |
|
503 | 24 | $commentsSQL = []; |
|
504 | |||
505 | 24 | $queryParts = []; |
|
506 | 24 | foreach ($diff->addedColumns as $column) { |
|
507 | 4 | if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { |
|
508 | continue; |
||
509 | } |
||
510 | |||
511 | 4 | $columnDef = $column->toArray(); |
|
512 | 4 | $queryPart = 'ADD COLUMN ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef); |
|
513 | |||
514 | // Adding non-nullable columns to a table requires a default value to be specified. |
||
515 | 4 | if ( ! empty($columnDef['notnull']) && |
|
516 | 4 | ! isset($columnDef['default']) && |
|
517 | 4 | empty($columnDef['autoincrement']) |
|
518 | ) { |
||
519 | 3 | $queryPart .= ' WITH DEFAULT'; |
|
520 | } |
||
521 | |||
522 | 4 | $queryParts[] = $queryPart; |
|
523 | |||
524 | 4 | $comment = $this->getColumnComment($column); |
|
525 | |||
526 | 4 | View Code Duplication | if (null !== $comment && '' !== $comment) { |
527 | 1 | $commentsSQL[] = $this->getCommentOnColumnSQL( |
|
528 | 1 | $diff->getName($this)->getQuotedName($this), |
|
529 | 1 | $column->getQuotedName($this), |
|
530 | 4 | $comment |
|
531 | ); |
||
532 | } |
||
533 | } |
||
534 | |||
535 | 24 | View Code Duplication | foreach ($diff->removedColumns as $column) { |
536 | 3 | if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { |
|
537 | continue; |
||
538 | } |
||
539 | |||
540 | 3 | $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this); |
|
541 | } |
||
542 | |||
543 | 24 | foreach ($diff->changedColumns as $columnDiff) { |
|
544 | 17 | if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { |
|
545 | continue; |
||
546 | } |
||
547 | |||
548 | 17 | if ($columnDiff->hasChanged('comment')) { |
|
549 | 1 | $commentsSQL[] = $this->getCommentOnColumnSQL( |
|
550 | 1 | $diff->getName($this)->getQuotedName($this), |
|
551 | 1 | $columnDiff->column->getQuotedName($this), |
|
552 | 1 | $this->getColumnComment($columnDiff->column) |
|
553 | ); |
||
554 | |||
555 | 1 | if (count($columnDiff->changedProperties) === 1) { |
|
556 | 1 | continue; |
|
557 | } |
||
558 | } |
||
559 | |||
560 | 16 | $this->gatherAlterColumnSQL($diff->fromTable, $columnDiff, $sql, $queryParts); |
|
561 | } |
||
562 | |||
563 | 24 | View Code Duplication | foreach ($diff->renamedColumns as $oldColumnName => $column) { |
564 | 4 | if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { |
|
565 | continue; |
||
566 | } |
||
567 | |||
568 | 4 | $oldColumnName = new Identifier($oldColumnName); |
|
569 | |||
570 | 4 | $queryParts[] = 'RENAME COLUMN ' . $oldColumnName->getQuotedName($this) . |
|
571 | 4 | ' TO ' . $column->getQuotedName($this); |
|
572 | } |
||
573 | |||
574 | 24 | $tableSql = []; |
|
575 | |||
576 | 24 | if ( ! $this->onSchemaAlterTable($diff, $tableSql)) { |
|
577 | 24 | if (count($queryParts) > 0) { |
|
578 | 18 | $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . implode(" ", $queryParts); |
|
579 | } |
||
580 | |||
581 | // Some table alteration operations require a table reorganization. |
||
582 | 24 | if ( ! empty($diff->removedColumns) || ! empty($diff->changedColumns)) { |
|
583 | 17 | $sql[] = "CALL SYSPROC.ADMIN_CMD ('REORG TABLE " . $diff->getName($this)->getQuotedName($this) . "')"; |
|
584 | } |
||
585 | |||
586 | 24 | $sql = array_merge($sql, $commentsSQL); |
|
587 | |||
588 | 24 | if ($diff->newName !== false) { |
|
589 | 2 | $sql[] = 'RENAME TABLE ' . $diff->getName($this)->getQuotedName($this) . ' TO ' . $diff->getNewName()->getQuotedName($this); |
|
590 | } |
||
591 | |||
592 | 24 | $sql = array_merge( |
|
593 | 24 | $this->getPreAlterTableIndexForeignKeySQL($diff), |
|
594 | 24 | $sql, |
|
595 | 24 | $this->getPostAlterTableIndexForeignKeySQL($diff) |
|
596 | ); |
||
597 | } |
||
598 | |||
599 | 24 | return array_merge($sql, $tableSql, $columnSql); |
|
600 | } |
||
601 | |||
602 | /** |
||
603 | * Gathers the table alteration SQL for a given column diff. |
||
604 | * |
||
605 | * @param Table $table The table to gather the SQL for. |
||
606 | * @param ColumnDiff $columnDiff The column diff to evaluate. |
||
607 | * @param array $sql The sequence of table alteration statements to fill. |
||
608 | * @param array $queryParts The sequence of column alteration clauses to fill. |
||
609 | */ |
||
610 | 16 | private function gatherAlterColumnSQL(Table $table, ColumnDiff $columnDiff, array &$sql, array &$queryParts) |
|
611 | { |
||
612 | 16 | $alterColumnClauses = $this->getAlterColumnClausesSQL($columnDiff); |
|
613 | |||
614 | 16 | if (empty($alterColumnClauses)) { |
|
615 | 2 | return; |
|
616 | } |
||
617 | |||
618 | // If we have a single column alteration, we can append the clause to the main query. |
||
619 | 14 | if (count($alterColumnClauses) === 1) { |
|
620 | 13 | $queryParts[] = current($alterColumnClauses); |
|
621 | |||
622 | 13 | return; |
|
623 | } |
||
624 | |||
625 | // We have multiple alterations for the same column, |
||
626 | // so we need to trigger a complete ALTER TABLE statement |
||
627 | // for each ALTER COLUMN clause. |
||
628 | 1 | foreach ($alterColumnClauses as $alterColumnClause) { |
|
629 | 1 | $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' ' . $alterColumnClause; |
|
630 | } |
||
631 | 1 | } |
|
632 | |||
633 | /** |
||
634 | * Returns the ALTER COLUMN SQL clauses for altering a column described by the given column diff. |
||
635 | * |
||
636 | * @param ColumnDiff $columnDiff The column diff to evaluate. |
||
637 | * |
||
638 | * @return array |
||
639 | */ |
||
640 | 16 | private function getAlterColumnClausesSQL(ColumnDiff $columnDiff) |
|
641 | { |
||
642 | 16 | $column = $columnDiff->column->toArray(); |
|
643 | |||
644 | 16 | $alterClause = 'ALTER COLUMN ' . $columnDiff->column->getQuotedName($this); |
|
645 | |||
646 | 16 | if ($column['columnDefinition']) { |
|
647 | 1 | return [$alterClause . ' ' . $column['columnDefinition']]; |
|
648 | } |
||
649 | |||
650 | 15 | $clauses = []; |
|
651 | |||
652 | 15 | if ($columnDiff->hasChanged('type') || |
|
653 | 12 | $columnDiff->hasChanged('length') || |
|
654 | 11 | $columnDiff->hasChanged('precision') || |
|
655 | 10 | $columnDiff->hasChanged('scale') || |
|
656 | 15 | $columnDiff->hasChanged('fixed') |
|
657 | ) { |
||
658 | 8 | $clauses[] = $alterClause . ' SET DATA TYPE ' . $column['type']->getSQLDeclaration($column, $this); |
|
659 | } |
||
660 | |||
661 | 15 | if ($columnDiff->hasChanged('notnull')) { |
|
662 | 4 | $clauses[] = $column['notnull'] ? $alterClause . ' SET NOT NULL' : $alterClause . ' DROP NOT NULL'; |
|
663 | } |
||
664 | |||
665 | 15 | if ($columnDiff->hasChanged('default')) { |
|
666 | 4 | if (isset($column['default'])) { |
|
667 | 3 | $defaultClause = $this->getDefaultValueDeclarationSQL($column); |
|
668 | |||
669 | 3 | if ($defaultClause) { |
|
670 | 3 | $clauses[] = $alterClause . ' SET' . $defaultClause; |
|
671 | } |
||
672 | } else { |
||
673 | 1 | $clauses[] = $alterClause . ' DROP DEFAULT'; |
|
674 | } |
||
675 | } |
||
676 | |||
677 | 15 | return $clauses; |
|
678 | } |
||
679 | |||
680 | /** |
||
681 | * {@inheritDoc} |
||
682 | */ |
||
683 | 24 | protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) |
|
684 | { |
||
685 | 24 | $sql = []; |
|
686 | 24 | $table = $diff->getName($this)->getQuotedName($this); |
|
687 | |||
688 | 24 | foreach ($diff->removedIndexes as $remKey => $remIndex) { |
|
689 | foreach ($diff->addedIndexes as $addKey => $addIndex) { |
||
690 | if ($remIndex->getColumns() == $addIndex->getColumns()) { |
||
691 | if ($remIndex->isPrimary()) { |
||
692 | $sql[] = 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY'; |
||
693 | } elseif ($remIndex->isUnique()) { |
||
694 | $sql[] = 'ALTER TABLE ' . $table . ' DROP UNIQUE ' . $remIndex->getQuotedName($this); |
||
695 | } else { |
||
696 | $sql[] = $this->getDropIndexSQL($remIndex, $table); |
||
697 | } |
||
698 | |||
699 | $sql[] = $this->getCreateIndexSQL($addIndex, $table); |
||
700 | |||
701 | unset($diff->removedIndexes[$remKey]); |
||
702 | unset($diff->addedIndexes[$addKey]); |
||
703 | |||
704 | break; |
||
705 | } |
||
706 | } |
||
707 | } |
||
708 | |||
709 | 24 | $sql = array_merge($sql, parent::getPreAlterTableIndexForeignKeySQL($diff)); |
|
710 | |||
711 | 24 | return $sql; |
|
712 | } |
||
713 | |||
714 | /** |
||
715 | * {@inheritdoc} |
||
716 | */ |
||
717 | 5 | View Code Duplication | protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) |
718 | { |
||
719 | 5 | if (strpos($tableName, '.') !== false) { |
|
720 | 2 | list($schema) = explode('.', $tableName); |
|
721 | 2 | $oldIndexName = $schema . '.' . $oldIndexName; |
|
722 | } |
||
723 | |||
724 | 5 | return ['RENAME INDEX ' . $oldIndexName . ' TO ' . $index->getQuotedName($this)]; |
|
725 | } |
||
726 | |||
727 | /** |
||
728 | * {@inheritDoc} |
||
729 | */ |
||
730 | 22 | public function getDefaultValueDeclarationSQL($field) |
|
731 | { |
||
732 | 22 | if ( ! empty($field['autoincrement'])) { |
|
733 | 2 | return ''; |
|
734 | } |
||
735 | |||
736 | 21 | if (isset($field['version']) && $field['version']) { |
|
737 | if ((string) $field['type'] != "DateTime") { |
||
738 | $field['default'] = "1"; |
||
739 | } |
||
740 | } |
||
741 | |||
742 | 21 | return parent::getDefaultValueDeclarationSQL($field); |
|
743 | } |
||
744 | |||
745 | /** |
||
746 | * {@inheritDoc} |
||
747 | */ |
||
748 | public function getEmptyIdentityInsertSQL($tableName, $identifierColumnName) |
||
749 | { |
||
750 | return 'INSERT INTO ' . $tableName . ' (' . $identifierColumnName . ') VALUES (DEFAULT)'; |
||
751 | } |
||
752 | |||
753 | /** |
||
754 | * {@inheritDoc} |
||
755 | */ |
||
756 | 1 | public function getCreateTemporaryTableSnippetSQL() |
|
757 | { |
||
758 | 1 | return "DECLARE GLOBAL TEMPORARY TABLE"; |
|
759 | } |
||
760 | |||
761 | /** |
||
762 | * {@inheritDoc} |
||
763 | */ |
||
764 | public function getTemporaryTableName($tableName) |
||
765 | { |
||
766 | return "SESSION." . $tableName; |
||
767 | } |
||
768 | |||
769 | /** |
||
770 | * {@inheritDoc} |
||
771 | */ |
||
772 | 1 | protected function doModifyLimitQuery($query, $limit, $offset = null) |
|
773 | { |
||
774 | 1 | $where = []; |
|
775 | |||
776 | 1 | if ($offset > 0) { |
|
777 | 1 | $where[] = sprintf('db22.DC_ROWNUM >= %d', $offset + 1); |
|
778 | } |
||
779 | |||
780 | 1 | if ($limit !== null) { |
|
781 | 1 | $where[] = sprintf('db22.DC_ROWNUM <= %d', $offset + $limit); |
|
782 | } |
||
783 | |||
784 | 1 | if (empty($where)) { |
|
785 | 1 | return $query; |
|
786 | } |
||
787 | |||
788 | // Todo OVER() needs ORDER BY data! |
||
789 | 1 | return sprintf( |
|
790 | 1 | 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (%s) db21) db22 WHERE %s', |
|
791 | 1 | $query, |
|
792 | 1 | implode(' AND ', $where) |
|
793 | ); |
||
794 | } |
||
795 | |||
796 | /** |
||
797 | * {@inheritDoc} |
||
798 | */ |
||
799 | 1 | View Code Duplication | public function getLocateExpression($str, $substr, $startPos = false) |
800 | { |
||
801 | 1 | if ($startPos == false) { |
|
802 | 1 | return 'LOCATE(' . $substr . ', ' . $str . ')'; |
|
803 | } |
||
804 | |||
805 | 1 | return 'LOCATE(' . $substr . ', ' . $str . ', '.$startPos.')'; |
|
806 | } |
||
807 | |||
808 | /** |
||
809 | * {@inheritDoc} |
||
810 | */ |
||
811 | 1 | View Code Duplication | public function getSubstringExpression($value, $from, $length = null) |
812 | { |
||
813 | 1 | if ($length === null) { |
|
814 | 1 | return 'SUBSTR(' . $value . ', ' . $from . ')'; |
|
815 | } |
||
816 | |||
817 | 1 | return 'SUBSTR(' . $value . ', ' . $from . ', ' . $length . ')'; |
|
818 | } |
||
819 | |||
820 | /** |
||
821 | * {@inheritDoc} |
||
822 | */ |
||
823 | 1 | public function supportsIdentityColumns() |
|
824 | { |
||
825 | 1 | return true; |
|
826 | } |
||
827 | |||
828 | /** |
||
829 | * {@inheritDoc} |
||
830 | */ |
||
831 | 1 | public function prefersIdentityColumns() |
|
834 | } |
||
835 | |||
836 | /** |
||
837 | * {@inheritDoc} |
||
838 | * |
||
839 | * DB2 returns all column names in SQL result sets in uppercase. |
||
840 | */ |
||
841 | 1 | public function getSQLResultCasing($column) |
|
844 | } |
||
845 | |||
846 | /** |
||
847 | * {@inheritDoc} |
||
848 | */ |
||
849 | 1 | public function getForUpdateSQL() |
|
850 | { |
||
851 | 1 | return ' WITH RR USE AND KEEP UPDATE LOCKS'; |
|
852 | } |
||
853 | |||
854 | /** |
||
855 | * {@inheritDoc} |
||
856 | */ |
||
857 | public function getDummySelectSQL() |
||
858 | { |
||
859 | return 'SELECT 1 FROM sysibm.sysdummy1'; |
||
860 | } |
||
861 | |||
862 | /** |
||
863 | * {@inheritDoc} |
||
864 | * |
||
865 | * DB2 supports savepoints, but they work semantically different than on other vendor platforms. |
||
866 | * |
||
867 | * TODO: We have to investigate how to get DB2 up and running with savepoints. |
||
868 | */ |
||
869 | 1 | public function supportsSavepoints() |
|
872 | } |
||
873 | |||
874 | /** |
||
875 | * {@inheritDoc} |
||
876 | */ |
||
877 | 52 | protected function getReservedKeywordsClass() |
|
878 | { |
||
879 | 52 | return Keywords\DB2Keywords::class; |
|
880 | } |
||
881 | } |
||
882 |
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.