/**
  * {@inheritdoc}
  */
 protected function getSelectColumnsSQL()
 {
     if ($this->currentPersisterContext->selectColumnListSql !== null) {
         return $this->currentPersisterContext->selectColumnListSql;
     }
     $columnList[] = parent::getSelectColumnsSQL();
     $rootClass = $this->em->getClassMetadata($this->class->rootEntityName);
     $tableAlias = $this->getSQLTableAlias($rootClass->name);
     // Append discriminator column
     $discrColumn = $this->class->discriminatorColumn['name'];
     $discrColumnType = $this->class->discriminatorColumn['type'];
     $columnList[] = $tableAlias . '.' . $discrColumn;
     $resultColumnName = $this->platform->getSQLResultCasing($discrColumn);
     $this->currentPersisterContext->rsm->setDiscriminatorColumn('r', $resultColumnName);
     $this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumn, false, $discrColumnType);
     // Append subclass columns
     foreach ($this->class->subClasses as $subClassName) {
         $subClass = $this->em->getClassMetadata($subClassName);
         // Regular columns
         foreach ($subClass->fieldMappings as $fieldName => $mapping) {
             if (isset($mapping['inherited'])) {
                 continue;
             }
             $columnList[] = $this->getSelectColumnSQL($fieldName, $subClass);
         }
         // Foreign key columns
         foreach ($subClass->associationMappings as $assoc) {
             if (!$assoc['isOwningSide'] || !($assoc['type'] & ClassMetadata::TO_ONE) || isset($assoc['inherited'])) {
                 continue;
             }
             $className = isset($assoc['inherited']) ? $assoc['inherited'] : $this->class->name;
             $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
             foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
                 $columnList[] = $this->getSelectJoinColumnSQL($tableAlias, $srcColumn, $className, PersisterHelper::getTypeOfColumn($assoc['sourceToTargetKeyColumns'][$srcColumn], $targetClass, $this->em));
             }
         }
     }
     $this->currentPersisterContext->selectColumnListSql = implode(', ', $columnList);
     return $this->currentPersisterContext->selectColumnListSql;
 }
 /**
  * Ensure this method is never called. This persister overrides getSelectEntitiesSQL directly.
  *
  * @return string
  */
 protected function getSelectColumnsSQL()
 {
     // Create the column list fragment only once
     if ($this->currentPersisterContext->selectColumnListSql !== null) {
         return $this->currentPersisterContext->selectColumnListSql;
     }
     $columnList = array();
     $discrColumn = $this->class->discriminatorColumn['name'];
     $discrColumnType = $this->class->discriminatorColumn['type'];
     $baseTableAlias = $this->getSQLTableAlias($this->class->name);
     $resultColumnName = $this->platform->getSQLResultCasing($discrColumn);
     $this->currentPersisterContext->rsm->addEntityResult($this->class->name, 'r');
     $this->currentPersisterContext->rsm->setDiscriminatorColumn('r', $resultColumnName);
     $this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumn, false, $discrColumnType);
     // Add regular columns
     foreach ($this->class->fieldMappings as $fieldName => $mapping) {
         $class = isset($mapping['inherited']) ? $this->em->getClassMetadata($mapping['inherited']) : $this->class;
         $columnList[] = $this->getSelectColumnSQL($fieldName, $class);
     }
     // Add foreign key columns
     foreach ($this->class->associationMappings as $mapping) {
         if (!$mapping['isOwningSide'] || !($mapping['type'] & ClassMetadata::TO_ONE)) {
             continue;
         }
         $tableAlias = isset($mapping['inherited']) ? $this->getSQLTableAlias($mapping['inherited']) : $baseTableAlias;
         foreach ($mapping['targetToSourceKeyColumns'] as $srcColumn) {
             $className = isset($mapping['inherited']) ? $mapping['inherited'] : $this->class->name;
             $targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
             $columnList[] = $this->getSelectJoinColumnSQL($tableAlias, $srcColumn, $className, PersisterHelper::getTypeOfColumn($mapping['sourceToTargetKeyColumns'][$srcColumn], $targetClass, $this->em));
         }
     }
     // Add discriminator column (DO NOT ALIAS, see AbstractEntityInheritancePersister#processSQLResult).
     $tableAlias = $this->class->rootEntityName == $this->class->name ? $baseTableAlias : $this->getSQLTableAlias($this->class->rootEntityName);
     $columnList[] = $tableAlias . '.' . $discrColumn;
     // sub tables
     foreach ($this->class->subClasses as $subClassName) {
         $subClass = $this->em->getClassMetadata($subClassName);
         $tableAlias = $this->getSQLTableAlias($subClassName);
         // Add subclass columns
         foreach ($subClass->fieldMappings as $fieldName => $mapping) {
             if (isset($mapping['inherited'])) {
                 continue;
             }
             $columnList[] = $this->getSelectColumnSQL($fieldName, $subClass);
         }
         // Add join columns (foreign keys)
         foreach ($subClass->associationMappings as $mapping) {
             if (!$mapping['isOwningSide'] || !($mapping['type'] & ClassMetadata::TO_ONE) || isset($mapping['inherited'])) {
                 continue;
             }
             foreach ($mapping['targetToSourceKeyColumns'] as $srcColumn) {
                 $className = isset($mapping['inherited']) ? $mapping['inherited'] : $subClass->name;
                 $targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
                 $columnList[] = $this->getSelectJoinColumnSQL($tableAlias, $srcColumn, $className, PersisterHelper::getTypeOfColumn($mapping['sourceToTargetKeyColumns'][$srcColumn], $targetClass, $this->em));
             }
         }
     }
     $this->currentPersisterContext->selectColumnListSql = implode(', ', $columnList);
     return $this->currentPersisterContext->selectColumnListSql;
 }
 /**
  * Infers field types to be used by parameter type casting.
  *
  * @param string $field
  * @param mixed  $value
  *
  * @return array
  *
  * @throws \Doctrine\ORM\Query\QueryException
  */
 private function getTypes($field, $value, ClassMetadata $class)
 {
     $types = array();
     switch (true) {
         case isset($class->fieldMappings[$field]):
             $types = array_merge($types, PersisterHelper::getTypeOfField($field, $class, $this->em));
             break;
         case isset($class->associationMappings[$field]):
             $assoc = $class->associationMappings[$field];
             $class = $this->em->getClassMetadata($assoc['targetEntity']);
             if (!$assoc['isOwningSide']) {
                 $assoc = $class->associationMappings[$assoc['mappedBy']];
                 $class = $this->em->getClassMetadata($assoc['targetEntity']);
             }
             $columns = $assoc['type'] === ClassMetadata::MANY_TO_MANY ? $assoc['relationToTargetKeyColumns'] : $assoc['sourceToTargetKeyColumns'];
             foreach ($columns as $column) {
                 $types[] = PersisterHelper::getTypeOfColumn($column, $class, $this->em);
             }
             break;
         default:
             $types[] = null;
             break;
     }
     if (is_array($value)) {
         return array_map(function ($type) {
             return Type::getType($type)->getBindingType() + Connection::ARRAY_PARAM_OFFSET;
         }, $types);
     }
     return $types;
 }
 /**
  * Initializes a new <tt>MultiTableUpdateExecutor</tt>.
  *
  * Internal note: Any SQL construction and preparation takes place in the constructor for
  *                best performance. With a query cache the executor will be cached.
  *
  * @param \Doctrine\ORM\Query\AST\Node  $AST The root AST node of the DQL query.
  * @param \Doctrine\ORM\Query\SqlWalker $sqlWalker The walker used for SQL generation from the AST.
  */
 public function __construct(AST\Node $AST, $sqlWalker)
 {
     $em = $sqlWalker->getEntityManager();
     $conn = $em->getConnection();
     $platform = $conn->getDatabasePlatform();
     $quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
     $updateClause = $AST->updateClause;
     $primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName);
     $rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
     $updateItems = $updateClause->updateItems;
     $tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName());
     $idColumnNames = $rootClass->getIdentifierColumnNames();
     $idColumnList = implode(', ', $idColumnNames);
     // 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause()
     $sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $updateClause->aliasIdentificationVariable);
     $this->_insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')' . ' SELECT t0.' . implode(', t0.', $idColumnNames);
     $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $updateClause->aliasIdentificationVariable);
     $fromClause = new AST\FromClause([new AST\IdentificationVariableDeclaration($rangeDecl, null, [])]);
     $this->_insertSql .= $sqlWalker->walkFromClause($fromClause);
     // 2. Create ID subselect statement used in UPDATE ... WHERE ... IN (subselect)
     $idSubselect = 'SELECT ' . $idColumnList . ' FROM ' . $tempTable;
     // 3. Create and store UPDATE statements
     $classNames = array_merge($primaryClass->parentClasses, [$primaryClass->name], $primaryClass->subClasses);
     $i = -1;
     foreach (array_reverse($classNames) as $className) {
         $affected = false;
         $class = $em->getClassMetadata($className);
         $updateSql = 'UPDATE ' . $quoteStrategy->getTableName($class, $platform) . ' SET ';
         foreach ($updateItems as $updateItem) {
             $field = $updateItem->pathExpression->field;
             if (isset($class->fieldMappings[$field]) && !isset($class->fieldMappings[$field]['inherited']) || isset($class->associationMappings[$field]) && !isset($class->associationMappings[$field]['inherited'])) {
                 $newValue = $updateItem->newValue;
                 if (!$affected) {
                     $affected = true;
                     ++$i;
                 } else {
                     $updateSql .= ', ';
                 }
                 $updateSql .= $sqlWalker->walkUpdateItem($updateItem);
                 if ($newValue instanceof AST\InputParameter) {
                     $this->_sqlParameters[$i][] = $newValue->name;
                     ++$this->_numParametersInUpdateClause;
                 }
             }
         }
         if ($affected) {
             $this->_sqlStatements[$i] = $updateSql . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')';
         }
     }
     // Append WHERE clause to insertSql, if there is one.
     if ($AST->whereClause) {
         $this->_insertSql .= $sqlWalker->walkWhereClause($AST->whereClause);
     }
     // 4. Store DDL for temporary identifier table.
     $columnDefinitions = [];
     foreach ($idColumnNames as $idColumnName) {
         $columnDefinitions[$idColumnName] = ['notnull' => true, 'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em))];
     }
     $this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' . $platform->getColumnDeclarationListSQL($columnDefinitions) . ')';
     $this->_dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable);
 }
Пример #5
0
 /**
  * Delete Class Table Inheritance entities.
  * A temporary table is needed to keep IDs to be deleted in both parent and child class' tables.
  *
  * Thanks Steve Ebersole (Hibernate) for idea on how to tackle reliably this scenario, we owe him a beer! =)
  *
  * @param PersistentCollection $collection
  *
  * @return int
  *
  * @throws \Doctrine\DBAL\DBALException
  */
 private function deleteJoinedEntityCollection(PersistentCollection $collection)
 {
     $mapping = $collection->getMapping();
     $sourceClass = $this->em->getClassMetadata($mapping['sourceEntity']);
     $targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
     $rootClass = $this->em->getClassMetadata($targetClass->rootEntityName);
     // 1) Build temporary table DDL
     $tempTable = $this->platform->getTemporaryTableName($rootClass->getTemporaryIdTableName());
     $idColumnNames = $rootClass->getIdentifierColumnNames();
     $idColumnList = implode(', ', $idColumnNames);
     $columnDefinitions = [];
     foreach ($idColumnNames as $idColumnName) {
         $columnDefinitions[$idColumnName] = ['notnull' => true, 'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $this->em))];
     }
     $statement = $this->platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' . $this->platform->getColumnDeclarationListSQL($columnDefinitions) . ')';
     $this->conn->executeUpdate($statement);
     // 2) Build insert table records into temporary table
     $query = $this->em->createQuery(' SELECT t0.' . implode(', t0.', $rootClass->getIdentifierFieldNames()) . ' FROM ' . $targetClass->name . ' t0 WHERE t0.' . $mapping['mappedBy'] . ' = :owner')->setParameter('owner', $collection->getOwner());
     $statement = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ') ' . $query->getSQL();
     $parameters = array_values($sourceClass->getIdentifierValues($collection->getOwner()));
     $numDeleted = $this->conn->executeUpdate($statement, $parameters);
     // 3) Delete records on each table in the hierarchy
     $classNames = array_merge($targetClass->parentClasses, [$targetClass->name], $targetClass->subClasses);
     foreach (array_reverse($classNames) as $className) {
         $tableName = $this->quoteStrategy->getTableName($this->em->getClassMetadata($className), $this->platform);
         $statement = 'DELETE FROM ' . $tableName . ' WHERE (' . $idColumnList . ')' . ' IN (SELECT ' . $idColumnList . ' FROM ' . $tempTable . ')';
         $this->conn->executeUpdate($statement);
     }
     // 4) Drop temporary table
     $statement = $this->platform->getDropTemporaryTableSQL($tempTable);
     $this->conn->executeUpdate($statement);
     return $numDeleted;
 }
 /**
  * Adds the result set mapping of the results of native SQL queries to the result set.
  *
  * @param ClassMetadataInfo $class
  * @param string            $resultSetMappingName
  *
  * @return ResultSetMappingBuilder
  */
 public function addNamedNativeQueryResultSetMapping(ClassMetadataInfo $class, $resultSetMappingName)
 {
     $counter = 0;
     $resultMapping = $class->getSqlResultSetMapping($resultSetMappingName);
     $rootShortName = $class->reflClass->getShortName();
     $rootAlias = strtolower($rootShortName[0]) . $counter;
     if (isset($resultMapping['entities'])) {
         foreach ($resultMapping['entities'] as $key => $entityMapping) {
             $classMetadata = $this->em->getClassMetadata($entityMapping['entityClass']);
             if ($class->reflClass->name == $classMetadata->reflClass->name) {
                 $this->addEntityResult($classMetadata->name, $rootAlias);
                 $this->addNamedNativeQueryEntityResultMapping($classMetadata, $entityMapping, $rootAlias);
             } else {
                 $shortName = $classMetadata->reflClass->getShortName();
                 $joinAlias = strtolower($shortName[0]) . ++$counter;
                 $associations = $class->getAssociationsByTargetClass($classMetadata->name);
                 $this->addNamedNativeQueryEntityResultMapping($classMetadata, $entityMapping, $joinAlias);
                 foreach ($associations as $relation => $mapping) {
                     $this->addJoinedEntityResult($mapping['targetEntity'], $joinAlias, $rootAlias, $relation);
                 }
             }
         }
     }
     if (isset($resultMapping['columns'])) {
         foreach ($resultMapping['columns'] as $entityMapping) {
             $type = isset($class->fieldNames[$entityMapping['name']]) ? PersisterHelper::getTypeOfColumn($entityMapping['name'], $class, $this->em) : 'string';
             $this->addScalarResult($entityMapping['name'], $entityMapping['name'], $type);
         }
     }
     return $this;
 }
Пример #7
0
 /**
  * {@inheritdoc}
  */
 public function walkSelectClause($selectClause)
 {
     $sql = 'SELECT ' . ($selectClause->isDistinct ? 'DISTINCT ' : '');
     $sqlSelectExpressions = array_filter(array_map([$this, 'walkSelectExpression'], $selectClause->selectExpressions));
     if ($this->query->getHint(Query::HINT_INTERNAL_ITERATION) == true && $selectClause->isDistinct) {
         $this->query->setHint(self::HINT_DISTINCT, true);
     }
     $addMetaColumns = !$this->query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) && $this->query->getHydrationMode() == Query::HYDRATE_OBJECT || $this->query->getHydrationMode() != Query::HYDRATE_OBJECT && $this->query->getHint(Query::HINT_INCLUDE_META_COLUMNS);
     foreach ($this->selectedClasses as $selectedClass) {
         $class = $selectedClass['class'];
         $dqlAlias = $selectedClass['dqlAlias'];
         $resultAlias = $selectedClass['resultAlias'];
         // Register as entity or joined entity result
         if ($this->queryComponents[$dqlAlias]['relation'] === null) {
             $this->rsm->addEntityResult($class->name, $dqlAlias, $resultAlias);
         } else {
             $this->rsm->addJoinedEntityResult($class->name, $dqlAlias, $this->queryComponents[$dqlAlias]['parent'], $this->queryComponents[$dqlAlias]['relation']['fieldName']);
         }
         if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) {
             // Add discriminator columns to SQL
             $rootClass = $this->em->getClassMetadata($class->rootEntityName);
             $tblAlias = $this->getSQLTableAlias($rootClass->getTableName(), $dqlAlias);
             $discrColumn = $rootClass->discriminatorColumn;
             $columnAlias = $this->getSQLColumnAlias($discrColumn['name']);
             $sqlSelectExpressions[] = $tblAlias . '.' . $discrColumn['name'] . ' AS ' . $columnAlias;
             $this->rsm->setDiscriminatorColumn($dqlAlias, $columnAlias);
             $this->rsm->addMetaResult($dqlAlias, $columnAlias, $discrColumn['fieldName'], false, $discrColumn['type']);
         }
         // Add foreign key columns to SQL, if necessary
         if (!$addMetaColumns && !$class->containsForeignIdentifier) {
             continue;
         }
         // Add foreign key columns of class and also parent classes
         foreach ($class->associationMappings as $assoc) {
             if (!($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE)) {
                 continue;
             } else {
                 if (!$addMetaColumns && !isset($assoc['id'])) {
                     continue;
                 }
             }
             $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
             $isIdentifier = isset($assoc['id']) && $assoc['id'] === true;
             $owningClass = isset($assoc['inherited']) ? $this->em->getClassMetadata($assoc['inherited']) : $class;
             $sqlTableAlias = $this->getSQLTableAlias($owningClass->getTableName(), $dqlAlias);
             foreach ($assoc['joinColumns'] as $joinColumn) {
                 $columnName = $joinColumn['name'];
                 $columnAlias = $this->getSQLColumnAlias($columnName);
                 $columnType = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em);
                 $sqlSelectExpressions[] = $sqlTableAlias . '.' . $columnName . ' AS ' . $columnAlias;
                 $this->rsm->addMetaResult($dqlAlias, $columnAlias, $columnName, $isIdentifier, $columnType);
             }
         }
         // Add foreign key columns to SQL, if necessary
         if (!$addMetaColumns) {
             continue;
         }
         // Add foreign key columns of subclasses
         foreach ($class->subClasses as $subClassName) {
             $subClass = $this->em->getClassMetadata($subClassName);
             $sqlTableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias);
             foreach ($subClass->associationMappings as $assoc) {
                 // Skip if association is inherited
                 if (isset($assoc['inherited'])) {
                     continue;
                 }
                 if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
                     $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
                     foreach ($assoc['joinColumns'] as $joinColumn) {
                         $columnName = $joinColumn['name'];
                         $columnAlias = $this->getSQLColumnAlias($columnName);
                         $columnType = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em);
                         $sqlSelectExpressions[] = $sqlTableAlias . '.' . $columnName . ' AS ' . $columnAlias;
                         $this->rsm->addMetaResult($dqlAlias, $columnAlias, $columnName, $subClass->isIdentifier($columnName), $columnType);
                     }
                 }
             }
         }
     }
     $sql .= implode(', ', $sqlSelectExpressions);
     return $sql;
 }
 /**
  * Initializes a new <tt>MultiTableDeleteExecutor</tt>.
  *
  * Internal note: Any SQL construction and preparation takes place in the constructor for
  *                best performance. With a query cache the executor will be cached.
  *
  * @param \Doctrine\ORM\Query\AST\Node  $AST       The root AST node of the DQL query.
  * @param \Doctrine\ORM\Query\SqlWalker $sqlWalker The walker used for SQL generation from the AST.
  */
 public function __construct(AST\Node $AST, $sqlWalker)
 {
     $em = $sqlWalker->getEntityManager();
     $conn = $em->getConnection();
     $platform = $conn->getDatabasePlatform();
     $quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
     $primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName);
     $primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable;
     $rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
     $tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName());
     $idColumnNames = $rootClass->getIdentifierColumnNames();
     $idColumnList = implode(', ', $idColumnNames);
     // 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause()
     $sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $primaryDqlAlias);
     $this->_insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')' . ' SELECT t0.' . implode(', t0.', $idColumnNames);
     $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $primaryDqlAlias);
     $fromClause = new AST\FromClause([new AST\IdentificationVariableDeclaration($rangeDecl, null, [])]);
     $this->_insertSql .= $sqlWalker->walkFromClause($fromClause);
     // Append WHERE clause, if there is one.
     if ($AST->whereClause) {
         $this->_insertSql .= $sqlWalker->walkWhereClause($AST->whereClause);
     }
     // 2. Create ID subselect statement used in DELETE ... WHERE ... IN (subselect)
     $idSubselect = 'SELECT ' . $idColumnList . ' FROM ' . $tempTable;
     // 3. Create and store DELETE statements
     $classNames = array_merge($primaryClass->parentClasses, [$primaryClass->name], $primaryClass->subClasses);
     foreach (array_reverse($classNames) as $className) {
         $tableName = $quoteStrategy->getTableName($em->getClassMetadata($className), $platform);
         $this->_sqlStatements[] = 'DELETE FROM ' . $tableName . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')';
     }
     // 4. Store DDL for temporary identifier table.
     $columnDefinitions = [];
     foreach ($idColumnNames as $idColumnName) {
         $columnDefinitions[$idColumnName] = ['notnull' => true, 'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em))];
     }
     $this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' . $platform->getColumnDeclarationListSQL($columnDefinitions) . ')';
     $this->_dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable);
 }
Пример #9
0
 /**
  * @param \Doctrine\ORM\PersistentCollection $collection
  * @param object                             $element
  * @param boolean                            $addFilters Whether the filter SQL should be included or not.
  *
  * @return array ordered vector:
  *                - quoted join table name
  *                - where clauses to be added for filtering
  *                - parameters to be bound for filtering
  *                - types of the parameters to be bound for filtering
  */
 private function getJoinTableRestrictions(PersistentCollection $collection, $element, $addFilters)
 {
     $filterMapping = $collection->getMapping();
     $mapping = $filterMapping;
     if (!$mapping['isOwningSide']) {
         $sourceClass = $this->em->getClassMetadata($mapping['targetEntity']);
         $targetClass = $this->em->getClassMetadata($mapping['sourceEntity']);
         $sourceId = $this->uow->getEntityIdentifier($element);
         $targetId = $this->uow->getEntityIdentifier($collection->getOwner());
         $mapping = $sourceClass->associationMappings[$mapping['mappedBy']];
     } else {
         $sourceClass = $this->em->getClassMetadata($mapping['sourceEntity']);
         $targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
         $sourceId = $this->uow->getEntityIdentifier($collection->getOwner());
         $targetId = $this->uow->getEntityIdentifier($element);
     }
     $quotedJoinTable = $this->quoteStrategy->getJoinTableName($mapping, $sourceClass, $this->platform);
     $whereClauses = array();
     $params = array();
     $types = array();
     foreach ($mapping['joinTableColumns'] as $joinTableColumn) {
         $whereClauses[] = ($addFilters ? 't.' : '') . $joinTableColumn . ' = ?';
         if (isset($mapping['relationToTargetKeyColumns'][$joinTableColumn])) {
             $targetColumn = $mapping['relationToTargetKeyColumns'][$joinTableColumn];
             $params[] = $targetId[$targetClass->getFieldForColumn($targetColumn)];
             $types[] = PersisterHelper::getTypeOfColumn($targetColumn, $targetClass, $this->em);
             continue;
         }
         // relationToSourceKeyColumns
         $targetColumn = $mapping['relationToSourceKeyColumns'][$joinTableColumn];
         $params[] = $sourceId[$sourceClass->getFieldForColumn($targetColumn)];
         $types[] = PersisterHelper::getTypeOfColumn($targetColumn, $sourceClass, $this->em);
     }
     if ($addFilters) {
         $quotedJoinTable .= ' t';
         list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($filterMapping);
         if ($filterSql) {
             $quotedJoinTable .= ' ' . $joinTargetEntitySQL;
             $whereClauses[] = $filterSql;
         }
     }
     return array($quotedJoinTable, $whereClauses, $params, $types);
 }