Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #525, branch 'issue-124'

* issue-124:
  better fix for issues #124
  added @since annotation
  added docblocks to CMysqlCommandBuilder+CHANGELOG
  added some unit tests mysql
  Add CMysqlCommandBuilder to handle joins on update
  • Loading branch information...
commit ed49b77ca059c0895be17df5813ee1e83d4c916d 2 parents 7cc18cb + 266df50
@cebe cebe authored
View
1  CHANGELOG
@@ -3,6 +3,7 @@
Version 1.1.13 work in progress
-------------------------------
+- Bug #124: Added CMysqlCommandBuilder to handle JOIN directive on update commands correctly (cebe, DaSourcerer)
- Enh #556: CDbColumnSchema::$comment property has been added. It stores comment for the table column, comment retrieving is working for MySQL, PgSQL and Oracle (resurtm)
- Enh: Fixed the check for ajaxUpdate false value in jquery.yiilistview.js as that never happens (mdomba)
- Enh: Requirements checker: added check for Oracle database (pdo_oci extension) and MSSQL (pdo_dblib, pdo_sqlsrv and pdo_mssql extensions) (resurtm)
View
1  framework/YiiBase.php
@@ -707,6 +707,7 @@ public static function registerAutoloader($callback, $append=false)
'CMssqlSchema' => '/db/schema/mssql/CMssqlSchema.php',
'CMssqlTableSchema' => '/db/schema/mssql/CMssqlTableSchema.php',
'CMysqlColumnSchema' => '/db/schema/mysql/CMysqlColumnSchema.php',
+ 'CMysqlCommandBuilder' => '/db/schema/mysql/CMysqlCommandBuilder.php',
'CMysqlSchema' => '/db/schema/mysql/CMysqlSchema.php',
'CMysqlTableSchema' => '/db/schema/mysql/CMysqlTableSchema.php',
'COciColumnSchema' => '/db/schema/oci/COciColumnSchema.php',
View
37 framework/db/schema/mysql/CMysqlCommandBuilder.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * CMysqlCommandBuilder class file.
+ *
+ * @author Carsten Brandt <mail@cebe.cc>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CMysqlCommandBuilder provides basic methods to create query commands for tables.
+ *
+ * @author Carsten Brandt <mail@cebe.cc>
+ * @package system.db.schema.mysql
+ * @since 1.1.13
+ */
+class CMysqlCommandBuilder extends CDbCommandBuilder
+{
+ /**
+ * Alters the SQL to apply JOIN clause.
+ * This method handles the mysql specific syntax where JOIN has to come before SET in UPDATE statement
+ * @param string $sql the SQL statement to be altered
+ * @param string $join the JOIN clause (starting with join type, such as INNER JOIN)
+ * @return string the altered SQL statement
+ */
+ public function applyJoin($sql,$join)
+ {
+ if($join=='')
+ return $sql;
+
+ if(strpos($sql,'UPDATE')===0 && ($pos=strpos($sql,'SET'))!==false)
+ return substr($sql,0,$pos).$join.' '.substr($sql,$pos);
+ else
+ return $sql.' '.$join;
+ }
+}
View
11 framework/db/schema/mysql/CMysqlSchema.php
@@ -257,6 +257,17 @@ protected function findTableNames($schema='')
}
/**
+ * Creates a command builder for the database.
+ * This method overrides parent implementation in order to create a MySQL specific command builder
+ * @return CDbCommandBuilder command builder instance
+ * @since 1.1.13
+ */
+ protected function createCommandBuilder()
+ {
+ return new CMysqlCommandBuilder($this);
+ }
+
+ /**
* Builds a SQL statement for renaming a column.
* @param string $table the table whose column is to be renamed. The name will be properly quoted by the method.
* @param string $name the old name of the column. The name will be properly quoted by the method.
View
28 tests/framework/db/schema/CMysqlTest.php
@@ -179,16 +179,36 @@ public function testCommandBuilder()
'condition'=>'id=:id',
'params'=>array('id'=>5))));
$this->assertEquals('new post 5',$c->queryScalar());
-
+
$c=$builder->createSqlCommand('SELECT title FROM posts WHERE id=:id',array(':id'=>3));
$this->assertEquals('post 3',$c->queryScalar());
- $c=$builder->createUpdateCounterCommand($table,array('author_id'=>-2),new CDbCriteria(array('condition'=>'id=5')));
- $this->assertEquals('UPDATE `posts` SET `author_id`=`author_id`-2 WHERE id=5',$c->text);
+ $c=$builder->createUpdateCounterCommand($table,array('author_id'=>-1),new CDbCriteria(array('condition'=>'id=5')));
+ $this->assertEquals('UPDATE `posts` SET `author_id`=`author_id`-1 WHERE id=5',$c->text);
$c->execute();
$c=$builder->createSqlCommand('SELECT author_id FROM posts WHERE id=5');
+ $this->assertEquals(2,$c->queryScalar());
+
+ // test for updates with joins
+ $c=$builder->createUpdateCommand($table,array('title'=>'new post 1'),new CDbCriteria(array(
+ 'condition'=>'u.`username`=:username',
+ 'join'=>'JOIN `users` u ON `author_id`=u.`id`',
+ 'params'=>array(':username'=>'user1'))));
+ $c->execute();
+ $c=$builder->createFindCommand($table,new CDbCriteria(array(
+ 'select'=>'title',
+ 'condition'=>'id=:id',
+ 'params'=>array('id'=>1))));
+ $this->assertEquals('new post 1',$c->queryScalar());
+
+ $c=$builder->createUpdateCounterCommand($table,array('author_id'=>-1),new CDbCriteria(array(
+ 'condition'=>'u.`username`="user2"',
+ 'join'=>'JOIN `users` u ON `author_id`=u.`id`')));
+ $this->assertEquals('UPDATE `posts` JOIN `users` u ON `author_id`=u.`id` SET `author_id`=`author_id`-1 WHERE u.`username`="user2"',$c->text);
+ $c->execute();
+ $c=$builder->createSqlCommand('SELECT author_id FROM posts WHERE id=2');
$this->assertEquals(1,$c->queryScalar());
-
+
// test bind by position
$c=$builder->createFindCommand($table,new CDbCriteria(array(
'select'=>'title',
Please sign in to comment.
Something went wrong with that request. Please try again.