/lib/Doctrine/MongoDB/CommandCursor.php
PHP | 260 lines | 111 code | 31 blank | 118 comment | 5 complexity | b2245ee6f7afa4d1d3a93aa6c85708fe MD5 | raw file
- <?php
- namespace Doctrine\MongoDB;
- use BadMethodCallException;
- use MongoCommandCursor;
- /**
- * Wrapper for the PHP MongoCommandCursor class.
- *
- * @since 1.2
- * @author Jeremy Mikola <jmikola@gmail.com>
- */
- class CommandCursor implements Iterator
- {
- /**
- * The MongoCommandCursor instance being wrapped.
- *
- * @var MongoCommandCursor
- */
- private $mongoCommandCursor;
- /**
- * Number of times to retry queries.
- *
- * @var integer
- */
- private $numRetries;
- private $batchSize;
- private $timeout;
- /**
- * Constructor.
- *
- * @param MongoCommandCursor $mongoCommandCursor MongoCommandCursor instance being wrapped
- * @param integer $numRetries Number of times to retry queries
- */
- public function __construct(MongoCommandCursor $mongoCommandCursor, $numRetries = 0)
- {
- $this->mongoCommandCursor = $mongoCommandCursor;
- $this->numRetries = (integer) $numRetries;
- }
- /**
- * Wrapper method for MongoCommandCursor::batchSize().
- *
- * @see http://php.net/manual/en/mongocommandcursor.batchsize.php
- * @param integer $num
- * @return $this
- */
- public function batchSize($num)
- {
- $this->batchSize = (integer) $num;
- $this->mongoCommandCursor->batchSize($num);
- return $this;
- }
- /**
- * Recreates the command cursor and counts its results.
- *
- * @see http://php.net/manual/en/countable.count.php
- * @return integer
- */
- public function count()
- {
- $cursor = $this;
- return $this->retry(function() use ($cursor) {
- return iterator_count($cursor);
- });
- }
- /**
- * Wrapper method for MongoCommandCursor::current().
- *
- * @see http://php.net/manual/en/iterator.current.php
- * @see http://php.net/manual/en/mongocommandcursor.current.php
- * @return array|null
- */
- public function current()
- {
- return $this->mongoCommandCursor->current();
- }
- /**
- * Wrapper method for MongoCommandCursor::dead().
- *
- * @see http://php.net/manual/en/mongocommandcursor.dead.php
- * @return boolean
- */
- public function dead()
- {
- return $this->mongoCommandCursor->dead();
- }
- /**
- * Returns the MongoCommandCursor instance being wrapped.
- *
- * @return \MongoCommandCursor
- */
- public function getMongoCommandCursor()
- {
- return $this->mongoCommandCursor;
- }
- /**
- * Rewind the cursor and return its first result.
- *
- * @see Iterator::getSingleResult()
- * @return array|null
- */
- public function getSingleResult()
- {
- $result = null;
- foreach ($this as $result) {
- break;
- }
- /* Avoid rewinding the cursor here, as that would re-execute the
- * command prematurely and later iteration will rewind on its own.
- */
- return $result;
- }
- /**
- * Wrapper method for MongoCommandCursor::info().
- *
- * @see http://php.net/manual/en/mongocommandcursor.info.php
- * @return array
- */
- public function info()
- {
- return $this->mongoCommandCursor->info();
- }
- /**
- * Wrapper method for MongoCommandCursor::key().
- *
- * @see http://php.net/manual/en/iterator.key.php
- * @see http://php.net/manual/en/mongocommandcursor.key.php
- * @return integer
- */
- public function key()
- {
- return $this->mongoCommandCursor->key();
- }
- /**
- * Wrapper method for MongoCommandCursor::next().
- *
- * @see http://php.net/manual/en/iterator.next.php
- * @see http://php.net/manual/en/mongocommandcursor.next.php
- */
- public function next()
- {
- $cursor = $this;
- $this->retry(function() use ($cursor) {
- $cursor->getMongoCommandCursor()->next();
- });
- }
- /**
- * Wrapper method for MongoCommandCursor::rewind().
- *
- * @see http://php.net/manual/en/iterator.rewind.php
- * @see http://php.net/manual/en/mongocommandcursor.rewind.php
- * @return array
- */
- public function rewind()
- {
- $cursor = $this;
- return $this->retry(function() use ($cursor) {
- return $cursor->getMongoCommandCursor()->rewind();
- });
- }
- /**
- * Wrapper method for MongoCommandCursor::timeout().
- *
- * @see http://php.net/manual/en/mongocommandcursor.timeout.php
- * @param integer $ms
- * @return $this
- * @throws BadMethodCallException if MongoCommandCursor::timeout() is not available
- */
- public function timeout($ms)
- {
- if ( ! method_exists('MongoCommandCursor', 'timeout')) {
- throw new BadMethodCallException('MongoCommandCursor::timeout() is not available');
- }
- $this->timeout = (integer) $ms;
- $this->mongoCommandCursor->timeout($ms);
- return $this;
- }
- /**
- * Return the cursor's results as an array.
- *
- * @see Iterator::toArray()
- * @return array
- */
- public function toArray()
- {
- $cursor = $this;
- return $this->retry(function() use ($cursor) {
- return iterator_to_array($cursor);
- });
- }
- /**
- * Wrapper method for MongoCommandCursor::valid().
- *
- * @see http://php.net/manual/en/iterator.valid.php
- * @see http://php.net/manual/en/mongocommandcursor.valid.php
- * @return boolean
- */
- public function valid()
- {
- return $this->mongoCommandCursor->valid();
- }
- /**
- * Conditionally retry a closure if it yields an exception.
- *
- * If the closure does not return successfully within the configured number
- * of retries, its first exception will be thrown.
- *
- * @param \Closure $retry
- * @return mixed
- */
- protected function retry(\Closure $retry)
- {
- if ($this->numRetries < 1) {
- return $retry();
- }
- $firstException = null;
- for ($i = 0; $i <= $this->numRetries; $i++) {
- try {
- return $retry();
- } catch (\MongoCursorException $e) {
- } catch (\MongoConnectionException $e) {
- }
- if ($firstException === null) {
- $firstException = $e;
- }
- if ($i === $this->numRetries) {
- throw $firstException;
- }
- }
- }
- }