Completed
Pull Request — master (#3512)
by David
16:25
created

DB2SchemaManager::listTableDetails()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 12
ccs 7
cts 7
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Doctrine\DBAL\Schema;
4
5
use Doctrine\DBAL\Platforms\DB2Platform;
6
use Doctrine\DBAL\Types\Type;
7
use const CASE_LOWER;
8
use function array_change_key_case;
9
use function is_resource;
10
use function strpos;
11
use function strtolower;
12
use function substr;
13
use function trim;
14
15
/**
16
 * IBM Db2 Schema Manager.
17
 */
18
class DB2SchemaManager extends AbstractSchemaManager
19
{
20
    /**
21
     * {@inheritdoc}
22
     *
23
     * Apparently creator is the schema not the user who created it:
24
     * {@link http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.sqlref/db2z_sysibmsystablestable.htm}
25
     */
26 186
    public function listTableNames()
27
    {
28 186
        $sql  = $this->_platform->getListTablesSQL();
29 186
        $sql .= ' AND CREATOR = UPPER(' . $this->_conn->quote($this->_conn->getUsername()) . ')';
30
31 186
        $tables = $this->_conn->fetchAll($sql);
32
33 186
        return $this->filterAssetNames($this->_getPortableTablesList($tables));
34
    }
35
36
    /**
37
     * {@inheritdoc}
38
     */
39 49
    protected function _getPortableTableColumnDefinition($tableColumn)
40
    {
41 49
        $tableColumn = array_change_key_case($tableColumn, CASE_LOWER);
42
43 49
        $length    = null;
44 49
        $fixed     = null;
45 49
        $scale     = false;
46 49
        $precision = false;
47
48 49
        $default = null;
49
50 49
        if ($tableColumn['default'] !== null && $tableColumn['default'] !== 'NULL') {
51 49
            $default = trim($tableColumn['default'], "'");
52
        }
53
54 49
        $type = $this->_platform->getDoctrineTypeMapping($tableColumn['typename']);
55
56 49
        if (isset($tableColumn['comment'])) {
57 48
            $type                   = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type);
58 48
            $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type);
59
        }
60
61 49
        switch (strtolower($tableColumn['typename'])) {
62
            case 'varchar':
63 46
                $length = $tableColumn['length'];
64 46
                $fixed  = false;
65 46
                break;
66
            case 'character':
67 46
                $length = $tableColumn['length'];
68 46
                $fixed  = true;
69 46
                break;
70
            case 'clob':
71 46
                $length = $tableColumn['length'];
72 46
                break;
73
            case 'decimal':
74
            case 'double':
75
            case 'real':
76 45
                $scale     = $tableColumn['scale'];
77 45
                $precision = $tableColumn['length'];
78 49
                break;
79
        }
80
81
        $options = [
82 49
            'length'        => $length,
83
            'unsigned'      => false,
84 49
            'fixed'         => (bool) $fixed,
85 49
            'default'       => $default,
86 49
            'autoincrement' => (bool) $tableColumn['autoincrement'],
87 49
            'notnull'       => (bool) ($tableColumn['nulls'] === 'N'),
88
            'scale'         => null,
89
            'precision'     => null,
90 49
            'comment'       => isset($tableColumn['comment']) && $tableColumn['comment'] !== ''
91 47
                ? $tableColumn['comment']
92
                : null,
93
            'platformOptions' => [],
94
        ];
95
96 49
        if ($scale !== null && $precision !== null) {
97 49
            $options['scale']     = $scale;
98 49
            $options['precision'] = $precision;
99
        }
100
101 49
        return new Column($tableColumn['colname'], Type::getType($type), $options);
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107 186
    protected function _getPortableTablesList($tables)
108
    {
109 186
        $tableNames = [];
110 186
        foreach ($tables as $tableRow) {
111 186
            $tableRow     = array_change_key_case($tableRow, CASE_LOWER);
112 186
            $tableNames[] = $tableRow['name'];
113
        }
114
115 186
        return $tableNames;
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121 49
    protected function _getPortableTableIndexesList($tableIndexRows, $tableName = null)
122
    {
123 49
        foreach ($tableIndexRows as &$tableIndexRow) {
124 46
            $tableIndexRow            = array_change_key_case($tableIndexRow, CASE_LOWER);
125 46
            $tableIndexRow['primary'] = (bool) $tableIndexRow['primary'];
126
        }
127
128 49
        return parent::_getPortableTableIndexesList($tableIndexRows, $tableName);
129
    }
130
131
    /**
132
     * {@inheritdoc}
133
     */
134 38
    protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
135
    {
136 38
        return new ForeignKeyConstraint(
137 38
            $tableForeignKey['local_columns'],
138 38
            $tableForeignKey['foreign_table'],
139 38
            $tableForeignKey['foreign_columns'],
140 38
            $tableForeignKey['name'],
141 38
            $tableForeignKey['options']
142
        );
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148 49
    protected function _getPortableTableForeignKeysList($tableForeignKeys)
149
    {
150 49
        $foreignKeys = [];
151
152 49
        foreach ($tableForeignKeys as $tableForeignKey) {
153 38
            $tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER);
154
155 38
            if (! isset($foreignKeys[$tableForeignKey['index_name']])) {
156 38
                $foreignKeys[$tableForeignKey['index_name']] = [
157 38
                    'local_columns'   => [$tableForeignKey['local_column']],
158 38
                    'foreign_table'   => $tableForeignKey['foreign_table'],
159 38
                    'foreign_columns' => [$tableForeignKey['foreign_column']],
160 38
                    'name'            => $tableForeignKey['index_name'],
161
                    'options'         => [
162 38
                        'onUpdate' => $tableForeignKey['on_update'],
163 38
                        'onDelete' => $tableForeignKey['on_delete'],
164
                    ],
165
                ];
166
            } else {
167 24
                $foreignKeys[$tableForeignKey['index_name']]['local_columns'][]   = $tableForeignKey['local_column'];
168 24
                $foreignKeys[$tableForeignKey['index_name']]['foreign_columns'][] = $tableForeignKey['foreign_column'];
169
            }
170
        }
171
172 49
        return parent::_getPortableTableForeignKeysList($foreignKeys);
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178
    protected function _getPortableForeignKeyRuleDef($def)
179
    {
180
        if ($def === 'C') {
181
            return 'CASCADE';
182
        }
183
184
        if ($def === 'N') {
185
            return 'SET NULL';
186
        }
187
188
        return null;
189
    }
190
191
    /**
192
     * {@inheritdoc}
193
     */
194 34
    protected function _getPortableViewDefinition($view)
195
    {
196 34
        $view = array_change_key_case($view, CASE_LOWER);
197
        // sadly this still segfaults on PDO_IBM, see http://pecl.php.net/bugs/bug.php?id=17199
198
        //$view['text'] = (is_resource($view['text']) ? stream_get_contents($view['text']) : $view['text']);
199 34
        if (! is_resource($view['text'])) {
200 34
            $pos = strpos($view['text'], ' AS ');
201 34
            $sql = substr($view['text'], $pos+4);
202
        } else {
203
            $sql = '';
204
        }
205
206 34
        return new View($view['name'], $sql);
207
    }
208
209 49
    public function listTableDetails($tableName) : Table
210
    {
211 49
        $table = parent::listTableDetails($tableName);
212
213
        /** @var DB2Platform $platform */
214 49
        $platform = $this->_platform;
215 49
        $sql      = $platform->getListTableCommentsSQL($tableName);
216
217 49
        $tableOptions = $this->_conn->fetchAssoc($sql);
218 49
        $table->addOption('comment', $tableOptions['REMARKS']);
219
220 49
        return $table;
221
    }
222
}
223