Skip to content

Commit

Permalink
reverted back the previous changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
qiang.xue committed Jan 8, 2010
1 parent ff0059b commit fcd6bd3
Show file tree
Hide file tree
Showing 12 changed files with 55 additions and 64 deletions.
1 change: 0 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Version 1.1.0 to be released
----------------------------
- Bug #720: The new table prefix feature does not work with many-many relationship in AR (Qiang)
- Bug #735: CDbCriteria should save 'with' attribute when toArray() is called (Qiang)
- Chg #796: The alias name for the primary table in a relational AR query is changed to be 't' (Qiang)
- Chg: renamed CDetailView::model to be 'data'. renamed 'dataField' and 'dataExpression' to be 'name' and 'value' for grid view columns. (Qiang)
- Enh #656: Added support to indicate the size of enum column type for MySQL schema (sebas)
- Enh #767: Added CUrlRule::matchValue option to support creating URLs only when a rule's parameter value patterns are matched. (Qiang)
Expand Down
1 change: 0 additions & 1 deletion UPGRADE
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ Upgrading from v1.1rc
---------------------
- CRudColumn is renamed as CButtonColumn
- CDataColumn.dataField and dataExpression are renamed as name and value, respectively
- The alias name for the primary table in a relational AR query is fixed to be 't'

Upgrading from v1.1b
--------------------
Expand Down
2 changes: 1 addition & 1 deletion demos/blog/protected/controllers/CommentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function actionIndex()
$dataProvider=new CActiveDataProvider('Comment', array(
'criteria'=>array(
'with'=>'post',
'order'=>'t.status, t.create_time DESC',
'order'=>'{{comment}}.status, {{comment}}.create_time DESC',
),
));

Expand Down
4 changes: 2 additions & 2 deletions demos/blog/protected/models/Comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ public function getPendingCommentCount()
public function findRecentComments($limit=10)
{
return $this->with('post')->findAll(array(
'condition'=>'t.status='.self::STATUS_APPROVED,
'order'=>'t.create_time DESC',
'condition'=>'{{comment}}.status='.self::STATUS_APPROVED,
'order'=>'{{comment}}.create_time DESC',
'limit'=>$limit,
));
}
Expand Down
6 changes: 4 additions & 2 deletions docs/blog/comment.admin.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function actionIndex()
$dataProvider=new CActiveDataProvider('Comment', array(
'criteria'=>array(
'with'=>'post',
'order'=>'t.status, t.create_time DESC',
'order'=>'{{comment}}.status, {{comment}}.create_time DESC',
),
));

Expand All @@ -53,7 +53,9 @@ public function actionIndex()
}
~~~

Notice that in the above code, because both `tbl_post` and `tbl_comment` have columns `status` and `create_time`, we need to disambiguate the corresponding column reference by prefixing them with table alias names. As described in [the guide](http://www.yiiframework.com/doc/guide/database.arr#disambiguating-column-names), the alias for the primary table in a relational query is always `t`. Therefore, we are prefixing `t` to the `status` and `create_time` columns in the above code.
Notice that in the above code, we refer to the `tbl_comment` table via the token `{{comment}}` when we specify the query criteria. This is because of the table prefix feature we exploit when we set up the database connection.

We need to prefix the columns with the table prefix because we are querying the comments together with their belonging posts which also have columns `status` and `create_time`. The table prefix will disambiguate the column references.

Like the post index view, the `index` view for `CommentController` uses [[CListView]] to display the comment list which in turn uses the partial view `/wwwroot/blog/protected/views/comment/_view.php` to display the detail of each individual comment. We will not go into details here. Interested readers may refer to the corresponding file in the blog demo `/wwwroot/yii/demos/blog/protected/views/comment/_view.php`.

Expand Down
4 changes: 2 additions & 2 deletions docs/blog/portlet.comments.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class Comment extends CActiveRecord
public function findRecentComments($limit=10)
{
return $this->with('post')->findAll(array(
'condition'=>'t.status='.self::STATUS_APPROVED,
'order'=>'t.create_time DESC',
'condition'=>'{{comment}}.status='.self::STATUS_APPROVED,
'order'=>'{{comment}}.create_time DESC',
'limit'=>$limit,
));
}
Expand Down
25 changes: 15 additions & 10 deletions docs/guide/database.arr.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ section.

![ER Diagram](er.png)

> Info: Support for foreign key constraints varies in different DBMS.
> Tip: Support for foreign key constraints varies in different DBMS.
>
> SQLite does not support foreign key constraints, but you can still
> declare the constraints when creating tables.
> declare the constraints when creating tables. AR can exploit these
> declarations to correctly support relational queries.
>
> MySQL supports foreign key constraints with InnoDB engine, but not with
> MyISAM. It is thus recommended that you use InnoDB for your MySQL database
> if you want to use foreign key constraints.


Declaring Relationship
Expand Down Expand Up @@ -81,8 +87,7 @@ class Post extends CActiveRecord
{
return array(
'author'=>array(self::BELONGS_TO, 'User', 'author_id'),
'categories'=>array(self::MANY_MANY, 'Category',
'tbl_post_category(post_id, category_id)'),
'categories'=>array(self::MANY_MANY, 'Category', 'tbl_post_category(post_id, category_id)'),
);
}
}
Expand Down Expand Up @@ -319,11 +324,12 @@ When a column name appears in two or more tables being joined
together, it needs to be disambiguated. This is done by prefixing the
column name with its table's alias name.

In relational AR query, the alias name for the primary table is fixed as `t`,
while the alias name for a relational table
In relational AR query, the alias name for the primary table is the same
as the primary table name, while the alias name for a relational table
is the same as the corresponding relation name by default. For example,
in the following statement, the alias name for `Post` and `Comment` is
`t` and `comments`, respectively:
`Post` and `comments`, respectively (assuming the table name for `Post` is
`Post`):

~~~
[php]
Expand All @@ -338,15 +344,14 @@ creation time. We need to disambiguate the `create_time` column like the followi
~~~
[php]
$posts=Post::model()->with('comments')->findAll(array(
'order'=>'t.create_time, comments.create_time'
'order'=>'Post.create_time, comments.create_time'
));
~~~

> Note: the behavior of column disambiguation has been changed since version 1.1.0.
> Previously in version 1.0.x, by default Yii would automatically generate a table
> alias for each relational table, and we had to use the prefix `??.` to refer to
> this automatically generated alias. Also, in version 1.0.x, the alias name
> of the primary table is the table name itself.
> this automatically generated alias.


Dynamic Relational Query Options
Expand Down
5 changes: 1 addition & 4 deletions docs/guide/upgrade.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ objects. Previsoulay in version 1.0.x, the default behavior is that
there will be `N+1` SQL statements if an eager loading involves
`N` `HAS_MANY` or `MANY_MANY` relations.


Changes Related with Table Alias in Relational Active Record
------------------------------------------------------------

Expand All @@ -43,10 +44,6 @@ relation name. Previously in version 1.0.x, by default Yii would automatically
generate a table alias for each relational table, and we had to use the prefix
`??.` to refer to this automatically generated alias.

- The alias name for the primary table in a relational AR query is fixed to be `t`.
Previsouly in version 1.0.x, it was the same as the table name.


Changes Related with Tabular Input
----------------------------------

Expand Down
10 changes: 4 additions & 6 deletions framework/db/ar/CActiveFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public function findAll($condition='',$params=array())
public function findByPk($pk,$condition='',$params=array())
{
Yii::trace(get_class($this->_joinTree->model).'.findByPk() eagerly','system.db.ar.CActiveRecord');
$criteria=$this->_builder->createPkCriteria($this->_joinTree->model->getTableSchema(),$pk,$condition,$params,$this->_joinTree->rawTableAlias.'.');
$criteria=$this->_builder->createPkCriteria($this->_joinTree->model->getTableSchema(),$pk,$condition,$params);
return $this->query($criteria);
}

Expand All @@ -117,7 +117,7 @@ public function findByPk($pk,$condition='',$params=array())
public function findAllByPk($pk,$condition='',$params=array())
{
Yii::trace(get_class($this->_joinTree->model).'.findAllByPk() eagerly','system.db.ar.CActiveRecord');
$criteria=$this->_builder->createPkCriteria($this->_joinTree->model->getTableSchema(),$pk,$condition,$params,$this->_joinTree->rawTableAlias.'.');
$criteria=$this->_builder->createPkCriteria($this->_joinTree->model->getTableSchema(),$pk,$condition,$params);
return $this->query($criteria,true);
}

Expand All @@ -127,7 +127,7 @@ public function findAllByPk($pk,$condition='',$params=array())
public function findByAttributes($attributes,$condition='',$params=array())
{
Yii::trace(get_class($this->_joinTree->model).'.findByAttributes() eagerly','system.db.ar.CActiveRecord');
$criteria=$this->_builder->createColumnCriteria($this->_joinTree->model->getTableSchema(),$attributes,$condition,$params,$this->_joinTree->rawTableAlias.'.');
$criteria=$this->_builder->createColumnCriteria($this->_joinTree->model->getTableSchema(),$attributes,$condition,$params);
return $this->query($criteria);
}

Expand All @@ -137,7 +137,7 @@ public function findByAttributes($attributes,$condition='',$params=array())
public function findAllByAttributes($attributes,$condition='',$params=array())
{
Yii::trace(get_class($this->_joinTree->model).'.findAllByAttributes() eagerly','system.db.ar.CActiveRecord');
$criteria=$this->_builder->createColumnCriteria($this->_joinTree->model->getTableSchema(),$attributes,$condition,$params,$this->_joinTree->rawTableAlias.'.');
$criteria=$this->_builder->createColumnCriteria($this->_joinTree->model->getTableSchema(),$attributes,$condition,$params);
return $this->query($criteria,true);
}

Expand Down Expand Up @@ -360,8 +360,6 @@ public function __construct($finder,$relation,$parent=null,$id=0)
$this->model=$relation;
$this->_builder=$relation->getCommandBuilder();
$this->_table=$relation->getTableSchema();
$this->tableAlias='t';
$this->rawTableAlias=$this->_builder->getSchema()->quoteTableName('t');
}

// set up column aliases, such as t1_c2
Expand Down
18 changes: 7 additions & 11 deletions framework/db/schema/CDbCommandBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -420,18 +420,17 @@ public function createCriteria($condition='',$params=array())
* @param array parameters to be bound to an SQL statement.
* This is only used when the second parameter is a string (query condition).
* In other cases, please use {@link CDbCriteria::params} to set parameters.
* @param string column prefix (ended with dot). If null, it will be the table name
* @return CDbCriteria the created query criteria
*/
public function createPkCriteria($table,$pk,$condition='',$params=array(),$prefix=null)
public function createPkCriteria($table,$pk,$condition='',$params=array())
{
$this->ensureTable($table);
$criteria=$this->createCriteria($condition,$params);
if(!is_array($pk)) // single key
$pk=array($pk);
if(is_array($table->primaryKey) && !isset($pk[0]) && $pk!==array()) // single composite key
$pk=array($pk);
$condition=$this->createInCondition($table,$table->primaryKey,$pk,$prefix);
$condition=$this->createInCondition($table,$table->primaryKey,$pk);
if($criteria->condition!=='')
$criteria->condition=$condition.' AND ('.$criteria->condition.')';
else
Expand Down Expand Up @@ -464,41 +463,38 @@ public function createPkCondition($table,$values,$prefix=null)
* @param array parameters to be bound to an SQL statement.
* This is only used when the second parameter is a string (query condition).
* In other cases, please use {@link CDbCriteria::params} to set parameters.
* @param string column prefix (ended with dot). If null, it will be the table name
* @return CDbCriteria the created query criteria
*/
public function createColumnCriteria($table,$columns,$condition='',$params=array(),$prefix=null)
public function createColumnCriteria($table,$columns,$condition='',$params=array())
{
$this->ensureTable($table);
$criteria=$this->createCriteria($condition,$params);
$bindByPosition=isset($criteria->params[0]);
$conditions=array();
$values=array();
$i=0;
if($prefix===null)
$prefix=$table->rawName.'.';
foreach($columns as $name=>$value)
{
if(($column=$table->getColumn($name))!==null)
{
if(is_array($value))
$conditions[]=$this->createInCondition($table,$name,$value,$prefix);
$conditions[]=$this->createInCondition($table,$name,$value);
else if($value!==null)
{
if($bindByPosition)
{
$conditions[]=$prefix.$column->rawName.'=?';
$conditions[]=$table->rawName.'.'.$column->rawName.'=?';
$values[]=$value;
}
else
{
$conditions[]=$prefix.$column->rawName.'='.self::PARAM_PREFIX.$i;
$conditions[]=$table->rawName.'.'.$column->rawName.'='.self::PARAM_PREFIX.$i;
$values[self::PARAM_PREFIX.$i]=$value;
$i++;
}
}
else
$conditions[]=$prefix.$column->rawName.' IS NULL';
$conditions[]=$table->rawName.'.'.$column->rawName.' IS NULL';
}
else
throw new CDbException(Yii::t('yii','Table "{table}" does not have a column named "{column}".',
Expand Down
20 changes: 10 additions & 10 deletions tests/unit/framework/db/ar/CActiveRecord2Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ public function testEagerRecursiveRelation()

public function testRelationWithCondition()
{
$posts=Post2::model()->with('comments')->findAllByPk(array(2,3,4),array('order'=>'t.id'));
$posts=Post2::model()->with('comments')->findAllByPk(array(2,3,4),array('order'=>'posts.id'));
$this->assertEquals(3,count($posts));
$this->assertEquals(2,count($posts[0]->comments));
$this->assertEquals(4,count($posts[1]->comments));
Expand All @@ -528,24 +528,24 @@ public function testRelationWithCondition()
$posts=Post2::model()->with('comments')->findAllBySql('select * from test.posts where id=:id1 OR id=:id2',array(':id1'=>2,':id2'=>3));
$this->assertEquals(2,count($posts));

$post=Post2::model()->with('comments','author')->find('t.id=:id',array(':id'=>2));
$post=Post2::model()->with('comments','author')->find('posts.id=:id',array(':id'=>2));
$this->assertTrue($post instanceof Post2);

$posts=Post2::model()->with('comments','author')->findAll(array(
'select'=>'title',
'condition'=>'t.id=:id',
'condition'=>'posts.id=:id',
'limit'=>1,
'offset'=>0,
'order'=>'t.title',
'order'=>'posts.title',
'params'=>array(':id'=>2)));
$this->assertTrue($posts[0] instanceof Post2);

$posts=Post2::model()->with('comments','author')->findAll(array(
'select'=>'title',
'condition'=>'t.id=:id',
'condition'=>'posts.id=:id',
'limit'=>1,
'offset'=>2,
'order'=>'t.title',
'order'=>'posts.title',
'params'=>array(':id'=>2)));
$this->assertTrue($posts===array());
}
Expand All @@ -572,19 +572,19 @@ public function testRelationalCount()
$count=Post2::model()->with('author','firstComment','comments','categories')->count();
$this->assertEquals(5,$count);

$count=Post2::model()->with('author','firstComment','comments','categories')->count('t.id=4');
$count=Post2::model()->with('author','firstComment','comments','categories')->count('posts.id=4');
$this->assertEquals(1,$count);

$count=Post2::model()->with('author','firstComment','comments','categories')->count('t.id=14');
$count=Post2::model()->with('author','firstComment','comments','categories')->count('posts.id=14');
$this->assertEquals(0,$count);
}

public function testEmptyFinding()
{
$post=Post2::model()->with('author','firstComment','comments','categories')->find('t.id=100');
$post=Post2::model()->with('author','firstComment','comments','categories')->find('posts.id=100');
$this->assertNull($post);

$posts=Post2::model()->with('author','firstComment','comments','categories')->findAll('t.id=100');
$posts=Post2::model()->with('author','firstComment','comments','categories')->findAll('posts.id=100');
$this->assertTrue($posts===array());

$post=Post2::model()->with('author','firstComment','comments','categories')->findBySql('SELECT * FROM test.posts WHERE id=100');
Expand Down
23 changes: 9 additions & 14 deletions tests/unit/framework/db/ar/CActiveRecordTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -413,11 +413,6 @@ public function testLazyRelation()
'name'=>'order 22'),$item->order->attributes);
}

public function testEagerRelation2()
{
$post=Post::model()->with('author','firstComment','comments','categories')->findByPk(2);
}

public function testEagerRelation()
{
$post=Post::model()->with('author','firstComment','comments','categories')->findByPk(2);
Expand Down Expand Up @@ -498,7 +493,7 @@ public function testEagerRecursiveRelation()

public function testRelationWithCondition()
{
$posts=Post::model()->with('comments')->findAllByPk(array(2,3,4),array('order'=>'t.id'));
$posts=Post::model()->with('comments')->findAllByPk(array(2,3,4),array('order'=>'posts.id'));
$this->assertEquals(3,count($posts));
$this->assertEquals(2,count($posts[0]->comments));
$this->assertEquals(4,count($posts[1]->comments));
Expand All @@ -515,25 +510,25 @@ public function testRelationWithCondition()
$posts=Post::model()->with('comments')->findAllBySql('select * from posts where id=:id1 OR id=:id2',array(':id1'=>2,':id2'=>3));
$this->assertEquals(2,count($posts));

$post=Post::model()->with('comments','author')->find('t.id=:id',array(':id'=>2));
$post=Post::model()->with('comments','author')->find('posts.id=:id',array(':id'=>2));
$this->assertTrue($post instanceof Post);

$posts=Post::model()->with('comments','author')->findAll(array(
'select'=>'title',
'condition'=>'t.id=:id',
'condition'=>'posts.id=:id',
'limit'=>1,
'offset'=>0,
'order'=>'t.title',
'group'=>'t.id',
'order'=>'posts.title',
'group'=>'posts.id',
'params'=>array(':id'=>2)));
$this->assertTrue($posts[0] instanceof Post);

$posts=Post::model()->with('comments','author')->findAll(array(
'select'=>'title',
'condition'=>'t.id=:id',
'condition'=>'posts.id=:id',
'limit'=>1,
'offset'=>2,
'order'=>'t.title',
'order'=>'posts.title',
'params'=>array(':id'=>2)));
$this->assertTrue($posts===array());
}
Expand Down Expand Up @@ -636,10 +631,10 @@ public function testRelationalCount()
$count=Post::model()->with('author','firstComment','comments','categories')->count();
$this->assertEquals(5,$count);

$count=Post::model()->with('author','firstComment','comments','categories')->count('t.id=4');
$count=Post::model()->with('author','firstComment','comments','categories')->count('posts.id=4');
$this->assertEquals(1,$count);

$count=Post::model()->with('author','firstComment','comments','categories')->count('t.id=14');
$count=Post::model()->with('author','firstComment','comments','categories')->count('posts.id=14');
$this->assertEquals(0,$count);
}

Expand Down

0 comments on commit fcd6bd3

Please sign in to comment.