Failed Conditions
Pull Request — master (#2929)
by Alexander
12:25
created

getPreAlterTableIndexForeignKeySQL()   C

Complexity

Conditions 7
Paths 12

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 7.0119

Importance

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

338
    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...
339
    {
340
        throw DBALException::notSupported('VARCHARs not supported by Platform.');
341
    }
342
343
    /**
344
     * Returns the SQL snippet used to declare a BINARY/VARBINARY column type.
345
     *
346
     * @param integer $length The length of the column.
347
     * @param boolean $fixed  Whether the column length is fixed.
348
     *
349
     * @return string
350
     *
351
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
352
     */
353
    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

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

793
            $expression .= /** @scrutinizer ignore-type */ $char . ' ';
Loading history...
794
        }
795
796
        if ($pos || false !== $char) {
797
            $expression .= 'FROM ';
798
        }
799
800
        return 'TRIM(' . $expression . $str . ')';
801
    }
802
803
    /**
804
     * Returns the SQL snippet to trim trailing space characters from the expression.
805
     *
806
     * @param string $str Literal string or column name.
807
     *
808
     * @return string
809
     */
810 4
    public function getRtrimExpression($str)
811
    {
812 4
        return 'RTRIM(' . $str . ')';
813
    }
814
815
    /**
816
     * Returns the SQL snippet to trim leading space characters from the expression.
817
     *
818
     * @param string $str Literal string or column name.
819
     *
820
     * @return string
821
     */
822 4
    public function getLtrimExpression($str)
823
    {
824 4
        return 'LTRIM(' . $str . ')';
825
    }
826
827
    /**
828
     * Returns the SQL snippet to change all characters from the expression to uppercase,
829
     * according to the current character set mapping.
830
     *
831
     * @param string $str Literal string or column name.
832
     *
833
     * @return string
834
     */
835
    public function getUpperExpression($str)
836
    {
837
        return 'UPPER(' . $str . ')';
838
    }
839
840
    /**
841
     * Returns the SQL snippet to change all characters from the expression to lowercase,
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 getLowerExpression($str)
849
    {
850
        return 'LOWER(' . $str . ')';
851
    }
852
853
    /**
854
     * Returns the SQL snippet to get the position of the first occurrence of substring $substr in string $str.
855
     *
856
     * @param string          $str      Literal string.
857
     * @param string          $substr   Literal string to find.
858
     * @param integer|boolean $startPos Position to start at, beginning of string by default.
859
     *
860
     * @return string
861
     *
862
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
863
     */
864
    public function getLocateExpression($str, $substr, $startPos = false)
0 ignored issues
show
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

864
    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...
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

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

1035
    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

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

1293
    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

1293
    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

1293
    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...
1294
    {
1295
        throw DBALException::notSupported(__METHOD__);
1296
    }
1297
1298
    /**
1299
     * Returns the SQL bit AND comparison expression.
1300
     *
1301
     * @param string $value1
1302
     * @param string $value2
1303
     *
1304
     * @return string
1305
     */
1306 17
    public function getBitAndComparisonExpression($value1, $value2)
1307
    {
1308 17
        return '(' . $value1 . ' & ' . $value2 . ')';
1309
    }
1310
1311
    /**
1312
     * Returns the SQL bit OR comparison expression.
1313
     *
1314
     * @param string $value1
1315
     * @param string $value2
1316
     *
1317
     * @return string
1318
     */
1319 17
    public function getBitOrComparisonExpression($value1, $value2)
1320
    {
1321 17
        return '(' . $value1 . ' | ' . $value2 . ')';
1322
    }
1323
1324
    /**
1325
     * Returns the FOR UPDATE expression.
1326
     *
1327
     * @return string
1328
     */
1329
    public function getForUpdateSQL()
1330
    {
1331
        return 'FOR UPDATE';
1332
    }
1333
1334
    /**
1335
     * Honors that some SQL vendors such as MsSql use table hints for locking instead of the ANSI SQL FOR UPDATE specification.
1336
     *
1337
     * @param string       $fromClause The FROM clause to append the hint for the given lock mode to.
1338
     * @param integer|null $lockMode   One of the Doctrine\DBAL\LockMode::* constants. If null is given, nothing will
1339
     *                                 be appended to the FROM clause.
1340
     *
1341
     * @return string
1342
     */
1343
    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

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

1700
    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...
1701
    {
1702
        throw DBALException::notSupported(__METHOD__);
1703
    }
1704
1705
    /**
1706
     * Returns the SQL to change a sequence on this platform.
1707
     *
1708
     * @param \Doctrine\DBAL\Schema\Sequence $sequence
1709
     *
1710
     * @return string
1711
     *
1712
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1713
     */
1714
    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

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

1831
        return 'ALTER TABLE ' . /** @scrutinizer ignore-type */ $table . ' ADD PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index->getQuotedColumns($this)) . ')';
Loading history...
1832
    }
1833
1834
    /**
1835
     * Returns the SQL to create a named schema.
1836
     *
1837
     * @param string $schemaName
1838
     *
1839
     * @return string
1840
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
1841
     */
1842 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

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

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

2897
    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...
2898
    {
2899
        throw DBALException::notSupported(__METHOD__);
2900
    }
2901
2902
    /**
2903
     * @param string $sequenceName
2904
     *
2905
     * @return string
2906
     *
2907
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
2908
     */
2909
    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

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

3461
    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...
3462
    {
3463 3
        $tableIdentifier = new Identifier($tableName);
3464
3465 3
        return 'TRUNCATE ' . $tableIdentifier->getQuotedName($this);
3466
    }
3467
3468
    /**
3469
     * This is for test reasons, many vendors have special requirements for dummy statements.
3470
     *
3471
     * @return string
3472
     */
3473 6
    public function getDummySelectSQL()
3474
    {
3475 6
        return 'SELECT 1';
3476
    }
3477
3478
    /**
3479
     * Returns the SQL to create a new savepoint.
3480
     *
3481
     * @param string $savepoint
3482
     *
3483
     * @return string
3484
     */
3485 1
    public function createSavePoint($savepoint)
3486
    {
3487 1
        return 'SAVEPOINT ' . $savepoint;
3488
    }
3489
3490
    /**
3491
     * Returns the SQL to release a savepoint.
3492
     *
3493
     * @param string $savepoint
3494
     *
3495
     * @return string
3496
     */
3497 1
    public function releaseSavePoint($savepoint)
3498
    {
3499 1
        return 'RELEASE SAVEPOINT ' . $savepoint;
3500
    }
3501
3502
    /**
3503
     * Returns the SQL to rollback a savepoint.
3504
     *
3505
     * @param string $savepoint
3506
     *
3507
     * @return string
3508
     */
3509 1
    public function rollbackSavePoint($savepoint)
3510
    {
3511 1
        return 'ROLLBACK TO SAVEPOINT ' . $savepoint;
3512
    }
3513
3514
    /**
3515
     * Returns the keyword list instance of this platform.
3516
     *
3517
     * @return \Doctrine\DBAL\Platforms\Keywords\KeywordList
3518
     *
3519
     * @throws \Doctrine\DBAL\DBALException If no keyword list is specified.
3520
     */
3521 1076
    final public function getReservedKeywordsList()
3522
    {
3523
        // Check for an existing instantiation of the keywords class.
3524 1076
        if ($this->_keywords) {
3525 1009
            return $this->_keywords;
3526
        }
3527
3528 953
        $class = $this->getReservedKeywordsClass();
3529 953
        $keywords = new $class;
3530 953
        if ( ! $keywords instanceof \Doctrine\DBAL\Platforms\Keywords\KeywordList) {
3531
            throw DBALException::notSupported(__METHOD__);
3532
        }
3533
3534
        // Store the instance so it doesn't need to be generated on every request.
3535 953
        $this->_keywords = $keywords;
3536
3537 953
        return $keywords;
3538
    }
3539
3540
    /**
3541
     * Returns the class name of the reserved keywords list.
3542
     *
3543
     * @return string
3544
     *
3545
     * @throws \Doctrine\DBAL\DBALException If not supported on this platform.
3546
     */
3547
    protected function getReservedKeywordsClass()
3548
    {
3549
        throw DBALException::notSupported(__METHOD__);
3550
    }
3551
3552
    /**
3553
     * Quotes a literal string.
3554
     * This method is NOT meant to fix SQL injections!
3555
     * It is only meant to escape this platform's string literal
3556
     * quote character inside the given literal string.
3557
     *
3558
     * @param string $str The literal string to be quoted.
3559
     *
3560
     * @return string The quoted literal string.
3561
     */
3562 334
    public function quoteStringLiteral($str)
3563
    {
3564 334
        $c = $this->getStringLiteralQuoteCharacter();
3565
3566 334
        return $c . str_replace($c, $c . $c, $str) . $c;
3567
    }
3568
3569
    /**
3570
     * Gets the character used for string literal quoting.
3571
     *
3572
     * @return string
3573
     */
3574 352
    public function getStringLiteralQuoteCharacter()
3575
    {
3576 352
        return "'";
3577
    }
3578
3579 19
    protected function getDropPrimaryKeySQL(string $table): string
3580
    {
3581 19
        return 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY';
3582
    }
3583
}
3584