composer package updates
[openemr.git] / vendor / doctrine / orm / lib / Doctrine / ORM / AbstractQuery.php
blob7ca5f51ca191f85ec5f4c5cd0cfbc8ec4ec5cb35
1 <?php
2 /*
3 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 * This software consists of voluntary contributions made by many individuals
16 * and is licensed under the MIT license. For more information, see
17 * <http://www.doctrine-project.org>.
20 namespace Doctrine\ORM;
22 use Doctrine\Common\Util\ClassUtils;
23 use Doctrine\Common\Collections\Collection;
24 use Doctrine\Common\Collections\ArrayCollection;
26 use Doctrine\ORM\Query\Parameter;
27 use Doctrine\ORM\Cache\QueryCacheKey;
28 use Doctrine\DBAL\Cache\QueryCacheProfile;
30 use Doctrine\ORM\Cache;
31 use Doctrine\ORM\Query\ResultSetMapping;
33 /**
34 * Base contract for ORM queries. Base class for Query and NativeQuery.
36 * @link www.doctrine-project.org
37 * @since 2.0
38 * @author Benjamin Eberlei <kontakt@beberlei.de>
39 * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
40 * @author Jonathan Wage <jonwage@gmail.com>
41 * @author Roman Borschel <roman@code-factory.org>
42 * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
44 abstract class AbstractQuery
46 /* Hydration mode constants */
48 /**
49 * Hydrates an object graph. This is the default behavior.
51 const HYDRATE_OBJECT = 1;
53 /**
54 * Hydrates an array graph.
56 const HYDRATE_ARRAY = 2;
58 /**
59 * Hydrates a flat, rectangular result set with scalar values.
61 const HYDRATE_SCALAR = 3;
63 /**
64 * Hydrates a single scalar value.
66 const HYDRATE_SINGLE_SCALAR = 4;
68 /**
69 * Very simple object hydrator (optimized for performance).
71 const HYDRATE_SIMPLEOBJECT = 5;
73 /**
74 * The parameter map of this query.
76 * @var \Doctrine\Common\Collections\ArrayCollection
78 protected $parameters;
80 /**
81 * The user-specified ResultSetMapping to use.
83 * @var \Doctrine\ORM\Query\ResultSetMapping
85 protected $_resultSetMapping;
87 /**
88 * The entity manager used by this query object.
90 * @var EntityManagerInterface
92 protected $_em;
94 /**
95 * The map of query hints.
97 * @var array
99 protected $_hints = array();
102 * The hydration mode.
104 * @var integer
106 protected $_hydrationMode = self::HYDRATE_OBJECT;
109 * @param \Doctrine\DBAL\Cache\QueryCacheProfile
111 protected $_queryCacheProfile;
114 * Whether or not expire the result cache.
116 * @var boolean
118 protected $_expireResultCache = false;
121 * @param \Doctrine\DBAL\Cache\QueryCacheProfile
123 protected $_hydrationCacheProfile;
126 * Whether to use second level cache, if available.
128 * @var boolean
130 protected $cacheable = false;
133 * @var boolean
135 protected $hasCache = false;
138 * Second level cache region name.
140 * @var string|null
142 protected $cacheRegion;
145 * Second level query cache mode.
147 * @var integer|null
149 protected $cacheMode;
152 * @var \Doctrine\ORM\Cache\Logging\CacheLogger|null
154 protected $cacheLogger;
157 * @var integer
159 protected $lifetime = 0;
162 * Initializes a new instance of a class derived from <tt>AbstractQuery</tt>.
164 * @param \Doctrine\ORM\EntityManagerInterface $em
166 public function __construct(EntityManagerInterface $em)
168 $this->_em = $em;
169 $this->parameters = new ArrayCollection();
170 $this->_hints = $em->getConfiguration()->getDefaultQueryHints();
171 $this->hasCache = $this->_em->getConfiguration()->isSecondLevelCacheEnabled();
173 if ($this->hasCache) {
174 $this->cacheLogger = $em->getConfiguration()
175 ->getSecondLevelCacheConfiguration()
176 ->getCacheLogger();
182 * Enable/disable second level query (result) caching for this query.
184 * @param boolean $cacheable
186 * @return static This query instance.
188 public function setCacheable($cacheable)
190 $this->cacheable = (boolean) $cacheable;
192 return $this;
196 * @return boolean TRUE if the query results are enable for second level cache, FALSE otherwise.
198 public function isCacheable()
200 return $this->cacheable;
204 * @param string $cacheRegion
206 * @return static This query instance.
208 public function setCacheRegion($cacheRegion)
210 $this->cacheRegion = (string) $cacheRegion;
212 return $this;
216 * Obtain the name of the second level query cache region in which query results will be stored
218 * @return The cache region name; NULL indicates the default region.
220 public function getCacheRegion()
222 return $this->cacheRegion;
226 * @return boolean TRUE if the query cache and second level cache are enabled, FALSE otherwise.
228 protected function isCacheEnabled()
230 return $this->cacheable && $this->hasCache;
234 * @return integer
236 public function getLifetime()
238 return $this->lifetime;
242 * Sets the life-time for this query into second level cache.
244 * @param integer $lifetime
246 * @return static This query instance.
248 public function setLifetime($lifetime)
250 $this->lifetime = (integer) $lifetime;
252 return $this;
256 * @return integer
258 public function getCacheMode()
260 return $this->cacheMode;
264 * @param integer $cacheMode
266 * @return static This query instance.
268 public function setCacheMode($cacheMode)
270 $this->cacheMode = (integer) $cacheMode;
272 return $this;
276 * Gets the SQL query that corresponds to this query object.
277 * The returned SQL syntax depends on the connection driver that is used
278 * by this query object at the time of this method call.
280 * @return string SQL query
282 abstract public function getSQL();
285 * Retrieves the associated EntityManager of this Query instance.
287 * @return \Doctrine\ORM\EntityManager
289 public function getEntityManager()
291 return $this->_em;
295 * Frees the resources used by the query object.
297 * Resets Parameters, Parameter Types and Query Hints.
299 * @return void
301 public function free()
303 $this->parameters = new ArrayCollection();
305 $this->_hints = $this->_em->getConfiguration()->getDefaultQueryHints();
309 * Get all defined parameters.
311 * @return \Doctrine\Common\Collections\ArrayCollection The defined query parameters.
313 public function getParameters()
315 return $this->parameters;
319 * Gets a query parameter.
321 * @param mixed $key The key (index or name) of the bound parameter.
323 * @return Query\Parameter|null The value of the bound parameter, or NULL if not available.
325 public function getParameter($key)
327 $filteredParameters = $this->parameters->filter(
328 function (Query\Parameter $parameter) use ($key) {
329 $parameterName = $parameter->getName();
331 return $key === $parameterName || (string) $key === (string) $parameterName;
335 return ! $filteredParameters->isEmpty() ? $filteredParameters->first() : null;
339 * Sets a collection of query parameters.
341 * @param \Doctrine\Common\Collections\ArrayCollection|array $parameters
343 * @return static This query instance.
345 public function setParameters($parameters)
347 // BC compatibility with 2.3-
348 if (is_array($parameters)) {
349 $parameterCollection = new ArrayCollection();
351 foreach ($parameters as $key => $value) {
352 $parameterCollection->add(new Parameter($key, $value));
355 $parameters = $parameterCollection;
358 $this->parameters = $parameters;
360 return $this;
364 * Sets a query parameter.
366 * @param string|int $key The parameter position or name.
367 * @param mixed $value The parameter value.
368 * @param string|null $type The parameter type. If specified, the given value will be run through
369 * the type conversion of this type. This is usually not needed for
370 * strings and numeric types.
372 * @return static This query instance.
374 public function setParameter($key, $value, $type = null)
376 $existingParameter = $this->getParameter($key);
378 if ($existingParameter !== null) {
379 $existingParameter->setValue($value, $type);
381 return $this;
384 $this->parameters->add(new Parameter($key, $value, $type));
386 return $this;
390 * Processes an individual parameter value.
392 * @param mixed $value
394 * @return array
396 * @throws \Doctrine\ORM\ORMInvalidArgumentException
398 public function processParameterValue($value)
400 if (is_scalar($value)) {
401 return $value;
404 if ($value instanceof Collection) {
405 $value = $value->toArray();
408 if (is_array($value)) {
409 foreach ($value as $key => $paramValue) {
410 $paramValue = $this->processParameterValue($paramValue);
411 $value[$key] = is_array($paramValue) ? reset($paramValue) : $paramValue;
414 return $value;
417 if (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($value))) {
418 $value = $this->_em->getUnitOfWork()->getSingleIdentifierValue($value);
420 if ($value === null) {
421 throw ORMInvalidArgumentException::invalidIdentifierBindingEntity();
425 if ($value instanceof Mapping\ClassMetadata) {
426 return $value->name;
429 return $value;
433 * Sets the ResultSetMapping that should be used for hydration.
435 * @param \Doctrine\ORM\Query\ResultSetMapping $rsm
437 * @return static This query instance.
439 public function setResultSetMapping(Query\ResultSetMapping $rsm)
441 $this->translateNamespaces($rsm);
442 $this->_resultSetMapping = $rsm;
444 return $this;
448 * Gets the ResultSetMapping used for hydration.
450 * @return \Doctrine\ORM\Query\ResultSetMapping
452 protected function getResultSetMapping()
454 return $this->_resultSetMapping;
458 * Allows to translate entity namespaces to full qualified names.
460 * @param Query\ResultSetMapping $rsm
462 * @return void
464 private function translateNamespaces(Query\ResultSetMapping $rsm)
466 $translate = function ($alias) {
467 return $this->_em->getClassMetadata($alias)->getName();
470 $rsm->aliasMap = array_map($translate, $rsm->aliasMap);
471 $rsm->declaringClasses = array_map($translate, $rsm->declaringClasses);
475 * Set a cache profile for hydration caching.
477 * If no result cache driver is set in the QueryCacheProfile, the default
478 * result cache driver is used from the configuration.
480 * Important: Hydration caching does NOT register entities in the
481 * UnitOfWork when retrieved from the cache. Never use result cached
482 * entities for requests that also flush the EntityManager. If you want
483 * some form of caching with UnitOfWork registration you should use
484 * {@see AbstractQuery::setResultCacheProfile()}.
486 * @example
487 * $lifetime = 100;
488 * $resultKey = "abc";
489 * $query->setHydrationCacheProfile(new QueryCacheProfile());
490 * $query->setHydrationCacheProfile(new QueryCacheProfile($lifetime, $resultKey));
492 * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
494 * @return static This query instance.
496 public function setHydrationCacheProfile(QueryCacheProfile $profile = null)
498 if ( ! $profile->getResultCacheDriver()) {
499 $resultCacheDriver = $this->_em->getConfiguration()->getHydrationCacheImpl();
500 $profile = $profile->setResultCacheDriver($resultCacheDriver);
503 $this->_hydrationCacheProfile = $profile;
505 return $this;
509 * @return \Doctrine\DBAL\Cache\QueryCacheProfile
511 public function getHydrationCacheProfile()
513 return $this->_hydrationCacheProfile;
517 * Set a cache profile for the result cache.
519 * If no result cache driver is set in the QueryCacheProfile, the default
520 * result cache driver is used from the configuration.
522 * @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
524 * @return static This query instance.
526 public function setResultCacheProfile(QueryCacheProfile $profile = null)
528 if ($profile !== null && ! $profile->getResultCacheDriver()) {
529 $resultCacheDriver = $this->_em->getConfiguration()->getResultCacheImpl();
530 $profile = $profile->setResultCacheDriver($resultCacheDriver);
533 $this->_queryCacheProfile = $profile;
535 return $this;
539 * Defines a cache driver to be used for caching result sets and implicitly enables caching.
541 * @param \Doctrine\Common\Cache\Cache|null $resultCacheDriver Cache driver
543 * @return static This query instance.
545 * @throws ORMException
547 public function setResultCacheDriver($resultCacheDriver = null)
549 if ($resultCacheDriver !== null && ! ($resultCacheDriver instanceof \Doctrine\Common\Cache\Cache)) {
550 throw ORMException::invalidResultCacheDriver();
553 $this->_queryCacheProfile = $this->_queryCacheProfile
554 ? $this->_queryCacheProfile->setResultCacheDriver($resultCacheDriver)
555 : new QueryCacheProfile(0, null, $resultCacheDriver);
557 return $this;
561 * Returns the cache driver used for caching result sets.
563 * @deprecated
565 * @return \Doctrine\Common\Cache\Cache Cache driver
567 public function getResultCacheDriver()
569 if ($this->_queryCacheProfile && $this->_queryCacheProfile->getResultCacheDriver()) {
570 return $this->_queryCacheProfile->getResultCacheDriver();
573 return $this->_em->getConfiguration()->getResultCacheImpl();
577 * Set whether or not to cache the results of this query and if so, for
578 * how long and which ID to use for the cache entry.
580 * @param boolean $bool
581 * @param integer $lifetime
582 * @param string $resultCacheId
584 * @return static This query instance.
586 public function useResultCache($bool, $lifetime = null, $resultCacheId = null)
588 if ($bool) {
589 $this->setResultCacheLifetime($lifetime);
590 $this->setResultCacheId($resultCacheId);
592 return $this;
595 $this->_queryCacheProfile = null;
597 return $this;
601 * Defines how long the result cache will be active before expire.
603 * @param integer $lifetime How long the cache entry is valid.
605 * @return static This query instance.
607 public function setResultCacheLifetime($lifetime)
609 $lifetime = ($lifetime !== null) ? (int) $lifetime : 0;
611 $this->_queryCacheProfile = $this->_queryCacheProfile
612 ? $this->_queryCacheProfile->setLifetime($lifetime)
613 : new QueryCacheProfile($lifetime, null, $this->_em->getConfiguration()->getResultCacheImpl());
615 return $this;
619 * Retrieves the lifetime of resultset cache.
621 * @deprecated
623 * @return integer
625 public function getResultCacheLifetime()
627 return $this->_queryCacheProfile ? $this->_queryCacheProfile->getLifetime() : 0;
631 * Defines if the result cache is active or not.
633 * @param boolean $expire Whether or not to force resultset cache expiration.
635 * @return static This query instance.
637 public function expireResultCache($expire = true)
639 $this->_expireResultCache = $expire;
641 return $this;
645 * Retrieves if the resultset cache is active or not.
647 * @return boolean
649 public function getExpireResultCache()
651 return $this->_expireResultCache;
655 * @return QueryCacheProfile
657 public function getQueryCacheProfile()
659 return $this->_queryCacheProfile;
663 * Change the default fetch mode of an association for this query.
665 * $fetchMode can be one of ClassMetadata::FETCH_EAGER or ClassMetadata::FETCH_LAZY
667 * @param string $class
668 * @param string $assocName
669 * @param int $fetchMode
671 * @return static This query instance.
673 public function setFetchMode($class, $assocName, $fetchMode)
675 if ($fetchMode !== Mapping\ClassMetadata::FETCH_EAGER) {
676 $fetchMode = Mapping\ClassMetadata::FETCH_LAZY;
679 $this->_hints['fetchMode'][$class][$assocName] = $fetchMode;
681 return $this;
685 * Defines the processing mode to be used during hydration / result set transformation.
687 * @param integer $hydrationMode Doctrine processing mode to be used during hydration process.
688 * One of the Query::HYDRATE_* constants.
690 * @return static This query instance.
692 public function setHydrationMode($hydrationMode)
694 $this->_hydrationMode = $hydrationMode;
696 return $this;
700 * Gets the hydration mode currently used by the query.
702 * @return integer
704 public function getHydrationMode()
706 return $this->_hydrationMode;
710 * Gets the list of results for the query.
712 * Alias for execute(null, $hydrationMode = HYDRATE_OBJECT).
714 * @param int $hydrationMode
716 * @return array
718 public function getResult($hydrationMode = self::HYDRATE_OBJECT)
720 return $this->execute(null, $hydrationMode);
724 * Gets the array of results for the query.
726 * Alias for execute(null, HYDRATE_ARRAY).
728 * @return array
730 public function getArrayResult()
732 return $this->execute(null, self::HYDRATE_ARRAY);
736 * Gets the scalar results for the query.
738 * Alias for execute(null, HYDRATE_SCALAR).
740 * @return array
742 public function getScalarResult()
744 return $this->execute(null, self::HYDRATE_SCALAR);
748 * Get exactly one result or null.
750 * @param int $hydrationMode
752 * @return mixed
754 * @throws NonUniqueResultException
756 public function getOneOrNullResult($hydrationMode = null)
758 try {
759 $result = $this->execute(null, $hydrationMode);
760 } catch (NoResultException $e) {
761 return null;
765 if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
766 return null;
769 if ( ! is_array($result)) {
770 return $result;
773 if (count($result) > 1) {
774 throw new NonUniqueResultException;
777 return array_shift($result);
781 * Gets the single result of the query.
783 * Enforces the presence as well as the uniqueness of the result.
785 * If the result is not unique, a NonUniqueResultException is thrown.
786 * If there is no result, a NoResultException is thrown.
788 * @param integer $hydrationMode
790 * @return mixed
792 * @throws NonUniqueResultException If the query result is not unique.
793 * @throws NoResultException If the query returned no result.
795 public function getSingleResult($hydrationMode = null)
797 $result = $this->execute(null, $hydrationMode);
799 if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
800 throw new NoResultException;
803 if ( ! is_array($result)) {
804 return $result;
807 if (count($result) > 1) {
808 throw new NonUniqueResultException;
811 return array_shift($result);
815 * Gets the single scalar result of the query.
817 * Alias for getSingleResult(HYDRATE_SINGLE_SCALAR).
819 * @return mixed
821 * @throws NonUniqueResultException If the query result is not unique.
822 * @throws NoResultException If the query returned no result.
824 public function getSingleScalarResult()
826 return $this->getSingleResult(self::HYDRATE_SINGLE_SCALAR);
830 * Sets a query hint. If the hint name is not recognized, it is silently ignored.
832 * @param string $name The name of the hint.
833 * @param mixed $value The value of the hint.
835 * @return static This query instance.
837 public function setHint($name, $value)
839 $this->_hints[$name] = $value;
841 return $this;
845 * Gets the value of a query hint. If the hint name is not recognized, FALSE is returned.
847 * @param string $name The name of the hint.
849 * @return mixed The value of the hint or FALSE, if the hint name is not recognized.
851 public function getHint($name)
853 return isset($this->_hints[$name]) ? $this->_hints[$name] : false;
857 * Check if the query has a hint
859 * @param string $name The name of the hint
861 * @return bool False if the query does not have any hint
863 public function hasHint($name)
865 return isset($this->_hints[$name]);
869 * Return the key value map of query hints that are currently set.
871 * @return array
873 public function getHints()
875 return $this->_hints;
879 * Executes the query and returns an IterableResult that can be used to incrementally
880 * iterate over the result.
882 * @param ArrayCollection|array|null $parameters The query parameters.
883 * @param integer|null $hydrationMode The hydration mode to use.
885 * @return \Doctrine\ORM\Internal\Hydration\IterableResult
887 public function iterate($parameters = null, $hydrationMode = null)
889 if ($hydrationMode !== null) {
890 $this->setHydrationMode($hydrationMode);
893 if ( ! empty($parameters)) {
894 $this->setParameters($parameters);
897 $rsm = $this->getResultSetMapping();
898 $stmt = $this->_doExecute();
900 return $this->_em->newHydrator($this->_hydrationMode)->iterate($stmt, $rsm, $this->_hints);
904 * Executes the query.
906 * @param ArrayCollection|array|null $parameters Query parameters.
907 * @param integer|null $hydrationMode Processing mode to be used during the hydration process.
909 * @return mixed
911 public function execute($parameters = null, $hydrationMode = null)
913 if ($this->cacheable && $this->isCacheEnabled()) {
914 return $this->executeUsingQueryCache($parameters, $hydrationMode);
917 return $this->executeIgnoreQueryCache($parameters, $hydrationMode);
921 * Execute query ignoring second level cache.
923 * @param ArrayCollection|array|null $parameters
924 * @param integer|null $hydrationMode
926 * @return mixed
928 private function executeIgnoreQueryCache($parameters = null, $hydrationMode = null)
930 if ($hydrationMode !== null) {
931 $this->setHydrationMode($hydrationMode);
934 if ( ! empty($parameters)) {
935 $this->setParameters($parameters);
938 $setCacheEntry = function() {};
940 if ($this->_hydrationCacheProfile !== null) {
941 list($cacheKey, $realCacheKey) = $this->getHydrationCacheId();
943 $queryCacheProfile = $this->getHydrationCacheProfile();
944 $cache = $queryCacheProfile->getResultCacheDriver();
945 $result = $cache->fetch($cacheKey);
947 if (isset($result[$realCacheKey])) {
948 return $result[$realCacheKey];
951 if ( ! $result) {
952 $result = array();
955 $setCacheEntry = function($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) {
956 $result[$realCacheKey] = $data;
958 $cache->save($cacheKey, $result, $queryCacheProfile->getLifetime());
962 $stmt = $this->_doExecute();
964 if (is_numeric($stmt)) {
965 $setCacheEntry($stmt);
967 return $stmt;
970 $rsm = $this->getResultSetMapping();
971 $data = $this->_em->newHydrator($this->_hydrationMode)->hydrateAll($stmt, $rsm, $this->_hints);
973 $setCacheEntry($data);
975 return $data;
979 * Load from second level cache or executes the query and put into cache.
981 * @param ArrayCollection|array|null $parameters
982 * @param integer|null $hydrationMode
984 * @return mixed
986 private function executeUsingQueryCache($parameters = null, $hydrationMode = null)
988 $rsm = $this->getResultSetMapping();
989 $queryCache = $this->_em->getCache()->getQueryCache($this->cacheRegion);
990 $queryKey = new QueryCacheKey(
991 $this->getHash(),
992 $this->lifetime,
993 $this->cacheMode ?: Cache::MODE_NORMAL,
994 $this->getTimestampKey()
997 $result = $queryCache->get($queryKey, $rsm, $this->_hints);
999 if ($result !== null) {
1000 if ($this->cacheLogger) {
1001 $this->cacheLogger->queryCacheHit($queryCache->getRegion()->getName(), $queryKey);
1004 return $result;
1007 $result = $this->executeIgnoreQueryCache($parameters, $hydrationMode);
1008 $cached = $queryCache->put($queryKey, $rsm, $result, $this->_hints);
1010 if ($this->cacheLogger) {
1011 $this->cacheLogger->queryCacheMiss($queryCache->getRegion()->getName(), $queryKey);
1013 if ($cached) {
1014 $this->cacheLogger->queryCachePut($queryCache->getRegion()->getName(), $queryKey);
1018 return $result;
1022 * @return \Doctrine\ORM\Cache\TimestampCacheKey|null
1024 private function getTimestampKey()
1026 $entityName = reset($this->_resultSetMapping->aliasMap);
1028 if (empty($entityName)) {
1029 return null;
1032 $metadata = $this->_em->getClassMetadata($entityName);
1034 return new Cache\TimestampCacheKey($metadata->rootEntityName);
1038 * Get the result cache id to use to store the result set cache entry.
1039 * Will return the configured id if it exists otherwise a hash will be
1040 * automatically generated for you.
1042 * @return array ($key, $hash)
1044 protected function getHydrationCacheId()
1046 $parameters = array();
1048 foreach ($this->getParameters() as $parameter) {
1049 $parameters[$parameter->getName()] = $this->processParameterValue($parameter->getValue());
1052 $sql = $this->getSQL();
1053 $queryCacheProfile = $this->getHydrationCacheProfile();
1054 $hints = $this->getHints();
1055 $hints['hydrationMode'] = $this->getHydrationMode();
1057 ksort($hints);
1059 return $queryCacheProfile->generateCacheKeys($sql, $parameters, $hints);
1063 * Set the result cache id to use to store the result set cache entry.
1064 * If this is not explicitly set by the developer then a hash is automatically
1065 * generated for you.
1067 * @param string $id
1069 * @return static This query instance.
1071 public function setResultCacheId($id)
1073 $this->_queryCacheProfile = $this->_queryCacheProfile
1074 ? $this->_queryCacheProfile->setCacheKey($id)
1075 : new QueryCacheProfile(0, $id, $this->_em->getConfiguration()->getResultCacheImpl());
1077 return $this;
1081 * Get the result cache id to use to store the result set cache entry if set.
1083 * @deprecated
1085 * @return string
1087 public function getResultCacheId()
1089 return $this->_queryCacheProfile ? $this->_queryCacheProfile->getCacheKey() : null;
1093 * Executes the query and returns a the resulting Statement object.
1095 * @return \Doctrine\DBAL\Driver\Statement The executed database statement that holds the results.
1097 abstract protected function _doExecute();
1100 * Cleanup Query resource when clone is called.
1102 * @return void
1104 public function __clone()
1106 $this->parameters = new ArrayCollection();
1108 $this->_hints = array();
1109 $this->_hints = $this->_em->getConfiguration()->getDefaultQueryHints();
1113 * Generates a string of currently query to use for the cache second level cache.
1115 * @return string
1117 protected function getHash()
1119 $query = $this->getSQL();
1120 $hints = $this->getHints();
1121 $params = array_map(function(Parameter $parameter) {
1122 // Small optimization
1123 // Does not invoke processParameterValue for scalar values
1124 if (is_scalar($value = $parameter->getValue())) {
1125 return $value;
1128 return $this->processParameterValue($value);
1129 }, $this->parameters->getValues());
1131 ksort($hints);
1133 return sha1($query . '-' . serialize($params) . '-' . serialize($hints));