| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665 | 
							- <?php
 - /*
 -  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 -  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 -  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 -  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 -  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 -  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 -  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 -  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 -  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 -  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 -  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 -  *
 -  * This software consists of voluntary contributions made by many individuals
 -  * and is licensed under the LGPL. For more information, see
 -  * <http://www.doctrine-project.org>.
 -  */
 - 
 - namespace Doctrine\ORM;
 - 
 - use Doctrine\DBAL\Types\Type,
 -     Doctrine\ORM\Query\QueryException;
 - 
 - /**
 -  * Base contract for ORM queries. Base class for Query and NativeQuery.
 -  *
 -  * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
 -  * @link    www.doctrine-project.org
 -  * @since   2.0
 -  * @version $Revision$
 -  * @author  Benjamin Eberlei <kontakt@beberlei.de>
 -  * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
 -  * @author  Jonathan Wage <jonwage@gmail.com>
 -  * @author  Roman Borschel <roman@code-factory.org>
 -  * @author  Konsta Vesterinen <kvesteri@cc.hut.fi>
 -  */
 - abstract class AbstractQuery
 - {
 -     /* Hydration mode constants */
 -     /**
 -      * Hydrates an object graph. This is the default behavior.
 -      */
 -     const HYDRATE_OBJECT = 1;
 -     /**
 -      * Hydrates an array graph.
 -      */
 -     const HYDRATE_ARRAY = 2;
 -     /**
 -      * Hydrates a flat, rectangular result set with scalar values.
 -      */
 -     const HYDRATE_SCALAR = 3;
 -     /**
 -      * Hydrates a single scalar value.
 -      */
 -     const HYDRATE_SINGLE_SCALAR = 4;
 - 
 -     /**
 -      * Very simple object hydrator (optimized for performance).
 -      */
 -     const HYDRATE_SIMPLEOBJECT = 5;
 - 
 -     /**
 -      * @var array The parameter map of this query.
 -      */
 -     protected $_params = array();
 - 
 -     /**
 -      * @var array The parameter type map of this query.
 -      */
 -     protected $_paramTypes = array();
 - 
 -     /**
 -      * @var ResultSetMapping The user-specified ResultSetMapping to use.
 -      */
 -     protected $_resultSetMapping;
 - 
 -     /**
 -      * @var Doctrine\ORM\EntityManager The entity manager used by this query object.
 -      */
 -     protected $_em;
 - 
 -     /**
 -      * @var array The map of query hints.
 -      */
 -     protected $_hints = array();
 - 
 -     /**
 -      * @var integer The hydration mode.
 -      */
 -     protected $_hydrationMode = self::HYDRATE_OBJECT;
 - 
 -     /**
 -      * The locally set cache driver used for caching result sets of this query.
 -      *
 -      * @var CacheDriver
 -      */
 -     protected $_resultCacheDriver;
 - 
 -     /**
 -      * Boolean flag for whether or not to cache the results of this query.
 -      *
 -      * @var boolean
 -      */
 -     protected $_useResultCache;
 - 
 -     /**
 -      * @var string The id to store the result cache entry under.
 -      */
 -     protected $_resultCacheId;
 - 
 -     /**
 -      * @var boolean Boolean value that indicates whether or not expire the result cache.
 -      */
 -     protected $_expireResultCache = false;
 - 
 -     /**
 -      * @var int Result Cache lifetime.
 -      */
 -     protected $_resultCacheTTL;
 - 
 -     /**
 -      * Initializes a new instance of a class derived from <tt>AbstractQuery</tt>.
 -      *
 -      * @param Doctrine\ORM\EntityManager $entityManager
 -      */
 -     public function __construct(EntityManager $em)
 -     {
 -         $this->_em = $em;
 -     }
 - 
 -     /**
 -      * Retrieves the associated EntityManager of this Query instance.
 -      *
 -      * @return Doctrine\ORM\EntityManager
 -      */
 -     public function getEntityManager()
 -     {
 -         return $this->_em;
 -     }
 - 
 -     /**
 -      * Frees the resources used by the query object.
 -      *
 -      * Resets Parameters, Parameter Types and Query Hints.
 -      *
 -      * @return void
 -      */
 -     public function free()
 -     {
 -         $this->_params = array();
 -         $this->_paramTypes = array();
 -         $this->_hints = array();
 -     }
 - 
 -     /**
 -      * Get all defined parameters.
 -      *
 -      * @return array The defined query parameters.
 -      */
 -     public function getParameters()
 -     {
 -         return $this->_params;
 -     }
 - 
 -     /**
 -      * Gets a query parameter.
 -      *
 -      * @param mixed $key The key (index or name) of the bound parameter.
 -      * @return mixed The value of the bound parameter.
 -      */
 -     public function getParameter($key)
 -     {
 -         return isset($this->_params[$key]) ? $this->_params[$key] : null;
 -     }
 - 
 -     /**
 -      * Gets the SQL query that corresponds to this query object.
 -      * The returned SQL syntax depends on the connection driver that is used
 -      * by this query object at the time of this method call.
 -      *
 -      * @return string SQL query
 -      */
 -     abstract public function getSQL();
 - 
 -     /**
 -      * Sets a query parameter.
 -      *
 -      * @param string|integer $key The parameter position or name.
 -      * @param mixed $value The parameter value.
 -      * @param string $type The parameter type. If specified, the given value will be run through
 -      *                     the type conversion of this type. This is usually not needed for
 -      *                     strings and numeric types.
 -      * @return Doctrine\ORM\AbstractQuery This query instance.
 -      */
 -     public function setParameter($key, $value, $type = null)
 -     {
 -         if ($type === null) {
 -             $type = Query\ParameterTypeInferer::inferType($value);
 -         }
 -         
 -         $this->_paramTypes[$key] = $type;
 -         $this->_params[$key] = $value;
 -         
 -         return $this;
 -     }
 - 
 -     /**
 -      * Sets a collection of query parameters.
 -      *
 -      * @param array $params
 -      * @param array $types
 -      * @return Doctrine\ORM\AbstractQuery This query instance.
 -      */
 -     public function setParameters(array $params, array $types = array())
 -     {
 -         foreach ($params as $key => $value) {
 -             if (isset($types[$key])) {
 -                 $this->setParameter($key, $value, $types[$key]);
 -             } else {
 -                 $this->setParameter($key, $value);
 -             }
 -         }
 -         return $this;
 -     }
 - 
 -     /**
 -      * Sets the ResultSetMapping that should be used for hydration.
 -      *
 -      * @param ResultSetMapping $rsm
 -      * @return Doctrine\ORM\AbstractQuery
 -      */
 -     public function setResultSetMapping(Query\ResultSetMapping $rsm)
 -     {
 -         $this->_resultSetMapping = $rsm;
 -         return $this;
 -     }
 - 
 -     /**
 -      * Defines a cache driver to be used for caching result sets.
 -      *
 -      * @param Doctrine\Common\Cache\Cache $driver Cache driver
 -      * @return Doctrine\ORM\AbstractQuery
 -      */
 -     public function setResultCacheDriver($resultCacheDriver = null)
 -     {
 -         if ($resultCacheDriver !== null && ! ($resultCacheDriver instanceof \Doctrine\Common\Cache\Cache)) {
 -             throw ORMException::invalidResultCacheDriver();
 -         }
 -         $this->_resultCacheDriver = $resultCacheDriver;
 -         if ($resultCacheDriver) {
 -             $this->_useResultCache = true;
 -         }
 -         return $this;
 -     }
 - 
 -     /**
 -      * Returns the cache driver used for caching result sets.
 -      *
 -      * @return Doctrine\Common\Cache\Cache Cache driver
 -      */
 -     public function getResultCacheDriver()
 -     {
 -         if ($this->_resultCacheDriver) {
 -             return $this->_resultCacheDriver;
 -         } else {
 -             return $this->_em->getConfiguration()->getResultCacheImpl();
 -         }
 -     }
 - 
 -     /**
 -      * Set whether or not to cache the results of this query and if so, for
 -      * how long and which ID to use for the cache entry.
 -      *
 -      * @param boolean $bool
 -      * @param integer $timeToLive
 -      * @param string $resultCacheId
 -      * @return Doctrine\ORM\AbstractQuery This query instance.
 -      */
 -     public function useResultCache($bool, $timeToLive = null, $resultCacheId = null)
 -     {
 -         $this->_useResultCache = $bool;
 -         if ($timeToLive) {
 -             $this->setResultCacheLifetime($timeToLive);
 -         }
 -         if ($resultCacheId) {
 -             $this->_resultCacheId = $resultCacheId;
 -         }
 -         return $this;
 -     }
 - 
 -     /**
 -      * Defines how long the result cache will be active before expire.
 -      *
 -      * @param integer $timeToLive How long the cache entry is valid.
 -      * @return Doctrine\ORM\AbstractQuery This query instance.
 -      */
 -     public function setResultCacheLifetime($timeToLive)
 -     {
 -         if ($timeToLive !== null) {
 -             $timeToLive = (int) $timeToLive;
 -         }
 - 
 -         $this->_resultCacheTTL = $timeToLive;
 -         return $this;
 -     }
 - 
 -     /**
 -      * Retrieves the lifetime of resultset cache.
 -      *
 -      * @return integer
 -      */
 -     public function getResultCacheLifetime()
 -     {
 -         return $this->_resultCacheTTL;
 -     }
 - 
 -     /**
 -      * Defines if the result cache is active or not.
 -      *
 -      * @param boolean $expire Whether or not to force resultset cache expiration.
 -      * @return Doctrine\ORM\AbstractQuery This query instance.
 -      */
 -     public function expireResultCache($expire = true)
 -     {
 -         $this->_expireResultCache = $expire;
 -         return $this;
 -     }
 - 
 -     /**
 -      * Retrieves if the resultset cache is active or not.
 -      *
 -      * @return boolean
 -      */
 -     public function getExpireResultCache()
 -     {
 -         return $this->_expireResultCache;
 -     }
 - 
 -     /**
 -      * Change the default fetch mode of an association for this query.
 -      *
 -      * $fetchMode can be one of ClassMetadata::FETCH_EAGER or ClassMetadata::FETCH_LAZY
 -      *
 -      * @param  string $class
 -      * @param  string $assocName
 -      * @param  int $fetchMode
 -      * @return AbstractQuery
 -      */
 -     public function setFetchMode($class, $assocName, $fetchMode)
 -     {
 -         if ($fetchMode !== Mapping\ClassMetadata::FETCH_EAGER) {
 -             $fetchMode = Mapping\ClassMetadata::FETCH_LAZY;
 -         }
 - 
 -         $this->_hints['fetchMode'][$class][$assocName] = $fetchMode;
 -         return $this;
 -     }
 - 
 -     /**
 -      * Defines the processing mode to be used during hydration / result set transformation.
 -      *
 -      * @param integer $hydrationMode Doctrine processing mode to be used during hydration process.
 -      *                               One of the Query::HYDRATE_* constants.
 -      * @return Doctrine\ORM\AbstractQuery This query instance.
 -      */
 -     public function setHydrationMode($hydrationMode)
 -     {
 -         $this->_hydrationMode = $hydrationMode;
 -         return $this;
 -     }
 - 
 -     /**
 -      * Gets the hydration mode currently used by the query.
 -      *
 -      * @return integer
 -      */
 -     public function getHydrationMode()
 -     {
 -         return $this->_hydrationMode;
 -     }
 - 
 -     /**
 -      * Gets the list of results for the query.
 -      *
 -      * Alias for execute(array(), $hydrationMode = HYDRATE_OBJECT).
 -      *
 -      * @return array
 -      */
 -     public function getResult($hydrationMode = self::HYDRATE_OBJECT)
 -     {
 -         return $this->execute(array(), $hydrationMode);
 -     }
 - 
 -     /**
 -      * Gets the array of results for the query.
 -      *
 -      * Alias for execute(array(), HYDRATE_ARRAY).
 -      *
 -      * @return array
 -      */
 -     public function getArrayResult()
 -     {
 -         return $this->execute(array(), self::HYDRATE_ARRAY);
 -     }
 - 
 -     /**
 -      * Gets the scalar results for the query.
 -      *
 -      * Alias for execute(array(), HYDRATE_SCALAR).
 -      *
 -      * @return array
 -      */
 -     public function getScalarResult()
 -     {
 -         return $this->execute(array(), self::HYDRATE_SCALAR);
 -     }
 - 
 -     /**
 -      * Get exactly one result or null.
 -      *
 -      * @throws NonUniqueResultException
 -      * @param int $hydrationMode
 -      * @return mixed
 -      */
 -     public function getOneOrNullResult($hydrationMode = null)
 -     {
 -         $result = $this->execute(array(), $hydrationMode);
 - 
 -         if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
 -             return null;
 -         }
 - 
 -         if (is_array($result)) {
 -             if (count($result) > 1) {
 -                 throw new NonUniqueResultException;
 -             }
 -             return array_shift($result);
 -         }
 - 
 -         return $result;
 -     }
 - 
 -     /**
 -      * Gets the single result of the query.
 -      *
 -      * Enforces the presence as well as the uniqueness of the result.
 -      *
 -      * If the result is not unique, a NonUniqueResultException is thrown.
 -      * If there is no result, a NoResultException is thrown.
 -      *
 -      * @param integer $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)
 -     {
 -         $result = $this->execute(array(), $hydrationMode);
 - 
 -         if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
 -             throw new NoResultException;
 -         }
 - 
 -         if (is_array($result)) {
 -             if (count($result) > 1) {
 -                 throw new NonUniqueResultException;
 -             }
 -             return array_shift($result);
 -         }
 - 
 -         return $result;
 -     }
 - 
 -     /**
 -      * Gets the single scalar result of the query.
 -      *
 -      * Alias for getSingleResult(HYDRATE_SINGLE_SCALAR).
 -      *
 -      * @return mixed
 -      * @throws QueryException If the query result is not unique.
 -      */
 -     public function getSingleScalarResult()
 -     {
 -         return $this->getSingleResult(self::HYDRATE_SINGLE_SCALAR);
 -     }
 - 
 -     /**
 -      * 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 Doctrine\ORM\AbstractQuery
 -      */
 -     public function setHint($name, $value)
 -     {
 -         $this->_hints[$name] = $value;
 -         return $this;
 -     }
 - 
 -     /**
 -      * 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)
 -     {
 -         return isset($this->_hints[$name]) ? $this->_hints[$name] : false;
 -     }
 - 
 -     /**
 -      * Return the key value map of query hints that are currently set.
 -      * 
 -      * @return array
 -      */
 -     public function getHints()
 -     {
 -         return $this->_hints;
 -     }
 - 
 -     /**
 -      * Executes the query and returns an IterableResult that can be used to incrementally
 -      * iterate over the result.
 -      *
 -      * @param array $params The query parameters.
 -      * @param integer $hydrationMode The hydration mode to use.
 -      * @return IterableResult
 -      */
 -     public function iterate(array $params = array(), $hydrationMode = null)
 -     {
 -         if ($hydrationMode !== null) {
 -             $this->setHydrationMode($hydrationMode);
 -         }
 - 
 -         if ($params) {
 -             $this->setParameters($params);
 -         }
 - 
 -         $stmt = $this->_doExecute();
 - 
 -         return $this->_em->newHydrator($this->_hydrationMode)->iterate(
 -             $stmt, $this->_resultSetMapping, $this->_hints
 -         );
 -     }
 - 
 -     /**
 -      * Executes the query.
 -      *
 -      * @param array $params Any additional query parameters.
 -      * @param integer $hydrationMode Processing mode to be used during the hydration process.
 -      * @return mixed
 -      */
 -     public function execute($params = array(), $hydrationMode = null)
 -     {
 -         if ($hydrationMode !== null) {
 -             $this->setHydrationMode($hydrationMode);
 -         }
 - 
 -         if ($params) {
 -             $this->setParameters($params);
 -         }
 - 
 -         // Check result cache
 -         if ($this->_useResultCache && $cacheDriver = $this->getResultCacheDriver()) {
 -             list($key, $hash) = $this->getResultCacheId();
 -             $cached = $this->_expireResultCache ? false : $cacheDriver->fetch($hash);
 - 
 -             if ($cached === false || !isset($cached[$key])) {
 -                 // Cache miss.
 -                 $stmt = $this->_doExecute();
 - 
 -                 $result = $this->_em->getHydrator($this->_hydrationMode)->hydrateAll(
 -                     $stmt, $this->_resultSetMapping, $this->_hints
 -                 );
 - 
 -                 $cacheDriver->save($hash, array($key => $result), $this->_resultCacheTTL);
 - 
 -                 return $result;
 -             } else {
 -                 // Cache hit.
 -                 return $cached[$key];
 -             }
 -         }
 - 
 -         $stmt = $this->_doExecute();
 - 
 -         if (is_numeric($stmt)) {
 -             return $stmt;
 -         }
 - 
 -         return $this->_em->getHydrator($this->_hydrationMode)->hydrateAll(
 -                 $stmt, $this->_resultSetMapping, $this->_hints
 -                 );
 -     }
 - 
 -     /**
 -      * Set the result cache id to use to store the result set cache entry.
 -      * If this is not explicitely set by the developer then a hash is automatically
 -      * generated for you.
 -      *
 -      * @param string $id
 -      * @return Doctrine\ORM\AbstractQuery This query instance.
 -      */
 -     public function setResultCacheId($id)
 -     {
 -         $this->_resultCacheId = $id;
 -         return $this;
 -     }
 - 
 -     /**
 -      * Get the result cache id to use to store the result set cache entry.
 -      * Will return the configured id if it exists otherwise a hash will be
 -      * automatically generated for you.
 -      *
 -      * @return array ($key, $hash)
 -      */
 -     protected function getResultCacheId()
 -     {
 -         if ($this->_resultCacheId) {
 -             return array($this->_resultCacheId, $this->_resultCacheId);
 -         } else {
 -             $params = $this->_params;
 -             foreach ($params AS $key => $value) {
 -                 if (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value))) {
 -                     if ($this->_em->getUnitOfWork()->getEntityState($value) == UnitOfWork::STATE_MANAGED) {
 -                         $idValues = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
 -                     } else {
 -                         $class = $this->_em->getClassMetadata(get_class($value));
 -                         $idValues = $class->getIdentifierValues($value);
 -                     }
 -                     $params[$key] = $idValues;
 -                 } else {
 -                     $params[$key] = $value;
 -                 }
 -             }
 - 
 -             $sql = $this->getSql();
 -             ksort($this->_hints);
 -             $key = implode(";", (array)$sql) . var_export($params, true) .
 -                 var_export($this->_hints, true)."&hydrationMode=".$this->_hydrationMode;
 -             return array($key, md5($key));
 -         }
 -     }
 - 
 -     /**
 -      * Executes the query and returns a the resulting Statement object.
 -      *
 -      * @return Doctrine\DBAL\Driver\Statement The executed database statement that holds the results.
 -      */
 -     abstract protected function _doExecute();
 - 
 -     /**
 -      * Cleanup Query resource when clone is called.
 -      *
 -      * @return void
 -      */
 -     public function __clone()
 -     {
 -         $this->_params = array();
 -         $this->_paramTypes = array();
 -         $this->_hints = array();
 -     }
 - }
 
 
  |