Doctrine\ORM\Tools\SchemaTool::getSchemaFromMetadata PHP Method

getSchemaFromMetadata() public method

From a given set of metadata classes this method creates a Schema instance.
public getSchemaFromMetadata ( array $classes ) : Schema
$classes array
return Schema
    public function getSchemaFromMetadata(array $classes)
    {
        $processedClasses = array(); // Reminder for processed classes, used for hierarchies

        $sm = $this->_em->getConnection()->getSchemaManager();
        $metadataSchemaConfig = $sm->createSchemaConfig();
        $metadataSchemaConfig->setExplicitForeignKeyIndexes(false);
        $schema = new \Doctrine\DBAL\Schema\Schema(array(), array(), $metadataSchemaConfig);

        $evm = $this->_em->getEventManager();

        foreach ($classes as $class) {
            if ($this->processingNotRequired($class, $processedClasses)) {
                continue;
            }

            $table = $schema->createTable($class->getQuotedTableName($this->_platform));

            // TODO: Remove
            /**if ($class->isIdGeneratorIdentity()) {
                $table->setIdGeneratorType(\Doctrine\DBAL\Schema\Table::ID_IDENTITY);
            } else if ($class->isIdGeneratorSequence()) {
                $table->setIdGeneratorType(\Doctrine\DBAL\Schema\Table::ID_SEQUENCE);
            }*/

            $columns = array(); // table columns

            if ($class->isInheritanceTypeSingleTable()) {
                $columns = $this->_gatherColumns($class, $table);
                $this->_gatherRelationsSql($class, $table, $schema);

                // Add the discriminator column
                $discrColumnDef = $this->_getDiscriminatorColumnDefinition($class, $table);

                // Aggregate all the information from all classes in the hierarchy
                foreach ($class->parentClasses as $parentClassName) {
                    // Parent class information is already contained in this class
                    $processedClasses[$parentClassName] = true;
                }

                foreach ($class->subClasses as $subClassName) {
                    $subClass = $this->_em->getClassMetadata($subClassName);
                    $this->_gatherColumns($subClass, $table);
                    $this->_gatherRelationsSql($subClass, $table, $schema);
                    $processedClasses[$subClassName] = true;
                }
            } else if ($class->isInheritanceTypeJoined()) {
                // Add all non-inherited fields as columns
                $pkColumns = array();
                foreach ($class->fieldMappings as $fieldName => $mapping) {
                    if ( ! isset($mapping['inherited'])) {
                        $columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
                        $this->_gatherColumn($class, $mapping, $table);

                        if ($class->isIdentifier($fieldName)) {
                            $pkColumns[] = $columnName;
                        }
                    }
                }

                $this->_gatherRelationsSql($class, $table, $schema);

                // Add the discriminator column only to the root table
                if ($class->name == $class->rootEntityName) {
                    $discrColumnDef = $this->_getDiscriminatorColumnDefinition($class, $table);
                } else {
                    // Add an ID FK column to child tables
                    /* @var Doctrine\ORM\Mapping\ClassMetadata $class */
                    $idMapping = $class->fieldMappings[$class->identifier[0]];
                    $this->_gatherColumn($class, $idMapping, $table);
                    $columnName = $class->getQuotedColumnName($class->identifier[0], $this->_platform);
                    // TODO: This seems rather hackish, can we optimize it?
                    $table->getColumn($class->identifier[0])->setAutoincrement(false);

                    $pkColumns[] = $columnName;
                    // TODO: REMOVE
                    /*if ($table->isIdGeneratorIdentity()) {
                       $table->setIdGeneratorType(\Doctrine\DBAL\Schema\Table::ID_NONE);
                    }*/

                    // Add a FK constraint on the ID column
                    $table->addUnnamedForeignKeyConstraint(
                        $this->_em->getClassMetadata($class->rootEntityName)->getTableName(),
                        array($columnName), array($columnName), array('onDelete' => 'CASCADE')
                    );
                }

                $table->setPrimaryKey($pkColumns);

            } else if ($class->isInheritanceTypeTablePerClass()) {
                throw ORMException::notSupported();
            } else {
                $this->_gatherColumns($class, $table);
                $this->_gatherRelationsSql($class, $table, $schema);
            }

            if (isset($class->table['indexes'])) {
                foreach ($class->table['indexes'] AS $indexName => $indexData) {
                    $table->addIndex($indexData['columns'], $indexName);
                }
            }

            if (isset($class->table['uniqueConstraints'])) {
                foreach ($class->table['uniqueConstraints'] AS $indexName => $indexData) {
                    $table->addUniqueIndex($indexData['columns'], $indexName);
                }
            }

            $processedClasses[$class->name] = true;

            if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) {
                $seqDef = $class->sequenceGeneratorDefinition;

                if (!$schema->hasSequence($seqDef['sequenceName'])) {
                    $schema->createSequence(
                        $seqDef['sequenceName'],
                        $seqDef['allocationSize'],
                        $seqDef['initialValue']
                    );
                }
            }

            if ($evm->hasListeners(ToolEvents::postGenerateSchemaTable)) {
                $evm->dispatchEvent(ToolEvents::postGenerateSchemaTable, new GenerateSchemaTableEventArgs($class, $schema, $table));
            }
        }

        if ($evm->hasListeners(ToolEvents::postGenerateSchema)) {
            $evm->dispatchEvent(ToolEvents::postGenerateSchema, new GenerateSchemaEventArgs($this->_em, $schema));
        }

        return $schema;
    }

Usage Example

 /**
  * Updates DB Schema.
  * @throws \Exception if there are no changes in entities
  */
 protected function updateDbSchema()
 {
     /**
      * @var $em \Doctrine\ORM\EntityManager
      */
     $em = $this->getContainer()->get('doctrine.orm.entity_manager');
     $event = $em->getEventManager();
     $sm = $em->getConnection()->getSchemaManager();
     $allMetadata = $em->getMetadataFactory()->getAllMetadata();
     $schemaTool = new SchemaTool($em);
     $entitiesMetadata = array($em->getClassMetadata(ApiUser::getClassName()), $em->getClassMetadata(DiamanteUser::getClassName()));
     $event->disableListeners();
     $currentSchema = $sm->createSchema();
     $schemaFromMetadata = $schemaTool->getSchemaFromMetadata($allMetadata);
     $entitiesSchema = $schemaTool->getSchemaFromMetadata($entitiesMetadata);
     $entitiesTables = $entitiesSchema->getTables();
     $entitiesTableName = array_keys($entitiesTables);
     $currentDiamanteSchema = $this->getTargetSchema($currentSchema, $entitiesTableName);
     $diamanteSchemaFromMetadata = $this->getTargetSchema($schemaFromMetadata, $entitiesTableName);
     $comparator = new Comparator();
     $diff = $comparator->compare($currentDiamanteSchema, $diamanteSchemaFromMetadata);
     $toUpdate = $diff->toSql($em->getConnection()->getDatabasePlatform());
     if (empty($toUpdate)) {
         throw new \Exception('No new updates found. Diamante Api Bundle is up to date!');
     }
     $conn = $em->getConnection();
     foreach ($toUpdate as $sql) {
         $conn->executeQuery($sql);
     }
 }
All Usage Examples Of Doctrine\ORM\Tools\SchemaTool::getSchemaFromMetadata