Tests and implementation for DQL functions contains(), like() and regexp()
This commit is contained in:
parent
060739d72c
commit
120d18565c
@ -541,10 +541,14 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static function bracketExplode($str,$d,$e1 = '(',$e2 = ')') {
|
public static function bracketExplode($str,$d,$e1 = '(',$e2 = ')') {
|
||||||
$str = explode("$d",$str);
|
if(is_array($d))
|
||||||
|
$a = explode("$d",$str);
|
||||||
|
else
|
||||||
|
$a = explode("$d",$str);
|
||||||
|
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$term = array();
|
$term = array();
|
||||||
foreach($str as $key=>$val) {
|
foreach($a as $key=>$val) {
|
||||||
if (empty($term[$i])) {
|
if (empty($term[$i])) {
|
||||||
$term[$i] = trim($val);
|
$term[$i] = trim($val);
|
||||||
$s1 = substr_count($term[$i],"$e1");
|
$s1 = substr_count($term[$i],"$e1");
|
||||||
|
@ -33,14 +33,17 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition {
|
|||||||
$pos = strpos($field, "(");
|
$pos = strpos($field, "(");
|
||||||
|
|
||||||
if($pos !== false) {
|
if($pos !== false) {
|
||||||
$func = substr($field, 0, $pos);
|
$func = substr($field, 0, $pos);
|
||||||
$value = substr($field, ($pos + 1), -1);
|
$value = substr($field, ($pos + 1), -1);
|
||||||
$field = array_pop($a);
|
|
||||||
$reference = implode(".",$a);
|
$values = Doctrine_Query::sqlExplode($value, ',');
|
||||||
$table = $this->query->load($reference, false);
|
|
||||||
|
$field = array_pop($a);
|
||||||
|
$reference = implode(".",$a);
|
||||||
|
$table = $this->query->load($reference, false);
|
||||||
array_pop($a);
|
array_pop($a);
|
||||||
$reference2 = implode('.', $a);
|
$reference2 = implode('.', $a);
|
||||||
$alias = $this->query->getTableAlias($reference2);
|
$alias = $this->query->getTableAlias($reference2);
|
||||||
|
|
||||||
$stack = $this->query->getRelationStack();
|
$stack = $this->query->getRelationStack();
|
||||||
$relation = end($stack);
|
$relation = end($stack);
|
||||||
@ -49,16 +52,20 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition {
|
|||||||
|
|
||||||
switch($func) {
|
switch($func) {
|
||||||
case 'contains':
|
case 'contains':
|
||||||
$operator = ' = ';
|
|
||||||
case 'regexp':
|
case 'regexp':
|
||||||
$operator = ' RLIKE ';
|
|
||||||
case 'like':
|
case 'like':
|
||||||
if(empty($relation))
|
$operator = $this->getOperator($func);
|
||||||
throw new Doctrine_Query_Exception('DQL function contains can only be used for fields of related components');
|
|
||||||
|
|
||||||
$where = $alias.'.'.$relation->getLocal().
|
if(empty($relation))
|
||||||
|
throw new Doctrine_Query_Exception('DQL functions contains/regexp/like can only be used for fields of related components');
|
||||||
|
|
||||||
|
$where = array();
|
||||||
|
foreach($values as $value) {
|
||||||
|
$where[] = $alias.'.'.$relation->getLocal().
|
||||||
' IN (SELECT '.$relation->getForeign().
|
' IN (SELECT '.$relation->getForeign().
|
||||||
' FROM '.$relation->getTable()->getTableName().' WHERE '.$field.' = '.$value.')';
|
' FROM '.$relation->getTable()->getTableName().' WHERE '.$field.$operator.$value.')';
|
||||||
|
}
|
||||||
|
$where = implode(' AND ', $where);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Doctrine_Query_Exception('Unknown DQL function: '.$func);
|
throw new Doctrine_Query_Exception('Unknown DQL function: '.$func);
|
||||||
@ -82,11 +89,25 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition {
|
|||||||
$where = $this->query->getTableAlias($reference).'.'.$field.' '.$operator.' '.$value;
|
$where = $this->query->getTableAlias($reference).'.'.$field.' '.$operator.' '.$value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
throw new Doctrine_Query_Exception('Unknown component path. The correct format should be component1.component2 ... componentN.field');
|
|
||||||
return $where;
|
return $where;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getOperator($func) {
|
||||||
|
switch($func) {
|
||||||
|
case 'contains':
|
||||||
|
$operator = ' = ';
|
||||||
|
break;
|
||||||
|
case 'regexp':
|
||||||
|
$operator = $this->query->getConnection()->getRegexpOperator();
|
||||||
|
break;
|
||||||
|
case 'like':
|
||||||
|
$operator = ' LIKE ';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $operator;
|
||||||
|
}
|
||||||
|
|
||||||
public function __toString() {
|
public function __toString() {
|
||||||
return ( ! empty($this->parts))?implode(" AND ", $this->parts):'';
|
return ( ! empty($this->parts))?implode(" AND ", $this->parts):'';
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,16 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
|
|||||||
}
|
}
|
||||||
$this->assertTrue($f);
|
$this->assertTrue($f);
|
||||||
}
|
}
|
||||||
|
public function testBadFunctionLogic() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
$f = false;
|
||||||
|
try {
|
||||||
|
$q->from('User')->where('User.name.contains(?)');
|
||||||
|
} catch(Doctrine_Query_Exception $e) {
|
||||||
|
$f = true;
|
||||||
|
}
|
||||||
|
$this->assertTrue($f);
|
||||||
|
}
|
||||||
public function testDqlContainsFunction() {
|
public function testDqlContainsFunction() {
|
||||||
$q = new Doctrine_Query();
|
$q = new Doctrine_Query();
|
||||||
$this->connection->clear();
|
$this->connection->clear();
|
||||||
@ -47,8 +57,6 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
|
|||||||
$this->assertEqual(count($q->getTableStack()), 2);
|
$this->assertEqual(count($q->getTableStack()), 2);
|
||||||
$this->assertEqual(count($q->getRelationStack()), 1);
|
$this->assertEqual(count($q->getRelationStack()), 1);
|
||||||
|
|
||||||
//print Doctrine_Lib::formatSql($q->getQuery());
|
|
||||||
|
|
||||||
$coll = $q->execute(array('123 123'));
|
$coll = $q->execute(array('123 123'));
|
||||||
|
|
||||||
$this->assertEqual($q->getQuery(), 'SELECT entity.id AS entity__id, entity.name AS entity__name, entity.loginname AS entity__loginname, entity.password AS entity__password, entity.type AS entity__type, entity.created AS entity__created, entity.updated AS entity__updated, entity.email_id AS entity__email_id FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE entity.id IN (SELECT entity_id FROM phonenumber WHERE phonenumber = ?) AND (entity.type = 0)');
|
$this->assertEqual($q->getQuery(), 'SELECT entity.id AS entity__id, entity.name AS entity__name, entity.loginname AS entity__loginname, entity.password AS entity__password, entity.type AS entity__type, entity.created AS entity__created, entity.updated AS entity__updated, entity.email_id AS entity__email_id FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE entity.id IN (SELECT entity_id FROM phonenumber WHERE phonenumber = ?) AND (entity.type = 0)');
|
||||||
@ -58,10 +66,45 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
|
|||||||
$this->assertEqual($coll[0]->Phonenumber->count(), 1);
|
$this->assertEqual($coll[0]->Phonenumber->count(), 1);
|
||||||
$this->assertEqual($coll[1]->Phonenumber->count(), 3);
|
$this->assertEqual($coll[1]->Phonenumber->count(), 3);
|
||||||
$this->assertEqual($coll[2]->Phonenumber->count(), 1);
|
$this->assertEqual($coll[2]->Phonenumber->count(), 1);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
public function testDqlFunctionWithMultipleParams() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
$this->connection->clear();
|
||||||
|
|
||||||
|
$q->from('User')->where('User.Phonenumber.phonenumber.like(?,?)');
|
||||||
|
$this->assertEqual(count($q->getTableStack()), 2);
|
||||||
|
$this->assertEqual(count($q->getRelationStack()), 1);
|
||||||
|
|
||||||
|
$coll = $q->execute(array('%123%', '%5%'));
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'SELECT entity.id AS entity__id, entity.name AS entity__name, entity.loginname AS entity__loginname, entity.password AS entity__password, entity.type AS entity__type, entity.created AS entity__created, entity.updated AS entity__updated, entity.email_id AS entity__email_id FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE entity.id IN (SELECT entity_id FROM phonenumber WHERE phonenumber LIKE ?) AND entity.id IN (SELECT entity_id FROM phonenumber WHERE phonenumber LIKE ?) AND (entity.type = 0)');
|
||||||
|
|
||||||
|
$this->assertEqual($coll->count(), 3);
|
||||||
|
$this->assertEqual($coll[0]->name, 'Arnold Schwarzenegger');
|
||||||
|
$this->assertEqual($coll[0]->Phonenumber->count(), 3);
|
||||||
|
$this->assertEqual($coll[1]->Phonenumber->count(), 3);
|
||||||
|
$this->assertEqual($coll[2]->Phonenumber->count(), 3);
|
||||||
|
}
|
||||||
|
public function testDqlLikeFunction() {
|
||||||
|
$q = new Doctrine_Query();
|
||||||
|
$this->connection->clear();
|
||||||
|
|
||||||
|
$q->from('User')->where('User.Phonenumber.phonenumber.like(?)');
|
||||||
|
$this->assertEqual(count($q->getTableStack()), 2);
|
||||||
|
$this->assertEqual(count($q->getRelationStack()), 1);
|
||||||
|
|
||||||
|
$coll = $q->execute(array('123%'));
|
||||||
|
|
||||||
|
$this->assertEqual($q->getQuery(), 'SELECT entity.id AS entity__id, entity.name AS entity__name, entity.loginname AS entity__loginname, entity.password AS entity__password, entity.type AS entity__type, entity.created AS entity__created, entity.updated AS entity__updated, entity.email_id AS entity__email_id FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE entity.id IN (SELECT entity_id FROM phonenumber WHERE phonenumber LIKE ?) AND (entity.type = 0)');
|
||||||
|
|
||||||
|
$this->assertEqual($coll->count(), 5);
|
||||||
|
$this->assertEqual($coll[0]->name, 'zYne');
|
||||||
|
$this->assertEqual($coll[0]->Phonenumber->count(), 1);
|
||||||
|
$this->assertEqual($coll[1]->Phonenumber->count(), 3);
|
||||||
|
$this->assertEqual($coll[2]->Phonenumber->count(), 1);
|
||||||
|
$this->assertEqual($coll[3]->Phonenumber->count(), 3);
|
||||||
|
$this->assertEqual($coll[4]->Phonenumber->count(), 3);
|
||||||
|
}
|
||||||
public function testEnumConversion() {
|
public function testEnumConversion() {
|
||||||
$e[0] = new EnumTest();
|
$e[0] = new EnumTest();
|
||||||
$e[0]->status = 'open';
|
$e[0]->status = 'open';
|
||||||
|
@ -31,7 +31,7 @@ require_once("ImportTestCase.php");
|
|||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
$test = new GroupTest("Doctrine Framework Unit Tests");
|
$test = new GroupTest("Doctrine Framework Unit Tests");
|
||||||
/**
|
|
||||||
$test->addTestCase(new Doctrine_AccessTestCase());
|
$test->addTestCase(new Doctrine_AccessTestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_EventListenerTestCase());
|
$test->addTestCase(new Doctrine_EventListenerTestCase());
|
||||||
@ -73,7 +73,7 @@ $test->addTestCase(new Doctrine_ImportTestCase());
|
|||||||
$test->addTestCase(new Doctrine_ValidatorTestCase());
|
$test->addTestCase(new Doctrine_ValidatorTestCase());
|
||||||
|
|
||||||
$test->addTestCase(new Doctrine_CollectionTestCase());
|
$test->addTestCase(new Doctrine_CollectionTestCase());
|
||||||
*/
|
|
||||||
$test->addTestCase(new Doctrine_QueryTestCase());
|
$test->addTestCase(new Doctrine_QueryTestCase());
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user