DB2SchemaManager.php 6.93 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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
        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,
90 91
            'unsigned'      => (bool) $unsigned,
            'fixed'         => (bool) $fixed,
92
            'default'       => $default,
93
            'autoincrement' => (boolean) $tableColumn['autoincrement'],
94 95 96 97 98 99 100 101 102 103 104 105 106 107
            'notnull'       => (bool) ($tableColumn['nulls'] == 'N'),
            'scale'         => null,
            'precision'     => null,
            '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
108 109 110
    /**
     * {@inheritdoc}
     */
111 112 113
    protected function _getPortableTablesList($tables)
    {
        $tableNames = array();
114
        foreach ($tables as $tableRow) {
115 116 117
            $tableRow = array_change_key_case($tableRow, \CASE_LOWER);
            $tableNames[] = $tableRow['name'];
        }
Benjamin Morel's avatar
Benjamin Morel committed
118

119 120 121
        return $tableNames;
    }

Benjamin Morel's avatar
Benjamin Morel committed
122 123 124
    /**
     * {@inheritdoc}
     */
125
    protected function _getPortableTableIndexesList($tableIndexRows, $tableName = null)
126
    {
127 128 129
        foreach ($tableIndexRows as &$tableIndexRow) {
            $tableIndexRow = array_change_key_case($tableIndexRow, \CASE_LOWER);
            $tableIndexRow['primary'] = (boolean) $tableIndexRow['primary'];
130 131
        }

132
        return parent::_getPortableTableIndexesList($tableIndexRows, $tableName);
133 134
    }

Benjamin Morel's avatar
Benjamin Morel committed
135 136 137
    /**
     * {@inheritdoc}
     */
138 139 140
    protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
    {
        return new ForeignKeyConstraint(
141 142 143 144 145
            $tableForeignKey['local_columns'],
            $tableForeignKey['foreign_table'],
            $tableForeignKey['foreign_columns'],
            $tableForeignKey['name'],
            $tableForeignKey['options']
146 147 148
        );
    }

149 150 151 152 153 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
    /**
     * {@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
179 180 181
    /**
     * {@inheritdoc}
     */
182 183 184 185
    protected function _getPortableForeignKeyRuleDef($def)
    {
        if ($def == "C") {
            return "CASCADE";
Steve Müller's avatar
Steve Müller committed
186
        } elseif ($def == "N") {
187 188
            return "SET NULL";
        }
Benjamin Morel's avatar
Benjamin Morel committed
189

190 191 192
        return null;
    }

Benjamin Morel's avatar
Benjamin Morel committed
193 194 195
    /**
     * {@inheritdoc}
     */
196 197 198
    protected function _getPortableViewDefinition($view)
    {
        $view = array_change_key_case($view, \CASE_LOWER);
199 200 201 202 203 204 205 206
        // 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 = '';
        }
207 208 209

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