1
0
mirror of synced 2024-12-14 07:06:04 +03:00
This commit is contained in:
zYne 2007-05-11 00:19:46 +00:00
parent e3b3439415
commit 16a2370e27
2 changed files with 79 additions and 177 deletions

View File

@ -31,7 +31,7 @@ Doctrine::autoload("Doctrine_Access");
* @version $Revision: 1207 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_Collection2 extends Doctrine_Access implements Countable, IteratorAggregate, Serializable
class Doctrine_Collection2 extends Doctrine_Collection implements Countable, IteratorAggregate, Serializable
{
/**
* @var array $data an array containing the data access objects of this collection
@ -40,7 +40,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
/**
* @var Doctrine_Table $table each collection has only records of specified table
*/
protected $table;
protected $_table;
/**
* @var Doctrine_Record $reference collection can belong to a record
*/
@ -75,7 +75,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
$table = Doctrine_Manager::getInstance()
->getTable($table);
}
$this->table = $table;
$this->_table = $table;
$name = $table->getAttribute(Doctrine::ATTR_COLL_KEY);
if ($name !== null) {
@ -100,7 +100,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
*/
public function getTable()
{
return $this->table;
return $this->_table;
}
/**
* this method is automatically called when this Doctrine_Collection is serialized
@ -139,12 +139,12 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
$this->$name = $values;
}
$this->table = $connection->getTable($this->table);
$this->_table = $connection->getTable($this->_table);
$this->expanded = array();
$this->expandable = true;
$name = $this->table->getAttribute(Doctrine::ATTR_COLL_KEY);
$name = $this->_table->getAttribute(Doctrine::ATTR_COLL_KEY);
if ($name !== null) {
$this->keyColumn = $name;
}
@ -294,8 +294,8 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
*/
public function get($key)
{
if ($key === null) {
$record = $this->table->create();
if ($key === null || ! isset($this->data[$key])) {
$record = $this->_table->create();
if (isset($this->referenceField)) {
$record->set($this->referenceField, $this->reference, false);
@ -306,22 +306,6 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
return $record;
}
if ( ! isset($this->data[$key])) {
if ( ! isset($this->data[$key])) {
$this->data[$key] = $this->table->create();
}
if (isset($this->referenceField)) {
$value = $this->reference->get($this->relation->getLocal());
if ($value !== null) {
$this->data[$key]->set($this->referenceField, $value, false);
} else {
$this->data[$key]->set($this->referenceField, $this->reference, false);
}
}
}
return $this->data[$key];
}
@ -331,7 +315,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
public function getPrimaryKeys()
{
$list = array();
$name = $this->table->getIdentifier();
$name = $this->_table->getIdentifier();
foreach ($this->data as $record) {
if (is_array($record) && isset($record[$name])) {
@ -380,7 +364,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
* @param string $key optional key for the record
* @return boolean
*/
public function add(Doctrine_Record $record,$key = null)
public function add(Doctrine_Record $record, $key = null)
{
if (isset($this->referenceField)) {
$record->set($this->referenceField, $this->reference, false);
@ -424,7 +408,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
public function loadRelated($name = null)
{
$list = array();
$query = new Doctrine_Query($this->table->getConnection());
$query = new Doctrine_Query($this->_table->getConnection());
if ( ! isset($name)) {
foreach ($this->data as $record) {
@ -433,13 +417,13 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
$list[] = $value;
}
};
$query->from($this->table->getComponentName() . '(' . implode(", ",$this->table->getPrimaryKeys()) . ')');
$query->where($this->table->getComponentName() . '.id IN (' . substr(str_repeat("?, ", count($list)),0,-2) . ')');
$query->from($this->_table->getComponentName() . '(' . implode(", ",$this->_table->getPrimaryKeys()) . ')');
$query->where($this->_table->getComponentName() . '.id IN (' . substr(str_repeat("?, ", count($list)),0,-2) . ')');
return $query;
}
$rel = $this->table->getRelation($name);
$rel = $this->_table->getRelation($name);
if ($rel instanceof Doctrine_Relation_LocalKey || $rel instanceof Doctrine_Relation_ForeignKey) {
foreach ($this->data as $record) {
@ -469,7 +453,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
*/
public function populateRelated($name, Doctrine_Collection $coll)
{
$rel = $this->table->getRelation($name);
$rel = $this->_table->getRelation($name);
$table = $rel->getTable();
$foreign = $rel->getForeign();
$local = $rel->getLocal();
@ -501,7 +485,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
$this->data[$key]->setRelated($name, $sub);
}
} elseif ($rel instanceof Doctrine_Relation_Association) {
$identifier = $this->table->getIdentifier();
$identifier = $this->_table->getIdentifier();
$asf = $rel->getAssociationFactory();
$name = $table->getComponentName();
@ -541,7 +525,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
public function save(Doctrine_Connection $conn = null)
{
if ($conn == null) {
$conn = $this->table->getConnection();
$conn = $this->_table->getConnection();
}
$conn->beginTransaction();
@ -561,7 +545,7 @@ class Doctrine_Collection2 extends Doctrine_Access implements Countable, Iterato
public function delete(Doctrine_Connection $conn = null)
{
if ($conn == null) {
$conn = $this->table->getConnection();
$conn = $this->_table->getConnection();
}
$conn->beginTransaction();

View File

@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
Doctrine::autoload('Doctrine_Access');
/**
* Doctrine_Hydrate is a base class for Doctrine_RawSql and Doctrine_Query.
* Its purpose is to populate object graphs.
@ -32,7 +32,7 @@ Doctrine::autoload('Doctrine_Access');
* @version $Revision: 1255 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
class Doctrine_Hydrate2 extends Doctrine_Access
class Doctrine_Hydrate2
{
/**
* QUERY TYPE CONSTANTS
@ -77,7 +77,9 @@ class Doctrine_Hydrate2 extends Doctrine_Access
*
* table table object associated with given alias
*
* relation the relation object owned by the parent
*
* parent the alias of the parent
*/
protected $_aliasMap = array();
@ -320,6 +322,7 @@ class Doctrine_Hydrate2 extends Doctrine_Access
*
* @param Doctrine_Record $record
* @param array $row
* @return Doctrine_Record
*/
public function mapAggregateValues($record, array $row)
{
@ -338,6 +341,15 @@ class Doctrine_Hydrate2 extends Doctrine_Access
}
}
return $record;
}
/**
* mapRelated
*
* @return
*/
public function mapRelated()
{
}
/**
* execute
@ -353,10 +365,11 @@ class Doctrine_Hydrate2 extends Doctrine_Access
if (empty($this->_aliasMap)) {
throw new Doctrine_Hydrate_Exception("Couldn't execute query. Component alias map was empty.");
}
// initialize some variables used within the main loop
$rootMap = current($this->_aliasMap);
$coll = new Doctrine_Collection($rootMap['table']);
$prev[key($this->_aliasMap)] = $coll;
$rootAlias = key($this->_aliasMap);
$coll = new Doctrine_Collection2($rootMap['table']);
$prev[$rootAlias] = $coll;
$prevRow = array();
/**
@ -368,47 +381,78 @@ class Doctrine_Hydrate2 extends Doctrine_Access
* remove duplicated data rows and map data into objects
*/
foreach ($data as $tableAlias => $row) {
// skip empty rows (not mappable)
if (empty($row)) {
continue;
}
// check for validity
if ( ! isset($this->tableAliases[$tableAlias])) {
throw new Doctrine_Hydrate_Exception('Unknown table alias ' . $tableAlias);
}
$alias = $this->tableAliases[$tableAlias];
$map = $this->_aliasMap[$alias];
// initialize previous row array if not set
if ( ! isset($prevRow[$tableAlias])) {
$prevRow[$tableAlias] = array();
}
// don't map duplicate rows
if ($prevRow[$tableAlias] !== $row) {
// set internal data
$this->tables[$name]->setData($row);
$map['table']->setData($row);
// initialize a new record
$record = $this->tables[$name]->getRecord();
$record = $map['table']->getRecord();
// map aggregate values (if any)
$this->mapAggregateValues($record, $row);
if ($name == $root) {
if ($alias == $rootAlias) {
// add record into root collection
$coll->add($record);
unset($previd);
unset($prevRow);
} else {
$prev = $this->addRelated($prev, $name, $record);
$relation = $map['relation'];
$parentAlias = $map['parent'];
$parentMap = $this->_aliasMap[$parentAlias];
$parent = $prev[$parentAlias]->getLast();
// check the type of the relation
if ($relation->isOneToOne()) {
$prev[$alias] = $record;
} else {
// one-to-many relation or many-to-many relation
if ( ! $prev[$parentAlias]->getLast()->hasReference($relation->getAlias())) {
// initialize a new collection
$prev[$alias] = new Doctrine_Collection2($parentMap['table']);
$prev[$alias]->setReference($parent, $relation);
} else {
// previous entry found from memory
$prev[$alias] = $prev[$parentAlias]->getLast()->get($relation->getAlias());
}
// add record to the current collection
$prev[$alias]->add($record);
}
// initialize the relation from parent to the current collection/record
$parent->set($relation->getAlias(), $prev[$alias]);
}
// following statement is needed to ensure that mappings
// are being done properly when the result set doesn't
// contain the rows in 'right order'
if ($prev[$name] !== $record) {
$prev[$name] = $record;
if ($prev[$alias] !== $record) {
$prev[$alias] = $record;
}
}
$prevRow[$tableAlias] = $row;
}
}
return $coll;
}
/**
* execute
@ -418,12 +462,6 @@ class Doctrine_Hydrate2 extends Doctrine_Access
* @return Doctrine_Collection the root collection
*/
public function execute2($params = array(), $return = Doctrine::FETCH_RECORD) {
$array = $this->_fetch($params = array(), $return = Doctrine::FETCH_RECORD);
$keys = array_keys($this->tables);
$root = $keys[0];
$previd = array();
/**
* iterate over the fetched data
* here $data is a two dimensional array
@ -488,131 +526,11 @@ class Doctrine_Hydrate2 extends Doctrine_Access
continue;
}
if ( ! isset($previd[$name])) {
$previd[$name] = array();
}
if ($previd[$name] !== $row) {
// set internal data
$this->tables[$name]->setData($row);
// initialize a new record
$record = $this->tables[$name]->getRecord();
// aggregate values have numeric keys
if (isset($row[0])) {
$path = array_search($name, $this->tableAliases);
$alias = $this->getPathAlias($path);
// map each aggregate value
foreach ($row as $index => $value) {
$agg = false;
if (isset($this->pendingAggregates[$alias][$index])) {
$agg = $this->pendingAggregates[$alias][$index][3];
} elseif (isset($this->subqueryAggregates[$alias][$index])) {
$agg = $this->subqueryAggregates[$alias][$index];
}
$record->mapValue($agg, $value);
}
}
if ($name == $root) {
// add record into root collection
$coll->add($record);
unset($previd);
} else {
$prev = $this->addRelated($prev, $name, $record);
}
// following statement is needed to ensure that mappings
// are being done properly when the result set doesn't
// contain the rows in 'right order'
if ($prev[$name] !== $record) {
$prev[$name] = $record;
}
}
$previd[$name] = $row;
}
}
return $coll;
}
/**
* initRelation
*
* @param array $prev
* @param string $name
* @return array
*/
public function initRelated(array $prev, $name)
{
$pointer = $this->joins[$name];
$path = array_search($name, $this->tableAliases);
$tmp = explode('.', $path);
$alias = end($tmp);
if ( ! isset($prev[$pointer]) ) {
return $prev;
}
$fk = $this->tables[$pointer]->getRelation($alias);
if ( ! $fk->isOneToOne()) {
if ($prev[$pointer]->getLast() instanceof Doctrine_Record) {
if ( ! $prev[$pointer]->getLast()->hasReference($alias)) {
$prev[$name] = $this->getCollection($name);
$prev[$pointer]->getLast()->initReference($prev[$name],$fk);
} else {
$prev[$name] = $prev[$pointer]->getLast()->get($alias);
}
}
}
return $prev;
}
/**
* addRelated
*
* @param array $prev
* @param string $name
* @return array
*/
public function addRelated(array $prev, $name, Doctrine_Record $record)
{
$pointer = $this->joins[$name];
$path = array_search($name, $this->tableAliases);
$tmp = explode('.', $path);
$alias = end($tmp);
$fk = $this->tables[$pointer]->getRelation($alias);
if ($fk->isOneToOne()) {
$prev[$pointer]->getLast()->set($fk->getAlias(), $record);
$prev[$name] = $record;
} else {
// one-to-many relation or many-to-many relation
if ( ! $prev[$pointer]->getLast()->hasReference($alias)) {
$prev[$name] = $this->getCollection($name);
$prev[$pointer]->getLast()->initReference($prev[$name], $fk);
} else {
// previous entry found from memory
$prev[$name] = $prev[$pointer]->getLast()->get($alias);
}
$prev[$pointer]->getLast()->addReference($record, $fk);
}
return $prev;
}
/**
* isIdentifiable
* returns whether or not a given data row is identifiable (it contains