vendor/doctrine/lib/Doctrine/ORM/Tools/SchemaTool.php
author ymh <ymh.work@gmail.com>
Sat, 24 Sep 2011 15:40:41 +0200
changeset 0 7f95f8617b0b
permissions -rwxr-xr-x
first commit
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
/*
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
 * This software consists of voluntary contributions made by many individuals
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
 * and is licensed under the LGPL. For more information, see
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
 * <http://www.doctrine-project.org>.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
namespace Doctrine\ORM\Tools;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
use Doctrine\ORM\ORMException,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
    Doctrine\DBAL\Types\Type,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
    Doctrine\ORM\EntityManager,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
    Doctrine\ORM\Mapping\ClassMetadata,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
    Doctrine\ORM\Internal\CommitOrderCalculator,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
    Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs,
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
    Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
/**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
 * The SchemaTool is a tool to create/drop/update database schemas based on
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
 * <tt>ClassMetadata</tt> class descriptors.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
 * @link    www.doctrine-project.org
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
 * @since   2.0
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
 * @version $Revision$
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
 * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
 * @author  Jonathan Wage <jonwage@gmail.com>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
 * @author  Roman Borschel <roman@code-factory.org>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
 * @author  Benjamin Eberlei <kontakt@beberlei.de>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
class SchemaTool
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
{
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
     * @var \Doctrine\ORM\EntityManager
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
    private $_em;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
    private $_platform;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
     * Initializes a new SchemaTool instance that uses the connection of the
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
     * provided EntityManager.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
     * @param Doctrine\ORM\EntityManager $em
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
    public function __construct(EntityManager $em)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
        $this->_em = $em;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
        $this->_platform = $em->getConnection()->getDatabasePlatform();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
     * Creates the database schema for the given array of ClassMetadata instances.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
     * @param array $classes
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
    public function createSchema(array $classes)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
        $createSchemaSql = $this->getCreateSchemaSql($classes);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
        $conn = $this->_em->getConnection();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
        foreach ($createSchemaSql as $sql) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
            $conn->executeQuery($sql);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
     * Gets the list of DDL statements that are required to create the database schema for
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
     * the given list of ClassMetadata instances.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
     * @param array $classes
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
     * @return array $sql The SQL statements needed to create the schema for the classes.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
    public function getCreateSchemaSql(array $classes)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
        $schema = $this->getSchemaFromMetadata($classes);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
        return $schema->toSql($this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
     * Some instances of ClassMetadata don't need to be processed in the SchemaTool context. This method detects them.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
     * 
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
     * @param ClassMetadata $class
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
     * @param array $processedClasses
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
     * @return bool
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
    private function processingNotRequired($class, array $processedClasses)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
        return (
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
            isset($processedClasses[$class->name]) ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
            $class->isMappedSuperclass ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
            ($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
        );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
     * From a given set of metadata classes this method creates a Schema instance.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
     * @param array $classes
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
     * @return Schema
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
    public function getSchemaFromMetadata(array $classes)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
        $processedClasses = array(); // Reminder for processed classes, used for hierarchies
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
        $sm = $this->_em->getConnection()->getSchemaManager();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
        $metadataSchemaConfig = $sm->createSchemaConfig();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
        $metadataSchemaConfig->setExplicitForeignKeyIndexes(false);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
        $schema = new \Doctrine\DBAL\Schema\Schema(array(), array(), $metadataSchemaConfig);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
        $evm = $this->_em->getEventManager();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
        foreach ($classes as $class) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
            if ($this->processingNotRequired($class, $processedClasses)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
                continue;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
            $table = $schema->createTable($class->getQuotedTableName($this->_platform));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
            $columns = array(); // table columns
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
            if ($class->isInheritanceTypeSingleTable()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
                $columns = $this->_gatherColumns($class, $table);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
                $this->_gatherRelationsSql($class, $table, $schema);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
                // Add the discriminator column
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
                $discrColumnDef = $this->_getDiscriminatorColumnDefinition($class, $table);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
                // Aggregate all the information from all classes in the hierarchy
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
                foreach ($class->parentClasses as $parentClassName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
                    // Parent class information is already contained in this class
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
                    $processedClasses[$parentClassName] = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
                foreach ($class->subClasses as $subClassName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
                    $subClass = $this->_em->getClassMetadata($subClassName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
                    $this->_gatherColumns($subClass, $table);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
                    $this->_gatherRelationsSql($subClass, $table, $schema);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
                    $processedClasses[$subClassName] = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
            } else if ($class->isInheritanceTypeJoined()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
                // Add all non-inherited fields as columns
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
                $pkColumns = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
                foreach ($class->fieldMappings as $fieldName => $mapping) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
                    if ( ! isset($mapping['inherited'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
                        $columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
                        $this->_gatherColumn($class, $mapping, $table);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
                        if ($class->isIdentifier($fieldName)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
                            $pkColumns[] = $columnName;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   166
                        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   167
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   168
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   169
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   170
                $this->_gatherRelationsSql($class, $table, $schema);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   171
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   172
                // Add the discriminator column only to the root table
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   173
                if ($class->name == $class->rootEntityName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   174
                    $discrColumnDef = $this->_getDiscriminatorColumnDefinition($class, $table);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   175
                } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   176
                    // Add an ID FK column to child tables
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   177
                    /* @var Doctrine\ORM\Mapping\ClassMetadata $class */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   178
                    $idMapping = $class->fieldMappings[$class->identifier[0]];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   179
                    $this->_gatherColumn($class, $idMapping, $table);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   180
                    $columnName = $class->getQuotedColumnName($class->identifier[0], $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   181
                    // TODO: This seems rather hackish, can we optimize it?
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   182
                    $table->getColumn($columnName)->setAutoincrement(false);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   183
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   184
                    $pkColumns[] = $columnName;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   185
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   186
                    // Add a FK constraint on the ID column
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   187
                    $table->addUnnamedForeignKeyConstraint(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   188
                        $this->_em->getClassMetadata($class->rootEntityName)->getQuotedTableName($this->_platform),
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   189
                        array($columnName), array($columnName), array('onDelete' => 'CASCADE')
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   190
                    );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   191
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   192
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   193
                $table->setPrimaryKey($pkColumns);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   194
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   195
            } else if ($class->isInheritanceTypeTablePerClass()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   196
                throw ORMException::notSupported();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   197
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   198
                $this->_gatherColumns($class, $table);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   199
                $this->_gatherRelationsSql($class, $table, $schema);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   200
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   201
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   202
            $pkColumns = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   203
            foreach ($class->identifier AS $identifierField) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   204
                if (isset($class->fieldMappings[$identifierField])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   205
                    $pkColumns[] = $class->getQuotedColumnName($identifierField, $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   206
                } else if (isset($class->associationMappings[$identifierField])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   207
                    /* @var $assoc \Doctrine\ORM\Mapping\OneToOne */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   208
                    $assoc = $class->associationMappings[$identifierField];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   209
                    foreach ($assoc['joinColumns'] AS $joinColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   210
                        $pkColumns[] = $joinColumn['name'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   211
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   212
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   213
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   214
            if (!$table->hasIndex('primary')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   215
                $table->setPrimaryKey($pkColumns);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   216
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   217
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   218
            if (isset($class->table['indexes'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   219
                foreach ($class->table['indexes'] AS $indexName => $indexData) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   220
                    $table->addIndex($indexData['columns'], $indexName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   221
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   222
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   223
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   224
            if (isset($class->table['uniqueConstraints'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   225
                foreach ($class->table['uniqueConstraints'] AS $indexName => $indexData) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   226
                    $table->addUniqueIndex($indexData['columns'], $indexName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   227
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   228
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   229
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   230
            $processedClasses[$class->name] = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   231
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   232
            if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   233
                $seqDef = $class->sequenceGeneratorDefinition;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   234
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   235
                if (!$schema->hasSequence($seqDef['sequenceName'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   236
                    $schema->createSequence(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   237
                        $seqDef['sequenceName'],
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   238
                        $seqDef['allocationSize'],
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   239
                        $seqDef['initialValue']
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   240
                    );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   241
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   242
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   243
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   244
            if ($evm->hasListeners(ToolEvents::postGenerateSchemaTable)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   245
                $evm->dispatchEvent(ToolEvents::postGenerateSchemaTable, new GenerateSchemaTableEventArgs($class, $schema, $table));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   246
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   247
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   248
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   249
        if ($evm->hasListeners(ToolEvents::postGenerateSchema)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   250
            $evm->dispatchEvent(ToolEvents::postGenerateSchema, new GenerateSchemaEventArgs($this->_em, $schema));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   251
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   252
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   253
        return $schema;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   254
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   255
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   256
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   257
     * Gets a portable column definition as required by the DBAL for the discriminator
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   258
     * column of a class.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   259
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   260
     * @param ClassMetadata $class
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   261
     * @return array The portable column definition of the discriminator column as required by
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   262
     *              the DBAL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   263
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   264
    private function _getDiscriminatorColumnDefinition($class, $table)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   265
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   266
        $discrColumn = $class->discriminatorColumn;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   267
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   268
        if (!isset($discrColumn['type']) || (strtolower($discrColumn['type']) == 'string' && $discrColumn['length'] === null)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   269
            $discrColumn['type'] = 'string';
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   270
            $discrColumn['length'] = 255;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   271
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   272
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   273
        $table->addColumn(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   274
            $discrColumn['name'],
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   275
            $discrColumn['type'],
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   276
            array('length' => $discrColumn['length'], 'notnull' => true)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   277
        );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   278
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   279
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   280
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   281
     * Gathers the column definitions as required by the DBAL of all field mappings
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   282
     * found in the given class.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   283
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   284
     * @param ClassMetadata $class
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   285
     * @param Table $table
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   286
     * @return array The list of portable column definitions as required by the DBAL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   287
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   288
    private function _gatherColumns($class, $table)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   289
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   290
        $columns = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   291
        $pkColumns = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   292
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   293
        foreach ($class->fieldMappings as $fieldName => $mapping) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   294
            if ($class->isInheritanceTypeSingleTable() && isset($mapping['inherited'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   295
                continue;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   296
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   297
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   298
            $column = $this->_gatherColumn($class, $mapping, $table);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   299
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   300
            if ($class->isIdentifier($mapping['fieldName'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   301
                $pkColumns[] = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   302
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   303
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   304
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   305
        // For now, this is a hack required for single table inheritence, since this method is called
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   306
        // twice by single table inheritence relations
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   307
        if(!$table->hasIndex('primary')) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   308
            //$table->setPrimaryKey($pkColumns);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   309
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   310
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   311
        return $columns;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   312
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   313
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   314
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   315
     * Creates a column definition as required by the DBAL from an ORM field mapping definition.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   316
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   317
     * @param ClassMetadata $class The class that owns the field mapping.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   318
     * @param array $mapping The field mapping.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   319
     * @param Table $table
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   320
     * @return array The portable column definition as required by the DBAL.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   321
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   322
    private function _gatherColumn($class, array $mapping, $table)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   323
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   324
        $columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   325
        $columnType = $mapping['type'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   326
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   327
        $options = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   328
        $options['length'] = isset($mapping['length']) ? $mapping['length'] : null;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   329
        $options['notnull'] = isset($mapping['nullable']) ? ! $mapping['nullable'] : true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   330
        if ($class->isInheritanceTypeSingleTable() && count($class->parentClasses) > 0) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   331
            $options['notnull'] = false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   332
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   333
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   334
        $options['platformOptions'] = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   335
        $options['platformOptions']['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   336
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   337
        if(strtolower($columnType) == 'string' && $options['length'] === null) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   338
            $options['length'] = 255;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   339
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   340
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   341
        if (isset($mapping['precision'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   342
            $options['precision'] = $mapping['precision'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   343
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   344
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   345
        if (isset($mapping['scale'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   346
            $options['scale'] = $mapping['scale'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   347
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   348
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   349
        if (isset($mapping['default'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   350
            $options['default'] = $mapping['default'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   351
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   352
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   353
        if (isset($mapping['columnDefinition'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   354
            $options['columnDefinition'] = $mapping['columnDefinition'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   355
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   356
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   357
        if ($class->isIdGeneratorIdentity() && $class->getIdentifierFieldNames() == array($mapping['fieldName'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   358
            $options['autoincrement'] = true;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   359
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   360
        if ($class->isInheritanceTypeJoined() && $class->name != $class->rootEntityName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   361
            $options['autoincrement'] = false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   362
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   363
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   364
        if ($table->hasColumn($columnName)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   365
            // required in some inheritance scenarios
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   366
            $table->changeColumn($columnName, $options);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   367
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   368
            $table->addColumn($columnName, $columnType, $options);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   369
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   370
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   371
        $isUnique = isset($mapping['unique']) ? $mapping['unique'] : false;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   372
        if ($isUnique) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   373
            $table->addUniqueIndex(array($columnName));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   374
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   375
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   376
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   377
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   378
     * Gathers the SQL for properly setting up the relations of the given class.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   379
     * This includes the SQL for foreign key constraints and join tables.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   380
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   381
     * @param ClassMetadata $class
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   382
     * @param \Doctrine\DBAL\Schema\Table $table
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   383
     * @param \Doctrine\DBAL\Schema\Schema $schema
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   384
     * @return void
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   385
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   386
    private function _gatherRelationsSql($class, $table, $schema)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   387
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   388
        foreach ($class->associationMappings as $fieldName => $mapping) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   389
            if (isset($mapping['inherited'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   390
                continue;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   391
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   392
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   393
            $foreignClass = $this->_em->getClassMetadata($mapping['targetEntity']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   394
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   395
            if ($mapping['type'] & ClassMetadata::TO_ONE && $mapping['isOwningSide']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   396
                $primaryKeyColumns = $uniqueConstraints = array(); // PK is unnecessary for this relation-type
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   397
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   398
                $this->_gatherRelationJoinColumns($mapping['joinColumns'], $table, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   399
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   400
                foreach($uniqueConstraints AS $indexName => $unique) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   401
                    $table->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   402
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   403
            } else if ($mapping['type'] == ClassMetadata::ONE_TO_MANY && $mapping['isOwningSide']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   404
                //... create join table, one-many through join table supported later
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   405
                throw ORMException::notSupported();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   406
            } else if ($mapping['type'] == ClassMetadata::MANY_TO_MANY && $mapping['isOwningSide']) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   407
                // create join table
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   408
                $joinTable = $mapping['joinTable'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   409
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   410
                $theJoinTable = $schema->createTable($foreignClass->getQuotedJoinTableName($mapping, $this->_platform));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   411
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   412
                $primaryKeyColumns = $uniqueConstraints = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   413
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   414
                // Build first FK constraint (relation table => source table)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   415
                $this->_gatherRelationJoinColumns($joinTable['joinColumns'], $theJoinTable, $class, $mapping, $primaryKeyColumns, $uniqueConstraints);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   416
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   417
                // Build second FK constraint (relation table => target table)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   418
                $this->_gatherRelationJoinColumns($joinTable['inverseJoinColumns'], $theJoinTable, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   419
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   420
                $theJoinTable->setPrimaryKey($primaryKeyColumns);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   421
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   422
                foreach($uniqueConstraints AS $indexName => $unique) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   423
                    $theJoinTable->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   424
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   425
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   426
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   427
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   428
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   429
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   430
     * Get the class metadata that is responsible for the definition of the referenced column name.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   431
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   432
     * Previously this was a simple task, but with DDC-117 this problem is actually recursive. If its
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   433
     * not a simple field, go through all identifier field names that are associations recursivly and
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   434
     * find that referenced column name.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   435
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   436
     * TODO: Is there any way to make this code more pleasing?
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   437
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   438
     * @param ClassMetadata $class
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   439
     * @param string $referencedColumnName
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   440
     * @return array(ClassMetadata, referencedFieldName)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   441
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   442
    private function getDefiningClass($class, $referencedColumnName)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   443
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   444
        $referencedFieldName = $class->getFieldName($referencedColumnName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   445
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   446
        if ($class->hasField($referencedFieldName)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   447
            return array($class, $referencedFieldName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   448
        } else if (in_array($referencedColumnName, $class->getIdentifierColumnNames())) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   449
            // it seems to be an entity as foreign key
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   450
            foreach ($class->getIdentifierFieldNames() AS $fieldName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   451
                if ($class->hasAssociation($fieldName) && $class->getSingleAssociationJoinColumnName($fieldName) == $referencedColumnName) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   452
                    return $this->getDefiningClass(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   453
                        $this->_em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']),
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   454
                        $class->getSingleAssociationReferencedJoinColumnName($fieldName)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   455
                    );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   456
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   457
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   458
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   459
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   460
        return null;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   461
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   462
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   463
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   464
     * Gather columns and fk constraints that are required for one part of relationship.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   465
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   466
     * @param array $joinColumns
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   467
     * @param \Doctrine\DBAL\Schema\Table $theJoinTable
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   468
     * @param ClassMetadata $class
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   469
     * @param array $mapping
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   470
     * @param array $primaryKeyColumns
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   471
     * @param array $uniqueConstraints
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   472
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   473
    private function _gatherRelationJoinColumns($joinColumns, $theJoinTable, $class, $mapping, &$primaryKeyColumns, &$uniqueConstraints)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   474
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   475
        $localColumns = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   476
        $foreignColumns = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   477
        $fkOptions = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   478
        $foreignTableName = $class->getQuotedTableName($this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   479
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   480
        foreach ($joinColumns as $joinColumn) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   481
            $columnName = $joinColumn['name'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   482
            list($definingClass, $referencedFieldName) = $this->getDefiningClass($class, $joinColumn['referencedColumnName']);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   483
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   484
            if (!$definingClass) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   485
                throw new \Doctrine\ORM\ORMException(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   486
                    "Column name `".$joinColumn['referencedColumnName']."` referenced for relation from ".
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   487
                    $mapping['sourceEntity'] . " towards ". $mapping['targetEntity'] . " does not exist."
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   488
                );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   489
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   490
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   491
            $primaryKeyColumns[] = $columnName;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   492
            $localColumns[] = $columnName;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   493
            $foreignColumns[] = $joinColumn['referencedColumnName'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   494
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   495
            if ( ! $theJoinTable->hasColumn($joinColumn['name'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   496
                // Only add the column to the table if it does not exist already.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   497
                // It might exist already if the foreign key is mapped into a regular
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   498
                // property as well.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   499
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   500
                $fieldMapping = $definingClass->getFieldMapping($referencedFieldName);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   501
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   502
                $columnDef = null;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   503
                if (isset($joinColumn['columnDefinition'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   504
                    $columnDef = $joinColumn['columnDefinition'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   505
                } else if (isset($fieldMapping['columnDefinition'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   506
                    $columnDef = $fieldMapping['columnDefinition'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   507
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   508
                $columnOptions = array('notnull' => false, 'columnDefinition' => $columnDef);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   509
                if (isset($joinColumn['nullable'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   510
                    $columnOptions['notnull'] = !$joinColumn['nullable'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   511
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   512
                if ($fieldMapping['type'] == "string" && isset($fieldMapping['length'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   513
                    $columnOptions['length'] = $fieldMapping['length'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   514
                } else if ($fieldMapping['type'] == "decimal") {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   515
                    $columnOptions['scale'] = $fieldMapping['scale'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   516
                    $columnOptions['precision'] = $fieldMapping['precision'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   517
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   518
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   519
                $theJoinTable->addColumn($columnName, $fieldMapping['type'], $columnOptions);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   520
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   521
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   522
            if (isset($joinColumn['unique']) && $joinColumn['unique'] == true) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   523
                $uniqueConstraints[] = array('columns' => array($columnName));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   524
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   525
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   526
            if (isset($joinColumn['onUpdate'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   527
                $fkOptions['onUpdate'] = $joinColumn['onUpdate'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   528
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   529
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   530
            if (isset($joinColumn['onDelete'])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   531
                $fkOptions['onDelete'] = $joinColumn['onDelete'];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   532
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   533
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   534
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   535
        $theJoinTable->addUnnamedForeignKeyConstraint(
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   536
            $foreignTableName, $localColumns, $foreignColumns, $fkOptions
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   537
        );
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   538
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   539
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   540
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   541
     * Drops the database schema for the given classes.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   542
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   543
     * In any way when an exception is thrown it is supressed since drop was
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   544
     * issued for all classes of the schema and some probably just don't exist.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   545
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   546
     * @param array $classes
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   547
     * @return void
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   548
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   549
    public function dropSchema(array $classes)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   550
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   551
        $dropSchemaSql = $this->getDropSchemaSQL($classes);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   552
        $conn = $this->_em->getConnection();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   553
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   554
        foreach ($dropSchemaSql as $sql) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   555
            try {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   556
                $conn->executeQuery($sql);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   557
            } catch(\Exception $e) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   558
                
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   559
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   560
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   561
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   562
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   563
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   564
     * Drops all elements in the database of the current connection.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   565
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   566
     * @return void
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   567
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   568
    public function dropDatabase()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   569
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   570
        $dropSchemaSql = $this->getDropDatabaseSQL();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   571
        $conn = $this->_em->getConnection();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   572
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   573
        foreach ($dropSchemaSql as $sql) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   574
            $conn->executeQuery($sql);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   575
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   576
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   577
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   578
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   579
     * Gets the SQL needed to drop the database schema for the connections database.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   580
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   581
     * @return array
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   582
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   583
    public function getDropDatabaseSQL()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   584
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   585
        $sm = $this->_em->getConnection()->getSchemaManager();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   586
        $schema = $sm->createSchema();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   587
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   588
        $visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   589
        /* @var $schema \Doctrine\DBAL\Schema\Schema */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   590
        $schema->visit($visitor);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   591
        return $visitor->getQueries();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   592
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   593
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   594
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   595
     * Get SQL to drop the tables defined by the passed classes.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   596
     * 
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   597
     * @param array $classes
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   598
     * @return array
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   599
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   600
    public function getDropSchemaSQL(array $classes)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   601
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   602
        $visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   603
        $schema = $this->getSchemaFromMetadata($classes);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   604
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   605
        $sm = $this->_em->getConnection()->getSchemaManager();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   606
        $fullSchema = $sm->createSchema();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   607
        foreach ($fullSchema->getTables() AS $table) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   608
            if (!$schema->hasTable($table->getName())) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   609
                foreach ($table->getForeignKeys() AS $foreignKey) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   610
                    /* @var $foreignKey \Doctrine\DBAL\Schema\ForeignKeyConstraint */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   611
                    if ($schema->hasTable($foreignKey->getForeignTableName())) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   612
                        $visitor->acceptForeignKey($table, $foreignKey);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   613
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   614
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   615
            } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   616
                $visitor->acceptTable($table);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   617
                foreach ($table->getForeignKeys() AS $foreignKey) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   618
                    $visitor->acceptForeignKey($table, $foreignKey);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   619
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   620
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   621
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   622
        
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   623
        if ($this->_platform->supportsSequences()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   624
            foreach ($schema->getSequences() AS $sequence) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   625
                $visitor->acceptSequence($sequence);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   626
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   627
            foreach ($schema->getTables() AS $table) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   628
                /* @var $sequence Table */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   629
                if ($table->hasPrimaryKey()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   630
                    $columns = $table->getPrimaryKey()->getColumns();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   631
                    if (count($columns) == 1) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   632
                        $checkSequence = $table->getName() . "_" . $columns[0] . "_seq";
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   633
                        if ($fullSchema->hasSequence($checkSequence)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   634
                            $visitor->acceptSequence($fullSchema->getSequence($checkSequence));
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   635
                        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   636
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   637
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   638
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   639
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   640
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   641
        return $visitor->getQueries();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   642
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   643
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   644
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   645
     * Updates the database schema of the given classes by comparing the ClassMetadata
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   646
     * instances to the current database schema that is inspected. If $saveMode is set
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   647
     * to true the command is executed in the Database, else SQL is returned.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   648
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   649
     * @param array $classes
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   650
     * @param boolean $saveMode
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   651
     * @return void
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   652
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   653
    public function updateSchema(array $classes, $saveMode=false)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   654
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   655
        $updateSchemaSql = $this->getUpdateSchemaSql($classes, $saveMode);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   656
        $conn = $this->_em->getConnection();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   657
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   658
        foreach ($updateSchemaSql as $sql) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   659
            $conn->executeQuery($sql);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   660
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   661
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   662
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   663
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   664
     * Gets the sequence of SQL statements that need to be performed in order
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   665
     * to bring the given class mappings in-synch with the relational schema.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   666
     * If $saveMode is set to true the command is executed in the Database, 
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   667
     * else SQL is returned.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   668
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   669
     * @param array $classes The classes to consider.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   670
     * @param boolean $saveMode True for writing to DB, false for SQL string
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   671
     * @return array The sequence of SQL statements.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   672
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   673
    public function getUpdateSchemaSql(array $classes, $saveMode=false)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   674
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   675
        $sm = $this->_em->getConnection()->getSchemaManager();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   676
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   677
        $fromSchema = $sm->createSchema();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   678
        $toSchema = $this->getSchemaFromMetadata($classes);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   679
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   680
        $comparator = new \Doctrine\DBAL\Schema\Comparator();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   681
        $schemaDiff = $comparator->compare($fromSchema, $toSchema);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   682
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   683
        if ($saveMode) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   684
            return $schemaDiff->toSaveSql($this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   685
        } else {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   686
            return $schemaDiff->toSql($this->_platform);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   687
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   688
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   689
}