vendor/doctrine/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.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.doctrine-project.org>.
       
    20  */
       
    21 
       
    22 namespace Doctrine\ORM\Tools;
       
    23 
       
    24 use Doctrine\ORM\Mapping\ClassMetadataInfo,
       
    25     Doctrine\ORM\Tools\Export\Driver\AbstractExporter,
       
    26     Doctrine\Common\Util\Inflector;
       
    27 
       
    28 /**
       
    29  * Class to help with converting Doctrine 1 schema files to Doctrine 2 mapping files
       
    30  *
       
    31  * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
       
    32  * @link    www.doctrine-project.org
       
    33  * @since   2.0
       
    34  * @version $Revision$
       
    35  * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
       
    36  * @author  Jonathan Wage <jonwage@gmail.com>
       
    37  * @author  Roman Borschel <roman@code-factory.org>
       
    38  */
       
    39 class ConvertDoctrine1Schema
       
    40 {
       
    41     private $_legacyTypeMap = array(
       
    42         // TODO: This list may need to be updated
       
    43         'clob' => 'text',
       
    44         'timestamp' => 'datetime',
       
    45         'enum' => 'string'
       
    46     );
       
    47 
       
    48     /**
       
    49      * Constructor passes the directory or array of directories
       
    50      * to convert the Doctrine 1 schema files from
       
    51      *
       
    52      * @param array $from
       
    53      * @author Jonathan Wage
       
    54      */
       
    55     public function __construct($from)
       
    56     {
       
    57         $this->_from = (array) $from;
       
    58     }
       
    59 
       
    60     /**
       
    61      * Get an array of ClassMetadataInfo instances from the passed
       
    62      * Doctrine 1 schema
       
    63      *
       
    64      * @return array $metadatas  An array of ClassMetadataInfo instances
       
    65      */
       
    66     public function getMetadata()
       
    67     {
       
    68         $schema = array();
       
    69         foreach ($this->_from as $path) {
       
    70             if (is_dir($path)) {
       
    71                 $files = glob($path . '/*.yml');
       
    72                 foreach ($files as $file) {
       
    73                     $schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($file));
       
    74                 }
       
    75             } else {
       
    76                 $schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($path));
       
    77             }
       
    78         }
       
    79 
       
    80         $metadatas = array();
       
    81         foreach ($schema as $className => $mappingInformation) {
       
    82             $metadatas[] = $this->_convertToClassMetadataInfo($className, $mappingInformation);
       
    83         }
       
    84 
       
    85         return $metadatas;
       
    86     }
       
    87 
       
    88     private function _convertToClassMetadataInfo($className, $mappingInformation)
       
    89     {
       
    90         $metadata = new ClassMetadataInfo($className);
       
    91 
       
    92         $this->_convertTableName($className, $mappingInformation, $metadata);
       
    93         $this->_convertColumns($className, $mappingInformation, $metadata);
       
    94         $this->_convertIndexes($className, $mappingInformation, $metadata);
       
    95         $this->_convertRelations($className, $mappingInformation, $metadata);
       
    96 
       
    97         return $metadata;
       
    98     }
       
    99 
       
   100     private function _convertTableName($className, array $model, ClassMetadataInfo $metadata)
       
   101     {
       
   102         if (isset($model['tableName']) && $model['tableName']) {
       
   103             $e = explode('.', $model['tableName']);
       
   104             if (count($e) > 1) {
       
   105                 $metadata->table['schema'] = $e[0];
       
   106                 $metadata->table['name'] = $e[1];
       
   107             } else {
       
   108                 $metadata->table['name'] = $e[0];
       
   109             }
       
   110         }
       
   111     }
       
   112 
       
   113     private function _convertColumns($className, array $model, ClassMetadataInfo $metadata)
       
   114     {
       
   115         $id = false;
       
   116 
       
   117         if (isset($model['columns']) && $model['columns']) {
       
   118             foreach ($model['columns'] as $name => $column) {
       
   119                 $fieldMapping = $this->_convertColumn($className, $name, $column, $metadata);
       
   120 
       
   121                 if (isset($fieldMapping['id']) && $fieldMapping['id']) {
       
   122                     $id = true;
       
   123                 }
       
   124             }
       
   125         }
       
   126 
       
   127         if ( ! $id) {
       
   128             $fieldMapping = array(
       
   129                 'fieldName' => 'id',
       
   130                 'columnName' => 'id',
       
   131                 'type' => 'integer',
       
   132                 'id' => true
       
   133             );
       
   134             $metadata->mapField($fieldMapping);
       
   135             $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
       
   136         }
       
   137     }
       
   138 
       
   139     private function _convertColumn($className, $name, $column, ClassMetadataInfo $metadata)
       
   140     {
       
   141         if (is_string($column)) {
       
   142             $string = $column;
       
   143             $column = array();
       
   144             $column['type'] = $string;
       
   145         }
       
   146         if ( ! isset($column['name'])) {
       
   147             $column['name'] = $name;
       
   148         }
       
   149         // check if a column alias was used (column_name as field_name)
       
   150         if (preg_match("/(\w+)\sas\s(\w+)/i", $column['name'], $matches)) {
       
   151             $name = $matches[1];
       
   152             $column['name'] = $name;
       
   153             $column['alias'] = $matches[2];
       
   154         }
       
   155         if (preg_match("/([a-zA-Z]+)\(([0-9]+)\)/", $column['type'], $matches)) {
       
   156             $column['type'] = $matches[1];
       
   157             $column['length'] = $matches[2];
       
   158         }
       
   159         $column['type'] = strtolower($column['type']);
       
   160         // check if legacy column type (1.x) needs to be mapped to a 2.0 one
       
   161         if (isset($this->_legacyTypeMap[$column['type']])) {
       
   162             $column['type'] = $this->_legacyTypeMap[$column['type']];
       
   163         }
       
   164         if ( ! \Doctrine\DBAL\Types\Type::hasType($column['type'])) {
       
   165             throw ToolsException::couldNotMapDoctrine1Type($column['type']);
       
   166         }
       
   167 
       
   168         $fieldMapping = array();
       
   169         if (isset($column['primary'])) {
       
   170             $fieldMapping['id'] = true;
       
   171         }
       
   172         $fieldMapping['fieldName'] = isset($column['alias']) ? $column['alias'] : $name;
       
   173         $fieldMapping['columnName'] = $column['name'];
       
   174         $fieldMapping['type'] = $column['type'];
       
   175         if (isset($column['length'])) {
       
   176             $fieldMapping['length'] = $column['length'];
       
   177         }
       
   178         $allowed = array('precision', 'scale', 'unique', 'options', 'notnull', 'version');
       
   179         foreach ($column as $key => $value) {
       
   180             if (in_array($key, $allowed)) {
       
   181                 $fieldMapping[$key] = $value;
       
   182             }
       
   183         }
       
   184 
       
   185         $metadata->mapField($fieldMapping);
       
   186 
       
   187         if (isset($column['autoincrement'])) {
       
   188             $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
       
   189         } else if (isset($column['sequence'])) {
       
   190             $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
       
   191             $definition = array(
       
   192                 'sequenceName' => is_array($column['sequence']) ? $column['sequence']['name']:$column['sequence']
       
   193             );
       
   194             if (isset($column['sequence']['size'])) {
       
   195                 $definition['allocationSize'] = $column['sequence']['size'];
       
   196             }
       
   197             if (isset($column['sequence']['value'])) {
       
   198                 $definition['initialValue'] = $column['sequence']['value'];
       
   199             }
       
   200             $metadata->setSequenceGeneratorDefinition($definition);
       
   201         }
       
   202         return $fieldMapping;
       
   203     }
       
   204 
       
   205     private function _convertIndexes($className, array $model, ClassMetadataInfo $metadata)
       
   206     {
       
   207         if (isset($model['indexes']) && $model['indexes']) {
       
   208             foreach ($model['indexes'] as $name => $index) {
       
   209                 $type = (isset($index['type']) && $index['type'] == 'unique')
       
   210                     ? 'uniqueConstraints' : 'indexes';
       
   211 
       
   212                 $metadata->table[$type][$name] = array(
       
   213                     'columns' => $index['fields']
       
   214                 );
       
   215             }
       
   216         }
       
   217     }
       
   218 
       
   219     private function _convertRelations($className, array $model, ClassMetadataInfo $metadata)
       
   220     {
       
   221         if (isset($model['relations']) && $model['relations']) {
       
   222             foreach ($model['relations'] as $name => $relation) {
       
   223                 if ( ! isset($relation['alias'])) {
       
   224                     $relation['alias'] = $name;
       
   225                 }
       
   226                 if ( ! isset($relation['class'])) {
       
   227                     $relation['class'] = $name;
       
   228                 }
       
   229                 if ( ! isset($relation['local'])) {
       
   230                     $relation['local'] = Inflector::tableize($relation['class']);
       
   231                 }
       
   232                 if ( ! isset($relation['foreign'])) {
       
   233                     $relation['foreign'] = 'id';
       
   234                 }
       
   235                 if ( ! isset($relation['foreignAlias'])) {
       
   236                     $relation['foreignAlias'] = $className;
       
   237                 }
       
   238 
       
   239                 if (isset($relation['refClass'])) {
       
   240                     $type = 'many';
       
   241                     $foreignType = 'many';
       
   242                     $joinColumns = array();
       
   243                 } else {
       
   244                     $type = isset($relation['type']) ? $relation['type'] : 'one';
       
   245                     $foreignType = isset($relation['foreignType']) ? $relation['foreignType'] : 'many';
       
   246                     $joinColumns = array(
       
   247                         array(
       
   248                             'name' => $relation['local'],
       
   249                             'referencedColumnName' => $relation['foreign'],
       
   250                             'onDelete' => isset($relation['onDelete']) ? $relation['onDelete'] : null,
       
   251                             'onUpdate' => isset($relation['onUpdate']) ? $relation['onUpdate'] : null,
       
   252                         )
       
   253                     );
       
   254                 }
       
   255 
       
   256                 if ($type == 'one' && $foreignType == 'one') {
       
   257                     $method = 'mapOneToOne';
       
   258                 } else if ($type == 'many' && $foreignType == 'many') {
       
   259                     $method = 'mapManyToMany';
       
   260                 } else {
       
   261                     $method = 'mapOneToMany';
       
   262                 }
       
   263 
       
   264                 $associationMapping = array();
       
   265                 $associationMapping['fieldName'] = $relation['alias'];
       
   266                 $associationMapping['targetEntity'] = $relation['class'];
       
   267                 $associationMapping['mappedBy'] = $relation['foreignAlias'];
       
   268                 $associationMapping['joinColumns'] = $joinColumns;
       
   269 
       
   270                 $metadata->$method($associationMapping);
       
   271             }
       
   272         }
       
   273     }
       
   274 }