Failed Conditions
Pull Request — master (#2929)
by Alexander
62:06
created

AbstractPlatform::getDropPrimaryKeySQL()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 1
crap 2
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\DBAL\Platforms;
21
22
use Doctrine\Common\EventManager;
23
use Doctrine\DBAL\DBALException;
24
use Doctrine\DBAL\Event\SchemaAlterTableAddColumnEventArgs;
25
use Doctrine\DBAL\Event\SchemaAlterTableChangeColumnEventArgs;
26
use Doctrine\DBAL\Event\SchemaAlterTableEventArgs;
27
use Doctrine\DBAL\Event\SchemaAlterTableRemoveColumnEventArgs;
28
use Doctrine\DBAL\Event\SchemaAlterTableRenameColumnEventArgs;
29
use Doctrine\DBAL\Event\SchemaCreateTableColumnEventArgs;
30
use Doctrine\DBAL\Event\SchemaCreateTableEventArgs;
31
use Doctrine\DBAL\Event\SchemaDropTableEventArgs;
32
use Doctrine\DBAL\Events;
33
use Doctrine\DBAL\Schema\Column;
34
use Doctrine\DBAL\Schema\ColumnDiff;
35
use Doctrine\DBAL\Schema\Constraint;
36
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
37
use Doctrine\DBAL\Schema\Identifier;
38
use Doctrine\DBAL\Schema\Index;
39
use Doctrine\DBAL\Schema\Sequence;
40
use Doctrine\DBAL\Schema\Table;
41
use Doctrine\DBAL\Schema\TableDiff;
42
use Doctrine\DBAL\TransactionIsolationLevel;
43
use Doctrine\DBAL\Types;
44
use Doctrine\DBAL\Types\Type;
45
use function addcslashes;
46
use function preg_quote;
47
use function preg_replace;
48
use function sprintf;
49
use function strlen;
50
51
/**
52
 * Base class for all DatabasePlatforms. The DatabasePlatforms are the central
53
 * point of abstraction of platform-specific behaviors, features and SQL dialects.
54
 * They are a passive source of information.
55
 *
56
 * @link   www.doctrine-project.org
57
 * @since  2.0
58
 * @author Guilherme Blanco <[email protected]>
59
 * @author Jonathan Wage <[email protected]>
60
 * @author Roman Borschel <[email protected]>
61
 * @author Lukas Smith <[email protected]> (PEAR MDB2 library)
62
 * @author Benjamin Eberlei <[email protected]>
63
 * @todo   Remove any unnecessary methods.
64
 */
65
abstract class AbstractPlatform
66
{
67
    /**
68
     * @var int
69
     */
70
    const CREATE_INDEXES = 1;
71
72
    /**
73
     * @var int
74
     */
75
    const CREATE_FOREIGNKEYS = 2;
76
77
    /**
78
     * @deprecated Use DateIntervalUnit::INTERVAL_UNIT_SECOND.
79
     */
80
    public const DATE_INTERVAL_UNIT_SECOND = DateIntervalUnit::SECOND;
81
82
    /**
83
     * @deprecated Use DateIntervalUnit::MINUTE.
84
     */
85
    public const DATE_INTERVAL_UNIT_MINUTE = DateIntervalUnit::MINUTE;
86
87
    /**
88
     * @deprecated Use DateIntervalUnit::HOUR.
89
     */
90
    public const DATE_INTERVAL_UNIT_HOUR = DateIntervalUnit::HOUR;
91
92
    /**
93
     * @deprecated Use DateIntervalUnit::DAY.
94
     */
95
    public const DATE_INTERVAL_UNIT_DAY = DateIntervalUnit::DAY;
96
97
    /**
98
     * @deprecated Use DateIntervalUnit::WEEK.
99
     */
100
    public const DATE_INTERVAL_UNIT_WEEK = DateIntervalUnit::WEEK;
101
102
    /**
103
     * @deprecated Use DateIntervalUnit::MONTH.
104
     */
105
    public const DATE_INTERVAL_UNIT_MONTH = DateIntervalUnit::MONTH;
106
107
    /**
108
     * @deprecated Use DateIntervalUnit::QUARTER.
109
     */
110
    public const DATE_INTERVAL_UNIT_QUARTER = DateIntervalUnit::QUARTER;
111
112
    /**
113
     * @deprecated Use DateIntervalUnit::QUARTER.
114
     */
115
    public const DATE_INTERVAL_UNIT_YEAR = DateIntervalUnit::YEAR;
116
117
    /**
118
     * @var int
119
     *
120
     * @deprecated Use TrimMode::UNSPECIFIED.
121
     */
122
    public const TRIM_UNSPECIFIED = TrimMode::UNSPECIFIED;
123
124
    /**
125
     * @var int
126
     *
127
     * @deprecated Use TrimMode::LEADING.
128
     */
129
    public const TRIM_LEADING = TrimMode::LEADING;
130
131
    /**
132
     * @var int
133
     *
134
     * @deprecated Use TrimMode::TRAILING.
135
     */
136
    public const TRIM_TRAILING = TrimMode::TRAILING;
137
138
    /**
139
     * @var int
140
     *
141
     * @deprecated Use TrimMode::BOTH.
142
     */
143
    public const TRIM_BOTH = TrimMode::BOTH;
144
145
    /**
146
     * @var array|null
147
     */
148
    protected $doctrineTypeMapping = null;
149
150
    /**
151
     * Contains a list of all columns that should generate parseable column comments for type-detection
152
     * in reverse engineering scenarios.
153
     *
154
     * @var array|null
155
     */
156
    protected $doctrineTypeComments = null;
157
158
    /**
159
     * @var \Doctrine\Common\EventManager
160
     */
161
    protected $_eventManager;
162
163
    /**
164
     * Holds the KeywordList instance for the current platform.
165
     *
166
     * @var \Doctrine\DBAL\Platforms\Keywords\KeywordList
167
     */
168
    protected $_keywords;
169
170
    /**
171
     * Constructor.
172
     */
173 3422
    public function __construct()
174
    {
175 3422
    }
176
177
    /**
178
     * Sets the EventManager used by the Platform.
179
     *
180
     * @param \Doctrine\Common\EventManager $eventManager
181
     */
182 81
    public function setEventManager(EventManager $eventManager)
183
    {
184 81
        $this->_eventManager = $eventManager;
185 81
    }
186
187
    /**
188
     * Gets the EventManager used by the Platform.
189
     *
190
     * @return \Doctrine\Common\EventManager
191
     */
192 45
    public function getEventManager()
193
    {
194 45
        return $this->_eventManager;
195
    }
196
197
    /**
198
     * Returns the SQL snippet that declares a boolean column.
199
     *
200
     * @param array $columnDef
201
     *
202
     * @return string
203
     */
204
    abstract public function getBooleanTypeDeclarationSQL(array $columnDef);
205
206
    /**
207
     * Returns the SQL snippet that declares a 4 byte integer column.
208
     *
209
     * @param array $columnDef
210
     *
211
     * @return string
212
     */
213
    abstract public function getIntegerTypeDeclarationSQL(array $columnDef);
214
215
    /**
216
     * Returns the SQL snippet that declares an 8 byte integer column.
217
     *
218
     * @param array $columnDef
219
     *
220
     * @return string
221
     */
222
    abstract public function getBigIntTypeDeclarationSQL(array $columnDef);
223
224
    /**
225
     * Returns the SQL snippet that declares a 2 byte integer column.
226
     *
227
     * @param array $columnDef
228
     *
229
     * @return string
230
     */
231
    abstract public function getSmallIntTypeDeclarationSQL(array $columnDef);
232
233
    /**
234
     * Returns the SQL snippet that declares common properties of an integer column.
235
     *
236
     * @param array $columnDef
237
     *
238
     * @return string
239
     */
240
    abstract protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef);
241
242
    /**
243
     * Lazy load Doctrine Type Mappings.
244
     *
245
     * @return void
246
     */
247
    abstract protected function initializeDoctrineTypeMappings();
248
249
    /**
250
     * Initializes Doctrine Type Mappings with the platform defaults
251
     * and with all additional type mappings.
252
     *
253
     * @return void
254
     */
255 99
    private function initializeAllDoctrineTypeMappings()
256
    {
257 99
        $this->initializeDoctrineTypeMappings();
258
259 99
        foreach (Type::getTypesMap() as $typeName => $className) {
260 99
            foreach (Type::getType($typeName)->getMappedDatabaseTypes($this) as $dbType) {
261 99
                $this->doctrineTypeMapping[$dbType] = $typeName;
262
            }
263
        }
264 99
    }
265
266
    /**
267
     * Returns the SQL snippet used to declare a VARCHAR column type.
268
     *
269
     * @param array $field
270
     *
271
     * @return string
272
     */
273 331
    public function getVarcharTypeDeclarationSQL(array $field)
274
    {
275 331
        if ( !isset($field['length'])) {
276 81
            $field['length'] = $this->getVarcharDefaultLength();
277
        }
278
279 331
        $fixed = $field['fixed'] ?? false;
280
281 331
        if ($field['length'] > $this->getVarcharMaxLength()) {
282
            return $this->getClobTypeDeclarationSQL($field);
283
        }
284
285 331
        return $this->getVarcharTypeDeclarationSQLSnippet($field['length'], $fixed);
286
    }
287
288
    /**
289
     * Returns the SQL snippet used to declare a BINARY/VARBINARY column type.
290
     *
291
     * @param array $field The column definition.
292
     *
293
     * @return string
294
     */
295 22
    public function getBinaryTypeDeclarationSQL(array $field)
296
    {
297 22
        if ( ! isset($field['length'])) {
298 19
            $field['length'] = $this->getBinaryDefaultLength();
299
        }
300
301 22
        $fixed = $field['fixed'] ?? false;
302
303 22
        if ($field['length'] > $this->getBinaryMaxLength()) {
304 21
            return $this->getBlobTypeDeclarationSQL($field);
305
        }
306
307 19
        return $this->getBinaryTypeDeclarationSQLSnippet($field['length'], $fixed);
308
    }
309
310
    /**
311
     * Returns the SQL snippet to declare a GUID/UUID field.
312
     *
313
     * By default this maps directly to a CHAR(36) and only maps to more
314
     * special datatypes when the underlying databases support this datatype.
315
     *
316
     * @param array $field
317
     *
318
     * @return string
319
     */
320 6
    public function getGuidTypeDeclarationSQL(array $field)
321
    {
322 6
        $field['length'] = 36;
323 6
        $field['fixed']  = true;
324
325 6
        return $this->getVarcharTypeDeclarationSQL($field);
326
    }
327
328
    /**
329
     * Returns the SQL snippet to declare a JSON field.
330
     *
331
     * By default this maps directly to a CLOB and only maps to more
332
     * special datatypes when the underlying databases support this datatype.
333
     *
334
     * @param array $field
335
     *
336
     * @return string
337
     */
338 30
    public function getJsonTypeDeclarationSQL(array $field)
339
    {
340 30
        return $this->getClobTypeDeclarationSQL($field);
341
    }
342
343
    /**
344
     * @param int  $length
345
     * @param bool $fixed
346
     *
347
     * @return string
348
     *
349
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
350
     */
351
    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
0 ignored issues
show
Unused Code introduced by
The parameter $fixed 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

351
    protected function getVarcharTypeDeclarationSQLSnippet($length, /** @scrutinizer ignore-unused */ $fixed)

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...
352
    {
353
        throw DBALException::notSupported('VARCHARs not supported by Platform.');
354
    }
355
356
    /**
357
     * Returns the SQL snippet used to declare a BINARY/VARBINARY column type.
358
     *
359
     * @param int  $length The length of the column.
360
     * @param bool $fixed  Whether the column length is fixed.
361
     *
362
     * @return string
363
     *
364
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
365
     */
366
    protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
0 ignored issues
show
Unused Code introduced by
The parameter $fixed 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

366
    protected function getBinaryTypeDeclarationSQLSnippet($length, /** @scrutinizer ignore-unused */ $fixed)

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...
367
    {
368
        throw DBALException::notSupported('BINARY/VARBINARY column types are not supported by this platform.');
369
    }
370
371
    /**
372
     * Returns the SQL snippet used to declare a CLOB column type.
373
     *
374
     * @param array $field
375
     *
376
     * @return string
377
     */
378
    abstract public function getClobTypeDeclarationSQL(array $field);
379
380
    /**
381
     * Returns the SQL Snippet used to declare a BLOB column type.
382
     *
383
     * @param array $field
384
     *
385
     * @return string
386
     */
387
    abstract public function getBlobTypeDeclarationSQL(array $field);
388
389
    /**
390
     * Gets the name of the platform.
391
     *
392
     * @return string
393
     */
394
    abstract public function getName();
395
396
    /**
397
     * Registers a doctrine type to be used in conjunction with a column type of this platform.
398
     *
399
     * @param string $dbType
400
     * @param string $doctrineType
401
     *
402
     * @throws \Doctrine\DBAL\DBALException If the type is not found.
403
     */
404 55
    public function registerDoctrineTypeMapping($dbType, $doctrineType)
405
    {
406 55
        if ($this->doctrineTypeMapping === null) {
407 55
            $this->initializeAllDoctrineTypeMappings();
408
        }
409
410 55
        if (!Types\Type::hasType($doctrineType)) {
411 18
            throw DBALException::typeNotFound($doctrineType);
412
        }
413
414 37
        $dbType = strtolower($dbType);
415 37
        $this->doctrineTypeMapping[$dbType] = $doctrineType;
416
417 37
        $doctrineType = Type::getType($doctrineType);
418
419 37
        if ($doctrineType->requiresSQLCommentHint($this)) {
420 18
            $this->markDoctrineTypeCommented($doctrineType);
421
        }
422 37
    }
423
424
    /**
425
     * Gets the Doctrine type that is mapped for the given database column type.
426
     *
427
     * @param string $dbType
428
     *
429
     * @return string
430
     *
431
     * @throws \Doctrine\DBAL\DBALException
432
     */
433 101
    public function getDoctrineTypeMapping($dbType)
434
    {
435 101
        if ($this->doctrineTypeMapping === null) {
436 21
            $this->initializeAllDoctrineTypeMappings();
437
        }
438
439 101
        $dbType = strtolower($dbType);
440
441 101
        if (!isset($this->doctrineTypeMapping[$dbType])) {
442 18
            throw new \Doctrine\DBAL\DBALException("Unknown database type ".$dbType." requested, " . get_class($this) . " may not support it.");
443
        }
444
445 83
        return $this->doctrineTypeMapping[$dbType];
446
    }
447
448
    /**
449
     * Checks if a database type is currently supported by this platform.
450
     *
451
     * @param string $dbType
452
     *
453
     * @return bool
454
     */
455 24
    public function hasDoctrineTypeMappingFor($dbType)
456
    {
457 24
        if ($this->doctrineTypeMapping === null) {
458 23
            $this->initializeAllDoctrineTypeMappings();
459
        }
460
461 24
        $dbType = strtolower($dbType);
462
463 24
        return isset($this->doctrineTypeMapping[$dbType]);
464
    }
465
466
    /**
467
     * Initializes the Doctrine Type comments instance variable for in_array() checks.
468
     *
469
     * @return void
470
     */
471 860
    protected function initializeCommentedDoctrineTypes()
472
    {
473 860
        $this->doctrineTypeComments = [];
474
475 860
        foreach (Type::getTypesMap() as $typeName => $className) {
476 860
            $type = Type::getType($typeName);
477
478 860
            if ($type->requiresSQLCommentHint($this)) {
479 860
                $this->doctrineTypeComments[] = $typeName;
480
            }
481
        }
482 860
    }
483
484
    /**
485
     * Is it necessary for the platform to add a parsable type comment to allow reverse engineering the given type?
486
     *
487
     * @param \Doctrine\DBAL\Types\Type $doctrineType
488
     *
489
     * @return bool
490
     */
491 975
    public function isCommentedDoctrineType(Type $doctrineType)
492
    {
493 975
        if ($this->doctrineTypeComments === null) {
494 842
            $this->initializeCommentedDoctrineTypes();
495
        }
496
497 975
        return in_array($doctrineType->getName(), $this->doctrineTypeComments);
498
    }
499
500
    /**
501
     * Marks this type as to be commented in ALTER TABLE and CREATE TABLE statements.
502
     *
503
     * @param string|\Doctrine\DBAL\Types\Type $doctrineType
504
     *
505
     * @return void
506
     */
507 18
    public function markDoctrineTypeCommented($doctrineType)
508
    {
509 18
        if ($this->doctrineTypeComments === null) {
510 18
            $this->initializeCommentedDoctrineTypes();
511
        }
512
513 18
        $this->doctrineTypeComments[] = $doctrineType instanceof Type ? $doctrineType->getName() : $doctrineType;
514 18
    }
515
516
    /**
517
     * Gets the comment to append to a column comment that helps parsing this type in reverse engineering.
518
     *
519
     * @param \Doctrine\DBAL\Types\Type $doctrineType
520
     *
521
     * @return string
522
     */
523 42
    public function getDoctrineTypeComment(Type $doctrineType)
524
    {
525 42
        return '(DC2Type:' . $doctrineType->getName() . ')';
526
    }
527
528
    /**
529
     * Gets the comment of a passed column modified by potential doctrine type comment hints.
530
     *
531
     * @param \Doctrine\DBAL\Schema\Column $column
532
     *
533
     * @return string
534
     */
535 508
    protected function getColumnComment(Column $column)
536
    {
537 508
        $comment = $column->getComment();
538
539 508
        if ($this->isCommentedDoctrineType($column->getType())) {
540 42
            $comment .= $this->getDoctrineTypeComment($column->getType());
541
        }
542
543 508
        return $comment;
544
    }
545
546
    /**
547
     * Gets the character used for identifier quoting.
548
     *
549
     * @return string
550
     */
551 310
    public function getIdentifierQuoteCharacter()
552
    {
553 310
        return '"';
554
    }
555
556
    /**
557
     * Gets the string portion that starts an SQL comment.
558
     *
559
     * @return string
560
     */
561
    public function getSqlCommentStartString()
562
    {
563
        return "--";
564
    }
565
566
    /**
567
     * Gets the string portion that ends an SQL comment.
568
     *
569
     * @return string
570
     */
571
    public function getSqlCommentEndString()
572
    {
573
        return "\n";
574
    }
575
576
    /**
577
     * Gets the maximum length of a varchar field.
578
     *
579
     * @return int
580
     */
581 178
    public function getVarcharMaxLength()
582
    {
583 178
        return 4000;
584
    }
585
586
    /**
587
     * Gets the default length of a varchar field.
588
     *
589
     * @return int
590
     */
591 69
    public function getVarcharDefaultLength()
592
    {
593 69
        return 255;
594
    }
595
596
    /**
597
     * Gets the maximum length of a binary field.
598
     *
599
     * @return int
600
     */
601
    public function getBinaryMaxLength()
602
    {
603
        return 4000;
604
    }
605
606
    /**
607
     * Gets the default length of a binary field.
608
     *
609
     * @return int
610
     */
611 14
    public function getBinaryDefaultLength()
612
    {
613 14
        return 255;
614
    }
615
616
    /**
617
     * Gets all SQL wildcard characters of the platform.
618
     *
619
     * @return array
620
     */
621
    public function getWildcards()
622
    {
623
        return ['%', '_'];
624
    }
625
626
    /**
627
     * Returns the regular expression operator.
628
     *
629
     * @return string
630
     *
631
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
632
     */
633 5
    public function getRegexpExpression()
634
    {
635 5
        throw DBALException::notSupported(__METHOD__);
636
    }
637
638
    /**
639
     * Returns the global unique identifier expression.
640
     *
641
     * @return string
642
     *
643
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
644
     */
645
    public function getGuidExpression()
646
    {
647
        throw DBALException::notSupported(__METHOD__);
648
    }
649
650
    /**
651
     * Returns the SQL snippet to get the average value of a column.
652
     *
653
     * @param string $column The column to use.
654
     *
655
     * @return string Generated SQL including an AVG aggregate function.
656
     */
657
    public function getAvgExpression($column)
658
    {
659
        return 'AVG(' . $column . ')';
660
    }
661
662
    /**
663
     * Returns the SQL snippet to get the number of rows (without a NULL value) of a column.
664
     *
665
     * If a '*' is used instead of a column the number of selected rows is returned.
666
     *
667
     * @param string|integer $column The column to use.
668
     *
669
     * @return string Generated SQL including a COUNT aggregate function.
670
     */
671
    public function getCountExpression($column)
672
    {
673
        return 'COUNT(' . $column . ')';
674
    }
675
676
    /**
677
     * Returns the SQL snippet to get the highest value of a column.
678
     *
679
     * @param string $column The column to use.
680
     *
681
     * @return string Generated SQL including a MAX aggregate function.
682
     */
683
    public function getMaxExpression($column)
684
    {
685
        return 'MAX(' . $column . ')';
686
    }
687
688
    /**
689
     * Returns the SQL snippet to get the lowest value of a column.
690
     *
691
     * @param string $column The column to use.
692
     *
693
     * @return string Generated SQL including a MIN aggregate function.
694
     */
695
    public function getMinExpression($column)
696
    {
697
        return 'MIN(' . $column . ')';
698
    }
699
700
    /**
701
     * Returns the SQL snippet to get the total sum of a column.
702
     *
703
     * @param string $column The column to use.
704
     *
705
     * @return string Generated SQL including a SUM aggregate function.
706
     */
707
    public function getSumExpression($column)
708
    {
709
        return 'SUM(' . $column . ')';
710
    }
711
712
    // scalar functions
713
714
    /**
715
     * Returns the SQL snippet to get the md5 sum of a field.
716
     *
717
     * Note: Not SQL92, but common functionality.
718
     *
719
     * @param string $column
720
     *
721
     * @return string
722
     */
723
    public function getMd5Expression($column)
724
    {
725
        return 'MD5(' . $column . ')';
726
    }
727
728
    /**
729
     * Returns the SQL snippet to get the length of a text field.
730
     *
731
     * @param string $column
732
     *
733
     * @return string
734
     */
735
    public function getLengthExpression($column)
736
    {
737
        return 'LENGTH(' . $column . ')';
738
    }
739
740
    /**
741
     * Returns the SQL snippet to get the squared value of a column.
742
     *
743
     * @param string $column The column to use.
744
     *
745
     * @return string Generated SQL including an SQRT aggregate function.
746
     */
747
    public function getSqrtExpression($column)
748
    {
749
        return 'SQRT(' . $column . ')';
750
    }
751
752
    /**
753
     * Returns the SQL snippet to round a numeric field to the number of decimals specified.
754
     *
755
     * @param string $column
756
     * @param int    $decimals
757
     *
758
     * @return string
759
     */
760
    public function getRoundExpression($column, $decimals = 0)
761
    {
762
        return 'ROUND(' . $column . ', ' . $decimals . ')';
763
    }
764
765
    /**
766
     * Returns the SQL snippet to get the remainder of the division operation $expression1 / $expression2.
767
     *
768
     * @param string $expression1
769
     * @param string $expression2
770
     *
771
     * @return string
772
     */
773
    public function getModExpression($expression1, $expression2)
774
    {
775
        return 'MOD(' . $expression1 . ', ' . $expression2 . ')';
776
    }
777
778
    /**
779
     * Returns the SQL snippet to trim a string.
780
     *
781
     * @param string      $str  The expression to apply the trim to.
782
     * @param int         $mode The position of the trim (leading/trailing/both).
783
     * @param string|bool $char The char to trim, has to be quoted already. Defaults to space.
784
     *
785
     * @return string
786
     */
787
    public function getTrimExpression($str, $mode = TrimMode::UNSPECIFIED, $char = false)
788
    {
789
        $expression = '';
790
791
        switch ($mode) {
792
            case TrimMode::LEADING:
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
793
                $expression = 'LEADING ';
794
                break;
795
796
            case TrimMode::TRAILING:
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
797
                $expression = 'TRAILING ';
798
                break;
799
800
            case TrimMode::BOTH:
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
801
                $expression = 'BOTH ';
802
                break;
803
        }
804
805
        if ($char !== false) {
806
            $expression .= $char . ' ';
0 ignored issues
show
Bug introduced by
Are you sure $char of type string|true can be used in concatenation? ( Ignorable by Annotation )

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

806
            $expression .= /** @scrutinizer ignore-type */ $char . ' ';
Loading history...
807
        }
808
809
        if ($mode || $char !== false) {
810
            $expression .= 'FROM ';
811
        }
812
813
        return 'TRIM(' . $expression . $str . ')';
814
    }
815
816
    /**
817
     * Returns the SQL snippet to trim trailing space characters from the expression.
818
     *
819
     * @param string $str Literal string or column name.
820
     *
821
     * @return string
822
     */
823 4
    public function getRtrimExpression($str)
824
    {
825 4
        return 'RTRIM(' . $str . ')';
826
    }
827
828
    /**
829
     * Returns the SQL snippet to trim leading space characters from the expression.
830
     *
831
     * @param string $str Literal string or column name.
832
     *
833
     * @return string
834
     */
835 4
    public function getLtrimExpression($str)
836
    {
837 4
        return 'LTRIM(' . $str . ')';
838
    }
839
840
    /**
841
     * Returns the SQL snippet to change all characters from the expression to uppercase,
842
     * according to the current character set mapping.
843
     *
844
     * @param string $str Literal string or column name.
845
     *
846
     * @return string
847
     */
848
    public function getUpperExpression($str)
849
    {
850
        return 'UPPER(' . $str . ')';
851
    }
852
853
    /**
854
     * Returns the SQL snippet to change all characters from the expression to lowercase,
855
     * according to the current character set mapping.
856
     *
857
     * @param string $str Literal string or column name.
858
     *
859
     * @return string
860
     */
861
    public function getLowerExpression($str)
862
    {
863
        return 'LOWER(' . $str . ')';
864
    }
865
866
    /**
867
     * Returns the SQL snippet to get the position of the first occurrence of substring $substr in string $str.
868
     *
869
     * @param string   $str      Literal string.
870
     * @param string   $substr   Literal string to find.
871
     * @param int|bool $startPos Position to start at, beginning of string by default.
872
     *
873
     * @return string
874
     *
875
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
876
     */
877
    public function getLocateExpression($str, $substr, $startPos = false)
0 ignored issues
show
Unused Code introduced by
The parameter $substr 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

877
    public function getLocateExpression($str, /** @scrutinizer ignore-unused */ $substr, $startPos = false)

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...
Unused Code introduced by
The parameter $startPos 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

877
    public function getLocateExpression($str, $substr, /** @scrutinizer ignore-unused */ $startPos = false)

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...
878
    {
879
        throw DBALException::notSupported(__METHOD__);
880
    }
881
882
    /**
883
     * Returns the SQL snippet to get the current system date.
884
     *
885
     * @return string
886
     */
887
    public function getNowExpression()
888
    {
889
        return 'NOW()';
890
    }
891
892
    /**
893
     * Returns a SQL snippet to get a substring inside an SQL statement.
894
     *
895
     * Note: Not SQL92, but common functionality.
896
     *
897
     * SQLite only supports the 2 parameter variant of this function.
898
     *
899
     * @param string   $value  An sql string literal or column name/alias.
900
     * @param int      $from   Where to start the substring portion.
901
     * @param int|null $length The substring portion length.
902
     *
903
     * @return string
904
     */
905
    public function getSubstringExpression($value, $from, $length = null)
906
    {
907
        if ($length === null) {
908
            return 'SUBSTRING(' . $value . ' FROM ' . $from . ')';
909
        }
910
911
        return 'SUBSTRING(' . $value . ' FROM ' . $from . ' FOR ' . $length . ')';
912
    }
913
914
    /**
915
     * Returns a SQL snippet to concatenate the given expressions.
916
     *
917
     * Accepts an arbitrary number of string parameters. Each parameter must contain an expression.
918
     *
919
     * @return string
920
     */
921 6
    public function getConcatExpression()
922
    {
923 6
        return join(' || ', func_get_args());
924
    }
925
926
    /**
927
     * Returns the SQL for a logical not.
928
     *
929
     * Example:
930
     * <code>
931
     * $q = new Doctrine_Query();
932
     * $e = $q->expr;
933
     * $q->select('*')->from('table')
934
     *   ->where($e->eq('id', $e->not('null'));
935
     * </code>
936
     *
937
     * @param string $expression
938
     *
939
     * @return string The logical expression.
940
     */
941
    public function getNotExpression($expression)
942
    {
943
        return 'NOT(' . $expression . ')';
944
    }
945
946
    /**
947
     * Returns the SQL that checks if an expression is null.
948
     *
949
     * @param string $expression The expression that should be compared to null.
950
     *
951
     * @return string The logical expression.
952
     */
953 4
    public function getIsNullExpression($expression)
954
    {
955 4
        return $expression . ' IS NULL';
956
    }
957
958
    /**
959
     * Returns the SQL that checks if an expression is not null.
960
     *
961
     * @param string $expression The expression that should be compared to null.
962
     *
963
     * @return string The logical expression.
964
     */
965
    public function getIsNotNullExpression($expression)
966
    {
967
        return $expression . ' IS NOT NULL';
968
    }
969
970
    /**
971
     * Returns the SQL that checks if an expression evaluates to a value between two values.
972
     *
973
     * The parameter $expression is checked if it is between $value1 and $value2.
974
     *
975
     * Note: There is a slight difference in the way BETWEEN works on some databases.
976
     * http://www.w3schools.com/sql/sql_between.asp. If you want complete database
977
     * independence you should avoid using between().
978
     *
979
     * @param string $expression The value to compare to.
980
     * @param string $value1     The lower value to compare with.
981
     * @param string $value2     The higher value to compare with.
982
     *
983
     * @return string The logical expression.
984
     */
985
    public function getBetweenExpression($expression, $value1, $value2)
986
    {
987
        return $expression . ' BETWEEN ' .$value1 . ' AND ' . $value2;
988
    }
989
990
    /**
991
     * Returns the SQL to get the arccosine of a value.
992
     *
993
     * @param string $value
994
     *
995
     * @return string
996
     */
997
    public function getAcosExpression($value)
998
    {
999
        return 'ACOS(' . $value . ')';
1000
    }
1001
1002
    /**
1003
     * Returns the SQL to get the sine of a value.
1004
     *
1005
     * @param string $value
1006
     *
1007
     * @return string
1008
     */
1009
    public function getSinExpression($value)
1010
    {
1011
        return 'SIN(' . $value . ')';
1012
    }
1013
1014
    /**
1015
     * Returns the SQL to get the PI value.
1016
     *
1017
     * @return string
1018
     */
1019
    public function getPiExpression()
1020
    {
1021
        return 'PI()';
1022
    }
1023
1024
    /**
1025
     * Returns the SQL to get the cosine of a value.
1026
     *
1027
     * @param string $value
1028
     *
1029
     * @return string
1030
     */
1031
    public function getCosExpression($value)
1032
    {
1033
        return 'COS(' . $value . ')';
1034
    }
1035
1036
    /**
1037
     * Returns the SQL to calculate the difference in days between the two passed dates.
1038
     *
1039
     * Computes diff = date1 - date2.
1040
     *
1041
     * @param string $date1
1042
     * @param string $date2
1043
     *
1044
     * @return string
1045
     *
1046
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1047
     */
1048
    public function getDateDiffExpression($date1, $date2)
0 ignored issues
show
Unused Code introduced by
The parameter $date1 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

1048
    public function getDateDiffExpression(/** @scrutinizer ignore-unused */ $date1, $date2)

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...
Unused Code introduced by
The parameter $date2 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

1048
    public function getDateDiffExpression($date1, /** @scrutinizer ignore-unused */ $date2)

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...
1049
    {
1050
        throw DBALException::notSupported(__METHOD__);
1051
    }
1052
1053
    /**
1054
     * Returns the SQL to add the number of given seconds to a date.
1055
     *
1056
     * @param string $date
1057
     * @param int    $seconds
1058
     *
1059
     * @return string
1060
     *
1061
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1062
     */
1063 6
    public function getDateAddSecondsExpression($date, $seconds)
1064
    {
1065 6
        return $this->getDateArithmeticIntervalExpression($date, '+', $seconds, DateIntervalUnit::SECOND);
1066
    }
1067
1068
    /**
1069
     * Returns the SQL to subtract the number of given seconds from a date.
1070
     *
1071
     * @param string $date
1072
     * @param int    $seconds
1073
     *
1074
     * @return string
1075
     *
1076
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1077
     */
1078 6
    public function getDateSubSecondsExpression($date, $seconds)
1079
    {
1080 6
        return $this->getDateArithmeticIntervalExpression($date, '-', $seconds, DateIntervalUnit::SECOND);
1081
    }
1082
1083
    /**
1084
     * Returns the SQL to add the number of given minutes to a date.
1085
     *
1086
     * @param string $date
1087
     * @param int    $minutes
1088
     *
1089
     * @return string
1090
     *
1091
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1092
     */
1093 6
    public function getDateAddMinutesExpression($date, $minutes)
1094
    {
1095 6
        return $this->getDateArithmeticIntervalExpression($date, '+', $minutes, DateIntervalUnit::MINUTE);
1096
    }
1097
1098
    /**
1099
     * Returns the SQL to subtract the number of given minutes from a date.
1100
     *
1101
     * @param string $date
1102
     * @param int    $minutes
1103
     *
1104
     * @return string
1105
     *
1106
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1107
     */
1108 6
    public function getDateSubMinutesExpression($date, $minutes)
1109
    {
1110 6
        return $this->getDateArithmeticIntervalExpression($date, '-', $minutes, DateIntervalUnit::MINUTE);
1111
    }
1112
1113
    /**
1114
     * Returns the SQL to add the number of given hours to a date.
1115
     *
1116
     * @param string $date
1117
     * @param int    $hours
1118
     *
1119
     * @return string
1120
     *
1121
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1122
     */
1123 6
    public function getDateAddHourExpression($date, $hours)
1124
    {
1125 6
        return $this->getDateArithmeticIntervalExpression($date, '+', $hours, DateIntervalUnit::HOUR);
1126
    }
1127
1128
    /**
1129
     * Returns the SQL to subtract the number of given hours to a date.
1130
     *
1131
     * @param string $date
1132
     * @param int    $hours
1133
     *
1134
     * @return string
1135
     *
1136
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1137
     */
1138 6
    public function getDateSubHourExpression($date, $hours)
1139
    {
1140 6
        return $this->getDateArithmeticIntervalExpression($date, '-', $hours, DateIntervalUnit::HOUR);
1141
    }
1142
1143
    /**
1144
     * Returns the SQL to add the number of given days to a date.
1145
     *
1146
     * @param string $date
1147
     * @param int    $days
1148
     *
1149
     * @return string
1150
     *
1151
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1152
     */
1153 6
    public function getDateAddDaysExpression($date, $days)
1154
    {
1155 6
        return $this->getDateArithmeticIntervalExpression($date, '+', $days, DateIntervalUnit::DAY);
1156
    }
1157
1158
    /**
1159
     * Returns the SQL to subtract the number of given days to a date.
1160
     *
1161
     * @param string $date
1162
     * @param int    $days
1163
     *
1164
     * @return string
1165
     *
1166
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1167
     */
1168 6
    public function getDateSubDaysExpression($date, $days)
1169
    {
1170 6
        return $this->getDateArithmeticIntervalExpression($date, '-', $days, DateIntervalUnit::DAY);
1171
    }
1172
1173
    /**
1174
     * Returns the SQL to add the number of given weeks to a date.
1175
     *
1176
     * @param string $date
1177
     * @param int    $weeks
1178
     *
1179
     * @return string
1180
     *
1181
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1182
     */
1183 6
    public function getDateAddWeeksExpression($date, $weeks)
1184
    {
1185 6
        return $this->getDateArithmeticIntervalExpression($date, '+', $weeks, DateIntervalUnit::WEEK);
1186
    }
1187
1188
    /**
1189
     * Returns the SQL to subtract the number of given weeks from a date.
1190
     *
1191
     * @param string $date
1192
     * @param int    $weeks
1193
     *
1194
     * @return string
1195
     *
1196
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1197
     */
1198 6
    public function getDateSubWeeksExpression($date, $weeks)
1199
    {
1200 6
        return $this->getDateArithmeticIntervalExpression($date, '-', $weeks, DateIntervalUnit::WEEK);
1201
    }
1202
1203
    /**
1204
     * Returns the SQL to add the number of given months to a date.
1205
     *
1206
     * @param string $date
1207
     * @param int    $months
1208
     *
1209
     * @return string
1210
     *
1211
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1212
     */
1213 6
    public function getDateAddMonthExpression($date, $months)
1214
    {
1215 6
        return $this->getDateArithmeticIntervalExpression($date, '+', $months, DateIntervalUnit::MONTH);
1216
    }
1217
1218
    /**
1219
     * Returns the SQL to subtract the number of given months to a date.
1220
     *
1221
     * @param string $date
1222
     * @param int    $months
1223
     *
1224
     * @return string
1225
     *
1226
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1227
     */
1228 6
    public function getDateSubMonthExpression($date, $months)
1229
    {
1230 6
        return $this->getDateArithmeticIntervalExpression($date, '-', $months, DateIntervalUnit::MONTH);
1231
    }
1232
1233
    /**
1234
     * Returns the SQL to add the number of given quarters to a date.
1235
     *
1236
     * @param string $date
1237
     * @param int    $quarters
1238
     *
1239
     * @return string
1240
     *
1241
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1242
     */
1243 6
    public function getDateAddQuartersExpression($date, $quarters)
1244
    {
1245 6
        return $this->getDateArithmeticIntervalExpression($date, '+', $quarters, DateIntervalUnit::QUARTER);
1246
    }
1247
1248
    /**
1249
     * Returns the SQL to subtract the number of given quarters from a date.
1250
     *
1251
     * @param string $date
1252
     * @param int    $quarters
1253
     *
1254
     * @return string
1255
     *
1256
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1257
     */
1258 6
    public function getDateSubQuartersExpression($date, $quarters)
1259
    {
1260 6
        return $this->getDateArithmeticIntervalExpression($date, '-', $quarters, DateIntervalUnit::QUARTER);
1261
    }
1262
1263
    /**
1264
     * Returns the SQL to add the number of given years to a date.
1265
     *
1266
     * @param string $date
1267
     * @param int    $years
1268
     *
1269
     * @return string
1270
     *
1271
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1272
     */
1273 6
    public function getDateAddYearsExpression($date, $years)
1274
    {
1275 6
        return $this->getDateArithmeticIntervalExpression($date, '+', $years, DateIntervalUnit::YEAR);
1276
    }
1277
1278
    /**
1279
     * Returns the SQL to subtract the number of given years from a date.
1280
     *
1281
     * @param string $date
1282
     * @param int    $years
1283
     *
1284
     * @return string
1285
     *
1286
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1287
     */
1288 6
    public function getDateSubYearsExpression($date, $years)
1289
    {
1290 6
        return $this->getDateArithmeticIntervalExpression($date, '-', $years, DateIntervalUnit::YEAR);
1291
    }
1292
1293
    /**
1294
     * Returns the SQL for a date arithmetic expression.
1295
     *
1296
     * @param string $date     The column or literal representing a date to perform the arithmetic operation on.
1297
     * @param string $operator The arithmetic operator (+ or -).
1298
     * @param int    $interval The interval that shall be calculated into the date.
1299
     * @param string $unit     The unit of the interval that shall be calculated into the date.
1300
     *                         One of the DATE_INTERVAL_UNIT_* constants.
1301
     *
1302
     * @return string
1303
     *
1304
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1305
     */
1306
    protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit)
0 ignored issues
show
Unused Code introduced by
The parameter $operator 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

1306
    protected function getDateArithmeticIntervalExpression($date, /** @scrutinizer ignore-unused */ $operator, $interval, $unit)

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...
Unused Code introduced by
The parameter $interval 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

1306
    protected function getDateArithmeticIntervalExpression($date, $operator, /** @scrutinizer ignore-unused */ $interval, $unit)

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...
Unused Code introduced by
The parameter $unit 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

1306
    protected function getDateArithmeticIntervalExpression($date, $operator, $interval, /** @scrutinizer ignore-unused */ $unit)

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...
1307
    {
1308
        throw DBALException::notSupported(__METHOD__);
1309
    }
1310
1311
    /**
1312
     * Returns the SQL bit AND comparison expression.
1313
     *
1314
     * @param string $value1
1315
     * @param string $value2
1316
     *
1317
     * @return string
1318
     */
1319 17
    public function getBitAndComparisonExpression($value1, $value2)
1320
    {
1321 17
        return '(' . $value1 . ' & ' . $value2 . ')';
1322
    }
1323
1324
    /**
1325
     * Returns the SQL bit OR comparison expression.
1326
     *
1327
     * @param string $value1
1328
     * @param string $value2
1329
     *
1330
     * @return string
1331
     */
1332 17
    public function getBitOrComparisonExpression($value1, $value2)
1333
    {
1334 17
        return '(' . $value1 . ' | ' . $value2 . ')';
1335
    }
1336
1337
    /**
1338
     * Returns the FOR UPDATE expression.
1339
     *
1340
     * @return string
1341
     */
1342
    public function getForUpdateSQL()
1343
    {
1344
        return 'FOR UPDATE';
1345
    }
1346
1347
    /**
1348
     * Honors that some SQL vendors such as MsSql use table hints for locking instead of the ANSI SQL FOR UPDATE specification.
1349
     *
1350
     * @param string   $fromClause The FROM clause to append the hint for the given lock mode to.
1351
     * @param int|null $lockMode   One of the Doctrine\DBAL\LockMode::* constants. If null is given, nothing will
1352
     *                             be appended to the FROM clause.
1353
     *
1354
     * @return string
1355
     */
1356
    public function appendLockHint($fromClause, $lockMode)
0 ignored issues
show
Unused Code introduced by
The parameter $lockMode 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

1356
    public function appendLockHint($fromClause, /** @scrutinizer ignore-unused */ $lockMode)

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...
1357
    {
1358
        return $fromClause;
1359
    }
1360
1361
    /**
1362
     * Returns the SQL snippet to append to any SELECT statement which locks rows in shared read lock.
1363
     *
1364
     * This defaults to the ANSI SQL "FOR UPDATE", which is an exclusive lock (Write). Some database
1365
     * vendors allow to lighten this constraint up to be a real read lock.
1366
     *
1367
     * @return string
1368
     */
1369
    public function getReadLockSQL()
1370
    {
1371
        return $this->getForUpdateSQL();
1372
    }
1373
1374
    /**
1375
     * Returns the SQL snippet to append to any SELECT statement which obtains an exclusive lock on the rows.
1376
     *
1377
     * The semantics of this lock mode should equal the SELECT .. FOR UPDATE of the ANSI SQL standard.
1378
     *
1379
     * @return string
1380
     */
1381
    public function getWriteLockSQL()
1382
    {
1383
        return $this->getForUpdateSQL();
1384
    }
1385
1386
    /**
1387
     * Returns the SQL snippet to drop an existing database.
1388
     *
1389
     * @param string $database The name of the database that should be dropped.
1390
     *
1391
     * @return string
1392
     */
1393 5
    public function getDropDatabaseSQL($database)
1394
    {
1395 5
        return 'DROP DATABASE ' . $database;
1396
    }
1397
1398
    /**
1399
     * Returns the SQL snippet to drop an existing table.
1400
     *
1401
     * @param \Doctrine\DBAL\Schema\Table|string $table
1402
     *
1403
     * @return string
1404
     *
1405
     * @throws \InvalidArgumentException
1406
     */
1407 109
    public function getDropTableSQL($table)
1408
    {
1409 109
        $tableArg = $table;
1410
1411 109
        if ($table instanceof Table) {
1412 27
            $table = $table->getQuotedName($this);
1413 94
        } elseif (!is_string($table)) {
0 ignored issues
show
introduced by
The condition is_string($table) is always true.
Loading history...
1414
            throw new \InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
1415
        }
1416
1417 109
        if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaDropTable)) {
1418 18
            $eventArgs = new SchemaDropTableEventArgs($tableArg, $this);
1419 18
            $this->_eventManager->dispatchEvent(Events::onSchemaDropTable, $eventArgs);
1420
1421 18
            if ($eventArgs->isDefaultPrevented()) {
1422
                return $eventArgs->getSql();
1423
            }
1424
        }
1425
1426 109
        return 'DROP TABLE ' . $table;
1427
    }
1428
1429
    /**
1430
     * Returns the SQL to safely drop a temporary table WITHOUT implicitly committing an open transaction.
1431
     *
1432
     * @param \Doctrine\DBAL\Schema\Table|string $table
1433
     *
1434
     * @return string
1435
     */
1436 2
    public function getDropTemporaryTableSQL($table)
1437
    {
1438 2
        return $this->getDropTableSQL($table);
1439
    }
1440
1441
    /**
1442
     * Returns the SQL to drop an index from a table.
1443
     *
1444
     * @param \Doctrine\DBAL\Schema\Index|string $index
1445
     * @param \Doctrine\DBAL\Schema\Table|string $table
1446
     *
1447
     * @return string
1448
     *
1449
     * @throws \InvalidArgumentException
1450
     */
1451 10
    public function getDropIndexSQL($index, $table = null)
1452
    {
1453 10
        if ($index instanceof Index) {
1454 9
            $index = $index->getQuotedName($this);
1455 1
        } elseif (!is_string($index)) {
0 ignored issues
show
introduced by
The condition is_string($index) is always true.
Loading history...
1456
            throw new \InvalidArgumentException('AbstractPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.');
1457
        }
1458
1459 10
        return 'DROP INDEX ' . $index;
1460
    }
1461
1462
    /**
1463
     * Returns the SQL to drop a constraint.
1464
     *
1465
     * @param \Doctrine\DBAL\Schema\Constraint|string $constraint
1466
     * @param \Doctrine\DBAL\Schema\Table|string      $table
1467
     *
1468
     * @return string
1469
     */
1470 36
    public function getDropConstraintSQL($constraint, $table)
1471
    {
1472 36
        if (! $constraint instanceof Constraint) {
1473 26
            $constraint = new Identifier($constraint);
1474
        }
1475
1476 36
        if (! $table instanceof Table) {
1477 36
            $table = new Identifier($table);
1478
        }
1479
1480 36
        $constraint = $constraint->getQuotedName($this);
1481 36
        $table = $table->getQuotedName($this);
1482
1483 36
        return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $constraint;
1484
    }
1485
1486
    /**
1487
     * Returns the SQL to drop a foreign key.
1488
     *
1489
     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint|string $foreignKey
1490
     * @param \Doctrine\DBAL\Schema\Table|string                $table
1491
     *
1492
     * @return string
1493
     */
1494 21
    public function getDropForeignKeySQL($foreignKey, $table)
1495
    {
1496 21
        if (! $foreignKey instanceof ForeignKeyConstraint) {
1497 8
            $foreignKey = new Identifier($foreignKey);
1498
        }
1499
1500 21
        if (! $table instanceof Table) {
1501 21
            $table = new Identifier($table);
1502
        }
1503
1504 21
        $foreignKey = $foreignKey->getQuotedName($this);
1505 21
        $table = $table->getQuotedName($this);
1506
1507 21
        return 'ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $foreignKey;
1508
    }
1509
1510
    /**
1511
     * Returns the SQL statement(s) to create a table with the specified name, columns and constraints
1512
     * on this platform.
1513
     *
1514
     * @param \Doctrine\DBAL\Schema\Table $table
1515
     * @param int                         $createFlags
1516
     *
1517
     * @return array The sequence of SQL statements.
1518
     *
1519
     * @throws \Doctrine\DBAL\DBALException
1520
     * @throws \InvalidArgumentException
1521
     */
1522 399
    public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES)
1523
    {
1524 399
        if ( ! is_int($createFlags)) {
0 ignored issues
show
introduced by
The condition is_int($createFlags) is always true.
Loading history...
1525
            throw new \InvalidArgumentException("Second argument of AbstractPlatform::getCreateTableSQL() has to be integer.");
1526
        }
1527
1528 399
        if (count($table->getColumns()) === 0) {
1529 18
            throw DBALException::noColumnsSpecifiedForTable($table->getName());
1530
        }
1531
1532 381
        $tableName = $table->getQuotedName($this);
1533 381
        $options = $table->getOptions();
1534 381
        $options['uniqueConstraints'] = [];
1535 381
        $options['indexes'] = [];
1536 381
        $options['primary'] = [];
1537
1538 381
        if (($createFlags&self::CREATE_INDEXES) > 0) {
1539 358
            foreach ($table->getIndexes() as $index) {
1540
                /* @var $index Index */
1541 249
                if ($index->isPrimary()) {
1542 184
                    $options['primary']       = $index->getQuotedColumns($this);
1543 184
                    $options['primary_index'] = $index;
1544
                } else {
1545 249
                    $options['indexes'][$index->getQuotedName($this)] = $index;
1546
                }
1547
            }
1548
        }
1549
1550 381
        $columnSql = [];
1551 381
        $columns = [];
1552
1553 381
        foreach ($table->getColumns() as $column) {
1554
            /* @var \Doctrine\DBAL\Schema\Column $column */
1555
1556 381
            if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)) {
1557 18
                $eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this);
1558 18
                $this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs);
1559
1560 18
                $columnSql = array_merge($columnSql, $eventArgs->getSql());
1561
1562 18
                if ($eventArgs->isDefaultPrevented()) {
1563
                    continue;
1564
                }
1565
            }
1566
1567 381
            $columnData = $column->toArray();
1568 381
            $columnData['name'] = $column->getQuotedName($this);
1569 381
            $columnData['version'] = $column->hasPlatformOption("version") ? $column->getPlatformOption('version') : false;
1570 381
            $columnData['comment'] = $this->getColumnComment($column);
1571
1572 381
            if ($columnData['type'] instanceof Types\StringType && $columnData['length'] === null) {
1573 142
                $columnData['length'] = 255;
1574
            }
1575
1576 381
            if (in_array($column->getName(), $options['primary'])) {
1577 164
                $columnData['primary'] = true;
1578
            }
1579
1580 381
            $columns[$columnData['name']] = $columnData;
1581
        }
1582
1583 381
        if (($createFlags&self::CREATE_FOREIGNKEYS) > 0) {
1584 174
            $options['foreignKeys'] = [];
1585 174
            foreach ($table->getForeignKeys() as $fkConstraint) {
1586 31
                $options['foreignKeys'][] = $fkConstraint;
1587
            }
1588
        }
1589
1590 381
        if (null !== $this->_eventManager && $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) {
1591 18
            $eventArgs = new SchemaCreateTableEventArgs($table, $columns, $options, $this);
1592 18
            $this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs);
1593
1594 18
            if ($eventArgs->isDefaultPrevented()) {
1595
                return array_merge($eventArgs->getSql(), $columnSql);
1596
            }
1597
        }
1598
1599 381
        $sql = $this->_getCreateTableSQL($tableName, $columns, $options);
1600 381
        if ($this->supportsCommentOnStatement()) {
1601 141
            foreach ($table->getColumns() as $column) {
1602 141
                $comment = $this->getColumnComment($column);
1603
1604 141
                if (null !== $comment && '' !== $comment) {
1605 141
                    $sql[] = $this->getCommentOnColumnSQL($tableName, $column->getQuotedName($this), $comment);
1606
                }
1607
            }
1608
        }
1609
1610 381
        return array_merge($sql, $columnSql);
1611
    }
1612
1613
    /**
1614
     * @param string $tableName
1615
     * @param string $columnName
1616
     * @param string $comment
1617
     *
1618
     * @return string
1619
     */
1620 34
    public function getCommentOnColumnSQL($tableName, $columnName, $comment)
1621
    {
1622 34
        $tableName = new Identifier($tableName);
1623 34
        $columnName = new Identifier($columnName);
1624 34
        $comment = $this->quoteStringLiteral($comment);
1625
1626 34
        return "COMMENT ON COLUMN " . $tableName->getQuotedName($this) . "." . $columnName->getQuotedName($this) .
1627 34
            " IS " . $comment;
1628
    }
1629
1630
    /**
1631
     * Returns the SQL to create inline comment on a column.
1632
     *
1633
     * @param string $comment
1634
     *
1635
     * @return string
1636
     *
1637
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1638
     */
1639 41
    public function getInlineColumnCommentSQL($comment)
1640
    {
1641 41
        if (! $this->supportsInlineColumnComments()) {
1642 14
            throw DBALException::notSupported(__METHOD__);
1643
        }
1644
1645 27
        return "COMMENT " . $this->quoteStringLiteral($comment);
1646
    }
1647
1648
    /**
1649
     * Returns the SQL used to create a table.
1650
     *
1651
     * @param string $tableName
1652
     * @param array  $columns
1653
     * @param array  $options
1654
     *
1655
     * @return array
1656
     */
1657 23
    protected function _getCreateTableSQL($tableName, array $columns, array $options = [])
1658
    {
1659 23
        $columnListSql = $this->getColumnDeclarationListSQL($columns);
1660
1661 23
        if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
1662
            foreach ($options['uniqueConstraints'] as $name => $definition) {
1663
                $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition);
1664
            }
1665
        }
1666
1667 23
        if (isset($options['primary']) && ! empty($options['primary'])) {
1668 10
            $columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')';
1669
        }
1670
1671 23
        if (isset($options['indexes']) && ! empty($options['indexes'])) {
1672
            foreach ($options['indexes'] as $index => $definition) {
1673
                $columnListSql .= ', ' . $this->getIndexDeclarationSQL($index, $definition);
1674
            }
1675
        }
1676
1677 23
        $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql;
1678
1679 23
        $check = $this->getCheckDeclarationSQL($columns);
1680 23
        if ( ! empty($check)) {
1681 1
            $query .= ', ' . $check;
1682
        }
1683 23
        $query .= ')';
1684
1685 23
        $sql[] = $query;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$sql was never initialized. Although not strictly required by PHP, it is generally a good practice to add $sql = array(); before regardless.
Loading history...
1686
1687 23
        if (isset($options['foreignKeys'])) {
1688 3
            foreach ((array) $options['foreignKeys'] as $definition) {
1689 3
                $sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
1690
            }
1691
        }
1692
1693 23
        return $sql;
1694
    }
1695
1696
    /**
1697
     * @return string
1698
     */
1699 2
    public function getCreateTemporaryTableSnippetSQL()
1700
    {
1701 2
        return "CREATE TEMPORARY TABLE";
1702
    }
1703
1704
    /**
1705
     * Returns the SQL to create a sequence on this platform.
1706
     *
1707
     * @param \Doctrine\DBAL\Schema\Sequence $sequence
1708
     *
1709
     * @return string
1710
     *
1711
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1712
     */
1713
    public function getCreateSequenceSQL(Sequence $sequence)
0 ignored issues
show
Unused Code introduced by
The parameter $sequence 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

1713
    public function getCreateSequenceSQL(/** @scrutinizer ignore-unused */ Sequence $sequence)

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...
1714
    {
1715
        throw DBALException::notSupported(__METHOD__);
1716
    }
1717
1718
    /**
1719
     * Returns the SQL to change a sequence on this platform.
1720
     *
1721
     * @param \Doctrine\DBAL\Schema\Sequence $sequence
1722
     *
1723
     * @return string
1724
     *
1725
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1726
     */
1727
    public function getAlterSequenceSQL(Sequence $sequence)
0 ignored issues
show
Unused Code introduced by
The parameter $sequence 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

1727
    public function getAlterSequenceSQL(/** @scrutinizer ignore-unused */ Sequence $sequence)

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...
1728
    {
1729
        throw DBALException::notSupported(__METHOD__);
1730
    }
1731
1732
    /**
1733
     * Returns the SQL to create a constraint on a table on this platform.
1734
     *
1735
     * @param \Doctrine\DBAL\Schema\Constraint   $constraint
1736
     * @param \Doctrine\DBAL\Schema\Table|string $table
1737
     *
1738
     * @return string
1739
     *
1740
     * @throws \InvalidArgumentException
1741
     */
1742 16
    public function getCreateConstraintSQL(Constraint $constraint, $table)
1743
    {
1744 16
        if ($table instanceof Table) {
1745
            $table = $table->getQuotedName($this);
1746
        }
1747
1748 16
        $query = 'ALTER TABLE ' . $table . ' ADD CONSTRAINT ' . $constraint->getQuotedName($this);
1749
1750 16
        $columnList = '('. implode(', ', $constraint->getQuotedColumns($this)) . ')';
1751
1752 16
        $referencesClause = '';
1753 16
        if ($constraint instanceof Index) {
1754 16
            if ($constraint->isPrimary()) {
1755 16
                $query .= ' PRIMARY KEY';
1756 13
            } elseif ($constraint->isUnique()) {
1757 13
                $query .= ' UNIQUE';
1758
            } else {
1759
                throw new \InvalidArgumentException(
1760 16
                    'Can only create primary or unique constraints, no common indexes with getCreateConstraintSQL().'
1761
                );
1762
            }
1763 13
        } elseif ($constraint instanceof ForeignKeyConstraint) {
1764 13
            $query .= ' FOREIGN KEY';
1765
1766 13
            $referencesClause = ' REFERENCES ' . $constraint->getQuotedForeignTableName($this) .
1767 13
                ' (' . implode(', ', $constraint->getQuotedForeignColumns($this)) . ')';
1768
        }
1769 16
        $query .= ' '.$columnList.$referencesClause;
1770
1771 16
        return $query;
1772
    }
1773
1774
    /**
1775
     * Returns the SQL to create an index on a table on this platform.
1776
     *
1777
     * @param \Doctrine\DBAL\Schema\Index        $index
1778
     * @param \Doctrine\DBAL\Schema\Table|string $table The name of the table on which the index is to be created.
1779
     *
1780
     * @return string
1781
     *
1782
     * @throws \InvalidArgumentException
1783
     */
1784 155
    public function getCreateIndexSQL(Index $index, $table)
1785
    {
1786 155
        if ($table instanceof Table) {
1787 1
            $table = $table->getQuotedName($this);
1788
        }
1789 155
        $name = $index->getQuotedName($this);
1790 155
        $columns = $index->getQuotedColumns($this);
1791
1792 155
        if (count($columns) == 0) {
1793
            throw new \InvalidArgumentException("Incomplete definition. 'columns' required.");
1794
        }
1795
1796 155
        if ($index->isPrimary()) {
1797 21
            return $this->getCreatePrimaryKeySQL($index, $table);
1798
        }
1799
1800 136
        $query = 'CREATE ' . $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name . ' ON ' . $table;
1801 136
        $query .= ' (' . $this->getIndexFieldDeclarationListSQL($columns) . ')' . $this->getPartialIndexSQL($index);
1802
1803 136
        return $query;
1804
    }
1805
1806
    /**
1807
     * Adds condition for partial index.
1808
     *
1809
     * @param \Doctrine\DBAL\Schema\Index $index
1810
     *
1811
     * @return string
1812
     */
1813 183
    protected function getPartialIndexSQL(Index $index)
1814
    {
1815 183
        if ($this->supportsPartialIndexes() && $index->hasOption('where')) {
1816 5
            return  ' WHERE ' . $index->getOption('where');
1817
        }
1818
1819 178
        return '';
1820
    }
1821
1822
    /**
1823
     * Adds additional flags for index generation.
1824
     *
1825
     * @param \Doctrine\DBAL\Schema\Index $index
1826
     *
1827
     * @return string
1828
     */
1829 67
    protected function getCreateIndexSQLFlags(Index $index)
1830
    {
1831 67
        return $index->isUnique() ? 'UNIQUE ' : '';
1832
    }
1833
1834
    /**
1835
     * Returns the SQL to create an unnamed primary key constraint.
1836
     *
1837
     * @param \Doctrine\DBAL\Schema\Index        $index
1838
     * @param \Doctrine\DBAL\Schema\Table|string $table
1839
     *
1840
     * @return string
1841
     */
1842 17
    public function getCreatePrimaryKeySQL(Index $index, $table)
1843
    {
1844 17
        return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index->getQuotedColumns($this)) . ')';
0 ignored issues
show
Bug introduced by
Are you sure $table of type Doctrine\DBAL\Schema\Table|string can be used in concatenation? ( Ignorable by Annotation )

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

1844
        return 'ALTER TABLE ' . /** @scrutinizer ignore-type */ $table . ' ADD PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index->getQuotedColumns($this)) . ')';
Loading history...
1845
    }
1846
1847
    /**
1848
     * Returns the SQL to create a named schema.
1849
     *
1850
     * @param string $schemaName
1851
     *
1852
     * @return string
1853
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1854
     */
1855 10
    public function getCreateSchemaSQL($schemaName)
0 ignored issues
show
Unused Code introduced by
The parameter $schemaName 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

1855
    public function getCreateSchemaSQL(/** @scrutinizer ignore-unused */ $schemaName)

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...
1856
    {
1857 10
        throw DBALException::notSupported(__METHOD__);
1858
    }
1859
1860
    /**
1861
     * Quotes a string so that it can be safely used as a table or column name,
1862
     * even if it is a reserved word of the platform. This also detects identifier
1863
     * chains separated by dot and quotes them independently.
1864
     *
1865
     * NOTE: Just because you CAN use quoted identifiers doesn't mean
1866
     * you SHOULD use them. In general, they end up causing way more
1867
     * problems than they solve.
1868
     *
1869
     * @param string $str The identifier name to be quoted.
1870
     *
1871
     * @return string The quoted identifier string.
1872
     */
1873 392
    public function quoteIdentifier($str)
1874
    {
1875 392
        if (strpos($str, ".") !== false) {
1876 18
            $parts = array_map([$this, "quoteSingleIdentifier"], explode(".", $str));
1877
1878 18
            return implode(".", $parts);
1879
        }
1880
1881 392
        return $this->quoteSingleIdentifier($str);
1882
    }
1883
1884
    /**
1885
     * Quotes a single identifier (no dot chain separation).
1886
     *
1887
     * @param string $str The identifier name to be quoted.
1888
     *
1889
     * @return string The quoted identifier string.
1890
     */
1891 378
    public function quoteSingleIdentifier($str)
1892
    {
1893 378
        $c = $this->getIdentifierQuoteCharacter();
1894
1895 378
        return $c . str_replace($c, $c.$c, $str) . $c;
1896
    }
1897
1898
    /**
1899
     * Returns the SQL to create a new foreign key.
1900
     *
1901
     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey The foreign key constraint.
1902
     * @param \Doctrine\DBAL\Schema\Table|string         $table      The name of the table on which the foreign key is to be created.
1903
     *
1904
     * @return string
1905
     */
1906 78
    public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table)
1907
    {
1908 78
        if ($table instanceof Table) {
1909 1
            $table = $table->getQuotedName($this);
1910
        }
1911
1912 78
        $query = 'ALTER TABLE ' . $table . ' ADD ' . $this->getForeignKeyDeclarationSQL($foreignKey);
1913
1914 78
        return $query;
1915
    }
1916
1917
    /**
1918
     * Gets the SQL statements for altering an existing table.
1919
     *
1920
     * This method returns an array of SQL statements, since some platforms need several statements.
1921
     *
1922
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
1923
     *
1924
     * @return array
1925
     *
1926
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1927
     */
1928
    public function getAlterTableSQL(TableDiff $diff)
1929
    {
1930
        throw DBALException::notSupported(__METHOD__);
1931
    }
1932
1933
    /**
1934
     * @param \Doctrine\DBAL\Schema\Column    $column
1935
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
1936
     * @param array                           $columnSql
1937
     *
1938
     * @return bool
1939
     */
1940 96
    protected function onSchemaAlterTableAddColumn(Column $column, TableDiff $diff, &$columnSql)
1941
    {
1942 96
        if (null === $this->_eventManager) {
1943 77
            return false;
1944
        }
1945
1946 19
        if ( ! $this->_eventManager->hasListeners(Events::onSchemaAlterTableAddColumn)) {
1947 1
            return false;
1948
        }
1949
1950 18
        $eventArgs = new SchemaAlterTableAddColumnEventArgs($column, $diff, $this);
1951 18
        $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableAddColumn, $eventArgs);
1952
1953 18
        $columnSql = array_merge($columnSql, $eventArgs->getSql());
1954
1955 18
        return $eventArgs->isDefaultPrevented();
1956
    }
1957
1958
    /**
1959
     * @param \Doctrine\DBAL\Schema\Column    $column
1960
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
1961
     * @param array                           $columnSql
1962
     *
1963
     * @return bool
1964
     */
1965 76
    protected function onSchemaAlterTableRemoveColumn(Column $column, TableDiff $diff, &$columnSql)
1966
    {
1967 76
        if (null === $this->_eventManager) {
1968 57
            return false;
1969
        }
1970
1971 19
        if ( ! $this->_eventManager->hasListeners(Events::onSchemaAlterTableRemoveColumn)) {
1972 1
            return false;
1973
        }
1974
1975 18
        $eventArgs = new SchemaAlterTableRemoveColumnEventArgs($column, $diff, $this);
1976 18
        $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableRemoveColumn, $eventArgs);
1977
1978 18
        $columnSql = array_merge($columnSql, $eventArgs->getSql());
1979
1980 18
        return $eventArgs->isDefaultPrevented();
1981
    }
1982
1983
    /**
1984
     * @param \Doctrine\DBAL\Schema\ColumnDiff $columnDiff
1985
     * @param \Doctrine\DBAL\Schema\TableDiff  $diff
1986
     * @param array                            $columnSql
1987
     *
1988
     * @return bool
1989
     */
1990 185
    protected function onSchemaAlterTableChangeColumn(ColumnDiff $columnDiff, TableDiff $diff, &$columnSql)
1991
    {
1992 185
        if (null === $this->_eventManager) {
1993 155
            return false;
1994
        }
1995
1996 30
        if ( ! $this->_eventManager->hasListeners(Events::onSchemaAlterTableChangeColumn)) {
1997 12
            return false;
1998
        }
1999
2000 18
        $eventArgs = new SchemaAlterTableChangeColumnEventArgs($columnDiff, $diff, $this);
2001 18
        $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableChangeColumn, $eventArgs);
2002
2003 18
        $columnSql = array_merge($columnSql, $eventArgs->getSql());
2004
2005 18
        return $eventArgs->isDefaultPrevented();
2006
    }
2007
2008
    /**
2009
     * @param string                          $oldColumnName
2010
     * @param \Doctrine\DBAL\Schema\Column    $column
2011
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
2012
     * @param array                           $columnSql
2013
     *
2014
     * @return bool
2015
     */
2016 76
    protected function onSchemaAlterTableRenameColumn($oldColumnName, Column $column, TableDiff $diff, &$columnSql)
2017
    {
2018 76
        if (null === $this->_eventManager) {
2019 58
            return false;
2020
        }
2021
2022 18
        if ( ! $this->_eventManager->hasListeners(Events::onSchemaAlterTableRenameColumn)) {
2023
            return false;
2024
        }
2025
2026 18
        $eventArgs = new SchemaAlterTableRenameColumnEventArgs($oldColumnName, $column, $diff, $this);
2027 18
        $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableRenameColumn, $eventArgs);
2028
2029 18
        $columnSql = array_merge($columnSql, $eventArgs->getSql());
2030
2031 18
        return $eventArgs->isDefaultPrevented();
2032
    }
2033
2034
    /**
2035
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
2036
     * @param array                           $sql
2037
     *
2038
     * @return bool
2039
     */
2040 358
    protected function onSchemaAlterTable(TableDiff $diff, &$sql)
2041
    {
2042 358
        if (null === $this->_eventManager) {
2043 321
            return false;
2044
        }
2045
2046 37
        if ( ! $this->_eventManager->hasListeners(Events::onSchemaAlterTable)) {
2047 19
            return false;
2048
        }
2049
2050 18
        $eventArgs = new SchemaAlterTableEventArgs($diff, $this);
2051 18
        $this->_eventManager->dispatchEvent(Events::onSchemaAlterTable, $eventArgs);
2052
2053 18
        $sql = array_merge($sql, $eventArgs->getSql());
2054
2055 18
        return $eventArgs->isDefaultPrevented();
2056
    }
2057
2058
    /**
2059
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
2060
     *
2061
     * @return array
2062
     */
2063 326
    protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
2064
    {
2065 326
        $tableName = $diff->getName($this)->getQuotedName($this);
2066
2067 326
        $sql = [];
2068 326
        if ($this->supportsForeignKeyConstraints()) {
2069 326
            foreach ($diff->removedForeignKeys as $foreignKey) {
2070 25
                $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName);
2071
            }
2072 326
            foreach ($diff->changedForeignKeys as $foreignKey) {
2073 20
                $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName);
2074
            }
2075
        }
2076
2077 326
        foreach ($diff->removedIndexes as $index) {
2078 11
            $sql[] = $this->getDropIndexSQL($index, $tableName);
2079
        }
2080 326
        foreach ($diff->changedIndexes as $index) {
2081 16
            if ($index->isPrimary()) {
2082
                $sql[] = $this->getDropPrimaryKeySQL($tableName);
2083
2084 326
                continue;
2085
            }
2086
2087
            $sql[] = $this->getDropIndexSQL($index, $tableName);
2088
        }
2089
2090
        return $sql;
2091
    }
2092 326
2093
    /**
2094 326
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
2095 34
     *
2096 326
     * @return array
2097
     */
2098 326
    protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
2099
    {
2100 326
        $tableName = (false !== $diff->newName)
2101 326
            ? $diff->getNewName()->getQuotedName($this)
2102 20
            : $diff->getName($this)->getQuotedName($this);
2103
2104
        $sql = [];
2105 326
2106 20
        if ($this->supportsForeignKeyConstraints()) {
2107
            foreach ($diff->addedForeignKeys as $foreignKey) {
2108
                $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName);
2109
            }
2110 326
2111 3
            foreach ($diff->changedForeignKeys as $foreignKey) {
2112
                $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName);
2113
            }
2114 326
        }
2115 16
2116
        foreach ($diff->addedIndexes as $index) {
2117
            $sql[] = $this->getCreateIndexSQL($index, $tableName);
2118 326
        }
2119 85
2120 85
        foreach ($diff->changedIndexes as $index) {
2121 85
            $sql[] = $this->getCreateIndexSQL($index, $tableName);
2122 85
        }
2123
2124
        foreach ($diff->renamedIndexes as $oldIndexName => $index) {
2125
            $oldIndexName = new Identifier($oldIndexName);
2126 326
            $sql          = array_merge(
2127
                $sql,
2128
                $this->getRenameIndexSQL($oldIndexName->getQuotedName($this), $index, $tableName)
2129
            );
2130
        }
2131
2132
        return $sql;
2133
    }
2134
2135
    /**
2136
     * Returns the SQL for renaming an index on a table.
2137
     *
2138 10
     * @param string                      $oldIndexName The name of the index to rename from.
2139
     * @param \Doctrine\DBAL\Schema\Index $index        The definition of the index to rename to.
2140
     * @param string                      $tableName    The table to rename the given index on.
2141 10
     *
2142 10
     * @return array The sequence of SQL statements for renaming the given index.
2143
     */
2144
    protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName)
2145
    {
2146
        return [
2147
            $this->getDropIndexSQL($oldIndexName, $tableName),
2148
            $this->getCreateIndexSQL($index, $tableName)
2149
        ];
2150
    }
2151
2152
    /**
2153
     * Common code for alter table statement generation that updates the changed Index and Foreign Key definitions.
2154
     *
2155
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
2156
     *
2157
     * @return array
2158
     */
2159
    protected function _getAlterTableIndexForeignKeySQL(TableDiff $diff)
2160
    {
2161
        return array_merge($this->getPreAlterTableIndexForeignKeySQL($diff), $this->getPostAlterTableIndexForeignKeySQL($diff));
2162
    }
2163
2164
    /**
2165
     * Gets declaration of a number of fields in bulk.
2166
     *
2167
     * @param array $fields A multidimensional associative array.
2168
     *                      The first dimension determines the field name, while the second
2169
     *                      dimension is keyed with the name of the properties
2170
     *                      of the field being declared as array indexes. Currently, the types
2171
     *                      of supported field properties are as follows:
2172
     *
2173
     *      length
2174
     *          Integer value that determines the maximum length of the text
2175
     *          field. If this argument is missing the field should be
2176
     *          declared to have the longest length allowed by the DBMS.
2177
     *
2178
     *      default
2179
     *          Text value to be used as default for this field.
2180
     *
2181
     *      notnull
2182
     *          Boolean flag that indicates whether this field is constrained
2183
     *          to not be set to null.
2184
     *      charset
2185
     *          Text value with the default CHARACTER SET for this field.
2186
     *      collation
2187 381
     *          Text value with the default COLLATION for this field.
2188
     *      unique
2189 381
     *          unique constraint
2190
     *
2191 381
     * @return string
2192 381
     */
2193
    public function getColumnDeclarationListSQL(array $fields)
2194
    {
2195 381
        $queryFields = [];
2196
2197
        foreach ($fields as $fieldName => $field) {
2198
            $queryFields[] = $this->getColumnDeclarationSQL($fieldName, $field);
2199
        }
2200
2201
        return implode(', ', $queryFields);
2202
    }
2203
2204
    /**
2205
     * Obtains DBMS specific SQL code portion needed to declare a generic type
2206
     * field to be used in statements like CREATE TABLE.
2207
     *
2208
     * @param string $name  The name the field to be declared.
2209
     * @param array  $field An associative array with the name of the properties
2210
     *                      of the field being declared as array indexes. Currently, the types
2211
     *                      of supported field properties are as follows:
2212
     *
2213
     *      length
2214
     *          Integer value that determines the maximum length of the text
2215
     *          field. If this argument is missing the field should be
2216
     *          declared to have the longest length allowed by the DBMS.
2217
     *
2218
     *      default
2219
     *          Text value to be used as default for this field.
2220
     *
2221
     *      notnull
2222
     *          Boolean flag that indicates whether this field is constrained
2223
     *          to not be set to null.
2224
     *      charset
2225
     *          Text value with the default CHARACTER SET for this field.
2226
     *      collation
2227
     *          Text value with the default COLLATION for this field.
2228
     *      unique
2229
     *          unique constraint
2230
     *      check
2231 432
     *          column check constraint
2232
     *      columnDefinition
2233 432
     *          a string that defines the complete column
2234 15
     *
2235
     * @return string DBMS specific SQL code portion that should be used to declare the column.
2236 418
     */
2237
    public function getColumnDeclarationSQL($name, array $field)
2238 418
    {
2239 418
        if (isset($field['columnDefinition'])) {
2240
            $columnDef = $this->getCustomTypeDeclarationSQL($field);
2241 418
        } else {
2242 418
            $default = $this->getDefaultValueDeclarationSQL($field);
2243
2244 418
            $charset = (isset($field['charset']) && $field['charset']) ?
2245
                ' ' . $this->getColumnCharsetDeclarationSQL($field['charset']) : '';
2246 418
2247 418
            $collation = (isset($field['collation']) && $field['collation']) ?
2248
                ' ' . $this->getColumnCollationDeclarationSQL($field['collation']) : '';
2249 418
2250 418
            $notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
2251
2252 418
            $unique = (isset($field['unique']) && $field['unique']) ?
2253 418
                ' ' . $this->getUniqueFieldDeclarationSQL() : '';
2254
2255 418
            $check = (isset($field['check']) && $field['check']) ?
2256 53
                ' ' . $field['check'] : '';
2257
2258
            $typeDecl = $field['type']->getSQLDeclaration($field, $this);
2259
            $columnDef = $typeDecl . $charset . $default . $notnull . $unique . $check . $collation;
2260 432
2261
            if ($this->supportsInlineColumnComments() && isset($field['comment']) && $field['comment'] !== '') {
2262
                $columnDef .= ' ' . $this->getInlineColumnCommentSQL($field['comment']);
2263
            }
2264
        }
2265
2266
        return $name . ' ' . $columnDef;
2267
    }
2268
2269
    /**
2270 133
     * Returns the SQL snippet that declares a floating point column of arbitrary precision.
2271
     *
2272 133
     * @param array $columnDef
2273 133
     *
2274 133
     * @return string
2275 133
     */
2276
    public function getDecimalTypeDeclarationSQL(array $columnDef)
2277 133
    {
2278
        $columnDef['precision'] = ( ! isset($columnDef['precision']) || empty($columnDef['precision']))
2279
            ? 10 : $columnDef['precision'];
2280
        $columnDef['scale'] = ( ! isset($columnDef['scale']) || empty($columnDef['scale']))
2281
            ? 0 : $columnDef['scale'];
2282
2283
        return 'NUMERIC(' . $columnDef['precision'] . ', ' . $columnDef['scale'] . ')';
2284
    }
2285
2286
    /**
2287
     * Obtains DBMS specific SQL code portion needed to set a default value
2288 472
     * declaration to be used in statements like CREATE TABLE.
2289
     *
2290 472
     * @param array $field The field definition array.
2291 405
     *
2292
     * @return string DBMS specific SQL code portion needed to set a default value.
2293
     */
2294 88
    public function getDefaultValueDeclarationSQL($field)
2295
    {
2296 88
        if ( ! isset($field['default'])) {
2297
            return empty($field['notnull']) ? ' DEFAULT NULL' : '';
2298
        }
2299
2300 88
        $default = $field['default'];
2301
2302 88
        if ( ! isset($field['type'])) {
2303 23
            return " DEFAULT '" . $default . "'";
2304
        }
2305
2306 67
        $type = $field['type'];
2307 15
2308
        if ($type instanceof Types\PhpIntegerMappingType) {
2309
            return ' DEFAULT ' . $default;
2310 52
        }
2311
2312
        if ($type instanceof Types\PhpDateTimeMappingType && $default === $this->getCurrentTimestampSQL()) {
2313
            return ' DEFAULT ' . $this->getCurrentTimestampSQL();
2314 52
        }
2315 15
2316
        if ($type instanceof Types\TimeType && $default === $this->getCurrentTimeSQL()) {
2317
            return ' DEFAULT ' . $this->getCurrentTimeSQL();
2318 37
        }
2319 15
2320
        if ($type instanceof Types\DateType && $default === $this->getCurrentDateSQL()) {
2321
            return ' DEFAULT ' . $this->getCurrentDateSQL();
2322 37
        }
2323
2324
        if ($type instanceof Types\BooleanType) {
2325
            return " DEFAULT '" . $this->convertBooleans($default) . "'";
2326
        }
2327
2328
        return " DEFAULT '" . $default . "'";
2329
    }
2330
2331
    /**
2332
     * Obtains DBMS specific SQL code portion needed to set a CHECK constraint
2333 117
     * declaration to be used in statements like CREATE TABLE.
2334
     *
2335 117
     * @param array $definition The check definition.
2336 117
     *
2337 117
     * @return string DBMS specific SQL code portion needed to set a CHECK constraint.
2338
     */
2339
    public function getCheckDeclarationSQL(array $definition)
2340 117
    {
2341 5
        $constraints = [];
2342
        foreach ($definition as $field => $def) {
2343
            if (is_string($def)) {
2344 117
                $constraints[] = 'CHECK (' . $def . ')';
2345 117
            } else {
2346
                if (isset($def['min'])) {
2347
                    $constraints[] = 'CHECK (' . $field . ' >= ' . $def['min'] . ')';
2348
                }
2349
2350 117
                if (isset($def['max'])) {
2351
                    $constraints[] = 'CHECK (' . $field . ' <= ' . $def['max'] . ')';
2352
                }
2353
            }
2354
        }
2355
2356
        return implode(', ', $constraints);
2357
    }
2358
2359
    /**
2360
     * Obtains DBMS specific SQL code portion needed to set a unique
2361
     * constraint declaration to be used in statements like CREATE TABLE.
2362
     *
2363
     * @param string                      $name  The name of the unique constraint.
2364 28
     * @param \Doctrine\DBAL\Schema\Index $index The index definition.
2365
     *
2366 28
     * @return string DBMS specific SQL code portion needed to set a constraint.
2367 28
     *
2368
     * @throws \InvalidArgumentException
2369 28
     */
2370
    public function getUniqueConstraintDeclarationSQL($name, Index $index)
2371
    {
2372
        $columns = $index->getQuotedColumns($this);
2373 28
        $name = new Identifier($name);
2374 28
2375 28
        if (count($columns) === 0) {
2376
            throw new \InvalidArgumentException("Incomplete definition. 'columns' required.");
2377
        }
2378
2379
        return 'CONSTRAINT ' . $name->getQuotedName($this) . ' UNIQUE ('
2380
            . $this->getIndexFieldDeclarationListSQL($columns)
2381
            . ')' . $this->getPartialIndexSQL($index);
2382
    }
2383
2384
    /**
2385
     * Obtains DBMS specific SQL code portion needed to set an index
2386
     * declaration to be used in statements like CREATE TABLE.
2387
     *
2388
     * @param string                      $name  The name of the index.
2389 46
     * @param \Doctrine\DBAL\Schema\Index $index The index definition.
2390
     *
2391 46
     * @return string DBMS specific SQL code portion needed to set an index.
2392 46
     *
2393
     * @throws \InvalidArgumentException
2394 46
     */
2395
    public function getIndexDeclarationSQL($name, Index $index)
2396
    {
2397
        $columns = $index->getQuotedColumns($this);
2398 46
        $name = new Identifier($name);
2399 46
2400 46
        if (count($columns) === 0) {
2401
            throw new \InvalidArgumentException("Incomplete definition. 'columns' required.");
2402
        }
2403
2404
        return $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name->getQuotedName($this) . ' ('
2405
            . $this->getIndexFieldDeclarationListSQL($columns)
2406
            . ')' . $this->getPartialIndexSQL($index);
2407
    }
2408
2409
    /**
2410
     * Obtains SQL code portion needed to create a custom column,
2411
     * e.g. when a field has the "columnDefinition" keyword.
2412 19
     * Only "AUTOINCREMENT" and "PRIMARY KEY" are added if appropriate.
2413
     *
2414 19
     * @param array $columnDef
2415
     *
2416
     * @return string
2417
     */
2418
    public function getCustomTypeDeclarationSQL(array $columnDef)
2419
    {
2420
        return $columnDef['columnDefinition'];
2421
    }
2422
2423
    /**
2424
     * Obtains DBMS specific SQL code portion needed to set an index
2425 253
     * declaration to be used in statements like CREATE TABLE.
2426
     *
2427 253
     * @param array $fields
2428
     *
2429 253
     * @return string
2430 253
     */
2431
    public function getIndexFieldDeclarationListSQL(array $fields)
2432
    {
2433 253
        $ret = [];
2434
2435
        foreach ($fields as $field => $definition) {
2436
            if (is_array($definition)) {
2437 253
                $ret[] = $field;
2438
            } else {
2439
                $ret[] = $definition;
2440
            }
2441
        }
2442
2443
        return implode(', ', $ret);
2444
    }
2445
2446
    /**
2447
     * Returns the required SQL string that fits between CREATE ... TABLE
2448
     * to create the table as a temporary table.
2449
     *
2450
     * Should be overridden in driver classes to return the correct string for the
2451
     * specific database type.
2452
     *
2453
     * The default is to return the string "TEMPORARY" - this will result in a
2454
     * SQL error for any database that does not support temporary tables, or that
2455
     * requires a different SQL command from "CREATE TEMPORARY TABLE".
2456
     *
2457
     * @return string The string required to be placed between "CREATE" and "TABLE"
2458
     *                to generate a temporary table, if possible.
2459
     */
2460
    public function getTemporaryTableSQL()
2461
    {
2462
        return 'TEMPORARY';
2463
    }
2464
2465
    /**
2466
     * Some vendors require temporary table names to be qualified specially.
2467
     *
2468
     * @param string $tableName
2469
     *
2470
     * @return string
2471
     */
2472
    public function getTemporaryTableName($tableName)
2473
    {
2474
        return $tableName;
2475
    }
2476
2477
    /**
2478
     * Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
2479
     * of a field declaration to be used in statements like CREATE TABLE.
2480 113
     *
2481
     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey
2482 113
     *
2483 101
     * @return string DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
2484
     *                of a field declaration.
2485 101
     */
2486
    public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey)
2487
    {
2488
        $sql  = $this->getForeignKeyBaseDeclarationSQL($foreignKey);
2489
        $sql .= $this->getAdvancedForeignKeyOptionsSQL($foreignKey);
2490
2491
        return $sql;
2492
    }
2493
2494
    /**
2495
     * Returns the FOREIGN KEY query section dealing with non-standard options
2496 97
     * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
2497
     *
2498 97
     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey The foreign key definition.
2499 97
     *
2500 4
     * @return string
2501
     */
2502 97
    public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey)
2503 9
    {
2504
        $query = '';
2505
        if ($this->supportsForeignKeyOnUpdate() && $foreignKey->hasOption('onUpdate')) {
2506 97
            $query .= ' ON UPDATE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onUpdate'));
2507
        }
2508
        if ($foreignKey->hasOption('onDelete')) {
2509
            $query .= ' ON DELETE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onDelete'));
2510
        }
2511
2512
        return $query;
2513
    }
2514
2515
    /**
2516
     * Returns the given referential action in uppercase if valid, otherwise throws an exception.
2517
     *
2518 121
     * @param string $action The foreign key referential action.
2519
     *
2520 121
     * @return string
2521
     *
2522 121
     * @throws \InvalidArgumentException if unknown referential action given
2523 82
     */
2524 61
    public function getForeignKeyReferentialActionSQL($action)
2525 48
    {
2526 34
        $upper = strtoupper($action);
2527 104
        switch ($upper) {
2528
            case 'CASCADE':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
2529 17
            case 'SET NULL':
2530
            case 'NO ACTION':
2531
            case 'RESTRICT':
2532
            case 'SET DEFAULT':
2533
                return $upper;
2534
            default:
2535
                throw new \InvalidArgumentException('Invalid foreign key action: ' . $upper);
2536
        }
2537
    }
2538
2539
    /**
2540
     * Obtains DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
2541
     * of a field declaration to be used in statements like CREATE TABLE.
2542
     *
2543 73
     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey
2544
     *
2545 73
     * @return string
2546 73
     *
2547 59
     * @throws \InvalidArgumentException
2548
     */
2549 73
    public function getForeignKeyBaseDeclarationSQL(ForeignKeyConstraint $foreignKey)
2550
    {
2551 73
        $sql = '';
2552
        if (strlen($foreignKey->getName())) {
2553
            $sql .= 'CONSTRAINT ' . $foreignKey->getQuotedName($this) . ' ';
2554 73
        }
2555
        $sql .= 'FOREIGN KEY (';
2556
2557 73
        if (count($foreignKey->getLocalColumns()) === 0) {
2558
            throw new \InvalidArgumentException("Incomplete definition. 'local' required.");
2559
        }
2560
        if (count($foreignKey->getForeignColumns()) === 0) {
2561 73
            throw new \InvalidArgumentException("Incomplete definition. 'foreign' required.");
2562 73
        }
2563 73
        if (strlen($foreignKey->getForeignTableName()) === 0) {
2564 73
            throw new \InvalidArgumentException("Incomplete definition. 'foreignTable' required.");
2565
        }
2566 73
2567
        $sql .= implode(', ', $foreignKey->getQuotedLocalColumns($this))
2568
            . ') REFERENCES '
2569
            . $foreignKey->getQuotedForeignTableName($this) . ' ('
2570
            . implode(', ', $foreignKey->getQuotedForeignColumns($this)) . ')';
2571
2572
        return $sql;
2573
    }
2574
2575
    /**
2576
     * Obtains DBMS specific SQL code portion needed to set the UNIQUE constraint
2577
     * of a field declaration to be used in statements like CREATE TABLE.
2578
     *
2579
     * @return string DBMS specific SQL code portion needed to set the UNIQUE constraint
2580
     *                of a field declaration.
2581
     */
2582
    public function getUniqueFieldDeclarationSQL()
2583
    {
2584
        return 'UNIQUE';
2585
    }
2586
2587
    /**
2588
     * Obtains DBMS specific SQL code portion needed to set the CHARACTER SET
2589
     * of a field declaration to be used in statements like CREATE TABLE.
2590
     *
2591
     * @param string $charset The name of the charset.
2592
     *
2593
     * @return string DBMS specific SQL code portion needed to set the CHARACTER SET
2594
     *                of a field declaration.
2595
     */
2596
    public function getColumnCharsetDeclarationSQL($charset)
0 ignored issues
show
Unused Code introduced by
The parameter $charset 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

2596
    public function getColumnCharsetDeclarationSQL(/** @scrutinizer ignore-unused */ $charset)

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...
2597
    {
2598
        return '';
2599
    }
2600
2601
    /**
2602
     * Obtains DBMS specific SQL code portion needed to set the COLLATION
2603
     * of a field declaration to be used in statements like CREATE TABLE.
2604 1
     *
2605
     * @param string $collation The name of the collation.
2606 1
     *
2607
     * @return string DBMS specific SQL code portion needed to set the COLLATION
2608
     *                of a field declaration.
2609
     */
2610
    public function getColumnCollationDeclarationSQL($collation)
2611
    {
2612
        return $this->supportsColumnCollation() ? 'COLLATE ' . $collation : '';
2613
    }
2614
2615 5
    /**
2616
     * Whether the platform prefers sequences for ID generation.
2617 5
     * Subclasses should override this method to return TRUE if they prefer sequences.
2618
     *
2619
     * @return bool
2620
     */
2621
    public function prefersSequences()
2622
    {
2623
        return false;
2624
    }
2625
2626 6
    /**
2627
     * Whether the platform prefers identity columns (eg. autoincrement) for ID generation.
2628 6
     * Subclasses should override this method to return TRUE if they prefer identity columns.
2629
     *
2630
     * @return bool
2631
     */
2632
    public function prefersIdentityColumns()
2633
    {
2634
        return false;
2635
    }
2636
2637
    /**
2638
     * Some platforms need the boolean values to be converted.
2639
     *
2640
     * The default conversion in this implementation converts to integers (false => 0, true => 1).
2641
     *
2642
     * Note: if the input is not a boolean the original input might be returned.
2643
     *
2644
     * There are two contexts when converting booleans: Literals and Prepared Statements.
2645 23
     * This method should handle the literal case
2646
     *
2647 23
     * @param mixed $item A boolean or an array of them.
2648
     *
2649
     * @return mixed A boolean database value or an array of them.
2650
     */
2651
    public function convertBooleans($item)
2652
    {
2653 23
        if (is_array($item)) {
2654 22
            foreach ($item as $k => $value) {
2655
                if (is_bool($value)) {
2656
                    $item[$k] = (int) $value;
2657 23
                }
2658
            }
2659
        } elseif (is_bool($item)) {
2660
            $item = (int) $item;
2661
        }
2662
2663
        return $item;
2664
    }
2665
2666
    /**
2667
     * Some platforms have boolean literals that needs to be correctly converted
2668
     *
2669 49
     * The default conversion tries to convert value into bool "(bool)$item"
2670
     *
2671 49
     * @param mixed $item
2672
     *
2673
     * @return bool|null
2674
     */
2675
    public function convertFromBoolean($item)
2676
    {
2677
        return null === $item ? null: (bool) $item ;
2678
    }
2679
2680
    /**
2681
     * This method should handle the prepared statements case. When there is no
2682
     * distinction, it's OK to use the same method.
2683
     *
2684 8
     * Note: if the input is not a boolean the original input might be returned.
2685
     *
2686 8
     * @param mixed $item A boolean or an array of them.
2687
     *
2688
     * @return mixed A boolean database value or an array of them.
2689
     */
2690
    public function convertBooleansToDatabaseValue($item)
2691
    {
2692
        return $this->convertBooleans($item);
2693
    }
2694 11
2695
    /**
2696 11
     * Returns the SQL specific for the platform to get the current date.
2697
     *
2698
     * @return string
2699
     */
2700
    public function getCurrentDateSQL()
2701
    {
2702
        return 'CURRENT_DATE';
2703
    }
2704
2705
    /**
2706
     * Returns the SQL specific for the platform to get the current time.
2707
     *
2708
     * @return string
2709
     */
2710
    public function getCurrentTimeSQL()
2711
    {
2712
        return 'CURRENT_TIME';
2713
    }
2714 17
2715
    /**
2716 17
     * Returns the SQL specific for the platform to get the current timestamp
2717
     *
2718
     * @return string
2719
     */
2720
    public function getCurrentTimestampSQL()
2721
    {
2722
        return 'CURRENT_TIMESTAMP';
2723
    }
2724
2725
    /**
2726
     * Returns the SQL for a given transaction isolation level Connection constant.
2727
     *
2728 11
     * @param int $level
2729
     *
2730
     * @return string
2731 11
     *
2732 11
     * @throws \InvalidArgumentException
2733 11
     */
2734 11
    protected function _getTransactionIsolationLevelSQL($level)
2735 11
    {
2736 11
        switch ($level) {
2737 11
            case TransactionIsolationLevel::READ_UNCOMMITTED:
2738 11
                return 'READ UNCOMMITTED';
2739
            case TransactionIsolationLevel::READ_COMMITTED:
2740
                return 'READ COMMITTED';
2741
            case TransactionIsolationLevel::REPEATABLE_READ:
2742
                return 'REPEATABLE READ';
2743
            case TransactionIsolationLevel::SERIALIZABLE:
2744
                return 'SERIALIZABLE';
2745
            default:
2746
                throw new \InvalidArgumentException('Invalid isolation level:' . $level);
2747
        }
2748
    }
2749 1
2750
    /**
2751 1
     * @return string
2752
     *
2753
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2754
     */
2755
    public function getListDatabasesSQL()
2756
    {
2757
        throw DBALException::notSupported(__METHOD__);
2758
    }
2759
2760
    /**
2761
     * Returns the SQL statement for retrieving the namespaces defined in the database.
2762
     *
2763
     * @return string
2764
     *
2765
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2766
     */
2767
    public function getListNamespacesSQL()
2768
    {
2769
        throw DBALException::notSupported(__METHOD__);
2770
    }
2771
2772
    /**
2773
     * @param string $database
2774
     *
2775
     * @return string
2776
     *
2777
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2778
     */
2779
    public function getListSequencesSQL($database)
2780
    {
2781
        throw DBALException::notSupported(__METHOD__);
2782
    }
2783
2784
    /**
2785
     * @param string $table
2786
     *
2787
     * @return string
2788
     *
2789
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2790
     */
2791
    public function getListTableConstraintsSQL($table)
2792
    {
2793
        throw DBALException::notSupported(__METHOD__);
2794
    }
2795
2796
    /**
2797
     * @param string      $table
2798
     * @param string|null $database
2799
     *
2800
     * @return string
2801
     *
2802
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2803
     */
2804
    public function getListTableColumnsSQL($table, $database = null)
2805
    {
2806
        throw DBALException::notSupported(__METHOD__);
2807
    }
2808
2809
    /**
2810
     * @return string
2811
     *
2812
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2813
     */
2814
    public function getListTablesSQL()
2815
    {
2816
        throw DBALException::notSupported(__METHOD__);
2817
    }
2818
2819
    /**
2820
     * @return string
2821
     *
2822
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2823
     */
2824
    public function getListUsersSQL()
2825
    {
2826
        throw DBALException::notSupported(__METHOD__);
2827
    }
2828
2829
    /**
2830
     * Returns the SQL to list all views of a database or user.
2831
     *
2832
     * @param string $database
2833
     *
2834
     * @return string
2835
     *
2836
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2837
     */
2838
    public function getListViewsSQL($database)
2839
    {
2840
        throw DBALException::notSupported(__METHOD__);
2841
    }
2842
2843
    /**
2844
     * Returns the list of indexes for the current database.
2845
     *
2846
     * The current database parameter is optional but will always be passed
2847
     * when using the SchemaManager API and is the database the given table is in.
2848
     *
2849
     * Attention: Some platforms only support currentDatabase when they
2850
     * are connected with that database. Cross-database information schema
2851
     * requests may be impossible.
2852
     *
2853
     * @param string $table
2854
     * @param string $currentDatabase
2855
     *
2856
     * @return string
2857
     *
2858
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2859
     */
2860
    public function getListTableIndexesSQL($table, $currentDatabase = null)
2861
    {
2862
        throw DBALException::notSupported(__METHOD__);
2863
    }
2864
2865
    /**
2866
     * @param string $table
2867
     *
2868
     * @return string
2869
     *
2870
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2871
     */
2872
    public function getListTableForeignKeysSQL($table)
2873
    {
2874
        throw DBALException::notSupported(__METHOD__);
2875
    }
2876
2877
    /**
2878
     * @param string $name
2879
     * @param string $sql
2880
     *
2881
     * @return string
2882
     *
2883
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2884
     */
2885
    public function getCreateViewSQL($name, $sql)
2886
    {
2887
        throw DBALException::notSupported(__METHOD__);
2888
    }
2889
2890
    /**
2891
     * @param string $name
2892
     *
2893
     * @return string
2894
     *
2895
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2896
     */
2897
    public function getDropViewSQL($name)
2898
    {
2899
        throw DBALException::notSupported(__METHOD__);
2900
    }
2901
2902
    /**
2903
     * Returns the SQL snippet to drop an existing sequence.
2904
     *
2905
     * @param Sequence|string $sequence
2906
     *
2907
     * @return string
2908
     *
2909
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2910
     */
2911
    public function getDropSequenceSQL($sequence)
0 ignored issues
show
Unused Code introduced by
The parameter $sequence 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

2911
    public function getDropSequenceSQL(/** @scrutinizer ignore-unused */ $sequence)

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...
2912
    {
2913
        throw DBALException::notSupported(__METHOD__);
2914
    }
2915
2916
    /**
2917
     * @param string $sequenceName
2918
     *
2919
     * @return string
2920
     *
2921
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2922
     */
2923
    public function getSequenceNextValSQL($sequenceName)
0 ignored issues
show
Unused Code introduced by
The parameter $sequenceName 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

2923
    public function getSequenceNextValSQL(/** @scrutinizer ignore-unused */ $sequenceName)

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...
2924
    {
2925
        throw DBALException::notSupported(__METHOD__);
2926
    }
2927
2928
    /**
2929
     * Returns the SQL to create a new database.
2930
     *
2931 1
     * @param string $database The name of the database that should be created.
2932
     *
2933 1
     * @return string
2934
     *
2935
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2936
     */
2937
    public function getCreateDatabaseSQL($database)
2938
    {
2939
        throw DBALException::notSupported(__METHOD__);
2940
    }
2941
2942
    /**
2943
     * Returns the SQL to set the transaction isolation level.
2944
     *
2945
     * @param int $level
2946
     *
2947
     * @return string
2948
     *
2949
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2950
     */
2951
    public function getSetTransactionIsolationSQL($level)
2952
    {
2953
        throw DBALException::notSupported(__METHOD__);
2954
    }
2955
2956
    /**
2957
     * Obtains DBMS specific SQL to be used to create datetime fields in
2958
     * statements like CREATE TABLE.
2959
     *
2960
     * @param array $fieldDeclaration
2961
     *
2962
     * @return string
2963
     *
2964
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2965
     */
2966
    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
2967
    {
2968
        throw DBALException::notSupported(__METHOD__);
2969
    }
2970
2971
    /**
2972 15
     * Obtains DBMS specific SQL to be used to create datetime with timezone offset fields.
2973
     *
2974 15
     * @param array $fieldDeclaration
2975
     *
2976
     * @return string
2977
     */
2978
    public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
2979
    {
2980
        return $this->getDateTimeTypeDeclarationSQL($fieldDeclaration);
2981
    }
2982
2983
2984
    /**
2985
     * Obtains DBMS specific SQL to be used to create date fields in statements
2986
     * like CREATE TABLE.
2987
     *
2988
     * @param array $fieldDeclaration
2989
     *
2990
     * @return string
2991
     *
2992
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2993
     */
2994
    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
2995
    {
2996
        throw DBALException::notSupported(__METHOD__);
2997
    }
2998
2999
    /**
3000
     * Obtains DBMS specific SQL to be used to create time fields in statements
3001
     * like CREATE TABLE.
3002
     *
3003
     * @param array $fieldDeclaration
3004
     *
3005
     * @return string
3006
     *
3007
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
3008
     */
3009
    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
3010
    {
3011
        throw DBALException::notSupported(__METHOD__);
3012
    }
3013 105
3014
    /**
3015 105
     * @param array $fieldDeclaration
3016
     *
3017
     * @return string
3018
     */
3019
    public function getFloatDeclarationSQL(array $fieldDeclaration)
3020
    {
3021
        return 'DOUBLE PRECISION';
3022
    }
3023
3024
    /**
3025
     * Gets the default transaction isolation level of the platform.
3026
     *
3027
     * @return int The default isolation level.
3028
     *
3029
     * @see TransactionIsolationLevel
3030
     */
3031
    public function getDefaultTransactionIsolationLevel()
3032
    {
3033
        return TransactionIsolationLevel::READ_COMMITTED;
3034
    }
3035
3036
    /* supports*() methods */
3037 6
3038
    /**
3039 6
     * Whether the platform supports sequences.
3040
     *
3041
     * @return bool
3042
     */
3043
    public function supportsSequences()
3044
    {
3045
        return false;
3046
    }
3047
3048
    /**
3049
     * Whether the platform supports identity columns.
3050 1
     *
3051
     * Identity columns are columns that receive an auto-generated value from the
3052 1
     * database on insert of a row.
3053
     *
3054
     * @return bool
3055
     */
3056
    public function supportsIdentityColumns()
3057
    {
3058
        return false;
3059
    }
3060
3061
    /**
3062
     * Whether the platform emulates identity columns through sequences.
3063
     *
3064 13
     * Some platforms that do not support identity columns natively
3065
     * but support sequences can emulate identity columns by using
3066 13
     * sequences.
3067
     *
3068
     * @return bool
3069
     */
3070
    public function usesSequenceEmulatedIdentityColumns()
3071
    {
3072
        return false;
3073
    }
3074
3075
    /**
3076
     * Returns the name of the sequence for a particular identity column in a particular table.
3077
     *
3078
     * @param string $tableName  The name of the table to return the sequence name for.
3079
     * @param string $columnName The name of the identity column in the table to return the sequence name for.
3080
     *
3081 12
     * @return string
3082
     *
3083 12
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
3084
     *
3085
     * @see    usesSequenceEmulatedIdentityColumns
3086
     */
3087
    public function getIdentitySequenceName($tableName, $columnName)
3088
    {
3089
        throw DBALException::notSupported(__METHOD__);
3090
    }
3091 4
3092
    /**
3093 4
     * Whether the platform supports indexes.
3094
     *
3095
     * @return bool
3096
     */
3097
    public function supportsIndexes()
3098
    {
3099
        return true;
3100
    }
3101 143
3102
    /**
3103 143
     * Whether the platform supports partial indexes.
3104
     *
3105
     * @return bool
3106
     */
3107
    public function supportsPartialIndexes()
3108
    {
3109
        return false;
3110
    }
3111 5
3112
    /**
3113 5
     * Whether the platform supports altering tables.
3114
     *
3115
     * @return bool
3116
     */
3117
    public function supportsAlterTable()
3118
    {
3119
        return true;
3120
    }
3121 4
3122
    /**
3123 4
     * Whether the platform supports transactions.
3124
     *
3125
     * @return bool
3126
     */
3127
    public function supportsTransactions()
3128
    {
3129
        return true;
3130
    }
3131 22
3132
    /**
3133 22
     * Whether the platform supports savepoints.
3134
     *
3135
     * @return bool
3136
     */
3137
    public function supportsSavepoints()
3138
    {
3139
        return true;
3140
    }
3141 5
3142
    /**
3143 5
     * Whether the platform supports releasing savepoints.
3144
     *
3145
     * @return bool
3146
     */
3147
    public function supportsReleaseSavepoints()
3148
    {
3149
        return $this->supportsSavepoints();
3150
    }
3151 4
3152
    /**
3153 4
     * Whether the platform supports primary key constraints.
3154
     *
3155
     * @return bool
3156
     */
3157
    public function supportsPrimaryConstraints()
3158
    {
3159
        return true;
3160
    }
3161 423
3162
    /**
3163 423
     * Whether the platform supports foreign key constraints.
3164
     *
3165
     * @return bool
3166
     */
3167
    public function supportsForeignKeyConstraints()
3168
    {
3169
        return true;
3170
    }
3171 101
3172
    /**
3173 101
     * Whether this platform supports onUpdate in foreign key constraints.
3174
     *
3175
     * @return bool
3176
     */
3177
    public function supportsForeignKeyOnUpdate()
3178
    {
3179
        return ($this->supportsForeignKeyConstraints() && true);
3180
    }
3181 10
3182
    /**
3183 10
     * Whether the platform supports database schemas.
3184
     *
3185
     * @return bool
3186
     */
3187
    public function supportsSchemas()
3188
    {
3189
        return false;
3190
    }
3191
3192
    /**
3193
     * Whether this platform can emulate schemas.
3194
     *
3195 4
     * Platforms that either support or emulate schemas don't automatically
3196
     * filter a schema for the namespaced elements in {@link
3197 4
     * AbstractManager#createSchema}.
3198
     *
3199
     * @return bool
3200
     */
3201
    public function canEmulateSchemas()
3202
    {
3203
        return false;
3204
    }
3205
3206
    /**
3207
     * Returns the default schema name.
3208
     *
3209
     * @return string
3210
     *
3211
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
3212
     */
3213
    public function getDefaultSchemaName()
3214
    {
3215
        throw DBALException::notSupported(__METHOD__);
3216
    }
3217
3218
    /**
3219 4
     * Whether this platform supports create database.
3220
     *
3221 4
     * Some databases don't allow to create and drop databases at all or only with certain tools.
3222
     *
3223
     * @return bool
3224
     */
3225
    public function supportsCreateDropDatabase()
3226
    {
3227
        return true;
3228
    }
3229 4
3230
    /**
3231 4
     * Whether the platform supports getting the affected rows of a recent update/delete type query.
3232
     *
3233
     * @return bool
3234
     */
3235
    public function supportsGettingAffectedRows()
3236
    {
3237
        return true;
3238
    }
3239 196
3240
    /**
3241 196
     * Whether this platform support to add inline column comments as postfix.
3242
     *
3243
     * @return bool
3244
     */
3245
    public function supportsInlineColumnComments()
3246
    {
3247
        return false;
3248
    }
3249 247
3250
    /**
3251 247
     * Whether this platform support the proprietary syntax "COMMENT ON asset".
3252
     *
3253
     * @return bool
3254
     */
3255
    public function supportsCommentOnStatement()
3256
    {
3257
        return false;
3258
    }
3259 300
3260
    /**
3261 300
     * Does this platform have native guid type.
3262
     *
3263
     * @return bool
3264
     */
3265
    public function hasNativeGuidType()
3266
    {
3267
        return false;
3268
    }
3269 626
3270
    /**
3271 626
     * Does this platform have native JSON type.
3272
     *
3273
     * @return bool
3274
     */
3275
    public function hasNativeJsonType()
3276
    {
3277
        return false;
3278
    }
3279
3280
    /**
3281
     * @deprecated
3282
     * @todo Remove in 3.0
3283
     */
3284
    public function getIdentityColumnNullInsertSQL()
3285
    {
3286
        return "";
3287
    }
3288 1
3289
    /**
3290 1
     * Whether this platform supports views.
3291
     *
3292
     * @return bool
3293
     */
3294
    public function supportsViews()
3295
    {
3296
        return true;
3297
    }
3298
3299
    /**
3300
     * Does this platform support column collation?
3301
     *
3302
     * @return bool
3303
     */
3304
    public function supportsColumnCollation()
3305
    {
3306
        return false;
3307
    }
3308
3309 18
    /**
3310
     * Gets the format string, as accepted by the date() function, that describes
3311 18
     * the format of a stored datetime value of this platform.
3312
     *
3313
     * @return string The format string.
3314
     */
3315
    public function getDateTimeFormatString()
3316
    {
3317
        return 'Y-m-d H:i:s';
3318
    }
3319
3320 8
    /**
3321
     * Gets the format string, as accepted by the date() function, that describes
3322 8
     * the format of a stored datetime with timezone value of this platform.
3323
     *
3324
     * @return string The format string.
3325
     */
3326
    public function getDateTimeTzFormatString()
3327
    {
3328
        return 'Y-m-d H:i:s';
3329
    }
3330
3331 7
    /**
3332
     * Gets the format string, as accepted by the date() function, that describes
3333 7
     * the format of a stored date value of this platform.
3334
     *
3335
     * @return string The format string.
3336
     */
3337
    public function getDateFormatString()
3338
    {
3339
        return 'Y-m-d';
3340
    }
3341
3342 6
    /**
3343
     * Gets the format string, as accepted by the date() function, that describes
3344 6
     * the format of a stored time value of this platform.
3345
     *
3346
     * @return string The format string.
3347
     */
3348
    public function getTimeFormatString()
3349
    {
3350
        return 'H:i:s';
3351
    }
3352
3353
    /**
3354
     * Adds an driver-specific LIMIT clause to the query.
3355
     *
3356
     * @param string   $query
3357
     * @param int|null $limit
3358 118
     * @param int|null $offset
3359
     *
3360 118
     * @return string
3361 112
     *
3362
     * @throws DBALException
3363
     */
3364 118
    final public function modifyLimitQuery($query, $limit, $offset = null)
3365 47
    {
3366
        if ($limit !== null) {
3367 47
            $limit = (int) $limit;
3368
        }
3369
3370 47
        if ($offset !== null) {
3371
            $offset = (int) $offset;
3372
3373
            if ($offset < 0) {
3374
                throw new DBALException("LIMIT argument offset=$offset is not valid");
3375 118
            }
3376
            if ($offset > 0 && ! $this->supportsLimitOffset()) {
3377
                throw new DBALException(sprintf("Platform %s does not support offset values in limit queries.", $this->getName()));
3378
            }
3379
        }
3380
3381
        return $this->doModifyLimitQuery($query, $limit, $offset);
3382
    }
3383
3384
    /**
3385
     * Adds an driver-specific LIMIT clause to the query.
3386
     *
3387 19
     * @param string   $query
3388
     * @param int|null $limit
3389 19
     * @param int|null $offset
3390 19
     *
3391
     * @return string
3392
     */
3393 19
    protected function doModifyLimitQuery($query, $limit, $offset)
3394 13
    {
3395
        if ($limit !== null) {
3396
            $query .= ' LIMIT ' . $limit;
3397 19
        }
3398
3399
        if ($offset !== null) {
3400
            $query .= ' OFFSET ' . $offset;
3401
        }
3402
3403
        return $query;
3404
    }
3405 18
3406
    /**
3407 18
     * Whether the database platform support offsets in modify limit clauses.
3408
     *
3409
     * @return bool
3410
     */
3411
    public function supportsLimitOffset()
3412
    {
3413
        return true;
3414
    }
3415
3416
    /**
3417
     * Gets the character casing of a column in an SQL result set of this platform.
3418
     *
3419
     * @param string $column The column name for which to get the correct character casing.
3420
     *
3421
     * @return string The column name in the character casing used in SQL result sets.
3422
     */
3423
    public function getSQLResultCasing($column)
3424
    {
3425
        return $column;
3426
    }
3427
3428
    /**
3429
     * Makes any fixes to a name of a schema element (table, sequence, ...) that are required
3430
     * by restrictions of the platform, like a maximum length.
3431
     *
3432
     * @param string $schemaElementName
3433
     *
3434
     * @return string
3435
     */
3436
    public function fixSchemaElementName($schemaElementName)
3437
    {
3438
        return $schemaElementName;
3439
    }
3440 14
3441
    /**
3442 14
     * Maximum length of any given database identifier, like tables or column names.
3443
     *
3444
     * @return int
3445
     */
3446
    public function getMaxIdentifierLength()
3447
    {
3448
        return 63;
3449
    }
3450
3451
    /**
3452
     * Returns the insert SQL for an empty insert statement.
3453 1
     *
3454
     * @param string $tableName
3455 1
     * @param string $identifierColumnName
3456
     *
3457
     * @return string
3458
     */
3459
    public function getEmptyIdentityInsertSQL($tableName, $identifierColumnName)
3460
    {
3461
        return 'INSERT INTO ' . $tableName . ' (' . $identifierColumnName . ') VALUES (null)';
3462
    }
3463
3464
    /**
3465
     * Generates a Truncate Table SQL statement for a given table.
3466
     *
3467
     * Cascade is not supported on many platforms but would optionally cascade the truncate by
3468
     * following the foreign keys.
3469 3
     *
3470
     * @param string $tableName
3471 3
     * @param bool   $cascade
3472
     *
3473 3
     * @return string
3474
     */
3475
    public function getTruncateTableSQL($tableName, $cascade = false)
0 ignored issues
show
Unused Code introduced by
The parameter $cascade 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

3475
    public function getTruncateTableSQL($tableName, /** @scrutinizer ignore-unused */ $cascade = false)

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...
3476
    {
3477
        $tableIdentifier = new Identifier($tableName);
3478
3479
        return 'TRUNCATE ' . $tableIdentifier->getQuotedName($this);
3480
    }
3481 8
3482
    /**
3483 8
     * This is for test reasons, many vendors have special requirements for dummy statements.
3484
     *
3485
     * @return string
3486
     */
3487
    public function getDummySelectSQL()
3488
    {
3489
        return 'SELECT 1';
3490
    }
3491
3492
    /**
3493 1
     * Returns the SQL to create a new savepoint.
3494
     *
3495 1
     * @param string $savepoint
3496
     *
3497
     * @return string
3498
     */
3499
    public function createSavePoint($savepoint)
3500
    {
3501
        return 'SAVEPOINT ' . $savepoint;
3502
    }
3503
3504
    /**
3505 1
     * Returns the SQL to release a savepoint.
3506
     *
3507 1
     * @param string $savepoint
3508
     *
3509
     * @return string
3510
     */
3511
    public function releaseSavePoint($savepoint)
3512
    {
3513
        return 'RELEASE SAVEPOINT ' . $savepoint;
3514
    }
3515
3516
    /**
3517 1
     * Returns the SQL to rollback a savepoint.
3518
     *
3519 1
     * @param string $savepoint
3520
     *
3521
     * @return string
3522
     */
3523
    public function rollbackSavePoint($savepoint)
3524
    {
3525
        return 'ROLLBACK TO SAVEPOINT ' . $savepoint;
3526
    }
3527
3528
    /**
3529 1078
     * Returns the keyword list instance of this platform.
3530
     *
3531
     * @return \Doctrine\DBAL\Platforms\Keywords\KeywordList
3532 1078
     *
3533 1011
     * @throws \Doctrine\DBAL\DBALException If no keyword list is specified.
3534
     */
3535
    final public function getReservedKeywordsList()
3536 954
    {
3537 954
        // Check for an existing instantiation of the keywords class.
3538 954
        if ($this->_keywords) {
3539
            return $this->_keywords;
3540
        }
3541
3542
        $class = $this->getReservedKeywordsClass();
3543 954
        $keywords = new $class;
3544
        if ( ! $keywords instanceof \Doctrine\DBAL\Platforms\Keywords\KeywordList) {
3545 954
            throw DBALException::notSupported(__METHOD__);
3546
        }
3547
3548
        // Store the instance so it doesn't need to be generated on every request.
3549
        $this->_keywords = $keywords;
3550
3551
        return $keywords;
3552
    }
3553
3554
    /**
3555
     * Returns the class name of the reserved keywords list.
3556
     *
3557
     * @return string
3558
     *
3559
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
3560
     */
3561
    protected function getReservedKeywordsClass()
3562
    {
3563
        throw DBALException::notSupported(__METHOD__);
3564
    }
3565
3566
    /**
3567
     * Quotes a literal string.
3568
     * This method is NOT meant to fix SQL injections!
3569
     * It is only meant to escape this platform's string literal
3570 334
     * quote character inside the given literal string.
3571
     *
3572 334
     * @param string $str The literal string to be quoted.
3573
     *
3574 334
     * @return string The quoted literal string.
3575
     */
3576
    public function quoteStringLiteral($str)
3577
    {
3578
        $c = $this->getStringLiteralQuoteCharacter();
3579
3580
        return $c . str_replace($c, $c . $c, $str) . $c;
3581
    }
3582 352
3583
    /**
3584 352
     * Gets the character used for string literal quoting.
3585
     *
3586
     * @return string
3587
     */
3588
    public function getStringLiteralQuoteCharacter()
3589
    {
3590
        return "'";
3591
    }
3592
3593
    /**
3594
     * Escapes metacharacters in a string intended to be used with a LIKE
3595 19
     * operator.
3596
     *
3597 19
     * @param string $inputString a literal, unquoted string
3598 19
     * @param string $escapeChar  should be reused by the caller in the LIKE
3599 19
     *                            expression.
3600 19
     */
3601
    final public function escapeStringForLike(string $inputString, string $escapeChar) : string
3602
    {
3603
        return preg_replace(
3604 19
            '~([' . preg_quote($this->getLikeWildcardCharacters() . $escapeChar, '~') . '])~u',
3605
            addcslashes($escapeChar, '\\') . '$1',
3606 19
            $inputString
3607
        );
3608
    }
3609
3610
    protected function getLikeWildcardCharacters() : string
3611
    {
3612
        return '%_';
3613
    }
3614
3615
    protected function getDropPrimaryKeySQL(string $table) : string
3616
    {
3617
        return 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY';
3618
    }
3619
}
3620