1
0
mirror of synced 2025-01-20 23:41:39 +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
*/
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
*/
@ -48,6 +53,8 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
private $pendingFields = array();
protected $type = self::SELECT;
/**
* create
* returns a new Doctrine_Query object
@ -270,10 +277,28 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
public function __call($name, $args) {
$name = strtolower($name);
if(isset($this->parts[$name])) {
if($name == 'select')
$method = "parse".ucwords($name);
switch($name):
case "from":
switch($name) {
case 'select':
$this->type = self::SELECT;
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();
@ -288,17 +313,17 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
$parser->parse($args[0]);
break;
case "where":
case "having":
case "orderby":
case "groupby":
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":
case 'limit':
case 'offset':
if($args[0] == null)
$args[0] = false;
@ -307,9 +332,10 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
default:
$this->parts[$name] = array();
$this->$method($args[0]);
endswitch;
} else
throw new Doctrine_Query_Exception("Unknown overload method");
}
return $this;
}
@ -371,6 +397,23 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
public function isLimitSubqueryUsed() {
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
*
@ -396,8 +439,11 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
if($this->isDistinct())
$str = 'DISTINCT ';
$q = "SELECT ".$str.implode(", ",$this->parts["select"]).
" FROM ";
$q = $this->getQueryBase();
foreach($this->parts["from"] as $tname => $bool) {
$a[] = $tname;
@ -523,17 +569,18 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
foreach($e as $k=>$part) {
$part = trim($part);
switch(strtolower($part)) {
case "select":
case "from":
case "where":
case "limit":
case "offset":
case "having":
case 'delete':
case 'select':
case 'from':
case 'where':
case 'limit':
case 'offset':
case 'having':
$p = $part;
$parts[$part] = array();
break;
case "order":
case "group":
case 'order':
case 'group':
$i = ($k + 1);
if(isset($e[$i]) && strtolower($e[$i]) === "by") {
$p = $part;
@ -554,29 +601,36 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
foreach($parts as $k => $part) {
$part = implode(" ",$part);
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);
break;
case "FROM":
case 'FROM':
$class = "Doctrine_Query_".ucwords(strtolower($k));
$parser = new $class($this);
$parser->parse($part);
break;
case "GROUP":
case "ORDER":
case 'GROUP':
case 'ORDER':
$k .= "by";
case "WHERE":
case "HAVING":
case 'WHERE':
case 'HAVING':
$class = "Doctrine_Query_".ucwords(strtolower($k));
$parser = new $class($this);
$name = strtolower($k);
$this->parts[$name][] = $parser->parse($part);
break;
case "LIMIT":
case 'LIMIT':
$this->parts["limit"] = trim($part);
break;
case "OFFSET":
case 'OFFSET':
$this->parts["offset"] = trim($part);
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)');
}
public function testEmptySelectPart() {
$q = new Doctrine_Query();
try {
$q->select();
$this->fail();
} catch(Doctrine_Query_Exception $e) {
$this->pass();
}
}
public function testUnknownAggregateFunction() {
$q = new Doctrine_Query();

View File

@ -1,5 +1,5 @@
<?php
class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
class Doctrine_Query_TestCase extends Doctrine_UnitTestCase {
public function prepareTables() {
$this->tables[] = "Forum_Category";
$this->tables[] = "Forum_Entry";

View File

@ -38,6 +38,7 @@ require_once("QueryConditionTestCase.php");
require_once("QueryComponentAliasTestCase.php");
require_once("QuerySubqueryTestCase.php");
require_once("QuerySelectTestCase.php");
require_once("QueryDeleteTestCase.php");
require_once("DBTestCase.php");
require_once("SchemaTestCase.php");
@ -49,9 +50,6 @@ require_once("RelationTestCase.php");
require_once("DataDictSqliteTestCase.php");
require_once("CustomResultSetOrderTestCase.php");
// unsorted tests are here, these should be moved somewhere sensible
require_once("UnsortedTestCase.php");
error_reporting(E_ALL);
print "<pre>";
@ -127,7 +125,7 @@ $test->addTestCase(new Doctrine_Query_ComponentAlias_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());
@ -135,7 +133,8 @@ $test->addTestCase(new Doctrine_Query_From_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_SqliteTestCase());