Commit e15cfd70 authored by doctrine's avatar doctrine

DQL: Lazy property fetching

parent cf5b0ef9
...@@ -116,22 +116,26 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -116,22 +116,26 @@ class Doctrine_Query extends Doctrine_Access {
* @access private * @access private
* @param object Doctrine_Table $table a Doctrine_Table object * @param object Doctrine_Table $table a Doctrine_Table object
* @param integer $fetchmode fetchmode the table is using eg. Doctrine::FETCH_LAZY * @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 * @return void
*/ */
private function loadFields(Doctrine_Table $table,$fetchmode) { private function loadFields(Doctrine_Table $table, $fetchmode, array $names) {
$name = $table->getComponentName(); $name = $table->getComponentName();
switch($fetchmode): switch($fetchmode):
case Doctrine::FETCH_OFFSET: case Doctrine::FETCH_OFFSET:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT); $this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT);
case Doctrine::FETCH_IMMEDIATE: 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(); $names = $table->getColumnNames();
break; break;
case Doctrine::FETCH_LAZY_OFFSET: case Doctrine::FETCH_LAZY_OFFSET:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT); $this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT);
case Doctrine::FETCH_LAZY: case Doctrine::FETCH_LAZY:
case Doctrine::FETCH_BATCH: case Doctrine::FETCH_BATCH:
$names = $table->getPrimaryKeys(); $names = array_merge($table->getPrimaryKeys(), $names);
break; break;
default: default:
throw new Doctrine_Exception("Unknown fetchmode."); throw new Doctrine_Exception("Unknown fetchmode.");
...@@ -879,9 +883,9 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -879,9 +883,9 @@ class Doctrine_Query extends Doctrine_Access {
$e = preg_split("/[.:]/",$path); $e = preg_split("/[.:]/",$path);
$index = 0; $index = 0;
foreach($e as $key => $name) { foreach($e as $key => $fullname) {
try { try {
$e2 = explode("-",$name); $e2 = preg_split("/[-(]/",$fullname);
$name = $e2[0]; $name = $e2[0];
if($key == 0) { if($key == 0) {
...@@ -943,15 +947,28 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -943,15 +947,28 @@ class Doctrine_Query extends Doctrine_Access {
} }
if( ! isset($this->tables[$name])) { if( ! isset($this->tables[$name])) {
$this->tables[$name] = $table;
$this->tables[$name] = $table;
if($loadFields && ! $this->aggregate) { if($loadFields && ! $this->aggregate) {
if(isset($e2[1])) { $fields = array();
$fetchmode = $this->parseFetchMode($e2[1]);
} else if(strpos($fullname, "-") === false) {
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE); $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 ...@@ -125,6 +125,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
// get the data array // get the data array
$this->data = $this->table->getData(); $this->data = $this->table->getData();
// get the column count
$count = count($this->data);
// clean data array // clean data array
$cols = $this->cleanData(); $cols = $this->cleanData();
...@@ -143,8 +146,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -143,8 +146,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
} else { } else {
$this->state = Doctrine_Record::STATE_CLEAN; $this->state = Doctrine_Record::STATE_CLEAN;
if($cols <= 1) if($count < $this->table->getColumnCount()) {
$this->state = Doctrine_Record::STATE_PROXY; $this->state = Doctrine_Record::STATE_PROXY;
}
// listen the onLoad event // listen the onLoad event
......
...@@ -780,6 +780,12 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -780,6 +780,12 @@ class Doctrine_Table extends Doctrine_Configurable {
} }
return $coll; return $coll;
} }
/**
* @return integer
*/
final public function getColumnCount() {
return count($this->columns);
}
/** /**
* returns all columns and their definitions * returns all columns and their definitions
* *
......
...@@ -7,7 +7,7 @@ class Doctrine_Validator_Notnull { ...@@ -7,7 +7,7 @@ class Doctrine_Validator_Notnull {
* @return boolean * @return boolean
*/ */
public function validate(Doctrine_Record $record, $key, $value) { public function validate(Doctrine_Record $record, $key, $value) {
if ($value === null) if ($value === null || $value === '')
return false; return false;
return true; return true;
......
...@@ -7,6 +7,48 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -7,6 +7,48 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$this->tables[] = "Forum_Thread"; $this->tables[] = "Forum_Thread";
parent::prepareTables(); 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() { public function testQueryWithComplexAliases() {
$q = new Doctrine_Query($this->session); $q = new Doctrine_Query($this->session);
...@@ -353,13 +395,13 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -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)"); "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->assertTrue($users instanceof Doctrine_Collection);
$this->assertEqual($users->count(),1); $this->assertEqual($users->count(),1);
/**
$values = $query->query("SELECT COUNT(User.name) AS users, MAX(User.name) AS max FROM User"); //$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->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(is_array($values));
$this->assertTrue(isset($values['users'])); //$this->assertTrue(isset($values['users']));
$this->assertTrue(isset($values['max'])); //$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