1
0
mirror of synced 2024-12-05 03:06:05 +03:00
This commit is contained in:
doctrine 2006-04-19 16:01:36 +00:00
parent 61790d31cf
commit 16497adb6a
18 changed files with 642 additions and 150 deletions

View File

@ -30,9 +30,13 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/
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
*/
@ -55,6 +59,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
public function getTable() {
return $this->table;
}
public function isExpanded($offset) {
return isset($this->expanded[$offset]);
}
public function isExpandable() {
return $this->expandable;
}
/**
* @param Doctrine_IndexGenerator $generator
* @return void
@ -99,7 +109,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$value = $record->get($relation->getLocal());
foreach($this as $record) {
foreach($this->getNormalIterator() as $record) {
if($value !== null) {
$record->set($this->reference_field, $value);
} else {
@ -117,67 +127,121 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
/**
* @return boolean
*/
public function expand($i = null) {
if( ! isset($this->reference))
return false;
public function expand($key) {
$where = array();
$params = array();
$limit = null;
$offset = null;
$id = $this->reference->getID();
switch(get_class($this)):
case "Doctrine_Collection_Offset":
$limit = $this->getLimit();
$offset = (floor($key / $limit) * $limit);
if(empty($id))
return false;
if( ! $this->expandable && isset($this->expanded[$offset]))
return false;
$fields = implode(", ",$this->table->getColumnNames());
break;
default:
if( ! $this->expandable)
return false;
foreach($this->data as $v) {
switch(gettype($v)):
case "array":
$ids[] = $v['id'];
break;
case "object":
$id = $v->getID();
if( ! empty($id))
$ids[] = $id;
break;
endswitch;
}
if( ! isset($this->reference))
return false;
if($this instanceof Doctrine_Collection_Immediate) {
$fields = implode(", ",$this->table->getColumnNames());
} else {
$fields = implode(", ",$this->table->getPrimaryKeys());
}
$id = $this->reference->getID();
if($this->relation instanceof Doctrine_ForeignKey) {
$str = "";
$params = array($this->reference->getID());
if(empty($id))
return false;
if( ! empty($ids)) {
$str = " && id NOT IN (".substr(str_repeat("?, ",count($ids)),0,-2).")";
$params = array_merge($params,$ids);
switch(get_class($this)):
case "Doctrine_Collection_Immediate":
$fields = implode(", ",$this->table->getColumnNames());
break;
default:
$fields = implode(", ",$this->table->getPrimaryKeys());
endswitch;
endswitch;
if(isset($this->relation)) {
if($this->relation instanceof Doctrine_ForeignKey) {
$params = array($this->reference->getID());
$where[] = $this->reference_field." = ?";
if( ! isset($offset)) {
$ids = $this->getPrimaryKeys();
if( ! empty($ids)) {
$where[] = "id NOT IN (".substr(str_repeat("?, ",count($ids)),0,-2).")";
$params = array_merge($params,$ids);
}
$this->expandable = false;
}
} elseif($this->relation instanceof Doctrine_Association) {
$asf = $fk->getAssociationFactory();
$query = "SELECT ".$foreign." FROM ".$asf->getTableName()." WHERE ".$local."=".$this->getID();
$table = $fk->getTable();
$graph = new Doctrine_DQL_Parser($table->getSession());
$q = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".id IN ($query)";
}
$str = " WHERE ".$this->reference_field." = ?".$str;
$query = "SELECT ".$fields." FROM ".$this->table->getTableName().$str;
$coll = $this->table->execute($query,$params);
} elseif($this->relation instanceof Doctrine_Association) {
$asf = $fk->getAssociationFactory();
$query = "SELECT ".$foreign." FROM ".$asf->getTableName()." WHERE ".$local."=".$this->getID();
$table = $fk->getTable();
$graph = new Doctrine_DQL_Parser($table->getSession());
$q = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".id IN ($query)";
}
foreach($coll as $record) {
if(isset($this->reference_field))
$record->rawSet($this->reference_field, $this->reference);
$this->reference->addReference($record);
$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);
}
return true;
$params = array_merge($params, array_values($this->table->getInheritanceMap()));
$coll = $this->table->execute($query, $params, $limit, $offset);
if( ! isset($offset)) {
foreach($coll as $record) {
if(isset($this->reference_field))
$record->rawSet($this->reference_field,$this->reference);
$this->reference->addReference($record);
}
} else {
$i = $offset;
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
*/
@ -199,11 +263,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
}
/**
* @param mixed $key
* @return object Doctrine_Record return a specified dao
* @return object Doctrine_Record return a specified record
*/
public function get($key) {
if( ! isset($this->data[$key])) {
$this->expand();
$this->expand($key);
if( ! isset($this->data[$key]))
$this->data[$key] = $this->table->create();
@ -227,8 +291,12 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/
public function getPrimaryKeys() {
$list = array();
foreach($this->data[$key] as $record):
$list[] = $record->getID();
foreach($this->data as $record):
if(is_array($record) && isset($record['id'])) {
$list[] = $record['id'];
} else {
$list[] = $record->getID();
}
endforeach;
return $list;
}
@ -275,6 +343,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
return false;
$this->data[$key] = $record;
return true;
}
if(isset($this->generator)) {
@ -282,8 +351,45 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$this->data[$key] = $record;
} else
$this->data[] = $record;
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
* saves all records

View File

@ -1,8 +1,8 @@
<?php
require_once(Doctrine::getPath().DIRECTORY_SEPARATOR."Collection.class.php");
/**
* Doctrine_Collection_Batch a collection of data access objects,
* with batch load strategy
* Doctrine_Collection_Batch a collection of records,
* with batch load strategy
*
*
* @author Konsta Vesterinen
@ -21,21 +21,8 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
*/
private $loaded = array();
public function __construct(Doctrine_DQL_Parser $graph,$key) {
parent::__construct($graph->getTable($key));
$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]);
}
}
public function __construct(Doctrine_Table $table) {
parent::__construct($table);
$this->batchSize = $this->getTable()->getAttribute(Doctrine::ATTR_BATCH_SIZE);
}
@ -146,7 +133,7 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
endswitch;
} else {
$this->expand();
$this->expand($key);
if( ! isset($this->data[$key]))
$this->data[$key] = $this->table->create();
@ -161,10 +148,10 @@ class Doctrine_Collection_Batch extends Doctrine_Collection {
return $this->data[$key];
}
/**
* @return Doctrine_BatchIterator
* @return Doctrine_Iterator
*/
public function getIterator() {
return new Doctrine_BatchIterator($this);
return new Doctrine_Iterator_Expandable($this);
}
}
?>

View File

@ -12,19 +12,8 @@ class Doctrine_Collection_Immediate extends Doctrine_Collection {
* @param Doctrine_DQL_Parser $graph
* @param integer $key
*/
public function __construct(Doctrine_DQL_Parser $graph,$key) {
$table = $graph->getTable($key);
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;
}
public function __construct(Doctrine_Table $table) {
parent::__construct($table);
}
}
?>

View File

@ -10,9 +10,9 @@ class Doctrine_Collection_Lazy extends Doctrine_Collection_Batch {
* @param Doctrine_DQL_Parser $graph
* @param string $key
*/
public function __construct(Doctrine_DQL_Parser $graph,$key) {
public function __construct(Doctrine_Table $table) {
parent::__construct($table);
parent::setBatchSize(1);
parent::__construct($graph,$key);
}
}
?>

View File

@ -0,0 +1,31 @@
<?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);
}
}
?>

View File

@ -56,7 +56,7 @@ abstract class Doctrine_Configurable {
break;
case Doctrine::ATTR_FETCHMODE:
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;
case Doctrine::ATTR_LISTENER:
$this->setEventListener($value);
@ -87,6 +87,11 @@ abstract class Doctrine_Configurable {
case Doctrine::ATTR_CREATE_TABLES:
$value = (bool) $value;
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:
if( ! ($this instanceof Doctrine_Table))
throw new Doctrine_Exception("This attribute can only be set at table level.");
@ -124,7 +129,7 @@ abstract class Doctrine_Configurable {
final public function getAttribute($attribute) {
$attribute = (int) $attribute;
if($attribute < 1 || $attribute > 15)
if($attribute < 1 || $attribute > 16)
throw new InvalidKeyException();
if( ! isset($this->attributes[$attribute])) {

View File

@ -25,7 +25,11 @@ class Doctrine_DQL_Parser {
/**
* @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
*/
@ -91,6 +95,9 @@ class Doctrine_DQL_Parser {
$this->aggregate = false;
$this->data = array();
$this->connectors = array();
$this->collections = array();
$this->paths = array();
$this->joined = array();
}
/**
* loadFields -- this method loads fields for a given factory and
@ -104,16 +111,22 @@ class Doctrine_DQL_Parser {
* @return void
*/
private function loadFields(Doctrine_Table $table,$fetchmode) {
$name = $table->getComponentName();
switch($fetchmode):
case Doctrine::FETCH_OFFSET:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT);
case Doctrine::FETCH_IMMEDIATE:
$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();
break;
default:
throw new InvalidFetchModeException();
throw new Doctrine_Exception("Unknown fetchmode.");
endswitch;
$cname = $table->getComponentName();
$this->fetchModes[$cname] = $fetchmode;
@ -276,7 +289,7 @@ class Doctrine_DQL_Parser {
* @return array the data row for the specified factory
*/
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 array();
@ -406,20 +419,26 @@ class Doctrine_DQL_Parser {
* @param integer $index
*/
private function getCollection($name) {
$table = $this->session->getTable($name);
switch($this->fetchModes[$name]):
case 0:
$coll = new Doctrine_Collection_Immediate($this,$name);
case Doctrine::FETCH_BATCH:
$coll = new Doctrine_Collection_Batch($table);
break;
case 1:
$coll = new Doctrine_Collection_Batch($this,$name);
case Doctrine::FETCH_LAZY:
$coll = new Doctrine_Collection_Lazy($table);
break;
case 2:
$coll = new Doctrine_Collection_Lazy($this,$name);
case Doctrine::FETCH_OFFSET:
$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;
default:
throw new Exception("Unknown fetchmode");
endswitch;
$coll->populate($this);
return $coll;
}
/**
@ -555,6 +574,13 @@ class Doctrine_DQL_Parser {
case "lazy":
$fetchmode = Doctrine::FETCH_LAZY;
break;
case "o":
case "offset":
$fetchmode = Doctrine::FETCH_OFFSET;
break;
case "lo":
case "lazyoffset":
$fetchmode = Doctrine::FETCH_LAZYOFFSET;
default:
throw new DQLException("Unknown fetchmode '$e[1]'. The availible fetchmodes are 'i', 'b' and 'l'.");
endswitch;

View File

@ -120,6 +120,10 @@ final class Doctrine {
* collection key attribute
*/
const ATTR_COLL_KEY = 15;
/**
* collection limit attribute
*/
const ATTR_COLL_LIMIT = 16;
@ -146,18 +150,27 @@ final class Doctrine {
* IMMEDIATE FETCHING
* mode for immediate fetching
*/
const FETCH_IMMEDIATE = 0;
const FETCH_IMMEDIATE = 0;
/**
* BATCH FETCHING
* mode for batch fetching
*/
const FETCH_BATCH = 1;
const FETCH_BATCH = 1;
/**
* 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
*/
@ -165,11 +178,11 @@ final class Doctrine {
/**
* mode for optimistic locking
*/
const LOCK_OPTIMISTIC = 0;
const LOCK_OPTIMISTIC = 0;
/**
* mode for pessimistic locking
*/
const LOCK_PESSIMISTIC = 1;
const LOCK_PESSIMISTIC = 1;
/**
* PRIMARY KEY TYPE CONSTANTS
@ -178,11 +191,11 @@ final class Doctrine {
/**
* auto-incremented/(sequence updated) primary key
*/
const INCREMENT_KEY = 0;
const INCREMENT_KEY = 0;
/**
* unique key
*/
const UNIQUE_KEY = 1;
const UNIQUE_KEY = 1;
/**

101
classes/Iterator.class.php Normal file
View File

@ -0,0 +1,101 @@
<?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;
}
}
}
?>

140
classes/Lib.class.php Normal file
View File

@ -0,0 +1,140 @@
<?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);
}
}
?>

View File

@ -47,6 +47,7 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
Doctrine::ATTR_CACHE_SIZE => 100,
Doctrine::ATTR_CACHE => Doctrine::CACHE_NONE,
Doctrine::ATTR_BATCH_SIZE => 5,
Doctrine::ATTR_COLL_LIMIT => 5,
Doctrine::ATTR_LISTENER => new EmptyEventListener(),
Doctrine::ATTR_PK_COLUMNS => array("id"),
Doctrine::ATTR_PK_TYPE => Doctrine::INCREMENT_KEY,

View File

@ -777,10 +777,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
/**
* addReference
*/
public function addReference(Doctrine_Record $record) {
public function addReference(Doctrine_Record $record, $key = null) {
$name = $record->getTable()->getComponentName();
$this->references[$name]->add($record);
$this->originals[$name]->add($record);
$this->references[$name]->add($record, $key);
$this->originals[$name]->add($record, $key);
}
/**
* getReferences
@ -823,7 +823,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
// ONE-TO-MANY
$this->references[$name]->setReference($this,$fk);
}
$this->originals[$name] = new Doctrine_Collection($table);
$this->originals[$name] = new Doctrine_Collection($table);
}
break;
case Doctrine_Record::STATE_DIRTY:
@ -875,7 +875,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$coll = $graph->query($query, array($this->getID()));
$this->references[$name] = $coll;
$this->originals[$name] = clone $coll;
$this->originals[$name] = clone $coll;
}
endswitch;

View File

@ -4,13 +4,13 @@
*/
class Doctrine_Session_Common extends Doctrine_Session {
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;
else
$query .= " LIMIT 99999999999999";
if(isset($offset))
$query .= " OFFSET ".$offset;
} elseif( ! isset($limit) && isset($offset)) {
$query .= " LIMIT 999999999999 OFFSET ".$offset;
}
return $query;
}

View File

@ -448,7 +448,7 @@ class Doctrine_Table extends Doctrine_Configurable {
* @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
*/
final public function create(array $array = array()) {
public function create(array $array = array()) {
$this->data = $array;
$this->isNewEntry = true;
$record = $this->getRecord();
@ -460,7 +460,7 @@ class Doctrine_Table extends Doctrine_Configurable {
* @throws Doctrine_Find_Exception
* @return Doctrine_Record a record for given database identifier
*/
final public function find($id = null) {
public function find($id = null) {
if($id !== null) {
$query = $this->query." WHERE ".implode(" = ? AND ",$this->primaryKeys)." = ?";
$query = $this->applyInheritance($query);
@ -494,7 +494,7 @@ class Doctrine_Table extends Doctrine_Configurable {
* findAll
* @return Doctrine_Collection a collection of all data access objects
*/
final public function findAll() {
public function findAll() {
$graph = new Doctrine_DQL_Parser($this->session);
$users = $graph->query("FROM ".$this->name);
return $users;
@ -503,7 +503,7 @@ class Doctrine_Table extends Doctrine_Configurable {
* findBySql
* @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);
$users = $graph->query("FROM ".$this->name." WHERE ".$sql);
return $users;
@ -553,10 +553,15 @@ class Doctrine_Table extends Doctrine_Configurable {
/**
* execute
*/
public function execute($query, array $array = array()) {
$coll = new Doctrine_Collection($this);
$stmt = $this->session->getDBH()->prepare($query);
$stmt->execute($array);
public function execute($query, array $array = array(), $limit = null, $offset = null) {
$coll = new Doctrine_Collection($this);
$query = $this->session->modifyLimitQuery($query,$limit,$offset);
if( ! empty($array)) {
$stmt = $this->session->getDBH()->prepare($query);
$stmt->execute($array);
} else {
$stmt = $this->session->getDBH()->query($query);
}
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();

View File

@ -0,0 +1,77 @@
<?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);
}
}
?>

View File

@ -6,46 +6,52 @@ class Doctrine_CollectionTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($coll->count(),1);
$coll->add(new User());
$this->assertTrue($coll->count(),2);
$this->assertEqual($coll->getKeys(), array(0,1));
$coll[2] = new User();
$this->assertTrue($coll->count(),3);
$this->assertEqual($coll->getKeys(), array(0,1,2));
}
public function testExpand() {
$users = $this->session->query("FROM User, User.Phonenumber-l WHERE User.Phonenumber.phonenumber LIKE '%123%'");
$this->assertTrue($users instanceof Doctrine_Collection);
$users = $this->session->query("FROM User-b, User.Phonenumber-l WHERE User.Phonenumber.phonenumber LIKE '%123%'");
$this->assertTrue($users instanceof Doctrine_Collection_Batch);
$this->assertTrue($users[1] instanceof User);
$this->assertTrue($users[1]->Phonenumber instanceof Doctrine_Collection_Lazy);
$data = $users[1]->Phonenumber->getData();
$coll = $users[1]->Phonenumber;
$this->assertEqual(count($data), 1);
foreach($coll as $record) {
$record->phonenumber;
}
$coll[1];
$this->assertEqual(count($coll), 3);
$this->assertTrue($coll[2]->getState() == Doctrine_Record::STATE_PROXY);
$generator = new Doctrine_IndexGenerator("id");
$coll->setGenerator($generator);
$generator = $coll->getGenerator();
$this->assertEqual($generator->getIndex($this->old), 4);
}
public function testGenerator() {
$generator = new Doctrine_IndexGenerator("name");
$coll = new Doctrine_Collection($this->objTable);
$coll->setGenerator($generator);
$user = new User();
$user->name = "name";
$coll->add($user);
$this->assertEqual($coll["name"], $user);

View File

@ -3,8 +3,6 @@ require_once("UnitTestCase.class.php");
class Doctrine_DQL_ParserTestCase extends Doctrine_UnitTestCase {
public function testLimit() {
$graph = new Doctrine_DQL_Parser($this->session);
$coll = $graph->query("FROM User LIMIT 3");
$this->assertEqual($graph->getLimit(), 3);
@ -26,7 +24,7 @@ class Doctrine_DQL_ParserTestCase extends Doctrine_UnitTestCase {
$graph = new Doctrine_DQL_Parser($this->session);
$this->graph = $graph;
$user = $this->objTable->find(5);
@ -84,7 +82,6 @@ class Doctrine_DQL_ParserTestCase extends Doctrine_UnitTestCase {
//$this->assertEqual($users[0]->Group[2]->name, "Terminators");
//$this->assertEqual(count($users[0]->Group), 3);
$this->clearCache();
$users = $graph->query("FROM User-b, User.Phonenumber-l WHERE User.Phonenumber.phonenumber LIKE '%123%'");

View File

@ -14,6 +14,7 @@ require_once("ValidatorTestCase.class.php");
require_once("CollectionTestCase.class.php");
require_once("CacheSqliteTestCase.class.php");
require_once("CollectionOffsetTestCase.class.php");
require_once("SenseiTestCase.class.php");
@ -25,7 +26,7 @@ $test = new GroupTest("Doctrine Framework Unit Tests");
/**
$test->addTestCase(new Doctrine_RecordTestCase());
$test->addTestCase(new Doctrine_SessionTestCase());
@ -45,10 +46,17 @@ $test->addTestCase(new Doctrine_BatchIteratorTestCase());
$test->addTestCase(new Doctrine_DQL_ParserTestCase());
$test->addTestCase(new Doctrine_CollectionTestCase());
$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());