/**
  * Dump the contents of the identity map into a stream.
  *
  * @param EntityManager $em
  * @return void
  */
 public function dumpIdentityMap(EntityManager $em)
 {
     $uow = $em->getUnitOfWork();
     $identityMap = $uow->getIdentityMap();
     $fh = fopen($this->file, "x+");
     if (count($identityMap) == 0) {
         fwrite($fh, "Flush Operation [" . $this->context . "] - Empty identity map.\n");
         return;
     }
     fwrite($fh, "Flush Operation [" . $this->context . "] - Dumping identity map:\n");
     foreach ($identityMap as $className => $map) {
         fwrite($fh, "Class: " . $className . "\n");
         foreach ($map as $idHash => $entity) {
             fwrite($fh, " Entity: " . $this->getIdString($entity, $uow) . " " . spl_object_hash($entity) . "\n");
             fwrite($fh, "  Associations:\n");
             $cm = $em->getClassMetadata($className);
             foreach ($cm->associationMappings as $field => $assoc) {
                 fwrite($fh, "   " . $field . " ");
                 $value = $cm->reflFields[$field]->getValue($entity);
                 if ($assoc['type'] & ClassMetadata::TO_ONE) {
                     if ($value === null) {
                         fwrite($fh, " NULL\n");
                     } else {
                         if ($value instanceof Proxy && !$value->__isInitialized__) {
                             fwrite($fh, "[PROXY] ");
                         }
                         fwrite($fh, $this->getIdString($value, $uow) . " " . spl_object_hash($value) . "\n");
                     }
                 } else {
                     $initialized = !$value instanceof PersistentCollection || $value->isInitialized();
                     if ($value === null) {
                         fwrite($fh, " NULL\n");
                     } else {
                         if ($initialized) {
                             fwrite($fh, "[INITIALIZED] " . $this->getType($value) . " " . count($value) . " elements\n");
                             foreach ($value as $obj) {
                                 fwrite($fh, "    " . $this->getIdString($obj, $uow) . " " . spl_object_hash($obj) . "\n");
                             }
                         } else {
                             fwrite($fh, "[PROXY] " . $this->getType($value) . " unknown element size\n");
                             foreach ($value->unwrap() as $obj) {
                                 fwrite($fh, "    " . $this->getIdString($obj, $uow) . " " . spl_object_hash($obj) . "\n");
                             }
                         }
                     }
                 }
             }
         }
     }
     fclose($fh);
 }
示例#2
0
 /**
  * {@inheritdoc}
  *
  * @param object $sourceEntity      the entity source of this association
  * @param object $targetEntity      the entity to load data in
  * @param EntityManager $em
  * @param array $joinColumnValues  Values of the join columns of $sourceEntity.
  */
 public function load($sourceEntity, $targetEntity, $em, array $joinColumnValues = array())
 {
     $targetClass = $em->getClassMetadata($this->targetEntityName);
     if ($this->isOwningSide) {
         $inverseField = isset($targetClass->inverseMappings[$this->sourceEntityName][$this->sourceFieldName]) ? $targetClass->inverseMappings[$this->sourceEntityName][$this->sourceFieldName]->sourceFieldName : false;
         // Mark inverse side as fetched in the hints, otherwise the UoW would
         // try to load it in a separate query (remember: to-one inverse sides can not be lazy).
         $hints = array();
         if ($inverseField) {
             $hints['fetched'][$targetClass->name][$inverseField] = true;
             if ($targetClass->subClasses) {
                 foreach ($targetClass->subClasses as $targetSubclassName) {
                     $hints['fetched'][$targetSubclassName][$inverseField] = true;
                 }
             }
         }
         /* cascade read-only status
            if ($em->getUnitOfWork()->isReadOnly($sourceEntity)) {
                $hints[Query::HINT_READ_ONLY] = true;
            }
            */
         $targetEntity = $em->getUnitOfWork()->getEntityPersister($this->targetEntityName)->load($joinColumnValues, $targetEntity, $this, $hints);
         if ($targetEntity !== null && $inverseField && !$targetClass->isCollectionValuedAssociation($inverseField)) {
             $targetClass->reflFields[$inverseField]->setValue($targetEntity, $sourceEntity);
         }
     } else {
         $conditions = array();
         $sourceClass = $em->getClassMetadata($this->sourceEntityName);
         $owningAssoc = $targetClass->getAssociationMapping($this->mappedBy);
         // TRICKY: since the association is specular source and target are flipped
         foreach ($owningAssoc->targetToSourceKeyColumns as $sourceKeyColumn => $targetKeyColumn) {
             if (isset($sourceClass->fieldNames[$sourceKeyColumn])) {
                 $conditions[$targetKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity);
             } else {
                 throw MappingException::joinColumnMustPointToMappedField($sourceClass->name, $sourceKeyColumn);
             }
         }
         $targetEntity = $em->getUnitOfWork()->getEntityPersister($this->targetEntityName)->load($conditions, $targetEntity, $this);
         if ($targetEntity !== null) {
             $targetClass->setFieldValue($targetEntity, $this->mappedBy, $sourceEntity);
         }
     }
     return $targetEntity;
 }
 /**
  * Finds a single entity by a set of criteria.
  *
  * @param string $column
  * @param string $value
  * @return object
  */
 public function findOneBy(array $criteria)
 {
     return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($criteria);
 }
示例#4
0
 /**
  * Walks down a SelectExpression AST node and generates the corresponding SQL.
  *
  * @param SelectExpression $selectExpression
  * @return string The SQL.
  */
 public function walkSelectExpression($selectExpression)
 {
     $sql = '';
     $expr = $selectExpression->expression;
     if ($expr instanceof AST\PathExpression) {
         if ($expr->type == AST\PathExpression::TYPE_STATE_FIELD) {
             $parts = $expr->parts;
             $fieldName = array_pop($parts);
             $dqlAlias = $expr->identificationVariable . (!empty($parts) ? '.' . implode('.', $parts) : '');
             $qComp = $this->_queryComponents[$dqlAlias];
             $class = $qComp['metadata'];
             if (!$selectExpression->fieldIdentificationVariable) {
                 $resultAlias = $fieldName;
             } else {
                 $resultAlias = $selectExpression->fieldIdentificationVariable;
             }
             if ($class->isInheritanceTypeJoined()) {
                 $tableName = $this->_em->getUnitOfWork()->getEntityPersister($class->name)->getOwningTable($fieldName);
             } else {
                 $tableName = $class->getTableName();
             }
             $sqlTableAlias = $this->getSqlTableAlias($tableName, $dqlAlias);
             $columnName = $class->getQuotedColumnName($fieldName, $this->_platform);
             $columnAlias = $this->getSqlColumnAlias($columnName);
             $sql .= $sqlTableAlias . '.' . $columnName . ' AS ' . $columnAlias;
             $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
             $this->_rsm->addScalarResult($columnAlias, $resultAlias);
         } else {
             throw QueryException::invalidPathExpression($expr->type);
         }
     } else {
         if ($expr instanceof AST\AggregateExpression) {
             if (!$selectExpression->fieldIdentificationVariable) {
                 $resultAlias = $this->_scalarResultCounter++;
             } else {
                 $resultAlias = $selectExpression->fieldIdentificationVariable;
             }
             $columnAlias = 'sclr' . $this->_aliasCounter++;
             $sql .= $this->walkAggregateExpression($expr) . ' AS ' . $columnAlias;
             $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
             $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
             $this->_rsm->addScalarResult($columnAlias, $resultAlias);
         } else {
             if ($expr instanceof AST\Subselect) {
                 if (!$selectExpression->fieldIdentificationVariable) {
                     $resultAlias = $this->_scalarResultCounter++;
                 } else {
                     $resultAlias = $selectExpression->fieldIdentificationVariable;
                 }
                 $columnAlias = 'sclr' . $this->_aliasCounter++;
                 $sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias;
                 $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
                 $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
                 $this->_rsm->addScalarResult($columnAlias, $resultAlias);
             } else {
                 if ($expr instanceof AST\Functions\FunctionNode) {
                     if (!$selectExpression->fieldIdentificationVariable) {
                         $resultAlias = $this->_scalarResultCounter++;
                     } else {
                         $resultAlias = $selectExpression->fieldIdentificationVariable;
                     }
                     $columnAlias = 'sclr' . $this->_aliasCounter++;
                     $sql .= $this->walkFunction($expr) . ' AS ' . $columnAlias;
                     $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
                     $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
                     $this->_rsm->addScalarResult($columnAlias, $resultAlias);
                 } else {
                     if ($expr instanceof AST\SimpleArithmeticExpression) {
                         if (!$selectExpression->fieldIdentificationVariable) {
                             $resultAlias = $this->_scalarResultCounter++;
                         } else {
                             $resultAlias = $selectExpression->fieldIdentificationVariable;
                         }
                         $columnAlias = 'sclr' . $this->_aliasCounter++;
                         $sql .= $this->walkSimpleArithmeticExpression($expr) . ' AS ' . $columnAlias;
                         $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
                         $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
                         $this->_rsm->addScalarResult($columnAlias, $resultAlias);
                     } else {
                         // IdentificationVariable or PartialObjectExpression
                         if ($expr instanceof AST\PartialObjectExpression) {
                             $dqlAlias = $expr->identificationVariable;
                             $partialFieldSet = $expr->partialFieldSet;
                         } else {
                             $dqlAlias = $expr;
                             $partialFieldSet = array();
                         }
                         $queryComp = $this->_queryComponents[$dqlAlias];
                         $class = $queryComp['metadata'];
                         if (!isset($this->_selectedClasses[$dqlAlias])) {
                             $this->_selectedClasses[$dqlAlias] = $class;
                         }
                         $beginning = true;
                         // Select all fields from the queried class
                         foreach ($class->fieldMappings as $fieldName => $mapping) {
                             if ($partialFieldSet && !in_array($fieldName, $partialFieldSet)) {
                                 continue;
                             }
                             if (isset($mapping['inherited'])) {
                                 $tableName = $this->_em->getClassMetadata($mapping['inherited'])->primaryTable['name'];
                             } else {
                                 $tableName = $class->primaryTable['name'];
                             }
                             if ($beginning) {
                                 $beginning = false;
                             } else {
                                 $sql .= ', ';
                             }
                             $sqlTableAlias = $this->getSqlTableAlias($tableName, $dqlAlias);
                             $columnAlias = $this->getSqlColumnAlias($mapping['columnName']);
                             $sql .= $sqlTableAlias . '.' . $class->getQuotedColumnName($fieldName, $this->_platform) . ' AS ' . $columnAlias;
                             $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
                             $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $class->name);
                         }
                         // Add any additional fields of subclasses (excluding inherited fields)
                         // 1) on Single Table Inheritance: always, since its marginal overhead
                         // 2) on Class Table Inheritance only if partial objects are disallowed,
                         //    since it requires outer joining subtables.
                         if ($class->isInheritanceTypeSingleTable() || !$this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) {
                             foreach ($class->subClasses as $subClassName) {
                                 $subClass = $this->_em->getClassMetadata($subClassName);
                                 $sqlTableAlias = $this->getSqlTableAlias($subClass->primaryTable['name'], $dqlAlias);
                                 foreach ($subClass->fieldMappings as $fieldName => $mapping) {
                                     if (isset($mapping['inherited']) || $partialFieldSet && !in_array($fieldName, $partialFieldSet)) {
                                         continue;
                                     }
                                     if ($beginning) {
                                         $beginning = false;
                                     } else {
                                         $sql .= ', ';
                                     }
                                     $columnAlias = $this->getSqlColumnAlias($mapping['columnName']);
                                     $sql .= $sqlTableAlias . '.' . $subClass->getQuotedColumnName($fieldName, $this->_platform) . ' AS ' . $columnAlias;
                                     $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
                                     $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $subClassName);
                                 }
                                 // Add join columns (foreign keys) of the subclass
                                 //TODO: Probably better do this in walkSelectClause to honor the INCLUDE_META_COLUMNS hint
                                 foreach ($subClass->associationMappings as $fieldName => $assoc) {
                                     if ($assoc->isOwningSide && $assoc->isOneToOne() && !isset($subClass->inheritedAssociationFields[$fieldName])) {
                                         foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
                                             if ($beginning) {
                                                 $beginning = false;
                                             } else {
                                                 $sql .= ', ';
                                             }
                                             $columnAlias = $this->getSqlColumnAlias($srcColumn);
                                             $sql .= $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
                                             $this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $srcColumn);
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return $sql;
 }
示例#5
0
 /**
  * Walks down a SelectExpression AST node and generates the corresponding SQL.
  *
  * @param SelectExpression $selectExpression
  * @return string The SQL.
  */
 public function walkSelectExpression($selectExpression)
 {
     $sql = '';
     $expr = $selectExpression->expression;
     $hidden = $selectExpression->hiddenAliasResultVariable;
     switch (true) {
         case $expr instanceof AST\PathExpression:
             if ($expr->type !== AST\PathExpression::TYPE_STATE_FIELD) {
                 throw QueryException::invalidPathExpression($expr);
             }
             $fieldName = $expr->field;
             $dqlAlias = $expr->identificationVariable;
             $qComp = $this->queryComponents[$dqlAlias];
             $class = $qComp['metadata'];
             $resultAlias = $selectExpression->fieldIdentificationVariable ?: $fieldName;
             $tableName = $class->isInheritanceTypeJoined() ? $this->em->getUnitOfWork()->getEntityPersister($class->name)->getOwningTable($fieldName) : $class->getTableName();
             $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias);
             $columnName = $this->quoteStrategy->getColumnName($fieldName, $class, $this->platform);
             $columnAlias = $this->getSQLColumnAlias($class->fieldMappings[$fieldName]['columnName']);
             $col = $sqlTableAlias . '.' . $columnName;
             $fieldType = $class->getTypeOfField($fieldName);
             if (isset($class->fieldMappings[$fieldName]['requireSQLConversion'])) {
                 $type = Type::getType($fieldType);
                 $col = $type->convertToPHPValueSQL($col, $this->conn->getDatabasePlatform());
             }
             $sql .= $col . ' AS ' . $columnAlias;
             $this->scalarResultAliasMap[$resultAlias] = $columnAlias;
             if (!$hidden) {
                 $this->rsm->addScalarResult($columnAlias, $resultAlias, $fieldType);
                 $this->scalarFields[$dqlAlias][$fieldName] = $columnAlias;
             }
             break;
         case $expr instanceof AST\AggregateExpression:
         case $expr instanceof AST\Functions\FunctionNode:
         case $expr instanceof AST\SimpleArithmeticExpression:
         case $expr instanceof AST\ArithmeticTerm:
         case $expr instanceof AST\ArithmeticFactor:
         case $expr instanceof AST\Literal:
         case $expr instanceof AST\NullIfExpression:
         case $expr instanceof AST\CoalesceExpression:
         case $expr instanceof AST\GeneralCaseExpression:
         case $expr instanceof AST\SimpleCaseExpression:
             $columnAlias = $this->getSQLColumnAlias('sclr');
             $resultAlias = $selectExpression->fieldIdentificationVariable ?: $this->scalarResultCounter++;
             $sql .= $expr->dispatch($this) . ' AS ' . $columnAlias;
             $this->scalarResultAliasMap[$resultAlias] = $columnAlias;
             if (!$hidden) {
                 // We cannot resolve field type here; assume 'string'.
                 $this->rsm->addScalarResult($columnAlias, $resultAlias, 'string');
             }
             break;
         case $expr instanceof AST\Subselect:
             $columnAlias = $this->getSQLColumnAlias('sclr');
             $resultAlias = $selectExpression->fieldIdentificationVariable ?: $this->scalarResultCounter++;
             $sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias;
             $this->scalarResultAliasMap[$resultAlias] = $columnAlias;
             if (!$hidden) {
                 // We cannot resolve field type here; assume 'string'.
                 $this->rsm->addScalarResult($columnAlias, $resultAlias, 'string');
             }
             break;
         default:
             // IdentificationVariable or PartialObjectExpression
             if ($expr instanceof AST\PartialObjectExpression) {
                 $dqlAlias = $expr->identificationVariable;
                 $partialFieldSet = $expr->partialFieldSet;
             } else {
                 $dqlAlias = $expr;
                 $partialFieldSet = array();
             }
             $queryComp = $this->queryComponents[$dqlAlias];
             $class = $queryComp['metadata'];
             $resultAlias = $selectExpression->fieldIdentificationVariable ?: null;
             if (!isset($this->selectedClasses[$dqlAlias])) {
                 $this->selectedClasses[$dqlAlias] = array('class' => $class, 'dqlAlias' => $dqlAlias, 'resultAlias' => $resultAlias);
             }
             $sqlParts = array();
             // Select all fields from the queried class
             foreach ($class->fieldMappings as $fieldName => $mapping) {
                 if ($partialFieldSet && !in_array($fieldName, $partialFieldSet)) {
                     continue;
                 }
                 $tableName = isset($mapping['inherited']) ? $this->em->getClassMetadata($mapping['inherited'])->getTableName() : $class->getTableName();
                 $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias);
                 $columnAlias = $this->getSQLColumnAlias($mapping['columnName']);
                 $quotedColumnName = $this->quoteStrategy->getColumnName($fieldName, $class, $this->platform);
                 $col = $sqlTableAlias . '.' . $quotedColumnName;
                 if (isset($class->fieldMappings[$fieldName]['requireSQLConversion'])) {
                     $type = Type::getType($class->getTypeOfField($fieldName));
                     $col = $type->convertToPHPValueSQL($col, $this->platform);
                 }
                 $sqlParts[] = $col . ' AS ' . $columnAlias;
                 $this->scalarResultAliasMap[$resultAlias][] = $columnAlias;
                 $this->rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $class->name);
             }
             // Add any additional fields of subclasses (excluding inherited fields)
             // 1) on Single Table Inheritance: always, since its marginal overhead
             // 2) on Class Table Inheritance only if partial objects are disallowed,
             //    since it requires outer joining subtables.
             if ($class->isInheritanceTypeSingleTable() || !$this->query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) {
                 foreach ($class->subClasses as $subClassName) {
                     $subClass = $this->em->getClassMetadata($subClassName);
                     $sqlTableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias);
                     foreach ($subClass->fieldMappings as $fieldName => $mapping) {
                         if (isset($mapping['inherited']) || $partialFieldSet && !in_array($fieldName, $partialFieldSet)) {
                             continue;
                         }
                         $columnAlias = $this->getSQLColumnAlias($mapping['columnName']);
                         $quotedColumnName = $this->quoteStrategy->getColumnName($fieldName, $subClass, $this->platform);
                         $col = $sqlTableAlias . '.' . $quotedColumnName;
                         if (isset($subClass->fieldMappings[$fieldName]['requireSQLConversion'])) {
                             $type = Type::getType($subClass->getTypeOfField($fieldName));
                             $col = $type->convertToPHPValueSQL($col, $this->platform);
                         }
                         $sqlParts[] = $col . ' AS ' . $columnAlias;
                         $this->scalarResultAliasMap[$resultAlias][] = $columnAlias;
                         $this->rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $subClassName);
                     }
                 }
             }
             $sql .= implode(', ', $sqlParts);
     }
     return $sql;
 }
 /**
  * {@inheritdoc}
  *
  * @param object $sourceEntity      the entity source of this association
  * @param object $targetEntity      the entity to load data in
  * @param EntityManager $em
  * @param array $joinColumnValues  Values of the join columns of $sourceEntity.
  * @todo Remove
  */
 public function load($sourceEntity, $targetEntity, $em, array $joinColumnValues = array())
 {
     return $em->getUnitOfWork()->getEntityPersister($this->targetEntityName)->loadOneToOneEntity($this, $sourceEntity, $targetEntity, $joinColumnValues);
 }
示例#7
0
 /**
  * {@inheritdoc}
  *
  * @param object $owningEntity
  * @param object $targetEntity
  * @param EntityManager $em
  */
 public function load($owningEntity, $targetEntity, $em)
 {
     $sourceClass = $em->getClassMetadata($this->sourceEntityName);
     $targetClass = $em->getClassMetadata($this->targetEntityName);
     $conditions = array();
     if ($this->isOwningSide) {
         foreach ($this->sourceToTargetKeyColumns as $sourceKeyColumn => $targetKeyColumn) {
             $conditions[$targetKeyColumn] = $sourceClass->getReflectionProperty($sourceClass->getFieldName($sourceKeyColumn))->getValue($owningEntity);
         }
         if ($targetClass->hasInverseAssociation($this->sourceFieldName)) {
             $targetClass->setFieldValue($targetEntity, $targetClass->inverseMappings[$this->_sourceFieldName]->getSourceFieldName(), $owningEntity);
         }
     } else {
         $owningAssoc = $em->getClassMetadata($this->targetEntityName)->getAssociationMapping($this->mappedByFieldName);
         foreach ($owningAssoc->getTargetToSourceKeyColumns() as $targetKeyColumn => $sourceKeyColumn) {
             $conditions[$sourceKeyColumn] = $sourceClass->getReflectionProperty($sourceClass->getFieldName($targetKeyColumn))->getValue($owningEntity);
         }
         $targetClass->setFieldValue($targetEntity, $this->mappedByFieldName, $owningEntity);
     }
     $em->getUnitOfWork()->getEntityPersister($this->targetEntityName)->load($conditions, $targetEntity);
 }