Commit e15cfd70 authored by doctrine's avatar doctrine

DQL: Lazy property fetching

parent cf5b0ef9
......@@ -116,22 +116,26 @@ class Doctrine_Query extends Doctrine_Access {
* @access private
* @param object Doctrine_Table $table a Doctrine_Table object
* @param integer $fetchmode fetchmode the table is using eg. Doctrine::FETCH_LAZY
* @param array $names fields to be loaded (only used in lazy property loading)
* @return void
*/
private function loadFields(Doctrine_Table $table,$fetchmode) {
private function loadFields(Doctrine_Table $table, $fetchmode, array $names) {
$name = $table->getComponentName();
switch($fetchmode):
case Doctrine::FETCH_OFFSET:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT);
case Doctrine::FETCH_IMMEDIATE:
if( ! empty($names))
throw new Doctrine_Exception("Lazy property loading can only be used with fetching strategies lazy, batch and lazyoffset.");
$names = $table->getColumnNames();
break;
case Doctrine::FETCH_LAZY_OFFSET:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT);
case Doctrine::FETCH_LAZY:
case Doctrine::FETCH_BATCH:
$names = $table->getPrimaryKeys();
$names = array_merge($table->getPrimaryKeys(), $names);
break;
default:
throw new Doctrine_Exception("Unknown fetchmode.");
......@@ -879,9 +883,9 @@ class Doctrine_Query extends Doctrine_Access {
$e = preg_split("/[.:]/",$path);
$index = 0;
foreach($e as $key => $name) {
foreach($e as $key => $fullname) {
try {
$e2 = explode("-",$name);
$e2 = preg_split("/[-(]/",$fullname);
$name = $e2[0];
if($key == 0) {
......@@ -943,15 +947,28 @@ class Doctrine_Query extends Doctrine_Access {
}
if( ! isset($this->tables[$name])) {
$this->tables[$name] = $table;
$this->tables[$name] = $table;
if($loadFields && ! $this->aggregate) {
if(isset($e2[1])) {
$fetchmode = $this->parseFetchMode($e2[1]);
} else
$fields = array();
if(strpos($fullname, "-") === false) {
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE);
$this->loadFields($table, $fetchmode);
if(isset($e2[1]))
$fields = explode(",",substr($e2[1],0,-1));
} else {
if(isset($e2[1])) {
$fetchmode = $this->parseFetchMode($e2[1]);
} else
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE);
if(isset($e2[2]))
$fields = explode(",",substr($e2[2],0,-1));
}
$this->loadFields($table, $fetchmode, $fields);
}
}
......
......@@ -125,6 +125,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
// get the data array
$this->data = $this->table->getData();
// get the column count
$count = count($this->data);
// clean data array
$cols = $this->cleanData();
......@@ -143,8 +146,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
} else {
$this->state = Doctrine_Record::STATE_CLEAN;
if($cols <= 1)
if($count < $this->table->getColumnCount()) {
$this->state = Doctrine_Record::STATE_PROXY;
}
// listen the onLoad event
......
......@@ -780,6 +780,12 @@ class Doctrine_Table extends Doctrine_Configurable {
}
return $coll;
}
/**
* @return integer
*/
final public function getColumnCount() {
return count($this->columns);
}
/**
* returns all columns and their definitions
*
......
......@@ -7,7 +7,7 @@ class Doctrine_Validator_Notnull {
* @return boolean
*/
public function validate(Doctrine_Record $record, $key, $value) {
if ($value === null)
if ($value === null || $value === '')
return false;
return true;
......
......@@ -7,6 +7,48 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$this->tables[] = "Forum_Thread";
parent::prepareTables();
}
public function testNotValidLazyPropertyFetching() {
$q = new Doctrine_Query($this->session);
$f = false;
try {
$q->from("User(name)");
} catch(Doctrine_Exception $e) {
$f = true;
}
$this->assertTrue($f);
}
public function testValidLazyPropertyFetching() {
$q = new Doctrine_Query($this->session);
$q->from("User-l(name)");
$users = $q->execute();
$this->assertEqual($users->count(), 8);
$this->assertTrue($users instanceof Doctrine_Collection_Lazy);
$count = count($this->dbh);
$this->assertTrue(is_string($users[0]->name));
$this->assertEqual($count, count($this->dbh));
$count = count($this->dbh);
$this->assertTrue(is_numeric($users[0]->email_id));
$this->assertEqual($count + 1, count($this->dbh));
$users[0]->getTable()->clear();
$q->from("User-b(name)");
$users = $q->execute();
$this->assertEqual($users->count(), 8);
$this->assertTrue($users instanceof Doctrine_Collection_Batch);
$count = count($this->dbh);
$this->assertTrue(is_string($users[0]->name));
$this->assertEqual($count, count($this->dbh));
$count = count($this->dbh);
$this->assertTrue(is_numeric($users[0]->email_id));
$this->assertEqual($count + 1, count($this->dbh));
$this->assertTrue(is_numeric($users[1]->email_id));
$this->assertEqual($count + 1, count($this->dbh));
$this->assertTrue(is_numeric($users[2]->email_id));
$this->assertEqual($count + 1, count($this->dbh));
}
public function testQueryWithComplexAliases() {
$q = new Doctrine_Query($this->session);
......@@ -353,13 +395,13 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
"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)");
$this->assertTrue(is_array($values));
$this->assertTrue(isset($values['users']));
$this->assertTrue(isset($values['max']));
*/
//$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)");
//$this->assertTrue(is_array($values));
//$this->assertTrue(isset($values['users']));
//$this->assertTrue(isset($values['max']));
}
}
?>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment