DB2SchemaManager.php 7.34 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<?php
/*
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
Benjamin Eberlei's avatar
Benjamin Eberlei committed
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
Benjamin Morel's avatar
Benjamin Morel committed
18
 */
19 20 21 22

namespace Doctrine\DBAL\Schema;

/**
Benjamin Morel's avatar
Benjamin Morel committed
23
 * IBM Db2 Schema Manager.
24
 *
Benjamin Morel's avatar
Benjamin Morel committed
25 26 27
 * @link   www.doctrine-project.org
 * @since  1.0
 * @author Benjamin Eberlei <kontakt@beberlei.de>
28
 */
Benjamin Eberlei's avatar
Benjamin Eberlei committed
29
class DB2SchemaManager extends AbstractSchemaManager
30 31
{
    /**
Benjamin Morel's avatar
Benjamin Morel committed
32
     * {@inheritdoc}
33 34 35 36 37 38 39 40 41 42
     *
     * Apparently creator is the schema not the user who created it:
     * {@link http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.sqlref/db2z_sysibmsystablestable.htm}
     */
    public function listTableNames()
    {
        $sql = $this->_platform->getListTablesSQL();
        $sql .= " AND CREATOR = UPPER('".$this->_conn->getUsername()."')";

        $tables = $this->_conn->fetchAll($sql);
43

44 45 46 47
        return $this->_getPortableTablesList($tables);
    }

    /**
Benjamin Morel's avatar
Benjamin Morel committed
48
     * {@inheritdoc}
49 50 51 52 53 54 55 56 57 58
     */
    protected function _getPortableTableColumnDefinition($tableColumn)
    {
        $tableColumn = array_change_key_case($tableColumn, \CASE_LOWER);

        $length = null;
        $fixed = null;
        $unsigned = false;
        $scale = false;
        $precision = false;
59

60 61 62 63 64 65
        $default = null;

        if (null !== $tableColumn['default'] && 'NULL' != $tableColumn['default']) {
            $default = trim($tableColumn['default'], "'");
        }

66
        $type = $this->_platform->getDoctrineTypeMapping($tableColumn['typename']);
67

68 69 70 71 72
        if (isset($tableColumn['comment'])) {
            $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type);
            $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type);
        }

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
        switch (strtolower($tableColumn['typename'])) {
            case 'varchar':
                $length = $tableColumn['length'];
                $fixed = false;
                break;
            case 'character':
                $length = $tableColumn['length'];
                $fixed = true;
                break;
            case 'clob':
                $length = $tableColumn['length'];
                break;
            case 'decimal':
            case 'double':
            case 'real':
                $scale = $tableColumn['scale'];
                $precision = $tableColumn['length'];
                break;
        }

        $options = array(
            'length'        => $length,
95 96
            'unsigned'      => (bool) $unsigned,
            'fixed'         => (bool) $fixed,
97
            'default'       => $default,
98
            'autoincrement' => (boolean) $tableColumn['autoincrement'],
99 100 101
            'notnull'       => (bool) ($tableColumn['nulls'] == 'N'),
            'scale'         => null,
            'precision'     => null,
102 103 104
            'comment'       => isset($tableColumn['comment']) && $tableColumn['comment'] !== ''
                ? $tableColumn['comment']
                : null,
105 106 107 108 109 110 111 112 113 114 115
            'platformOptions' => array(),
        );

        if ($scale !== null && $precision !== null) {
            $options['scale'] = $scale;
            $options['precision'] = $precision;
        }

        return new Column($tableColumn['colname'], \Doctrine\DBAL\Types\Type::getType($type), $options);
    }

Benjamin Morel's avatar
Benjamin Morel committed
116 117 118
    /**
     * {@inheritdoc}
     */
119 120 121
    protected function _getPortableTablesList($tables)
    {
        $tableNames = array();
122
        foreach ($tables as $tableRow) {
123 124 125
            $tableRow = array_change_key_case($tableRow, \CASE_LOWER);
            $tableNames[] = $tableRow['name'];
        }
Benjamin Morel's avatar
Benjamin Morel committed
126

127 128 129
        return $tableNames;
    }

Benjamin Morel's avatar
Benjamin Morel committed
130 131 132
    /**
     * {@inheritdoc}
     */
133
    protected function _getPortableTableIndexesList($tableIndexRows, $tableName = null)
134
    {
135 136 137
        foreach ($tableIndexRows as &$tableIndexRow) {
            $tableIndexRow = array_change_key_case($tableIndexRow, \CASE_LOWER);
            $tableIndexRow['primary'] = (boolean) $tableIndexRow['primary'];
138 139
        }

140
        return parent::_getPortableTableIndexesList($tableIndexRows, $tableName);
141 142
    }

Benjamin Morel's avatar
Benjamin Morel committed
143 144 145
    /**
     * {@inheritdoc}
     */
146 147 148
    protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
    {
        return new ForeignKeyConstraint(
149 150 151 152 153
            $tableForeignKey['local_columns'],
            $tableForeignKey['foreign_table'],
            $tableForeignKey['foreign_columns'],
            $tableForeignKey['name'],
            $tableForeignKey['options']
154 155 156
        );
    }

157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
    /**
     * {@inheritdoc}
     */
    protected function _getPortableTableForeignKeysList($tableForeignKeys)
    {
        $foreignKeys = array();

        foreach ($tableForeignKeys as $tableForeignKey) {
            $tableForeignKey = array_change_key_case($tableForeignKey, \CASE_LOWER);

            if (!isset($foreignKeys[$tableForeignKey['index_name']])) {
                $foreignKeys[$tableForeignKey['index_name']] = array(
                    'local_columns'   => array($tableForeignKey['local_column']),
                    'foreign_table'   => $tableForeignKey['foreign_table'],
                    'foreign_columns' => array($tableForeignKey['foreign_column']),
                    'name'            => $tableForeignKey['index_name'],
                    'options'         => array(
                        'onUpdate' => $tableForeignKey['on_update'],
                        'onDelete' => $tableForeignKey['on_delete'],
                    )
                );
            } else {
                $foreignKeys[$tableForeignKey['index_name']]['local_columns'][] = $tableForeignKey['local_column'];
                $foreignKeys[$tableForeignKey['index_name']]['foreign_columns'][] = $tableForeignKey['foreign_column'];
            }
        }

        return parent::_getPortableTableForeignKeysList($foreignKeys);
    }

Benjamin Morel's avatar
Benjamin Morel committed
187 188 189
    /**
     * {@inheritdoc}
     */
190 191 192 193
    protected function _getPortableForeignKeyRuleDef($def)
    {
        if ($def == "C") {
            return "CASCADE";
Steve Müller's avatar
Steve Müller committed
194
        } elseif ($def == "N") {
195 196
            return "SET NULL";
        }
Benjamin Morel's avatar
Benjamin Morel committed
197

198 199 200
        return null;
    }

Benjamin Morel's avatar
Benjamin Morel committed
201 202 203
    /**
     * {@inheritdoc}
     */
204 205 206
    protected function _getPortableViewDefinition($view)
    {
        $view = array_change_key_case($view, \CASE_LOWER);
207 208 209 210 211 212 213 214
        // sadly this still segfaults on PDO_IBM, see http://pecl.php.net/bugs/bug.php?id=17199
        //$view['text'] = (is_resource($view['text']) ? stream_get_contents($view['text']) : $view['text']);
        if (!is_resource($view['text'])) {
            $pos = strpos($view['text'], ' AS ');
            $sql = substr($view['text'], $pos+4);
        } else {
            $sql = '';
        }
215 216 217

        return new View($view['name'], $sql);
    }
218
}