Completed
Pull Request — master (#1326)
by
unknown
04:09
created

OracleAdapter::connect()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 31
Code Lines 17

Duplication

Lines 5
Ratio 16.13 %

Importance

Changes 0
Metric Value
dl 5
loc 31
rs 8.439
c 0
b 0
f 0
cc 5
eloc 17
nc 6
nop 0
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 Phinx\Db\Table;
32
use Phinx\Db\Table\Column;
33
use Phinx\Db\Table\ForeignKey;
34
use Phinx\Db\Table\Index;
35
use Phinx\Migration\MigrationInterface;
36
37
/**
38
 * Phinx Oracle Adapter.
39
 *
40
 * @author Felipe Maia <[email protected]>
41
 */
42
class OracleAdapter extends PdoAdapter implements AdapterInterface
0 ignored issues
show
Bug introduced by
There is at least one abstract method in this class. Maybe declare it as abstract, or implement the remaining methods: getAddColumnInstructions, getAddForeignKeyInstructions, getAddIndexInstructions, getChangeColumnInstructions, getDropColumnInstructions, getDropForeignKeyByColumnsInstructions, getDropForeignKeyInstructions, getDropIndexByColumnsInstructions, getDropIndexByNameInstructions, getDropTableInstructions, getRenameColumnInstructions, getRenameTableInstructions
Loading history...
43
{
44
    protected $schema = 'dbo';
45
46
    protected $signedColumnTypes = ['integer' => true, 'biginteger' => true, 'float' => true, 'decimal' => true];
47
48
    /**
49
     * {@inheritdoc}
50
     */
51
    public function connect()
52
    {
53
        if ($this->connection === null) {
54
            if (!extension_loaded('pdo_oci')) {
55
                // @codeCoverageIgnoreStart
56
                throw new \RuntimeException('You need to enable the PDO_OCI extension for Phinx to run properly.');
57
                // @codeCoverageIgnoreEnd
58
            }
59
60
            $options = $this->getOptions();
61
62
            // if port is specified use it, otherwise use the Oracle default
63 View Code Duplication
            if (empty($options['port'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
64
                $dsn = "oci:dbname=//" . $options['host'] . "/" . $options['sid'] . "";
65
            } else {
66
                $dsn = "oci:dbname=//" . $options['host'] . ":" . $options['port'] . "/" . $options['sid'] . "";
67
            }
68
69
            $driverOptions = [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION];
70
71
            try {
72
                $db = new \PDO($dsn, $options['user'], $options['pass'], $driverOptions);
73
            } catch (\PDOException $exception) {
74
                throw new \InvalidArgumentException(sprintf(
75
                    'There was a problem connecting to the database: %s',
76
                    $exception->getMessage()
77
                ));
78
            }
79
            $this->setConnection($db);
80
        }
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function disconnect()
87
    {
88
        $this->connection = null;
89
    }
90
91
    /**
92
     * @codeCoverageIgnore
93
     * {@inheritdoc}
94
     */
95
    public function hasTransactions()
96
    {
97
        return true;
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     * @codeCoverageIgnore
103
     */
104
    public function beginTransaction()
105
    {
106
//        $this->execute('BEGIN TRANSACTION');
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     * @codeCoverageIgnore
112
     */
113
    public function commitTransaction()
114
    {
115
//        $this->execute('COMMIT TRANSACTION');
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     * @codeCoverageIgnore
121
     */
122
    public function rollbackTransaction()
123
    {
124
//        $this->execute('ROLLBACK TRANSACTION');
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130
    public function quoteTableName($tableName)
131
    {
132
        return str_replace('.', '].[', $this->quoteColumnName($tableName));
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138
    public function quoteColumnName($columnName)
139
    {
140
        return '"' . str_replace(']', '"', $columnName) . '"';
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146
    public function hasTable($tableName)
147
    {
148
        $result = $this->fetchRow(
149
            sprintf(
150
                'SELECT count(*) as count FROM ALL_TABLES WHERE table_name = \'%s\'',
151
                $tableName
152
            )
153
        );
154
155
        return $result['COUNT'] > 0;
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     */
161
    public function createTable(Table $table)
162
    {
163
        $options = $table->getOptions();
164
165
        // Add the default primary key
166
        $columns = $table->getPendingColumns();
0 ignored issues
show
Bug introduced by
The method getPendingColumns() does not seem to exist on object<Phinx\Db\Table>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
167
168
        if (!isset($options['id']) || (isset($options['id']) && $options['id'] === true)) {
169
            $column = new Column();
170
            $column->setName('id')
171
                ->setType('integer')
172
                ->setIdentity(true);
173
174
            array_unshift($columns, $column);
175
            $options['primary_key'] = 'id';
176
        } elseif (isset($options['id']) && is_string($options['id'])) {
177
            // Handle id => "field_name" to support AUTO_INCREMENT
178
            $column = new Column();
179
            $column->setName($options['id'])
180
                ->setType('integer')
181
                ->setIdentity(true);
182
183
            array_unshift($columns, $column);
184
            $options['primary_key'] = $options['id'];
185
        }
186
187
        $sql = 'CREATE TABLE ';
188
        $sql .= $this->quoteTableName($table->getName()) . ' (';
189
        $sqlBuffer = [];
190
        $columnsWithComments = [];
191
192 View Code Duplication
        foreach ($columns as $column) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
193
            $sqlBuffer[] = $this->quoteColumnName($column->getName()) . ' ' . $this->getColumnSqlDefinition($column);
194
195
            // set column comments, if needed
196
            if ($column->getComment()) {
197
                $columnsWithComments[] = $column;
198
            }
199
        }
200
201
        // set the primary key(s)
202 View Code Duplication
        if (isset($options['primary_key'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
203
            $pkSql = sprintf('CONSTRAINT PK_%s PRIMARY KEY (', substr($table->getName(), 0, 28));
204
            if (is_string($options['primary_key'])) { // handle primary_key => 'id'
205
                $pkSql .= $this->quoteColumnName($options['primary_key']);
206
            } elseif (is_array($options['primary_key'])) { // handle primary_key => array('tag_id', 'resource_id')
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
207
                $pkSql .= implode(',', array_map([$this, 'quoteColumnName'], $options['primary_key']));
208
            }
209
            $pkSql .= ')';
210
            $sqlBuffer[] = $pkSql;
211
        }
212
213
        // set the foreign keys
214
        $foreignKeys = $table->getForeignKeys();
0 ignored issues
show
Bug introduced by
The method getForeignKeys() does not seem to exist on object<Phinx\Db\Table>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
215
        foreach ($foreignKeys as $key => $foreignKey) {
216
            $sqlBuffer[] = $this->getForeignKeySqlDefinition($foreignKey, $table->getName());
217
        }
218
219
        $sql .= implode(', ', $sqlBuffer);
220
        $sql .= ')';
221
222
        $this->execute($sql);
223
        // process column comments
224
        foreach ($columnsWithComments as $key => $column) {
225
            $sql = $this->getColumnCommentSqlDefinition($column, $table->getName());
226
            $this->execute($sql);
227
        }
228
        // set the indexes
229
        $indexes = $table->getIndexes();
0 ignored issues
show
Bug introduced by
The method getIndexes() does not seem to exist on object<Phinx\Db\Table>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
230
231
        if (!empty($indexes)) {
232
            foreach ($indexes as $index) {
233
                $sql = $this->getIndexSqlDefinition($index, $table->getName());
234
                $this->execute($sql);
235
            }
236
        }
237
238
        if (!$this->hasSequence($table->getName())) {
239
            $sql = "CREATE SEQUENCE SQ_" . $table->getName() . " MINVALUE 1 MAXVALUE 99999999999999999 INCREMENT BY 1";
240
            $this->execute($sql);
241
        }
242
    }
243
244
    /**
245
     * Verify if the table has a Sequence for primary Key
246
     *
247
     * @param string $tableName Table name
248
     *
249
     * @return bool
250
     */
251
    public function hasSequence($tableName)
252
    {
253
        $sql = sprintf(
254
            "SELECT COUNT(*) as COUNT FROM user_sequences WHERE sequence_name = '%s'",
255
            strtoupper("SQ_" . $tableName)
256
        );
257
        $result = $this->fetchRow($sql);
258
259
        return $result['COUNT'] > 0;
260
    }
261
262
    /**
263
     * Gets the Oracle Column Comment Defininition for a column object.
264
     *
265
     * @param \Phinx\Db\Table\Column $column    Column
266
     * @param string $tableName Table name
267
     *
268
     * @return string
269
     */
270
    protected function getColumnCommentSqlDefinition(Column $column, $tableName)
271
    {
272
        $comment = (strcasecmp($column->getComment(), 'NULL') !== 0) ? $column->getComment() : '';
273
274
275
        return sprintf(
276
            "COMMENT ON COLUMN \"%s\".\"%s\" IS '%s'",
277
            $tableName,
278
            $column->getName(),
279
            str_replace("'", "", $comment)
280
        );
281
    }
282
283
    /**
284
     * {@inheritdoc}
285
     */
286
    public function renameTable($tableName, $newTableName)
287
    {
288
        $this->execute(sprintf('alter table "%s" rename to "%s"', $tableName, $newTableName));
289
290
        if (!$this->hasSequence("SQ_" . strtoupper($newTableName))) {
291
            $this->renameSequence("SQ_" . strtoupper($tableName), "SQ_" . strtoupper($newTableName));
292
        }
293
    }
294
295
    /**
296
     * Rename an Oracle Sequence Object.
297
     *
298
     * @param string $sequenceName Old Sequence Name
299
     * @param string $newSequenceName New Sequence Name
300
     *
301
     * @return void
302
     */
303
    public function renameSequence($sequenceName, $newSequenceName)
304
    {
305
        $this->execute(sprintf('rename "%s" to "%s"', $sequenceName, $newSequenceName));
306
    }
307
308
    /**
309
     * {@inheritdoc}
310
     */
311
    public function dropTable($tableName)
312
    {
313
        $this->execute(sprintf('DROP TABLE %s', $this->quoteTableName($tableName)));
314
        $this->execute(sprintf('DROP SEQUENCE %s', $this->quoteTableName(strtoupper("SQ_" . $tableName))));
315
    }
316
317
    /**
318
     * {@inheritdoc}
319
     */
320
    public function truncateTable($tableName)
321
    {
322
        $sql = sprintf(
323
            'TRUNCATE TABLE %s',
324
            $this->quoteTableName($tableName)
325
        );
326
327
        $this->execute($sql);
328
    }
329
330
    /**
331
     * Get the comment for a column
332
     *
333
     * @param string $tableName Table Name
334
     * @param string $columnName Column Name
335
     *
336
     * @return string
337
     */
338
    public function getColumnComment($tableName, $columnName)
339
    {
340
        $sql = sprintf(
341
            "select COMMENTS from ALL_COL_COMMENTS WHERE COLUMN_NAME = '%s' and TABLE_NAME = '%s'",
342
            $columnName,
343
            $tableName
344
        );
345
        $row = $this->fetchRow($sql);
346
347
        return $row['COMMENTS'];
348
    }
349
350
    /**
351
     * {@inheritdoc}
352
     */
353
    public function getColumns($tableName)
354
    {
355
        $columns = [];
356
357
        $sql = sprintf(
358
            "select TABLE_NAME \"TABLE_NAME\", COLUMN_NAME \"NAME\", DATA_TYPE \"TYPE\", NULLABLE \"NULL\", 
359
            DATA_DEFAULT \"DEFAULT\", DATA_LENGTH \"CHAR_LENGTH\", DATA_PRECISION \"PRECISION\", DATA_SCALE \"SCALE\", 
360
            COLUMN_ID \"ORDINAL_POSITION\" FROM ALL_TAB_COLUMNS WHERE table_name = '%s'",
361
            $tableName
362
        );
363
364
        $rows = $this->fetchAll($sql);
365
366
        foreach ($rows as $columnInfo) {
367
            $default = null;
368
            if (trim($columnInfo['DEFAULT']) != 'NULL') {
369
                $default = trim($columnInfo['DEFAULT']);
370
            }
371
372
            $column = new Column();
373
            $column->setName($columnInfo['NAME'])
374
                ->setType($this->getPhinxType($columnInfo['TYPE'], $columnInfo['PRECISION']))
375
                ->setNull($columnInfo['NULL'] !== 'N')
376
                ->setDefault($default)
377
                ->setComment($this->getColumnComment($columnInfo['TABLE_NAME'], $columnInfo['NAME']));
378
379
            if (!empty($columnInfo['CHAR_LENGTH'])) {
380
                $column->setLimit($columnInfo['CHAR_LENGTH']);
381
            }
382
383
            $columns[$columnInfo['NAME']] = $column;
384
        }
385
386
        return $columns;
387
    }
388
389
    /**
390
     * {@inheritdoc}
391
     */
392 View Code Duplication
    public function hasColumn($tableName, $columnName)
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...
393
    {
394
        $sql = sprintf(
395
            "select count(*) as count from ALL_TAB_COLUMNS 
396
            where table_name = '%s' and column_name = '%s'",
397
            $tableName,
398
            $columnName
399
        );
400
401
        $result = $this->fetchRow($sql);
402
403
        return $result['COUNT'] > 0;
404
    }
405
406
    /**
407
     * {@inheritdoc}
408
     */
409
    public function addColumn(Table $table, Column $column)
410
    {
411
        $sql = sprintf(
412
            'ALTER TABLE %s ADD %s %s',
413
            $this->quoteTableName($table->getName()),
414
            $this->quoteColumnName($column->getName()),
415
            $this->getColumnSqlDefinition($column)
416
        );
417
418
        $this->execute($sql);
419
    }
420
421
    /**
422
     * {@inheritdoc}
423
     */
424
    public function renameColumn($tableName, $columnName, $newColumnName)
425
    {
426
        if (!$this->hasColumn($tableName, $columnName)) {
427
            throw new \InvalidArgumentException("The specified column does not exist: $columnName");
428
        }
429
430
        $this->execute(
431
            sprintf(
432
                "alter table \"%s\" rename column \"%s\" TO \"%s\"",
433
                $tableName,
434
                $columnName,
435
                $newColumnName
436
            )
437
        );
438
    }
439
440
    /**
441
     * {@inheritdoc}
442
     */
443
    public function changeColumn($tableName, $columnName, Column $newColumn)
444
    {
445
        $columns = $this->getColumns($tableName);
446
447
        if ($columnName !== $newColumn->getName()) {
448
            $this->renameColumn($tableName, $columnName, $newColumn->getName());
449
        }
450
451
        $setNullSql = ($newColumn->isNull() == $columns[$columnName]->isNull() ? false : true);
452
453
        $this->execute(
454
            sprintf(
455
                'ALTER TABLE %s MODIFY(%s %s)',
456
                $this->quoteTableName($tableName),
457
                $this->quoteColumnName($newColumn->getName()),
458
                $this->getColumnSqlDefinition($newColumn, $setNullSql)
459
            )
460
        );
461
        // change column comment if needed
462
        if ($newColumn->getComment()) {
463
            $sql = $this->getColumnCommentSqlDefinition($newColumn, $tableName);
464
            $this->execute($sql);
465
        }
466
    }
467
468
    /**
469
     * {@inheritdoc}
470
     */
471
    public function dropColumn($tableName, $columnName)
472
    {
473
        $this->execute(
474
            sprintf(
475
                'ALTER TABLE %s DROP COLUMN %s',
476
                $this->quoteTableName($tableName),
477
                $this->quoteColumnName($columnName)
478
            )
479
        );
480
    }
481
482
    /**
483
     * Get an array of indexes from a particular table.
484
     *
485
     * @param string $tableName Table Name
486
     * @return array
487
     */
488 View Code Duplication
    public function getIndexes($tableName)
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...
489
    {
490
        $indexes = [];
491
        $sql = "SELECT index_owner as owner,index_name,column_name FROM ALL_IND_COLUMNS 
492
                WHERE TABLE_NAME = '$tableName'";
493
494
        $rows = $this->fetchAll($sql);
495
        foreach ($rows as $row) {
496
            if (!isset($indexes[$row['INDEX_NAME']])) {
497
                $indexes[$row['INDEX_NAME']] = ['columns' => []];
498
            }
499
            $indexes[$row['INDEX_NAME']]['columns'][] = strtoupper($row['COLUMN_NAME']);
500
        }
501
502
        return $indexes;
503
    }
504
505
    /**
506
     * {@inheritdoc}
507
     */
508 View Code Duplication
    public function hasIndex($tableName, $columns)
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...
509
    {
510
        if (is_string($columns)) {
511
            $columns = [$columns]; // str to array
512
        }
513
514
        $indexes = $this->getIndexes($tableName);
515
        foreach ($indexes as $index) {
516
            $a = array_diff($columns, $index['columns']);
517
518
            if (empty($a)) {
519
                return true;
520
            }
521
        }
522
523
        return false;
524
    }
525
526
    /**
527
     * {@inheritdoc}
528
     */
529 View Code Duplication
    public function hasIndexByName($tableName, $indexName)
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...
530
    {
531
        $indexes = $this->getIndexes($tableName);
532
533
        foreach ($indexes as $name => $index) {
534
            if ($name === $indexName) {
535
                return true;
536
            }
537
        }
538
539
        return false;
540
    }
541
542
    /**
543
     * {@inheritdoc}
544
     */
545
    public function addIndex(Table $table, Index $index)
546
    {
547
        $sql = $this->getIndexSqlDefinition($index, $table->getName());
548
        $this->execute($sql);
549
    }
550
551
    /**
552
     * {@inheritdoc}
553
     */
554
    public function dropIndex($tableName, $columns)
555
    {
556
        if (is_string($columns)) {
557
            $columns = [$columns]; // str to array
558
        }
559
560
        $indexes = $this->getIndexes($tableName);
561
        $columns = array_map('strtoupper', $columns);
562
563 View Code Duplication
        foreach ($indexes as $indexName => $index) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
564
            $a = array_diff($columns, $index['columns']);
565
            if (empty($a)) {
566
                $this->execute(
567
                    sprintf(
568
                        'DROP INDEX %s',
569
                        $this->quoteColumnName($indexName)
570
                    )
571
                );
572
573
                break;
574
            }
575
        }
576
    }
577
578
    /**
579
     * {@inheritdoc}
580
     */
581
    public function dropIndexByName($tableName, $indexName)
582
    {
583
        $indexes = $this->getIndexes($tableName);
584
585 View Code Duplication
        foreach ($indexes as $name => $index) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
586
            if ($name === $indexName) {
587
                $this->execute(
588
                    sprintf(
589
                        'DROP INDEX %s',
590
                        $this->quoteColumnName($indexName)
591
                    )
592
                );
593
594
                break;
595
            }
596
        }
597
    }
598
599
    /**
600
     * {@inheritdoc}
601
     */
602 View Code Duplication
    public function hasForeignKey($tableName, $columns, $constraint = 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...
603
    {
604
        if (is_string($columns)) {
605
            $columns = [$columns]; // str to array
606
        }
607
        $foreignKeys = $this->getForeignKeys($tableName);
608
609
        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...
610
            if (isset($foreignKeys[$constraint])) {
611
                return !empty($foreignKeys[$constraint]);
612
            }
613
614
            return false;
615
        } else {
616
            foreach ($foreignKeys as $key) {
617
                $a = array_diff($columns, $key['COLUMNS']);
618
                if (empty($a)) {
619
                    return true;
620
                }
621
            }
622
623
            return false;
624
        }
625
    }
626
627
    /**
628
     * Get an array of foreign keys from a particular table.
629
     *
630
     * @param string $tableName Table Name
631
     * @param string $type Type of Constraint Type (R, P)
632
     * @return array
633
     */
634 View Code Duplication
    protected function getForeignKeys($tableName, $type = 'R')
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...
635
    {
636
        $foreignKeys = [];
637
        $rows = $this->fetchAll(sprintf(
638
            "SELECT a.CONSTRAINT_NAME, a.TABLE_NAME, b.COLUMN_NAME, 
639
                    (SELECT c.TABLE_NAME from ALL_CONS_COLUMNS c 
640
                    WHERE c.CONSTRAINT_NAME = a.R_CONSTRAINT_NAME) referenced_table_name,
641
                    (SELECT c.COLUMN_NAME from ALL_CONS_COLUMNS c 
642
                    WHERE c.CONSTRAINT_NAME = a.R_CONSTRAINT_NAME) referenced_column_name
643
                    FROM all_constraints a JOIN ALL_CONS_COLUMNS b ON a.CONSTRAINT_NAME = b.CONSTRAINT_NAME
644
                    WHERE a.table_name = '%s'
645
                    AND CONSTRAINT_TYPE = '%s'",
646
            $tableName,
647
            $type
648
        ));
649
650
        foreach ($rows as $row) {
651
            $foreignKeys[$row['CONSTRAINT_NAME']]['TABLE'] = $row['TABLE_NAME'];
652
            $foreignKeys[$row['CONSTRAINT_NAME']]['COLUMNS'][] = $row['COLUMN_NAME'];
653
            $foreignKeys[$row['CONSTRAINT_NAME']]['REFERENCED_TABLE'] = $row['REFERENCED_TABLE_NAME'];
654
            $foreignKeys[$row['CONSTRAINT_NAME']]['REFERENCED_COLUMNS'][] = $row['REFERENCED_COLUMN_NAME'];
655
        }
656
657
        return $foreignKeys;
658
    }
659
660
    /**
661
     * {@inheritdoc}
662
     */
663
    public function addForeignKey(Table $table, ForeignKey $foreignKey)
664
    {
665
        $this->execute(
666
            sprintf(
667
                'ALTER TABLE %s ADD %s',
668
                $this->quoteTableName($table->getName()),
669
                $this->getForeignKeySqlDefinition($foreignKey, $table->getName())
670
            )
671
        );
672
    }
673
674
    /**
675
     * {@inheritdoc}
676
     */
677
    public function dropForeignKey($tableName, $columns, $constraint = null)
678
    {
679
        if (is_string($columns)) {
680
            $columns = [$columns]; // str to array
681
        }
682
683
        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...
684
            $this->execute(
685
                sprintf(
686
                    'ALTER TABLE %s DROP CONSTRAINT %s',
687
                    $this->quoteTableName($tableName),
688
                    $constraint
689
                )
690
            );
691
692
            return;
693
        } else {
694
            foreach ($columns as $column) {
695
                $rows = $this->fetchAll(sprintf(
696
                    "SELECT a.CONSTRAINT_NAME, a.TABLE_NAME, b.COLUMN_NAME, 
697
                    (SELECT c.TABLE_NAME from ALL_CONS_COLUMNS c 
698
                    WHERE c.CONSTRAINT_NAME = a.R_CONSTRAINT_NAME) referenced_table_name,
699
                    (SELECT c.COLUMN_NAME from ALL_CONS_COLUMNS c 
700
                    WHERE c.CONSTRAINT_NAME = a.R_CONSTRAINT_NAME) referenced_column_name
701
                    FROM all_constraints a JOIN ALL_CONS_COLUMNS b ON a.CONSTRAINT_NAME = b.CONSTRAINT_NAME
702
                    WHERE a.table_name = '%s'
703
                    AND CONSTRAINT_TYPE = 'R'
704
                    AND COLUMN_NAME = '%s'",
705
                    $tableName,
706
                    $column
707
                ));
708
                foreach ($rows as $row) {
709
                    $this->dropForeignKey($tableName, $columns, $row['CONSTRAINT_NAME']);
710
                }
711
            }
712
        }
713
    }
714
715
    /**
716
     * {@inheritdoc}
717
     */
718
    public function getSqlType($type, $limit = null)
719
    {
720
//      reference: https://docs.oracle.com/cd/B19306_01/gateways.102/b14270/apa.htm
721
        switch ($type) {
722
            case static::PHINX_TYPE_STRING:
723
                return ['name' => 'VARCHAR2', 'limit' => 255];
724
            case static::PHINX_TYPE_CHAR:
725
                return ['name' => 'CHAR', 'limit' => 255];
726
            case static::PHINX_TYPE_TEXT:
727
                return ['name' => 'LONG'];
728
            case static::PHINX_TYPE_INTEGER:
729
                return ['name' => 'NUMBER', 'precision' => 10];
730
            case static::PHINX_TYPE_BIG_INTEGER:
731
                return ['name' => 'NUMBER', 'precision' => 19];
732
            case static::PHINX_TYPE_FLOAT:
733
                return ['name' => 'FLOAT', 'precision' => 49];
734
            case static::PHINX_TYPE_DECIMAL:
735
                return ['name' => 'NUMBER'];
736
            case static::PHINX_TYPE_DATETIME:
737
                return ['name' => 'DATE'];
738
            case static::PHINX_TYPE_TIMESTAMP:
739
                return ['name' => 'TIMESTAMP'];
740
            case static::PHINX_TYPE_TIME:
741
                return ['name' => 'time'];
742
            case static::PHINX_TYPE_DATE:
743
                return ['name' => 'DATE'];
744
            case static::PHINX_TYPE_BLOB:
745
                return ['name' => 'BLOB'];
746
            case 'CLOB':
747
                return ['name' => 'CLOB'];
748
            case static::PHINX_TYPE_BINARY:
749
                return ['name' => 'RAW', 'limit' => 2000];
750
            case static::PHINX_TYPE_BOOLEAN:
751
                return ['name' => 'NUMBER', 'precision' => 1];
752
            case static::PHINX_TYPE_UUID:
753
                return ['name' => 'RAW', 'precision' => 16, 'default' => 'SYS_GUID()', 'limit' => 2000];
754
            case static::PHINX_TYPE_FILESTREAM:
755
                return ['name' => 'varbinary', 'limit' => 'max'];
756
            // Geospatial database types
757
            case static::PHINX_TYPE_GEOMETRY:
758
            case static::PHINX_TYPE_POINT:
759
            case static::PHINX_TYPE_LINESTRING:
760
            case static::PHINX_TYPE_POLYGON:
761
                // SQL Server stores all spatial data using a single data type.
762
                // Specific types (point, polygon, etc) are set at insert time.
763
                return ['name' => 'geography'];
764
            default:
765
                throw new \RuntimeException('The type: "' . $type . '" is not supported.');
766
        }
767
    }
768
769
    /**
770
     * Returns Phinx type by SQL type
771
     *
772
     * @param string $sqlType SQL Type definition
773
     * @param int $precision Precision of NUMBER type to define Phinx Type.
774
     * @throws \RuntimeException
775
     * @internal param string $sqlType SQL type
776
     * @return string Phinx type
777
     */
778
    public function getPhinxType($sqlType, $precision = null)
779
    {
780
        if ($sqlType === 'VARCHAR2') {
781
            return static::PHINX_TYPE_STRING;
782
        } elseif ($sqlType === 'CHAR') {
783
            return static::PHINX_TYPE_CHAR;
784
        } elseif ($sqlType == 'LONG') {
785
            return static::PHINX_TYPE_TEXT;
786
        } elseif ($sqlType === 'NUMBER' && $precision === 10) {
787
            return static::PHINX_TYPE_INTEGER;
788
        } elseif ($sqlType === 'NUMBER' && $precision === 19) {
789
            return static::PHINX_TYPE_BIG_INTEGER;
790
        } elseif ($sqlType === 'FLOAT') {
791
            return static::PHINX_TYPE_FLOAT;
792
        } elseif ($sqlType === 'TIMESTAMP(6)') {
793
            return static::PHINX_TYPE_TIMESTAMP;
794
        } elseif ($sqlType === 'TIME') {
795
            return static::PHINX_TYPE_TIME;
796
        } elseif ($sqlType === 'DATE') {
797
            return static::PHINX_TYPE_DATE;
798
        } elseif ($sqlType === 'BLOB') {
799
            return static::PHINX_TYPE_BLOB;
800
        } elseif ($sqlType === 'CLOB') {
801
            return 'CLOB';
802
        } elseif ($sqlType === 'RAW' && $precision === 16) {
803
            return static::PHINX_TYPE_UUID;
804
        } elseif ($sqlType === 'RAW') {
805
            return static::PHINX_TYPE_BLOB;
806
        } elseif ($sqlType === 'NUMBER' && $precision === 1) {
807
            return static::PHINX_TYPE_BOOLEAN;
808
        } elseif ($sqlType === 'NUMBER') {
809
            return static::PHINX_TYPE_DECIMAL;
810
        } else {
811
            throw new \RuntimeException('The Oracle type: "' . $sqlType . '" is not supported');
812
        }
813
    }
814
815
    /**
816
     * {@inheritdoc}
817
     */
818 View Code Duplication
    public function createDatabase($name, $options = [])
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...
819
    {
820
        if (isset($options['collation'])) {
821
            $this->execute(sprintf('CREATE DATABASE [%s] COLLATE [%s]', $name, $options['collation']));
822
        } else {
823
            $this->execute(sprintf('CREATE DATABASE [%s]', $name));
824
        }
825
        $this->execute(sprintf('USE [%s]', $name));
826
    }
827
828
    /**
829
     * {@inheritdoc}
830
     */
831
    public function hasDatabase($name)
832
    {
833
        $result = $this->fetchRow(
834
            sprintf(
835
                'SELECT count(*) as [count] FROM master.dbo.sysdatabases WHERE [name] = \'%s\'',
836
                $name
837
            )
838
        );
839
840
        return $result['count'] > 0;
841
    }
842
843
    /**
844
     * {@inheritdoc}
845
     */
846
    public function dropDatabase($name)
847
    {
848
        $sql = <<<SQL
849
USE master;
850
IF EXISTS(select * from sys.databases where name=N'$name')
851
ALTER DATABASE [$name] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
852
DROP DATABASE [$name];
853
SQL;
854
        $this->execute($sql);
855
    }
856
857
    /**
858
     * Get the defintion for a `DEFAULT` statement.
859
     *
860
     * @param  mixed $default Default value for column
861
     * @return string
862
     */
863
    protected function getDefaultValueDefinition($default)
864
    {
865
        if (is_string($default) && 'CURRENT_TIMESTAMP' !== $default && 'SYSDATE' !== $default) {
866
            $default = $this->getConnection()->quote($default);
867
        } elseif (is_bool($default)) {
868
            $default = $this->castToBool($default);
869
        }
870
871
        return isset($default) ? ' DEFAULT ' . $default : 'DEFAULT NULL';
872
    }
873
874
    /**
875
     * Gets the Oracle Column Definition for a Column object.
876
     *
877
     * @param \Phinx\Db\Table\Column $column Column
878
     * @param bool $setNullSql Set column nullable
879
     * @return string
880
     */
881
    protected function getColumnSqlDefinition(Column $column, $setNullSql = true)
882
    {
883
        $buffer = [];
884
885
        $sqlType = $this->getSqlType($column->getType());
0 ignored issues
show
Bug introduced by
It seems like $column->getType() targeting Phinx\Db\Table\Column::getType() can also be of type object<Phinx\Util\Literal>; however, Phinx\Db\Adapter\OracleAdapter::getSqlType() 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...
886
887
        $buffer[] = strtoupper($sqlType['name']);
888
        // integers cant have limits in Oracle
889
        $noLimits = [
890
            static::PHINX_TYPE_INTEGER,
891
            static::PHINX_TYPE_BIG_INTEGER,
892
            static::PHINX_TYPE_FLOAT,
893
            static::PHINX_TYPE_UUID,
894
            static::PHINX_TYPE_BOOLEAN
895
        ];
896 View Code Duplication
        if (!in_array($column->getType(), $noLimits) && ($column->getLimit() || isset($sqlType['limit']))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
897
            $buffer[] = sprintf('(%s)', $column->getLimit() ?: $sqlType['limit']);
898
        }
899 View Code Duplication
        if ($column->getPrecision() && $column->getScale()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
900
            $buffer[] = '(' . $column->getPrecision() . ',' . $column->getScale() . ')';
901
        }
902
903 View Code Duplication
        if ($column->getDefault() === null && $column->isNull()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
904
            $buffer[] = ' DEFAULT NULL';
905
        } else {
906
            $buffer[] = $this->getDefaultValueDefinition($column->getDefault());
907
        }
908
909
        if ($setNullSql) {
910
            $buffer[] = $column->isNull() ? 'NULL' : 'NOT NULL';
911
        }
912
913
        return implode(' ', $buffer);
914
    }
915
916
    /**
917
     * Gets the Oracle Index Definition for an Index object.
918
     *
919
     * @param \Phinx\Db\Table\Index $index Index
920
     * @param string $tableName Table Name
921
     * @return string
922
     */
923
    protected function getIndexSqlDefinition(Index $index, $tableName)
924
    {
925
        if (is_string($index->getName())) {
926
            $indexName = $index->getName();
927 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
928
            $columnNames = $index->getColumns();
929
            if (is_string($columnNames)) {
930
                $columnNames = [$columnNames];
931
            }
932
            $indexName = sprintf('%s_%s', $tableName, implode('_', $columnNames));
933
        }
934
        $def = sprintf(
935
            "CREATE %s INDEX %s ON %s (%s)",
936
            ($index->getType() === Index::UNIQUE ? 'UNIQUE' : ''),
937
            $indexName,
938
            $this->quoteTableName($tableName),
939
            '"' . implode('","', $index->getColumns()) . '"'
940
        );
941
942
        return $def;
943
    }
944
945
    /**
946
     * Gets the Oracle Foreign Key Definition for an ForeignKey object.
947
     *
948
     * @param \Phinx\Db\Table\ForeignKey $foreignKey Foreign Key Object
949
     * @param string $tableName Table Name
950
     * @return string
951
     */
952
    protected function getForeignKeySqlDefinition(ForeignKey $foreignKey, $tableName)
953
    {
954
        $constraintName = $foreignKey->getConstraint() ?: $tableName . '_' . implode('_', $foreignKey->getColumns());
955
        $def = ' CONSTRAINT ' . $this->quoteColumnName(substr($constraintName, 0, 27));
956
        $def .= ' FOREIGN KEY ("' . implode('", "', $foreignKey->getColumns()) . '")';
957
        $def .= " REFERENCES {$this->quoteTableName($foreignKey->getReferencedTable()->getName())} 
958
        (\"" . implode('", "', $foreignKey->getReferencedColumns()) . '")';
959
        if ($foreignKey->getOnDelete() && $foreignKey->getOnDelete() != "NO ACTION") {
960
            $def .= " ON DELETE {$foreignKey->getOnDelete()}";
961
        }
962
        if ($foreignKey->getOnUpdate()) {
963
            $def .= " ON UPDATE {$foreignKey->getOnUpdate()}";
964
        }
965
966
        return $def;
967
    }
968
969
    /**
970
     * {@inheritdoc}
971
     */
972
    public function getColumnTypes()
973
    {
974
        return array_merge(parent::getColumnTypes(), ['filestream']);
975
    }
976
977
    /**
978
     * Records a migration being run.
979
     *
980
     * @param \Phinx\Migration\MigrationInterface $migration Migration
981
     * @param string $direction Direction
982
     * @param int $startTime Start Time
983
     * @param int $endTime End Time
984
     * @return \Phinx\Db\Adapter\AdapterInterface
985
     */
986
    public function migrated(\Phinx\Migration\MigrationInterface $migration, $direction, $startTime, $endTime)
987
    {
988
        $startTime = "TO_TIMESTAMP('$startTime', 'YYYY-MM-DD HH24:MI:SS')";
989
        $endTime = "TO_TIMESTAMP('$endTime', 'YYYY-MM-DD HH24:MI:SS')";
990
991 View Code Duplication
        if (strcasecmp($direction, MigrationInterface::UP) === 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
992
            // up
993
            $sql = sprintf(
994
                "INSERT INTO \"%s\" (%s, %s, %s, %s, %s) VALUES ('%s', '%s', %s, %s, %s)",
995
                $this->getSchemaTableName(),
996
                $this->quoteColumnName('version'),
997
                $this->quoteColumnName('migration_name'),
998
                $this->quoteColumnName('start_time'),
999
                $this->quoteColumnName('end_time'),
1000
                $this->quoteColumnName('breakpoint'),
1001
                $migration->getVersion(),
1002
                substr($migration->getName(), 0, 100),
1003
                $startTime,
1004
                $endTime,
1005
                $this->castToBool(false)
1006
            );
1007
1008
            $this->execute($sql);
1009
        } else {
1010
            // down
1011
            $sql = sprintf(
1012
                "DELETE FROM \"%s\" WHERE %s = '%s'",
1013
                $this->getSchemaTableName(),
1014
                $this->quoteColumnName('version'),
1015
                $migration->getVersion()
1016
            );
1017
1018
            $this->execute($sql);
1019
        }
1020
1021
        return $this;
1022
    }
1023
1024
    /**
1025
     * {@inheritdoc}
1026
     */
1027
    public function bulkinsert(Table $table, $rows)
1028
    {
1029
        $sql = "INSERT ALL ";
1030
1031
        $vals = [];
1032
        $tableName = $table->getName();
1033
        $primaryKeyColumn = current($this->getForeignKeys($tableName, 'P'));
1034
        $sequenceNextVal = $this->getNextValSequence('SQ_' . $tableName);
1035
//        buscar sequence e primary key padr�o para incrementar PK com a SEQUENCE.NEXTVAL
1036
1037
        foreach ($rows as $key => $row) {
1038
            $pk = ($sequenceNextVal + $key);
1039
            $row[$primaryKeyColumn['COLUMNS'][0]] = (int)$pk;
1040
1041
            $sql .= sprintf(
1042
                "INTO %s ",
1043
                $this->quoteTableName($tableName)
1044
            );
1045
1046
            $keys = array_keys($row);
1047
            $sql .= "(" . implode(', ', array_map([$this, 'quoteColumnName'], $keys)) . ") VALUES";
1048
1049
            foreach ($row as $v) {
1050
                $vals[] = $v;
1051
            }
1052
1053
            $count_keys = count($keys);
1054
            $query = " (" . implode(', ', array_fill(0, $count_keys, '?')) . ") ";
1055
1056
            $queries = array_fill(0, 1, $query);
1057
            $sql .= implode(',', $queries);
1058
        }
1059
        $sql .= "SELECT 1 FROM DUAL";
1060
        $stmt = $this->getConnection()->prepare($sql);
1061
        $stmt->execute($vals);
1062
    }
1063
1064
    /**
1065
     * Get Next Auto Increment Value Sequence
1066
     *
1067
     *
1068
     * @param string $sequence Sequence Name
1069
     * @return int
1070
     */
1071
    protected function getNextValSequence($sequence)
1072
    {
1073
        $sql = "SELECT %s.NEXTVAL FROM DUAL";
1074
        $rows = $this->fetchAll(sprintf($sql, $sequence));
1075
1076
        return $rows[0]['NEXTVAL'];
1077
    }
1078
1079
    /**
1080
     * {@inheritdoc}
1081
     */
1082 View Code Duplication
    public function getVersionLog()
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...
1083
    {
1084
        $result = [];
1085
1086
        switch ($this->options['version_order']) {
1087
            case \Phinx\Config\Config::VERSION_ORDER_CREATION_TIME:
1088
                $orderBy = '"version" ASC';
1089
                break;
1090
            case \Phinx\Config\Config::VERSION_ORDER_EXECUTION_TIME:
1091
                $orderBy = '"start_time" ASC, "version" ASC';
1092
                break;
1093
            default:
1094
                throw new \RuntimeException('Invalid version_order configuration option');
1095
        }
1096
1097
        $rows = $this->fetchAll(sprintf('SELECT * FROM %s ORDER BY %s', $this->quoteColumnName(
1098
            $this->getSchemaTableName()
1099
        ), $orderBy));
1100
        foreach ($rows as $version) {
1101
            $result[$version['version']] = $version;
1102
        }
1103
1104
        return $result;
1105
    }
1106
}
1107