From 3eace16e8533e3846d9c7dbc7809fc8c487600f7 Mon Sep 17 00:00:00 2001 From: Hanish Singla Date: Tue, 20 Feb 2024 13:36:20 +0530 Subject: [PATCH 1/3] Allow (Array)ParameterType in QueryBuilder --- src/QueryBuilder.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 115dea0187d..f03951d2092 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -6,6 +6,8 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Criteria; +use Doctrine\DBAL\ArrayParameterType; +use Doctrine\DBAL\ParameterType; use Doctrine\ORM\Internal\QueryType; use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Parameter; @@ -428,12 +430,12 @@ public function getRootEntities(): array * ->setParameter('user_id', 1); * * - * @param string|int $key The parameter position or name. - * @param string|int|null $type ParameterType::* or \Doctrine\DBAL\Types\Type::* constant + * @param string|int $key The parameter position or name. + * @param ParameterType|ArrayParameterType|string|int|null $type ParameterType::*, ArrayParameterType::* or \Doctrine\DBAL\Types\Type::* constant * * @return $this */ - public function setParameter(string|int $key, mixed $value, string|int|null $type = null): static + public function setParameter(string|int $key, mixed $value, ParameterType|ArrayParameterType|string|int|null $type = null): static { $existingParameter = $this->getParameter($key); From a5bf9bb96a0b2edbefd8355a61fb799fae03cec8 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Thu, 22 Feb 2024 09:12:39 +0100 Subject: [PATCH 2/3] Be less restrictive in DiscriminatorColumnMapping phpdoc (#11226) * Be less restrictive in params * Allow null options * Simplify expression * Fix ci * Add support for null --- src/Mapping/ClassMetadata.php | 19 +++++++------------ src/Mapping/DiscriminatorColumnMapping.php | 10 +++++----- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/Mapping/ClassMetadata.php b/src/Mapping/ClassMetadata.php index 0d9889b6e77..3f5b1c77732 100644 --- a/src/Mapping/ClassMetadata.php +++ b/src/Mapping/ClassMetadata.php @@ -2108,13 +2108,12 @@ public function addEntityListener(string $eventName, string $class, string $meth * @param DiscriminatorColumnMapping|mixed[]|null $columnDef * @psalm-param DiscriminatorColumnMapping|array{ * name: string|null, - * fieldName?: string, - * type?: string, - * length?: int, + * fieldName?: string|null, + * type?: string|null, + * length?: int|null, * columnDefinition?: string|null, * enumType?: class-string|null, - * options?:array|null + * options?: array|null * }|null $columnDef * * @throws MappingException @@ -2136,13 +2135,9 @@ public function setDiscriminatorColumn(DiscriminatorColumnMapping|array|null $co throw MappingException::duplicateColumnName($this->name, $columnDef['name']); } - if (! isset($columnDef['fieldName'])) { - $columnDef['fieldName'] = $columnDef['name']; - } - - if (! isset($columnDef['type'])) { - $columnDef['type'] = 'string'; - } + $columnDef['fieldName'] ??= $columnDef['name']; + $columnDef['type'] ??= 'string'; + $columnDef['options'] ??= []; if (in_array($columnDef['type'], ['boolean', 'array', 'object', 'datetime', 'time', 'date'], true)) { throw MappingException::invalidDiscriminatorColumnType($this->name, $columnDef['type']); diff --git a/src/Mapping/DiscriminatorColumnMapping.php b/src/Mapping/DiscriminatorColumnMapping.php index cc23fdfdb3b..4ccb71c4b36 100644 --- a/src/Mapping/DiscriminatorColumnMapping.php +++ b/src/Mapping/DiscriminatorColumnMapping.php @@ -39,10 +39,10 @@ public function __construct( * type: string, * fieldName: string, * name: string, - * length?: int, - * columnDefinition?: string, - * enumType?: class-string, - * options?: array, + * length?: int|null, + * columnDefinition?: string|null, + * enumType?: class-string|null, + * options?: array|null, * } $mappingArray */ public static function fromMappingArray(array $mappingArray): self @@ -58,7 +58,7 @@ public static function fromMappingArray(array $mappingArray): self } if (property_exists($mapping, $key)) { - $mapping->$key = $value; + $mapping->$key = $value ?? $mapping->$key; } else { throw new Exception('Unknown property ' . $key . ' on class ' . static::class); } From 708146bbbc08651d8d2ec4eaa144b3ce96a57cf7 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 22 Feb 2024 00:00:19 +0100 Subject: [PATCH 3/3] Test different ways of settings query parameters --- .../ORM/Functional/QueryParameterTest.php | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 tests/Tests/ORM/Functional/QueryParameterTest.php diff --git a/tests/Tests/ORM/Functional/QueryParameterTest.php b/tests/Tests/ORM/Functional/QueryParameterTest.php new file mode 100644 index 00000000000..e7599cea5ea --- /dev/null +++ b/tests/Tests/ORM/Functional/QueryParameterTest.php @@ -0,0 +1,124 @@ +useModelSet('cms'); + + parent::setUp(); + + $user = new CmsUser(); + $user->name = 'John Doe'; + $user->username = 'john'; + $user2 = new CmsUser(); + $user2->name = 'Jane Doe'; + $user2->username = 'jane'; + $user3 = new CmsUser(); + $user3->name = 'Just Bill'; + $user3->username = 'bill'; + + $this->_em->persist($user); + $this->_em->persist($user2); + $this->_em->persist($user3); + $this->_em->flush(); + + $this->userId = $user->id; + + $this->_em->clear(); + } + + public function testParameterTypeInBuilder(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.id = :id') + ->setParameter('id', $this->userId, ParameterType::INTEGER) + ->getQuery() + ->getArrayResult(); + + self::assertSame([['name' => 'John Doe']], $result); + } + + public function testParameterTypeInQuery(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.id = :id') + ->getQuery() + ->setParameter('id', $this->userId, ParameterType::INTEGER) + ->getArrayResult(); + + self::assertSame([['name' => 'John Doe']], $result); + } + + public function testDbalTypeStringInBuilder(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.id = :id') + ->setParameter('id', $this->userId, Types::INTEGER) + ->getQuery() + ->getArrayResult(); + + self::assertSame([['name' => 'John Doe']], $result); + } + + public function testDbalTypeStringInQuery(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.id = :id') + ->getQuery() + ->setParameter('id', $this->userId, Types::INTEGER) + ->getArrayResult(); + + self::assertSame([['name' => 'John Doe']], $result); + } + + public function testArrayParameterTypeInBuilder(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.username IN (:usernames)') + ->orderBy('u.username') + ->setParameter('usernames', ['john', 'jane'], ArrayParameterType::STRING) + ->getQuery() + ->getArrayResult(); + + self::assertSame([['name' => 'Jane Doe'], ['name' => 'John Doe']], $result); + } + + public function testArrayParameterTypeInQuery(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.username IN (:usernames)') + ->orderBy('u.username') + ->getQuery() + ->setParameter('usernames', ['john', 'jane'], ArrayParameterType::STRING) + ->getArrayResult(); + + self::assertSame([['name' => 'Jane Doe'], ['name' => 'John Doe']], $result); + } +}