Passed
Pull Request — main (#122)
by Andreas
01:50
created

CratePlatform::getCreateDatabaseSQL()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * Licensed to CRATE Technology GmbH("Crate") under one or more contributor
4
 * license agreements.  See the NOTICE file distributed with this work for
5
 * additional information regarding copyright ownership.  Crate licenses
6
 * this file to you under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.  You may
8
 * obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
15
 * License for the specific language governing permissions and limitations
16
 * under the License.
17
 *
18
 * However, if you have executed another commercial license agreement
19
 * with Crate these terms will supersede the license and you may use the
20
 * software solely pursuant to the terms of the relevant commercial agreement.
21
 */
22
namespace Crate\DBAL\Platforms;
23
24
use Crate\DBAL\Types\MapType;
25
use Crate\DBAL\Types\TimestampType;
26
use Doctrine\DBAL\DBALException;
0 ignored issues
show
Bug introduced by
The type Doctrine\DBAL\DBALException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
use Doctrine\DBAL\Event\SchemaCreateTableColumnEventArgs;
28
use Doctrine\DBAL\Event\SchemaCreateTableEventArgs;
29
use Doctrine\DBAL\Events;
30
use Doctrine\DBAL\Platforms\AbstractPlatform;
31
use Doctrine\DBAL\Schema\Identifier;
32
use Doctrine\DBAL\Schema\Index;
33
use Doctrine\DBAL\Schema\Table;
34
use Doctrine\DBAL\Schema\TableDiff;
35
use Doctrine\DBAL\Types\Type;
36
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
37
use InvalidArgumentException;
38
39
class CratePlatform extends AbstractPlatform
40
{
41
42
    const TIMESTAMP_FORMAT =  'Y-m-d\TH:i:s';
43
    const TIMESTAMP_FORMAT_TZ =  'Y-m-d\TH:i:sO';
44
    const TABLE_WHERE_CLAUSE_FORMAT = '%s.table_name = %s AND %s.schema_name = %s';
45
46
    /**
47
     * {@inheritDoc}
48
     */
49 254
    public function __construct()
50
    {
51 254
        parent::__construct();
0 ignored issues
show
Bug introduced by
The method __construct() does not exist on Doctrine\DBAL\Platforms\AbstractPlatform. It seems like you code against a sub-type of Doctrine\DBAL\Platforms\AbstractPlatform such as Crate\DBAL\Platforms\CratePlatform. ( Ignorable by Annotation )

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

51
        parent::/** @scrutinizer ignore-call */ 
52
                __construct();
Loading history...
52 254
        $this->initializeDoctrineTypeMappings();
53 254
        if (!Type::hasType(MapType::NAME)) {
54
            Type::addType(MapType::NAME, 'Crate\DBAL\Types\MapType');
55
        }
56 254
        if (!Type::hasType(TimestampType::NAME)) {
57
            Type::addType(TimestampType::NAME, 'Crate\DBAL\Types\TimestampType');
58
        }
59 254
        Type::overrideType('array', 'Crate\DBAL\Types\ArrayType');
60
    }
61
62
    /**
63
     * {@inheritDoc}
64
     */
65 2
    public function getSubstringExpression($value, $from = 0, $length = null)
66
    {
67 2
        if ($length === null) {
68 2
            return 'SUBSTR(' . $value . ', ' . $from . ')';
69
        }
70
71 2
        return 'SUBSTR(' . $value . ', ' . $from . ', ' . $length . ')';
72
    }
73
74
    /**
75
     * {@inheritDoc}
76
     */
77 2
    public function getNowExpression()
78
    {
79 2
        throw DBALException::notSupported(__METHOD__);
80
    }
81
82
    /**
83
     * {@inheritDoc}
84
     */
85 2
    public function getRegexpExpression()
86
    {
87 2
        return 'LIKE';
88
    }
89
90
    /**
91
     * {@inheritDoc}
92
     */
93 2
    public function getDateDiffExpression($date1, $date2)
94
    {
95 2
        throw DBALException::notSupported(__METHOD__);
96
    }
97
98
    /**
99
     * {@inheritDoc}
100
     */
101 6
    public function supportsSequences()
102
    {
103 6
        return false;
104
    }
105
106
    /**
107
     * If we want to support Schemas, we need to implement
108
     * getListNamespacesSQL and getCreateSchemaSQL methods
109
     *
110
     * {@inheritDoc}
111
     */
112 6
    public function supportsSchemas()
113
    {
114 6
        return false;
115
    }
116
117
    /**
118
     * {@inheritDoc}
119
     */
120 2
    public function supportsIdentityColumns()
121
    {
122 2
        return true;
123
    }
124
125
    /**
126
     * {@inheritDoc}
127
     */
128 2
    public function supportsIndexes()
129
    {
130 2
        return false;
131
    }
132
133
    /**
134
     * {@inheritDoc}
135
     */
136 118
    public function supportsCommentOnStatement()
137
    {
138 118
        return false;
139
    }
140
141
    /**
142
     * {@inheritDoc}
143
     */
144 14
    public function supportsForeignKeyConstraints()
145
    {
146 14
        return false;
147
    }
148
149
    /**
150
     * {@inheritDoc}
151
     */
152 2
    public function supportsForeignKeyOnUpdate()
153
    {
154 2
        return false;
155
    }
156
157
    /**
158
     * {@inheritDoc}
159
     */
160 2
    public function supportsViews()
161
    {
162 2
        return false;
163
    }
164
165
    /**
166
     * {@inheritDoc}
167
     */
168 2
    public function prefersSequences()
169
    {
170 2
        return false;
171
    }
172
173
    /**
174
     * {@inheritDoc}
175
     */
176 2
    public function getListDatabasesSQL()
177
    {
178 2
        throw DBALException::notSupported(__METHOD__);
179
    }
180
181
    /**
182
     * {@inheritDoc}
183
     */
184
    public function getListTablesSQL()
185
    {
186
        return "SELECT table_name, schema_name FROM information_schema.tables " .
187
               "WHERE schema_name = 'doc' OR schema_name = 'blob'";
188
    }
189
190
    /**
191
     * {@inheritDoc}
192
     */
193 8
    public function getListTableColumnsSQL($table, $database = null)
194
    {
195 8
        return "SELECT * from information_schema.columns c " .
196 8
               "WHERE " . $this->getTableWhereClause($table);
197
    }
198
199
    /**
200
     * {@inheritDoc}
201
     */
202
    public function getListTableConstraintsSQL($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

202
    public function getListTableConstraintsSQL($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...
203
    {
204
        return "SELECT c.constraint_name, c.constraint_type " .
205
               "FROM information_schema.table_constraints c " .
206
               "WHERE " . $this->getTableWhereClause($table) . " AND constraint_type = 'PRIMARY KEY'";
207
    }
208
209
    /**
210
     * {@inheritDoc}
211
     */
212 8
    public function getListTableIndexesSQL($table, $currentDatabase = null)
213
    {
214 8
        return "SELECT c.constraint_name, c.constraint_type, k.column_name " .
215 8
               "FROM information_schema.table_constraints c " .
216 8
               "JOIN information_schema.key_column_usage k on c.constraint_name = k.constraint_name " .
217 8
               "WHERE " . $this->getTableWhereClause($table);
218
    }
219
220 10
    private function getTableWhereClause($table, $tableAlias = 'c')
221
    {
222 10
        if (strpos($table, '.') !== false) {
223
            [$schema, $table] = explode('.', $table);
224
            $schema = $this->quoteStringLiteral($schema);
225
        } else {
226 10
            $schema = $this->quoteStringLiteral('doc');
227
        }
228
229 10
        $table = new Identifier($table);
230 10
        $table = $this->quoteStringLiteral($table->getName());
231
232 10
        return sprintf(
233 10
            $this->getTableWhereClauseFormat(),
234 10
            $tableAlias,
235 10
            $table,
236 10
            $tableAlias,
237 10
            $schema
238 10
        );
239
    }
240
241
    /**
242
     * Return sprintf format string for usage at getTableWhereClause
243
     *
244
     * @return string
245
     */
246
    protected function getTableWhereClauseFormat()
247
    {
248
        return self::TABLE_WHERE_CLAUSE_FORMAT;
249
    }
250
251
    /**
252
     * {@inheritDoc}
253
     */
254 10
    public function getAlterTableSQL(TableDiff $diff)
255
    {
256 10
        $sql = array();
257 10
        $commentsSQL = array();
258 10
        $columnSql = array();
259
260 10
        foreach ($diff->addedColumns as $column) {
261 4
            if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
262
                continue;
263
            }
264
265 4
            $query = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
266 4
            $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
0 ignored issues
show
Deprecated Code introduced by
The property Doctrine\DBAL\Schema\TableDiff::$name has been deprecated: Use {@see getOldTable()} instead. ( Ignorable by Annotation )

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

266
            $sql[] = 'ALTER TABLE ' . /** @scrutinizer ignore-deprecated */ $diff->name . ' ' . $query;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
267 4
            if ($comment = $this->getColumnComment($column)) {
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Platforms\...orm::getColumnComment() has been deprecated: This method will be removed without replacement. ( Ignorable by Annotation )

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

267
            if ($comment = /** @scrutinizer ignore-deprecated */ $this->getColumnComment($column)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
268
                $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment);
0 ignored issues
show
Deprecated Code introduced by
The property Doctrine\DBAL\Schema\TableDiff::$name has been deprecated: Use {@see getOldTable()} instead. ( Ignorable by Annotation )

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

268
                $commentsSQL[] = $this->getCommentOnColumnSQL(/** @scrutinizer ignore-deprecated */ $diff->name, $column->getName(), $comment);

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
269
            }
270
        }
271
272 10
        if (count($diff->removedColumns) > 0) {
273
            throw DBALException::notSupported("Alter Table: drop columns");
274
        }
275 10
        if (count($diff->changedColumns) > 0) {
276
            throw DBALException::notSupported("Alter Table: change column options");
277
        }
278 10
        if (count($diff->renamedColumns) > 0) {
279
            throw DBALException::notSupported("Alter Table: rename columns");
280
        }
281
282 10
        $tableSql = array();
283
284 10
        if (!$this->onSchemaAlterTable($diff, $tableSql)) {
285 10
            if ($diff->newName !== false) {
0 ignored issues
show
Deprecated Code introduced by
The property Doctrine\DBAL\Schema\TableDiff::$newName has been deprecated: Rename tables via {@link AbstractSchemaManager::renameTable()} instead. ( Ignorable by Annotation )

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

285
            if (/** @scrutinizer ignore-deprecated */ $diff->newName !== false) {

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
286
                throw DBALException::notSupported("Alter Table: rename table");
287
            }
288
289 10
            $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL);
0 ignored issues
show
Bug introduced by
The method _getAlterTableIndexForeignKeySQL() does not exist on Crate\DBAL\Platforms\CratePlatform. ( Ignorable by Annotation )

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

289
            $sql = array_merge($sql, $this->/** @scrutinizer ignore-call */ _getAlterTableIndexForeignKeySQL($diff), $commentsSQL);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
290
        }
291
292 10
        return array_merge($sql, $tableSql, $columnSql);
293
    }
294
295
    /**
296
     * {@inheritDoc}
297
     */
298 126
    public function getColumnDeclarationSQL($name, array $column)
299
    {
300 126
        if (isset($column['columnDefinition'])) {
301 68
            $columnDef = $this->getCustomTypeDeclarationSQL($column);
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Platforms\...tomTypeDeclarationSQL() has been deprecated. ( Ignorable by Annotation )

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

301
            $columnDef = /** @scrutinizer ignore-deprecated */ $this->getCustomTypeDeclarationSQL($column);
Loading history...
302
        } else {
303 124
            $typeDecl = $column['type']->getSqlDeclaration($column, $this);
304 124
            $columnDef = $typeDecl;
305
        }
306
307 126
        return $name . ' ' . $columnDef;
308
    }
309
310
    /**
311
     * Generate table index column declaration
312
     * @codeCoverageIgnore
313
     */
314
    public function getIndexDeclarationSQL($name, Index $index)
315
    {
316
        $columns = $index->getQuotedColumns($this);
317
        $name = new Identifier($name);
318
319
        if (count($columns) == 0) {
320
            throw new \InvalidArgumentException("Incomplete definition. 'columns' required.");
321
        }
322
323
        return 'INDEX ' . $name->getQuotedName($this) .
324
               ' USING FULLTEXT ('. $this->getIndexFieldDeclarationListSQL($columns) . ')';
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Platforms\...eldDeclarationListSQL() has been deprecated. ( Ignorable by Annotation )

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

324
               ' USING FULLTEXT ('. /** @scrutinizer ignore-deprecated */ $this->getIndexFieldDeclarationListSQL($columns) . ')';
Loading history...
Bug introduced by
$columns of type string[] is incompatible with the type Doctrine\DBAL\Schema\Index expected by parameter $index of Doctrine\DBAL\Platforms\...eldDeclarationListSQL(). ( Ignorable by Annotation )

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

324
               ' USING FULLTEXT ('. $this->getIndexFieldDeclarationListSQL(/** @scrutinizer ignore-type */ $columns) . ')';
Loading history...
325
    }
326
327
    /**
328
     * {@inheritDoc}
329
     *
330
     * Crate wants boolean values converted to the strings 'true'/'false'.
331
     */
332 4
    public function convertBooleans($item)
333
    {
334 4
        if (is_array($item)) {
335 2
            foreach ($item as $key => $value) {
336 2
                if (is_bool($value)) {
337 2
                    $item[$key] = ($value) ? 'true' : 'false';
338 2
                } elseif (is_numeric($value)) {
339 2
                    $item[$key] = ($value > 0) ? 'true' : 'false';
340
                }
341
            }
342
        } else {
343 4
            if (is_bool($item)) {
344 4
                $item = ($item) ? 'true' : 'false';
345 2
            } elseif (is_numeric($item)) {
346 2
                $item = ($item > 0) ? 'true' : 'false';
347
            }
348
        }
349
350 4
        return $item;
351
    }
352
353
    /**
354
     * {@inheritDoc}
355
     */
356 22
    public function getBooleanTypeDeclarationSQL(array $field)
357
    {
358 22
        return 'BOOLEAN';
359
    }
360
361
    /**
362
     * {@inheritDoc}
363
     */
364 114
    public function getIntegerTypeDeclarationSQL(array $field)
365
    {
366 114
        return 'INTEGER';
367
    }
368
369
    /**
370
     * {@inheritDoc}
371
     */
372
    public function getBigIntTypeDeclarationSQL(array $field)
373
    {
374
        return 'LONG';
375
    }
376
377
    /**
378
     * {@inheritDoc}
379
     */
380
    public function getSmallIntTypeDeclarationSQL(array $field)
381
    {
382
        return 'SHORT';
383
    }
384
385
    /**
386
     * {@inheritDoc}
387
     */
388
    public function getFloatDeclarationSQL(array $field)
389
    {
390
        return 'DOUBLE';
391
    }
392
393
    /**
394
     * {@inheritDoc}
395
     */
396
    public function getDecimalTypeDeclarationSQL(array $columnDef)
397
    {
398
        return 'DOUBLE';
399
    }
400
401
    /**
402
     * {@inheritDoc}
403
     */
404 52
    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
405
    {
406 52
        return 'TIMESTAMP';
407
    }
408
409
    /**
410
     * {@inheritDoc}
411
     */
412 2
    public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
413
    {
414 2
        return 'TIMESTAMP';
415
    }
416
417
    /**
418
     * {@inheritDoc}
419
     */
420 2
    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
421
    {
422 2
        return 'TIMESTAMP';
423
    }
424
425
    /**
426
     * {@inheritDoc}
427
     */
428 2
    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
429
    {
430 2
        return 'TIMESTAMP';
431
    }
432
433
    /**
434
     * {@inheritDoc}
435
     */
436
    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
437
    {
438
        return '';
439
    }
440
441
    /**
442
     * {@inheritDoc}
443
     */
444
    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
445
    {
446
        return 'STRING';
447
    }
448
449
    /**
450
     * {@inheritDoc}
451
     */
452
    public function getClobTypeDeclarationSQL(array $field)
453
    {
454
        return 'STRING';
455
    }
456
457
    /**
458
     * {@inheritDoc}
459
     */
460 4
    public function getName()
461
    {
462 4
        return 'crate';
463
    }
464
465
    /**
466
     * {@inheritDoc}
467
     *
468
     * PostgreSQL returns all column names in SQL result sets in lowercase.
469
     */
470 2
    public function getSQLResultCasing($column)
471
    {
472 2
        return strtolower($column);
473
    }
474
475
    /**
476
     * {@inheritDoc}
477
     */
478 4
    public function getDateTimeTzFormatString()
479
    {
480 4
        return self::TIMESTAMP_FORMAT_TZ;
481
    }
482
483
    /**
484
     * {@inheritDoc}
485
     */
486 10
    public function getDateTimeFormatString()
487
    {
488 10
        return self::TIMESTAMP_FORMAT;
489
    }
490
491
    /**
492
     * {@inheritDoc}
493
     */
494 2
    public function getDateFormatString()
495
    {
496 2
        return self::TIMESTAMP_FORMAT;
497
    }
498
499
    /**
500
     * {@inheritDoc}
501
     */
502 2
    public function getTimeFormatString()
503
    {
504 2
        return self::TIMESTAMP_FORMAT;
505
    }
506
507
    /**
508
     * {@inheritDoc}
509
     */
510 2
    public function getTruncateTableSQL($tableName, $cascade = false)
511
    {
512 2
        throw DBALException::notSupported(__METHOD__);
513
    }
514
515
    /**
516
     * {@inheritDoc}
517
     */
518 2
    public function getReadLockSQL()
519
    {
520 2
        throw DBALException::notSupported(__METHOD__);
521
    }
522
523
    /**
524
     * {@inheritDoc}
525
     */
526 20
    protected function initializeDoctrineTypeMappings()
527
    {
528 20
        $this->doctrineTypeMapping = array(
529 20
            'short'         => 'smallint',
530 20
            'integer'       => 'integer',
531 20
            'long'          => 'bigint',
532 20
            'int'           => 'integer',
533 20
            'bool'          => 'boolean',
534 20
            'boolean'       => 'boolean',
535 20
            'string'        => 'string',
536 20
            'float'         => 'float',
537 20
            'double'        => 'float',
538 20
            'timestamp'     => 'timestamp',
539 20
            'object'        => 'map',
540 20
            'array'         => 'array',
541 20
        );
542
    }
543
544
    /**
545
     * {@inheritDoc}
546
     */
547 12
    public function getDoctrineTypeMapping($dbType)
548
    {
549
        // typed arrays will always end up in the same generic php array type
550 12
        if (substr_compare($dbType, 'array', -5) === 0) {
551 2
            $dbType = 'array';
552
        }
553 12
        return parent::getDoctrineTypeMapping($dbType);
554
    }
555
556
557
    /**
558
     * {@inheritDoc}
559
     */
560 112
    public function getVarcharMaxLength()
561
    {
562 112
        return PHP_INT_MAX;
563
    }
564
565
    /**
566
     * {@inheritDoc}
567
     */
568 54
    protected function getReservedKeywordsClass()
569
    {
570 54
        return 'Crate\DBAL\Platforms\Keywords\CrateKeywords';
571
    }
572
573
    /**
574
     * {@inheritDoc}
575
     */
576 2
    public function getBlobTypeDeclarationSQL(array $field)
577
    {
578 2
        throw DBALException::notSupported(__METHOD__);
579
    }
580
581
    /**
582
     * {@inheritDoc}
583
     * Gets the SQL statement(s) to create a table with the specified name, columns and constraints
584
     * on this platform.
585
     *
586
     * @param Table $table The name of the table.
587
     * @param integer $createFlags
588
     *
589
     * @return array The sequence of SQL statements.
590
     */
591 126
    public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES)
592
    {
593 126
        if (!is_int($createFlags)) {
0 ignored issues
show
introduced by
The condition is_int($createFlags) is always true.
Loading history...
594
            $msg = "Second argument of CratePlatform::getCreateTableSQL() has to be integer.";
595
            throw new InvalidArgumentException($msg);
596
        }
597
598 126
        if (count($table->getColumns()) === 0) {
599 4
            throw DBALException::noColumnsSpecifiedForTable($table->getName());
600
        }
601
602 122
        $tableName = $table->getQuotedName($this);
603 122
        $options = $table->getOptions();
604 122
        $options['uniqueConstraints'] = array();
605 122
        $options['indexes'] = array();
606 122
        $options['primary'] = array();
607
608 122
        if (($createFlags&self::CREATE_INDEXES) > 0) {
609 122
            foreach ($table->getIndexes() as $index) {
610
                /* @var $index Index */
611 88
                if ($index->isPrimary()) {
612 78
                    $platform = $this;
613 78
                    $options['primary'] = array_map(function ($columnName) use ($table, $platform) {
614 78
                        return $table->getColumn($columnName)->getQuotedName($platform);
615 78
                    }, $index->getColumns());
616 78
                    $options['primary_index'] = $index;
617 10
                } elseif ($index->isUnique()) {
618 4
                    throw DBALException::notSupported(
619 4
                        "Unique constraints are not supported. Use `primary key` instead"
620 4
                    );
621
                } else {
622 6
                    $options['indexes'][$index->getName()] = $index;
623
                }
624
            }
625
        }
626
627 118
        $columnSql = array();
628 118
        $columns = array();
629
630 118
        foreach ($table->getColumns() as $column) {
631 118
            if (null !== $this->_eventManager &&
0 ignored issues
show
Deprecated Code introduced by
The property Doctrine\DBAL\Platforms\...latform::$_eventManager has been deprecated. ( Ignorable by Annotation )

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

631
            if (null !== /** @scrutinizer ignore-deprecated */ $this->_eventManager &&
Loading history...
632 118
                $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)
0 ignored issues
show
introduced by
The constant Doctrine\DBAL\Events::onSchemaCreateTableColumn has been deprecated. ( Ignorable by Annotation )

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

632
                $this->_eventManager->hasListeners(/** @scrutinizer ignore-deprecated */ Events::onSchemaCreateTableColumn)
Loading history...
Deprecated Code introduced by
The property Doctrine\DBAL\Platforms\...latform::$_eventManager has been deprecated. ( Ignorable by Annotation )

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

632
                /** @scrutinizer ignore-deprecated */ $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)
Loading history...
633
            ) {
634 2
                $eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this);
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\DBAL\Event\Sche...ateTableColumnEventArgs has been deprecated. ( Ignorable by Annotation )

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

634
                $eventArgs = /** @scrutinizer ignore-deprecated */ new SchemaCreateTableColumnEventArgs($column, $table, $this);
Loading history...
635 2
                $this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs);
0 ignored issues
show
introduced by
The constant Doctrine\DBAL\Events::onSchemaCreateTableColumn has been deprecated. ( Ignorable by Annotation )

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

635
                $this->_eventManager->dispatchEvent(/** @scrutinizer ignore-deprecated */ Events::onSchemaCreateTableColumn, $eventArgs);
Loading history...
Deprecated Code introduced by
The property Doctrine\DBAL\Platforms\...latform::$_eventManager has been deprecated. ( Ignorable by Annotation )

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

635
                /** @scrutinizer ignore-deprecated */ $this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs);
Loading history...
636
637 2
                $columnSql = array_merge($columnSql, $eventArgs->getSql());
638
639 2
                if ($eventArgs->isDefaultPrevented()) {
640
                    continue;
641
                }
642
            }
643 118
            $columns[$column->getQuotedName($this)] = self::prepareColumnData($this, $column, $options['primary']);
644
        }
645
646 116
        if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) {
0 ignored issues
show
Deprecated Code introduced by
The property Doctrine\DBAL\Platforms\...latform::$_eventManager has been deprecated. ( Ignorable by Annotation )

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

646
        if (null !== $this->_eventManager && /** @scrutinizer ignore-deprecated */ $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) {
Loading history...
introduced by
The constant Doctrine\DBAL\Events::onSchemaCreateTable has been deprecated. ( Ignorable by Annotation )

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

646
        if (null !== $this->_eventManager && $this->_eventManager->hasListeners(/** @scrutinizer ignore-deprecated */ Events::onSchemaCreateTable)) {
Loading history...
647 2
            $eventArgs = new SchemaCreateTableEventArgs($table, $columns, $options, $this);
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\DBAL\Event\SchemaCreateTableEventArgs has been deprecated. ( Ignorable by Annotation )

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

647
            $eventArgs = /** @scrutinizer ignore-deprecated */ new SchemaCreateTableEventArgs($table, $columns, $options, $this);
Loading history...
648 2
            $this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs);
0 ignored issues
show
introduced by
The constant Doctrine\DBAL\Events::onSchemaCreateTable has been deprecated. ( Ignorable by Annotation )

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

648
            $this->_eventManager->dispatchEvent(/** @scrutinizer ignore-deprecated */ Events::onSchemaCreateTable, $eventArgs);
Loading history...
Deprecated Code introduced by
The property Doctrine\DBAL\Platforms\...latform::$_eventManager has been deprecated. ( Ignorable by Annotation )

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

648
            /** @scrutinizer ignore-deprecated */ $this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs);
Loading history...
649
650 2
            if ($eventArgs->isDefaultPrevented()) {
651
                return array_merge($eventArgs->getSql(), $columnSql);
652
            }
653
        }
654
655 116
        $sql = $this->_getCreateTableSQL($tableName, $columns, $options);
656 114
        if ($this->supportsCommentOnStatement()) {
657
            foreach ($table->getColumns() as $column) {
658
                if ($this->getColumnComment($column)) {
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Platforms\...orm::getColumnComment() has been deprecated: This method will be removed without replacement. ( Ignorable by Annotation )

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

658
                if (/** @scrutinizer ignore-deprecated */ $this->getColumnComment($column)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
659
                    $sql[] = $this->getCommentOnColumnSQL(
660
                        $tableName,
661
                        $column->getName(),
662
                        $this->getColumnComment($column)
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Platforms\...orm::getColumnComment() has been deprecated: This method will be removed without replacement. ( Ignorable by Annotation )

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

662
                        /** @scrutinizer ignore-deprecated */ $this->getColumnComment($column)

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
663
                    );
664
                }
665
            }
666
        }
667
668 114
        return array_merge($sql, $columnSql);
669
    }
670
671
    /**
672
     * {@inheritDoc}
673
     */
674 116
    protected function _getCreateTableSQL($name, array $columns, array $options = array())
675
    {
676 116
        $columnListSql = $this->getColumnDeclarationListSQL($columns);
677
678 116
        if (isset($options['primary']) && ! empty($options['primary'])) {
679 78
            $keyColumns = array_unique(array_values($options['primary']));
680 78
            $columnListSql .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
681
        }
682
683 116
        if (isset($options['indexes']) && ! empty($options['indexes'])) {
684 6
            foreach ($options['indexes'] as $index => $definition) {
685 6
                $columnListSql .= ', ' . $this->getIndexDeclarationSQL($index, $definition);
686
            }
687
        }
688
 
689 116
        if (isset($options['foreignKeys'])) {
690
            throw DBALException::notSupported("Create Table: foreign keys");
691
        }
692
693 116
        $query = 'CREATE TABLE ' . $name . ' (' . $columnListSql . ')';
694 116
        $query .= $this->buildShardingOptions($options);
695 116
        $query .= $this->buildPartitionOptions($options);
696 114
        $query .= $this->buildTableOptions($options);
697 114
        return array($query);
698
    }
699
700
    /**
701
     * Build SQL for table options
702
     *
703
     * @param mixed[] $options
704
     *
705
     * @return string
706
     */
707 114
    private function buildTableOptions(array $options)
708
    {
709 114
        if (! isset($options['table_options'])) {
710 110
            return '';
711
        }
712
713 4
        $tableOptions = [];
714 4
        foreach ($options['table_options'] as $key => $val) {
715 4
            $tableOptions[] = sprintf('"%s" = %s', $key, $this->quoteStringLiteral($val));
716
        }
717 4
        if (count($tableOptions) == 0) {
718
            return '';
719
        }
720
721 4
        return sprintf(' WITH (%s)', implode(', ', $tableOptions));
722
    }
723
724
    /**
725
     * Build SQL for sharding options.
726
     *
727
     * @param mixed[] $options
728
     *
729
     * @return string
730
     */
731 116
    private function buildShardingOptions(array $options)
732
    {
733 116
        $shardingOptions = [];
734
735 116
        if (isset($options['sharding_routing_column'])) {
736 4
            $columnName = new Identifier($options['sharding_routing_column']);
737 4
            $shardingOptions[] = sprintf('BY (%s)', $columnName->getQuotedName($this));
738
        }
739 116
        if (isset($options['sharding_num_shards'])) {
740 4
            $shardingOptions[] = sprintf("INTO %d SHARDS", $options['sharding_num_shards']);
741
        }
742
743 116
        if (count($shardingOptions) == 0) {
744 112
            return '';
745
        }
746
747 4
        return sprintf(" CLUSTERED %s", implode(' ', $shardingOptions));
748
    }
749
750
    /**
751
     * Build SQL for partition options.
752
     *
753
     * @param mixed[] $options
754
     *
755
     * @return string
756
     */
757 116
    private function buildPartitionOptions(array $options)
758
    {
759 116
        if (! isset($options['partition_columns'])) {
760 110
            return '';
761
        }
762 6
        $columns = $options['partition_columns'];
763 6
        if (! is_array($columns)) {
764 2
            throw new InvalidArgumentException(sprintf("Expecting array type at 'partition_columns'"));
765
        }
766 4
        $quotedNames = [];
767 4
        foreach ($columns as $name) {
768 4
            $name = new Identifier($name);
769 4
            $quotedNames[] = $name->getQuotedName($this);
770
        }
771
772 4
        return sprintf(" PARTITIONED BY (%s)", implode(', ', $quotedNames));
773
    }
774
775
    /**
776
     * @param \Doctrine\DBAL\Schema\Column $column The name of the table.
777
     * @param array List of primary key column names
0 ignored issues
show
Bug introduced by
The type Crate\DBAL\Platforms\List was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
778
     *
779
     * @return array The column data as associative array.
780
     * @throws DBALException
781
     */
782 122
    public static function prepareColumnData(AbstractPlatform $platform, $column, $primaries = array())
783
    {
784 122
        if ($column->hasCustomSchemaOption("unique") ? $column->getCustomSchemaOption("unique") : false) {
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\Schema\Col...hasCustomSchemaOption() has been deprecated: Use {@link hasPlatformOption()} instead ( Ignorable by Annotation )

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

784
        if (/** @scrutinizer ignore-deprecated */ $column->hasCustomSchemaOption("unique") ? $column->getCustomSchemaOption("unique") : false) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
Deprecated Code introduced by
The function Doctrine\DBAL\Schema\Col...getCustomSchemaOption() has been deprecated: Use {@link getPlatformOption()} instead ( Ignorable by Annotation )

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

784
        if ($column->hasCustomSchemaOption("unique") ? /** @scrutinizer ignore-deprecated */ $column->getCustomSchemaOption("unique") : false) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
785 2
            throw DBALException::notSupported("Unique constraints are not supported. Use `primary key` instead");
786
        }
787
788 120
        $columnData = array();
789 120
        $columnData['name'] = $column->getQuotedName($platform);
790 120
        $columnData['type'] = $column->getType();
791 120
        $columnData['length'] = $column->getLength();
792 120
        $columnData['notnull'] = $column->getNotNull();
793 120
        $columnData['fixed'] = $column->getFixed();
794 120
        $columnData['unique'] = false;
795 120
        $columnData['version'] = $column->hasPlatformOption("version") ? $column->getPlatformOption("version") : false;
796
797 120
        if (strtolower($columnData['type']) == $platform->getVarcharTypeDeclarationSQLSnippet(0, false)
798 120
                && $columnData['length'] === null) {
799
            $columnData['length'] = 255;
800
        }
801
802 120
        $columnData['unsigned'] = $column->getUnsigned();
803 120
        $columnData['precision'] = $column->getPrecision();
804 120
        $columnData['scale'] = $column->getScale();
805 120
        $columnData['default'] = $column->getDefault();
806 120
        $columnData['columnDefinition'] = $column->getColumnDefinition();
807 120
        $columnData['autoincrement'] = $column->getAutoincrement();
808 120
        $columnData['comment'] = $platform->getColumnComment($column);
809 120
        $columnData['platformOptions'] = $column->getPlatformOptions();
810
811 120
        if (in_array($column->getName(), $primaries)) {
812 76
            $columnData['primary'] = true;
813
        }
814 120
        return $columnData;
815
    }
816
817
    /**
818
     * {@inheritDoc}
819
     */
820 2
    public function getCreateDatabaseSQL($database)
821
    {
822 2
        throw DBALException::notSupported(__METHOD__);
823
    }
824
825
    /**
826
     * {@inheritDoc}
827
     */
828 2
    public function getDropDatabaseSQL($database)
829
    {
830 2
        throw DBALException::notSupported(__METHOD__);
831
    }
832
    
833
    /**
834
     * {@inheritDoc}
835
     */
836 2
    public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table)
837
    {
838 2
        throw DBALException::notSupported(__METHOD__);
839
    }
840
    
841
    /**
842
     * {@inheritDoc}
843
     */
844 2
    public function getGuidTypeDeclarationSQL(array $field)
845
    {
846 2
        throw DBALException::notSupported(__METHOD__);
847
    }
848
849
    /**
850
     * Returns the SQL query to return the CrateDB specific table options associated
851
     * with a given table.
852
     *
853
     * @return string
854
     */
855 6
    public function getTableOptionsSQL(string $table) : string
856
    {
857 6
        return "SELECT clustered_by, number_of_shards, partitioned_by, number_of_replicas, column_policy, settings " .
858 6
               "FROM information_schema.tables c " .
859 6
               "WHERE " . $this->getTableWhereClause($table);
860
    }
861
862
    /**
863
     * {@inheritDoc}
864
     */
865
    public function getCurrentDatabaseExpression(): string
866
    {
867
        // TODO: Implement getCurrentDatabaseExpression() method.
868
        //       Added when upgrading to Doctrine3.
869
    }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return string. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
870
}
871