/**
  * @param ClassMetadata $metadata metadata
  *
  * @return ClassMetadata|null
  */
 public function findReferenceFor(ClassMetadata $metadata)
 {
     $table = $metadata->getTableName();
     $references = $this->getReferencesForTable($table);
     if (empty($references)) {
         return;
     }
     if ($metadata->isInheritanceTypeNone()) {
         if (count($references) > 1) {
             throw new Exception\UnsupportedException(sprintf('You use different inheritance type on table %s', $table));
         }
         return current($references);
     }
     if (false === $metadata->isInheritanceTypeSingleTable()) {
         throw new Exception\UnsupportedException('Only “single_table“ inheritance type is supported by Rezzza\\DoctrineSchemaMultiMapping at this moment.');
     }
     $discriminatorValue = $metadata->discriminatorValue;
     $discriminatorColumn = $metadata->discriminatorColumn;
     foreach ($references as $reference) {
         if ($discriminatorColumn != $reference->discriminatorColumn) {
             throw new \LogicException(sprintf('You have 2 tables with inherhitance Single Table with a different discriminatorColumn on table "%s"', $table));
         }
         if ($discriminatorValue == $reference->discriminatorValue) {
             return $reference;
         }
     }
 }
Exemple #2
0
 /**
  * Gathers the column definitions as required by the DBAL of all field mappings
  * found in the given class.
  *
  * @param ClassMetadata $class
  * @param Table $table
  * @return array The list of portable column definitions as required by the DBAL.
  */
 private function _gatherColumns($class, $table)
 {
     $columns = array();
     $pkColumns = array();
     foreach ($class->fieldMappings as $fieldName => $mapping) {
         if ($class->isInheritanceTypeSingleTable() && isset($mapping['inherited'])) {
             continue;
         }
         $column = $this->_gatherColumn($class, $mapping, $table);
         if ($class->isIdentifier($mapping['fieldName'])) {
             $pkColumns[] = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class, $this->platform);
         }
     }
     // For now, this is a hack required for single table inheritence, since this method is called
     // twice by single table inheritence relations
     if (!$table->hasIndex('primary')) {
         //$table->setPrimaryKey($pkColumns);
     }
     return $columns;
 }
 /**
  * @param ClassMetadata $class
  * @param array $entityData
  * @param string $revType
  */
 private function saveRevisionEntityData($class, $entityData, $revType)
 {
     $params = array($this->getRevisionId(), $revType);
     $types = array(\PDO::PARAM_INT, \PDO::PARAM_STR);
     $fields = array();
     foreach ($class->associationMappings as $field => $assoc) {
         if ($class->isInheritanceTypeJoined() && $class->isInheritedAssociation($field)) {
             continue;
         }
         if (($assoc['type'] & ClassMetadata::TO_ONE) > 0 && $assoc['isOwningSide']) {
             $data = isset($entityData[$field]) ? $entityData[$field] : null;
             $relatedId = false;
             if ($data !== null && $this->uow->isInIdentityMap($data)) {
                 $relatedId = $this->uow->getEntityIdentifier($data);
             }
             $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
             foreach ($assoc['sourceToTargetKeyColumns'] as $sourceColumn => $targetColumn) {
                 $fields[$sourceColumn] = true;
                 if ($data === null) {
                     $params[] = null;
                     $types[] = \PDO::PARAM_STR;
                 } else {
                     $params[] = $relatedId ? $relatedId[$targetClass->fieldNames[$targetColumn]] : null;
                     $types[] = $targetClass->getTypeOfColumn($targetColumn);
                 }
             }
         }
     }
     foreach ($class->fieldNames as $field) {
         if (array_key_exists($field, $fields)) {
             continue;
         }
         if ($class->isInheritanceTypeJoined() && $class->isInheritedField($field) && !$class->isIdentifier($field)) {
             continue;
         }
         $params[] = isset($entityData[$field]) ? $entityData[$field] : null;
         $types[] = $class->fieldMappings[$field]['type'];
     }
     if ($class->isInheritanceTypeSingleTable()) {
         $params[] = $class->discriminatorValue;
         $types[] = $class->discriminatorColumn['type'];
     } elseif ($class->isInheritanceTypeJoined() && $class->name == $class->rootEntityName) {
         $params[] = $entityData[$class->discriminatorColumn['name']];
         $types[] = $class->discriminatorColumn['type'];
     }
     if ($class->isInheritanceTypeJoined() && $class->name != $class->rootEntityName && count($class->parentClasses)) {
         if (!isset($entityData[$class->discriminatorColumn['name']])) {
             $entityData[$class->discriminatorColumn['name']] = $class->discriminatorValue;
         }
         $this->saveRevisionEntityData($this->em->getClassMetadata($class->parentClasses[0]), $entityData, $revType);
     }
     $this->conn->executeUpdate($this->getInsertRevisionSQL($class), $params, $types);
 }
 /**
  * Creates a column definition as required by the DBAL from an ORM field mapping definition.
  *
  * @param ClassMetadata $class The class that owns the field mapping.
  * @param array $mapping The field mapping.
  * @param Table $table
  * @return array The portable column definition as required by the DBAL.
  */
 private function _gatherColumn($class, array $mapping, $table)
 {
     $columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
     $columnType = $mapping['type'];
     $options = array();
     $options['length'] = isset($mapping['length']) ? $mapping['length'] : null;
     $options['notnull'] = isset($mapping['nullable']) ? !$mapping['nullable'] : true;
     if ($class->isInheritanceTypeSingleTable() && count($class->parentClasses) > 0) {
         $options['notnull'] = false;
     }
     $options['platformOptions'] = array();
     $options['platformOptions']['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false;
     if (strtolower($columnType) == 'string' && $options['length'] === null) {
         $options['length'] = 255;
     }
     if (isset($mapping['precision'])) {
         $options['precision'] = $mapping['precision'];
     }
     if (isset($mapping['scale'])) {
         $options['scale'] = $mapping['scale'];
     }
     if (isset($mapping['default'])) {
         $options['default'] = $mapping['default'];
     }
     if (isset($mapping['columnDefinition'])) {
         $options['columnDefinition'] = $mapping['columnDefinition'];
     }
     if ($class->isIdGeneratorIdentity() && $class->getIdentifierFieldNames() == array($mapping['fieldName'])) {
         $options['autoincrement'] = true;
     }
     if ($class->isInheritanceTypeJoined() && $class->name != $class->rootEntityName) {
         $options['autoincrement'] = false;
     }
     if ($table->hasColumn($columnName)) {
         // required in some inheritance scenarios
         $table->changeColumn($columnName, $options);
     } else {
         $table->addColumn($columnName, $columnType, $options);
     }
     $isUnique = isset($mapping['unique']) ? $mapping['unique'] : false;
     if ($isUnique) {
         $table->addUniqueIndex(array($columnName));
     }
 }
 /**
  * @param ClassMetadata $class
  * @return string
  * @throws \Doctrine\DBAL\DBALException
  */
 private function getInsertRevisionSQL($class)
 {
     if (!isset($this->insertRevisionSQL[$class->name])) {
         $placeholders = array('?', '?');
         $tableName = $this->config->getTablePrefix() . $class->table['name'] . $this->config->getTableSuffix();
         $sql = "INSERT INTO " . $tableName . " (" . $this->config->getRevisionFieldName() . ", " . $this->config->getRevisionTypeFieldName();
         $fields = array();
         foreach ($class->associationMappings as $field => $assoc) {
             if ($class->isInheritanceTypeJoined() && $class->isInheritedAssociation($field)) {
                 continue;
             }
             if (($assoc['type'] & ClassMetadata::TO_ONE) > 0 && $assoc['isOwningSide']) {
                 foreach ($assoc['targetToSourceKeyColumns'] as $sourceCol) {
                     $fields[$sourceCol] = true;
                     $sql .= ', ' . $sourceCol;
                     $placeholders[] = '?';
                 }
             }
         }
         foreach ($class->fieldNames as $field) {
             if (array_key_exists($field, $fields)) {
                 continue;
             }
             if ($class->isInheritanceTypeJoined() && $class->isInheritedField($field) && !$class->isIdentifier($field)) {
                 continue;
             }
             $type = Type::getType($class->fieldMappings[$field]['type']);
             $placeholders[] = !empty($class->fieldMappings[$field]['requireSQLConversion']) ? $type->convertToDatabaseValueSQL('?', $this->platform) : '?';
             $sql .= ', ' . $class->getQuotedColumnName($field, $this->platform);
         }
         if ($class->isInheritanceTypeJoined() && $class->rootEntityName == $class->name || $class->isInheritanceTypeSingleTable()) {
             $sql .= ', ' . $class->discriminatorColumn['name'];
             $placeholders[] = '?';
         }
         $sql .= ") VALUES (" . implode(", ", $placeholders) . ")";
         $this->insertRevisionSQL[$class->name] = $sql;
     }
     return $this->insertRevisionSQL[$class->name];
 }
 /**
  * Generates any static SQL strings for a class and stores them in the descriptor.
  *
  * @param ClassMetadata $class
  */
 private function _generateStaticSql($class)
 {
     // Generate INSERT SQL
     $columns = $values = array();
     if ($class->inheritanceType == ClassMetadata::INHERITANCE_TYPE_JOINED) {
         foreach ($class->reflFields as $name => $field) {
             if (isset($class->fieldMappings[$name]['inherited']) && !isset($class->fieldMappings[$name]['id']) || isset($class->inheritedAssociationFields[$name])) {
                 continue;
             }
             if (isset($class->associationMappings[$name])) {
                 $assoc = $class->associationMappings[$name];
                 if ($assoc->isOneToOne() && $assoc->isOwningSide) {
                     foreach ($assoc->targetToSourceKeyColumns as $sourceCol) {
                         $columns[] = $this->_targetPlatform->quoteIdentifier($sourceCol);
                         $values[] = '?';
                     }
                 }
             } else {
                 if ($class->name != $class->rootEntityName || !$class->isIdGeneratorIdentity() || $class->identifier[0] != $name) {
                     $columns[] = $this->_targetPlatform->quoteIdentifier($class->columnNames[$name]);
                     $values[] = '?';
                 }
             }
         }
     } else {
         foreach ($class->reflFields as $name => $field) {
             if (isset($class->associationMappings[$name])) {
                 $assoc = $class->associationMappings[$name];
                 if ($assoc->isOwningSide && $assoc->isOneToOne()) {
                     foreach ($assoc->targetToSourceKeyColumns as $sourceCol) {
                         $columns[] = $this->_targetPlatform->quoteIdentifier($sourceCol);
                         $values[] = '?';
                     }
                 }
             } else {
                 if ($class->generatorType != ClassMetadata::GENERATOR_TYPE_IDENTITY || $class->identifier[0] != $name) {
                     $columns[] = $this->_targetPlatform->quoteIdentifier($class->columnNames[$name]);
                     $values[] = '?';
                 }
             }
         }
     }
     if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined() && $class->name == $class->rootEntityName) {
         $columns[] = $class->discriminatorColumn['name'];
         $values[] = '?';
     }
     $class->insertSql = 'INSERT INTO ' . $this->_targetPlatform->quoteIdentifier($class->primaryTable['name']) . ' (' . implode(', ', $columns) . ') ' . 'VALUES (' . implode(', ', $values) . ')';
 }