Failed Conditions
Pull Request — master (#2850)
by Adrien
33:12 queued 23:11
created

AbstractPlatform::quoteDefaultStringLiteral()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 3
rs 10
ccs 2
cts 2
cp 1
cc 1
eloc 1
nc 1
nop 1
crap 1
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 46
    public function getEventManager()
180
    {
181 46
        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 333
    public function getVarcharTypeDeclarationSQL(array $field)
261
    {
262 333
        if ( !isset($field['length'])) {
263 81
            $field['length'] = $this->getVarcharDefaultLength();
264
        }
265
266 333
        $fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
267
268 333
        if ($field['length'] > $this->getVarcharMaxLength()) {
269
            return $this->getClobTypeDeclarationSQL($field);
270
        }
271
272 333
        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 102
    public function getDoctrineTypeMapping($dbType)
421
    {
422 102
        if ($this->doctrineTypeMapping === null) {
423 21
            $this->initializeAllDoctrineTypeMappings();
424
        }
425
426 102
        $dbType = strtolower($dbType);
427
428 102
        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 84
        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 975
    public function isCommentedDoctrineType(Type $doctrineType)
479
    {
480 975
        if ($this->doctrineTypeComments === null) {
481 841
            $this->initializeCommentedDoctrineTypes();
482
        }
483
484 975
        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 508
    protected function getColumnComment(Column $column)
523
    {
524 508
        $comment = $column->getComment();
525
526 508
        if ($this->isCommentedDoctrineType($column->getType())) {
527 42
            $comment .= $this->getDoctrineTypeComment($column->getType());
528
        }
529
530 508
        return $comment;
531
    }
532
533
    /**
534
     * Gets the character used for identifier quoting.
535
     *
536
     * @return string
537
     */
538 311
    public function getIdentifierQuoteCharacter()
539
    {
540 311
        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 180
    public function getVarcharMaxLength()
569
    {
570 180
        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 110
    public function getDropTableSQL($table)
1395
    {
1396 110
        $tableArg = $table;
1397
1398 110
        if ($table instanceof Table) {
1399 27
            $table = $table->getQuotedName($this);
1400 95
        } elseif (!is_string($table)) {
1401
            throw new \InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
1402
        }
1403
1404 110
        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 110
        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 399
    public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES)
1510
    {
1511 399
        if ( ! is_int($createFlags)) {
1512
            throw new \InvalidArgumentException("Second argument of AbstractPlatform::getCreateTableSQL() has to be integer.");
1513
        }
1514
1515 399
        if (count($table->getColumns()) === 0) {
1516 18
            throw DBALException::noColumnsSpecifiedForTable($table->getName());
1517
        }
1518
1519 381
        $tableName = $table->getQuotedName($this);
1520 381
        $options = $table->getOptions();
1521 381
        $options['uniqueConstraints'] = [];
1522 381
        $options['indexes'] = [];
1523 381
        $options['primary'] = [];
1524
1525 381
        if (($createFlags&self::CREATE_INDEXES) > 0) {
1526 358
            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 381
        $columnSql = [];
1538 381
        $columns = [];
1539
1540 381
        foreach ($table->getColumns() as $column) {
1541
            /* @var \Doctrine\DBAL\Schema\Column $column */
1542
1543 381
            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 381
            $columnData = $column->toArray();
1555 381
            $columnData['name'] = $column->getQuotedName($this);
1556 381
            $columnData['version'] = $column->hasPlatformOption("version") ? $column->getPlatformOption('version') : false;
1557 381
            $columnData['comment'] = $this->getColumnComment($column);
1558
1559 381
            if ($columnData['type'] instanceof Types\StringType && $columnData['length'] === null) {
1560 144
                $columnData['length'] = 255;
1561
            }
1562
1563 381
            if (in_array($column->getName(), $options['primary'])) {
1564 164
                $columnData['primary'] = true;
1565
            }
1566
1567 381
            $columns[$columnData['name']] = $columnData;
1568
        }
1569
1570 381
        if (($createFlags&self::CREATE_FOREIGNKEYS) > 0) {
1571 175
            $options['foreignKeys'] = [];
1572 175
            foreach ($table->getForeignKeys() as $fkConstraint) {
1573 31
                $options['foreignKeys'][] = $fkConstraint;
1574
            }
1575
        }
1576
1577 381
        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 381
        $sql = $this->_getCreateTableSQL($tableName, $columns, $options);
1587 381
        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 381
        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 379
    public function quoteSingleIdentifier($str)
1879
    {
1880 379
        $c = $this->getIdentifierQuoteCharacter();
1881
1882 379
        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
            $sql[] = $this->getDropIndexSQL($index, $tableName);
2069
        }
2070
2071 326
        return $sql;
2072
    }
2073
2074
    /**
2075
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
2076
     *
2077
     * @return array
2078
     */
2079 326
    protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
2080
    {
2081 326
        $tableName = (false !== $diff->newName)
2082 34
            ? $diff->getNewName()->getQuotedName($this)
2083 326
            : $diff->getName($this)->getQuotedName($this);
2084
2085 326
        $sql = [];
2086
2087 326
        if ($this->supportsForeignKeyConstraints()) {
2088 326
            foreach ($diff->addedForeignKeys as $foreignKey) {
2089 20
                $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName);
2090
            }
2091
2092 326
            foreach ($diff->changedForeignKeys as $foreignKey) {
2093 20
                $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName);
2094
            }
2095
        }
2096
2097 326
        foreach ($diff->addedIndexes as $index) {
2098 3
            $sql[] = $this->getCreateIndexSQL($index, $tableName);
2099
        }
2100
2101 326
        foreach ($diff->changedIndexes as $index) {
2102 16
            $sql[] = $this->getCreateIndexSQL($index, $tableName);
2103
        }
2104
2105 326
        foreach ($diff->renamedIndexes as $oldIndexName => $index) {
2106 85
            $oldIndexName = new Identifier($oldIndexName);
2107 85
            $sql          = array_merge(
2108 85
                $sql,
2109 85
                $this->getRenameIndexSQL($oldIndexName->getQuotedName($this), $index, $tableName)
2110
            );
2111
        }
2112
2113 326
        return $sql;
2114
    }
2115
2116
    /**
2117
     * Returns the SQL for renaming an index on a table.
2118
     *
2119
     * @param string                      $oldIndexName The name of the index to rename from.
2120
     * @param \Doctrine\DBAL\Schema\Index $index        The definition of the index to rename to.
2121
     * @param string                      $tableName    The table to rename the given index on.
2122
     *
2123
     * @return array The sequence of SQL statements for renaming the given index.
2124
     */
2125 10
    protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName)
2126
    {
2127
        return [
2128 10
            $this->getDropIndexSQL($oldIndexName, $tableName),
2129 10
            $this->getCreateIndexSQL($index, $tableName)
2130
        ];
2131
    }
2132
2133
    /**
2134
     * Common code for alter table statement generation that updates the changed Index and Foreign Key definitions.
2135
     *
2136
     * @param \Doctrine\DBAL\Schema\TableDiff $diff
2137
     *
2138
     * @return array
2139
     */
2140
    protected function _getAlterTableIndexForeignKeySQL(TableDiff $diff)
2141
    {
2142
        return array_merge($this->getPreAlterTableIndexForeignKeySQL($diff), $this->getPostAlterTableIndexForeignKeySQL($diff));
2143
    }
2144
2145
    /**
2146
     * Gets declaration of a number of fields in bulk.
2147
     *
2148
     * @param array $fields A multidimensional associative array.
2149
     *                      The first dimension determines the field name, while the second
2150
     *                      dimension is keyed with the name of the properties
2151
     *                      of the field being declared as array indexes. Currently, the types
2152
     *                      of supported field properties are as follows:
2153
     *
2154
     *      length
2155
     *          Integer value that determines the maximum length of the text
2156
     *          field. If this argument is missing the field should be
2157
     *          declared to have the longest length allowed by the DBMS.
2158
     *
2159
     *      default
2160
     *          Text value to be used as default for this field.
2161
     *
2162
     *      notnull
2163
     *          Boolean flag that indicates whether this field is constrained
2164
     *          to not be set to null.
2165
     *      charset
2166
     *          Text value with the default CHARACTER SET for this field.
2167
     *      collation
2168
     *          Text value with the default COLLATION for this field.
2169
     *      unique
2170
     *          unique constraint
2171
     *
2172
     * @return string
2173
     */
2174 381
    public function getColumnDeclarationListSQL(array $fields)
2175
    {
2176 381
        $queryFields = [];
2177
2178 381
        foreach ($fields as $fieldName => $field) {
2179 381
            $queryFields[] = $this->getColumnDeclarationSQL($fieldName, $field);
2180
        }
2181
2182 381
        return implode(', ', $queryFields);
2183
    }
2184
2185
    /**
2186
     * Obtains DBMS specific SQL code portion needed to declare a generic type
2187
     * field to be used in statements like CREATE TABLE.
2188
     *
2189
     * @param string $name  The name the field to be declared.
2190
     * @param array  $field An associative array with the name of the properties
2191
     *                      of the field being declared as array indexes. Currently, the types
2192
     *                      of supported field properties are as follows:
2193
     *
2194
     *      length
2195
     *          Integer value that determines the maximum length of the text
2196
     *          field. If this argument is missing the field should be
2197
     *          declared to have the longest length allowed by the DBMS.
2198
     *
2199
     *      default
2200
     *          Text value to be used as default for this field.
2201
     *
2202
     *      notnull
2203
     *          Boolean flag that indicates whether this field is constrained
2204
     *          to not be set to null.
2205
     *      charset
2206
     *          Text value with the default CHARACTER SET for this field.
2207
     *      collation
2208
     *          Text value with the default COLLATION for this field.
2209
     *      unique
2210
     *          unique constraint
2211
     *      check
2212
     *          column check constraint
2213
     *      columnDefinition
2214
     *          a string that defines the complete column
2215
     *
2216
     * @return string DBMS specific SQL code portion that should be used to declare the column.
2217
     */
2218 432
    public function getColumnDeclarationSQL($name, array $field)
2219
    {
2220 432
        if (isset($field['columnDefinition'])) {
2221 15
            $columnDef = $this->getCustomTypeDeclarationSQL($field);
2222
        } else {
2223 418
            $default = $this->getDefaultValueDeclarationSQL($field);
2224
2225 418
            $charset = (isset($field['charset']) && $field['charset']) ?
2226 418
                ' ' . $this->getColumnCharsetDeclarationSQL($field['charset']) : '';
2227
2228 418
            $collation = (isset($field['collation']) && $field['collation']) ?
2229 418
                ' ' . $this->getColumnCollationDeclarationSQL($field['collation']) : '';
2230
2231 418
            $notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';
2232
2233 418
            $unique = (isset($field['unique']) && $field['unique']) ?
2234 418
                ' ' . $this->getUniqueFieldDeclarationSQL() : '';
2235
2236 418
            $check = (isset($field['check']) && $field['check']) ?
2237 418
                ' ' . $field['check'] : '';
2238
2239 418
            $typeDecl = $field['type']->getSQLDeclaration($field, $this);
2240 418
            $columnDef = $typeDecl . $charset . $default . $notnull . $unique . $check . $collation;
2241
2242 418
            if ($this->supportsInlineColumnComments() && isset($field['comment']) && $field['comment'] !== '') {
2243 53
                $columnDef .= ' ' . $this->getInlineColumnCommentSQL($field['comment']);
2244
            }
2245
        }
2246
2247 432
        return $name . ' ' . $columnDef;
2248
    }
2249
2250
    /**
2251
     * Returns the SQL snippet that declares a floating point column of arbitrary precision.
2252
     *
2253
     * @param array $columnDef
2254
     *
2255
     * @return string
2256
     */
2257 133
    public function getDecimalTypeDeclarationSQL(array $columnDef)
2258
    {
2259 133
        $columnDef['precision'] = ( ! isset($columnDef['precision']) || empty($columnDef['precision']))
2260 133
            ? 10 : $columnDef['precision'];
2261 133
        $columnDef['scale'] = ( ! isset($columnDef['scale']) || empty($columnDef['scale']))
2262 133
            ? 0 : $columnDef['scale'];
2263
2264 133
        return 'NUMERIC(' . $columnDef['precision'] . ', ' . $columnDef['scale'] . ')';
2265
    }
2266
2267
    /**
2268
     * Obtains DBMS specific SQL code portion needed to set a default value
2269
     * declaration to be used in statements like CREATE TABLE.
2270
     *
2271
     * @param array $field The field definition array.
2272
     *
2273
     * @return string DBMS specific SQL code portion needed to set a default value.
2274
     */
2275 472
    public function getDefaultValueDeclarationSQL($field)
2276
    {
2277 472
        if ( ! isset($field['default'])) {
2278 405
            return empty($field['notnull']) ? ' DEFAULT NULL' : '';
2279
        }
2280
2281 90
        $default = $field['default'];
2282
2283 90
        if ( ! isset($field['type'])) {
2284
            return " DEFAULT '" . $default . "'";
2285
        }
2286
2287 90
        $type = $field['type'];
2288
2289 90
        if ($type instanceof Types\PhpIntegerMappingType) {
2290 23
            return ' DEFAULT ' . $default;
2291
        }
2292
2293 69
        if ($type instanceof Types\PhpDateTimeMappingType && $default === $this->getCurrentTimestampSQL()) {
2294 15
            return ' DEFAULT ' . $this->getCurrentTimestampSQL();
2295
        }
2296
2297 54
        if ($type instanceof Types\TimeType && $default === $this->getCurrentTimeSQL()) {
2298
            return ' DEFAULT ' . $this->getCurrentTimeSQL();
2299
        }
2300
2301 54
        if ($type instanceof Types\DateType && $default === $this->getCurrentDateSQL()) {
2302 15
            return ' DEFAULT ' . $this->getCurrentDateSQL();
2303
        }
2304
2305 39
        if ($type instanceof Types\BooleanType) {
2306 15
            return " DEFAULT '" . $this->convertBooleans($default) . "'";
2307
        }
2308
2309 39
        return " DEFAULT " . $this->quoteDefaultStringLiteral($default);
2310
    }
2311
2312
    /**
2313
     * Obtains DBMS specific SQL code portion needed to set a CHECK constraint
2314
     * declaration to be used in statements like CREATE TABLE.
2315
     *
2316
     * @param array $definition The check definition.
2317
     *
2318
     * @return string DBMS specific SQL code portion needed to set a CHECK constraint.
2319
     */
2320 117
    public function getCheckDeclarationSQL(array $definition)
2321
    {
2322 117
        $constraints = [];
2323 117
        foreach ($definition as $field => $def) {
2324 117
            if (is_string($def)) {
2325
                $constraints[] = 'CHECK (' . $def . ')';
2326
            } else {
2327 117
                if (isset($def['min'])) {
2328 5
                    $constraints[] = 'CHECK (' . $field . ' >= ' . $def['min'] . ')';
2329
                }
2330
2331 117
                if (isset($def['max'])) {
2332 117
                    $constraints[] = 'CHECK (' . $field . ' <= ' . $def['max'] . ')';
2333
                }
2334
            }
2335
        }
2336
2337 117
        return implode(', ', $constraints);
2338
    }
2339
2340
    /**
2341
     * Obtains DBMS specific SQL code portion needed to set a unique
2342
     * constraint declaration to be used in statements like CREATE TABLE.
2343
     *
2344
     * @param string                      $name  The name of the unique constraint.
2345
     * @param \Doctrine\DBAL\Schema\Index $index The index definition.
2346
     *
2347
     * @return string DBMS specific SQL code portion needed to set a constraint.
2348
     *
2349
     * @throws \InvalidArgumentException
2350
     */
2351 28
    public function getUniqueConstraintDeclarationSQL($name, Index $index)
2352
    {
2353 28
        $columns = $index->getQuotedColumns($this);
2354 28
        $name = new Identifier($name);
2355
2356 28
        if (count($columns) === 0) {
2357
            throw new \InvalidArgumentException("Incomplete definition. 'columns' required.");
2358
        }
2359
2360 28
        return 'CONSTRAINT ' . $name->getQuotedName($this) . ' UNIQUE ('
2361 28
            . $this->getIndexFieldDeclarationListSQL($columns)
2362 28
            . ')' . $this->getPartialIndexSQL($index);
2363
    }
2364
2365
    /**
2366
     * Obtains DBMS specific SQL code portion needed to set an index
2367
     * declaration to be used in statements like CREATE TABLE.
2368
     *
2369
     * @param string                      $name  The name of the index.
2370
     * @param \Doctrine\DBAL\Schema\Index $index The index definition.
2371
     *
2372
     * @return string DBMS specific SQL code portion needed to set an index.
2373
     *
2374
     * @throws \InvalidArgumentException
2375
     */
2376 46
    public function getIndexDeclarationSQL($name, Index $index)
2377
    {
2378 46
        $columns = $index->getQuotedColumns($this);
2379 46
        $name = new Identifier($name);
2380
2381 46
        if (count($columns) === 0) {
2382
            throw new \InvalidArgumentException("Incomplete definition. 'columns' required.");
2383
        }
2384
2385 46
        return $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name->getQuotedName($this) . ' ('
2386 46
            . $this->getIndexFieldDeclarationListSQL($columns)
2387 46
            . ')' . $this->getPartialIndexSQL($index);
2388
    }
2389
2390
    /**
2391
     * Obtains SQL code portion needed to create a custom column,
2392
     * e.g. when a field has the "columnDefinition" keyword.
2393
     * Only "AUTOINCREMENT" and "PRIMARY KEY" are added if appropriate.
2394
     *
2395
     * @param array $columnDef
2396
     *
2397
     * @return string
2398
     */
2399 19
    public function getCustomTypeDeclarationSQL(array $columnDef)
2400
    {
2401 19
        return $columnDef['columnDefinition'];
2402
    }
2403
2404
    /**
2405
     * Obtains DBMS specific SQL code portion needed to set an index
2406
     * declaration to be used in statements like CREATE TABLE.
2407
     *
2408
     * @param array $fields
2409
     *
2410
     * @return string
2411
     */
2412 253
    public function getIndexFieldDeclarationListSQL(array $fields)
2413
    {
2414 253
        $ret = [];
2415
2416 253
        foreach ($fields as $field => $definition) {
2417 253
            if (is_array($definition)) {
2418
                $ret[] = $field;
2419
            } else {
2420 253
                $ret[] = $definition;
2421
            }
2422
        }
2423
2424 253
        return implode(', ', $ret);
2425
    }
2426
2427
    /**
2428
     * Returns the required SQL string that fits between CREATE ... TABLE
2429
     * to create the table as a temporary table.
2430
     *
2431
     * Should be overridden in driver classes to return the correct string for the
2432
     * specific database type.
2433
     *
2434
     * The default is to return the string "TEMPORARY" - this will result in a
2435
     * SQL error for any database that does not support temporary tables, or that
2436
     * requires a different SQL command from "CREATE TEMPORARY TABLE".
2437
     *
2438
     * @return string The string required to be placed between "CREATE" and "TABLE"
2439
     *                to generate a temporary table, if possible.
2440
     */
2441
    public function getTemporaryTableSQL()
2442
    {
2443
        return 'TEMPORARY';
2444
    }
2445
2446
    /**
2447
     * Some vendors require temporary table names to be qualified specially.
2448
     *
2449
     * @param string $tableName
2450
     *
2451
     * @return string
2452
     */
2453
    public function getTemporaryTableName($tableName)
2454
    {
2455
        return $tableName;
2456
    }
2457
2458
    /**
2459
     * Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
2460
     * of a field declaration to be used in statements like CREATE TABLE.
2461
     *
2462
     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey
2463
     *
2464
     * @return string DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
2465
     *                of a field declaration.
2466
     */
2467 113
    public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey)
2468
    {
2469 113
        $sql  = $this->getForeignKeyBaseDeclarationSQL($foreignKey);
2470 101
        $sql .= $this->getAdvancedForeignKeyOptionsSQL($foreignKey);
2471
2472 101
        return $sql;
2473
    }
2474
2475
    /**
2476
     * Returns the FOREIGN KEY query section dealing with non-standard options
2477
     * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
2478
     *
2479
     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey The foreign key definition.
2480
     *
2481
     * @return string
2482
     */
2483 97
    public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey)
2484
    {
2485 97
        $query = '';
2486 97
        if ($this->supportsForeignKeyOnUpdate() && $foreignKey->hasOption('onUpdate')) {
2487 4
            $query .= ' ON UPDATE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onUpdate'));
2488
        }
2489 97
        if ($foreignKey->hasOption('onDelete')) {
2490 9
            $query .= ' ON DELETE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onDelete'));
2491
        }
2492
2493 97
        return $query;
2494
    }
2495
2496
    /**
2497
     * Returns the given referential action in uppercase if valid, otherwise throws an exception.
2498
     *
2499
     * @param string $action The foreign key referential action.
2500
     *
2501
     * @return string
2502
     *
2503
     * @throws \InvalidArgumentException if unknown referential action given
2504
     */
2505 121
    public function getForeignKeyReferentialActionSQL($action)
2506
    {
2507 121
        $upper = strtoupper($action);
2508
        switch ($upper) {
2509 121
            case 'CASCADE':
2510 82
            case 'SET NULL':
2511 61
            case 'NO ACTION':
2512 48
            case 'RESTRICT':
2513 34
            case 'SET DEFAULT':
2514 104
                return $upper;
2515
            default:
2516 17
                throw new \InvalidArgumentException('Invalid foreign key action: ' . $upper);
2517
        }
2518
    }
2519
2520
    /**
2521
     * Obtains DBMS specific SQL code portion needed to set the FOREIGN KEY constraint
2522
     * of a field declaration to be used in statements like CREATE TABLE.
2523
     *
2524
     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey
2525
     *
2526
     * @return string
2527
     *
2528
     * @throws \InvalidArgumentException
2529
     */
2530 73
    public function getForeignKeyBaseDeclarationSQL(ForeignKeyConstraint $foreignKey)
2531
    {
2532 73
        $sql = '';
2533 73
        if (strlen($foreignKey->getName())) {
2534 59
            $sql .= 'CONSTRAINT ' . $foreignKey->getQuotedName($this) . ' ';
2535
        }
2536 73
        $sql .= 'FOREIGN KEY (';
2537
2538 73
        if (count($foreignKey->getLocalColumns()) === 0) {
2539
            throw new \InvalidArgumentException("Incomplete definition. 'local' required.");
2540
        }
2541 73
        if (count($foreignKey->getForeignColumns()) === 0) {
2542
            throw new \InvalidArgumentException("Incomplete definition. 'foreign' required.");
2543
        }
2544 73
        if (strlen($foreignKey->getForeignTableName()) === 0) {
2545
            throw new \InvalidArgumentException("Incomplete definition. 'foreignTable' required.");
2546
        }
2547
2548 73
        $sql .= implode(', ', $foreignKey->getQuotedLocalColumns($this))
2549 73
            . ') REFERENCES '
2550 73
            . $foreignKey->getQuotedForeignTableName($this) . ' ('
2551 73
            . implode(', ', $foreignKey->getQuotedForeignColumns($this)) . ')';
2552
2553 73
        return $sql;
2554
    }
2555
2556
    /**
2557
     * Obtains DBMS specific SQL code portion needed to set the UNIQUE constraint
2558
     * of a field declaration to be used in statements like CREATE TABLE.
2559
     *
2560
     * @return string DBMS specific SQL code portion needed to set the UNIQUE constraint
2561
     *                of a field declaration.
2562
     */
2563
    public function getUniqueFieldDeclarationSQL()
2564
    {
2565
        return 'UNIQUE';
2566
    }
2567
2568
    /**
2569
     * Obtains DBMS specific SQL code portion needed to set the CHARACTER SET
2570
     * of a field declaration to be used in statements like CREATE TABLE.
2571
     *
2572
     * @param string $charset The name of the charset.
2573
     *
2574
     * @return string DBMS specific SQL code portion needed to set the CHARACTER SET
2575
     *                of a field declaration.
2576
     */
2577
    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

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

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

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

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