Spec-Zone.ru › Yii 1.1

CJoinElement

Пакет system.db.ar
Наследование класс CJoinElement
С версии 1.0
Исходный код framework/db/ar/CActiveFinder.php
CJoinElement представляет узел дерева объединения, созданного классом CActiveFinder.

Общественные свойства

Свойство Тип Описание Определено в
children массив список дочерних элементов объединения CJoinElement
id целое уникальный идентификатор этого узла дерева CJoinElement
master CActiveRelation главное отношение CJoinElement
model CActiveRecord модель, связанная с этим узлом дерева CJoinElement
rawTableAlias строка цитируемое имя таблицы для этого элемента CJoinElement
records массив список записей активных моделей, найденных запросами. Индексируются значениями первичного ключа. CJoinElement
relation CActiveRelation отношение, представленное этим узлом дерева CJoinElement
slave CActiveRelation ведомое отношение CJoinElement
stats массив список элементов статистики CJoinElement
tableAlias строка псевдоним таблицы для этого элемента объединения CJoinElement

Общественные методы

Метод Описание Определено в
__construct() Конструктор. CJoinElement
afterFind() Вызывает CActiveRecord::afterFind для всех записей. CJoinElement
buildQuery() Строит запрос объединения со всеми дочерними узлами HAS_ONE и BELONGS_TO. CJoinElement
count() Подсчитывает количество записей основной таблицы, возвращаемых оператором объединения. CJoinElement
destroy() Удаляет ссылки на дочерние элементы и поиск, чтобы избежать циклических ссылок. CJoinElement
find() Выполняет рекурсивный поиск с заданными критериями. CJoinElement
findWithBase() Выполняет жадное загрузку с базовыми записями, готовыми к использованию. CJoinElement
getColumnPrefix() Возвращает префикс столбца для избежания неоднозначности при ссылке на столбцы. CJoinElement
getColumnSelect() Генерирует список столбцов для выборки. CJoinElement
getJoinCondition() Возвращает оператор объединения (в данном случае, этот узел объединяется со своим родителем). CJoinElement
getPrimaryKeyRange() Возвращает условие, которое указывает только строки с выбранными значениями первичного ключа. CJoinElement
getPrimaryKeySelect() Возвращает выборку первичного ключа. CJoinElement
getTableNameWithAlias() Возвращает имя таблицы и псевдоним таблицы (если есть). Это можно использовать непосредственно в SQL-запросе без экранирования. CJoinElement
lazyFind() Выполняет ленивый поиск с указанной базовой записью. CJoinElement
runQuery() Выполняет запрос объединения и заполняет результаты запроса. CJoinElement

Подробное описание свойств

children свойство

public array $children;

список дочерних элементов объединения

id свойство

public integer $id;

уникальный идентификатор этого узла дерева

master свойство

public CActiveRelation $master;

главное отношение

model свойство

public CActiveRecord $model;

модель, связанная с этим узлом дерева

rawTableAlias свойство

public string $rawTableAlias;

цитируемое имя таблицы для этого элемента

records свойство

public array $records;

список записей активных моделей, найденных запросами. Индексируются значениями первичного ключа.

relation свойство

public CActiveRelation $relation;

отношение, представленное этим узлом дерева

slave свойство

public CActiveRelation $slave;

ведомое отношение

stats свойство

public array $stats;

список элементов статистики

tableAlias свойство

public string $tableAlias;

псевдоним таблицы для этого элемента объединения

Подробное описание методов

__construct() метод

public void __construct(CActiveFinder $finder, mixed $relation, CJoinElement $parent=NULL, integer $id=0)
$finder CActiveFinder поисковик
$relation смешанный тип отношение (если третий параметр не равен null) или модель (если третий параметр равен null), связанная с этим узлом дерева.
$parent CJoinElement родительский узел дерева
$id целое идентификатор этого узла дерева, уникальный среди всех узлов дерева
Исходный код: framework/db/ar/CActiveFinder.php#375 (показать)
public function __construct($finder,$relation,$parent=null,$id=0)
{
    
$this->_finder=$finder;
    
$this->id=$id;
    if(
$parent!==null)
    {
        
$this->relation=$relation;
        
$this->_parent=$parent;
        
$this->model=$this->_finder->getModel($relation->className);
        
$this->_builder=$this->model->getCommandBuilder();
        
$this->tableAlias=$relation->alias===null?$relation->name:$relation->alias;
        
$this->rawTableAlias=$this->_builder->getSchema()->quoteTableName($this->tableAlias);
        
$this->_table=$this->model->getTableSchema();
    }
    else  
// root element, the first parameter is the model.
    
{
        
$this->model=$relation;
        
$this->_builder=$relation->getCommandBuilder();
        
$this->_table=$relation->getTableSchema();
        
$this->tableAlias=$this->model->getTableAlias();
        
$this->rawTableAlias=$this->_builder->getSchema()->quoteTableName($this->tableAlias);
    }

    
// set up column aliases, such as t1_c2
    
$table=$this->_table;
    if(
$this->model->getDbConnection()->getDriverName()==='oci')  // Issue 482
        
$prefix='T'.$id.'_C';
    else
        
$prefix='t'.$id.'_c';
    foreach(
$table->getColumnNames() as $key=>$name)
    {
        
$alias=$prefix.$key;
        
$this->_columnAliases[$name]=$alias;
        if(
$table->primaryKey===$name)
            
$this->_pkAlias=$alias;
        elseif(
is_array($table->primaryKey) && in_array($name,$table->primaryKey))
            
$this->_pkAlias[$name]=$alias;
    }
}

Конструктор.

afterFind() метод

public void afterFind()
Исходный код: framework/db/ar/CActiveFinder.php#772 (показать)
public function afterFind()
{
    foreach(
$this->records as $record)
        
$record->afterFindInternal();
    foreach(
$this->children as $child)
        
$child->afterFind();

    
$this->children = null;
}

Вызывает CActiveRecord::afterFind для всех записей.

buildQuery() метод

public void buildQuery(CJoinQuery $query)
$query CJoinQuery запрос, который строится
Исходный код: framework/db/ar/CActiveFinder.php#786 (показать)
public function buildQuery($query)
{
    foreach(
$this->children as $child)
    {
        if(
$child->master!==null)
            
$child->_joined=true;
        elseif(
$child->relation instanceof CHasOneRelation || $child->relation instanceof CBelongsToRelation
            
|| $this->_finder->joinAll || $child->relation->together || (!$this->_finder->baseLimited && $child->relation->together===null))
        {
            
$child->_joined=true;
            
$query->join($child);
            
$child->buildQuery($query);
        }
    }
}

Строит запрос объединения со всеми дочерними узлами HAS_ONE и BELONGS_TO.

count() метод

public string count(CDbCriteria $criteria=NULL)
$criteria CDbCriteria критерии запроса
{return} строка количество записей основной таблицы. Примечание: тип является строкой для сохранения максимальной точности.
Исходный код: framework/db/ar/CActiveFinder.php#728 (показать)
public function count($criteria=null)
{
    
$query=new CJoinQuery($this,$criteria);
    
// ensure only one big join statement is used
    
$this->_finder->baseLimited=false;
    
$this->_finder->joinAll=true;
    
$this->buildQuery($query);

    
$query->limit=$query->offset=-1;

    if(!empty(
$criteria->group) || !empty($criteria->having))
    {
        
$query->orders = array();
        
$command=$query->createCommand($this->_builder);
        
$sql=$command->getText();
        
$sql="SELECT COUNT(*) FROM ({$sql}) sq";
        
$command->setText($sql);
        
$command->params=$query->params;
        return 
$command->queryScalar();
    }
    else
    {
        
$select=is_array($criteria->select) ? implode(',',$criteria->select) : $criteria->select;
        if(
$select!=='*' && preg_match('/^count\s*\(/i',trim($select)))
            
$query->selects=array($select);
        elseif(
is_string($this->_table->primaryKey))
        {
            
$prefix=$this->getColumnPrefix();
            
$schema=$this->_builder->getSchema();
            
$column=$prefix.$schema->quoteColumnName($this->_table->primaryKey);
            
$query->selects=array("COUNT(DISTINCT $column)");
        }
        else
            
$query->selects=array("COUNT(*)");

        
$query->orders=$query->groups=$query->havings=array();
        
$command=$query->createCommand($this->_builder);
        return 
$command->queryScalar();
    }
}

Подсчитывает количество записей основной таблицы, возвращаемых оператором объединения.

destroy() метод

public void destroy()
Исходный код: framework/db/ar/CActiveFinder.php#419 (показать)
public function destroy()
{
    if(!empty(
$this->children))
    {
        foreach(
$this->children as $child)
            
$child->destroy();
    }
    unset(
$this->_finder, $this->_parent, $this->model, $this->relation, $this->master, $this->slave, $this->records, $this->children, $this->stats);
}

Удаляет ссылки на дочерние элементы и поиск, чтобы избежать циклических ссылок. Используется внутренне.

find() метод

public void find(CDbCriteria $criteria=NULL)
$criteria CDbCriteria критерии запроса
Исходный код: framework/db/ar/CActiveFinder.php#433 (показать)
public function find($criteria=null)
{
    if(
$this->_parent===null) // root element
    
{
        
$query=new CJoinQuery($this,$criteria);
        
$this->_finder->baseLimited=($criteria->offset>=0 || $criteria->limit>=0);
        
$this->buildQuery($query);
        
$this->_finder->baseLimited=false;
        
$this->runQuery($query);
    }
    elseif(!
$this->_joined && !empty($this->_parent->records)) // not joined before
    
{
        
$query=new CJoinQuery($this->_parent);
        
$this->_joined=true;
        
$query->join($this);
        
$this->buildQuery($query);
        
$this->_parent->runQuery($query);
    }

    foreach(
$this->children as $child) // find recursively
        
$child->find();

    foreach(
$this->stats as $stat)
        
$stat->query();
}

Выполняет рекурсивный поиск с заданными критериями.

findWithBase() метод

public void findWithBase(mixed $baseRecords)
$baseRecords смешанный тип доступные базовые записи.
Исходный код: framework/db/ar/CActiveFinder.php#692 (показать)
public function findWithBase($baseRecords)
{
    if(!
is_array($baseRecords))
        
$baseRecords=array($baseRecords);
    if(
is_string($this->_table->primaryKey))
    {
        foreach(
$baseRecords as $baseRecord)
            
$this->records[$baseRecord->{$this->_table->primaryKey}]=$baseRecord;
    }
    else
    {
        foreach(
$baseRecords as $baseRecord)
        {
            
$pk=array();
            foreach(
$this->_table->primaryKey as $name)
                
$pk[$name]=$baseRecord->$name;
            
$this->records[serialize($pk)]=$baseRecord;
        }
    }

    
$query=new CJoinQuery($this);
    
$this->buildQuery($query);
    if(
count($query->joins)>1)
        
$this->runQuery($query);
    foreach(
$this->children as $child)
        
$child->find();

    foreach(
$this->stats as $stat)
        
$stat->query();
}

Выполняет жадный запрос с готовыми базовыми записями.

getColumnPrefix() метод

public string getColumnPrefix()
{возврат} строка префикс столбца для устранения неоднозначности ссылок на столбцы
Исходный код: framework/db/ar/CActiveFinder.php#1020 (показать)
public function getColumnPrefix()
{
    if(
$this->tableAlias!==null)
        return 
$this->rawTableAlias.'.';
    else
        return 
$this->_table->rawName.'.';
}

getColumnSelect() метод

public string getColumnSelect(mixed $select='*')
$select смешанный тип столбцы для выбора. По умолчанию «*», означающее все столбцы.
{возврат} строка выбор столбцов
Исходный код: framework/db/ar/CActiveFinder.php#911 (показать)
public function getColumnSelect($select='*')
{
    
$schema=$this->_builder->getSchema();
    
$prefix=$this->getColumnPrefix();
    
$columns=array();
    if(
$select==='*')
    {
        foreach(
$this->_table->getColumnNames() as $name)
            
$columns[]=$prefix.$schema->quoteColumnName($name).' AS '.$schema->quoteColumnName($this->_columnAliases[$name]);
    }
    else
    {
        if(
is_string($select))
            
$select=explode(',',$select);
        
$selected=array();
        foreach(
$select as $name)
        {
            
$name=trim($name);
            
$matches=array();
            if((
$pos=strrpos($name,'.'))!==false)
                
$key=substr($name,$pos+1);
            else
                
$key=$name;
            
$key=trim($key,'\'"`');

            if(
$key==='*')
            {
                foreach(
$this->_table->columns as $name=>$column)
                {
                    
$alias=$this->_columnAliases[$name];
                    if(!isset(
$selected[$alias]))
                    {
                        
$columns[]=$prefix.$column->rawName.' AS '.$schema->quoteColumnName($alias);
                        
$selected[$alias]=1;
                    }
                }
                continue;
            }

            if(isset(
$this->_columnAliases[$key]))  // simple column names
            
{
                
$columns[]=$prefix.$schema->quoteColumnName($key).' AS '.$schema->quoteColumnName($this->_columnAliases[$key]);
                
$selected[$this->_columnAliases[$key]]=1;
            }
            elseif(
preg_match('/^(.*?)\s+AS\s+(\w+)$/im',$name,$matches)) // if the column is already aliased
            
{
                
$alias=$matches[2];
                if(!isset(
$this->_columnAliases[$alias]) || $this->_columnAliases[$alias]!==$alias)
                {
                    
$this->_columnAliases[$alias]=$alias;
                    
$columns[]=$name;
                    
$selected[$alias]=1;
                }
            }
            else
                throw new 
CDbException(Yii::t('yii','Active record "{class}" is trying to select an invalid column "{column}". Note, the column must exist in the table or be an expression with alias.',
                    array(
'{class}'=>get_class($this->model), '{column}'=>$name)));
        }
        
// add primary key selection if they are not selected
        
if(is_string($this->_pkAlias) && !isset($selected[$this->_pkAlias]))
            
$columns[]=$prefix.$schema->quoteColumnName($this->_table->primaryKey).' AS '.$schema->quoteColumnName($this->_pkAlias);
        elseif(
is_array($this->_pkAlias))
        {
            foreach(
$this->_pkAlias as $name=>$alias)
                if(!isset(
$selected[$alias]))
                    
$columns[]=$prefix.$schema->quoteColumnName($name).' AS '.$schema->quoteColumnName($alias);
        }
    }

    return 
implode(', ',$columns);
}

Генерирует список столбцов для выбора. Столбцы будут правильно алиасированы, а первичные ключи будут добавлены к выбору, если они не указаны.

getJoinCondition() метод

public string getJoinCondition()
{возврат} строка запрос объединения (этот узел объединяется со своим родителем)
Исходный код: framework/db/ar/CActiveFinder.php#1032 (показать)
public function getJoinCondition()
{
    
$parent=$this->_parent;
    if(
$this->relation instanceof CManyManyRelation)
    {
        
$schema=$this->_builder->getSchema();
        
$joinTableName=$this->relation->getJunctionTableName();
        if((
$joinTable=$schema->getTable($joinTableName))===null)
            throw new 
CDbException(Yii::t('yii','The relation "{relation}" in active record class "{class}" is not specified correctly: the join table "{joinTable}" given in the foreign key cannot be found in the database.',
                array(
'{class}'=>get_class($parent->model), '{relation}'=>$this->relation->name, '{joinTable}'=>$joinTableName)));
        
$fks=$this->relation->getJunctionForeignKeys();

        return 
$this->joinManyMany($joinTable,$fks,$parent);
    }
    else
    {
        
$fks=is_array($this->relation->foreignKey) ? $this->relation->foreignKey : preg_split('/\s*,\s*/',$this->relation->foreignKey,-1,PREG_SPLIT_NO_EMPTY);
        if(
$this->slave!==null)
        {
            if(
$this->relation instanceof CBelongsToRelation)
            {
                
$fks=array_flip($fks);
                
$pke=$this->slave;
                
$fke=$this;
            }
            else
            {
                
$pke=$this;
                
$fke=$this->slave;
            }
        }
        elseif(
$this->relation instanceof CBelongsToRelation)
        {
            
$pke=$this;
            
$fke=$parent;
        }
        else
        {
            
$pke=$parent;
            
$fke=$this;
        }
        return 
$this->joinOneMany($fke,$fks,$pke,$parent);
    }
}

getPrimaryKeyRange() метод

public string getPrimaryKeyRange()
{возврат} строка условие, которое задаёт только строки с выбранными значениями первичного ключа.
Исходный код: framework/db/ar/CActiveFinder.php#1004 (показать)
public function getPrimaryKeyRange()
{
    if(empty(
$this->records))
        return 
'';
    
$values=array_keys($this->records);
    if(
is_array($this->_table->primaryKey))
    {
        foreach(
$values as &$value)
            
$value=unserialize($value);
    }
    return 
$this->_builder->createInCondition($this->_table,$this->_table->primaryKey,$values,$this->getColumnPrefix());
}

getPrimaryKeySelect() метод

public string getPrimaryKeySelect()
{возврат} строка выбор первичного ключа
Исходный код: framework/db/ar/CActiveFinder.php#986 (показать)
public function getPrimaryKeySelect()
{
    
$schema=$this->_builder->getSchema();
    
$prefix=$this->getColumnPrefix();
    
$columns=array();
    if(
is_string($this->_pkAlias))
        
$columns[]=$prefix.$schema->quoteColumnName($this->_table->primaryKey).' AS '.$schema->quoteColumnName($this->_pkAlias);
    elseif(
is_array($this->_pkAlias))
    {
        foreach(
$this->_pkAlias as $name=>$alias)
            
$columns[]=$prefix.$schema->quoteColumnName($name).' AS '.$schema->quoteColumnName($alias);
    }
    return 
implode(', ',$columns);
}

getTableNameWithAlias() метод

public string getTableNameWithAlias()
{возврат} строка имя таблицы и псевдоним таблицы (если есть). Это можно использовать непосредственно в запросе SQL без экранирования.
Исходный код: framework/db/ar/CActiveFinder.php#896 (показать)
public function getTableNameWithAlias()
{
    if(
$this->tableAlias!==null)
        return 
$this->_table->rawName . ' ' . $this->rawTableAlias;
    else
        return 
$this->_table->rawName;
}

lazyFind() метод

public void lazyFind(CActiveRecord $baseRecord)
$baseRecord CActiveRecord активная запись, связанный объект которой требуется получить.
Исходный код: framework/db/ar/CActiveFinder.php#463 (показать)
public function lazyFind($baseRecord)
{
    if(
is_string($this->_table->primaryKey))
        
$this->records[$baseRecord->{$this->_table->primaryKey}]=$baseRecord;
    else
    {
        
$pk=array();
        foreach(
$this->_table->primaryKey as $name)
            
$pk[$name]=$baseRecord->$name;
        
$this->records[serialize($pk)]=$baseRecord;
    }

    foreach(
$this->stats as $stat)
        
$stat->query();

    if(!
$this->children)
        return;

    
$params=array();
    foreach(
$this->children as $child)
        if(
is_array($child->relation->params))
            
$params=array_merge($params,$child->relation->params);

    
$query=new CJoinQuery($child);
    
$query->selects=array($child->getColumnSelect($child->relation->select));
    
$query->conditions=array(
        
$child->relation->on,
    );
    
$query->groups[]=$child->relation->group;
    
$query->joins[]=$child->relation->join;
    
$query->havings[]=$child->relation->having;
    
$query->orders[]=$child->relation->order;
    
$query->params=$params;
    
$query->elements[$child->id]=true;
    if(
$child->relation instanceof CHasManyRelation)
    {
        
$query->limit=$child->relation->limit;
        
$query->offset=$child->relation->offset;
    }

    
$child->applyLazyCondition($query,$baseRecord);

    
$this->_joined=true;
    
$child->_joined=true;

    
$this->_finder->baseLimited=false;
    
$child->buildQuery($query);
    
$child->runQuery($query);
    foreach(
$child->children as $c)
        
$c->find();

    if(empty(
$child->records))
        return;
    if(
$child->relation instanceof CHasOneRelation || $child->relation instanceof CBelongsToRelation)
        
$baseRecord->addRelatedRecord($child->relation->name,reset($child->records),false);
    else 
// has_many and many_many
    
{
        foreach(
$child->records as $record)
        {
            if(
$child->relation->index!==null)
                
$index=$record->{$child->relation->index};
            else
                
$index=true;
            
$baseRecord->addRelatedRecord($child->relation->name,$record,$index);
        }
    }
}

Выполняет ленивый поиск с указанной базовой записью.

runQuery() метод

public void runQuery(CJoinQuery $query)
$query CJoinQuery запрос, который необходимо выполнить.
Исходный код: framework/db/ar/CActiveFinder.php#806 (показать)
public function runQuery($query)
{
    
$command=$query->createCommand($this->_builder);
    foreach(
$command->queryAll() as $row)
        
$this->populateRecord($query,$row);
}

Выполняет запрос объединения и заполняет результаты запроса.

© 2008–2017 by Yii Software LLC
Licensed under the three clause BSD license.
http://www.yiiframework.com/doc/api/1.1/CJoinElement

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API