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

CratePlatform::getSubstringExpression()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 10
cc 2
nc 2
nop 3
crap 2
1
<?php
2
3
/**
4
 * Licensed to CRATE Technology GmbH("Crate") under one or more contributor
5
 * license agreements.  See the NOTICE file distributed with this work for
6
 * additional information regarding copyright ownership.  Crate licenses
7
 * this file to you under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.  You may
9
 * obtain a copy of the License at
10
 *
11
 * http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
16
 * License for the specific language governing permissions and limitations
17
 * under the License.
18
 *
19
 * However, if you have executed another commercial license agreement
20
 * with Crate these terms will supersede the license and you may use the
21
 * software solely pursuant to the terms of the relevant commercial agreement.
22
 */
23
24
namespace Crate\DBAL\Platforms;
25
26
use Crate\DBAL\Types\MapType;
27
use Crate\DBAL\Types\TimestampType;
28
use Doctrine\DBAL\Event\SchemaCreateTableColumnEventArgs;
29
use Doctrine\DBAL\Event\SchemaCreateTableEventArgs;
30
use Doctrine\DBAL\Events;
31
use Doctrine\DBAL\Exception as DBALException;
32
use Doctrine\DBAL\Platforms\AbstractPlatform;
33
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
34
use Doctrine\DBAL\Schema\Identifier;
35
use Doctrine\DBAL\Schema\Index;
36
use Doctrine\DBAL\Schema\Table;
37
use Doctrine\DBAL\Schema\TableDiff;
38
use Doctrine\DBAL\Types\Type;
39
use InvalidArgumentException;
40
41
class CratePlatform extends AbstractPlatform
42
{
43
    public const TIMESTAMP_FORMAT =  'Y-m-d\TH:i:s';
44
    public const TIMESTAMP_FORMAT_TZ =  'Y-m-d\TH:i:sO';
45
    public const TABLE_WHERE_CLAUSE_FORMAT = '%s.table_name = %s AND %s.schema_name = %s';
46
47
    /**
48
     * {@inheritDoc}
49
     */
50 260
    public function __construct()
51
    {
52 260
        $this->initializeDoctrineTypeMappings();
53 260
        if (!Type::hasType(MapType::NAME)) {
54
            Type::addType(MapType::NAME, 'Crate\DBAL\Types\MapType');
55
        }
56 260
        if (!Type::hasType(TimestampType::NAME)) {
57
            Type::addType(TimestampType::NAME, 'Crate\DBAL\Types\TimestampType');
58
        }
59 260
        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 8
    public function supportsSequences()
102
    {
103 8
        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 10
    public function supportsSchemas()
113
    {
114 10
        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 114
    public function supportsCommentOnStatement()
137
    {
138 114
        return false;
139
    }
140
141
    /**
142
     * {@inheritDoc}
143
     */
144 10
    public function supportsForeignKeyConstraints()
145
    {
146 10
        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 6
    public function getAlterTableSQL(TableDiff $diff)
255
    {
256 6
        $sql = array();
257 6
        $commentsSQL = array();
258 6
        $columnSql = array();
259
260 6
        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 6
        if (count($diff->removedColumns) > 0) {
273
            throw DBALException::notSupported("Alter Table: drop columns");
274
        }
275 6
        if (count($diff->changedColumns) > 0) {
276
            throw DBALException::notSupported("Alter Table: change column options");
277
        }
278 6
        if (count($diff->renamedColumns) > 0) {
279
            throw DBALException::notSupported("Alter Table: rename columns");
280
        }
281
282 6
        $tableSql = array();
283
284 6
        if (!$this->onSchemaAlterTable($diff, $tableSql)) {
285 6
            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 6
            $sql = array_merge($sql, $this->getPreAlterTableIndexForeignKeySQL($diff), $commentsSQL);
290
        }
291
292 6
        return array_merge($sql, $tableSql, $columnSql);
293
    }
294
295
    /**
296
     * {@inheritDoc}
297
     */
298 124
    public function getColumnDeclarationSQL($name, array $column)
299
    {
300 124
        if (isset($column['columnDefinition'])) {
301 64
            $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 122
            $typeDecl = $column['type']->getSqlDeclaration($column, $this);
304 122
            $columnDef = $typeDecl;
305
        }
306
307 124
        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($index) . ')';
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($index) . ')';
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 110
    public function getIntegerTypeDeclarationSQL(array $field)
365
    {
366 110
        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 50
    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
405
    {
406 50
        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
    // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore
437
    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
438
    {
439
        return '';
440
    }
441
442
    /**
443
     * {@inheritDoc}
444
     */
445
    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
446
    {
447
        return 'STRING';
448
    }
449
450
    /**
451
     * {@inheritDoc}
452
     */
453
    public function getClobTypeDeclarationSQL(array $field)
454
    {
455
        return 'STRING';
456
    }
457
458
    /**
459
     * {@inheritDoc}
460
     */
461
    public function getName()
462
    {
463
        return 'crate';
464
    }
465
466
    /**
467
     * {@inheritDoc}
468
     *
469
     * PostgreSQL returns all column names in SQL result sets in lowercase.
470
     */
471 2
    public function getSQLResultCasing($column)
472
    {
473 2
        return strtolower($column);
474
    }
475
476
    /**
477
     * {@inheritDoc}
478
     */
479 4
    public function getDateTimeTzFormatString()
480
    {
481 4
        return self::TIMESTAMP_FORMAT_TZ;
482
    }
483
484
    /**
485
     * {@inheritDoc}
486
     */
487 10
    public function getDateTimeFormatString()
488
    {
489 10
        return self::TIMESTAMP_FORMAT;
490
    }
491
492
    /**
493
     * {@inheritDoc}
494
     */
495 2
    public function getDateFormatString()
496
    {
497 2
        return self::TIMESTAMP_FORMAT;
498
    }
499
500
    /**
501
     * {@inheritDoc}
502
     */
503 2
    public function getTimeFormatString()
504
    {
505 2
        return self::TIMESTAMP_FORMAT;
506
    }
507
508
    /**
509
     * {@inheritDoc}
510
     */
511 2
    public function getTruncateTableSQL($tableName, $cascade = false)
512
    {
513 2
        throw DBALException::notSupported(__METHOD__);
514
    }
515
516
    /**
517
     * {@inheritDoc}
518
     */
519 2
    public function getReadLockSQL()
520
    {
521 2
        throw DBALException::notSupported(__METHOD__);
522
    }
523
524
    /**
525
     * {@inheritDoc}
526
     */
527 20
    protected function initializeDoctrineTypeMappings()
528
    {
529 20
        $this->doctrineTypeMapping = array(
530 20
            'short'         => 'smallint',
531 20
            'integer'       => 'integer',
532 20
            'long'          => 'bigint',
533 20
            'int'           => 'integer',
534 20
            'bool'          => 'boolean',
535 20
            'boolean'       => 'boolean',
536 20
            'string'        => 'string',
537 20
            'float'         => 'float',
538 20
            'double'        => 'float',
539 20
            'timestamp'     => 'timestamp',
540 20
            'object'        => 'map',
541 20
            'array'         => 'array',
542 20
        );
543
    }
544
545
    /**
546
     * {@inheritDoc}
547
     */
548 14
    public function getDoctrineTypeMapping($dbType)
549
    {
550
        // typed arrays will always end up in the same generic php array type
551 14
        if (substr_compare($dbType, 'array', -5) === 0) {
552 2
            $dbType = 'array';
553
        }
554 14
        return parent::getDoctrineTypeMapping($dbType);
555
    }
556
557
558
    /**
559
     * {@inheritDoc}
560
     */
561 108
    public function getVarcharMaxLength()
562
    {
563 108
        return PHP_INT_MAX;
564
    }
565
566
    /**
567
     * {@inheritDoc}
568
     */
569 54
    protected function getReservedKeywordsClass()
570
    {
571 54
        return 'Crate\DBAL\Platforms\Keywords\CrateKeywords';
572
    }
573
574
    /**
575
     * {@inheritDoc}
576
     */
577 2
    public function getBlobTypeDeclarationSQL(array $field)
578
    {
579 2
        throw DBALException::notSupported(__METHOD__);
580
    }
581
582
    /**
583
     * {@inheritDoc}
584
     * Gets the SQL statement(s) to create a table with the specified name, columns and constraints
585
     * on this platform.
586
     *
587
     * @param Table $table The name of the table.
588
     * @param integer $createFlags
589
     *
590
     * @return array The sequence of SQL statements.
591
     */
592 122
    public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES)
593
    {
594 122
        if (!is_int($createFlags)) {
0 ignored issues
show
introduced by
The condition is_int($createFlags) is always true.
Loading history...
595
            $msg = "Second argument of CratePlatform::getCreateTableSQL() has to be integer.";
596
            throw new InvalidArgumentException($msg);
597
        }
598
599 122
        if (count($table->getColumns()) === 0) {
600 4
            throw DBALException::noColumnsSpecifiedForTable($table->getName());
601
        }
602
603 118
        $tableName = $table->getQuotedName($this);
604 118
        $options = $table->getOptions();
605 118
        $options['uniqueConstraints'] = array();
606 118
        $options['indexes'] = array();
607 118
        $options['primary'] = array();
608
609 118
        if (($createFlags & self::CREATE_INDEXES) > 0) {
610 118
            foreach ($table->getIndexes() as $index) {
611
                /* @var $index Index */
612 84
                if ($index->isPrimary()) {
613 74
                    $platform = $this;
614 74
                    $options['primary'] = array_map(function ($columnName) use ($table, $platform) {
615 74
                        return $table->getColumn($columnName)->getQuotedName($platform);
616 74
                    }, $index->getColumns());
617 74
                    $options['primary_index'] = $index;
618 10
                } elseif ($index->isUnique()) {
619 4
                    throw DBALException::notSupported(
620 4
                        "Unique constraints are not supported. Use `primary key` instead"
621 4
                    );
622
                } else {
623 6
                    $options['indexes'][$index->getName()] = $index;
624
                }
625
            }
626
        }
627
628 114
        $columnSql = array();
629 114
        $columns = array();
630
631 114
        foreach ($table->getColumns() as $column) {
632 114
            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

632
            if (null !== /** @scrutinizer ignore-deprecated */ $this->_eventManager &&
Loading history...
633 114
                $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)
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

633
                /** @scrutinizer ignore-deprecated */ $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)
Loading history...
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

633
                $this->_eventManager->hasListeners(/** @scrutinizer ignore-deprecated */ Events::onSchemaCreateTableColumn)
Loading history...
634
            ) {
635 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

635
                $eventArgs = /** @scrutinizer ignore-deprecated */ new SchemaCreateTableColumnEventArgs($column, $table, $this);
Loading history...
636 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

636
                $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

636
                /** @scrutinizer ignore-deprecated */ $this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs);
Loading history...
637
638 2
                $columnSql = array_merge($columnSql, $eventArgs->getSql());
639
640 2
                if ($eventArgs->isDefaultPrevented()) {
641
                    continue;
642
                }
643
            }
644 114
            $columns[$column->getQuotedName($this)] = self::prepareColumnData($this, $column, $options['primary']);
645
        }
646
647 112
        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

647
        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

647
        if (null !== $this->_eventManager && $this->_eventManager->hasListeners(/** @scrutinizer ignore-deprecated */ Events::onSchemaCreateTable)) {
Loading history...
648 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

648
            $eventArgs = /** @scrutinizer ignore-deprecated */ new SchemaCreateTableEventArgs($table, $columns, $options, $this);
Loading history...
649 2
            $this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs);
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

649
            /** @scrutinizer ignore-deprecated */ $this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs);
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

649
            $this->_eventManager->dispatchEvent(/** @scrutinizer ignore-deprecated */ Events::onSchemaCreateTable, $eventArgs);
Loading history...
650
651 2
            if ($eventArgs->isDefaultPrevented()) {
652
                return array_merge($eventArgs->getSql(), $columnSql);
653
            }
654
        }
655
656 112
        $sql = $this->_getCreateTableSQL($tableName, $columns, $options);
657 110
        if ($this->supportsCommentOnStatement()) {
658
            foreach ($table->getColumns() as $column) {
659
                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

659
                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...
660
                    $sql[] = $this->getCommentOnColumnSQL(
661
                        $tableName,
662
                        $column->getName(),
663
                        $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

663
                        /** @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...
664
                    );
665
                }
666
            }
667
        }
668
669 110
        return array_merge($sql, $columnSql);
670
    }
671
672
    /**
673
     * {@inheritDoc}
674
     */
675
    // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore
676 112
    protected function _getCreateTableSQL($name, array $columns, array $options = array())
677
    {
678 112
        $columnListSql = $this->getColumnDeclarationListSQL($columns);
679
680 112
        if (isset($options['primary']) && ! empty($options['primary'])) {
681 74
            $keyColumns = array_unique(array_values($options['primary']));
682 74
            $columnListSql .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
683
        }
684
685 112
        if (isset($options['indexes']) && ! empty($options['indexes'])) {
686 6
            foreach ($options['indexes'] as $index => $definition) {
687 6
                $columnListSql .= ', ' . $this->getIndexDeclarationSQL($index, $definition);
688
            }
689
        }
690
691 112
        if (isset($options['foreignKeys'])) {
692
            throw DBALException::notSupported("Create Table: foreign keys");
693
        }
694
695 112
        $query = 'CREATE TABLE ' . $name . ' (' . $columnListSql . ')';
696 112
        $query .= $this->buildShardingOptions($options);
697 112
        $query .= $this->buildPartitionOptions($options);
698 110
        $query .= $this->buildTableOptions($options);
699 110
        return array($query);
700
    }
701
702
    /**
703
     * Build SQL for table options
704
     *
705
     * @param mixed[] $options
706
     *
707
     * @return string
708
     */
709 110
    private function buildTableOptions(array $options)
710
    {
711 110
        if (! isset($options['table_options'])) {
712 106
            return '';
713
        }
714
715 4
        $tableOptions = [];
716 4
        foreach ($options['table_options'] as $key => $val) {
717 4
            $tableOptions[] = sprintf('"%s" = %s', $key, $this->quoteStringLiteral($val));
718
        }
719 4
        if (count($tableOptions) == 0) {
720
            return '';
721
        }
722
723 4
        return sprintf(' WITH (%s)', implode(', ', $tableOptions));
724
    }
725
726
    /**
727
     * Build SQL for sharding options.
728
     *
729
     * @param mixed[] $options
730
     *
731
     * @return string
732
     */
733 112
    private function buildShardingOptions(array $options)
734
    {
735 112
        $shardingOptions = [];
736
737 112
        if (isset($options['sharding_routing_column'])) {
738 4
            $columnName = new Identifier($options['sharding_routing_column']);
739 4
            $shardingOptions[] = sprintf('BY (%s)', $columnName->getQuotedName($this));
740
        }
741 112
        if (isset($options['sharding_num_shards'])) {
742 4
            $shardingOptions[] = sprintf("INTO %d SHARDS", $options['sharding_num_shards']);
743
        }
744
745 112
        if (count($shardingOptions) == 0) {
746 108
            return '';
747
        }
748
749 4
        return sprintf(" CLUSTERED %s", implode(' ', $shardingOptions));
750
    }
751
752
    /**
753
     * Build SQL for partition options.
754
     *
755
     * @param mixed[] $options
756
     *
757
     * @return string
758
     */
759 112
    private function buildPartitionOptions(array $options)
760
    {
761 112
        if (! isset($options['partition_columns'])) {
762 106
            return '';
763
        }
764 6
        $columns = $options['partition_columns'];
765 6
        if (! is_array($columns)) {
766 2
            throw new InvalidArgumentException(sprintf("Expecting array type at 'partition_columns'"));
767
        }
768 4
        $quotedNames = [];
769 4
        foreach ($columns as $name) {
770 4
            $name = new Identifier($name);
771 4
            $quotedNames[] = $name->getQuotedName($this);
772
        }
773
774 4
        return sprintf(" PARTITIONED BY (%s)", implode(', ', $quotedNames));
775
    }
776
777
    /**
778
     * @param \Doctrine\DBAL\Schema\Column $column The name of the table.
779
     * @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...
780
     *
781
     * @return array The column data as associative array.
782
     * @throws DBALException
783
     */
784 118
    public static function prepareColumnData(AbstractPlatform $platform, $column, $primaries = array())
785
    {
786 118
        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

786
        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

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