diff --git a/framework/db/ar/ActiveFinder.php b/framework/db/ar/ActiveFinder.php index b33b23f..a7daf3d 100644 --- a/framework/db/ar/ActiveFinder.php +++ b/framework/db/ar/ActiveFinder.php @@ -17,22 +17,8 @@ use yii\db\Exception; /** * ActiveFinder.php is ... - * todo: add SQL monitor - * todo: better handling on join() support in QueryBuilder: use regexp to detect table name and quote it - * todo: do not support anonymous parameter binding - * todo: add ActiveFinderBuilder - * todo: quote join/on part of the relational query - * todo: modify QueryBuilder about join() methods - * todo: unify ActiveFinder and ActiveRelation in query building process - * todo: intelligent table aliasing (first table name, then relation name, finally t?) - * todo: allow using tokens in primary query fragments - * todo: findBySql - * todo: base limited - * todo: lazy loading - * todo: scope - * todo: test via option - todo: inner join with one or multiple relations as filters - joinType should default to inner join in this case + * todo: base limited with has_many, bySQL, lazy loading + * todo: quoting column names in 'on' clause * * @property integer $count * @@ -45,10 +31,6 @@ class ActiveFinder extends \yii\base\Object * @var \yii\db\dao\Connection */ public $connection; - /** - * @var ActiveQuery - */ - public $query; public function __construct($connection) { @@ -56,16 +38,25 @@ class ActiveFinder extends \yii\base\Object } /** - * @param \yii\db\ar\ActiveQuery $query - * @param bool $all - * @return array + * @param ActiveQuery $query */ public function findRecords($query) { + if (!empty($query->with)) { + return $this->findRecordsWithRelations($query); + } + if ($query->sql !== null) { $sql = $query->sql; } else { - $this->initFrom($query); + if ($query->from === null) { + $modelClass = $query->modelClass; + $tableName = $modelClass::tableName(); + if ($query->tableAlias !== null) { + $tableName .= ' ' . $query->tableAlias; + } + $query->from = array($tableName); + } $this->applyScopes($query); $sql = $this->connection->getQueryBuilder()->build($query); if (strpos($sql, '@.') !== false) { @@ -93,11 +84,11 @@ class ActiveFinder extends \yii\base\Object $class = $query->modelClass; if ($query->indexBy === null) { foreach ($rows as $row) { - $records[] = $class::createRecord($row); + $records[] = $class::create($row); } } else { foreach ($rows as $row) { - $records[$row[$query->indexBy]] = $class::createRecord($row); + $records[$row[$query->indexBy]] = $class::create($row); } } } @@ -110,136 +101,52 @@ class ActiveFinder extends \yii\base\Object } + private $_joinCount; + private $_tableAliases; + + /** + * @param ActiveQuery $query + * @return array + */ public function findRecordsWithRelations($query) { - // todo: handle findBySql() and limit cases - $joinTree = $this->buildRelationalQuery(); - - if ($this->sql === null) { - $this->initFrom($element->query); - $command = $element->query->createCommand($this->getDbConnection()); - $this->sql = $command->getSql(); - } else { - $command = $this->getDbConnection()->createCommand($this->sql); - $command->bindValues($element->query->params); - } - - $rows = $command->queryAll(); - - if (isset($joinTree)) { - foreach ($rows as $row) { - $joinTree->populateData($row); - } - return array_values($joinTree->records); - } + $this->_joinCount = 0; + $this->_tableAliases = array(); + $joinTree = new JoinElement($this->_joinCount++, $query, null, null); + $this->buildJoinTree($joinTree, $query->with); + $this->initJoinTree($joinTree); - if ($this->asArray) { - if ($this->indexBy === null) { - return $rows; - } - $records = array(); - foreach ($rows as $row) { - $records[$row[$this->indexBy]] = $row; - } - return $records; - } else { - $records = array(); - $class = $this->modelClass; - if ($this->indexBy === null) { - foreach ($rows as $row) { - $records[] = $class::populateData($row); - } - } else { - $attribute = $this->indexBy; - foreach ($rows as $row) { - $record = $class::populateData($row); - $records[$record->$attribute] = $record; - } - } - return $records; + $q = new Query; + $this->buildJoinQuery($joinTree, $q); + $rows = $q->createCommand($this->connection)->queryAll(); + foreach ($rows as $row) { + $joinTree->createRecord($row); } - } - protected function initFrom($query) - { - if ($query->from === null) { - $modelClass = $query->modelClass; - $tableName = $modelClass::tableName(); - if ($query->tableAlias !== null) { - $tableName .= ' ' . $query->tableAlias; - } - $query->from = array($tableName); - } + return $query->indexBy !== null ? $joinTree->records : array_values($joinTree->records); } protected function applyScopes($query) { + $class = $query->modelClass; + $class::defaultScope($query); if (is_array($query->scopes)) { - $class = $query->modelClass; - $class::defaultScope($query); $scopes = $class::scopes(); foreach ($query->scopes as $name => $params) { if (is_integer($name)) { $name = $params; $params = array(); } - if (!isset($scopes[$name])) { + if (isset($scopes[$name])) { + array_unshift($params, $query); + call_user_func_array($scopes[$name], $params); + } else { throw new Exception("$class has no scope named '$name'."); } - array_unshift($params, $query); - call_user_func_array($scopes[$name], $params); } } } - private $_joinCount; - private $_tableAliases; - - protected function buildQuery() - { - $this->_joinCount = 0; - $joinTree = new JoinElement($this->_joinCount++, $element->query, null, null); - $this->buildJoinTree($joinTree, $element->query->with); - $this->_tableAliases = array(); - $this->buildTableAlias($joinTree); - - $query = new Query; - foreach ($joinTree->children as $child) { - $child->buildQuery($query); - } - - $select = $joinTree->buildSelect($element, $element->query->select); - if (!empty($query->select)) { - $element->query->select = array_merge($select, $query->select); - } else { - $element->query->select = $select; - } - if (!empty($query->where)) { - $element->query->andWhere('(' . implode(') AND (', $query->where) . ')'); - } - if (!empty($query->having)) { - $element->query->andHaving('(' . implode(') AND (', $query->having) . ')'); - } - if (!empty($query->join)) { - if ($element->query->join === null) { - $element->query->join = $query->join; - } else { - $element->query->join = array_merge($element->query->join, $query->join); - } - } - if (!empty($query->orderBy)) { - $element->query->addOrderBy($query->orderBy); - } - if (!empty($query->groupBy)) { - $element->query->addGroupBy($query->groupBy); - } - if (!empty($query->params)) { - $element->query->addParams($query->params); - } - - return $joinTree; - } - /** * @param JoinElement $parent * @param array|string $with @@ -297,7 +204,7 @@ class ActiveFinder extends \yii\base\Object /** * @param JoinElement $element */ - protected function buildTableAlias($element) + protected function initJoinTree($element) { if ($element->query->tableAlias !== null) { $alias = $element->query->tableAlias; @@ -313,58 +220,95 @@ class ActiveFinder extends \yii\base\Object $this->_tableAliases[$alias] = true; $element->query->tableAlias = $alias; + $this->applyScopes($element->query); + foreach ($element->children as $child) { - $this->buildTableAlias($child, $count); + $this->initJoinTree($child, $count); } } /** * @param JoinElement $element - * @param Query $query + * @param \yii\db\dao\Query $query */ protected function buildJoinQuery($element, $query) { - $prefixes = array( - '@.' => $element->query->tableAlias . '.', - '?.' => $element->parent->query->tableAlias . '.', - ); - $quotedPrefixes = array( - '@.' => $this->connection->quoteTableName($element->query->tableAlias, true) . '.', - '?.' => $this->connection->quoteTableName($element->parent->query->tableAlias, true) . '.', - ); + if ($element->parent) { + $prefixes = array( + '@.' => $element->query->tableAlias . '.', + '?.' => $element->parent->query->tableAlias . '.', + ); + $quotedPrefixes = array( + '@.' => $this->connection->quoteTableName($element->query->tableAlias, true) . '.', + '?.' => $this->connection->quoteTableName($element->parent->query->tableAlias, true) . '.', + ); + } else { + $prefixes = array( + '@.' => $element->query->tableAlias . '.', + ); + $quotedPrefixes = array( + '@.' => $this->connection->quoteTableName($element->query->tableAlias, true) . '.', + ); + } + + $qb = $this->connection->getQueryBuilder(); foreach ($this->buildSelect($element, $element->query->select) as $column) { $query->select[] = strtr($column, $prefixes); } - if ($element->query->where !== null) { - $query->where[] = strtr($element->query->where, $quotedPrefixes); + if ($element->query instanceof ActiveQuery) { + if ($element->query->from === null) { + $modelClass = $element->query->modelClass; + $tableName = $modelClass::tableName(); + if ($element->query->tableAlias !== null) { + $tableName .= ' ' . $element->query->tableAlias; + } + $query->from = array($tableName); + } else { + $query->from = $element->query->from; + } } - if ($element->query->having !== null) { - $query->having[] = strtr($element->query->having, $quotedPrefixes); + if (($where = $qb->buildCondition($element->query->where)) !== '') { + $query->andWhere(strtr($where, $quotedPrefixes)); } - if ($element->query->via !== null) { - $query->join[] = strtr($element->query->via, $quotedPrefixes); + if (($having = $qb->buildCondition($element->query->having)) !== '') { + $query->andHaving(strtr($having, $quotedPrefixes)); } - if ($element->query->joinType === null) { - $joinType = $element->query->select === false ? 'INNER JOIN' : 'LEFT JOIN'; - } else { - $joinType = $element->query->joinType; - } - $modelClass = $element->query->modelClass; - $tableName = $this->connection->quoteTableName($modelClass::tableName()); - $tableAlias = $this->connection->quoteTableName($element->query->tableAlias); - $join = "$joinType $tableName $tableAlias"; - if ($element->query->on !== null) { - $join .= ' ON ' . strtr($element->query->on, $quotedPrefixes); + if ($element->query instanceof ActiveRelation) { + if ($element->query->via !== null) { + $query->join[] = strtr($element->query->via, $quotedPrefixes); + } + + if ($element->query->joinType === null) { + $joinType = $element->query->select === false ? 'INNER JOIN' : 'LEFT JOIN'; + } else { + $joinType = $element->query->joinType; + } + $modelClass = $element->query->modelClass; + $tableName = $this->connection->quoteTableName($modelClass::tableName()); + $tableAlias = $this->connection->quoteTableName($element->query->tableAlias); + $join = "$joinType $tableName $tableAlias"; + if ($element->query->on !== null) { + $join .= ' ON ' . strtr($qb->buildCondition($element->query->on), $quotedPrefixes); + } + $query->join[] = $join; } - $query->join[] = $join; if ($element->query->join !== null) { - $query->join[] = strtr($element->query->join, $quotedPrefixes); + if (is_array($element->query->join)) { + foreach ($element->query->join as $join) { + if (is_array($join) && isset($join[2])) { + $join[2] = strtr($join[2], $quotedPrefixes); + } + $query->join[] = $join; + } + } else { + $query->join[] = strtr($element->query->join, $quotedPrefixes); + } } if ($element->query->orderBy !== null) { @@ -390,7 +334,7 @@ class ActiveFinder extends \yii\base\Object } foreach ($element->children as $child) { - $this->buildQuery($child, $query); + $this->buildJoinQuery($child, $query); } } @@ -406,7 +350,7 @@ class ActiveFinder extends \yii\base\Object $prefix = $element->query->tableAlias; if (empty($select) || $select === '*') { foreach ($table->columns as $column) { - $alias = "t{$element->id}c" . ($columnCount++); + $alias = "c{$element->id}_" . ($columnCount++); $columns[] = "$prefix.{$column->name} AS $alias"; $element->columnAliases[$alias] = $column->name; if ($column->isPrimaryKey) { @@ -418,7 +362,7 @@ class ActiveFinder extends \yii\base\Object $select = explode(',', $select); } foreach ($table->primaryKey as $column) { - $alias = "t{$element->id}c" . ($columnCount++); + $alias = "c{$element->id}_" . ($columnCount++); $columns[] = "$prefix.$column AS $alias"; $element->pkAlias[$column] = $alias; } @@ -429,7 +373,7 @@ class ActiveFinder extends \yii\base\Object $element->columnAliases[$matches[2]] = $matches[2]; $columns[] = $column; } elseif (!isset($element->pkAlias[$column])) { - $alias = "t{$element->id}c" . ($columnCount++); + $alias = "c{$element->id}_" . ($columnCount++); $columns[] = "$prefix.$column AS $alias"; $element->columnAliases[$alias] = $column; } @@ -438,4 +382,4 @@ class ActiveFinder extends \yii\base\Object return $columns; } -} +} \ No newline at end of file diff --git a/framework/db/ar/ActiveQuery.php b/framework/db/ar/ActiveQuery.php index 13b8424..3072ac5 100644 --- a/framework/db/ar/ActiveQuery.php +++ b/framework/db/ar/ActiveQuery.php @@ -243,10 +243,6 @@ class ActiveQuery extends BaseActiveQuery implements \IteratorAggregate, \ArrayA protected function findRecords() { $finder = new ActiveFinder($this->getDbConnection()); - if (!empty($this->with)) { - return $finder->findRecordsWithRelations($this); - } else { - return $finder->findRecords($this); - } + return $finder->findRecords($this); } } diff --git a/framework/db/ar/JoinElement.php b/framework/db/ar/JoinElement.php index 4a18875..ed2c1a6 100644 --- a/framework/db/ar/JoinElement.php +++ b/framework/db/ar/JoinElement.php @@ -49,9 +49,10 @@ class JoinElement extends \yii\base\Object public $relatedRecords; /** + * @param integer $id * @param ActiveRelation|ActiveQuery $query - * @param JoinElement $parent - * @param JoinElement $container + * @param null|JoinElement $parent + * @param null|JoinElement $container */ public function __construct($id, $query, $parent, $container) { @@ -70,15 +71,24 @@ class JoinElement extends \yii\base\Object */ public function createRecord($row) { - $pk = array(); - foreach ($this->pkAlias as $alias) { - if (isset($row[$alias])) { - $pk[] = $row[$alias]; + if ($this->query->indexBy === null) { + $pk = array(); + foreach ($this->pkAlias as $alias) { + if (isset($row[$alias])) { + $pk[] = $row[$alias]; + } else { + return null; + } + } + $pk = count($pk) === 1 ? $pk[0] : serialize($pk); + } else { + $pk = array_search($this->query->indexBy, $this->columnAliases); + if ($pk !== false) { + $pk = $row[$pk]; } else { - return null; + throw new Exception("Invalid indexBy: {$this->query->modelClass} has no attribute named '{$this->query->indexBy}'."); } } - $pk = count($pk) === 1 ? $pk[0] : serialize($pk); // create record if (isset($this->records[$pk])) { @@ -125,111 +135,4 @@ class JoinElement extends \yii\base\Object return $record; } - - public function buildQuery($query) - { - $prefixes = array( - '@.' => $this->query->tableAlias . '.', - '?.' => $this->parent->query->tableAlias . '.', - ); - $quotedPrefixes = ''; - foreach ($this->buildSelect($this->query->select) as $column) { - $query->select[] = strtr($column, $prefixes); - } - - if ($this->query->where !== null) { - $query->where[] = strtr($this->query->where, $prefixes); - } - - if ($this->query->having !== null) { - $query->having[] = strtr($this->query->having, $prefixes); - } - - if ($this->query->via !== null) { - $query->join[] = $this->query->via; - } - - $modelClass = $this->query->modelClass; - $tableName = $modelClass::tableName(); - $joinType = $this->query->joinType === null ? 'LEFT JOIN' : $this->query->joinType; - $join = "$joinType $tableName {$this->query->tableAlias}"; - if ($this->query->on !== null) { - $join .= ' ON ' . strtr($this->query->on, $prefixes); - } - $query->join[] = $join; - - - if ($this->query->join !== null) { - $query->join[] = strtr($this->query->join, $prefixes); - } - - // todo: convert orderBy to array first - if ($this->query->orderBy !== null) { - $query->orderBy[] = strtr($this->query->orderBy, $prefixes); - } - - // todo: convert groupBy to array first - if ($this->query->groupBy !== null) { - $query->groupBy[] = strtr($this->query->groupBy, $prefixes); - } - - if ($this->query->params !== null) { - foreach ($this->query->params as $name => $value) { - if (is_integer($name)) { - $query->params[] = $value; - } else { - $query->params[$name] = $value; - } - } - } - - foreach ($this->children as $child) { - $child->buildQuery($query); - } - } - - public function buildSelect($select) - { - if ($select === false) { - return array(); - } - $modelClass = $this->query->modelClass; - $table = $modelClass::getMetaData()->table; - $columns = array(); - $columnCount = 0; - $prefix = $this->query->tableAlias; - if (empty($select) || $select === '*') { - foreach ($table->columns as $column) { - $alias = "t{$this->id}c" . ($columnCount++); - $columns[] = "$prefix.{$column->name} AS $alias"; - $this->columnAliases[$alias] = $column->name; - if ($column->isPrimaryKey) { - $this->pkAlias[$column->name] = $alias; - } - } - } else { - if (is_string($select)) { - $select = explode(',', $select); - } - foreach ($table->primaryKey as $column) { - $alias = "t{$this->id}c" . ($columnCount++); - $columns[] = "$prefix.$column AS $alias"; - $this->pkAlias[$column] = $alias; - } - foreach ($select as $column) { - $column = trim($column); - if (preg_match('/^(.*?)\s+AS\s+(\w+)$/im', $column, $matches)) { - // if the column is already aliased - $this->columnAliases[$matches[2]] = $matches[2]; - $columns[] = $column; - } elseif (!isset($this->pkAlias[$column])) { - $alias = "t{$this->id}c" . ($columnCount++); - $columns[] = "$prefix.$column AS $alias"; - $this->columnAliases[$alias] = $column; - } - } - } - - return $columns; - } } \ No newline at end of file diff --git a/framework/db/dao/Command.php b/framework/db/dao/Command.php index 06558f3..8baa7b0 100644 --- a/framework/db/dao/Command.php +++ b/framework/db/dao/Command.php @@ -355,7 +355,7 @@ class Command extends \yii\base\Component } \Yii::trace("Querying SQL: {$sql}{$paramLog}", __CLASS__); - +echo $sql . "\n\n"; if ($db->queryCachingCount > 0 && $db->queryCachingDuration >= 0 && $method !== '') { $cache = \Yii::$application->getComponent($db->queryCacheID); } diff --git a/framework/db/dao/QueryBuilder.php b/framework/db/dao/QueryBuilder.php index 3e8893d..74d9904 100644 --- a/framework/db/dao/QueryBuilder.php +++ b/framework/db/dao/QueryBuilder.php @@ -43,7 +43,7 @@ class QueryBuilder extends \yii\base\Object */ public $typeMap = array(); /** - * @var Query the Query object that is currently processed by the query builder to generate a SQL statement. + * @var Query the Query object that is currently being processed by the query builder to generate a SQL statement. */ public $query; @@ -63,17 +63,16 @@ class QueryBuilder extends \yii\base\Object */ public function build($query) { - $this->query = $query; $clauses = array( - $this->buildSelect(), - $this->buildFrom(), - $this->buildJoin(), - $this->buildWhere(), - $this->buildGroupBy(), - $this->buildHaving(), - $this->buildUnion(), - $this->buildOrderBy(), - $this->buildLimit(), + $this->buildSelect($query->select, $query->distinct, $query->selectOption), + $this->buildFrom($query->from), + $this->buildJoin($query->join), + $this->buildWhere($query->where), + $this->buildGroupBy($query->groupBy), + $this->buildHaving($query->having), + $this->buildUnion($query->union), + $this->buildOrderBy($query->orderBy), + $this->buildLimit($query->limit, $query->offset), ); return implode($this->separator, array_filter($clauses)); } @@ -161,7 +160,7 @@ class QueryBuilder extends \yii\base\Object $this->query->addParams($params); } $sql = 'UPDATE ' . $this->quoteTableName($table) . ' SET ' . implode(', ', $lines); - if (($where = $this->buildCondition($condition)) != '') { + if (($where = $this->buildCondition($condition)) !== '') { $sql .= ' WHERE ' . $where; } @@ -185,7 +184,7 @@ class QueryBuilder extends \yii\base\Object public function delete($table, $condition = '', $params = array()) { $sql = 'DELETE FROM ' . $this->quoteTableName($table); - if (($where = $this->buildCondition($condition)) != '') { + if (($where = $this->buildCondition($condition)) !== '') { $sql .= ' WHERE ' . $where; } if ($params !== array() && $this->query instanceof BaseQuery) { @@ -620,16 +619,18 @@ class QueryBuilder extends \yii\base\Object } /** + * @param string|array $columns + * @param boolean $distinct + * @param string $selectOption * @return string the SELECT clause built from [[query]]. */ - protected function buildSelect() + public function buildSelect($columns, $distinct = false, $selectOption = null) { - $select = $this->query->distinct ? 'SELECT DISTINCT' : 'SELECT'; - if ($this->query->selectOption !== null) { - $select .= ' ' . $this->query->selectOption; + $select = $distinct ? 'SELECT DISTINCT' : 'SELECT'; + if ($selectOption !== null) { + $select .= ' ' . $selectOption; } - $columns = $this->query->select; if (empty($columns)) { return $select . ' *'; } @@ -664,16 +665,15 @@ class QueryBuilder extends \yii\base\Object } /** + * @param string|array $tables * @return string the FROM clause built from [[query]]. */ - protected function buildFrom() + public function buildFrom($tables) { - if (empty($this->query->from)) { + if (empty($tables)) { return ''; } - $tables = $this->query->from; - if ($this->autoQuote) { $driver = $this->connection->driver; if (!is_array($tables)) { @@ -702,11 +702,11 @@ class QueryBuilder extends \yii\base\Object } /** + * @param string|array $joins * @return string the JOIN clause built from [[query]]. */ - protected function buildJoin() + public function buildJoin($joins) { - $joins = $this->query->join; if (empty($joins)) { return ''; } @@ -715,7 +715,7 @@ class QueryBuilder extends \yii\base\Object } foreach ($joins as $i => $join) { - if (is_array($join)) { // join type, table name, on-condition + if (is_array($join)) { // 0:join type, 1:table name, 2:on-condition if (isset($join[0], $join[1])) { $table = $join[1]; if ($this->autoQuote && strpos($table, '(') === false) { @@ -743,44 +743,47 @@ class QueryBuilder extends \yii\base\Object } /** + * @param string|array $condition * @return string the WHERE clause built from [[query]]. */ - protected function buildWhere() + public function buildWhere($condition) { - $where = $this->buildCondition($this->query->where); - return empty($where) ? '' : 'WHERE ' . $where; + $where = $this->buildCondition($condition); + return $where === '' ? '' : 'WHERE ' . $where; } /** - * @return string the GROUP BY clause built from [[query]]. + * @param string|array $columns + * @return string the GROUP BY clause */ - protected function buildGroupBy() + public function buildGroupBy($columns) { - if (empty($this->query->groupBy)) { + if (empty($columns)) { return ''; } else { - return 'GROUP BY ' . $this->buildColumns($this->query->groupBy); + return 'GROUP BY ' . $this->buildColumns($columns); } } /** + * @param string|array $condition * @return string the HAVING clause built from [[query]]. */ - protected function buildHaving() + public function buildHaving($condition) { - $having = $this->buildCondition($this->query->having); - return empty($having) ? '' : 'HAVING ' . $having; + $having = $this->buildCondition($condition); + return $having === '' ? '' : 'HAVING ' . $having; } /** + * @param string|array $columns * @return string the ORDER BY clause built from [[query]]. */ - protected function buildOrderBy() + public function buildOrderBy($columns) { - if (empty($this->query->orderBy)) { + if (empty($columns)) { return ''; } - $columns = $this->query->orderBy; if ($this->autoQuote) { $driver = $this->connection->driver; if (!is_array($columns)) { @@ -809,26 +812,28 @@ class QueryBuilder extends \yii\base\Object } /** + * @param integer $limit + * @param integer $offset * @return string the LIMIT and OFFSET clauses built from [[query]]. */ - protected function buildLimit() + public function buildLimit($limit, $offset) { $sql = ''; - if ($this->query->limit !== null && $this->query->limit >= 0) { - $sql = 'LIMIT ' . (int)$this->query->limit; + if ($limit !== null && $limit >= 0) { + $sql = 'LIMIT ' . (int)$limit; } - if ($this->query->offset > 0) { - $sql .= ' OFFSET ' . (int)$this->query->offset; + if ($offset > 0) { + $sql .= ' OFFSET ' . (int)$offset; } return ltrim($sql); } /** + * @param string|array $unions * @return string the UNION clause built from [[query]]. */ - protected function buildUnion() + public function buildUnion($unions) { - $unions = $this->query->union; if (empty($unions)) { return ''; } @@ -836,8 +841,8 @@ class QueryBuilder extends \yii\base\Object $unions = array($unions); } foreach ($unions as $i => $union) { - if ($union instanceof Query) { - $unions[$i] = $union->getSql($this->connection); + if ($union instanceof BaseQuery) { + $unions[$i] = $this->build($union); } } return "UNION (\n" . implode("\n) UNION (\n", $unions) . "\n)"; diff --git a/tests/unit/framework/db/ar/ActiveRecordTest.php b/tests/unit/framework/db/ar/ActiveRecordTest.php index 21e1ec7..b3449f3 100644 --- a/tests/unit/framework/db/ar/ActiveRecordTest.php +++ b/tests/unit/framework/db/ar/ActiveRecordTest.php @@ -219,17 +219,18 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase // indexBy $customers = Customer::find()->orderBy('id')->indexBy('name')->all(); + $this->assertEquals(2, $customers['user2']['id']); } public function testEagerLoading() { - $customers = Customer::find()->with('orders')->orderBy('t0.id')->all(); + $customers = Customer::find()->with('orders')->orderBy('@.id')->all(); $this->assertEquals(3, count($customers)); $this->assertEquals(1, count($customers[0]->orders)); $this->assertEquals(2, count($customers[1]->orders)); $this->assertEquals(0, count($customers[2]->orders)); - $customers = Customer::find()->with('orders.customer')->orderBy('t0.id')->all(); + $customers = Customer::find()->with('orders.customer')->orderBy('@.id')->all(); } /*