Commit be87e178 by Qiang Xue

w

parent e6a9e645
......@@ -102,11 +102,11 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
return self::$_attributes[$className];
}
$class = new ReflectionClass($this);
$class = new \ReflectionClass($this);
$names = array();
foreach ($class->getProperties() as $property) {
foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
$name = $property->getName();
if ($property->isPublic() && !$property->isStatic()) {
if (!$property->isStatic()) {
$names[] = $name;
}
}
......
......@@ -94,8 +94,8 @@ class Command extends \yii\base\Component
}
else {
$this->query = new Query;
if (is_array($this->query)) {
$this->query->fromArray($this->query);
if (is_array($query)) {
$this->query->fromArray($query);
}
else {
$this->_sql = $query;
......@@ -124,9 +124,9 @@ class Command extends \yii\base\Component
/**
* @return string the SQL statement to be executed
*/
public function getSql()
public function getSql($rebuild = false)
{
if ($this->_sql == '' && is_object($this->query)) {
if ($this->_sql === null || $rebuild) {
$this->_sql = $this->query->getSql($this->connection);
}
return $this->_sql;
......@@ -168,7 +168,7 @@ class Command extends \yii\base\Component
\Yii::log('Error in preparing SQL: ' . $this->getSql(), CLogger::LEVEL_ERROR, 'system.db.Command');
$errorInfo = $e instanceof \PDOException ? $e->errorInfo : null;
throw new Exception('Unable to prepare the SQL statement: {error}',
array('{error}' => $e->getMessage())), (int)$e->getCode(), $errorInfo);
array('{error}' => $e->getMessage()), (int)$e->getCode(), $errorInfo);
}
}
}
......
......@@ -94,6 +94,136 @@ class Query extends \yii\base\Component
}
}
public function mergeWith($query, $useAnd = true)
{
$and = $useAnd ? 'AND' : 'OR';
if (is_array($query)) {
$query = new self($query);
}
if ($this->select !== $query->select) {
if($this->select === '*') {
$this->select = $query->select;
}
elseif($query->select!=='*') {
$select1 = is_string($this->select) ? preg_split('/\s*,\s*/', trim($this->select), -1, PREG_SPLIT_NO_EMPTY) : $this->select;
$select2 = is_string($query->select) ? preg_split('/\s*,\s*/', trim($query->select), -1, PREG_SPLIT_NO_EMPTY) : $query->select;
$this->select = array_merge($select1, array_diff($select2, $select1));
}
}
if ($this->selectOption !== $query->selectOption) {
if ($this->selectOption === null) {
$this->selectOption = $query->selectOption;
}
elseif ($query->selectOption !== null) {
$this->selectOption .= ' ' . $query->selectOption;
}
}
if ($query->distinct) {
$this->distinct = $query->distinct;
}
if ($this->where !== $query->where) {
if (empty($this->where)) {
$this->where = $query->where;
}
elseif (!empty($query->where)) {
$this->where = array('AND', $this->where, $query->where);
}
}
if ($this->params !== $query->params) {
$this->params = $this->addParams($query->params);
}
if ($query->limit !== null) {
$this->limit = $query->limit;
}
if ($query->offset !== null) {
$this->offset = $query->offset;
}
if ($this->orderBy !== $query->orderBy) {
if (empty($this->orderBy)) {
$this->orderBy = $query->orderBy;
}
elseif (!empty($query->orderBy)) {
if (!is_array($this->orderBy)) {
$this->orderBy = array($this->orderBy);
}
if (is_array($query->orderBy)) {
$this->orderBy = array_merge($this->orderBy, $query->orderBy);
}
else {
$this->orderBy[] = $query->orderBy;
}
}
}
if ($this->groupBy !== $query->groupBy) {
if (empty($this->groupBy)) {
$this->groupBy = $query->groupBy;
}
elseif (!empty($query->groupBy)) {
if (!is_array($this->groupBy)) {
$this->groupBy = array($this->groupBy);
}
if (is_array($query->groupBy)) {
$this->groupBy = array_merge($this->groupBy, $query->groupBy);
}
else {
$this->groupBy[] = $query->groupBy;
}
}
}
if ($this->join !== $query->join) {
if (empty($this->join)) {
$this->join = $query->join;
}
elseif (!empty($query->join)) {
if (!is_array($this->join)) {
$this->join = array($this->join);
}
if (is_array($query->join)) {
$this->join = array_merge($this->join, $query->join);
}
else {
$this->join[] = $query->join;
}
}
}
if ($this->having !== $query->having) {
if (empty($this->having)) {
$this->having = $query->having;
}
elseif (!empty($query->having)) {
$this->having = array('AND', $this->having, $query->having);
}
}
if ($this->union !== $query->union) {
if (empty($this->union)) {
$this->union = $query->union;
}
elseif (!empty($query->union)) {
if (!is_array($this->union)) {
$this->union = array($this->union);
}
if (is_array($query->union)) {
$this->union = array_merge($this->union, $query->union);
}
else {
$this->union[] = $query->union;
}
}
}
}
/**
* Appends a condition to the existing {@link condition}.
* The new condition and the existing condition will be concatenated via the specified operator
......@@ -372,15 +502,44 @@ class Query extends \yii\base\Component
return $this;
}
public function reset()
{
$this->select = null;
$this->selectOption = null;
$this->from = null;
$this->distinct = null;
$this->where = null;
$this->limit = null;
$this->offset = null;
$this->orderBy = null;
$this->groupBy = null;
$this->join = null;
$this->having = null;
$this->params = array();
$this->union = null;
}
public function fromArray($array)
{
$this->reset();
foreach (array('select', 'selectOption', 'from', 'distinct', 'where', 'limit', 'offset', 'orderBy', 'groupBy', 'join', 'having', 'params', 'union') as $name) {
if (isset($array[$name])) {
$this->$name = $array[$name];
}
}
}
/**
* @return array the array representation of the criteria
* @since 1.0.6
*/
public function toArray()
{
$result = array();
foreach (array('select', 'condition', 'params', 'limit', 'offset', 'order', 'group', 'join', 'having', 'distinct', 'scopes', 'with', 'alias', 'index', 'together') as $name)
foreach (array('select', 'selectOption', 'from', 'distinct', 'where', 'limit', 'offset', 'orderBy', 'groupBy', 'join', 'having', 'params', 'union') as $name) {
if (!empty($this->$name)) {
$result[$name] = $this->$name;
}
}
return $result;
}
}
......@@ -5,5 +5,6 @@ return array(
'dsn' => 'mysql:host=127.0.0.1;dbname=yiitest',
'username' => 'root',
'password' => '',
'fixture' => __DIR__ . '/mysql.sql',
),
);
\ No newline at end of file
......@@ -4,6 +4,16 @@
* and create an account 'test/test' which owns this test database.
*/
DROP TABLE IF EXISTS types CASCADE;
DROP TABLE IF EXISTS items CASCADE;
DROP TABLE IF EXISTS orders CASCADE;
DROP TABLE IF EXISTS post_category CASCADE;
DROP TABLE IF EXISTS categories CASCADE;
DROP TABLE IF EXISTS comments CASCADE;
DROP TABLE IF EXISTS posts CASCADE;
DROP TABLE IF EXISTS profiles CASCADE;
DROP TABLE IF EXISTS users CASCADE;
CREATE TABLE users
(
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
......
<?php
use yii\db\dao\Connection;
use yii\db\dao\Command;
use yii\db\dao\Query;
class CommandTest extends TestCase
{
private $connection;
function setUp()
{
if(!extension_loaded('pdo') || !extension_loaded('pdo_mysql'))
$this->markTestSkipped('pdo and pdo_mysql extensions are required.');
$params = $this->getParam('mysql');
$this->connection = new Connection($params['dsn'], $params['username'], $params['password']);
$this->connection->open();
$this->connection->pdo->exec(file_get_contents($params['fixture']));
}
function tearDown()
{
$this->connection->close();
}
function testConstruct()
{
$command = $this->connection->createCommand();
$this->assertEquals("SELECT *\nFROM ", $command->sql);
$sql='SELECT * FROM posts';
$command = $this->connection->createCommand($sql);
$this->assertEquals($sql, $command->sql);
$query = new Query;
$command = $this->connection->createCommand($query);
$this->assertEquals($query, $command->query);
$query = array('select'=>'id', 'from'=>'posts');
$command = $this->connection->createCommand($query);
$this->assertEquals($query, $command->query->toArray());
}
function testReset()
{
}
function testGetSetSql()
{
}
function testPrepare()
{
}
function testBindParam()
{
}
function testBindValue()
{
}
function testExecute()
{
}
function testQuery()
{
}
function testQueryRow()
{
}
function testQueryAll()
{
}
function testQueryColumn()
{
}
function testQueryScalar()
{
}
function testFetchMode()
{
}
s /*
function testPrepare()
{
$sql='SELECT title FROM posts';
$command=$this->connection->createCommand($sql);
$this->assertEquals($command->pdoStatement,null);
$command->prepare();
$this->assertTrue($command->pdoStatement instanceof PDOStatement);
$this->assertEquals($command->queryScalar(),'post 1');
$command->text='Bad SQL';
$this->setExpectedException('CException');
$command->prepare();
}
function testCancel()
{
$sql='SELECT title FROM posts';
$command=$this->connection->createCommand($sql);
$command->prepare();
$this->assertTrue($command->pdoStatement instanceof PDOStatement);
$command->cancel();
$this->assertEquals($command->pdoStatement,null);
}
function testExecute()
{
$sql='INSERT INTO comments(content,post_id,author_id) VALUES (\'test comment\', 1, 1)';
$command=$this->connection->createCommand($sql);
$this->assertEquals($command->execute(),1);
$this->assertEquals($command->execute(),1);
$command=$this->connection->createCommand('SELECT * FROM comments WHERE content=\'test comment\'');
$this->assertEquals($command->execute(),0);
$command=$this->connection->createCommand('SELECT COUNT(*) FROM comments WHERE content=\'test comment\'');
$this->assertEquals($command->queryScalar(),2);
$command=$this->connection->createCommand('bad SQL');
$this->setExpectedException('CException');
$command->execute();
}
function testQuery()
{
$sql='SELECT * FROM posts';
$reader=$this->connection->createCommand($sql)->query();
$this->assertTrue($reader instanceof CDbDataReader);
$sql='SELECT * FROM posts';
$command=$this->connection->createCommand($sql);
$command->prepare();
$reader=$command->query();
$this->assertTrue($reader instanceof CDbDataReader);
$command=$this->connection->createCommand('bad SQL');
$this->setExpectedException('CException');
$command->query();
}
function testBindParam()
{
$sql='INSERT INTO posts(title,create_time,author_id) VALUES (:title, :create_time, 1)';
$command=$this->connection->createCommand($sql);
$title='test title';
$createTime=time();
$command->bindParam(':title',$title);
$command->bindParam(':create_time',$createTime);
$command->execute();
$sql='SELECT create_time FROM posts WHERE title=:title';
$command=$this->connection->createCommand($sql);
$command->bindParam(':title',$title);
$this->assertEquals($command->queryScalar(),$createTime);
$sql='INSERT INTO types (int_col, char_col, float_col, blob_col, numeric_col, bool_col) VALUES (:int_col, :char_col, :float_col, :blob_col, :numeric_col, :bool_col)';
$command=$this->connection->createCommand($sql);
$intCol=123;
$charCol='abc';
$floatCol=1.23;
$blobCol="\x10\x11\x12";
$numericCol='1.23';
$boolCol=false;
$command->bindParam(':int_col',$intCol);
$command->bindParam(':char_col',$charCol);
$command->bindParam(':float_col',$floatCol);
$command->bindParam(':blob_col',$blobCol);
$command->bindParam(':numeric_col',$numericCol);
$command->bindParam(':bool_col',$boolCol);
$this->assertEquals(1,$command->execute());
$sql='SELECT * FROM types';
$row=$this->connection->createCommand($sql)->queryRow();
$this->assertEquals($row['int_col'],$intCol);
$this->assertEquals($row['char_col'],$charCol);
$this->assertEquals($row['float_col'],$floatCol);
$this->assertEquals($row['blob_col'],$blobCol);
$this->assertEquals($row['numeric_col'],$numericCol);
}
function testBindValue()
{
$sql='INSERT INTO comments(content,post_id,author_id) VALUES (:content, 1, 1)';
$command=$this->connection->createCommand($sql);
$command->bindValue(':content','test comment');
$command->execute();
$sql='SELECT post_id FROM comments WHERE content=:content';
$command=$this->connection->createCommand($sql);
$command->bindValue(':content','test comment');
$this->assertEquals($command->queryScalar(),1);
}
function testQueryAll()
{
$rows=$this->connection->createCommand('SELECT * FROM posts')->queryAll();
$this->assertEquals(count($rows),5);
$row=$rows[2];
$this->assertEquals($row['id'],3);
$this->assertEquals($row['title'],'post 3');
$rows=$this->connection->createCommand('SELECT * FROM posts WHERE id=10')->queryAll();
$this->assertEquals($rows,array());
}
function testQueryRow()
{
$sql='SELECT * FROM posts';
$row=$this->connection->createCommand($sql)->queryRow();
$this->assertEquals($row['id'],1);
$this->assertEquals($row['title'],'post 1');
$sql='SELECT * FROM posts';
$command=$this->connection->createCommand($sql);
$command->prepare();
$row=$command->queryRow();
$this->assertEquals($row['id'],1);
$this->assertEquals($row['title'],'post 1');
$sql='SELECT * FROM posts WHERE id=10';
$command=$this->connection->createCommand($sql);
$this->assertFalse($command->queryRow());
$command=$this->connection->createCommand('bad SQL');
$this->setExpectedException('CException');
$command->queryRow();
}
function testQueryColumn()
{
$sql='SELECT * FROM posts';
$column=$this->connection->createCommand($sql)->queryColumn();
$this->assertEquals($column,range(1,5));
$command=$this->connection->createCommand('SELECT id FROM posts WHERE id=10');
$this->assertEquals($command->queryColumn(),array());
$command=$this->connection->createCommand('bad SQL');
$this->setExpectedException('CException');
$command->queryColumn();
}
function testQueryScalar()
{
$sql='SELECT * FROM posts';
$this->assertEquals($this->connection->createCommand($sql)->queryScalar(),1);
$sql='SELECT id FROM posts';
$command=$this->connection->createCommand($sql);
$command->prepare();
$this->assertEquals($command->queryScalar(),1);
$command=$this->connection->createCommand('SELECT id FROM posts WHERE id=10');
$this->assertFalse($command->queryScalar());
$command=$this->connection->createCommand('bad SQL');
$this->setExpectedException('CException');
$command->queryScalar();
}
function testFetchMode(){
$sql='SELECT * FROM posts';
$command=$this->connection->createCommand($sql);
$result = $command->queryRow();
$this->assertTrue(is_array($result));
$sql='SELECT * FROM posts';
$command=$this->connection->createCommand($sql);
$command->setFetchMode(PDO::FETCH_OBJ);
$result = $command->queryRow();
$this->assertTrue(is_object($result));
}
*/
}
\ No newline at end of file
......@@ -85,57 +85,9 @@ class ConnectionTest extends TestCase
}
function createConnection()
{
$params = $this->getParam('mysql');
return new Connection($params['dsn'], $params['username'], $params['password']);
}
/*
function testCreateCommand()
{
$sql='SELECT * FROM posts';
$this->connection->active=true;
$this->connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
$command=$this->connection->createCommand($sql);
$this->assertTrue($command instanceof CDbCommand);
}
function testLastInsertID()
{
$this->connection->active=true;
$this->connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
$sql='INSERT INTO posts(title,create_time,author_id) VALUES(\'test post\',11000,1)';
$this->connection->createCommand($sql)->execute();
$this->assertEquals($this->connection->lastInsertID,6);
}
function testQuoteValue()
{
$this->connection->active=true;
$this->connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
$str="this is 'my' name";
$expectedStr="'this is ''my'' name'";
$this->assertEquals($expectedStr,$this->connection->quoteValue($str));
}
function testColumnNameCase()
{
$this->connection->active=true;
$this->connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
$this->assertEquals(PDO::CASE_NATURAL,$this->connection->ColumnCase);
$this->connection->columnCase=PDO::CASE_LOWER;
$this->assertEquals(PDO::CASE_LOWER,$this->connection->ColumnCase);
}
function testNullConversion()
{
$this->connection->active=true;
$this->connection->pdoInstance->exec(file_get_contents(dirname(__FILE__).'/data/sqlite.sql'));
$this->assertEquals(PDO::NULL_NATURAL,$this->connection->NullConversion);
$this->connection->nullConversion=PDO::NULL_EMPTY_STRING;
$this->assertEquals(PDO::NULL_EMPTY_STRING,$this->connection->NullConversion);
}
*/
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment