vendor/doctrine-dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 /*
       
     3  *  $Id$
       
     4  *
       
     5  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
     6  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
     7  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
     8  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
     9  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    10  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    11  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    12  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    13  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    14  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    15  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    16  *
       
    17  * This software consists of voluntary contributions made by many individuals
       
    18  * and is licensed under the LGPL. For more information, see
       
    19  * <http://www.phpdoctrine.org>.
       
    20  */
       
    21 
       
    22 namespace Doctrine\DBAL\Schema;
       
    23 
       
    24 /**
       
    25  * Oracle Schema Manager
       
    26  *
       
    27  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
       
    28  * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
       
    29  * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
       
    30  * @author      Benjamin Eberlei <kontakt@beberlei.de>
       
    31  * @version     $Revision$
       
    32  * @since       2.0
       
    33  */
       
    34 class OracleSchemaManager extends AbstractSchemaManager
       
    35 {
       
    36     protected function _getPortableViewDefinition($view)
       
    37     {
       
    38         $view = \array_change_key_case($view, CASE_LOWER);
       
    39 
       
    40         return new View($view['view_name'], $view['text']);
       
    41     }
       
    42 
       
    43     protected function _getPortableUserDefinition($user)
       
    44     {
       
    45         $user = \array_change_key_case($user, CASE_LOWER);
       
    46 
       
    47         return array(
       
    48             'user' => $user['username'],
       
    49         );
       
    50     }
       
    51 
       
    52     protected function _getPortableTableDefinition($table)
       
    53     {
       
    54         $table = \array_change_key_case($table, CASE_LOWER);
       
    55 
       
    56         return $table['table_name'];
       
    57     }
       
    58 
       
    59     /**
       
    60      * @license New BSD License
       
    61      * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
       
    62      * @param  array $tableIndexes
       
    63      * @param  string $tableName
       
    64      * @return array
       
    65      */
       
    66     protected function _getPortableTableIndexesList($tableIndexes, $tableName=null)
       
    67     {
       
    68         $indexBuffer = array();
       
    69         foreach ( $tableIndexes as $tableIndex ) {
       
    70             $tableIndex = \array_change_key_case($tableIndex, CASE_LOWER);
       
    71 
       
    72             $keyName = strtolower($tableIndex['name']);
       
    73 
       
    74             if ( strtolower($tableIndex['is_primary']) == "p" ) {
       
    75                 $keyName = 'primary';
       
    76                 $buffer['primary'] = true;
       
    77                 $buffer['non_unique'] = false;
       
    78             } else {
       
    79                 $buffer['primary'] = false;
       
    80                 $buffer['non_unique'] = ( $tableIndex['is_unique'] == 0 ) ? true : false;
       
    81             }
       
    82             $buffer['key_name'] = $keyName;
       
    83             $buffer['column_name'] = $tableIndex['column_name'];
       
    84             $indexBuffer[] = $buffer;
       
    85         }
       
    86         return parent::_getPortableTableIndexesList($indexBuffer, $tableName);
       
    87     }
       
    88 
       
    89     protected function _getPortableTableColumnDefinition($tableColumn)
       
    90     {
       
    91         $tableColumn = \array_change_key_case($tableColumn, CASE_LOWER);
       
    92         
       
    93         $dbType = strtolower($tableColumn['data_type']);
       
    94         if(strpos($dbType, "timestamp(") === 0) {
       
    95             if (strpos($dbType, "WITH TIME ZONE")) {
       
    96                 $dbType = "timestamptz";
       
    97             } else {
       
    98                 $dbType = "timestamp";
       
    99             }
       
   100         }
       
   101 
       
   102         $type = array();
       
   103         $length = $unsigned = $fixed = null;
       
   104         if ( ! empty($tableColumn['data_length'])) {
       
   105             $length = $tableColumn['data_length'];
       
   106         }
       
   107 
       
   108         if ( ! isset($tableColumn['column_name'])) {
       
   109             $tableColumn['column_name'] = '';
       
   110         }
       
   111 
       
   112         if (stripos($tableColumn['data_default'], 'NULL') !== null) {
       
   113             $tableColumn['data_default'] = null;
       
   114         }
       
   115 
       
   116         $precision = null;
       
   117         $scale = null;
       
   118 
       
   119         $type = $this->_platform->getDoctrineTypeMapping($dbType);
       
   120         $type = $this->extractDoctrineTypeFromComment($tableColumn['comments'], $type);
       
   121         $tableColumn['comments'] = $this->removeDoctrineTypeFromComment($tableColumn['comments'], $type);
       
   122 
       
   123         switch ($dbType) {
       
   124             case 'number':
       
   125                 if ($tableColumn['data_precision'] == 20 && $tableColumn['data_scale'] == 0) {
       
   126                     $precision = 20;
       
   127                     $scale = 0;
       
   128                     $type = 'bigint';
       
   129                 } elseif ($tableColumn['data_precision'] == 5 && $tableColumn['data_scale'] == 0) {
       
   130                     $type = 'smallint';
       
   131                     $precision = 5;
       
   132                     $scale = 0;
       
   133                 } elseif ($tableColumn['data_precision'] == 1 && $tableColumn['data_scale'] == 0) {
       
   134                     $precision = 1;
       
   135                     $scale = 0;
       
   136                     $type = 'boolean';
       
   137                 } elseif ($tableColumn['data_scale'] > 0) {
       
   138                     $precision = $tableColumn['data_precision'];
       
   139                     $scale = $tableColumn['data_scale'];
       
   140                     $type = 'decimal';
       
   141                 }
       
   142                 $length = null;
       
   143                 break;
       
   144             case 'pls_integer':
       
   145             case 'binary_integer':
       
   146                 $length = null;
       
   147                 break;
       
   148             case 'varchar':
       
   149             case 'varchar2':
       
   150             case 'nvarchar2':
       
   151                 $length = $tableColumn['char_length'];
       
   152                 $fixed = false;
       
   153                 break;
       
   154             case 'char':
       
   155             case 'nchar':
       
   156                 $length = $tableColumn['char_length'];
       
   157                 $fixed = true;
       
   158                 break;
       
   159             case 'date':
       
   160             case 'timestamp':
       
   161                 $length = null;
       
   162                 break;
       
   163             case 'float':
       
   164                 $precision = $tableColumn['data_precision'];
       
   165                 $scale = $tableColumn['data_scale'];
       
   166                 $length = null;
       
   167                 break;
       
   168             case 'clob':
       
   169             case 'nclob':
       
   170                 $length = null;
       
   171                 break;
       
   172             case 'blob':
       
   173             case 'raw':
       
   174             case 'long raw':
       
   175             case 'bfile':
       
   176                 $length = null;
       
   177                 break;
       
   178             case 'rowid':
       
   179             case 'urowid':
       
   180             default:
       
   181                 $length = null;
       
   182         }
       
   183 
       
   184         $options = array(
       
   185             'notnull'    => (bool) ($tableColumn['nullable'] === 'N'),
       
   186             'fixed'      => (bool) $fixed,
       
   187             'unsigned'   => (bool) $unsigned,
       
   188             'default'    => $tableColumn['data_default'],
       
   189             'length'     => $length,
       
   190             'precision'  => $precision,
       
   191             'scale'      => $scale,
       
   192             'comment'       => (isset($tableColumn['comments'])) ? $tableColumn['comments'] : null,
       
   193             'platformDetails' => array(),
       
   194         );
       
   195 
       
   196         return new Column($tableColumn['column_name'], \Doctrine\DBAL\Types\Type::getType($type), $options);
       
   197     }
       
   198 
       
   199     protected function _getPortableTableForeignKeysList($tableForeignKeys)
       
   200     {
       
   201         $list = array();
       
   202         foreach ($tableForeignKeys as $key => $value) {
       
   203             $value = \array_change_key_case($value, CASE_LOWER);
       
   204             if (!isset($list[$value['constraint_name']])) {
       
   205                 if ($value['delete_rule'] == "NO ACTION") {
       
   206                     $value['delete_rule'] = null;
       
   207                 }
       
   208 
       
   209                 $list[$value['constraint_name']] = array(
       
   210                     'name' => $value['constraint_name'],
       
   211                     'local' => array(),
       
   212                     'foreign' => array(),
       
   213                     'foreignTable' => $value['references_table'],
       
   214                     'onDelete' => $value['delete_rule'],
       
   215                 );
       
   216             }
       
   217             $list[$value['constraint_name']]['local'][$value['position']] = $value['local_column'];
       
   218             $list[$value['constraint_name']]['foreign'][$value['position']] = $value['foreign_column'];
       
   219         }
       
   220 
       
   221         $result = array();
       
   222         foreach($list AS $constraint) {
       
   223             $result[] = new ForeignKeyConstraint(
       
   224                 array_values($constraint['local']), $constraint['foreignTable'],
       
   225                 array_values($constraint['foreign']),  $constraint['name'],
       
   226                 array('onDelete' => $constraint['onDelete'])
       
   227             );
       
   228         }
       
   229 
       
   230         return $result;
       
   231     }
       
   232 
       
   233     protected function _getPortableSequenceDefinition($sequence)
       
   234     {
       
   235         $sequence = \array_change_key_case($sequence, CASE_LOWER);
       
   236         return new Sequence($sequence['sequence_name'], $sequence['increment_by'], $sequence['min_value']);
       
   237     }
       
   238 
       
   239     protected function _getPortableFunctionDefinition($function)
       
   240     {
       
   241         $function = \array_change_key_case($function, CASE_LOWER);
       
   242         return $function['name'];
       
   243     }
       
   244 
       
   245     protected function _getPortableDatabaseDefinition($database)
       
   246     {
       
   247         $database = \array_change_key_case($database, CASE_LOWER);
       
   248         return $database['username'];
       
   249     }
       
   250 
       
   251     public function createDatabase($database = null)
       
   252     {
       
   253         if (is_null($database)) {
       
   254             $database = $this->_conn->getDatabase();
       
   255         }
       
   256 
       
   257         $params = $this->_conn->getParams();
       
   258         $username   = $database;
       
   259         $password   = $params['password'];
       
   260 
       
   261         $query  = 'CREATE USER ' . $username . ' IDENTIFIED BY ' . $password;
       
   262         $result = $this->_conn->executeUpdate($query);
       
   263 
       
   264         $query = 'GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE, CREATE TRIGGER TO ' . $username;
       
   265         $result = $this->_conn->executeUpdate($query);
       
   266 
       
   267         return true;
       
   268     }
       
   269 
       
   270     public function dropAutoincrement($table)
       
   271     {
       
   272         $sql = $this->_platform->getDropAutoincrementSql($table);
       
   273         foreach ($sql as $query) {
       
   274             $this->_conn->executeUpdate($query);
       
   275         }
       
   276 
       
   277         return true;
       
   278     }
       
   279 
       
   280     public function dropTable($name)
       
   281     {
       
   282         $this->dropAutoincrement($name);
       
   283 
       
   284         return parent::dropTable($name);
       
   285     }
       
   286 }