Commit 16497adb authored by doctrine's avatar doctrine

--no commit message

--no commit message
parent 61790d31
...@@ -30,9 +30,13 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -30,9 +30,13 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
protected $relation; protected $relation;
/** /**
* @var boolean $expanded whether or not this collection has been expanded * @var boolean $expandable whether or not this collection has been expanded
*/ */
protected $expanded = false; protected $expandable = true;
/**
* @var array $expanded
*/
protected $expanded = array();
/** /**
* @var mixed $generator * @var mixed $generator
*/ */
...@@ -55,6 +59,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -55,6 +59,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
public function getTable() { public function getTable() {
return $this->table; return $this->table;
} }
public function isExpanded($offset) {
return isset($this->expanded[$offset]);
}
public function isExpandable() {
return $this->expandable;
}
/** /**
* @param Doctrine_IndexGenerator $generator * @param Doctrine_IndexGenerator $generator
* @return void * @return void
...@@ -99,7 +109,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -99,7 +109,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$value = $record->get($relation->getLocal()); $value = $record->get($relation->getLocal());
foreach($this as $record) { foreach($this->getNormalIterator() as $record) {
if($value !== null) { if($value !== null) {
$record->set($this->reference_field, $value); $record->set($this->reference_field, $value);
} else { } else {
...@@ -117,7 +127,26 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -117,7 +127,26 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
/** /**
* @return boolean * @return boolean
*/ */
public function expand($i = null) { public function expand($key) {
$where = array();
$params = array();
$limit = null;
$offset = null;
switch(get_class($this)):
case "Doctrine_Collection_Offset":
$limit = $this->getLimit();
$offset = (floor($key / $limit) * $limit);
if( ! $this->expandable && isset($this->expanded[$offset]))
return false;
$fields = implode(", ",$this->table->getColumnNames());
break;
default:
if( ! $this->expandable)
return false;
if( ! isset($this->reference)) if( ! isset($this->reference))
return false; return false;
...@@ -126,36 +155,33 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -126,36 +155,33 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
if(empty($id)) if(empty($id))
return false; return false;
foreach($this->data as $v) { switch(get_class($this)):
switch(gettype($v)): case "Doctrine_Collection_Immediate":
case "array": $fields = implode(", ",$this->table->getColumnNames());
$ids[] = $v['id'];
break;
case "object":
$id = $v->getID();
if( ! empty($id))
$ids[] = $id;
break; break;
default:
$fields = implode(", ",$this->table->getPrimaryKeys());
endswitch; endswitch;
}
if($this instanceof Doctrine_Collection_Immediate) {
$fields = implode(", ",$this->table->getColumnNames());
} else {
$fields = implode(", ",$this->table->getPrimaryKeys());
}
endswitch;
if(isset($this->relation)) {
if($this->relation instanceof Doctrine_ForeignKey) { if($this->relation instanceof Doctrine_ForeignKey) {
$str = "";
$params = array($this->reference->getID()); $params = array($this->reference->getID());
$where[] = $this->reference_field." = ?";
if( ! isset($offset)) {
$ids = $this->getPrimaryKeys();
if( ! empty($ids)) { if( ! empty($ids)) {
$str = " && id NOT IN (".substr(str_repeat("?, ",count($ids)),0,-2).")"; $where[] = "id NOT IN (".substr(str_repeat("?, ",count($ids)),0,-2).")";
$params = array_merge($params,$ids); $params = array_merge($params,$ids);
} }
$str = " WHERE ".$this->reference_field." = ?".$str;
$query = "SELECT ".$fields." FROM ".$this->table->getTableName().$str; $this->expandable = false;
$coll = $this->table->execute($query,$params); }
} elseif($this->relation instanceof Doctrine_Association) { } elseif($this->relation instanceof Doctrine_Association) {
...@@ -166,18 +192,56 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -166,18 +192,56 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$graph = new Doctrine_DQL_Parser($table->getSession()); $graph = new Doctrine_DQL_Parser($table->getSession());
$q = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".id IN ($query)"; $q = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".id IN ($query)";
}
}
$query = "SELECT ".$fields." FROM ".$this->table->getTableName();
// apply column aggregation inheritance
foreach($this->table->getInheritanceMap() as $k => $v) {
$where[] = $k." = ?";
$params[] = $v;
} }
if( ! empty($where)) {
$query .= " WHERE ".implode(" AND ",$where);
}
$params = array_merge($params, array_values($this->table->getInheritanceMap()));
$coll = $this->table->execute($query, $params, $limit, $offset);
if( ! isset($offset)) {
foreach($coll as $record) { foreach($coll as $record) {
if(isset($this->reference_field)) if(isset($this->reference_field))
$record->rawSet($this->reference_field, $this->reference); $record->rawSet($this->reference_field,$this->reference);
$this->reference->addReference($record); $this->reference->addReference($record);
} }
} else {
$i = $offset;
return true; foreach($coll as $record) {
if(isset($this->reference)) {
$this->reference->addReference($record,$i);
} else
$this->data[$i] = $record;
$i++;
} }
$this->expanded[$offset] = true;
// check if the fetched collection's record count is smaller
// than the query limit, if so this collection has been expanded to its max size
if(count($coll) < $limit) {
$this->expandable = false;
}
}
return $coll;
}
/** /**
* @return boolean * @return boolean
*/ */
...@@ -199,11 +263,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -199,11 +263,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
/** /**
* @param mixed $key * @param mixed $key
* @return object Doctrine_Record return a specified dao * @return object Doctrine_Record return a specified record
*/ */
public function get($key) { public function get($key) {
if( ! isset($this->data[$key])) { if( ! isset($this->data[$key])) {
$this->expand(); $this->expand($key);
if( ! isset($this->data[$key])) if( ! isset($this->data[$key]))
$this->data[$key] = $this->table->create(); $this->data[$key] = $this->table->create();
...@@ -227,8 +291,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -227,8 +291,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
public function getPrimaryKeys() { public function getPrimaryKeys() {
$list = array(); $list = array();
foreach($this->data[$key] as $record): foreach($this->data as $record):
if(is_array($record) && isset($record['id'])) {
$list[] = $record['id'];
} else {
$list[] = $record->getID(); $list[] = $record->getID();
}
endforeach; endforeach;
return $list; return $list;
} }
...@@ -275,6 +343,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -275,6 +343,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
return false; return false;
$this->data[$key] = $record; $this->data[$key] = $record;
return true;
} }
if(isset($this->generator)) { if(isset($this->generator)) {
...@@ -282,8 +351,45 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator ...@@ -282,8 +351,45 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$this->data[$key] = $record; $this->data[$key] = $record;
} else } else
$this->data[] = $record; $this->data[] = $record;
return true; return true;
} }
/**
* @param Doctrine_DQL_Parser $graph
* @param integer $key
*/
public function populate(Doctrine_DQL_Parser $graph) {
$name = $this->table->getComponentName();
if($this instanceof Doctrine_Collection_Immediate ||
$this instanceof Doctrine_Collection_Offset) {
$data = $graph->getData($name);
if(is_array($data)) {
foreach($data as $k=>$v):
$this->table->setData($v);
$this->add($this->table->getRecord());
endforeach;
}
} elseif($this instanceof Doctrine_Collection_Batch) {
$this->data = $graph->getData($name);
if(isset($this->generator)) {
foreach($this->data as $k => $v) {
$record = $this->get($k);
$i = $this->generator->getIndex($record);
$this->data[$i] = $record;
unset($this->data[$k]);
}
}
}
}
/**
* @return Doctrine_Iterator_Normal
*/
public function getNormalIterator() {
return new Doctrine_Iterator_Normal($this);
}
/** /**
* save * save
* saves all records * saves all records
......
<?php <?php
require_once(Doctrine::getPath().DIRECTORY_SEPARATOR."Collection.class.php"); require_once(Doctrine::getPath().DIRECTORY_SEPARATOR."Collection.class.php");
/** /**
* Doctrine_Collection_Batch a collection of data access objects, * Doctrine_Collection_Batch a collection of records,
* with batch load strategy * with batch load strategy
* *
* *
...@@ -21,21 +21,8 @@ class Doctrine_Collection_Batch extends Doctrine_Collection { ...@@ -21,21 +21,8 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
*/ */
private $loaded = array(); private $loaded = array();
public function __construct(Doctrine_DQL_Parser $graph,$key) { public function __construct(Doctrine_Table $table) {
parent::__construct($graph->getTable($key)); parent::__construct($table);
$this->data = $graph->getData($key);
if( ! is_array($this->data))
$this->data = array();
if(isset($this->generator)) {
foreach($this->data as $k => $v) {
$record = $this->get($k);
$i = $this->generator->getIndex($record);
$this->data[$i] = $record;
unset($this->data[$k]);
}
}
$this->batchSize = $this->getTable()->getAttribute(Doctrine::ATTR_BATCH_SIZE); $this->batchSize = $this->getTable()->getAttribute(Doctrine::ATTR_BATCH_SIZE);
} }
...@@ -146,7 +133,7 @@ class Doctrine_Collection_Batch extends Doctrine_Collection { ...@@ -146,7 +133,7 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
endswitch; endswitch;
} else { } else {
$this->expand(); $this->expand($key);
if( ! isset($this->data[$key])) if( ! isset($this->data[$key]))
$this->data[$key] = $this->table->create(); $this->data[$key] = $this->table->create();
...@@ -161,10 +148,10 @@ class Doctrine_Collection_Batch extends Doctrine_Collection { ...@@ -161,10 +148,10 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
return $this->data[$key]; return $this->data[$key];
} }
/** /**
* @return Doctrine_BatchIterator * @return Doctrine_Iterator
*/ */
public function getIterator() { public function getIterator() {
return new Doctrine_BatchIterator($this); return new Doctrine_Iterator_Expandable($this);
} }
} }
?> ?>
...@@ -12,19 +12,8 @@ class Doctrine_Collection_Immediate extends Doctrine_Collection { ...@@ -12,19 +12,8 @@ class Doctrine_Collection_Immediate extends Doctrine_Collection {
* @param Doctrine_DQL_Parser $graph * @param Doctrine_DQL_Parser $graph
* @param integer $key * @param integer $key
*/ */
public function __construct(Doctrine_DQL_Parser $graph,$key) { public function __construct(Doctrine_Table $table) {
$table = $graph->getTable($key);
parent::__construct($table); parent::__construct($table);
$name = $table->getComponentName();
$data = $graph->getData($name);
if(is_array($data)) {
foreach($data as $k=>$v):
$table->setData($v);
$this->add($this->table->getRecord());
endforeach;
}
} }
} }
?> ?>
...@@ -10,9 +10,9 @@ class Doctrine_Collection_Lazy extends Doctrine_Collection_Batch { ...@@ -10,9 +10,9 @@ class Doctrine_Collection_Lazy extends Doctrine_Collection_Batch {
* @param Doctrine_DQL_Parser $graph * @param Doctrine_DQL_Parser $graph
* @param string $key * @param string $key
*/ */
public function __construct(Doctrine_DQL_Parser $graph,$key) { public function __construct(Doctrine_Table $table) {
parent::__construct($table);
parent::setBatchSize(1); parent::setBatchSize(1);
parent::__construct($graph,$key);
} }
} }
?> ?>
<?php
require_once(Doctrine::getPath().DIRECTORY_SEPARATOR."Collection.class.php");
/**
* Offset Collection
*/
class Doctrine_Collection_Offset extends Doctrine_Collection {
/**
* @var integer $limit
*/
private $limit;
/**
* @param Doctrine_Table $table
*/
public function __construct(Doctrine_Table $table) {
parent::__construct($table);
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT);
}
/**
* @return integer
*/
public function getLimit() {
return $this->limit;
}
/**
* @return Doctrine_Iterator_Offset
*/
public function getIterator() {
return new Doctrine_Iterator_Expandable($this);
}
}
?>
...@@ -56,7 +56,7 @@ abstract class Doctrine_Configurable { ...@@ -56,7 +56,7 @@ abstract class Doctrine_Configurable {
break; break;
case Doctrine::ATTR_FETCHMODE: case Doctrine::ATTR_FETCHMODE:
if($value < 0) if($value < 0)
throw new Doctrine_Exception("Unknown fetchmode. Fetchmode should be an integer between 0 and 2. See Doctrine::FETCH_* constants."); throw new Doctrine_Exception("Unknown fetchmode. See Doctrine::FETCH_* constants.");
break; break;
case Doctrine::ATTR_LISTENER: case Doctrine::ATTR_LISTENER:
$this->setEventListener($value); $this->setEventListener($value);
...@@ -87,6 +87,11 @@ abstract class Doctrine_Configurable { ...@@ -87,6 +87,11 @@ abstract class Doctrine_Configurable {
case Doctrine::ATTR_CREATE_TABLES: case Doctrine::ATTR_CREATE_TABLES:
$value = (bool) $value; $value = (bool) $value;
break; break;
case Doctrine::ATTR_COLL_LIMIT:
if($value < 1) {
throw new Doctrine_Exception("Collection limit should be a value greater than or equal to 1.");
}
break;
case Doctrine::ATTR_COLL_KEY: case Doctrine::ATTR_COLL_KEY:
if( ! ($this instanceof Doctrine_Table)) if( ! ($this instanceof Doctrine_Table))
throw new Doctrine_Exception("This attribute can only be set at table level."); throw new Doctrine_Exception("This attribute can only be set at table level.");
...@@ -124,7 +129,7 @@ abstract class Doctrine_Configurable { ...@@ -124,7 +129,7 @@ abstract class Doctrine_Configurable {
final public function getAttribute($attribute) { final public function getAttribute($attribute) {
$attribute = (int) $attribute; $attribute = (int) $attribute;
if($attribute < 1 || $attribute > 15) if($attribute < 1 || $attribute > 16)
throw new InvalidKeyException(); throw new InvalidKeyException();
if( ! isset($this->attributes[$attribute])) { if( ! isset($this->attributes[$attribute])) {
......
...@@ -26,6 +26,10 @@ class Doctrine_DQL_Parser { ...@@ -26,6 +26,10 @@ class Doctrine_DQL_Parser {
* @var array $tablenames an array containing all the tables used in the query * @var array $tablenames an array containing all the tables used in the query
*/ */
private $tablenames = array(); private $tablenames = array();
/**
* @var array $collections an array containing all collections this parser has created/will create
*/
private $collections = array();
/** /**
* @var array $from query FROM parts * @var array $from query FROM parts
*/ */
...@@ -91,6 +95,9 @@ class Doctrine_DQL_Parser { ...@@ -91,6 +95,9 @@ class Doctrine_DQL_Parser {
$this->aggregate = false; $this->aggregate = false;
$this->data = array(); $this->data = array();
$this->connectors = array(); $this->connectors = array();
$this->collections = array();
$this->paths = array();
$this->joined = array();
} }
/** /**
* loadFields -- this method loads fields for a given factory and * loadFields -- this method loads fields for a given factory and
...@@ -104,16 +111,22 @@ class Doctrine_DQL_Parser { ...@@ -104,16 +111,22 @@ class Doctrine_DQL_Parser {
* @return void * @return void
*/ */
private function loadFields(Doctrine_Table $table,$fetchmode) { private function loadFields(Doctrine_Table $table,$fetchmode) {
$name = $table->getComponentName();
switch($fetchmode): switch($fetchmode):
case Doctrine::FETCH_OFFSET:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT);
case Doctrine::FETCH_IMMEDIATE: case Doctrine::FETCH_IMMEDIATE:
$names = $table->getColumnNames(); $names = $table->getColumnNames();
break; break;
case Doctrine::FETCH_LAZY_OFFSET:
$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 = $table->getPrimaryKeys();
break; break;
default: default:
throw new InvalidFetchModeException(); throw new Doctrine_Exception("Unknown fetchmode.");
endswitch; endswitch;
$cname = $table->getComponentName(); $cname = $table->getComponentName();
$this->fetchModes[$cname] = $fetchmode; $this->fetchModes[$cname] = $fetchmode;
...@@ -276,7 +289,7 @@ class Doctrine_DQL_Parser { ...@@ -276,7 +289,7 @@ class Doctrine_DQL_Parser {
* @return array the data row for the specified factory * @return array the data row for the specified factory
*/ */
final public function getData($key) { final public function getData($key) {
if(isset($this->data[$key])) if(isset($this->data[$key]) && is_array($this->data[$key]))
return $this->data[$key]; return $this->data[$key];
return array(); return array();
...@@ -406,20 +419,26 @@ class Doctrine_DQL_Parser { ...@@ -406,20 +419,26 @@ class Doctrine_DQL_Parser {
* @param integer $index * @param integer $index
*/ */
private function getCollection($name) { private function getCollection($name) {
$table = $this->session->getTable($name);
switch($this->fetchModes[$name]): switch($this->fetchModes[$name]):
case 0: case Doctrine::FETCH_BATCH:
$coll = new Doctrine_Collection_Immediate($this,$name); $coll = new Doctrine_Collection_Batch($table);
break; break;
case 1: case Doctrine::FETCH_LAZY:
$coll = new Doctrine_Collection_Batch($this,$name); $coll = new Doctrine_Collection_Lazy($table);
break; break;
case 2: case Doctrine::FETCH_OFFSET:
$coll = new Doctrine_Collection_Lazy($this,$name); $coll = new Doctrine_Collection_Offset($table);
break;
case Doctrine::FETCH_IMMEDIATE:
$coll = new Doctrine_Collection_Immediate($table);
break;
case Doctrine::FETCH_LAZY_OFFSET:
$coll = new Doctrine_Collection_LazyOffset($table);
break; break;
default:
throw new Exception("Unknown fetchmode");
endswitch; endswitch;
$coll->populate($this);
return $coll; return $coll;
} }
/** /**
...@@ -555,6 +574,13 @@ class Doctrine_DQL_Parser { ...@@ -555,6 +574,13 @@ class Doctrine_DQL_Parser {
case "lazy": case "lazy":
$fetchmode = Doctrine::FETCH_LAZY; $fetchmode = Doctrine::FETCH_LAZY;
break; break;
case "o":
case "offset":
$fetchmode = Doctrine::FETCH_OFFSET;
break;
case "lo":
case "lazyoffset":
$fetchmode = Doctrine::FETCH_LAZYOFFSET;
default: default:
throw new DQLException("Unknown fetchmode '$e[1]'. The availible fetchmodes are 'i', 'b' and 'l'."); throw new DQLException("Unknown fetchmode '$e[1]'. The availible fetchmodes are 'i', 'b' and 'l'.");
endswitch; endswitch;
......
...@@ -120,6 +120,10 @@ final class Doctrine { ...@@ -120,6 +120,10 @@ final class Doctrine {
* collection key attribute * collection key attribute
*/ */
const ATTR_COLL_KEY = 15; const ATTR_COLL_KEY = 15;
/**
* collection limit attribute
*/
const ATTR_COLL_LIMIT = 16;
...@@ -157,7 +161,16 @@ final class Doctrine { ...@@ -157,7 +161,16 @@ final class Doctrine {
* mode for lazy fetching * mode for lazy fetching
*/ */
const FETCH_LAZY = 2; const FETCH_LAZY = 2;
/**
* LAZY FETCHING
* mode for offset fetching
*/
const FETCH_OFFSET = 3;
/**
* LAZY OFFSET FETCHING
* mode for lazy offset fetching
*/
const FETCH_LAZY_OFFSET = 4;
/** /**
* LOCKMODE CONSTANTS * LOCKMODE CONSTANTS
*/ */
......
<?php
/**
* Doctrine_Iterator
* iterates through Doctrine_Collection
*/
abstract class Doctrine_Iterator implements Iterator {
/**
* @var Doctrine_Collection $collection
*/
protected $collection;
/**
* @var array $keys
*/
protected $keys;
/**
* @var mixed $key
*/
protected $key;
/**
* @var integer $index
*/
protected $index;
/**
* @var integer $count
*/
protected $count;
/**
* constructor
* @var Doctrine_Collection $collection
*/
public function __construct(Doctrine_Collection $collection) {
$this->collection = $collection;
$this->keys = $this->collection->getKeys();
$this->count = $this->collection->count();
}
/**
* @return void
*/
public function rewind() {
$this->index = 0;
$i = $this->index;
if(isset($this->keys[$i]))
$this->key = $this->keys[$i];
}
/**
* @return integer the current key
*/
public function key() {
return $this->key;
}
/**
* @return Doctrine_Record the current record
*/
public function current() {
return $this->collection->get($this->key);
}
/**
* @return void
*/
public function next() {
$this->index++;
$i = $this->index;
if(isset($this->keys[$i]))
$this->key = $this->keys[$i];
}
}
class Doctrine_Iterator_Normal extends Doctrine_Iterator {
/**
* @return boolean whether or not the iteration will continue
*/
public function valid() {
return ($this->index < $this->count);
}
}
class Doctrine_Iterator_Offset extends Doctrine_Iterator {
public function valid() { }
}
class Doctrine_Iterator_Expandable extends Doctrine_Iterator {
public function valid() {
if($this->index < $this->count)
return true;
elseif($this->index == $this->count) {
$coll = $this->collection->expand($this->index);
if($coll instanceof Doctrine_Collection) {
$count = count($coll);
if($count > 0) {
$this->keys = array_merge($this->keys, $coll->getKeys());
$this->count += $count;
return true;
}
}
return false;
}
}
}
?>
<?php
class Doctrine_Lib {
/**
* @param integer $state the state of record
* @see Doctrine_Record::STATE_* constants
* @return string string representation of given state
*/
public static function getRecordStateAsString($state) {
switch($state):
case Doctrine_Record::STATE_PROXY:
return "proxy";
break;
case Doctrine_Record::STATE_CLEAN:
return "persistent clean";
break;
case Doctrine_Record::STATE_DIRTY:
return "persistent dirty";
break;
case Doctrine_Record::STATE_TDIRTY:
return "transient dirty";
break;
case Doctrine_Record::STATE_TCLEAN:
return "transient clean";
break;
endswitch;
}
/**
* returns a string representation of Doctrine_Record object
* @param Doctrine_Record $record
* @return string
*/
public function getRecordAsString(Doctrine_Record $record) {
$r[] = "<pre>";
$r[] = "Component : ".$record->getTable()->getComponentName();
$r[] = "ID : ".$record->getID();
$r[] = "References : ".count($record->getReferences());
$r[] = "State : ".Doctrine_Lib::getRecordStateAsString($record->getState());
$r[] = "OID : ".$record->getOID();
$r[] = "</pre>";
return implode("\n",$r)."<br />";
}
/**
* getStateAsString
* returns a given session state as string
* @param integer $state session state
*/
public static function getSessionStateAsString($state) {
switch($state):
case Doctrine_Session::STATE_OPEN:
return "open";
break;
case Doctrine_Session::STATE_CLOSED:
return "closed";
break;
case Doctrine_Session::STATE_BUSY:
return "busy";
break;
case Doctrine_Session::STATE_ACTIVE:
return "active";
break;
endswitch;
}
/**
* returns a string representation of Doctrine_Session object
* @param Doctrine_Session $session
* @return string
*/
public function getSessionAsString(Doctrine_Session $session) {
$r[] = "<pre>";
$r[] = "Doctrine_Session object";
$r[] = "State : ".Doctrine_Session::getStateAsString($session->getState());
$r[] = "Open Transactions : ".$session->getTransactionLevel();
$r[] = "Open Factories : ".$session->count();
$sum = 0;
$rsum = 0;
$csum = 0;
foreach($session->getTables() as $objTable) {
if($objTable->getCache() instanceof Doctrine_Cache_File) {
$sum += array_sum($objTable->getCache()->getStats());
$rsum += $objTable->getRepository()->count();
$csum += $objTable->getCache()->count();
}
}
$r[] = "Cache Hits : ".$sum." hits ";
$r[] = "Cache : ".$csum." objects ";
$r[] = "Repositories : ".$rsum." objects ";
$queries = false;
if($session->getDBH() instanceof Doctrine_DB) {
$handler = "Doctrine Database Handler";
$queries = count($session->getDBH()->getQueries());
$sum = array_sum($session->getDBH()->getExecTimes());
} elseif($session->getDBH() instanceof PDO) {
$handler = "PHP Native PDO Driver";
} else
$handler = "Unknown Database Handler";
$r[] = "DB Handler : ".$handler;
if($queries) {
$r[] = "Executed Queries : ".$queries;
$r[] = "Sum of Exec Times : ".$sum;
}
$r[] = "</pre>";
return implode("\n",$r)."<br>";
}
/**
* returns a string representation of Doctrine_Table object
* @param Doctrine_Table $table
* @return string
*/
public function getTableAsString(Doctrine_Table $table) {
$r[] = "<pre>";
$r[] = "Component : ".$this->getComponentName();
$r[] = "Table : ".$this->getTableName();
$r[] = "Repository : ".$this->getRepository()->count()." objects";
if($table->getCache() instanceof Doctrine_Cache_File) {
$r[] = "Cache : ".$this->getCache()->count()." objects";
$r[] = "Cache hits : ".array_sum($this->getCache()->getStats())." hits";
}
$r[] = "</pre>";
return implode("\n",$r)."<br>";
}
/**
* returns a string representation of Doctrine_Collection object
* @param Doctrine_Collection $collection
* @return string
*/
public function getCollectionAsString(Doctrine_Collection $collection) {
$r[] = "<pre>";
$r[] = get_class($collection);
foreach($collection as $key => $record) {
$r[] = "Key : ".$key." ID : ".$record->getID();
}
$r[] = "</pre>";
return implode("\n",$r);
}
}
?>
...@@ -47,6 +47,7 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera ...@@ -47,6 +47,7 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
Doctrine::ATTR_CACHE_SIZE => 100, Doctrine::ATTR_CACHE_SIZE => 100,
Doctrine::ATTR_CACHE => Doctrine::CACHE_NONE, Doctrine::ATTR_CACHE => Doctrine::CACHE_NONE,
Doctrine::ATTR_BATCH_SIZE => 5, Doctrine::ATTR_BATCH_SIZE => 5,
Doctrine::ATTR_COLL_LIMIT => 5,
Doctrine::ATTR_LISTENER => new EmptyEventListener(), Doctrine::ATTR_LISTENER => new EmptyEventListener(),
Doctrine::ATTR_PK_COLUMNS => array("id"), Doctrine::ATTR_PK_COLUMNS => array("id"),
Doctrine::ATTR_PK_TYPE => Doctrine::INCREMENT_KEY, Doctrine::ATTR_PK_TYPE => Doctrine::INCREMENT_KEY,
......
...@@ -777,10 +777,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -777,10 +777,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
/** /**
* addReference * addReference
*/ */
public function addReference(Doctrine_Record $record) { public function addReference(Doctrine_Record $record, $key = null) {
$name = $record->getTable()->getComponentName(); $name = $record->getTable()->getComponentName();
$this->references[$name]->add($record); $this->references[$name]->add($record, $key);
$this->originals[$name]->add($record); $this->originals[$name]->add($record, $key);
} }
/** /**
* getReferences * getReferences
......
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
*/ */
class Doctrine_Session_Common extends Doctrine_Session { class Doctrine_Session_Common extends Doctrine_Session {
public function modifyLimitQuery($query,$limit = null,$offset = null) { public function modifyLimitQuery($query,$limit = null,$offset = null) {
if(isset($limit)) if(isset($limit) && isset($offset)) {
$query .= " LIMIT ".$limit." OFFSET ".$offset;
} elseif(isset($limit) && ! isset($offset)) {
$query .= " LIMIT ".$limit; $query .= " LIMIT ".$limit;
else } elseif( ! isset($limit) && isset($offset)) {
$query .= " LIMIT 99999999999999"; $query .= " LIMIT 999999999999 OFFSET ".$offset;
}
if(isset($offset))
$query .= " OFFSET ".$offset;
return $query; return $query;
} }
......
...@@ -448,7 +448,7 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -448,7 +448,7 @@ class Doctrine_Table extends Doctrine_Configurable {
* @param $array an array where keys are field names and values representing field values * @param $array an array where keys are field names and values representing field values
* @return Doctrine_Record A new Data Access Object. Uses an sql insert statement when saved * @return Doctrine_Record A new Data Access Object. Uses an sql insert statement when saved
*/ */
final public function create(array $array = array()) { public function create(array $array = array()) {
$this->data = $array; $this->data = $array;
$this->isNewEntry = true; $this->isNewEntry = true;
$record = $this->getRecord(); $record = $this->getRecord();
...@@ -460,7 +460,7 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -460,7 +460,7 @@ class Doctrine_Table extends Doctrine_Configurable {
* @throws Doctrine_Find_Exception * @throws Doctrine_Find_Exception
* @return Doctrine_Record a record for given database identifier * @return Doctrine_Record a record for given database identifier
*/ */
final public function find($id = null) { public function find($id = null) {
if($id !== null) { if($id !== null) {
$query = $this->query." WHERE ".implode(" = ? AND ",$this->primaryKeys)." = ?"; $query = $this->query." WHERE ".implode(" = ? AND ",$this->primaryKeys)." = ?";
$query = $this->applyInheritance($query); $query = $this->applyInheritance($query);
...@@ -494,7 +494,7 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -494,7 +494,7 @@ class Doctrine_Table extends Doctrine_Configurable {
* findAll * findAll
* @return Doctrine_Collection a collection of all data access objects * @return Doctrine_Collection a collection of all data access objects
*/ */
final public function findAll() { public function findAll() {
$graph = new Doctrine_DQL_Parser($this->session); $graph = new Doctrine_DQL_Parser($this->session);
$users = $graph->query("FROM ".$this->name); $users = $graph->query("FROM ".$this->name);
return $users; return $users;
...@@ -503,7 +503,7 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -503,7 +503,7 @@ class Doctrine_Table extends Doctrine_Configurable {
* findBySql * findBySql
* @return Doctrine_Collection a collection of data access objects * @return Doctrine_Collection a collection of data access objects
*/ */
final public function findBySql($sql) { public function findBySql($sql) {
$graph = new Doctrine_DQL_Parser($this->session); $graph = new Doctrine_DQL_Parser($this->session);
$users = $graph->query("FROM ".$this->name." WHERE ".$sql); $users = $graph->query("FROM ".$this->name." WHERE ".$sql);
return $users; return $users;
...@@ -553,10 +553,15 @@ class Doctrine_Table extends Doctrine_Configurable { ...@@ -553,10 +553,15 @@ class Doctrine_Table extends Doctrine_Configurable {
/** /**
* execute * execute
*/ */
public function execute($query, array $array = array()) { public function execute($query, array $array = array(), $limit = null, $offset = null) {
$coll = new Doctrine_Collection($this); $coll = new Doctrine_Collection($this);
$query = $this->session->modifyLimitQuery($query,$limit,$offset);
if( ! empty($array)) {
$stmt = $this->session->getDBH()->prepare($query); $stmt = $this->session->getDBH()->prepare($query);
$stmt->execute($array); $stmt->execute($array);
} else {
$stmt = $this->session->getDBH()->query($query);
}
$data = $stmt->fetchAll(PDO::FETCH_ASSOC); $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor(); $stmt->closeCursor();
......
<?php
class Doctrine_Collection_OffsetTestCase extends Doctrine_UnitTestCase {
public function testExpand() {
$users = $this->session->query("FROM User-o");
$this->assertTrue($users instanceof Doctrine_Collection_Offset);
$this->assertEqual(count($users), 5);
$users[5];
$this->assertEqual($users[5]->getState(), Doctrine_Record::STATE_CLEAN);
$users[5];
$this->session->setAttribute(Doctrine::ATTR_COLL_LIMIT, 3);
$users = $this->session->query("FROM User-o");
$this->assertEqual(count($users), 3);
$this->assertEqual($users[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($users[1]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($users[2]->getState(), Doctrine_Record::STATE_CLEAN);
// indexes 0,1,2 in use
$users[7];
$this->assertEqual(count($users), 5);
$this->assertFalse($users->contains(3));
$this->assertFalse($users->contains(4));
$this->assertFalse($users->contains(5));
$this->assertTrue($users->contains(6));
$this->assertTrue($users->contains(7));
$this->assertEqual($users[6]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($users[7]->getState(), Doctrine_Record::STATE_CLEAN);
$users[5];
$this->assertEqual(count($users), 8);
$this->assertEqual($users[3]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($users[4]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($users[5]->getState(), Doctrine_Record::STATE_CLEAN);
$this->session->setAttribute(Doctrine::ATTR_COLL_LIMIT, 1);
$users = $this->session->query("FROM User-b, User.Phonenumber-o WHERE User.id = 5");
$this->assertEqual(count($users), 1);
$coll = $users[0]->Phonenumber;
$this->assertEqual(count($coll), 1);
$coll[1];
$this->assertEqual(count($coll), 2);
$this->assertEqual($coll[1]->phonenumber, "456 456");
}
public function testGetIterator() {
$this->session->setAttribute(Doctrine::ATTR_COLL_LIMIT, 4);
$coll = $this->session->query("FROM User-o");
foreach($coll as $user) {
}
$this->assertEqual($coll->count(), 8);
$this->assertEqual($coll[3]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($coll[6]->getState(), Doctrine_Record::STATE_CLEAN);
$this->session->setAttribute(Doctrine::ATTR_COLL_LIMIT, 3);
$coll = $this->session->query("FROM User-o");
foreach($coll as $user) {
}
$this->assertEqual($coll->count(), 8);
$this->assertEqual($coll[3]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($coll[6]->getState(), Doctrine_Record::STATE_CLEAN);
}
}
?>
...@@ -14,18 +14,23 @@ class Doctrine_CollectionTestCase extends Doctrine_UnitTestCase { ...@@ -14,18 +14,23 @@ class Doctrine_CollectionTestCase extends Doctrine_UnitTestCase {
$this->assertTrue($coll->count(),3); $this->assertTrue($coll->count(),3);
$this->assertEqual($coll->getKeys(), array(0,1,2)); $this->assertEqual($coll->getKeys(), array(0,1,2));
} }
public function testExpand() { public function testExpand() {
$users = $this->session->query("FROM User, User.Phonenumber-l WHERE User.Phonenumber.phonenumber LIKE '%123%'"); $users = $this->session->query("FROM User-b, User.Phonenumber-l WHERE User.Phonenumber.phonenumber LIKE '%123%'");
$this->assertTrue($users instanceof Doctrine_Collection); $this->assertTrue($users instanceof Doctrine_Collection_Batch);
$this->assertTrue($users[1] instanceof User); $this->assertTrue($users[1] instanceof User);
$this->assertTrue($users[1]->Phonenumber instanceof Doctrine_Collection_Lazy);
$data = $users[1]->Phonenumber->getData(); $data = $users[1]->Phonenumber->getData();
$coll = $users[1]->Phonenumber; $coll = $users[1]->Phonenumber;
$this->assertEqual(count($data), 1); $this->assertEqual(count($data), 1);
foreach($coll as $record) {
$record->phonenumber;
}
$coll[1]; $coll[1];
$this->assertEqual(count($coll), 3); $this->assertEqual(count($coll), 3);
...@@ -36,6 +41,7 @@ class Doctrine_CollectionTestCase extends Doctrine_UnitTestCase { ...@@ -36,6 +41,7 @@ class Doctrine_CollectionTestCase extends Doctrine_UnitTestCase {
$coll->setGenerator($generator); $coll->setGenerator($generator);
$generator = $coll->getGenerator(); $generator = $coll->getGenerator();
$this->assertEqual($generator->getIndex($this->old), 4); $this->assertEqual($generator->getIndex($this->old), 4);
} }
public function testGenerator() { public function testGenerator() {
$generator = new Doctrine_IndexGenerator("name"); $generator = new Doctrine_IndexGenerator("name");
......
...@@ -3,8 +3,6 @@ require_once("UnitTestCase.class.php"); ...@@ -3,8 +3,6 @@ require_once("UnitTestCase.class.php");
class Doctrine_DQL_ParserTestCase extends Doctrine_UnitTestCase { class Doctrine_DQL_ParserTestCase extends Doctrine_UnitTestCase {
public function testLimit() { public function testLimit() {
$graph = new Doctrine_DQL_Parser($this->session); $graph = new Doctrine_DQL_Parser($this->session);
$coll = $graph->query("FROM User LIMIT 3"); $coll = $graph->query("FROM User LIMIT 3");
$this->assertEqual($graph->getLimit(), 3); $this->assertEqual($graph->getLimit(), 3);
...@@ -84,7 +82,6 @@ class Doctrine_DQL_ParserTestCase extends Doctrine_UnitTestCase { ...@@ -84,7 +82,6 @@ class Doctrine_DQL_ParserTestCase extends Doctrine_UnitTestCase {
//$this->assertEqual($users[0]->Group[2]->name, "Terminators"); //$this->assertEqual($users[0]->Group[2]->name, "Terminators");
//$this->assertEqual(count($users[0]->Group), 3); //$this->assertEqual(count($users[0]->Group), 3);
$this->clearCache(); $this->clearCache();
$users = $graph->query("FROM User-b, User.Phonenumber-l WHERE User.Phonenumber.phonenumber LIKE '%123%'"); $users = $graph->query("FROM User-b, User.Phonenumber-l WHERE User.Phonenumber.phonenumber LIKE '%123%'");
......
...@@ -14,6 +14,7 @@ require_once("ValidatorTestCase.class.php"); ...@@ -14,6 +14,7 @@ require_once("ValidatorTestCase.class.php");
require_once("CollectionTestCase.class.php"); require_once("CollectionTestCase.class.php");
require_once("CacheSqliteTestCase.class.php"); require_once("CacheSqliteTestCase.class.php");
require_once("CollectionOffsetTestCase.class.php");
require_once("SenseiTestCase.class.php"); require_once("SenseiTestCase.class.php");
...@@ -25,7 +26,7 @@ $test = new GroupTest("Doctrine Framework Unit Tests"); ...@@ -25,7 +26,7 @@ $test = new GroupTest("Doctrine Framework Unit Tests");
/**
$test->addTestCase(new Doctrine_RecordTestCase()); $test->addTestCase(new Doctrine_RecordTestCase());
$test->addTestCase(new Doctrine_SessionTestCase()); $test->addTestCase(new Doctrine_SessionTestCase());
...@@ -45,10 +46,17 @@ $test->addTestCase(new Doctrine_BatchIteratorTestCase()); ...@@ -45,10 +46,17 @@ $test->addTestCase(new Doctrine_BatchIteratorTestCase());
$test->addTestCase(new Doctrine_DQL_ParserTestCase()); $test->addTestCase(new Doctrine_DQL_ParserTestCase());
$test->addTestCase(new Doctrine_CollectionTestCase());
$test->addTestCase(new Doctrine_ConfigurableTestCase()); $test->addTestCase(new Doctrine_ConfigurableTestCase());
$test->addTestCase(new Sensei_UnitTestCase()); $test->addTestCase(new Doctrine_CollectionTestCase());
*/
$test->addTestCase(new Doctrine_Collection_OffsetTestCase());
//$test->addTestCase(new Sensei_UnitTestCase());
//$test->addTestCase(new Doctrine_Cache_FileTestCase()); //$test->addTestCase(new Doctrine_Cache_FileTestCase());
......
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