From bf6655a534a6775d30cafa67bd801276bda1d98d Mon Sep 17 00:00:00 2001 From: polo Date: Tue, 13 Aug 2024 23:45:21 +0200 Subject: =?UTF-8?q?VERSION=200.2=20doctrine=20ORM=20et=20entit=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orm/src/Query/ResultSetMappingBuilder.php | 281 +++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 vendor/doctrine/orm/src/Query/ResultSetMappingBuilder.php (limited to 'vendor/doctrine/orm/src/Query/ResultSetMappingBuilder.php') diff --git a/vendor/doctrine/orm/src/Query/ResultSetMappingBuilder.php b/vendor/doctrine/orm/src/Query/ResultSetMappingBuilder.php new file mode 100644 index 0000000..f28f3a9 --- /dev/null +++ b/vendor/doctrine/orm/src/Query/ResultSetMappingBuilder.php @@ -0,0 +1,281 @@ + queryColumnName). + * @psalm-param class-string $class + * @psalm-param array $renamedColumns + * @psalm-param self::COLUMN_RENAMING_*|null $renameMode + */ + public function addRootEntityFromClassMetadata( + string $class, + string $alias, + array $renamedColumns = [], + int|null $renameMode = null, + ): void { + $renameMode = $renameMode ?: $this->defaultRenameMode; + $columnAliasMap = $this->getColumnAliasMap($class, $renameMode, $renamedColumns); + + $this->addEntityResult($class, $alias); + $this->addAllClassFields($class, $alias, $columnAliasMap); + } + + /** + * Adds a joined entity and all of its fields to the result set. + * + * @param string $class The class name of the joined entity. + * @param string $alias The unique alias to use for the joined entity. + * @param string $parentAlias The alias of the entity result that is the parent of this joined result. + * @param string $relation The association field that connects the parent entity result + * with the joined entity result. + * @param string[] $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName). + * @psalm-param class-string $class + * @psalm-param array $renamedColumns + * @psalm-param self::COLUMN_RENAMING_*|null $renameMode + */ + public function addJoinedEntityFromClassMetadata( + string $class, + string $alias, + string $parentAlias, + string $relation, + array $renamedColumns = [], + int|null $renameMode = null, + ): void { + $renameMode = $renameMode ?: $this->defaultRenameMode; + $columnAliasMap = $this->getColumnAliasMap($class, $renameMode, $renamedColumns); + + $this->addJoinedEntityResult($class, $alias, $parentAlias, $relation); + $this->addAllClassFields($class, $alias, $columnAliasMap); + } + + /** + * Adds all fields of the given class to the result set mapping (columns and meta fields). + * + * @param string[] $columnAliasMap + * @psalm-param array $columnAliasMap + * + * @throws InvalidArgumentException + */ + protected function addAllClassFields(string $class, string $alias, array $columnAliasMap = []): void + { + $classMetadata = $this->em->getClassMetadata($class); + $platform = $this->em->getConnection()->getDatabasePlatform(); + + if (! $this->isInheritanceSupported($classMetadata)) { + throw new InvalidArgumentException('ResultSetMapping builder does not currently support your inheritance scheme.'); + } + + foreach ($classMetadata->getColumnNames() as $columnName) { + $propertyName = $classMetadata->getFieldName($columnName); + $columnAlias = $this->getSQLResultCasing($platform, $columnAliasMap[$columnName]); + + if (isset($this->fieldMappings[$columnAlias])) { + throw new InvalidArgumentException(sprintf( + "The column '%s' conflicts with another column in the mapper.", + $columnName, + )); + } + + $this->addFieldResult($alias, $columnAlias, $propertyName); + + $enumType = $classMetadata->getFieldMapping($propertyName)->enumType ?? null; + if (! empty($enumType)) { + $this->addEnumResult($columnAlias, $enumType); + } + } + + foreach ($classMetadata->associationMappings as $associationMapping) { + if ($associationMapping->isToOneOwningSide()) { + $targetClass = $this->em->getClassMetadata($associationMapping->targetEntity); + $isIdentifier = isset($associationMapping->id) && $associationMapping->id === true; + + foreach ($associationMapping->joinColumns as $joinColumn) { + $columnName = $joinColumn->name; + $columnAlias = $this->getSQLResultCasing($platform, $columnAliasMap[$columnName]); + $columnType = PersisterHelper::getTypeOfColumn($joinColumn->referencedColumnName, $targetClass, $this->em); + + if (isset($this->metaMappings[$columnAlias])) { + throw new InvalidArgumentException(sprintf( + "The column '%s' conflicts with another column in the mapper.", + $columnAlias, + )); + } + + $this->addMetaResult($alias, $columnAlias, $columnName, $isIdentifier, $columnType); + } + } + } + } + + private function isInheritanceSupported(ClassMetadata $classMetadata): bool + { + if ( + $classMetadata->isInheritanceTypeSingleTable() + && in_array($classMetadata->name, $classMetadata->discriminatorMap, true) + ) { + return true; + } + + return ! ($classMetadata->isInheritanceTypeSingleTable() || $classMetadata->isInheritanceTypeJoined()); + } + + /** + * Gets column alias for a given column. + * + * @psalm-param array $customRenameColumns + * + * @psalm-assert self::COLUMN_RENAMING_* $mode + */ + private function getColumnAlias(string $columnName, int $mode, array $customRenameColumns): string + { + return match ($mode) { + self::COLUMN_RENAMING_INCREMENT => $columnName . $this->sqlCounter++, + self::COLUMN_RENAMING_CUSTOM => $customRenameColumns[$columnName] ?? $columnName, + self::COLUMN_RENAMING_NONE => $columnName, + default => throw new InvalidArgumentException(sprintf('%d is not a valid value for $mode', $mode)), + }; + } + + /** + * Retrieves a class columns and join columns aliases that are used in the SELECT clause. + * + * This depends on the renaming mode selected by the user. + * + * @psalm-param class-string $className + * @psalm-param self::COLUMN_RENAMING_* $mode + * @psalm-param array $customRenameColumns + * + * @return string[] + * @psalm-return array + */ + private function getColumnAliasMap( + string $className, + int $mode, + array $customRenameColumns, + ): array { + if ($customRenameColumns) { // for BC with 2.2-2.3 API + $mode = self::COLUMN_RENAMING_CUSTOM; + } + + $columnAlias = []; + $class = $this->em->getClassMetadata($className); + + foreach ($class->getColumnNames() as $columnName) { + $columnAlias[$columnName] = $this->getColumnAlias($columnName, $mode, $customRenameColumns); + } + + foreach ($class->associationMappings as $associationMapping) { + if ($associationMapping->isToOneOwningSide()) { + foreach ($associationMapping->joinColumns as $joinColumn) { + $columnName = $joinColumn->name; + $columnAlias[$columnName] = $this->getColumnAlias($columnName, $mode, $customRenameColumns); + } + } + } + + return $columnAlias; + } + + /** + * Generates the Select clause from this ResultSetMappingBuilder. + * + * Works only for all the entity results. The select parts for scalar + * expressions have to be written manually. + * + * @param string[] $tableAliases + * @psalm-param array $tableAliases + */ + public function generateSelectClause(array $tableAliases = []): string + { + $sql = ''; + + foreach ($this->columnOwnerMap as $columnName => $dqlAlias) { + $tableAlias = $tableAliases[$dqlAlias] ?? $dqlAlias; + + if ($sql !== '') { + $sql .= ', '; + } + + if (isset($this->fieldMappings[$columnName])) { + $class = $this->em->getClassMetadata($this->declaringClasses[$columnName]); + $fieldName = $this->fieldMappings[$columnName]; + $classFieldMapping = $class->fieldMappings[$fieldName]; + $columnSql = $tableAlias . '.' . $classFieldMapping->columnName; + + $type = Type::getType($classFieldMapping->type); + $columnSql = $type->convertToPHPValueSQL($columnSql, $this->em->getConnection()->getDatabasePlatform()); + + $sql .= $columnSql; + } elseif (isset($this->metaMappings[$columnName])) { + $sql .= $tableAlias . '.' . $this->metaMappings[$columnName]; + } elseif (isset($this->discriminatorColumns[$dqlAlias])) { + $sql .= $tableAlias . '.' . $this->discriminatorColumns[$dqlAlias]; + } + + $sql .= ' AS ' . $columnName; + } + + return $sql; + } + + public function __toString(): string + { + return $this->generateSelectClause([]); + } +} -- cgit v1.2.3