welcome back to dyb-tech
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\ORM\Utility;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
|
||||
/** @internal This class exists only to avoid code duplication, do not reuse it externally */
|
||||
final class HierarchyDiscriminatorResolver
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is needed to make INSTANCEOF work correctly with inheritance: if the class at hand has inheritance,
|
||||
* it extracts all the discriminators from the child classes and returns them
|
||||
*
|
||||
* @return null[]
|
||||
* @psalm-return array<array-key, null>
|
||||
*/
|
||||
public static function resolveDiscriminatorsForClass(
|
||||
ClassMetadata $rootClassMetadata,
|
||||
EntityManagerInterface $entityManager
|
||||
): array {
|
||||
$hierarchyClasses = $rootClassMetadata->subClasses;
|
||||
$hierarchyClasses[] = $rootClassMetadata->name;
|
||||
|
||||
$discriminators = [];
|
||||
|
||||
foreach ($hierarchyClasses as $class) {
|
||||
$currentMetadata = $entityManager->getClassMetadata($class);
|
||||
$currentDiscriminator = $currentMetadata->discriminatorValue;
|
||||
|
||||
if ($currentDiscriminator !== null) {
|
||||
$discriminators[$currentDiscriminator] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $discriminators;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\ORM\Utility;
|
||||
|
||||
use BackedEnum;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\UnitOfWork;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadataFactory;
|
||||
|
||||
use function assert;
|
||||
use function implode;
|
||||
use function is_a;
|
||||
|
||||
/**
|
||||
* The IdentifierFlattener utility now houses some of the identifier manipulation logic from unit of work, so that it
|
||||
* can be re-used elsewhere.
|
||||
*/
|
||||
final class IdentifierFlattener
|
||||
{
|
||||
/**
|
||||
* The UnitOfWork used to coordinate object-level transactions.
|
||||
*
|
||||
* @var UnitOfWork
|
||||
*/
|
||||
private $unitOfWork;
|
||||
|
||||
/**
|
||||
* The metadata factory, used to retrieve the ORM metadata of entity classes.
|
||||
*
|
||||
* @var ClassMetadataFactory
|
||||
*/
|
||||
private $metadataFactory;
|
||||
|
||||
/**
|
||||
* Initializes a new IdentifierFlattener instance, bound to the given EntityManager.
|
||||
*/
|
||||
public function __construct(UnitOfWork $unitOfWork, ClassMetadataFactory $metadataFactory)
|
||||
{
|
||||
$this->unitOfWork = $unitOfWork;
|
||||
$this->metadataFactory = $metadataFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert foreign identifiers into scalar foreign key values to avoid object to string conversion failures.
|
||||
*
|
||||
* @param mixed[] $id
|
||||
*
|
||||
* @return mixed[]
|
||||
* @psalm-return array<string, mixed>
|
||||
*/
|
||||
public function flattenIdentifier(ClassMetadata $class, array $id): array
|
||||
{
|
||||
$flatId = [];
|
||||
|
||||
foreach ($class->identifier as $field) {
|
||||
if (isset($class->associationMappings[$field]) && isset($id[$field]) && is_a($id[$field], $class->associationMappings[$field]['targetEntity'])) {
|
||||
$targetClassMetadata = $this->metadataFactory->getMetadataFor(
|
||||
$class->associationMappings[$field]['targetEntity']
|
||||
);
|
||||
assert($targetClassMetadata instanceof ClassMetadata);
|
||||
|
||||
if ($this->unitOfWork->isInIdentityMap($id[$field])) {
|
||||
$associatedId = $this->flattenIdentifier($targetClassMetadata, $this->unitOfWork->getEntityIdentifier($id[$field]));
|
||||
} else {
|
||||
$associatedId = $this->flattenIdentifier($targetClassMetadata, $targetClassMetadata->getIdentifierValues($id[$field]));
|
||||
}
|
||||
|
||||
$flatId[$field] = implode(' ', $associatedId);
|
||||
} elseif (isset($class->associationMappings[$field])) {
|
||||
$associatedId = [];
|
||||
|
||||
foreach ($class->associationMappings[$field]['joinColumns'] as $joinColumn) {
|
||||
$associatedId[] = $id[$joinColumn['name']];
|
||||
}
|
||||
|
||||
$flatId[$field] = implode(' ', $associatedId);
|
||||
} else {
|
||||
if ($id[$field] instanceof BackedEnum) {
|
||||
$flatId[$field] = $id[$field]->value;
|
||||
} else {
|
||||
$flatId[$field] = $id[$field];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $flatId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\ORM\Utility;
|
||||
|
||||
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Platforms\DB2Platform;
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLServerPlatform;
|
||||
|
||||
/** @internal */
|
||||
trait LockSqlHelper
|
||||
{
|
||||
private function getReadLockSQL(AbstractPlatform $platform): string
|
||||
{
|
||||
if ($platform instanceof AbstractMySQLPlatform || $platform instanceof MySQLPlatform) {
|
||||
return 'LOCK IN SHARE MODE';
|
||||
}
|
||||
|
||||
if ($platform instanceof PostgreSQLPlatform) {
|
||||
return 'FOR SHARE';
|
||||
}
|
||||
|
||||
return $this->getWriteLockSQL($platform);
|
||||
}
|
||||
|
||||
private function getWriteLockSQL(AbstractPlatform $platform): string
|
||||
{
|
||||
if ($platform instanceof DB2Platform) {
|
||||
return 'WITH RR USE AND KEEP UPDATE LOCKS';
|
||||
}
|
||||
|
||||
if ($platform instanceof SqlitePlatform) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($platform instanceof SQLServerPlatform) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return 'FOR UPDATE';
|
||||
}
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\ORM\Utility;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Query\QueryException;
|
||||
use RuntimeException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* The PersisterHelper contains logic to infer binding types which is used in
|
||||
* several persisters.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
*/
|
||||
class PersisterHelper
|
||||
{
|
||||
/**
|
||||
* @param string $fieldName
|
||||
*
|
||||
* @return array<int, string>
|
||||
*
|
||||
* @throws QueryException
|
||||
*/
|
||||
public static function getTypeOfField($fieldName, ClassMetadata $class, EntityManagerInterface $em)
|
||||
{
|
||||
if (isset($class->fieldMappings[$fieldName])) {
|
||||
return [$class->fieldMappings[$fieldName]['type']];
|
||||
}
|
||||
|
||||
if (! isset($class->associationMappings[$fieldName])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$assoc = $class->associationMappings[$fieldName];
|
||||
|
||||
if (! $assoc['isOwningSide']) {
|
||||
return self::getTypeOfField($assoc['mappedBy'], $em->getClassMetadata($assoc['targetEntity']), $em);
|
||||
}
|
||||
|
||||
if ($assoc['type'] & ClassMetadata::MANY_TO_MANY) {
|
||||
$joinData = $assoc['joinTable'];
|
||||
} else {
|
||||
$joinData = $assoc;
|
||||
}
|
||||
|
||||
$types = [];
|
||||
$targetClass = $em->getClassMetadata($assoc['targetEntity']);
|
||||
|
||||
foreach ($joinData['joinColumns'] as $joinColumn) {
|
||||
$types[] = self::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $em);
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $columnName
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function getTypeOfColumn($columnName, ClassMetadata $class, EntityManagerInterface $em)
|
||||
{
|
||||
if (isset($class->fieldNames[$columnName])) {
|
||||
$fieldName = $class->fieldNames[$columnName];
|
||||
|
||||
if (isset($class->fieldMappings[$fieldName])) {
|
||||
return $class->fieldMappings[$fieldName]['type'];
|
||||
}
|
||||
}
|
||||
|
||||
// iterate over to-one association mappings
|
||||
foreach ($class->associationMappings as $assoc) {
|
||||
if (! isset($assoc['joinColumns'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($assoc['joinColumns'] as $joinColumn) {
|
||||
if ($joinColumn['name'] === $columnName) {
|
||||
$targetColumnName = $joinColumn['referencedColumnName'];
|
||||
$targetClass = $em->getClassMetadata($assoc['targetEntity']);
|
||||
|
||||
return self::getTypeOfColumn($targetColumnName, $targetClass, $em);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iterate over to-many association mappings
|
||||
foreach ($class->associationMappings as $assoc) {
|
||||
if (! (isset($assoc['joinTable']) && isset($assoc['joinTable']['joinColumns']))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($assoc['joinTable']['joinColumns'] as $joinColumn) {
|
||||
if ($joinColumn['name'] === $columnName) {
|
||||
$targetColumnName = $joinColumn['referencedColumnName'];
|
||||
$targetClass = $em->getClassMetadata($assoc['targetEntity']);
|
||||
|
||||
return self::getTypeOfColumn($targetColumnName, $targetClass, $em);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf(
|
||||
'Could not resolve type of column "%s" of class "%s"',
|
||||
$columnName,
|
||||
$class->getName()
|
||||
));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user