1
0
mirror of synced 2025-01-18 06:21:40 +03:00

DQL: Many-to-Many fetching with where clause

This commit is contained in:
doctrine 2006-06-12 08:44:08 +00:00
parent 9c16da05bc
commit daeef41b2a
5 changed files with 71 additions and 56 deletions

View File

@ -45,8 +45,10 @@ class Doctrine_Form implements Iterator {
} else {
if($length <= 255) {
$elements[$column] = "<input name='data[$column]' type='text' value='".$this->record->get($column)."' maxlength=$length \>\n";
} else {
} elseif($length <= 4000) {
$elements[$column] = "<textarea name='data[$column]' cols=40 rows=10>".$this->record->get($column)."</textarea>\n";
} else {
$elements[$column] = "<textarea name='data[$column]' cols=60 rows=25>".$this->record->get($column)."</textarea>\n";
}
}
return $elements[$column];

View File

@ -187,6 +187,7 @@ class Doctrine_Query extends Doctrine_Access {
break;
case "from":
$this->parts['columns'] = array();
$this->parts['join'] = array();
$this->joins = array();
$this->tables = array();
$this->fetchModes = array();
@ -234,6 +235,7 @@ class Doctrine_Query extends Doctrine_Access {
break;
case "from":
$this->parts['columns'] = array();
$this->parts['join'] = array();
$this->joins = array();
$this->tables = array();
$this->fetchModes = array();
@ -513,6 +515,8 @@ class Doctrine_Query extends Doctrine_Access {
switch($fk->getType()):
case Doctrine_Relation::ONE_COMPOSITE:
case Doctrine_Relation::ONE_AGGREGATE:
// one-to-one relation
$last->internalSet($this->connectors[$name]->getLocal(), $record->getID());
$last->initSingleReference($record);
@ -895,42 +899,12 @@ class Doctrine_Query extends Doctrine_Access {
$operator = array_shift($e);
$value = implode(" ",$e);
$reference = implode(".",$a);
$count = count($a);
if(count($a) > 1)
$objTable = $this->tables[$a[0]]->getForeignKey(end($a))->getTable();
else
$objTable = $this->session->getTable(end($a));
$table = $this->load($reference, false);
$where = $objTable->getTableName().".".$field." ".$operator." ".$value;
if(count($a) > 1 && isset($a[1])) {
$root = $a[0];
$fk = $this->tables[$root]->getForeignKey($a[1]);
if($fk instanceof Doctrine_Association) {
$asf = $fk->getAssociationFactory();
switch($fk->getType()):
case Doctrine_Relation::ONE_AGGREGATE:
case Doctrine_Relation::ONE_COMPOSITE:
break;
case Doctrine_Relation::MANY_AGGREGATE:
case Doctrine_Relation::MANY_COMPOSITE:
// subquery needed
$where = $objTable->getComponentName().".".$field." ".$operator." ".$value;
$b = $fk->getTable()->getComponentName();
$graph = new Doctrine_Query($this->session);
$graph->parseQuery("FROM $b-l WHERE $where");
$where = $this->tables[$root]->getTableName().".".$this->tables[$root]->getIdentifier()." IN (SELECT ".$fk->getLocal()." FROM ".$asf->getTableName()." WHERE ".$fk->getForeign()." IN (".$graph->getQuery()."))";
break;
endswitch;
} else
$this->load($reference, false);
} else
$this->load($reference, false);
$component = $table->getComponentName();
$where = $this->tableAliases[$component].".".$field." ".$operator." ".$value;
}
return $where;
}
@ -961,13 +935,18 @@ class Doctrine_Query extends Doctrine_Access {
$index += strlen($e[($key - 1)]) + 1;
// the mark here is either '.' or ':'
$mark = substr($path,($index - 1),1);
$parent = $table->getComponentName();
if(isset($this->tableAliases[$parent])) {
$tname = $this->tableAliases[$parent];
} else
$tname = $table->getTableName();
$fk = $table->getForeignKey($name);
$name = $fk->getTable()->getComponentName();
$tname = $table->getTableName();
$name = $fk->getTable()->getComponentName();
$tname2 = $fk->getTable()->getTableName();
$this->connectors[$name] = $fk;
@ -1044,6 +1023,7 @@ class Doctrine_Query extends Doctrine_Access {
throw new DQLException($e->__toString());
}
}
return $table;
}
}

View File

@ -495,9 +495,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
// check if the property is null (= it is the Doctrine_Null object located in self::$null)
if($this->data[$name] === self::$null) {
// no use trying to load the data from database if the Doctrine_Record is not a proxy
// only load the data from database if the Doctrine_Record is in proxy state
if($this->state == Doctrine_Record::STATE_PROXY) {
if( ! empty($this->collections)) {
// delegate the loading operation to collections in which this record resides
foreach($this->collections as $collection) {
$collection->load($this);
}
@ -525,6 +526,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
}
/**
* internalSet
*
* @param mixed $name
* @param mixed $value
*/
final public function internalSet($name, $value) {
$this->data[$name] = $value;

View File

@ -454,8 +454,9 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
}
/**
* commits the current transaction
* if lockmode is optimistic this method starts a transaction
* if lockmode is optimistic this method starts a transaction
* and commits it instantly
*
* @return void
*/
public function commit() {
@ -489,12 +490,14 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
}
}
$this->dbh->commit();
} catch(PDOException $e) {
$this->rollback();
throw new Doctrine_Exception($e->getMessage());
}
$this->dbh->commit();
$this->getAttribute(Doctrine::ATTR_LISTENER)->onTransactionCommit($this);
$this->delete = array();

View File

@ -17,6 +17,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
public function testManyToManyFetchingWithColumnAggregationInheritance() {
$query = new Doctrine_Query($this->session);
$query->from('User-l:Group-l');
$users = $query->execute();
@ -24,6 +25,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($users[0]->Group->count(), 1);
$query->from('User-l.Group-l');
$users = $query->execute();
$this->assertEqual($users->count(), 8);
$this->assertEqual($users[0]->Group->count(), 0);
@ -44,6 +46,32 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($users[2]->type, 0);
$this->session->flush();
$users = $query->query("FROM User-b WHERE User.Group.name = 'Action Actors'");
$this->assertEqual(trim($query->getQuery()),
"SELECT entity.id AS User__id FROM entity LEFT JOIN groupuser ON entity.id = groupuser.user_id LEFT JOIN entity AS entity2 ON entity2.id = groupuser.group_id WHERE (entity2.name = 'Action Actors') AND (entity.type = 0 || entity2.type = 1)");
$this->assertTrue($users instanceof Doctrine_Collection);
$this->assertEqual($users->count(),1);
$this->assertEqual(count($this->dbh->query($query->getQuery())->fetchAll()),1);
$users = $query->query("FROM User-b WHERE User.Group.Phonenumber.phonenumber LIKE '123 123'");
$this->assertEqual(trim($query->getQuery()),
"SELECT entity.id AS User__id FROM entity LEFT JOIN groupuser ON entity.id = groupuser.user_id LEFT JOIN entity AS entity2 ON entity2.id = groupuser.group_id LEFT JOIN phonenumber ON entity2.id = phonenumber.entity_id WHERE (phonenumber.phonenumber LIKE '123 123') AND (entity.type = 0 || entity2.type = 1)");
$this->assertTrue($users instanceof Doctrine_Collection);
$this->assertEqual($users->count(),1);
$users = $query->query("FROM User.Group WHERE User.Group.name = 'Action Actors'");
$this->assertEqual($users->count(), 1);
$count = $this->dbh->count();
$this->assertTrue($users instanceof Doctrine_Collection);
$this->assertEqual(get_class($users[0]), 'User');
$this->assertEqual($users[0]->Group->count(), 1);
$this->assertEqual($count, $this->dbh->count());
$this->assertEqual($users[0]->Group[0]->name, 'Action Actors');
$this->assertEqual($count, $this->dbh->count());
}
@ -59,7 +87,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$task->name = "T2";
$task->ResourceAlias[0]->name = "R3";
$task->ResourceAlias[0]->Type[0]->type = 'TY2';
$task->ResourceAlias[0]->Type[0]->type = 'TY3';
$task->ResourceAlias[0]->Type[1]->type = 'TY3';
$task->ResourceAlias[1]->name = "R4";
$task->ResourceAlias[2]->name = "R5";
$task->ResourceAlias[2]->Type[0]->type = 'TY4';
@ -97,6 +125,16 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($tasks[0]->ResourceAlias[1]->Type->count(), 0);
$this->assertEqual($tasks[1]->ResourceAlias->count(), 4);
$this->session->clear();
$query->from("Task")->where("Task.ResourceAlias.Type.type = 'TY2' || Task.ResourceAlias.Type.type = 'TY1'");
$tasks = $query->execute();
$this->assertEqual($tasks->count(),2);
$this->assertEqual(count($this->dbh->query($query->getQuery())->fetchAll(PDO::FETCH_ASSOC)),2);
$this->assertEqual($tasks[0]->name, 'T1');
$this->assertEqual($tasks[1]->name, 'T2');
}
@ -889,18 +927,6 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
"SELECT entity.id AS User__id FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE (phonenumber.phonenumber REGEXP '[123]') AND (entity.type = 0)");
$this->assertEqual($users->count(),8);
$users = $query->query("FROM User-b WHERE User.Group.name = 'Action Actors'");
$this->assertEqual(trim($query->getQuery()),
"SELECT entity.id AS User__id FROM entity WHERE (entity.id IN (SELECT user_id FROM groupuser WHERE group_id IN (SELECT entity.id AS Group__id FROM entity WHERE (entity.name = 'Action Actors') AND (entity.type = 1)))) AND (entity.type = 0)");
$this->assertTrue($users instanceof Doctrine_Collection);
$this->assertEqual($users->count(),1);
$users = $query->query("FROM User-b WHERE User.Group.Phonenumber.phonenumber LIKE '123 123'");
$this->assertEqual(trim($query->getQuery()),
"SELECT entity.id AS User__id FROM entity WHERE (entity.id IN (SELECT user_id FROM groupuser WHERE group_id IN (SELECT entity.id AS Group__id FROM entity, phonenumber WHERE (phonenumber.phonenumber LIKE '123 123') AND (entity.type = 1)))) AND (entity.type = 0)");
$this->assertTrue($users instanceof Doctrine_Collection);
$this->assertEqual($users->count(),1);
//$values = $query->query("SELECT COUNT(User.name) AS users, MAX(User.name) AS max FROM User");
//$this->assertEqual(trim($query->getQuery()),"SELECT COUNT(entity.name) AS users, MAX(entity.name) AS max FROM entity WHERE (entity.type = 0)");