Passed
Push — master ( 047d0e...5cefa4 )
by Marco
06:53
created

lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\Schema;
21
22
use Doctrine\DBAL\Events;
23
use Doctrine\DBAL\Event\SchemaColumnDefinitionEventArgs;
24
use Doctrine\DBAL\Event\SchemaIndexDefinitionEventArgs;
25
use Doctrine\DBAL\DBALException;
26
use Doctrine\DBAL\Platforms\AbstractPlatform;
27
28
/**
29
 * Base class for schema managers. Schema managers are used to inspect and/or
30
 * modify the database schema/structure.
31
 *
32
 * @author Konsta Vesterinen <[email protected]>
33
 * @author Lukas Smith <[email protected]> (PEAR MDB2 library)
34
 * @author Roman Borschel <[email protected]>
35
 * @author Jonathan H. Wage <[email protected]>
36
 * @author Benjamin Eberlei <[email protected]>
37
 * @since  2.0
38
 */
39
abstract class AbstractSchemaManager
40
{
41
    /**
42
     * Holds instance of the Doctrine connection for this schema manager.
43
     *
44
     * @var \Doctrine\DBAL\Connection
45
     */
46
    protected $_conn;
47
48
    /**
49
     * Holds instance of the database platform used for this schema manager.
50
     *
51
     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
52
     */
53
    protected $_platform;
54
55
    /**
56
     * Constructor. Accepts the Connection instance to manage the schema for.
57
     *
58
     * @param \Doctrine\DBAL\Connection                      $conn
59
     * @param \Doctrine\DBAL\Platforms\AbstractPlatform|null $platform
60
     */
61 38
    public function __construct(\Doctrine\DBAL\Connection $conn, AbstractPlatform $platform = null)
62
    {
63 38
        $this->_conn     = $conn;
64 38
        $this->_platform = $platform ?: $this->_conn->getDatabasePlatform();
65 38
    }
66
67
    /**
68
     * Returns the associated platform.
69
     *
70
     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
71
     */
72 12
    public function getDatabasePlatform()
73
    {
74 12
        return $this->_platform;
75
    }
76
77
    /**
78
     * Tries any method on the schema manager. Normally a method throws an
79
     * exception when your DBMS doesn't support it or if an error occurs.
80
     * This method allows you to try and method on your SchemaManager
81
     * instance and will return false if it does not work or is not supported.
82
     *
83
     * <code>
84
     * $result = $sm->tryMethod('dropView', 'view_name');
85
     * </code>
86
     *
87
     * @return mixed
88
     */
89 49
    public function tryMethod()
90
    {
91 49
        $args = func_get_args();
92 49
        $method = $args[0];
93 49
        unset($args[0]);
94 49
        $args = array_values($args);
95
96
        try {
97 49
            return call_user_func_array(array($this, $method), $args);
98 14
        } catch (\Exception $e) {
99 14
            return false;
100
        }
101
    }
102
103
    /**
104
     * Lists the available databases for this connection.
105
     *
106
     * @return array
107
     */
108 1
    public function listDatabases()
109
    {
110 1
        $sql = $this->_platform->getListDatabasesSQL();
111
112
        $databases = $this->_conn->fetchAll($sql);
113
114
        return $this->_getPortableDatabasesList($databases);
115
    }
116
117
    /**
118
     * Returns a list of all namespaces in the current database.
119
     *
120
     * @return array
121
     */
122
    public function listNamespaceNames()
123
    {
124
        $sql = $this->_platform->getListNamespacesSQL();
125
126
        $namespaces = $this->_conn->fetchAll($sql);
127
128
        return $this->getPortableNamespacesList($namespaces);
129
    }
130
131
    /**
132
     * Lists the available sequences for this connection.
133
     *
134
     * @param string|null $database
135
     *
136
     * @return \Doctrine\DBAL\Schema\Sequence[]
137
     */
138 1
    public function listSequences($database = null)
139
    {
140 1
        if (is_null($database)) {
141
            $database = $this->_conn->getDatabase();
142
        }
143 1
        $sql = $this->_platform->getListSequencesSQL($database);
144
145 1
        $sequences = $this->_conn->fetchAll($sql);
146
147 1
        return $this->filterAssetNames($this->_getPortableSequencesList($sequences));
148
    }
149
150
    /**
151
     * Lists the columns for a given table.
152
     *
153
     * In contrast to other libraries and to the old version of Doctrine,
154
     * this column definition does try to contain the 'primary' field for
155
     * the reason that it is not portable across different RDBMS. Use
156
     * {@see listTableIndexes($tableName)} to retrieve the primary key
157
     * of a table. We're a RDBMS specifies more details these are held
158
     * in the platformDetails array.
159
     *
160
     * @param string      $table    The name of the table.
161
     * @param string|null $database
162
     *
163
     * @return \Doctrine\DBAL\Schema\Column[]
164
     */
165 38 View Code Duplication
    public function listTableColumns($table, $database = null)
0 ignored issues
show
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...
166
    {
167 38
        if ( ! $database) {
168 38
            $database = $this->_conn->getDatabase();
169
        }
170
171 38
        $sql = $this->_platform->getListTableColumnsSQL($table, $database);
172
173 38
        $tableColumns = $this->_conn->fetchAll($sql);
174
175 38
        return $this->_getPortableTableColumnList($table, $database, $tableColumns);
176
    }
177
178
    /**
179
     * Lists the indexes for a given table returning an array of Index instances.
180
     *
181
     * Keys of the portable indexes list are all lower-cased.
182
     *
183
     * @param string $table The name of the table.
184
     *
185
     * @return \Doctrine\DBAL\Schema\Index[]
186
     */
187 31
    public function listTableIndexes($table)
188
    {
189 31
        $sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase());
190
191 31
        $tableIndexes = $this->_conn->fetchAll($sql);
192
193 31
        return $this->_getPortableTableIndexesList($tableIndexes, $table);
194
    }
195
196
    /**
197
     * Returns true if all the given tables exist.
198
     *
199
     * @param array $tableNames
200
     *
201
     * @return boolean
202
     */
203 8
    public function tablesExist($tableNames)
204
    {
205 8
        $tableNames = array_map('strtolower', (array) $tableNames);
206
207 8
        return count($tableNames) == count(\array_intersect($tableNames, array_map('strtolower', $this->listTableNames())));
208
    }
209
210
    /**
211
     * Returns a list of all tables in the current database.
212
     *
213
     * @return array
214
     */
215 14
    public function listTableNames()
216
    {
217 14
        $sql = $this->_platform->getListTablesSQL();
218
219 14
        $tables = $this->_conn->fetchAll($sql);
220 14
        $tableNames = $this->_getPortableTablesList($tables);
221
222 14
        return $this->filterAssetNames($tableNames);
223
    }
224
225
    /**
226
     * Filters asset names if they are configured to return only a subset of all
227
     * the found elements.
228
     *
229
     * @param array $assetNames
230
     *
231
     * @return array
232
     */
233 15
    protected function filterAssetNames($assetNames)
234
    {
235 15
        $filterExpr = $this->getFilterSchemaAssetsExpression();
236 15
        if ( ! $filterExpr) {
237 14
            return $assetNames;
238
        }
239
240 1
        return array_values(
241 1
            array_filter($assetNames, function ($assetName) use ($filterExpr) {
242 1
                $assetName = ($assetName instanceof AbstractAsset) ? $assetName->getName() : $assetName;
243
244 1
                return preg_match($filterExpr, $assetName);
245 1
            })
246
        );
247
    }
248
249
    /**
250
     * @return string|null
251
     */
252 15
    protected function getFilterSchemaAssetsExpression()
253
    {
254 15
        return $this->_conn->getConfiguration()->getFilterSchemaAssetsExpression();
255
    }
256
257
    /**
258
     * Lists the tables for this connection.
259
     *
260
     * @return \Doctrine\DBAL\Schema\Table[]
261
     */
262 5
    public function listTables()
263
    {
264 5
        $tableNames = $this->listTableNames();
265
266 5
        $tables = array();
267 5
        foreach ($tableNames as $tableName) {
268 4
            $tables[] = $this->listTableDetails($tableName);
269
        }
270
271 5
        return $tables;
272
    }
273
274
    /**
275
     * @param string $tableName
276
     *
277
     * @return \Doctrine\DBAL\Schema\Table
278
     */
279 27
    public function listTableDetails($tableName)
280
    {
281 27
        $columns = $this->listTableColumns($tableName);
282 27
        $foreignKeys = array();
283 27
        if ($this->_platform->supportsForeignKeyConstraints()) {
284
            $foreignKeys = $this->listTableForeignKeys($tableName);
285
        }
286 27
        $indexes = $this->listTableIndexes($tableName);
287
288 27
        return new Table($tableName, $columns, $indexes, $foreignKeys, false, array());
289
    }
290
291
    /**
292
     * Lists the views this connection has.
293
     *
294
     * @return \Doctrine\DBAL\Schema\View[]
295
     */
296 1
    public function listViews()
297
    {
298 1
        $database = $this->_conn->getDatabase();
299 1
        $sql = $this->_platform->getListViewsSQL($database);
300 1
        $views = $this->_conn->fetchAll($sql);
301
302 1
        return $this->_getPortableViewsList($views);
303
    }
304
305
    /**
306
     * Lists the foreign keys for the given table.
307
     *
308
     * @param string      $table    The name of the table.
309
     * @param string|null $database
310
     *
311
     * @return \Doctrine\DBAL\Schema\ForeignKeyConstraint[]
312
     */
313 1 View Code Duplication
    public function listTableForeignKeys($table, $database = null)
314
    {
315 1
        if (is_null($database)) {
316 1
            $database = $this->_conn->getDatabase();
317
        }
318 1
        $sql = $this->_platform->getListTableForeignKeysSQL($table, $database);
319 1
        $tableForeignKeys = $this->_conn->fetchAll($sql);
320
321 1
        return $this->_getPortableTableForeignKeysList($tableForeignKeys);
322
    }
323
324
    /* drop*() Methods */
325
326
    /**
327
     * Drops a database.
328
     *
329
     * NOTE: You can not drop the database this SchemaManager is currently connected to.
330
     *
331
     * @param string $database The name of the database to drop.
332
     *
333
     * @return void
334
     */
335
    public function dropDatabase($database)
336
    {
337
        $this->_execSql($this->_platform->getDropDatabaseSQL($database));
338
    }
339
340
    /**
341
     * Drops the given table.
342
     *
343
     * @param string $tableName The name of the table to drop.
344
     *
345
     * @return void
346
     */
347 59
    public function dropTable($tableName)
348
    {
349 59
        $this->_execSql($this->_platform->getDropTableSQL($tableName));
350 44
    }
351
352
    /**
353
     * Drops the index from the given table.
354
     *
355
     * @param \Doctrine\DBAL\Schema\Index|string $index The name of the index.
356
     * @param \Doctrine\DBAL\Schema\Table|string $table The name of the table.
357
     *
358
     * @return void
359
     */
360 1
    public function dropIndex($index, $table)
361
    {
362 1
        if ($index instanceof Index) {
363
            $index = $index->getQuotedName($this->_platform);
364
        }
365
366 1
        $this->_execSql($this->_platform->getDropIndexSQL($index, $table));
367 1
    }
368
369
    /**
370
     * Drops the constraint from the given table.
371
     *
372
     * @param \Doctrine\DBAL\Schema\Constraint   $constraint
373
     * @param \Doctrine\DBAL\Schema\Table|string $table      The name of the table.
374
     *
375
     * @return void
376
     */
377
    public function dropConstraint(Constraint $constraint, $table)
378
    {
379
        $this->_execSql($this->_platform->getDropConstraintSQL($constraint, $table));
380
    }
381
382
    /**
383
     * Drops a foreign key from a table.
384
     *
385
     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint|string $foreignKey The name of the foreign key.
386
     * @param \Doctrine\DBAL\Schema\Table|string                $table      The name of the table with the foreign key.
387
     *
388
     * @return void
389
     */
390
    public function dropForeignKey($foreignKey, $table)
391
    {
392
        $this->_execSql($this->_platform->getDropForeignKeySQL($foreignKey, $table));
393
    }
394
395
    /**
396
     * Drops a sequence with a given name.
397
     *
398
     * @param string $name The name of the sequence to drop.
399
     *
400
     * @return void
401
     */
402
    public function dropSequence($name)
403
    {
404
        $this->_execSql($this->_platform->getDropSequenceSQL($name));
405
    }
406
407
    /**
408
     * Drops a view.
409
     *
410
     * @param string $name The name of the view.
411
     *
412
     * @return void
413
     */
414 1
    public function dropView($name)
415
    {
416 1
        $this->_execSql($this->_platform->getDropViewSQL($name));
417
    }
418
419
    /* create*() Methods */
420
421
    /**
422
     * Creates a new database.
423
     *
424
     * @param string $database The name of the database to create.
425
     *
426
     * @return void
427
     */
428
    public function createDatabase($database)
429
    {
430
        $this->_execSql($this->_platform->getCreateDatabaseSQL($database));
431
    }
432
433
    /**
434
     * Creates a new table.
435
     *
436
     * @param \Doctrine\DBAL\Schema\Table $table
437
     *
438
     * @return void
439
     */
440 115
    public function createTable(Table $table)
441
    {
442 115
        $createFlags = AbstractPlatform::CREATE_INDEXES|AbstractPlatform::CREATE_FOREIGNKEYS;
443 115
        $this->_execSql($this->_platform->getCreateTableSQL($table, $createFlags));
444 83
    }
445
446
    /**
447
     * Creates a new sequence.
448
     *
449
     * @param \Doctrine\DBAL\Schema\Sequence $sequence
450
     *
451
     * @return void
452
     *
453
     * @throws \Doctrine\DBAL\ConnectionException If something fails at database level.
454
     */
455
    public function createSequence($sequence)
456
    {
457
        $this->_execSql($this->_platform->getCreateSequenceSQL($sequence));
458
    }
459
460
    /**
461
     * Creates a constraint on a table.
462
     *
463
     * @param \Doctrine\DBAL\Schema\Constraint   $constraint
464
     * @param \Doctrine\DBAL\Schema\Table|string $table
465
     *
466
     * @return void
467
     */
468
    public function createConstraint(Constraint $constraint, $table)
469
    {
470
        $this->_execSql($this->_platform->getCreateConstraintSQL($constraint, $table));
471
    }
472
473
    /**
474
     * Creates a new index on a table.
475
     *
476
     * @param \Doctrine\DBAL\Schema\Index        $index
477
     * @param \Doctrine\DBAL\Schema\Table|string $table The name of the table on which the index is to be created.
478
     *
479
     * @return void
480
     */
481 1
    public function createIndex(Index $index, $table)
482
    {
483 1
        $this->_execSql($this->_platform->getCreateIndexSQL($index, $table));
484 1
    }
485
486
    /**
487
     * Creates a new foreign key.
488
     *
489
     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey The ForeignKey instance.
490
     * @param \Doctrine\DBAL\Schema\Table|string         $table      The name of the table on which the foreign key is to be created.
491
     *
492
     * @return void
493
     */
494
    public function createForeignKey(ForeignKeyConstraint $foreignKey, $table)
495
    {
496
        $this->_execSql($this->_platform->getCreateForeignKeySQL($foreignKey, $table));
497
    }
498
499
    /**
500
     * Creates a new view.
501
     *
502
     * @param \Doctrine\DBAL\Schema\View $view
503
     *
504
     * @return void
505
     */
506 1
    public function createView(View $view)
507
    {
508 1
        $this->_execSql($this->_platform->getCreateViewSQL($view->getQuotedName($this->_platform), $view->getSql()));
509 1
    }
510
511
    /* dropAndCreate*() Methods */
512
513
    /**
514
     * Drops and creates a constraint.
515
     *
516
     * @see dropConstraint()
517
     * @see createConstraint()
518
     *
519
     * @param \Doctrine\DBAL\Schema\Constraint   $constraint
520
     * @param \Doctrine\DBAL\Schema\Table|string $table
521
     *
522
     * @return void
523
     */
524
    public function dropAndCreateConstraint(Constraint $constraint, $table)
525
    {
526
        $this->tryMethod('dropConstraint', $constraint, $table);
527
        $this->createConstraint($constraint, $table);
528
    }
529
530
    /**
531
     * Drops and creates a new index on a table.
532
     *
533
     * @param \Doctrine\DBAL\Schema\Index        $index
534
     * @param \Doctrine\DBAL\Schema\Table|string $table The name of the table on which the index is to be created.
535
     *
536
     * @return void
537
     */
538 1
    public function dropAndCreateIndex(Index $index, $table)
539
    {
540 1
        $this->tryMethod('dropIndex', $index->getQuotedName($this->_platform), $table);
541 1
        $this->createIndex($index, $table);
542 1
    }
543
544
    /**
545
     * Drops and creates a new foreign key.
546
     *
547
     * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey An associative array that defines properties of the foreign key to be created.
548
     * @param \Doctrine\DBAL\Schema\Table|string         $table      The name of the table on which the foreign key is to be created.
549
     *
550
     * @return void
551
     */
552
    public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table)
553
    {
554
        $this->tryMethod('dropForeignKey', $foreignKey, $table);
555
        $this->createForeignKey($foreignKey, $table);
556
    }
557
558
    /**
559
     * Drops and create a new sequence.
560
     *
561
     * @param \Doctrine\DBAL\Schema\Sequence $sequence
562
     *
563
     * @return void
564
     *
565
     * @throws \Doctrine\DBAL\ConnectionException If something fails at database level.
566
     */
567
    public function dropAndCreateSequence(Sequence $sequence)
568
    {
569
        $this->tryMethod('dropSequence', $sequence->getQuotedName($this->_platform));
570
        $this->createSequence($sequence);
571
    }
572
573
    /**
574
     * Drops and creates a new table.
575
     *
576
     * @param \Doctrine\DBAL\Schema\Table $table
577
     *
578
     * @return void
579
     */
580 48
    public function dropAndCreateTable(Table $table)
581
    {
582 48
        $this->tryMethod('dropTable', $table->getQuotedName($this->_platform));
583 48
        $this->createTable($table);
584 48
    }
585
586
    /**
587
     * Drops and creates a new database.
588
     *
589
     * @param string $database The name of the database to create.
590
     *
591
     * @return void
592
     */
593 1
    public function dropAndCreateDatabase($database)
594
    {
595 1
        $this->tryMethod('dropDatabase', $database);
596 1
        $this->createDatabase($database);
597 1
    }
598
599
    /**
600
     * Drops and creates a new view.
601
     *
602
     * @param \Doctrine\DBAL\Schema\View $view
603
     *
604
     * @return void
605
     */
606 1
    public function dropAndCreateView(View $view)
607
    {
608 1
        $this->tryMethod('dropView', $view->getQuotedName($this->_platform));
609 1
        $this->createView($view);
610 1
    }
611
612
    /* alterTable() Methods */
613
614
    /**
615
     * Alters an existing tables schema.
616
     *
617
     * @param \Doctrine\DBAL\Schema\TableDiff $tableDiff
618
     *
619
     * @return void
620
     */
621 14
    public function alterTable(TableDiff $tableDiff)
622
    {
623 14
        $queries = $this->_platform->getAlterTableSQL($tableDiff);
624 14
        if (is_array($queries) && count($queries)) {
625 14
            foreach ($queries as $ddlQuery) {
626 14
                $this->_execSql($ddlQuery);
627
            }
628
        }
629 14
    }
630
631
    /**
632
     * Renames a given table to another name.
633
     *
634
     * @param string $name    The current name of the table.
635
     * @param string $newName The new name of the table.
636
     *
637
     * @return void
638
     */
639
    public function renameTable($name, $newName)
640
    {
641
        $tableDiff = new TableDiff($name);
642
        $tableDiff->newName = $newName;
643
        $this->alterTable($tableDiff);
644
    }
645
646
    /**
647
     * Methods for filtering return values of list*() methods to convert
648
     * the native DBMS data definition to a portable Doctrine definition
649
     */
650
651
    /**
652
     * @param array $databases
653
     *
654
     * @return array
655
     */
656
    protected function _getPortableDatabasesList($databases)
657
    {
658
        $list = array();
659
        foreach ($databases as $value) {
660
            if ($value = $this->_getPortableDatabaseDefinition($value)) {
661
                $list[] = $value;
662
            }
663
        }
664
665
        return $list;
666
    }
667
668
    /**
669
     * Converts a list of namespace names from the native DBMS data definition to a portable Doctrine definition.
670
     *
671
     * @param array $namespaces The list of namespace names in the native DBMS data definition.
672
     *
673
     * @return array
674
     */
675
    protected function getPortableNamespacesList(array $namespaces)
676
    {
677
        $namespacesList = array();
678
679
        foreach ($namespaces as $namespace) {
680
            $namespacesList[] = $this->getPortableNamespaceDefinition($namespace);
681
        }
682
683
        return $namespacesList;
684
    }
685
686
    /**
687
     * @param array $database
688
     *
689
     * @return mixed
690
     */
691
    protected function _getPortableDatabaseDefinition($database)
692
    {
693
        return $database;
694
    }
695
696
    /**
697
     * Converts a namespace definition from the native DBMS data definition to a portable Doctrine definition.
698
     *
699
     * @param array $namespace The native DBMS namespace definition.
700
     *
701
     * @return mixed
702
     */
703
    protected function getPortableNamespaceDefinition(array $namespace)
704
    {
705
        return $namespace;
706
    }
707
708
    /**
709
     * @param array $functions
710
     *
711
     * @return array
712
     */
713
    protected function _getPortableFunctionsList($functions)
714
    {
715
        $list = array();
716
        foreach ($functions as $value) {
717
            if ($value = $this->_getPortableFunctionDefinition($value)) {
718
                $list[] = $value;
719
            }
720
        }
721
722
        return $list;
723
    }
724
725
    /**
726
     * @param array $function
727
     *
728
     * @return mixed
729
     */
730
    protected function _getPortableFunctionDefinition($function)
731
    {
732
        return $function;
733
    }
734
735
    /**
736
     * @param array $triggers
737
     *
738
     * @return array
739
     */
740
    protected function _getPortableTriggersList($triggers)
741
    {
742
        $list = array();
743
        foreach ($triggers as $value) {
744
            if ($value = $this->_getPortableTriggerDefinition($value)) {
745
                $list[] = $value;
746
            }
747
        }
748
749
        return $list;
750
    }
751
752
    /**
753
     * @param array $trigger
754
     *
755
     * @return mixed
756
     */
757
    protected function _getPortableTriggerDefinition($trigger)
758
    {
759
        return $trigger;
760
    }
761
762
    /**
763
     * @param array $sequences
764
     *
765
     * @return array
766
     */
767
    protected function _getPortableSequencesList($sequences)
768
    {
769
        $list = array();
770
        foreach ($sequences as $value) {
771
            if ($value = $this->_getPortableSequenceDefinition($value)) {
772
                $list[] = $value;
773
            }
774
        }
775
776
        return $list;
777
    }
778
779
    /**
780
     * @param array $sequence
781
     *
782
     * @return \Doctrine\DBAL\Schema\Sequence
783
     *
784
     * @throws \Doctrine\DBAL\DBALException
785
     */
786
    protected function _getPortableSequenceDefinition($sequence)
787
    {
788
        throw DBALException::notSupported('Sequences');
789
    }
790
791
    /**
792
     * Independent of the database the keys of the column list result are lowercased.
793
     *
794
     * The name of the created column instance however is kept in its case.
795
     *
796
     * @param string $table        The name of the table.
797
     * @param string $database
798
     * @param array  $tableColumns
799
     *
800
     * @return array
801
     */
802 38
    protected function _getPortableTableColumnList($table, $database, $tableColumns)
803
    {
804 38
        $eventManager = $this->_platform->getEventManager();
805
806 38
        $list = array();
807 38
        foreach ($tableColumns as $tableColumn) {
808 38
            $column = null;
809 38
            $defaultPrevented = false;
810
811 38 View Code Duplication
            if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaColumnDefinition)) {
812 1
                $eventArgs = new SchemaColumnDefinitionEventArgs($tableColumn, $table, $database, $this->_conn);
813 1
                $eventManager->dispatchEvent(Events::onSchemaColumnDefinition, $eventArgs);
814
815 1
                $defaultPrevented = $eventArgs->isDefaultPrevented();
816 1
                $column = $eventArgs->getColumn();
817
            }
818
819 38
            if ( ! $defaultPrevented) {
820 38
                $column = $this->_getPortableTableColumnDefinition($tableColumn);
821
            }
822
823 38
            if ($column) {
824 38
                $name = strtolower($column->getQuotedName($this->_platform));
825 38
                $list[$name] = $column;
826
            }
827
        }
828
829 38
        return $list;
830
    }
831
832
    /**
833
     * Gets Table Column Definition.
834
     *
835
     * @param array $tableColumn
836
     *
837
     * @return \Doctrine\DBAL\Schema\Column
838
     */
839
    abstract protected function _getPortableTableColumnDefinition($tableColumn);
840
841
    /**
842
     * Aggregates and groups the index results according to the required data result.
843
     *
844
     * @param array       $tableIndexRows
845
     * @param string|null $tableName
846
     *
847
     * @return array
848
     */
849 31
    protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null)
850
    {
851 31
        $result = array();
852 31
        foreach ($tableIndexRows as $tableIndex) {
853 21
            $indexName = $keyName = $tableIndex['key_name'];
854 21
            if ($tableIndex['primary']) {
855 21
                $keyName = 'primary';
856
            }
857 21
            $keyName = strtolower($keyName);
858
859 21
            if (!isset($result[$keyName])) {
860 21
                $result[$keyName] = array(
861 21
                    'name' => $indexName,
862 21
                    'columns' => array($tableIndex['column_name']),
863 21
                    'unique' => $tableIndex['non_unique'] ? false : true,
864 21
                    'primary' => $tableIndex['primary'],
865 21
                    'flags' => isset($tableIndex['flags']) ? $tableIndex['flags'] : array(),
866 21
                    'options' => isset($tableIndex['where']) ? array('where' => $tableIndex['where']) : array(),
867
                );
868
            } else {
869 7
                $result[$keyName]['columns'][] = $tableIndex['column_name'];
870
            }
871
        }
872
873 31
        $eventManager = $this->_platform->getEventManager();
874
875 31
        $indexes = array();
876 31
        foreach ($result as $indexKey => $data) {
877 21
            $index = null;
878 21
            $defaultPrevented = false;
879
880 21 View Code Duplication
            if (null !== $eventManager && $eventManager->hasListeners(Events::onSchemaIndexDefinition)) {
881 1
                $eventArgs = new SchemaIndexDefinitionEventArgs($data, $tableName, $this->_conn);
882 1
                $eventManager->dispatchEvent(Events::onSchemaIndexDefinition, $eventArgs);
883
884 1
                $defaultPrevented = $eventArgs->isDefaultPrevented();
885 1
                $index = $eventArgs->getIndex();
886
            }
887
888 21
            if ( ! $defaultPrevented) {
889 21
                $index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary'], $data['flags'], $data['options']);
890
            }
891
892 21
            if ($index) {
893 21
                $indexes[$indexKey] = $index;
894
            }
895
        }
896
897 31
        return $indexes;
898
    }
899
900
    /**
901
     * @param array $tables
902
     *
903
     * @return array
904
     */
905 14
    protected function _getPortableTablesList($tables)
906
    {
907 14
        $list = array();
908 14
        foreach ($tables as $value) {
909 13
            if ($value = $this->_getPortableTableDefinition($value)) {
910 13
                $list[] = $value;
911
            }
912
        }
913
914 14
        return $list;
915
    }
916
917
    /**
918
     * @param array $table
919
     *
920
     * @return array
921
     */
922
    protected function _getPortableTableDefinition($table)
923
    {
924
        return $table;
925
    }
926
927
    /**
928
     * @param array $users
929
     *
930
     * @return array
931
     */
932
    protected function _getPortableUsersList($users)
933
    {
934
        $list = array();
935
        foreach ($users as $value) {
936
            if ($value = $this->_getPortableUserDefinition($value)) {
937
                $list[] = $value;
938
            }
939
        }
940
941
        return $list;
942
    }
943
944
    /**
945
     * @param array $user
946
     *
947
     * @return mixed
948
     */
949
    protected function _getPortableUserDefinition($user)
950
    {
951
        return $user;
952
    }
953
954
    /**
955
     * @param array $views
956
     *
957
     * @return array
958
     */
959 1
    protected function _getPortableViewsList($views)
960
    {
961 1
        $list = array();
962 1
        foreach ($views as $value) {
963 1
            if ($view = $this->_getPortableViewDefinition($value)) {
964 1
                $viewName = strtolower($view->getQuotedName($this->_platform));
965 1
                $list[$viewName] = $view;
966
            }
967
        }
968
969 1
        return $list;
970
    }
971
972
    /**
973
     * @param array $view
974
     *
975
     * @return mixed
976
     */
977
    protected function _getPortableViewDefinition($view)
978
    {
979
        return false;
980
    }
981
982
    /**
983
     * @param array $tableForeignKeys
984
     *
985
     * @return array
986
     */
987
    protected function _getPortableTableForeignKeysList($tableForeignKeys)
988
    {
989
        $list = array();
990
        foreach ($tableForeignKeys as $value) {
991
            if ($value = $this->_getPortableTableForeignKeyDefinition($value)) {
992
                $list[] = $value;
993
            }
994
        }
995
996
        return $list;
997
    }
998
999
    /**
1000
     * @param array $tableForeignKey
1001
     *
1002
     * @return mixed
1003
     */
1004
    protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
1005
    {
1006
        return $tableForeignKey;
1007
    }
1008
1009
    /**
1010
     * @param array|string $sql
1011
     *
1012
     * @return void
1013
     */
1014 115
    protected function _execSql($sql)
1015
    {
1016 115
        foreach ((array) $sql as $query) {
1017 115
            $this->_conn->executeUpdate($query);
1018
        }
1019 83
    }
1020
1021
    /**
1022
     * Creates a schema instance for the current database.
1023
     *
1024
     * @return \Doctrine\DBAL\Schema\Schema
1025
     */
1026 4
    public function createSchema()
1027
    {
1028 4
        $namespaces = array();
1029
1030 4
        if ($this->_platform->supportsSchemas()) {
1031
            $namespaces = $this->listNamespaceNames();
1032
        }
1033
1034 4
        $sequences = array();
1035
1036 4
        if ($this->_platform->supportsSequences()) {
1037
            $sequences = $this->listSequences();
1038
        }
1039
1040 4
        $tables = $this->listTables();
1041
1042 4
        return new Schema($tables, $sequences, $this->createSchemaConfig(), $namespaces);
1043
    }
1044
1045
    /**
1046
     * Creates the configuration for this schema.
1047
     *
1048
     * @return \Doctrine\DBAL\Schema\SchemaConfig
1049
     */
1050 13
    public function createSchemaConfig()
1051
    {
1052 13
        $schemaConfig = new SchemaConfig();
1053 13
        $schemaConfig->setMaxIdentifierLength($this->_platform->getMaxIdentifierLength());
1054
1055 13
        $searchPaths = $this->getSchemaSearchPaths();
1056 13
        if (isset($searchPaths[0])) {
1057
            $schemaConfig->setName($searchPaths[0]);
1058
        }
1059
1060 13
        $params = $this->_conn->getParams();
1061 13
        if (isset($params['defaultTableOptions'])) {
1062
            $schemaConfig->setDefaultTableOptions($params['defaultTableOptions']);
1063
        }
1064
1065 13
        return $schemaConfig;
1066
    }
1067
1068
    /**
1069
     * The search path for namespaces in the currently connected database.
1070
     *
1071
     * The first entry is usually the default namespace in the Schema. All
1072
     * further namespaces contain tables/sequences which can also be addressed
1073
     * with a short, not full-qualified name.
1074
     *
1075
     * For databases that don't support subschema/namespaces this method
1076
     * returns the name of the currently connected database.
1077
     *
1078
     * @return array
1079
     */
1080 13
    public function getSchemaSearchPaths()
1081
    {
1082 13
        return array($this->_conn->getDatabase());
1083
    }
1084
1085
    /**
1086
     * Given a table comment this method tries to extract a typehint for Doctrine Type, or returns
1087
     * the type given as default.
1088
     *
1089
     * @param string $comment
1090
     * @param string $currentType
1091
     *
1092
     * @return string
1093
     */
1094 15
    public function extractDoctrineTypeFromComment($comment, $currentType)
1095
    {
1096 15
        if (preg_match("(\(DC2Type:([a-zA-Z0-9_]+)\))", $comment, $match)) {
1097 2
            $currentType = $match[1];
1098
        }
1099
1100 15
        return $currentType;
1101
    }
1102
1103
    /**
1104
     * @param string $comment
1105
     * @param string $type
1106
     *
1107
     * @return string
1108
     */
1109 3
    public function removeDoctrineTypeFromComment($comment, $type)
1110
    {
1111 3
        return str_replace('(DC2Type:'.$type.')', '', $comment);
1112
    }
1113
}
1114