Completed
Push — master ( e33650...15989c )
by José
02:42
created

PdoAdapter::executeActions()   F

Complexity

Conditions 20
Paths 16

Size

Total Lines 105

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 420

Importance

Changes 0
Metric Value
dl 0
loc 105
rs 3.3333
c 0
b 0
f 0
ccs 0
cts 0
cp 0
cc 20
nc 16
nop 2
crap 420

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Phinx
4
 *
5
 * (The MIT license)
6
 * Copyright (c) 2015 Rob Morgan
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated * documentation files (the "Software"), to
10
 * deal in the Software without restriction, including without limitation the
11
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12
 * sell copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24
 * IN THE SOFTWARE.
25
 *
26
 * @package    Phinx
27
 * @subpackage Phinx\Db\Adapter
28
 */
29
namespace Phinx\Db\Adapter;
30
31
use BadMethodCallException;
32
use Phinx\Db\Action\AddColumn;
33
use Phinx\Db\Action\AddForeignKey;
34
use Phinx\Db\Action\AddIndex;
35
use Phinx\Db\Action\ChangeColumn;
36
use Phinx\Db\Action\ChangeComment;
37
use Phinx\Db\Action\ChangePrimaryKey;
38
use Phinx\Db\Action\DropForeignKey;
39
use Phinx\Db\Action\DropIndex;
40
use Phinx\Db\Action\DropTable;
41
use Phinx\Db\Action\RemoveColumn;
42
use Phinx\Db\Action\RenameColumn;
43
use Phinx\Db\Action\RenameTable;
44
use Phinx\Db\Table\Column;
45
use Phinx\Db\Table\ForeignKey;
46
use Phinx\Db\Table\Index;
47
use Phinx\Db\Table\Table;
48
use Phinx\Db\Util\AlterInstructions;
49
use Phinx\Migration\MigrationInterface;
50
use Symfony\Component\Console\Output\OutputInterface;
51 287
52
/**
53 287
 * Phinx PDO Adapter.
54
 *
55 287
 * @author Rob Morgan <[email protected]>
56 3
 */
57 3
abstract class PdoAdapter extends AbstractAdapter implements DirectActionInterface
58
{
59 287
    /**
60
     * @var \PDO|null
61
     */
62
    protected $connection;
63
64
    /**
65
     * Writes a message to stdout if verbose output is on
66
     *
67
     * @param string $message The message to show
68 193
     * @return void
69
     */
70 193
    protected function verboseLog($message)
71
    {
72
        if (!$this->isDryRunEnabled() &&
73 193
             $this->getOutput()->getVerbosity() < OutputInterface::VERBOSITY_VERY_VERBOSE) {
74 191
            return;
75 191
        }
76 74
77 74
        $this->getOutput()->writeln($message);
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83
    public function setOptions(array $options)
84
    {
85
        parent::setOptions($options);
86 74
87
        if (isset($options['connection'])) {
88
            $this->setConnection($options['connection']);
89
        }
90
91
        return $this;
92
    }
93 193
94
    /**
95
     * Sets the database connection.
96
     *
97
     * @param \PDO $connection Connection
98
     * @return \Phinx\Db\Adapter\AdapterInterface
99
     */
100
    public function setConnection(\PDO $connection)
101 191
    {
102
        $this->connection = $connection;
103 191
104 189
        // Create the schema table if it doesn't already exist
105 189
        if (!$this->hasSchemaTable()) {
106 191
            $this->createSchemaTable();
107
        } else {
108
            $table = new \Phinx\Db\Table($this->getSchemaTableName(), [], $this);
109
            if (!$table->hasColumn('migration_name')) {
110
                $table
111
                    ->addColumn(
112 1
                        'migration_name',
113
                        'string',
114 1
                        ['limit' => 100, 'after' => 'version', 'default' => null, 'null' => true]
115
                    )
116
                    ->save();
117
            }
118
            if (!$table->hasColumn('breakpoint')) {
119
                $table
120
                    ->addColumn('breakpoint', 'boolean', ['default' => false])
121
                    ->save();
122
            }
123
        }
124
125
        return $this;
126 218
    }
127
128 218
    /**
129 3
     * Gets the database connection
130 3
     *
131
     * @return \PDO
132
     */
133 217
    public function getConnection()
134
    {
135
        if ($this->connection === null) {
136
            $this->connect();
137
        }
138
139
        return $this->connection;
140
    }
141
142 220
    /**
143
     * {@inheritdoc}
144 220
     */
145
    public function connect()
146
    {
147
    }
148
149
    /**
150 151
     * {@inheritdoc}
151
     */
152 151
    public function disconnect()
153 151
    {
154
    }
155
156
    /**
157
     * {@inheritdoc}
158
     */
159 213
    public function execute($sql)
160
    {
161 213
        $this->verboseLog($sql);
162 213
163 213
        if ($this->isDryRunEnabled()) {
164 208
            return 0;
165 208
        }
166 213
167
        return $this->getConnection()->exec($sql);
168
    }
169
170
    /**
171
     * Returns the Cake\Database connection object using the same underlying
172 1
     * PDO object as this connection.
173
     *
174 1
     * @return \Cake\Database\Connection
175 1
     */
176 1
    abstract public function getDecoratedConnection();
177 1
178
    /**
179 1
     * {@inheritdoc}
180 1
     */
181 1
    public function getQueryBuilder()
182
    {
183 1
        return $this->getDecoratedConnection()->newQuery();
184 1
    }
185 1
186
    /**
187
     * Executes a query and returns PDOStatement.
188
     *
189
     * @param string $sql SQL
190 11
     * @return \PDOStatement
191
     */
192 11
    public function query($sql)
193 11
    {
194 11
        return $this->getConnection()->query($sql);
195 11
    }
196
197 11
    /**
198 11
     * {@inheritdoc}
199 11
     */
200
    public function fetchRow($sql)
201 11
    {
202 11
        $result = $this->query($sql);
203 11
204 11
        return $result->fetch();
205 11
    }
206 11
207
    /**
208 11
     * {@inheritdoc}
209 11
     */
210
    public function fetchAll($sql)
211 11
    {
212 11
        $rows = [];
213 11
        $result = $this->query($sql);
214
        while ($row = $result->fetch()) {
215 11
            $rows[] = $row;
216 11
        }
217 11
218
        return $rows;
219
    }
220
221
    /**
222 5
     * {@inheritdoc}
223
     */
224 5
    public function insert(Table $table, $row)
225
    {
226 5
        $sql = sprintf(
227
            'INSERT INTO %s ',
228
            $this->quoteTableName($table->getName())
229
        );
230
        $columns = array_keys($row);
231
        $sql .= '(' . implode(', ', array_map([$this, 'quoteColumnName'], $columns)) . ')';
232 8
233
        foreach ($row as $column => $value) {
234 8
            if (is_bool($value)) {
235
                $row[$column] = $this->castToBool($value);
236 8
            }
237 8
        }
238 6
239 6
        if ($this->isDryRunEnabled()) {
240 2
            $sql .= ' VALUES (' . implode(', ', array_map([$this, 'quoteValue'], $row)) . ');';
241 1
            $this->output->writeln($sql);
242 1
        } else {
243 1
            $sql .= ' VALUES (' . implode(', ', array_fill(0, count($columns), '?')) . ')';
244 1
            $stmt = $this->getConnection()->prepare($sql);
245 8
            $stmt->execute(array_values($row));
246
        }
247 7
    }
248 7
249 7
    /**
250 7
     * Quotes a database value.
251
     *
252 7
     * @param mixed $value  The value to quote
253
     * @return mixed
254
     */
255
    private function quoteValue($value)
256
    {
257
        if (is_numeric($value)) {
258 5
            return $value;
259
        }
260 5
261
        if ($value === null) {
262 5
            return 'null';
263 5
        }
264 5
265 5
        return $this->getConnection()->quote($value);
266 5
    }
267 5
268 5
    /**
269 5
     * {@inheritdoc}
270 5
     */
271 5
    public function bulkinsert(Table $table, $rows)
272 5
    {
273 5
        $sql = sprintf(
274 5
            'INSERT INTO %s ',
275 5
            $this->quoteTableName($table->getName())
276
        );
277 5
        $current = current($rows);
278 5
        $keys = array_keys($current);
279
        $sql .= '(' . implode(', ', array_map([$this, 'quoteColumnName'], $keys)) . ') VALUES ';
280 3
281 3
        if ($this->isDryRunEnabled()) {
282 3
            $values = array_map(function ($row) {
283 3
                return '(' . implode(', ', array_map([$this, 'quoteValue'], $row)) . ')';
284 3
            }, $rows);
285 3
            $sql .= implode(', ', $values) . ';';
286
            $this->output->writeln($sql);
287 3
        } else {
288
            $count_keys = count($keys);
289
            $query = '(' . implode(', ', array_fill(0, $count_keys, '?')) . ')';
290 5
            $count_vars = count($rows);
291
            $queries = array_fill(0, $count_vars, $query);
292
            $sql .= implode(',', $queries);
293
            $stmt = $this->getConnection()->prepare($sql);
294
            $vals = [];
295
296 1
            foreach ($rows as $row) {
297
                foreach ($row as $v) {
298 1
                    if (is_bool($v)) {
299 1
                        $vals[] = $this->castToBool($v);
300 1
                    } else {
301 1
                        $vals[] = $v;
302 1
                    }
303 1
                }
304 1
            }
305 1
306 1
            $stmt->execute($vals);
307 1
        }
308 1
    }
309 1
310
    /**
311 1
     * {@inheritdoc}
312
     */
313
    public function getVersions()
314
    {
315
        $rows = $this->getVersionLog();
316
317 1
        return array_keys($rows);
318
    }
319 1
320 1
    /**
321 1
     * {@inheritdoc}
322 1
     */
323 1
    public function getVersionLog()
324 1
    {
325 1
        $result = [];
326 1
327 1
        switch ($this->options['version_order']) {
328
            case \Phinx\Config\Config::VERSION_ORDER_CREATION_TIME:
329
                $orderBy = 'version ASC';
330
                break;
331
            case \Phinx\Config\Config::VERSION_ORDER_EXECUTION_TIME:
332
                $orderBy = 'start_time ASC, version ASC';
333
                break;
334
            default:
335
                throw new \RuntimeException('Invalid version_order configuration option');
336
        }
337
338
        $rows = $this->fetchAll(sprintf('SELECT * FROM %s ORDER BY %s', $this->getSchemaTableName(), $orderBy));
339
        foreach ($rows as $version) {
340
            $result[$version['version']] = $version;
341
        }
342
343
        return $result;
344
    }
345
346
    /**
347
     * {@inheritdoc}
348
     */
349 208
    public function migrated(MigrationInterface $migration, $direction, $startTime, $endTime)
350
    {
351
        if (strcasecmp($direction, MigrationInterface::UP) === 0) {
352 208
            // up
353 208
            $sql = sprintf(
354 208
                "INSERT INTO %s (%s, %s, %s, %s, %s) VALUES ('%s', '%s', '%s', '%s', %s);",
355 208
                $this->quoteTableName($this->getSchemaTableName()),
356 208
                $this->quoteColumnName('version'),
357 208
                $this->quoteColumnName('migration_name'),
358 208
                $this->quoteColumnName('start_time'),
359 208
                $this->quoteColumnName('end_time'),
360 208
                $this->quoteColumnName('breakpoint'),
361 208
                $migration->getVersion(),
362 208
                substr($migration->getName(), 0, 100),
363 208
                $startTime,
364 208
                $endTime,
365 208
                $this->castToBool(false)
366 208
            );
367 208
368
            $this->execute($sql);
369 208
        } else {
370 208
            // down
371 208
            $sql = sprintf(
372 208
                "DELETE FROM %s WHERE %s = '%s'",
373 208
                $this->quoteTableName($this->getSchemaTableName()),
374
                $this->quoteColumnName('version'),
375
                $migration->getVersion()
376
            );
377
378
            $this->execute($sql);
379 121
        }
380
381 121
        return $this;
382
    }
383
384
    /**
385
     * {@inheritdoc}
386
     */
387
    public function toggleBreakpoint(MigrationInterface $migration)
388
    {
389
        $this->query(
390
            sprintf(
391
                'UPDATE %1$s SET %2$s = CASE %2$s WHEN %3$s THEN %4$s ELSE %3$s END, %7$s = %7$s WHERE %5$s = \'%6$s\';',
392
                $this->getSchemaTableName(),
393
                $this->quoteColumnName('breakpoint'),
394
                $this->castToBool(true),
395
                $this->castToBool(false),
396
                $this->quoteColumnName('version'),
397
                $migration->getVersion(),
398
                $this->quoteColumnName('start_time')
399
            )
400
        );
401
402
        return $this;
403
    }
404
405
    /**
406
     * {@inheritdoc}
407
     */
408
    public function resetAllBreakpoints()
409
    {
410
        return $this->execute(
411
            sprintf(
412
                'UPDATE %1$s SET %2$s = %3$s, %4$s = %4$s WHERE %2$s <> %3$s;',
413
                $this->getSchemaTableName(),
414
                $this->quoteColumnName('breakpoint'),
415
                $this->castToBool(false),
416
                $this->quoteColumnName('start_time')
417
            )
418
        );
419
    }
420
421
    /**
422
     * {@inheritdoc}
423
     */
424
    public function createSchema($schemaName = 'public')
425
    {
426
        throw new BadMethodCallException('Creating a schema is not supported');
427
    }
428
429
    /**
430
     * {@inheritdoc}
431
     */
432
    public function dropSchema($name)
433
    {
434
        throw new BadMethodCallException('Dropping a schema is not supported');
435
    }
436
437
    /**
438
     * {@inheritdoc}
439
     */
440
    public function getColumnTypes()
441
    {
442
        return [
443
            'string',
444
            'char',
445
            'text',
446
            'integer',
447
            'biginteger',
448
            'bit',
449
            'float',
450
            'decimal',
451
            'datetime',
452
            'timestamp',
453
            'time',
454
            'date',
455
            'blob',
456
            'binary',
457
            'varbinary',
458
            'boolean',
459
            'uuid',
460
            // Geospatial data types
461
            'geometry',
462
            'point',
463
            'linestring',
464
            'polygon',
465
        ];
466
    }
467
468
    /**
469
     * {@inheritdoc}
470
     */
471
    public function castToBool($value)
472
    {
473
        return (bool)$value ? 1 : 0;
474
    }
475
476
    /**
477
     * Retrieve a database connection attribute
478
     * @see http://php.net/manual/en/pdo.getattribute.php
479
     *
480
     * @param int $attribute One of the PDO::ATTR_* constants
481
     * @return mixed
482
     */
483
    public function getAttribute($attribute)
484
    {
485
        return $this->connection->getAttribute($attribute);
486
    }
487
488
    /**
489
     * Get the definition for a `DEFAULT` statement.
490
     *
491
     * @param  mixed $default Default value
492
     * @param string $columnType column type added
493
     * @return string
494
     */
495 View Code Duplication
    protected function getDefaultValueDefinition($default, $columnType = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
496
    {
497
        if (is_string($default) && 'CURRENT_TIMESTAMP' !== $default) {
498
            $default = $this->getConnection()->quote($default);
499
        } elseif (is_bool($default)) {
500
            $default = $this->castToBool($default);
501
        } elseif ($default !== null && $columnType === static::PHINX_TYPE_BOOLEAN) {
502
            $default = $this->castToBool((bool)$default);
503
        }
504
505
        return isset($default) ? " DEFAULT $default" : '';
506
    }
507
508
    /**
509
     * Executes all the ALTER TABLE instructions passed for the given table
510
     *
511
     * @param string $tableName The table name to use in the ALTER statement
512
     * @param AlterInstructions $instructions The object containing the alter sequence
513
     * @return void
514
     */
515
    protected function executeAlterSteps($tableName, AlterInstructions $instructions)
516
    {
517
        $alter = sprintf('ALTER TABLE %s %%s', $this->quoteTableName($tableName));
518
        $instructions->execute($alter, [$this, 'execute']);
519
    }
520
521
    /**
522
     * {@inheritdoc}
523
     */
524
    public function addColumn(Table $table, Column $column)
525
    {
526
        $instructions = $this->getAddColumnInstructions($table, $column);
527
        $this->executeAlterSteps($table->getName(), $instructions);
528
    }
529
530
    /**
531
     * Returns the instructions to add the specified column to a database table.
532
     *
533
     * @param \Phinx\Db\Table\Table $table Table
534
     * @param \Phinx\Db\Table\Column $column Column
535
     * @return AlterInstructions
536
     */
537
    abstract protected function getAddColumnInstructions(Table $table, Column $column);
538
539
    /**
540
     * {@inheritdoc}
541
     */
542
    public function renameColumn($tableName, $columnName, $newColumnName)
543
    {
544
        $instructions = $this->getRenameColumnInstructions($tableName, $columnName, $newColumnName);
545
        $this->executeAlterSteps($tableName, $instructions);
546
    }
547
548
    /**
549
     * Returns the instructions to rename the specified column.
550
     *
551
     * @param string $tableName Table Name
552
     * @param string $columnName Column Name
553
     * @param string $newColumnName New Column Name
554
     * @return AlterInstructions:w
0 ignored issues
show
Documentation introduced by
The doc-type AlterInstructions:w could not be parsed: Unknown type name "AlterInstructions:w" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
555
     *
556
     */
557
    abstract protected function getRenameColumnInstructions($tableName, $columnName, $newColumnName);
558
559
    /**
560
     * {@inheritdoc}
561
     */
562
    public function changeColumn($tableName, $columnName, Column $newColumn)
563
    {
564
        $instructions = $this->getChangeColumnInstructions($tableName, $columnName, $newColumn);
565
        $this->executeAlterSteps($tableName, $instructions);
566
    }
567
568
    /**
569
     * Returns the instructions to change a table column type.
570
     *
571
     * @param string $tableName  Table Name
572
     * @param string $columnName Column Name
573
     * @param \Phinx\Db\Table\Column $newColumn  New Column
574
     * @return AlterInstructions
575
     */
576
    abstract protected function getChangeColumnInstructions($tableName, $columnName, Column $newColumn);
577
578
    /**
579
     * {@inheritdoc}
580
     */
581
    public function dropColumn($tableName, $columnName)
582
    {
583
        $instructions = $this->getDropColumnInstructions($tableName, $columnName);
584
        $this->executeAlterSteps($tableName, $instructions);
585
    }
586
587
    /**
588
     * Returns the instructions to drop the specified column.
589
     *
590
     * @param string $tableName Table Name
591
     * @param string $columnName Column Name
592
     * @return AlterInstructions
593
     */
594
    abstract protected function getDropColumnInstructions($tableName, $columnName);
595
596
    /**
597
     * {@inheritdoc}
598
     */
599
    public function addIndex(Table $table, Index $index)
600
    {
601
        $instructions = $this->getAddIndexInstructions($table, $index);
602
        $this->executeAlterSteps($table->getName(), $instructions);
603
    }
604
605
    /**
606
     * Returns the instructions to add the specified index to a database table.
607
     *
608
     * @param \Phinx\Db\Table\Table $table Table
609
     * @param \Phinx\Db\Table\Index $index Index
610
     * @return AlterInstructions
611
     */
612
    abstract protected function getAddIndexInstructions(Table $table, Index $index);
613
614
    /**
615
     * {@inheritdoc}
616
     */
617
    public function dropIndex($tableName, $columns)
618
    {
619
        $instructions = $this->getDropIndexByColumnsInstructions($tableName, $columns);
620
        $this->executeAlterSteps($tableName, $instructions);
621
    }
622
623
    /**
624
     * Returns the instructions to drop the specified index from a database table.
625
     *
626
     * @param string $tableName The name of of the table where the index is
627
     * @param mixed $columns Column(s)
628
     * @return AlterInstructions
629
     */
630
    abstract protected function getDropIndexByColumnsInstructions($tableName, $columns);
631
632
    /**
633
     * {@inheritdoc}
634
     */
635
    public function dropIndexByName($tableName, $indexName)
636
    {
637
        $instructions = $this->getDropIndexByNameInstructions($tableName, $indexName);
638
        $this->executeAlterSteps($tableName, $instructions);
639
    }
640
641
    /**
642
     * Returns the instructions to drop the index specified by name from a database table.
643
     *
644
     * @param string $tableName The table name whe the index is
645
     * @param string $indexName The name of the index
646
     * @return AlterInstructions
647
     */
648
    abstract protected function getDropIndexByNameInstructions($tableName, $indexName);
649
650
    /**
651
     * {@inheritdoc}
652
     */
653
    public function addForeignKey(Table $table, ForeignKey $foreignKey)
654
    {
655
        $instructions = $this->getAddForeignKeyInstructions($table, $foreignKey);
656
        $this->executeAlterSteps($table->getName(), $instructions);
657
    }
658
659
    /**
660
     * Returns the instructions to adds the specified foreign key to a database table.
661
     *
662
     * @param \Phinx\Db\Table\Table $table The table to add the constraint to
663
     * @param \Phinx\Db\Table\ForeignKey $foreignKey The foreign key to add
664
     * @return AlterInstructions
665
     */
666
    abstract protected function getAddForeignKeyInstructions(Table $table, ForeignKey $foreignKey);
667
668
    /**
669
     * {@inheritdoc}
670
     */
671
    public function dropForeignKey($tableName, $columns, $constraint = null)
672
    {
673
        if ($constraint) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $constraint of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
674
            $instructions = $this->getDropForeignKeyInstructions($tableName, $constraint);
675
        } else {
676
            $instructions = $this->getDropForeignKeyByColumnsInstructions($tableName, $columns);
677
        }
678
679
        $this->executeAlterSteps($tableName, $instructions);
680
    }
681
682
    /**
683
     * Returns the instructions to drop the specified foreign key from a database table.
684
     *
685
     * @param string   $tableName The table where the foreign key constraint is
686
     * @param string   $constraint Constraint name
687
     * @return AlterInstructions
688
     */
689
    abstract protected function getDropForeignKeyInstructions($tableName, $constraint);
690
691
    /**
692
     * Returns the instructions to drop the specified foreign key from a database table.
693
     *
694
     * @param string $tableName The table where the foreign key constraint is
695
     * @param array $columns The list of column names
696
     * @return AlterInstructions
697
     */
698
    abstract protected function getDropForeignKeyByColumnsInstructions($tableName, $columns);
699
700
    /**
701
     * {@inheritdoc}
702
     */
703
    public function dropTable($tableName)
704
    {
705
        $instructions = $this->getDropTableInstructions($tableName);
706
        $this->executeAlterSteps($tableName, $instructions);
707
    }
708
709
    /**
710
     * Returns the instructions to drop the specified database table.
711
     *
712
     * @param string $tableName Table Name
713
     * @return AlterInstructions
714
     */
715
    abstract protected function getDropTableInstructions($tableName);
716
717
    /**
718
     * {@inheritdoc}
719
     */
720
    public function renameTable($tableName, $newTableName)
721
    {
722
        $instructions = $this->getRenameTableInstructions($tableName, $newTableName);
723
        $this->executeAlterSteps($tableName, $instructions);
724
    }
725
726
    /**
727
     * Returns the instructions to rename the specified database table.
728
     *
729
     * @param string $tableName Table Name
730
     * @param string $newTableName New Name
731
     * @return AlterInstructions
732
     */
733
    abstract protected function getRenameTableInstructions($tableName, $newTableName);
734
735
    /**
736
     * {@inheritdoc}
737
     */
738
    public function changePrimaryKey(Table $table, $newColumns)
739
    {
740
        $instructions = $this->getChangePrimaryKeyInstructions($table, $newColumns);
741
        $this->executeAlterSteps($table->getName(), $instructions);
742
    }
743
744
    /**
745
     * Returns the instructions to change the primary key for the specified database table.
746
     *
747
     * @param Table $table Table
748
     * @param string|array|null $newColumns Column name(s) to belong to the primary key, or null to drop the key
749
     * @return AlterInstructions
750
     */
751
    abstract protected function getChangePrimaryKeyInstructions(Table $table, $newColumns);
752
753
    /**
754
     * {@inheritdoc}
755
     */
756
    public function changeComment(Table $table, $newComment)
757
    {
758
        $instructions = $this->getChangeCommentInstructions($table, $newComment);
759
        $this->executeAlterSteps($table->getName(), $instructions);
760
    }
761
762
    /**
763
     * Returns the instruction to change the comment for the specified database table.
764
     *
765
     * @param Table $table Table
766
     * @param string|null $newComment New comment string, or null to drop the comment
767
     * @return AlterInstructions
768
     */
769
    abstract protected function getChangeCommentInstructions(Table $table, $newComment);
770
771
    /**
772
     * {@inheritdoc}
773
     */
774
    public function executeActions(Table $table, array $actions)
775
    {
776
        $instructions = new AlterInstructions();
777
778
        foreach ($actions as $action) {
779
            switch (true) {
780
                case ($action instanceof AddColumn):
781
                    $instructions->merge($this->getAddColumnInstructions($table, $action->getColumn()));
782
                    break;
783
784
                case ($action instanceof AddIndex):
785
                    $instructions->merge($this->getAddIndexInstructions($table, $action->getIndex()));
786
                    break;
787
788
                case ($action instanceof AddForeignKey):
789
                    $instructions->merge($this->getAddForeignKeyInstructions($table, $action->getForeignKey()));
790
                    break;
791
792
                case ($action instanceof ChangeColumn):
793
                    $instructions->merge($this->getChangeColumnInstructions(
794
                        $table->getName(),
795
                        $action->getColumnName(),
796
                        $action->getColumn()
797
                    ));
798
                    break;
799
800
                case ($action instanceof DropForeignKey && !$action->getForeignKey()->getConstraint()):
801
                    $instructions->merge($this->getDropForeignKeyByColumnsInstructions(
802
                        $table->getName(),
803
                        $action->getForeignKey()->getColumns()
804
                    ));
805
                    break;
806
807
                case ($action instanceof DropForeignKey && $action->getForeignKey()->getConstraint()):
808
                    $instructions->merge($this->getDropForeignKeyInstructions(
809
                        $table->getName(),
810
                        $action->getForeignKey()->getConstraint()
0 ignored issues
show
Bug introduced by
It seems like $action->getForeignKey()->getConstraint() targeting Phinx\Db\Table\ForeignKey::getConstraint() can also be of type boolean; however, Phinx\Db\Adapter\PdoAdap...oreignKeyInstructions() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
811
                    ));
812
                    break;
813
814
                case ($action instanceof DropIndex && $action->getIndex()->getName() !== null):
815
                    $instructions->merge($this->getDropIndexByNameInstructions(
816
                        $table->getName(),
817
                        $action->getIndex()->getName()
818
                    ));
819
                    break;
820
821
                case ($action instanceof DropIndex && $action->getIndex()->getName() == null):
822
                    $instructions->merge($this->getDropIndexByColumnsInstructions(
823
                        $table->getName(),
824
                        $action->getIndex()->getColumns()
825
                    ));
826
                    break;
827
828
                case ($action instanceof DropTable):
829
                    $instructions->merge($this->getDropTableInstructions(
830
                        $table->getName()
831
                    ));
832
                    break;
833
834
                case ($action instanceof RemoveColumn):
835
                    $instructions->merge($this->getDropColumnInstructions(
836
                        $table->getName(),
837
                        $action->getColumn()->getName()
838
                    ));
839
                    break;
840
841
                case ($action instanceof RenameColumn):
842
                    $instructions->merge($this->getRenameColumnInstructions(
843
                        $table->getName(),
844
                        $action->getColumn()->getName(),
845
                        $action->getNewName()
846
                    ));
847
                    break;
848
849
                case ($action instanceof RenameTable):
850
                    $instructions->merge($this->getRenameTableInstructions(
851
                        $table->getName(),
852
                        $action->getNewName()
853
                    ));
854
                    break;
855
856
                case ($action instanceof ChangePrimaryKey):
857
                    $instructions->merge($this->getChangePrimaryKeyInstructions(
858
                        $table,
859
                        $action->getNewColumns()
860
                    ));
861
                    break;
862
863
                case ($action instanceof ChangeComment):
864
                    $instructions->merge($this->getChangeCommentInstructions(
865
                        $table,
866
                        $action->getNewComment()
867
                    ));
868
                    break;
869
870
                default:
871
                    throw new \InvalidArgumentException(
872
                        sprintf("Don't know how to execute action: '%s'", get_class($action))
873
                    );
874
            }
875
        }
876
877
        $this->executeAlterSteps($table->getName(), $instructions);
878
    }
879
}
880