1
0
mirror of synced 2025-02-01 13:01:45 +03:00

DQL: DELETE support added

This commit is contained in:
zYne 2006-10-18 17:37:20 +00:00
parent cce886dadd
commit 1c8cf0271e
5 changed files with 194 additions and 61 deletions

View File

@ -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;
} }

View 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');
}
}
?>

View File

@ -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();

View File

@ -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";

View File

@ -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());