From 2ba2640e356efff305bb350e5b2078e37e6298f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 21 May 2022 14:53:28 +0200 Subject: [PATCH] Add native types to AbstractQuery --- lib/Doctrine/ORM/AbstractQuery.php | 250 +++++++++-------------------- lib/Doctrine/ORM/NativeQuery.php | 8 +- lib/Doctrine/ORM/Query.php | 22 +-- 3 files changed, 87 insertions(+), 193 deletions(-) diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index 3bcd0f4a044..fb5cac5364d 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -83,80 +83,63 @@ abstract class AbstractQuery * @var ArrayCollection|Parameter[] * @psalm-var ArrayCollection */ - protected $parameters; + protected ArrayCollection $parameters; /** * The user-specified ResultSetMapping to use. - * - * @var ResultSetMapping|null */ - protected $_resultSetMapping; + protected ?ResultSetMapping $_resultSetMapping = null; /** * The entity manager used by this query object. - * - * @var EntityManagerInterface */ - protected $_em; + protected EntityManagerInterface $_em; /** * The map of query hints. * * @psalm-var array */ - protected $_hints = []; + protected array $_hints = []; /** * The hydration mode. * - * @var string|int * @psalm-var string|AbstractQuery::HYDRATE_* */ - protected $_hydrationMode = self::HYDRATE_OBJECT; + protected string|int $_hydrationMode = self::HYDRATE_OBJECT; - /** @var QueryCacheProfile|null */ - protected $_queryCacheProfile; + protected ?QueryCacheProfile $_queryCacheProfile = null; /** * Whether or not expire the result cache. - * - * @var bool */ - protected $_expireResultCache = false; + protected bool $_expireResultCache = false; - /** @var QueryCacheProfile|null */ - protected $_hydrationCacheProfile; + protected ?QueryCacheProfile $_hydrationCacheProfile = null; /** * Whether to use second level cache, if available. - * - * @var bool */ - protected $cacheable = false; + protected bool $cacheable = false; - /** @var bool */ - protected $hasCache = false; + protected bool $hasCache = false; /** * Second level cache region name. - * - * @var string|null */ - protected $cacheRegion; + protected ?string $cacheRegion = null; /** * Second level query cache mode. * - * @var int|null * @psalm-var Cache::MODE_*|null */ - protected $cacheMode; + protected ?int $cacheMode = null; - /** @var CacheLogger|null */ - protected $cacheLogger; + protected ?CacheLogger $cacheLogger = null; - /** @var int */ - protected $lifetime = 0; + protected int $lifetime = 0; /** * Initializes a new instance of a class derived from AbstractQuery. @@ -178,13 +161,11 @@ public function __construct(EntityManagerInterface $em) /** * Enable/disable second level query (result) caching for this query. * - * @param bool $cacheable - * * @return $this */ - public function setCacheable($cacheable) + public function setCacheable(bool $cacheable): static { - $this->cacheable = (bool) $cacheable; + $this->cacheable = $cacheable; return $this; } @@ -192,17 +173,15 @@ public function setCacheable($cacheable) /** * @return bool TRUE if the query results are enable for second level cache, FALSE otherwise. */ - public function isCacheable() + public function isCacheable(): bool { return $this->cacheable; } /** - * @param string $cacheRegion - * * @return $this */ - public function setCacheRegion($cacheRegion) + public function setCacheRegion(string $cacheRegion): static { $this->cacheRegion = (string) $cacheRegion; @@ -214,7 +193,7 @@ public function setCacheRegion($cacheRegion) * * @return string|null The cache region name; NULL indicates the default region. */ - public function getCacheRegion() + public function getCacheRegion(): ?string { return $this->cacheRegion; } @@ -222,15 +201,12 @@ public function getCacheRegion() /** * @return bool TRUE if the query cache and second level cache are enabled, FALSE otherwise. */ - protected function isCacheEnabled() + protected function isCacheEnabled(): bool { return $this->cacheable && $this->hasCache; } - /** - * @return int - */ - public function getLifetime() + public function getLifetime(): int { return $this->lifetime; } @@ -238,11 +214,9 @@ public function getLifetime() /** * Sets the life-time for this query into second level cache. * - * @param int $lifetime - * * @return $this */ - public function setLifetime($lifetime) + public function setLifetime(int $lifetime): static { $this->lifetime = (int) $lifetime; @@ -250,23 +224,21 @@ public function setLifetime($lifetime) } /** - * @return int|null * @psalm-return Cache::MODE_*|null */ - public function getCacheMode() + public function getCacheMode(): ?int { return $this->cacheMode; } /** - * @param int $cacheMode * @psalm-param Cache::MODE_* $cacheMode * * @return $this */ - public function setCacheMode($cacheMode) + public function setCacheMode(int $cacheMode): static { - $this->cacheMode = (int) $cacheMode; + $this->cacheMode = $cacheMode; return $this; } @@ -278,14 +250,12 @@ public function setCacheMode($cacheMode) * * @return string SQL query */ - abstract public function getSQL(); + abstract public function getSQL(): string|array; /** * Retrieves the associated EntityManager of this Query instance. - * - * @return EntityManagerInterface */ - public function getEntityManager() + public function getEntityManager(): EntityManagerInterface { return $this->_em; } @@ -294,10 +264,8 @@ public function getEntityManager() * Frees the resources used by the query object. * * Resets Parameters, Parameter Types and Query Hints. - * - * @return void */ - public function free() + public function free(): void { $this->parameters = new ArrayCollection(); @@ -310,7 +278,7 @@ public function free() * @return ArrayCollection The defined query parameters. * @psalm-return ArrayCollection */ - public function getParameters() + public function getParameters(): ArrayCollection { return $this->parameters; } @@ -322,7 +290,7 @@ public function getParameters() * * @return Parameter|null The value of the bound parameter, or NULL if not available. */ - public function getParameter($key) + public function getParameter($key): ?Parameter { $key = Query\Parameter::normalizeName($key); @@ -345,7 +313,7 @@ static function (Query\Parameter $parameter) use ($key): bool { * * @return $this */ - public function setParameters($parameters) + public function setParameters(ArrayCollection|array $parameters): static { // BC compatibility with 2.3- if (is_array($parameters)) { @@ -375,7 +343,7 @@ public function setParameters($parameters) * * @return $this */ - public function setParameter($key, $value, $type = null) + public function setParameter(string|int $key, mixed $value, string|int|null $type = null): static { $existingParameter = $this->getParameter($key); @@ -393,14 +361,12 @@ public function setParameter($key, $value, $type = null) /** * Processes an individual parameter value. * - * @param mixed $value - * * @return mixed[]|string|int|float|bool * @psalm-return array|scalar * * @throws ORMInvalidArgumentException */ - public function processParameterValue($value) + public function processParameterValue(mixed $value): mixed { if (is_scalar($value)) { return $value; @@ -450,12 +416,8 @@ public function processParameterValue($value) /** * If no mapping is detected, trying to resolve the value as a Traversable - * - * @param mixed $value - * - * @return mixed */ - private function potentiallyProcessIterable($value) + private function potentiallyProcessIterable(mixed $value): mixed { if ($value instanceof Traversable) { $value = iterator_to_array($value); @@ -487,7 +449,7 @@ private function processArrayParameterValue(array $value): array * * @return $this */ - public function setResultSetMapping(Query\ResultSetMapping $rsm) + public function setResultSetMapping(Query\ResultSetMapping $rsm): static { $this->translateNamespaces($rsm); $this->_resultSetMapping = $rsm; @@ -497,10 +459,8 @@ public function setResultSetMapping(Query\ResultSetMapping $rsm) /** * Gets the ResultSetMapping used for hydration. - * - * @return ResultSetMapping|null */ - protected function getResultSetMapping() + protected function getResultSetMapping(): ?ResultSetMapping { return $this->_resultSetMapping; } @@ -538,7 +498,7 @@ private function translateNamespaces(Query\ResultSetMapping $rsm): void * $query->setHydrationCacheProfile(new QueryCacheProfile()); * $query->setHydrationCacheProfile(new QueryCacheProfile($lifetime, $resultKey)); */ - public function setHydrationCacheProfile(?QueryCacheProfile $profile = null) + public function setHydrationCacheProfile(?QueryCacheProfile $profile = null): static { if ($profile === null) { $this->_hydrationCacheProfile = null; @@ -558,10 +518,7 @@ public function setHydrationCacheProfile(?QueryCacheProfile $profile = null) return $this; } - /** - * @return QueryCacheProfile|null - */ - public function getHydrationCacheProfile() + public function getHydrationCacheProfile(): ?QueryCacheProfile { return $this->_hydrationCacheProfile; } @@ -574,7 +531,7 @@ public function getHydrationCacheProfile() * * @return $this */ - public function setResultCacheProfile(?QueryCacheProfile $profile = null) + public function setResultCacheProfile(?QueryCacheProfile $profile = null): static { if ($profile === null) { $this->_queryCacheProfile = null; @@ -596,10 +553,8 @@ public function setResultCacheProfile(?QueryCacheProfile $profile = null) /** * Defines a cache driver to be used for caching result sets and implicitly enables caching. - * - * @return $this */ - public function setResultCache(?CacheItemPoolInterface $resultCache = null) + public function setResultCache(?CacheItemPoolInterface $resultCache = null): static { if ($resultCache === null) { if ($this->_queryCacheProfile) { @@ -625,7 +580,7 @@ public function setResultCache(?CacheItemPoolInterface $resultCache = null) * * @return $this */ - public function enableResultCache(?int $lifetime = null, ?string $resultCacheId = null): self + public function enableResultCache(?int $lifetime = null, ?string $resultCacheId = null): static { $this->setResultCacheLifetime($lifetime); $this->setResultCacheId($resultCacheId); @@ -638,7 +593,7 @@ public function enableResultCache(?int $lifetime = null, ?string $resultCacheId * * @return $this */ - public function disableResultCache(): self + public function disableResultCache(): static { $this->_queryCacheProfile = null; @@ -652,7 +607,7 @@ public function disableResultCache(): self * * @return $this */ - public function setResultCacheLifetime($lifetime) + public function setResultCacheLifetime(?int $lifetime): static { $lifetime = (int) $lifetime; @@ -681,7 +636,7 @@ public function setResultCacheLifetime($lifetime) * * @return $this */ - public function expireResultCache($expire = true) + public function expireResultCache(bool $expire = true): static { $this->_expireResultCache = $expire; @@ -690,18 +645,13 @@ public function expireResultCache($expire = true) /** * Retrieves if the resultset cache is active or not. - * - * @return bool */ - public function getExpireResultCache() + public function getExpireResultCache(): bool { return $this->_expireResultCache; } - /** - * @return QueryCacheProfile|null - */ - public function getQueryCacheProfile() + public function getQueryCacheProfile(): ?QueryCacheProfile { return $this->_queryCacheProfile; } @@ -711,13 +661,9 @@ public function getQueryCacheProfile() * * $fetchMode can be one of ClassMetadata::FETCH_EAGER or ClassMetadata::FETCH_LAZY * - * @param string $class - * @param string $assocName - * @param int $fetchMode - * * @return $this */ - public function setFetchMode($class, $assocName, $fetchMode) + public function setFetchMode(string $class, string $assocName, int $fetchMode) { if ($fetchMode !== Mapping\ClassMetadata::FETCH_EAGER) { $fetchMode = Mapping\ClassMetadata::FETCH_LAZY; @@ -737,7 +683,7 @@ public function setFetchMode($class, $assocName, $fetchMode) * * @return $this */ - public function setHydrationMode($hydrationMode) + public function setHydrationMode(string|int $hydrationMode) { $this->_hydrationMode = $hydrationMode; @@ -747,10 +693,9 @@ public function setHydrationMode($hydrationMode) /** * Gets the hydration mode currently used by the query. * - * @return string|int * @psalm-return string|AbstractQuery::HYDRATE_* */ - public function getHydrationMode() + public function getHydrationMode(): string|int { return $this->_hydrationMode; } @@ -760,12 +705,9 @@ public function getHydrationMode() * * Alias for execute(null, $hydrationMode = HYDRATE_OBJECT). * - * @param string|int $hydrationMode * @psalm-param string|AbstractQuery::HYDRATE_* $hydrationMode - * - * @return mixed */ - public function getResult($hydrationMode = self::HYDRATE_OBJECT) + public function getResult(string|int $hydrationMode = self::HYDRATE_OBJECT): mixed { return $this->execute(null, $hydrationMode); } @@ -777,7 +719,7 @@ public function getResult($hydrationMode = self::HYDRATE_OBJECT) * * @return mixed[] */ - public function getArrayResult() + public function getArrayResult(): array { return $this->execute(null, self::HYDRATE_ARRAY); } @@ -789,7 +731,7 @@ public function getArrayResult() * * @return mixed[] */ - public function getSingleColumnResult() + public function getSingleColumnResult(): array { return $this->execute(null, self::HYDRATE_SCALAR_COLUMN); } @@ -801,7 +743,7 @@ public function getSingleColumnResult() * * @return mixed[] */ - public function getScalarResult() + public function getScalarResult(): array { return $this->execute(null, self::HYDRATE_SCALAR); } @@ -809,14 +751,11 @@ public function getScalarResult() /** * Get exactly one result or null. * - * @param string|int|null $hydrationMode * @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode * - * @return mixed - * * @throws NonUniqueResultException */ - public function getOneOrNullResult($hydrationMode = null) + public function getOneOrNullResult(string|int|null $hydrationMode = null): mixed { try { $result = $this->execute(null, $hydrationMode); @@ -847,15 +786,12 @@ public function getOneOrNullResult($hydrationMode = null) * If the result is not unique, a NonUniqueResultException is thrown. * If there is no result, a NoResultException is thrown. * - * @param string|int|null $hydrationMode * @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode * - * @return mixed - * * @throws NonUniqueResultException If the query result is not unique. * @throws NoResultException If the query returned no result. */ - public function getSingleResult($hydrationMode = null) + public function getSingleResult(string|int|null $hydrationMode = null): mixed { $result = $this->execute(null, $hydrationMode); @@ -879,12 +815,10 @@ public function getSingleResult($hydrationMode = null) * * Alias for getSingleResult(HYDRATE_SINGLE_SCALAR). * - * @return mixed The scalar result. - * * @throws NoResultException If the query returned no result. * @throws NonUniqueResultException If the query result is not unique. */ - public function getSingleScalarResult() + public function getSingleScalarResult(): mixed { return $this->getSingleResult(self::HYDRATE_SINGLE_SCALAR); } @@ -892,12 +826,9 @@ public function getSingleScalarResult() /** * Sets a query hint. If the hint name is not recognized, it is silently ignored. * - * @param string $name The name of the hint. - * @param mixed $value The value of the hint. - * * @return $this */ - public function setHint($name, $value) + public function setHint(string $name, mixed $value): static { $this->_hints[$name] = $value; @@ -907,23 +838,14 @@ public function setHint($name, $value) /** * Gets the value of a query hint. If the hint name is not recognized, FALSE is returned. * - * @param string $name The name of the hint. - * * @return mixed The value of the hint or FALSE, if the hint name is not recognized. */ - public function getHint($name) + public function getHint(string $name): mixed { return $this->_hints[$name] ?? false; } - /** - * Check if the query has a hint - * - * @param string $name The name of the hint - * - * @return bool False if the query does not have any hint - */ - public function hasHint($name) + public function hasHint(string $name): bool { return isset($this->_hints[$name]); } @@ -933,7 +855,7 @@ public function hasHint($name) * * @return array */ - public function getHints() + public function getHints(): array { return $this->_hints; } @@ -942,14 +864,12 @@ public function getHints() * Executes the query and returns an iterable that can be used to incrementally * iterate over the result. * - * @param ArrayCollection|array|mixed[] $parameters The query parameters. - * @param string|int|null $hydrationMode The hydration mode to use. * @psalm-param ArrayCollection|mixed[] $parameters * @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode * * @return iterable */ - public function toIterable(iterable $parameters = [], $hydrationMode = null): iterable + public function toIterable(iterable $parameters = [], string|int|null $hydrationMode = null): iterable { if ($hydrationMode !== null) { $this->setHydrationMode($hydrationMode); @@ -979,15 +899,13 @@ public function toIterable(iterable $parameters = [], $hydrationMode = null): it /** * Executes the query. * - * @param ArrayCollection|mixed[]|null $parameters Query parameters. - * @param string|int|null $hydrationMode Processing mode to be used during the hydration process. * @psalm-param ArrayCollection|mixed[]|null $parameters * @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode - * - * @return mixed */ - public function execute($parameters = null, $hydrationMode = null) - { + public function execute( + ArrayCollection|array|null $parameters = null, + string|int|null $hydrationMode = null + ): mixed { if ($this->cacheable && $this->isCacheEnabled()) { return $this->executeUsingQueryCache($parameters, $hydrationMode); } @@ -998,15 +916,13 @@ public function execute($parameters = null, $hydrationMode = null) /** * Execute query ignoring second level cache. * - * @param ArrayCollection|mixed[]|null $parameters - * @param string|int|null $hydrationMode * @psalm-param ArrayCollection|mixed[]|null $parameters * @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode - * - * @return mixed */ - private function executeIgnoreQueryCache($parameters = null, $hydrationMode = null) - { + private function executeIgnoreQueryCache( + ArrayCollection|array|null $parameters = null, + string|int|null $hydrationMode = null + ): mixed { if ($hydrationMode !== null) { $this->setHydrationMode($hydrationMode); } @@ -1071,15 +987,13 @@ private function getHydrationCache(): CacheItemPoolInterface /** * Load from second level cache or executes the query and put into cache. * - * @param ArrayCollection|mixed[]|null $parameters - * @param string|int|null $hydrationMode * @psalm-param ArrayCollection|mixed[]|null $parameters * @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode - * - * @return mixed */ - private function executeUsingQueryCache($parameters = null, $hydrationMode = null) - { + private function executeUsingQueryCache( + ArrayCollection|array|null $parameters = null, + string|int|null $hydrationMode = null + ): mixed { $rsm = $this->getResultSetMapping(); if ($rsm === null) { throw new LogicException('Uninitialized result set mapping.'); @@ -1139,7 +1053,7 @@ private function getTimestampKey(): ?TimestampCacheKey * @return string[] ($key, $hash) * @psalm-return array{string, string} ($key, $hash) */ - protected function getHydrationCacheId() + protected function getHydrationCacheId(): array { $parameters = []; @@ -1162,12 +1076,8 @@ protected function getHydrationCacheId() * Set the result cache id to use to store the result set cache entry. * If this is not explicitly set by the developer then a hash is automatically * generated for you. - * - * @param string|null $id - * - * @return $this */ - public function setResultCacheId($id) + public function setResultCacheId(?string $id): static { if (! $this->_queryCacheProfile) { return $this->setResultCacheProfile(new QueryCacheProfile(0, $id)); @@ -1185,14 +1095,12 @@ public function setResultCacheId($id) * the results, or an integer indicating how * many rows were affected. */ - abstract protected function _doExecute(); + abstract protected function _doExecute(): Result|int; /** * Cleanup Query resource when clone is called. - * - * @return void */ - public function __clone() + public function __clone(): void { $this->parameters = new ArrayCollection(); @@ -1202,10 +1110,8 @@ public function __clone() /** * Generates a string of currently query to use for the cache second level cache. - * - * @return string */ - protected function getHash() + protected function getHash(): string { $query = $this->getSQL(); $hints = $this->getHints(); diff --git a/lib/Doctrine/ORM/NativeQuery.php b/lib/Doctrine/ORM/NativeQuery.php index 9f82bad1cee..e2a5ed019f2 100644 --- a/lib/Doctrine/ORM/NativeQuery.php +++ b/lib/Doctrine/ORM/NativeQuery.php @@ -4,6 +4,7 @@ namespace Doctrine\ORM; +use Doctrine\DBAL\Result; use function array_values; use function is_int; use function key; @@ -38,15 +39,12 @@ public function setSQL($sql): self * * @override */ - public function getSQL() + public function getSQL(): string|array { return $this->sql; } - /** - * {@inheritdoc} - */ - protected function _doExecute() + protected function _doExecute(): Result|int { $parameters = []; $types = []; diff --git a/lib/Doctrine/ORM/Query.php b/lib/Doctrine/ORM/Query.php index 8f9eb0d5a67..c8b42abd2af 100644 --- a/lib/Doctrine/ORM/Query.php +++ b/lib/Doctrine/ORM/Query.php @@ -5,6 +5,7 @@ namespace Doctrine\ORM; use Doctrine\DBAL\LockMode; +use Doctrine\DBAL\Result; use Doctrine\DBAL\Types\Type; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Query\AST\DeleteStatement; @@ -184,7 +185,7 @@ final class Query extends AbstractQuery * * @override */ - public function getSQL() + public function getSQL(): string|array { return $this->parse()->getSqlExecutor()->getSqlStatements(); } @@ -201,12 +202,7 @@ public function getAST() return $parser->getAST(); } - /** - * {@inheritdoc} - * - * @return ResultSetMapping - */ - protected function getResultSetMapping() + protected function getResultSetMapping(): ResultSetMapping { // parse query or load from cache if ($this->_resultSetMapping === null) { @@ -270,10 +266,7 @@ private function parse(): ParserResult return $this->parserResult; } - /** - * {@inheritdoc} - */ - protected function _doExecute() + protected function _doExecute(): Result|int { $executor = $this->parse()->getSqlExecutor(); @@ -647,10 +640,7 @@ public function toIterable(iterable $parameters = [], $hydrationMode = self::HYD return parent::toIterable($parameters, $hydrationMode); } - /** - * {@inheritdoc} - */ - public function setHint($name, $value): self + public function setHint(string $name, mixed $value): static { $this->_state = self::STATE_DIRTY; @@ -730,7 +720,7 @@ protected function getHash(): string /** * Cleanup Query resource when clone is called. */ - public function __clone() + public function __clone(): void { parent::__clone();