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.
		
		
		
		
			
				
					234 lines
				
				6.1 KiB
			
		
		
			
		
	
	
					234 lines
				
				6.1 KiB
			| 
											14 years ago
										 | <?php
 | ||
|  | /**
 | ||
|  |  * ActiveQuery class file.
 | ||
|  |  *
 | ||
|  |  * @author Qiang Xue <qiang.xue@gmail.com>
 | ||
|  |  * @link http://www.yiiframework.com/
 | ||
|  |  * @copyright Copyright © 2008-2012 Yii Software LLC
 | ||
|  |  * @license http://www.yiiframework.com/license/
 | ||
|  |  */
 | ||
|  | 
 | ||
|  | namespace yii\db\ar;
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * ActiveFinder.php is ...
 | ||
|  |  * todo: add SQL monitor
 | ||
|  |  *
 | ||
|  |  * @author Qiang Xue <qiang.xue@gmail.com>
 | ||
|  |  * @since 2.0
 | ||
|  |  */
 | ||
|  | class ActiveQuery extends \yii\db\dao\BaseQuery implements \IteratorAggregate, \ArrayAccess, \Countable
 | ||
|  | {
 | ||
|  | 	public $modelClass;
 | ||
|  | 
 | ||
|  | 	public $with;
 | ||
|  | 	public $alias;
 | ||
|  | 	public $index;
 | ||
|  | 
 | ||
|  | 	private $_count;
 | ||
|  | 	private $_sql;
 | ||
|  | 	private $_countSql;
 | ||
|  | 	private $_asArray;
 | ||
|  | 	private $_records;
 | ||
|  | 
 | ||
|  | 	public function all()
 | ||
|  | 	{
 | ||
|  | 		return $this->performQuery();
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	public function one()
 | ||
|  | 	{
 | ||
|  | 		$this->limit = 1;
 | ||
|  | 		$records = $this->performQuery();
 | ||
|  | 		if (isset($records[0])) {
 | ||
|  | 			$this->_count = 1;
 | ||
|  | 			return $records[0];
 | ||
|  | 		} else {
 | ||
|  | 			$this->_count = 0;
 | ||
|  | 			return null;
 | ||
|  | 		}
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	public function asArray($value = true)
 | ||
|  | 	{
 | ||
|  | 		$this->_asArray = $value;
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	protected function performQuery()
 | ||
|  | 	{
 | ||
|  | 		$class = $this->modelClass;
 | ||
|  | 		$db = $class::getDbConnection();
 | ||
|  | 		$this->_sql = $this->getSql($db);
 | ||
|  | 		$command = $db->createCommand($this->_sql);
 | ||
|  | 		$command->bindValues($this->params);
 | ||
|  | 		$rows = $command->queryAll();
 | ||
|  | 		if ($this->_asArray) {
 | ||
|  | 			$records = $rows;
 | ||
|  | 		} else {
 | ||
|  | 			$records = array();
 | ||
|  | 			foreach ($rows as $row) {
 | ||
|  | 				$records[] = $class::populateRecord($row);
 | ||
|  | 			}
 | ||
|  | 		}
 | ||
|  | 		$this->_count = count($records);
 | ||
|  | 		return $records;
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	public function with()
 | ||
|  | 	{
 | ||
|  | 
 | ||
|  | 	}
 | ||
|  | //
 | ||
|  | //	public function getSql($connection = null)
 | ||
|  | //	{
 | ||
|  | //
 | ||
|  | //	}
 | ||
|  | 
 | ||
|  | 	public function setSql($value)
 | ||
|  | 	{
 | ||
|  | 		$this->_sql = $value;
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	public function getCountSql()
 | ||
|  | 	{
 | ||
|  | 
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	public function getOneSql()
 | ||
|  | 	{
 | ||
|  | 
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Returns the number of items in the vector.
 | ||
|  | 	 * @return integer the number of items in the vector
 | ||
|  | 	 */
 | ||
|  | 	public function getCount()
 | ||
|  | 	{
 | ||
|  | 		if ($this->_count !== null) {
 | ||
|  | 			return $this->_count;
 | ||
|  | 		} else {
 | ||
|  | 			return $this->_count = $this->performCountQuery();
 | ||
|  | 		}
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	protected function performCountQuery()
 | ||
|  | 	{
 | ||
|  | 		$select = $this->select;
 | ||
|  | 		$this->select = 'COUNT(*)';
 | ||
|  | 		$class = $this->modelClass;
 | ||
|  | 		$command = $this->createCommand($class::getDbConnection());
 | ||
|  | 		$this->_countSql = $command->getSql();
 | ||
|  | 		$count = $command->queryScalar();
 | ||
|  | 		$this->select = $select;
 | ||
|  | 		return $count;
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Sets the parameters about query caching.
 | ||
|  | 	 * This is a shortcut method to {@link CDbConnection::cache()}.
 | ||
|  | 	 * It changes the query caching parameter of the {@link dbConnection} instance.
 | ||
|  | 	 * @param integer $duration the number of seconds that query results may remain valid in cache.
 | ||
|  | 	 * If this is 0, the caching will be disabled.
 | ||
|  | 	 * @param CCacheDependency $dependency the dependency that will be used when saving the query results into cache.
 | ||
|  | 	 * @param integer $queryCount number of SQL queries that need to be cached after calling this method. Defaults to 1,
 | ||
|  | 	 * meaning that the next SQL query will be cached.
 | ||
|  | 	 * @return ActiveRecord the active record instance itself.
 | ||
|  | 	 */
 | ||
|  | 	public function cache($duration, $dependency = null, $queryCount = 1)
 | ||
|  | 	{
 | ||
|  | 		$this->connection->cache($duration, $dependency, $queryCount);
 | ||
|  | 		return $this;
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Returns an iterator for traversing the items in the vector.
 | ||
|  | 	 * This method is required by the SPL interface `IteratorAggregate`.
 | ||
|  | 	 * It will be implicitly called when you use `foreach` to traverse the vector.
 | ||
|  | 	 * @return Iterator an iterator for traversing the items in the vector.
 | ||
|  | 	 */
 | ||
|  | 	public function getIterator()
 | ||
|  | 	{
 | ||
|  | 		$records = $this->performQuery();
 | ||
|  | 		return new \yii\base\VectorIterator($records);
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Returns the number of items in the vector.
 | ||
|  | 	 * This method is required by the SPL `Countable` interface.
 | ||
|  | 	 * It will be implicitly called when you use `count($vector)`.
 | ||
|  | 	 * @return integer number of items in the vector.
 | ||
|  | 	 */
 | ||
|  | 	public function count()
 | ||
|  | 	{
 | ||
|  | 		return $this->getCount();
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Returns a value indicating whether there is an item at the specified offset.
 | ||
|  | 	 * This method is required by the SPL interface `ArrayAccess`.
 | ||
|  | 	 * It is implicitly called when you use something like `isset($vector[$offset])`.
 | ||
|  | 	 * @param integer $offset the offset to be checked
 | ||
|  | 	 * @return boolean whether there is an item at the specified offset.
 | ||
|  | 	 */
 | ||
|  | 	public function offsetExists($offset)
 | ||
|  | 	{
 | ||
|  | 		if ($this->_records === null) {
 | ||
|  | 			$this->_records = $this->performQuery();
 | ||
|  | 		}
 | ||
|  | 		return isset($this->_records[$offset]);
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Returns the item at the specified offset.
 | ||
|  | 	 * This method is required by the SPL interface `ArrayAccess`.
 | ||
|  | 	 * It is implicitly called when you use something like `$value = $vector[$offset];`.
 | ||
|  | 	 * This is equivalent to [[itemAt]].
 | ||
|  | 	 * @param integer $offset the offset to retrieve item.
 | ||
|  | 	 * @return mixed the item at the offset
 | ||
|  | 	 * @throws Exception if the offset is out of range
 | ||
|  | 	 */
 | ||
|  | 	public function offsetGet($offset)
 | ||
|  | 	{
 | ||
|  | 		if ($this->_records === null) {
 | ||
|  | 			$this->_records = $this->performQuery();
 | ||
|  | 		}
 | ||
|  | 		return isset($this->_records[$offset]) ? $this->_records[$offset] : null;
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Sets the item at the specified offset.
 | ||
|  | 	 * This method is required by the SPL interface `ArrayAccess`.
 | ||
|  | 	 * It is implicitly called when you use something like `$vector[$offset] = $item;`.
 | ||
|  | 	 * If the offset is null or equal to the number of the existing items,
 | ||
|  | 	 * the new item will be appended to the vector.
 | ||
|  | 	 * Otherwise, the existing item at the offset will be replaced with the new item.
 | ||
|  | 	 * @param integer $offset the offset to set item
 | ||
|  | 	 * @param mixed $item the item value
 | ||
|  | 	 * @throws Exception if the offset is out of range, or the vector is read only.
 | ||
|  | 	 */
 | ||
|  | 	public function offsetSet($offset, $item)
 | ||
|  | 	{
 | ||
|  | 		if ($this->_records === null) {
 | ||
|  | 			$this->_records = $this->performQuery();
 | ||
|  | 		}
 | ||
|  | 		$this->_records[$offset] = $item;
 | ||
|  | 	}
 | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Unsets the item at the specified offset.
 | ||
|  | 	 * This method is required by the SPL interface `ArrayAccess`.
 | ||
|  | 	 * It is implicitly called when you use something like `unset($vector[$offset])`.
 | ||
|  | 	 * This is equivalent to [[removeAt]].
 | ||
|  | 	 * @param integer $offset the offset to unset item
 | ||
|  | 	 * @throws Exception if the offset is out of range, or the vector is read only.
 | ||
|  | 	 */
 | ||
|  | 	public function offsetUnset($offset)
 | ||
|  | 	{
 | ||
|  | 		if ($this->_records === null) {
 | ||
|  | 			$this->_records = $this->performQuery();
 | ||
|  | 		}
 | ||
|  | 		unset($this->_records[$offset]);
 | ||
|  | 	}
 | ||
|  | }
 |