Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Psalmify QueryBuilder, Query and EntityRepository. #11406

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ parameters:
path: src/Proxy/ProxyFactory.php

-
message: "#^Parameter \\#2 \\$sqlParams of method Doctrine\\\\ORM\\\\Query\\:\\:evictResultSetCache\\(\\) expects array\\<string, mixed\\>, array\\<int, mixed\\> given\\.$#"
message: "#^Parameter \\#2 \\$sqlParams of method Doctrine\\\\ORM\\\\Query<T>\\:\\:evictResultSetCache\\(\\) expects array\\<string, mixed\\>, array\\<int, mixed\\> given\\.$#"
count: 1
path: src/Query.php

Expand Down Expand Up @@ -271,7 +271,7 @@ parameters:
path: src/Query/SqlWalker.php

-
message: "#^Parameter \\#2 \\$dqlPart of method Doctrine\\\\ORM\\\\QueryBuilder\\:\\:add\\(\\) expects array\\<'join'\\|int, array\\<int\\|string, object\\>\\|string\\>\\|object\\|string, non\\-empty\\-array\\<string, Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Join\\> given\\.$#"
message: "#^Parameter \\#2 \\$dqlPart of method Doctrine\\\\ORM\\\\QueryBuilder<T>\\:\\:add\\(\\) expects array\\<'join'\\|int, array\\<int\\|string, object\\>\\|string\\>\\|object\\|string, non\\-empty\\-array\\<string, Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Join\\> given\\.$#"
count: 2
path: src/QueryBuilder.php

Expand Down
20 changes: 20 additions & 0 deletions src/AbstractQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
* Base contract for ORM queries. Base class for Query and NativeQuery.
*
* @link www.doctrine-project.org
*
* @template T
*/
abstract class AbstractQuery
{
Expand Down Expand Up @@ -683,6 +685,12 @@ public function getHydrationMode(): string|int
* Alias for execute(null, $hydrationMode = HYDRATE_OBJECT).
*
* @psalm-param string|AbstractQuery::HYDRATE_* $hydrationMode
*
* @psalm-return (
* $hydrationMode is self::HYDRATE_OBJECT|null
* ? array<array-key, T>
* : mixed
* )
*/
public function getResult(string|int $hydrationMode = self::HYDRATE_OBJECT): mixed
{
Expand Down Expand Up @@ -730,6 +738,12 @@ public function getScalarResult(): array
*
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
*
* @psalm-return (
* $hydrationMode is self::HYDRATE_OBJECT|null
* ? T|null
* : mixed
* )
*
* @throws NonUniqueResultException
*/
public function getOneOrNullResult(string|int|null $hydrationMode = null): mixed
Expand Down Expand Up @@ -765,6 +779,12 @@ public function getOneOrNullResult(string|int|null $hydrationMode = null): mixed
*
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
*
* @psalm-return (
* $hydrationMode is self::HYDRATE_OBJECT|null
* ? T
* : mixed
* )
*
* @throws NonUniqueResultException If the query result is not unique.
* @throws NoResultException If the query returned no result.
*/
Expand Down
2 changes: 2 additions & 0 deletions src/EntityRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public function __construct(

/**
* Creates a new QueryBuilder instance that is prepopulated for this entity name.
*
* @return QueryBuilder<T>
*/
public function createQueryBuilder(string $alias, string|null $indexBy = null): QueryBuilder
{
Expand Down
1 change: 1 addition & 0 deletions src/NativeQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* Represents a native SQL query.
*
* @final
* @extends AbstractQuery<mixed>
*/
class NativeQuery extends AbstractQuery
{
Expand Down
2 changes: 2 additions & 0 deletions src/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
/**
* A Query object represents a DQL query.
*
* @template T
* @extends AbstractQuery<T>
* @final
*/
class Query extends AbstractQuery
Expand Down
9 changes: 9 additions & 0 deletions src/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
/**
* This class is responsible for building DQL query strings via an object oriented
* PHP interface.
*
* @template T
*/
class QueryBuilder implements Stringable
{
Expand Down Expand Up @@ -251,6 +253,8 @@ public function getDQL(): string
* $q = $qb->getQuery();
* $results = $q->execute();
* </code>
*
* @psalm-return Query<T>
*/
public function getQuery(): Query
{
Expand Down Expand Up @@ -613,6 +617,11 @@ public function add(string $dqlPartName, string|object|array $dqlPart, bool $app
* </code>
*
* @return $this
* @psalm-return static<mixed>
* @phpstan-return $this<mixed>
*
* @psalm-this-out static<mixed>
* @phpstan-this-out $this<mixed>
*/
public function select(mixed ...$select): static
{
Expand Down
56 changes: 56 additions & 0 deletions tests/StaticAnalysis/query-builder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM;

class Cat
{
}

/** @extends EntityRepository<Cat> */
class CatRepository extends EntityRepository
{
}

/** @return array<array-key, Cat> */
function getResultAsEntities(CatRepository $catRepository): array
{
return $catRepository->createQueryBuilder('c')->getQuery()->getResult();
}

function getOneOrNullEntity(CatRepository $catRepository): Cat|null
{
return $catRepository->createQueryBuilder('c')->getQuery()->getOneOrNullResult();
}

function getSingleEntity(CatRepository $catRepository): Cat
{
return $catRepository->createQueryBuilder('c')->getQuery()->getSingleResult();
}

/**
* Once QueryBuilder::select is called, all results will be mixed. User must manually assert returned type.
*
* @see QueryBuilder::select()
*/
function getMixedResults(CatRepository $catRepository): mixed
{
return $catRepository->createQueryBuilder('c')
->select('c.id')
->getQuery()->getResult();
}

function getMixedOrNullResult(CatRepository $catRepository): mixed
{
return $catRepository->createQueryBuilder('c')
->select('c.id')
->getQuery()->getOneOrNullResult();
}

function getMixedResult(CatRepository $catRepository): mixed
{
return $catRepository->createQueryBuilder('c')
->select('c.id')
->getQuery()->getSingleResult();
}
Loading