Yii2 framework backup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
3.5 KiB

<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\db;
use yii\base\Object;
/**
* BatchQueryResult represents a batch query from which you can retrieve data in batches.
*
* You usually do not instantiate BatchQueryResult directly. Instead, you obtain it by
* calling [[Query::batch()]] or [[Query::each()]]. Because BatchQueryResult implements the `Iterator` interface,
* you can iterate it to obtain a batch of data in each iteration. For example,
*
* ```php
* $query = (new Query)->from('tbl_user');
* foreach ($query->batch() as $i => $users) {
* // $users represents the rows in the $i-th batch
* }
* ```
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class BatchQueryResult extends Object implements \Iterator
{
/**
* @var Connection the DB connection to be used when performing batch query.
* If null, the "db" application component will be used.
*/
public $db;
/**
* @var Query the query object associated with this batch query.
* Do not modify this property directly unless after [[reset()]] is called explicitly.
*/
public $query;
/**
* @var DataReader the data reader associated with this batch query.
* Do not modify this property directly unless after [[reset()]] is called explicitly.
*/
public $dataReader;
/**
* @var integer the number of rows to be returned in each batch.
*/
public $batchSize = 100;
private $_data;
private $_key;
private $_index = -1;
/**
* Destructor.
*/
public function __destruct()
{
// make sure cursor is closed
$this->reset();
}
/**
* Resets the batch query.
* This method will clean up the existing batch query so that a new batch query can be performed.
*/
public function reset()
{
if ($this->dataReader !== null) {
$this->dataReader->close();
}
$this->dataReader = null;
$this->_data = null;
$this->_index = -1;
}
/**
* Resets the iterator to the initial state.
* This method is required by the interface Iterator.
*/
public function rewind()
{
$this->reset();
$this->next();
}
/**
* Returns the index of the current dataset.
* This method is required by the interface Iterator.
* @return integer the index of the current row.
*/
public function key()
{
return $this->batchSize == 1 ? $this->_key : $this->_index;
}
/**
* Returns the current dataset.
* This method is required by the interface Iterator.
* @return mixed the current dataset.
*/
public function current()
{
return $this->_data;
}
/**
* Moves the internal pointer to the next dataset.
* This method is required by the interface Iterator.
*/
public function next()
{
if ($this->dataReader === null) {
$this->dataReader = $this->query->createCommand($this->db)->query();
$this->_index = 0;
} else {
$this->_index++;
}
$rows = [];
$count = 0;
while ($count++ < $this->batchSize && ($row = $this->dataReader->read())) {
$rows[] = $row;
}
if (empty($rows)) {
$this->_data = null;
} else {
$this->_data = $this->query->prepareResult($rows);
if ($this->batchSize == 1) {
$row = reset($this->_data);
$this->_key = key($this->_data);
$this->_data = $row;
}
}
}
/**
* Returns whether there is a valid dataset at the current position.
* This method is required by the interface Iterator.
* @return boolean whether there is a valid dataset at the current position.
*/
public function valid()
{
return $this->_data !== null;
}
}