DQL: DELETE support added
This commit is contained in:
parent
cce886dadd
commit
1c8cf0271e
@ -27,6 +27,11 @@
|
|||||||
* @license LGPL
|
* @license LGPL
|
||||||
*/
|
*/
|
||||||
class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
||||||
|
const SELECT = 0;
|
||||||
|
|
||||||
|
const DELETE = 1;
|
||||||
|
|
||||||
|
const UPDATE = 2;
|
||||||
/**
|
/**
|
||||||
* @param array $subqueryAliases the table aliases needed in some LIMIT subqueries
|
* @param array $subqueryAliases the table aliases needed in some LIMIT subqueries
|
||||||
*/
|
*/
|
||||||
@ -48,6 +53,8 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
|
|
||||||
private $pendingFields = array();
|
private $pendingFields = array();
|
||||||
|
|
||||||
|
protected $type = self::SELECT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create
|
* create
|
||||||
* returns a new Doctrine_Query object
|
* returns a new Doctrine_Query object
|
||||||
@ -270,46 +277,65 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
public function __call($name, $args) {
|
public function __call($name, $args) {
|
||||||
$name = strtolower($name);
|
$name = strtolower($name);
|
||||||
|
|
||||||
if(isset($this->parts[$name])) {
|
if($name == 'select')
|
||||||
$method = "parse".ucwords($name);
|
|
||||||
switch($name):
|
|
||||||
case "from":
|
|
||||||
$this->parts['from'] = array();
|
|
||||||
$this->parts['select'] = array();
|
|
||||||
$this->parts['join'] = array();
|
|
||||||
$this->joins = array();
|
|
||||||
$this->tables = array();
|
|
||||||
$this->fetchModes = array();
|
|
||||||
$this->tableIndexes = array();
|
|
||||||
$this->tableAliases = array();
|
|
||||||
|
|
||||||
$class = "Doctrine_Query_".ucwords($name);
|
|
||||||
$parser = new $class($this);
|
|
||||||
|
|
||||||
$parser->parse($args[0]);
|
|
||||||
break;
|
|
||||||
case "where":
|
|
||||||
case "having":
|
|
||||||
case "orderby":
|
|
||||||
case "groupby":
|
|
||||||
$class = "Doctrine_Query_".ucwords($name);
|
|
||||||
$parser = new $class($this);
|
|
||||||
|
|
||||||
$this->parts[$name] = array($parser->parse($args[0]));
|
$method = "parse".ucwords($name);
|
||||||
break;
|
|
||||||
case "limit":
|
switch($name) {
|
||||||
case "offset":
|
case 'select':
|
||||||
if($args[0] == null)
|
$this->type = self::SELECT;
|
||||||
$args[0] = false;
|
|
||||||
|
if( ! isset($args[0]))
|
||||||
|
throw new Doctrine_Query_Exception('Empty select part');
|
||||||
|
|
||||||
|
$this->parseSelect($args[0]);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
$this->type = self::DELETE;
|
||||||
|
break;
|
||||||
|
case 'update':
|
||||||
|
$this->type = self::UPDATE;
|
||||||
|
break;
|
||||||
|
case 'from':
|
||||||
|
$this->parts['from'] = array();
|
||||||
|
$this->parts['select'] = array();
|
||||||
|
$this->parts['join'] = array();
|
||||||
|
$this->joins = array();
|
||||||
|
$this->tables = array();
|
||||||
|
$this->fetchModes = array();
|
||||||
|
$this->tableIndexes = array();
|
||||||
|
$this->tableAliases = array();
|
||||||
|
|
||||||
|
$class = "Doctrine_Query_".ucwords($name);
|
||||||
|
$parser = new $class($this);
|
||||||
|
|
||||||
|
$parser->parse($args[0]);
|
||||||
|
break;
|
||||||
|
case 'where':
|
||||||
|
case 'having':
|
||||||
|
case 'orderby':
|
||||||
|
case 'groupby':
|
||||||
|
$class = "Doctrine_Query_".ucwords($name);
|
||||||
|
$parser = new $class($this);
|
||||||
|
|
||||||
|
$this->parts[$name] = array($parser->parse($args[0]));
|
||||||
|
break;
|
||||||
|
case 'limit':
|
||||||
|
case 'offset':
|
||||||
|
if($args[0] == null)
|
||||||
|
$args[0] = false;
|
||||||
|
|
||||||
|
$this->parts[$name] = $args[0];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->parts[$name] = array();
|
||||||
|
$this->$method($args[0]);
|
||||||
|
|
||||||
$this->parts[$name] = $args[0];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->parts[$name] = array();
|
|
||||||
$this->$method($args[0]);
|
|
||||||
endswitch;
|
|
||||||
} else
|
|
||||||
throw new Doctrine_Query_Exception("Unknown overload method");
|
throw new Doctrine_Query_Exception("Unknown overload method");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -371,6 +397,23 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
public function isLimitSubqueryUsed() {
|
public function isLimitSubqueryUsed() {
|
||||||
return $this->limitSubqueryUsed;
|
return $this->limitSubqueryUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getQueryBase() {
|
||||||
|
switch($this->type) {
|
||||||
|
case self::DELETE:
|
||||||
|
$q = 'DELETE FROM ';
|
||||||
|
break;
|
||||||
|
case self::UPDATE:
|
||||||
|
$q = 'UPDATE ';
|
||||||
|
break;
|
||||||
|
case self::SELECT:
|
||||||
|
$distinct = ($this->isDistinct()) ? 'DISTINCT ' : '';
|
||||||
|
|
||||||
|
$q = 'SELECT '.$distinct.implode(', ', $this->parts['select']).' FROM ';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $q;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* returns the built sql query
|
* returns the built sql query
|
||||||
*
|
*
|
||||||
@ -396,8 +439,11 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
if($this->isDistinct())
|
if($this->isDistinct())
|
||||||
$str = 'DISTINCT ';
|
$str = 'DISTINCT ';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$q = "SELECT ".$str.implode(", ",$this->parts["select"]).
|
$q = "SELECT ".$str.implode(", ",$this->parts["select"]).
|
||||||
" FROM ";
|
" FROM ";
|
||||||
|
$q = $this->getQueryBase();
|
||||||
|
|
||||||
foreach($this->parts["from"] as $tname => $bool) {
|
foreach($this->parts["from"] as $tname => $bool) {
|
||||||
$a[] = $tname;
|
$a[] = $tname;
|
||||||
@ -523,17 +569,18 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
foreach($e as $k=>$part) {
|
foreach($e as $k=>$part) {
|
||||||
$part = trim($part);
|
$part = trim($part);
|
||||||
switch(strtolower($part)) {
|
switch(strtolower($part)) {
|
||||||
case "select":
|
case 'delete':
|
||||||
case "from":
|
case 'select':
|
||||||
case "where":
|
case 'from':
|
||||||
case "limit":
|
case 'where':
|
||||||
case "offset":
|
case 'limit':
|
||||||
case "having":
|
case 'offset':
|
||||||
|
case 'having':
|
||||||
$p = $part;
|
$p = $part;
|
||||||
$parts[$part] = array();
|
$parts[$part] = array();
|
||||||
break;
|
break;
|
||||||
case "order":
|
case 'order':
|
||||||
case "group":
|
case 'group':
|
||||||
$i = ($k + 1);
|
$i = ($k + 1);
|
||||||
if(isset($e[$i]) && strtolower($e[$i]) === "by") {
|
if(isset($e[$i]) && strtolower($e[$i]) === "by") {
|
||||||
$p = $part;
|
$p = $part;
|
||||||
@ -554,29 +601,36 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
foreach($parts as $k => $part) {
|
foreach($parts as $k => $part) {
|
||||||
$part = implode(" ",$part);
|
$part = implode(" ",$part);
|
||||||
switch(strtoupper($k)) {
|
switch(strtoupper($k)) {
|
||||||
case "SELECT":
|
case 'DELETE':
|
||||||
|
$this->type = self::DELETE;
|
||||||
|
break;
|
||||||
|
case 'UPDATE':
|
||||||
|
$this->type = self::UPDATE;
|
||||||
|
break;
|
||||||
|
case 'SELECT':
|
||||||
|
$this->type = self::SELECT;
|
||||||
$this->parseSelect($part);
|
$this->parseSelect($part);
|
||||||
break;
|
break;
|
||||||
case "FROM":
|
case 'FROM':
|
||||||
$class = "Doctrine_Query_".ucwords(strtolower($k));
|
$class = "Doctrine_Query_".ucwords(strtolower($k));
|
||||||
$parser = new $class($this);
|
$parser = new $class($this);
|
||||||
$parser->parse($part);
|
$parser->parse($part);
|
||||||
break;
|
break;
|
||||||
case "GROUP":
|
case 'GROUP':
|
||||||
case "ORDER":
|
case 'ORDER':
|
||||||
$k .= "by";
|
$k .= "by";
|
||||||
case "WHERE":
|
case 'WHERE':
|
||||||
case "HAVING":
|
case 'HAVING':
|
||||||
$class = "Doctrine_Query_".ucwords(strtolower($k));
|
$class = "Doctrine_Query_".ucwords(strtolower($k));
|
||||||
$parser = new $class($this);
|
$parser = new $class($this);
|
||||||
|
|
||||||
$name = strtolower($k);
|
$name = strtolower($k);
|
||||||
$this->parts[$name][] = $parser->parse($part);
|
$this->parts[$name][] = $parser->parse($part);
|
||||||
break;
|
break;
|
||||||
case "LIMIT":
|
case 'LIMIT':
|
||||||
$this->parts["limit"] = trim($part);
|
$this->parts["limit"] = trim($part);
|
||||||
break;
|
break;
|
||||||
case "OFFSET":
|
case 'OFFSET':
|
||||||
$this->parts["offset"] = trim($part);
|
$this->parts["offset"] = trim($part);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
69
tests/QueryDeleteTestCase.php
Normal file
69
tests/QueryDeleteTestCase.php
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
class Doctrine_Query_Delete_TestCase extends Doctrine_UnitTestCase {
|
||||||
|
public function testDeleteAllWithColumnAggregationInheritance() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->parseQuery('DELETE FROM User');
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'DELETE FROM entity WHERE (entity.type = 0)');
|
||||||
|
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->delete()->from('User');
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'DELETE FROM entity WHERE (entity.type = 0)');
|
||||||
|
}
|
||||||
|
public function testDeleteAll() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->parseQuery('DELETE FROM Entity');
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'DELETE FROM entity');
|
||||||
|
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->delete()->from('Entity');
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'DELETE FROM entity');
|
||||||
|
}
|
||||||
|
public function testDeleteWithCondition() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->parseQuery('DELETE FROM Entity WHERE id = 3');
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'DELETE FROM entity WHERE id = 3');
|
||||||
|
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->delete()->from('Entity')->where('id = 3');
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'DELETE FROM entity WHERE id = 3');
|
||||||
|
}
|
||||||
|
public function testDeleteWithLimit() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->parseQuery('DELETE FROM Entity LIMIT 20');
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'DELETE FROM entity LIMIT 20');
|
||||||
|
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->delete()->from('Entity')->limit(20);
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'DELETE FROM entity LIMIT 20');
|
||||||
|
}
|
||||||
|
public function testDeleteWithLimitAndOffset() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->parseQuery('DELETE FROM Entity LIMIT 10 OFFSET 20');
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'DELETE FROM entity LIMIT 10 OFFSET 20');
|
||||||
|
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
$q->delete()->from('Entity')->limit(10)->offset(20);
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'DELETE FROM entity LIMIT 10 OFFSET 20');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
@ -23,6 +23,17 @@ class Doctrine_Query_Select_TestCase extends Doctrine_UnitTestCase {
|
|||||||
|
|
||||||
$this->assertEqual($q->getQuery(), 'SELECT MAX(entity.id) AS entity__0, MIN(entity.name) AS entity__1, COUNT(phonenumber.id) AS phonenumber__2 FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE (entity.type = 0)');
|
$this->assertEqual($q->getQuery(), 'SELECT MAX(entity.id) AS entity__0, MIN(entity.name) AS entity__1, COUNT(phonenumber.id) AS phonenumber__2 FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE (entity.type = 0)');
|
||||||
}
|
}
|
||||||
|
public function testEmptySelectPart() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$q->select();
|
||||||
|
|
||||||
|
$this->fail();
|
||||||
|
} catch(Doctrine_Query_Exception $e) {
|
||||||
|
$this->pass();
|
||||||
|
}
|
||||||
|
}
|
||||||
public function testUnknownAggregateFunction() {
|
public function testUnknownAggregateFunction() {
|
||||||
$q = new Doctrine_Query();
|
$q = new Doctrine_Query();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
|
class Doctrine_Query_TestCase extends Doctrine_UnitTestCase {
|
||||||
public function prepareTables() {
|
public function prepareTables() {
|
||||||
$this->tables[] = "Forum_Category";
|
$this->tables[] = "Forum_Category";
|
||||||
$this->tables[] = "Forum_Entry";
|
$this->tables[] = "Forum_Entry";
|
||||||
|
@ -38,6 +38,7 @@ require_once("QueryConditionTestCase.php");
|
|||||||
require_once("QueryComponentAliasTestCase.php");
|
require_once("QueryComponentAliasTestCase.php");
|
||||||
require_once("QuerySubqueryTestCase.php");
|
require_once("QuerySubqueryTestCase.php");
|
||||||
require_once("QuerySelectTestCase.php");
|
require_once("QuerySelectTestCase.php");
|
||||||
|
require_once("QueryDeleteTestCase.php");
|
||||||
|
|
||||||
require_once("DBTestCase.php");
|
require_once("DBTestCase.php");
|
||||||
require_once("SchemaTestCase.php");
|
require_once("SchemaTestCase.php");
|
||||||
@ -49,9 +50,6 @@ require_once("RelationTestCase.php");
|
|||||||
require_once("DataDictSqliteTestCase.php");
|
require_once("DataDictSqliteTestCase.php");
|
||||||
require_once("CustomResultSetOrderTestCase.php");
|
require_once("CustomResultSetOrderTestCase.php");
|
||||||
|
|
||||||
// unsorted tests are here, these should be moved somewhere sensible
|
|
||||||
require_once("UnsortedTestCase.php");
|
|
||||||
|
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
print "<pre>";
|
print "<pre>";
|
||||||
|
|
||||||
@ -127,7 +125,7 @@ $test->addTestCase(new Doctrine_Query_ComponentAlias_TestCase());
|
|||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_Subquery_TestCase());
|
$test->addTestCase(new Doctrine_Query_Subquery_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_QueryTestCase());
|
$test->addTestCase(new Doctrine_Query_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_Where_TestCase());
|
$test->addTestCase(new Doctrine_Query_Where_TestCase());
|
||||||
|
|
||||||
@ -135,7 +133,8 @@ $test->addTestCase(new Doctrine_Query_From_TestCase());
|
|||||||
|
|
||||||
$test->addTestCase(new Doctrine_Query_Select_TestCase());
|
$test->addTestCase(new Doctrine_Query_Select_TestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_UnsortedTestCase());
|
$test->addTestCase(new Doctrine_Query_Delete_TestCase());
|
||||||
|
|
||||||
|
|
||||||
//$test->addTestCase(new Doctrine_Cache_FileTestCase());
|
//$test->addTestCase(new Doctrine_Cache_FileTestCase());
|
||||||
//$test->addTestCase(new Doctrine_Cache_SqliteTestCase());
|
//$test->addTestCase(new Doctrine_Cache_SqliteTestCase());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user