1
0
mirror of synced 2025-01-29 19:41:45 +03:00

Second merge from experimental branch to trunk.

This commit is contained in:
romanb 2008-01-12 19:49:11 +00:00
parent e01809d19a
commit 71d1150e3f
29 changed files with 768 additions and 499 deletions

View File

@ -20,8 +20,9 @@
*/ */
Doctrine::autoload('Doctrine_Access'); Doctrine::autoload('Doctrine_Access');
/** /**
* Doctrine_Collection * A Doctrine_Collection represents a collection of record objects.
* Collection of Doctrine_Record objects. * A collection object is strongly typed in the sense that it can only contain
* records of a specific type or one it's subtypes.
* *
* @package Doctrine * @package Doctrine
* @subpackage Collection * @subpackage Collection
@ -34,57 +35,74 @@ Doctrine::autoload('Doctrine_Access');
class Doctrine_Collection extends Doctrine_Access implements Countable, IteratorAggregate, Serializable class Doctrine_Collection extends Doctrine_Access implements Countable, IteratorAggregate, Serializable
{ {
/** /**
* @var array $data an array containing the records of this collection * An array containing the records of this collection.
*
* @var array
*/ */
protected $data = array(); protected $data = array();
/**
* The mapper object used to map the records of this collection to the database.
*
* @var Doctrine_Mapper
*/
protected $_mapper; protected $_mapper;
/** /**
* @var array $_snapshot a snapshot of the fetched data * A snapshot of the fetched data.
*
* @var array
*/ */
protected $_snapshot = array(); protected $_snapshot = array();
/** /**
* @var Doctrine_Record $reference collection can belong to a record * This record this collection is attached to, if any.
*
* @var Doctrine_Record
*/ */
protected $reference; protected $reference;
/** /**
* @var string $referenceField the reference field of the collection * The reference field of the collection.
*
* @var string $referenceField
*/ */
protected $referenceField; protected $referenceField;
/** /**
* @var Doctrine_Relation the record this collection is related to, if any * The relation this collection is related to, if any.
*
* @var Doctrine_Relation
*/ */
protected $relation; protected $relation;
/** /**
* @var string $keyColumn the name of the column that is used for collection key mapping * The name of the column that is used for collection key mapping.
*
* @var string
*/ */
protected $keyColumn; protected $keyColumn;
/** /**
* @var Doctrine_Null $null used for extremely fast null value testing * Helper variable. Used for fast null value testing.
*
* @var Doctrine_Null
*/ */
protected static $null; protected static $null;
/** /**
* constructor * Constructor.
* Creates a new collection that will hold instances of the type that is
* specified through the mapper. That means if the mapper is a mapper for
* the entity "User", then the resulting collection will be a collection of
* user objects.
* *
* @param Doctrine_Table|string $table * @param Doctrine_Mapper|string $mapper The mapper used by the collection.
* @param string $keyColumn The field name that will be used as the key
* in the collection.
*/ */
public function __construct($mapper, $keyColumn = null) public function __construct($mapper, $keyColumn = null)
{ {
if ($mapper instanceof Doctrine_Table) {
try {
throw new Exception();
} catch (Exception $e) {
echo $e->getTraceAsString();
}
}
if (is_string($mapper)) { if (is_string($mapper)) {
$mapper = Doctrine_Manager::getInstance()->getMapper($mapper); $mapper = Doctrine_Manager::getInstance()->getMapper($mapper);
} }
@ -105,7 +123,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
/** /**
* initNullObject * initNullObject
* initializes the null object for this collection * Initializes the null object for this collection.
* *
* @return void * @return void
*/ */
@ -116,7 +134,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
/** /**
* getTable * getTable
* returns the table this collection belongs to * Returns the table of the mapper of the collection.
* *
* @return Doctrine_Table * @return Doctrine_Table
*/ */
@ -124,6 +142,17 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{ {
return $this->_mapper->getTable(); return $this->_mapper->getTable();
} }
/**
* getMapper
* Returns the mapper of this collection.
*
* @return Doctrine_Mapper
*/
public function getMapper()
{
return $this->_mapper;
}
/** /**
* setData * setData
@ -137,7 +166,10 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
/** /**
* this method is automatically called when this Doctrine_Collection is serialized * Serializes the collection.
* This method is automatically called when this Doctrine_Collection is serialized.
*
* Part of the implementation of the Serializable interface.
* *
* @return array * @return array
*/ */
@ -158,15 +190,17 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
/** /**
* unseralize * Reconstitutes the collection object from it's serialized form.
* this method is automatically called everytime a Doctrine_Collection object is unserialized * This method is automatically called everytime a Doctrine_Collection object is unserialized.
*
* Part of the implementation of the Serializable interface.
* *
* @return void * @return void
*/ */
public function unserialize($serialized) public function unserialize($serialized)
{ {
$manager = Doctrine_Manager::getInstance(); $manager = Doctrine_Manager::getInstance();
$connection = $manager->getCurrentConnection(); $connection = $manager->getCurrentConnection();
$array = unserialize($serialized); $array = unserialize($serialized);
@ -196,7 +230,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
public function setKeyColumn($column) public function setKeyColumn($column)
{ {
$this->keyColumn = $column; $this->keyColumn = $column;
return $this; return $this;
} }
@ -243,6 +276,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{ {
return end($this->data); return end($this->data);
} }
/** /**
* returns the last record in the collection * returns the last record in the collection
* *
@ -252,6 +286,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{ {
return end($this->data); return end($this->data);
} }
/** /**
* returns the current key * returns the current key
* *
@ -261,6 +296,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{ {
return key($this->data); return key($this->data);
} }
/** /**
* setReference * setReference
* sets a reference pointer * sets a reference pointer
@ -269,18 +305,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
public function setReference(Doctrine_Record $record, Doctrine_Relation $relation) public function setReference(Doctrine_Record $record, Doctrine_Relation $relation)
{ {
/*try {
throw new Exception();
} catch (Exception $e) {
echo "relation set on collection: " . get_class($relation) . "<br />";
echo $e->getTraceAsString() . "<br />";
}*/
$this->reference = $record; $this->reference = $record;
$this->relation = $relation; $this->relation = $relation;
if ($relation instanceof Doctrine_Relation_ForeignKey || if ($relation instanceof Doctrine_Relation_ForeignKey ||
$relation instanceof Doctrine_Relation_LocalKey) { $relation instanceof Doctrine_Relation_LocalKey) {
$this->referenceField = $relation->getForeignFieldName(); $this->referenceField = $relation->getForeignFieldName();
$value = $record->get($relation->getLocalFieldName()); $value = $record->get($relation->getLocalFieldName());
foreach ($this->data as $record) { foreach ($this->data as $record) {
@ -331,6 +360,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
return isset($this->data[$key]); return isset($this->data[$key]);
} }
/**
*
*/
public function search(Doctrine_Record $record) public function search(Doctrine_Record $record)
{ {
return array_search($record, $this->data, true); return array_search($record, $this->data, true);
@ -367,6 +399,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$record->set($this->referenceField, $this->reference, false); $record->set($this->referenceField, $this->reference, false);
} }
} }
if ($key === null) { if ($key === null) {
$this->data[] = $record; $this->data[] = $record;
} else { } else {
@ -374,7 +407,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
if (isset($this->keyColumn)) { if (isset($this->keyColumn)) {
$record->set($this->keyColumn, $key); $record->set($this->keyColumn, $key);
} }
@ -385,7 +417,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
/** /**
* @return array an array containing all primary keys * Returns the primary keys of all records in the collection.
*
* @return array An array containing all primary keys.
*/ */
public function getPrimaryKeys() public function getPrimaryKeys()
{ {
@ -412,11 +446,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
/** /**
* count * Returns the number of records in this collection.
* this class implements interface countable
* returns the number of records in this collection
* *
* @return integer * Implementation of the Countable interface.
*
* @return integer The number of records in the collection.
*/ */
public function count() public function count()
{ {
@ -434,7 +468,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
if (isset($this->referenceField)) { if (isset($this->referenceField)) {
$record->set($this->referenceField, $this->reference, false); $record->set($this->referenceField, $this->reference, false);
} }
$this->data[$key] = $record; $this->data[$key] = $record;
} }
@ -455,7 +488,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$record->set($this->referenceField, $this->reference, false); $record->set($this->referenceField, $this->reference, false);
} }
} }
/** /*
* for some weird reason in_array cannot be used here (php bug ?) * for some weird reason in_array cannot be used here (php bug ?)
* *
* if used it results in fatal error : [ nesting level too deep ] * if used it results in fatal error : [ nesting level too deep ]
@ -495,7 +528,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
public function loadRelated($name = null) public function loadRelated($name = null)
{ {
$list = array(); $list = array();
$query = new Doctrine_Query($this->_mapper->getConnection()); $query = new Doctrine_Query($this->_mapper->getConnection());
if ( ! isset($name)) { if ( ! isset($name)) {
foreach ($this->data as $record) { foreach ($this->data as $record) {
@ -510,7 +543,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
return $query; return $query;
} }
$rel = $this->_mapper->getTable()->getRelation($name); $rel = $this->_mapper->getTable()->getRelation($name);
if ($rel instanceof Doctrine_Relation_LocalKey || $rel instanceof Doctrine_Relation_ForeignKey) { if ($rel instanceof Doctrine_Relation_LocalKey || $rel instanceof Doctrine_Relation_ForeignKey) {
foreach ($this->data as $record) { foreach ($this->data as $record) {
@ -525,9 +558,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
} }
} }
$dql = $rel->getRelationDql(count($list), 'collection'); $dql = $rel->getRelationDql(count($list), 'collection');
$coll = $query->query($dql, $list);
$coll = $query->query($dql, $list);
$this->populateRelated($name, $coll); $this->populateRelated($name, $coll);
} }
@ -618,7 +650,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
public function takeSnapshot() public function takeSnapshot()
{ {
$this->_snapshot = $this->data; $this->_snapshot = $this->data;
return $this; return $this;
} }
@ -647,7 +678,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
public function processDiff() public function processDiff()
{ {
foreach (array_udiff($this->_snapshot, $this->data, array($this, "compareRecords")) as $record) { foreach (array_udiff($this->_snapshot, $this->data, array($this, "_compareRecords")) as $record) {
$record->delete(); $record->delete();
} }
return $this; return $this;
@ -663,9 +694,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{ {
$data = array(); $data = array();
foreach ($this as $key => $record) { foreach ($this as $key => $record) {
$key = $prefixKey ? get_class($record) . '_' .$key:$key; $key = $prefixKey ? get_class($record) . '_' .$key:$key;
$data[$key] = $record->toArray($deep, $prefixKey); $data[$key] = $record->toArray($deep, $prefixKey);
} }
@ -758,7 +787,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
public function getDeleteDiff() public function getDeleteDiff()
{ {
return array_udiff($this->_snapshot, $this->data, array($this, "compareRecords")); return array_udiff($this->_snapshot, $this->data, array($this, "_compareRecords"));
} }
/** /**
@ -768,14 +797,14 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/ */
public function getInsertDiff() public function getInsertDiff()
{ {
return array_udiff($this->data, $this->_snapshot, array($this, "compareRecords")); return array_udiff($this->data, $this->_snapshot, array($this, "_compareRecords"));
} }
/** /**
* compareRecords * _compareRecords
* Compares two records. To be used on _snapshot diffs using array_udiff * Compares two records. To be used on _snapshot diffs using array_udiff.
*/ */
protected function compareRecords($a, $b) protected function _compareRecords($a, $b)
{ {
if ($a->getOid() == $b->getOid()) { if ($a->getOid() == $b->getOid()) {
return 0; return 0;
@ -786,8 +815,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
/** /**
* save * save
* saves all records of this collection and processes the * Saves all records of this collection and processes the
* difference of the last snapshot and the current data * difference of the last snapshot and the current data.
* *
* @param Doctrine_Connection $conn optional connection parameter * @param Doctrine_Connection $conn optional connection parameter
* @return Doctrine_Collection * @return Doctrine_Collection

View File

@ -60,6 +60,9 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/ */
protected $dbh; protected $dbh;
/**
*
*/
protected $_tableFactory; protected $_tableFactory;
/** /**
@ -169,6 +172,12 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
'Sqlite', 'Sqlite',
'Firebird' 'Firebird'
); );
/**
* The query count. Represents the number of executed database queries by the connection.
*
* @var integer
*/
protected $_count = 0; protected $_count = 0;
/** /**
@ -184,9 +193,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
throw new Doctrine_Connection_Exception('First argument should be an instance of PDO or implement Doctrine_Adapter_Interface'); throw new Doctrine_Connection_Exception('First argument should be an instance of PDO or implement Doctrine_Adapter_Interface');
} }
$this->dbh = $adapter; $this->dbh = $adapter;
$this->isConnected = true; $this->isConnected = true;
} else if (is_array($adapter)) { } else if (is_array($adapter)) {
$this->pendingAttributes[Doctrine::ATTR_DRIVER_NAME] = $adapter['scheme']; $this->pendingAttributes[Doctrine::ATTR_DRIVER_NAME] = $adapter['scheme'];
@ -235,7 +242,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/ */
public function getAttribute($attribute) public function getAttribute($attribute)
{ {
if ($attribute >= 100) { if ($attribute >= 100) {
if ( ! isset($this->attributes[$attribute])) { if ( ! isset($this->attributes[$attribute])) {
return parent::getAttribute($attribute); return parent::getAttribute($attribute);
@ -353,14 +359,13 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
} }
/** /**
* returns the database handler of which this connection uses * returns the database handler which this connection uses
* *
* @return PDO the database handler * @return PDO the database handler
*/ */
public function getDbh() public function getDbh()
{ {
$this->connect(); $this->connect();
return $this->dbh; return $this->dbh;
} }
@ -372,13 +377,11 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/ */
public function connect() public function connect()
{ {
if ($this->isConnected) { if ($this->isConnected) {
return false; return false;
} }
$event = new Doctrine_Event($this, Doctrine_Event::CONN_CONNECT); $event = new Doctrine_Event($this, Doctrine_Event::CONN_CONNECT);
$this->getListener()->preConnect($event); $this->getListener()->preConnect($event);
$e = explode(':', $this->options['dsn']); $e = explode(':', $this->options['dsn']);
@ -515,21 +518,19 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* *
* @throws Doctrine_Connection_Exception if something went wrong at the database level * @throws Doctrine_Connection_Exception if something went wrong at the database level
* @param string $table The table to delete data from * @param string $table The table to delete data from
* @param array $identifier An associateve array containing identifier column-value pairs. * @param array $identifier An associateve array containing identifier fieldname-value pairs.
* @return integer The number of affected rows * @return integer The number of affected rows
*/ */
public function delete(Doctrine_Table $table, array $identifier) public function delete(Doctrine_Table $table, array $identifier)
{ {
$tmp = array(); $criteria = array();
foreach (array_keys($identifier) as $id) { foreach (array_keys($identifier) as $id) {
$tmp[] = $table->getColumnName($id) . ' = ?'; $criteria[] = $table->getColumnName($id) . ' = ?';
} }
$query = 'DELETE FROM ' $query = 'DELETE FROM '
. $this->quoteIdentifier($table->getTableName()) . $this->quoteIdentifier($table->getTableName())
. ' WHERE ' . implode(' AND ', $tmp); . ' WHERE ' . implode(' AND ', $criteria);
return $this->exec($query, array_values($identifier)); return $this->exec($query, array_values($identifier));
} }
@ -573,7 +574,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* Inserts a table row with specified data. * Inserts a table row with specified data.
* *
* @param string $table The table to insert data into. * @param string $table The table to insert data into.
* @param array $values An associateve array containing column-value pairs. * @param array $fields An associateve array containing fieldname-value pairs.
* @return mixed boolean false if empty value array was given, * @return mixed boolean false if empty value array was given,
* otherwise returns the number of affected rows * otherwise returns the number of affected rows
*/ */
@ -606,53 +607,9 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$query .= implode(', ', $a) . ')'; $query .= implode(', ', $a) . ')';
// prepare and execute the statement // prepare and execute the statement
return $this->exec($query, array_values($fields)); return $this->exec($query, array_values($fields));
} }
/**
* @todo DESCRIBE WHAT THIS METHOD DOES, PLEASE!
*/
public function processSingleInsert(Doctrine_Record $record)
{
$fields = $record->getPrepared();
if (empty($fields)) {
return false;
}
$table = $record->getTable();
$identifier = (array) $table->getIdentifier();
$seq = $record->getTable()->getOption('sequenceName');
if ( ! empty($seq)) {
$id = $this->sequence->nextId($seq);
$seqName = $table->getIdentifier();
$fields[$seqName] = $id;
$record->assignIdentifier($id);
}
$this->insert($table, $fields);
if (empty($seq) && count($identifier) == 1 && $identifier[0] == $table->getIdentifier() &&
$table->getIdentifierType() != Doctrine::IDENTIFIER_NATURAL) {
if (strtolower($this->getName()) == 'pgsql') {
$seq = $table->getTableName() . '_' . $identifier[0];
}
$id = $this->sequence->lastInsertId($seq);
if ( ! $id) {
throw new Doctrine_Connection_Exception("Couldn't get last insert identifier.");
}
$record->assignIdentifier($id);
} else {
$record->assignIdentifier(true);
}
}
/** /**
* Set the charset on the current connection * Set the charset on the current connection
@ -661,11 +618,11 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/ */
public function setCharset($charset) public function setCharset($charset)
{ {
return true;
} }
/** /**
* Quote a string so it can be safely used as a table or column name * Quote a string so it can be safely used as a table or column name.
* *
* Delimiting style depends on which database driver is being used. * Delimiting style depends on which database driver is being used.
* *
@ -1032,7 +989,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
public function rethrowException(Exception $e, $invoker) public function rethrowException(Exception $e, $invoker)
{ {
$event = new Doctrine_Event($this, Doctrine_Event::CONN_ERROR); $event = new Doctrine_Event($this, Doctrine_Event::CONN_ERROR);
$this->getListener()->preError($event); $this->getListener()->preError($event);
$name = 'Doctrine_Connection_' . $this->driverName . '_Exception'; $name = 'Doctrine_Connection_' . $this->driverName . '_Exception';
@ -1079,7 +1035,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
} }
/** /**
* Gets a mapper for the specified domain class that is used map instances of * Gets a mapper for the specified domain class that is used to map instances of
* the class between the relational database and their object representation. * the class between the relational database and their object representation.
* *
* @return Doctrine_Mapper_Abstract The mapper object. * @return Doctrine_Mapper_Abstract The mapper object.
@ -1092,9 +1048,9 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$customMapperClass = $className . 'Mapper'; $customMapperClass = $className . 'Mapper';
if (class_exists($customMapperClass, $this->getAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES)) && if (class_exists($customMapperClass, $this->getAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES)) &&
in_array('Doctrine_Mapper', class_parents($customMapperClass))) { in_array('Doctrine_Mapper_Abstract', class_parents($customMapperClass))) {
$table = $this->getTable($className); $table = $this->getTable($className);
$mapper = new $customMapperClass($className, $this); $mapper = new $customMapperClass($className, $table);
} else { } else {
// instantiate correct mapper type // instantiate correct mapper type
$table = $this->getTable($className); $table = $this->getTable($className);
@ -1250,7 +1206,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
public function close() public function close()
{ {
$event = new Doctrine_Event($this, Doctrine_Event::CONN_CLOSE); $event = new Doctrine_Event($this, Doctrine_Event::CONN_CLOSE);
$this->getAttribute(Doctrine::ATTR_LISTENER)->preClose($event); $this->getAttribute(Doctrine::ATTR_LISTENER)->preClose($event);
$this->clear(); $this->clear();

View File

@ -73,7 +73,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
{ {
$tree = array(); $tree = array();
foreach ($tables as $k => $table) { foreach ($tables as $k => $table) {
if ( ! ($table instanceof Doctrine_Mapper)) { if ( ! ($table instanceof Doctrine_Mapper_Abstract)) {
$table = $this->conn->getMapper($table); $table = $this->conn->getMapper($table);
} }
$nm = $table->getComponentName(); $nm = $table->getComponentName();
@ -281,7 +281,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
* @return boolean true on success, false on failure * @return boolean true on success, false on failure
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper). * @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/ */
public function delete(Doctrine_Record $record) /*public function delete(Doctrine_Record $record)
{ {
if ( ! $this->_autoflush) { if ( ! $this->_autoflush) {
return true; return true;
@ -331,7 +331,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$this->conn->commit(); $this->conn->commit();
return true; return true;
} }*/
/** /**
* @todo Description. See also the todo for deleteMultiple(). * @todo Description. See also the todo for deleteMultiple().
@ -356,6 +356,8 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
}*/ }*/
/** /**
* DOESNT SEEM TO BE USED ANYWHERE.
*
* deleteMultiple * deleteMultiple
* deletes all records from the pending delete list * deletes all records from the pending delete list
* *
@ -364,7 +366,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
* queries itself and sometimes it leaves the sql construction to Connection. * queries itself and sometimes it leaves the sql construction to Connection.
* This should be changed. * This should be changed.
*/ */
public function deleteMultiple(array $records) /*public function deleteMultiple(array $records)
{ {
foreach ($this->delete as $name => $deletes) { foreach ($this->delete as $name => $deletes) {
$record = false; $record = false;
@ -414,7 +416,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} }
} }
} }
} }*/
/** /**
* saveRelated * saveRelated
@ -498,7 +500,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
* @throws PDOException if something went wrong at database level * @throws PDOException if something went wrong at database level
* @return void * @return void
*/ */
public function deleteComposites(Doctrine_Record $record) /*public function deleteComposites(Doctrine_Record $record)
{ {
foreach ($record->getTable()->getRelations() as $fk) { foreach ($record->getTable()->getRelations() as $fk) {
if ($fk->isComposite()) { if ($fk->isComposite()) {
@ -509,7 +511,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} }
} }
} }
} }*/
/** /**
* saveAll * saveAll
@ -554,22 +556,19 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
//echo "<br /><br />flushin all.<br /><br />"; //echo "<br /><br />flushin all.<br /><br />";
// get the flush tree // get the flush tree
$tree = $this->buildFlushTree($this->conn->getMappers()); $tree = $this->buildFlushTree($this->conn->getMappers());
//foreach ($tree as $name) echo $name . "<br />";
// save all records // save all records
foreach ($tree as $name) { foreach ($tree as $name) {
$mapper = $this->conn->getMapper($name); $mapper = $this->conn->getMapper($name);
foreach ($mapper->getRepository() as $record) { foreach ($mapper->getRepository() as $record) {
//echo $record->getOid() . "<br />"; //echo $record->getOid() . "<br />";
$mapper->save($record); $mapper->saveSingleRecord($record);
} }
} }
// save all associations // save all associations
foreach ($tree as $name) { foreach ($tree as $name) {
$mapper = $this->conn->getMapper($name); $mapper = $this->conn->getMapper($name);
foreach ($mapper->getRepository() as $record) { foreach ($mapper->getRepository() as $record) {
$mapper->saveAssociations($record); $mapper->saveAssociations($record);
} }

View File

@ -106,6 +106,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
// Initialize // Initialize
foreach ($this->_queryComponents as $dqlAlias => $data) { foreach ($this->_queryComponents as $dqlAlias => $data) {
$data['mapper']->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, false);
$componentName = $data['mapper']->getComponentName(); $componentName = $data['mapper']->getComponentName();
$listeners[$componentName] = $data['table']->getRecordListener(); $listeners[$componentName] = $data['table']->getRecordListener();
$identifierMap[$dqlAlias] = array(); $identifierMap[$dqlAlias] = array();
@ -229,6 +230,11 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
$driver->flush(); $driver->flush();
// re-enable lazy loading
foreach ($this->_queryComponents as $dqlAlias => $data) {
$data['mapper']->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, true);
}
//$e = microtime(true); //$e = microtime(true);
//echo 'Hydration took: ' . ($e - $s) . ' for '.count($result).' records<br />'; //echo 'Hydration took: ' . ($e - $s) . ' for '.count($result).' records<br />';
@ -290,8 +296,9 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
$e = explode('__', $key); $e = explode('__', $key);
$last = strtolower(array_pop($e)); $last = strtolower(array_pop($e));
$cache[$key]['dqlAlias'] = $this->_tableAliases[strtolower(implode('__', $e))]; $cache[$key]['dqlAlias'] = $this->_tableAliases[strtolower(implode('__', $e))];
$table = $this->_queryComponents[$cache[$key]['dqlAlias']]['table']; $mapper = $this->_queryComponents[$cache[$key]['dqlAlias']]['mapper'];
$fieldName = $table->getFieldName($last); $table = $mapper->getTable();
$fieldName = $mapper->getFieldName($last);
$cache[$key]['fieldName'] = $fieldName; $cache[$key]['fieldName'] = $fieldName;
if ($table->isIdentifier($fieldName)) { if ($table->isIdentifier($fieldName)) {
$cache[$key]['isIdentifier'] = true; $cache[$key]['isIdentifier'] = true;
@ -306,8 +313,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
} }
} }
$map = $this->_queryComponents[$cache[$key]['dqlAlias']]; $mapper = $this->_queryComponents[$cache[$key]['dqlAlias']]['mapper'];
$mapper = $map['mapper'];
$dqlAlias = $cache[$key]['dqlAlias']; $dqlAlias = $cache[$key]['dqlAlias'];
$fieldName = $cache[$key]['fieldName']; $fieldName = $cache[$key]['fieldName'];

View File

@ -37,18 +37,22 @@ class Doctrine_Hydrator_ArrayDriver
{ {
return array(); return array();
} }
public function getElement(array $data, $component) public function getElement(array $data, $component)
{ {
return $data; return $data;
} }
public function isIdentifiable(array $data, Doctrine_Table $table) public function isIdentifiable(array $data, Doctrine_Table $table)
{ {
return ( ! empty($data)); return ( ! empty($data));
} }
public function registerCollection($coll) public function registerCollection($coll)
{ {
} }
public function initRelated(array &$data, $name) public function initRelated(array &$data, $name)
{ {
if ( ! isset($data[$name])) { if ( ! isset($data[$name])) {
@ -56,10 +60,12 @@ class Doctrine_Hydrator_ArrayDriver
} }
return true; return true;
} }
public function getNullPointer() public function getNullPointer()
{ {
return null; return null;
} }
public function getLastKey(&$data) public function getLastKey(&$data)
{ {
end($data); end($data);

View File

@ -20,8 +20,8 @@
*/ */
/** /**
* Doctrine_Hydrate_Record * Doctrine_Hydrate_RecordDriver
* defines a record fetching strategy for Doctrine_Hydrate * Hydration strategy used for creating collections of entity objects.
* *
* @package Doctrine * @package Doctrine
* @subpackage Hydrate * @subpackage Hydrate
@ -30,14 +30,13 @@
* @since 1.0 * @since 1.0
* @version $Revision$ * @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
*/ */
class Doctrine_Hydrator_RecordDriver extends Doctrine_Locator_Injectable class Doctrine_Hydrator_RecordDriver extends Doctrine_Locator_Injectable
{ {
protected $_collections = array(); protected $_collections = array();
protected $_records = array(); protected $_records = array();
protected $_mappers = array();
protected $_tables = array();
public function getElementCollection($component) public function getElementCollection($component)
{ {
@ -105,13 +104,12 @@ class Doctrine_Hydrator_RecordDriver extends Doctrine_Locator_Injectable
public function getElement(array $data, $component) public function getElement(array $data, $component)
{ {
if ( ! isset($this->_tables[$component])) { if ( ! isset($this->_mappers[$component])) {
$this->_tables[$component] = Doctrine_Manager::getInstance()->getMapper($component); $this->_mappers[$component] = Doctrine_Manager::getInstance()->getMapper($component);
$this->_tables[$component]->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, false);
} }
$this->_tables[$component]->setData($data); $component = $this->_getClassnameToReturn($data, $component);
$record = $this->_tables[$component]->getRecord(); $record = $this->_mappers[$component]->getRecord($data);
if ( ! isset($this->_records[$record->getOid()]) ) { if ( ! isset($this->_records[$record->getOid()]) ) {
$record->clearRelated(); $record->clearRelated();
@ -127,8 +125,38 @@ class Doctrine_Hydrator_RecordDriver extends Doctrine_Locator_Injectable
foreach ($this->_collections as $key => $coll) { foreach ($this->_collections as $key => $coll) {
$coll->takeSnapshot(); $coll->takeSnapshot();
} }
foreach ($this->_tables as $table) { }
$table->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, true);
/**
* Check the dataset for a discriminator column, to determine the correct
* class to instantiate. If no discriminator column is found, the given
* classname will be returned.
*
* @todo this function could use reflection to check the first time it runs
* if the subclassing option is not set.
*
* @return string The name of the class to instantiate.
*
*/
protected function _getClassnameToReturn(array $data, $className)
{
$subClasses = $this->_mappers[$className]->getTable()->getOption('subclasses');
if ( ! isset($subClasses)) {
return $className;
} }
foreach ($subClasses as $subclass) {
if ( ! isset($this->_mappers[$subclass])) {
$this->_mappers[$subclass] = Doctrine_Manager::getInstance()->getMapper($subclass);
}
$mapper = $this->_mappers[$subclass];
$inheritanceMap = $mapper->getDiscriminatorColumn();
foreach ($inheritanceMap as $key => $value) {
if (isset($data[$key]) && $data[$key] == $value) {
return $mapper->getComponentName();
}
}
}
return $className;
} }
} }

View File

@ -255,7 +255,7 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
} }
$driverName = $adapter->getAttribute(Doctrine::ATTR_DRIVER_NAME); $driverName = $adapter->getAttribute(Doctrine::ATTR_DRIVER_NAME);
} elseif (is_array($adapter)) { } else if (is_array($adapter)) {
if ( ! isset($adapter[0])) { if ( ! isset($adapter[0])) {
throw new Doctrine_Manager_Exception('Empty data source name given.'); throw new Doctrine_Manager_Exception('Empty data source name given.');
} }

View File

@ -31,7 +31,8 @@
* @link www.phpdoctrine.org * @link www.phpdoctrine.org
* @since 1.0 * @since 1.0
*/ */
class Doctrine_Mapper extends Doctrine_Configurable implements Countable abstract class Doctrine_Mapper_Abstract extends Doctrine_Configurable
implements Countable
{ {
/** /**
* @var Doctrine_Table Metadata container that represents the database table this * @var Doctrine_Table Metadata container that represents the database table this
@ -48,13 +49,6 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
* The names of all the fields that are available on entities created by this mapper. * The names of all the fields that are available on entities created by this mapper.
*/ */
protected $_fieldNames = array(); protected $_fieldNames = array();
/**
* Temporary data which is then loaded into Doctrine_Record::$_data.
*
* @var array $data
*/
protected $_data = array();
/** /**
* The Doctrine_Connection object that the database connection of this mapper. * The Doctrine_Connection object that the database connection of this mapper.
@ -372,10 +366,9 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
* *
* @return Doctrine_Record * @return Doctrine_Record
*/ */
public function getRecord() public function getRecord(array $data)
{ {
if ( ! empty($this->_data)) { if ( ! empty($data)) {
$identifierFieldNames = $this->_table->getIdentifier(); $identifierFieldNames = $this->_table->getIdentifier();
if ( ! is_array($identifierFieldNames)) { if ( ! is_array($identifierFieldNames)) {
@ -384,18 +377,19 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
$found = false; $found = false;
foreach ($identifierFieldNames as $fieldName) { foreach ($identifierFieldNames as $fieldName) {
if ( ! isset($this->_data[$fieldName])) { if ( ! isset($data[$fieldName])) {
// primary key column not found return new record // primary key column not found return new record
$found = true; $found = true;
break; break;
} }
$id[] = $this->_data[$fieldName]; $id[] = $data[$fieldName];
} }
if ($found) { if ($found) {
$recordName = $this->getClassnameToReturn(); //$recordName = $this->getClassnameToReturn();
$record = new $recordName($this, true); //$record = new $recordName($this, true);
$this->_data = array(); $record = new $this->_domainClassName($this, true, $data);
$data = array();
return $record; return $record;
} }
@ -404,16 +398,18 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
if (isset($this->_identityMap[$id])) { if (isset($this->_identityMap[$id])) {
$record = $this->_identityMap[$id]; $record = $this->_identityMap[$id];
$record->hydrate($this->_data); $record->hydrate($data);
} else { } else {
$recordName = $this->getClassnameToReturn(); //$recordName = $this->getClassnameToReturn();
$record = new $recordName($this); //$record = new $recordName($this);
$record = new $this->_domainClassName($this, false, $data);
$this->_identityMap[$id] = $record; $this->_identityMap[$id] = $record;
} }
$this->_data = array(); $data = array();
} else { } else {
$recordName = $this->getClassnameToReturn(); //$recordName = $this->getClassnameToReturn();
$record = new $recordName($this, true); //$record = new $recordName($this, true);
$record = new $this->_domainClassName($this, true, $data);
} }
return $record; return $record;
@ -435,7 +431,7 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
* @return string The name of the class to create * @return string The name of the class to create
* *
*/ */
public function getClassnameToReturn() /*public function getClassnameToReturn()
{ {
$subClasses = $this->_table->getOption('subclasses'); $subClasses = $this->_table->getOption('subclasses');
if ( ! isset($subClasses)) { if ( ! isset($subClasses)) {
@ -457,7 +453,7 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
} }
} }
return $this->_domainClassName; return $this->_domainClassName;
} }*/
/** /**
* @param $id database row id * @param $id database row id
@ -472,15 +468,15 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
. ' WHERE ' . implode(' = ? && ', $identifierColumnNames) . ' = ?'; . ' WHERE ' . implode(' = ? && ', $identifierColumnNames) . ' = ?';
$query = $this->applyInheritance($query); $query = $this->applyInheritance($query);
$params = array_merge(array($id), array_values($this->getDiscriminatorColumn($this->_domainClassName))); $params = array_merge(array($id), array_values($this->getDiscriminatorColumn()));
$this->_data = $this->_conn->execute($query, $params)->fetch(PDO::FETCH_ASSOC); $data = $this->_conn->execute($query, $params)->fetch(PDO::FETCH_ASSOC);
if ($this->_data === false) { if ($data === false) {
return false; return false;
} }
} }
return $this->getRecord(); return $this->getRecord($data);
} }
/** /**
@ -490,7 +486,7 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
*/ */
final public function applyInheritance($where) final public function applyInheritance($where)
{ {
$inheritanceMap = $this->getDiscriminatorColumn($this->_domainClassName); $inheritanceMap = $this->getDiscriminatorColumn();
if ( ! empty($inheritanceMap)) { if ( ! empty($inheritanceMap)) {
$a = array(); $a = array();
foreach ($inheritanceMap as $field => $value) { foreach ($inheritanceMap as $field => $value) {
@ -523,30 +519,6 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
return $graph; return $graph;
} }
/**
* setData
* doctrine uses this function internally
* users are strongly discouraged to use this function
*
* @param array $data internal data
* @return void
*/
public function setData(array $data)
{
$this->_data = $data;
}
/**
* returns internal data, used by Doctrine_Record instances
* when retrieving data from database
*
* @return array
*/
public function getData()
{
return $this->_data;
}
/** /**
* prepareValue * prepareValue
* this method performs special data preparation depending on * this method performs special data preparation depending on
@ -728,12 +700,18 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
} }
/** /**
* Saves an entity and all it's related entities.
* *
* @param Doctrine_Record $record The entity to save.
* @param Doctrine_Connection $conn The connection to use. Will default to the mapper's
* connection.
* @throws Doctrine_Mapper_Exception If the mapper is unable to save the given record.
*/ */
public function saveGraph(Doctrine_Record $record, Doctrine_Connection $conn = null) public function save(Doctrine_Record $record, Doctrine_Connection $conn = null)
{ {
if ($this->_domainClassName != get_class($record)) { if ( ! ($record instanceof $this->_domainClassName)) {
echo "mismatch: " . $this->_domainClassName . " <-> " . get_class($record) . "<br />"; throw new Doctrine_Mapper_Exception("Mapper of type " . $this->_domainClassName . "
can't save instances of type" . get_class($record) . ".");
} }
if ($conn === null) { if ($conn === null) {
@ -798,9 +776,8 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
// save the MANY-TO-MANY associations // save the MANY-TO-MANY associations
$this->saveAssociations($record); $this->saveAssociations($record);
// reset state
$record->state($state); $record->state($state);
$conn->commit(); $conn->commit();
} catch (Exception $e) { } catch (Exception $e) {
// save() calls can be nested recursively and exceptions bubble up, so check // save() calls can be nested recursively and exceptions bubble up, so check
@ -815,14 +792,64 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
return true; return true;
} }
/**
* Inserts a single entity into the database, without any related entities.
*
* @param Doctrine_Record $record The entity to insert.
*/
protected function insertSingleRecord(Doctrine_Record $record)
{
$fields = $record->getPrepared();
if (empty($fields)) {
return false;
}
$table = $record->getTable();
$identifier = (array) $table->getIdentifier();
$seq = $table->getOption('sequenceName');
if ( ! empty($seq)) {
$id = $this->_conn->sequence->nextId($seq);
$seqName = $table->getIdentifier();
$fields[$seqName] = $id;
$record->assignIdentifier($id);
}
$this->_conn->insert($table, $fields);
if (empty($seq) && count($identifier) == 1 && $identifier[0] == $table->getIdentifier() &&
$table->getIdentifierType() != Doctrine::IDENTIFIER_NATURAL) {
if (strtolower($this->getName()) == 'pgsql') {
$seq = $table->getTableName() . '_' . $identifier[0];
}
$id = $this->_conn->sequence->lastInsertId($seq);
if ( ! $id) {
throw new Doctrine_Connection_Exception("Couldn't get last insert identifier.");
}
$record->assignIdentifier($id);
} else {
$record->assignIdentifier(true);
}
}
protected function _fireEvent($type, $callback, $invoker)
{
}
/** /**
* saves the given record * saves the given record
* *
* @param Doctrine_Record $record * @param Doctrine_Record $record
* @return void * @return void
*/ */
public function save(Doctrine_Record $record) public function saveSingleRecord(Doctrine_Record $record)
{ {
//$this->_fireEvent(Doctrine_Event::RECORD_SAVE, 'preSave', $record);
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_SAVE); $event = new Doctrine_Event($record, Doctrine_Event::RECORD_SAVE);
$record->preSave($event); $record->preSave($event);
$this->getRecordListener()->preSave($event); $this->getRecordListener()->preSave($event);
@ -925,7 +952,7 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
$assocRecord->set($assocTable->getFieldName($rel->getForeign()), $r); $assocRecord->set($assocTable->getFieldName($rel->getForeign()), $r);
$assocRecord->set($assocTable->getFieldName($rel->getLocal()), $record); $assocRecord->set($assocTable->getFieldName($rel->getLocal()), $record);
$this->save($assocRecord); $this->saveSingleRecord($assocRecord);
} }
} }
} }
@ -938,7 +965,7 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
* @return boolean whether or not the update was successful * @return boolean whether or not the update was successful
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper). * @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/ */
public function update(Doctrine_Record $record) protected function update(Doctrine_Record $record)
{ {
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_UPDATE); $event = new Doctrine_Event($record, Doctrine_Event::RECORD_UPDATE);
$record->preUpdate($event); $record->preUpdate($event);
@ -946,10 +973,7 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
$this->getRecordListener()->preUpdate($event); $this->getRecordListener()->preUpdate($event);
if ( ! $event->skipOperation) { if ( ! $event->skipOperation) {
$identifier = $record->identifier(); $this->_doUpdate($record);
$array = $record->getPrepared();
$this->_conn->update($table, $array, $identifier);
$record->assignIdentifier(true);
} }
$this->getRecordListener()->postUpdate($event); $this->getRecordListener()->postUpdate($event);
@ -958,22 +982,29 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
return true; return true;
} }
protected function _doUpdate(Doctrine_Record $record)
{
$identifier = $record->identifier();
$array = $record->getPrepared();
$this->_conn->update($this->_table, $array, $identifier);
$record->assignIdentifier(true);
}
/** /**
* inserts a record into database * inserts a record into database
* *
* @param Doctrine_Record $record record to be inserted * @param Doctrine_Record $record record to be inserted
* @return boolean * @return boolean
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/ */
public function insert(Doctrine_Record $record) protected function insert(Doctrine_Record $record)
{ {
// trigger event // trigger event
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_INSERT); $event = new Doctrine_Event($record, Doctrine_Event::RECORD_INSERT);
$record->preInsert($event); $record->preInsert($event);
$this->getRecordListener()->preInsert($event); $this->getRecordListener()->preInsert($event);
if ( ! $event->skipOperation) { if ( ! $event->skipOperation) {
$this->_conn->processSingleInsert($record); $this->_doInsert($record);
} }
// trigger event // trigger event
@ -984,9 +1015,95 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
return true; return true;
} }
public function delete(Doctrine_Record $record) protected function _doInsert(Doctrine_Record $record)
{ {
$this->insertSingleRecord($record);
}
/**
* deletes given record and all the related composites
* this operation is isolated by a transaction
*
* this event can be listened by the onPreDelete and onDelete listeners
*
* @return boolean true on success, false on failure
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/
public function delete(Doctrine_Record $record, Doctrine_Connection $conn = null)
{
if ( ! $record->exists()) {
return false;
}
if ( ! ($record instanceof $this->_domainClassName)) {
throw new Doctrine_Mapper_Exception("Mapper of type " . $this->_domainClassName . "
can't save instances of type" . get_class($record) . ".");
}
if ($conn == null) {
$conn = $this->_conn;
}
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_DELETE);
$record->preDelete($event);
$this->getRecordListener()->preDelete($event);
$table = $this->_table;
$state = $record->state();
$record->state(Doctrine_Record::STATE_LOCKED);
if ( ! $event->skipOperation) {
$this->_doDelete($record, $conn);
} else {
// return to original state
$record->state($state);
}
$this->getRecordListener()->postDelete($event);
$record->postDelete($event);
return true;
}
protected function _doDelete(Doctrine_Record $record, Doctrine_Connection $conn)
{
try {
$conn->beginInternalTransaction();
$this->deleteComposites($record);
$record->state(Doctrine_Record::STATE_TDIRTY);
$conn->delete($this->_table, $record->identifier());
$record->state(Doctrine_Record::STATE_TCLEAN);
$this->removeRecord($record);
$conn->commit();
} catch (Exception $e) {
$conn->rollback();
throw $e;
}
}
/**
* deletes all related composites
* this method is always called internally when a record is deleted
*
* @throws PDOException if something went wrong at database level
* @return void
*/
protected function deleteComposites(Doctrine_Record $record)
{
foreach ($this->_table->getRelations() as $fk) {
if ($fk->isComposite()) {
$obj = $record->get($fk->getAlias());
if ($obj instanceof Doctrine_Record &&
$obj->state() != Doctrine_Record::STATE_LOCKED) {
$obj->delete($this->_conn);
}
}
}
} }
public function executeQuery(Doctrine_Query $query) public function executeQuery(Doctrine_Query $query)
@ -998,15 +1115,10 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
{ {
return $this->_table; return $this->_table;
} }
public function getCustomJoins() public function getFieldName($columnName)
{ {
return array(); return $this->_table->getFieldName($columnName);
}
public function getDiscriminatorColumn($domainClassName)
{
return array();
} }
public function getFieldNames() public function getFieldNames()
@ -1014,15 +1126,14 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
if ($this->_fieldNames) { if ($this->_fieldNames) {
return $this->_fieldNames; return $this->_fieldNames;
} }
$this->_fieldNames = $this->_table->getFieldNames(); $this->_fieldNames = $this->_table->getFieldNames();
return $this->_table->getFieldNames(); return $this->_fieldNames;
} }
/*public function free() public function getOwningTable($fieldName)
{ {
unset($this->_table); return $this->_table;
}*/ }
public function getIdentityMap() public function getIdentityMap()
{ {
@ -1034,4 +1145,31 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
var_dump($this->_invokedMethods); var_dump($this->_invokedMethods);
} }
/*public function addToWhere($componentAlias, array &$sqlWhereParts, Doctrine_Query $query)
{
}
public function addToFrom($sqlString, Doctrine_Query $query)
{
}*/
/* Hooks used during SQL query construction to manipulate the query. */
public function getCustomJoins()
{
return array();
}
public function getCustomFields()
{
return array();
}
public function getDiscriminatorColumn()
{
return array();
}
} }

View File

@ -1,7 +1,8 @@
<?php <?php
class Doctrine_Mapper_Joined extends Doctrine_Mapper class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
{ {
protected $_columnNameFieldNameMap = array();
/** /**
* inserts a record into database * inserts a record into database
@ -10,7 +11,7 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
* @return boolean * @return boolean
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper). * @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/ */
public function insert(Doctrine_Record $record) protected function _doInsert(Doctrine_Record $record)
{ {
$table = $this->_table; $table = $this->_table;
@ -19,19 +20,39 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
$classes = $table->getOption('joinedParents'); $classes = $table->getOption('joinedParents');
array_unshift($classes, $component); array_unshift($classes, $component);
foreach (array_reverse($classes) as $k => $parent) { try {
if ($k === 0) { $this->_conn->beginInternalTransaction();
$rootRecord = new $parent(); $identifier = null;
$rootRecord->merge($dataSet[$parent]); foreach (array_reverse($classes) as $k => $parent) {
parent::insert($rootRecord); $parentTable = $this->_conn->getTable($parent);
$record->assignIdentifier($rootRecord->identifier()); if ($k == 0) {
} else { $identifierType = $parentTable->getIdentifierType();
foreach ((array) $rootRecord->identifier() as $id => $value) { if ($identifierType == Doctrine::IDENTIFIER_AUTOINC) {
$dataSet[$parent][$id] = $value; $this->_conn->insert($parentTable, $dataSet[$parent]);
$identifier = $this->_conn->sequence->lastInsertId();
} else if ($identifierType == Doctrine::IDENTIFIER_SEQUENCE) {
$seq = $record->getTable()->getOption('sequenceName');
if ( ! empty($seq)) {
$identifier = $this->_conn->sequence->nextId($seq);
$dataSet[$parent][$parentTable->getIdentifier()] = $identifier;
$this->_conn->insert($parentTable, $dataSet[$parent]);
}
} else {
throw new Doctrine_Mapper_Exception("Unsupported identifier type '$identifierType'.");
}
$record->assignIdentifier($identifier);
} else {
foreach ((array) $record->identifier() as $id => $value) {
$dataSet[$parent][$id] = $value;
}
$this->_conn->insert($parentTable, $dataSet[$parent]);
} }
$this->_conn->insert($this->_conn->getTable($parent), $dataSet[$parent]);
} }
$this->_conn->commit();
} catch (Exception $e) {
$this->_conn->rollback();
throw $e;
} }
return true; return true;
@ -44,39 +65,58 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
* @return boolean whether or not the update was successful * @return boolean whether or not the update was successful
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper). * @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/ */
public function update(Doctrine_Record $record) protected function _doUpdate(Doctrine_Record $record)
{ {
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_UPDATE);
$record->preUpdate($event);
$table = $this->_table; $table = $this->_table;
$this->getRecordListener()->preUpdate($event); $identifier = $record->identifier();
$dataSet = $this->_formatDataSet($record);
$component = $table->getComponentName();
$classes = $table->getOption('joinedParents');
array_unshift($classes, $component);
if ( ! $event->skipOperation) { foreach ($record as $field => $value) {
$identifier = $record->identifier(); if ($value instanceof Doctrine_Record) {
$dataSet = $this->_formatDataSet($record); if ( ! $value->exists()) {
$component = $table->getComponentName(); $value->save();
$classes = $table->getOption('joinedParents');
array_unshift($classes, $component);
foreach ($record as $field => $value) {
if ($value instanceof Doctrine_Record) {
if ( ! $value->exists()) {
$value->save();
}
$record->set($field, $value->getIncremented());
} }
$record->set($field, $value->getIncremented());
} }
}
foreach (array_reverse($classes) as $class) { foreach (array_reverse($classes) as $class) {
$parentTable = $this->_conn->getTable($class); $parentTable = $this->_conn->getTable($class);
$this->_conn->update($parentTable, $dataSet[$class], $identifier); $this->_conn->update($parentTable, $dataSet[$class], $identifier);
}
$record->assignIdentifier(true);
} }
$this->getRecordListener()->postUpdate($event); $record->assignIdentifier(true);
$record->postUpdate($event);
return true;
}
protected function _doDelete(Doctrine_Record $record, Doctrine_Connection $conn)
{
try {
$table = $this->_table;
$conn->beginInternalTransaction();
$this->deleteComposites($record);
$record->state(Doctrine_Record::STATE_TDIRTY);
foreach ($table->getOption('joinedParents') as $parent) {
$parentTable = $conn->getTable($parent);
$conn->delete($parentTable, $record->identifier());
}
$conn->delete($table, $record->identifier());
$record->state(Doctrine_Record::STATE_TCLEAN);
$this->removeRecord($record);
$conn->commit();
} catch (Exception $e) {
$conn->rollback();
throw $e;
}
return true; return true;
} }
@ -87,13 +127,33 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
*/ */
public function getCustomJoins() public function getCustomJoins()
{ {
return $this->_table->getOption('joinedParents'); $customJoins = array();
foreach ($this->_table->getOption('joinedParents') as $parentClass) {
$customJoins[$parentClass] = 'INNER';
}
foreach ((array)$this->_table->getOption('subclasses') as $subClass) {
if ($subClass != $this->_domainClassName) {
$customJoins[$subClass] = 'LEFT';
}
}
return $customJoins;
}
public function getCustomFields()
{
$fields = array();
if ($this->_table->getOption('subclasses')) {
foreach ($this->_table->getOption('subclasses') as $subClass) {
$fields = array_merge($this->_conn->getTable($subClass)->getFieldNames(), $fields);
}
}
return array_unique($fields);
} }
/** /**
* *
*/ */
public function getDiscriminatorColumn($domainClassName) public function getDiscriminatorColumn()
{ {
$joinedParents = $this->_table->getOption('joinedParents'); $joinedParents = $this->_table->getOption('joinedParents');
if (count($joinedParents) <= 0) { if (count($joinedParents) <= 0) {
@ -101,7 +161,7 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
} else { } else {
$inheritanceMap = $this->_conn->getTable(array_pop($joinedParents))->getOption('inheritanceMap'); $inheritanceMap = $this->_conn->getTable(array_pop($joinedParents))->getOption('inheritanceMap');
} }
return isset($inheritanceMap[$domainClassName]) ? $inheritanceMap[$domainClassName] : array(); return isset($inheritanceMap[$this->_domainClassName]) ? $inheritanceMap[$this->_domainClassName] : array();
} }
/** /**
@ -115,14 +175,67 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
$fieldNames = $this->_table->getFieldNames(); $fieldNames = $this->_table->getFieldNames();
foreach ($this->_table->getOption('joinedParents') as $parent) { foreach ($this->_table->getOption('joinedParents') as $parent) {
$fieldNames = array_merge($this->_conn->getTable($parent)->getFieldNames(), $parentTable = $this->_conn->getTable($parent);
$fieldNames); $fieldNames = array_merge($parentTable->getFieldNames(), $fieldNames);
} }
$this->_fieldNames = $fieldNames; $this->_fieldNames = array_unique($fieldNames);
return $fieldNames; return $fieldNames;
} }
public function getFieldName($columnName)
{
if (isset($this->_columnNameFieldNameMap[$columnName])) {
return $this->_columnNameFieldNameMap[$columnName];
}
if ($this->_table->hasColumn($columnName)) {
$this->_columnNameFieldNameMap[$columnName] = $this->_table->getFieldName($columnName);
return $this->_columnNameFieldNameMap[$columnName];
}
foreach ($this->_table->getOption('joinedParents') as $parentClass) {
$parentTable = $this->_conn->getTable($parentClass);
if ($parentTable->hasColumn($columnName)) {
$this->_columnNameFieldNameMap[$columnName] = $parentTable->getFieldName($columnName);
return $this->_columnNameFieldNameMap[$columnName];
}
}
foreach ((array)$this->_table->getOption('subclasses') as $subClass) {
$subTable = $this->_conn->getTable($subClass);
if ($subTable->hasColumn($columnName)) {
$this->_columnNameFieldNameMap[$columnName] = $subTable->getFieldName($columnName);
return $this->_columnNameFieldNameMap[$columnName];
}
}
throw new Doctrine_Mapper_Exception("No field name found for column name '$columnName'.");
}
public function getOwningTable($fieldName)
{
if ($this->_table->hasField($fieldName)) {
return $this->_table;
}
foreach ($this->_table->getOption('joinedParents') as $parentClass) {
$parentTable = $this->_conn->getTable($parentClass);
if ($parentTable->hasField($fieldName)) {
return $parentTable;
}
}
foreach ((array)$this->_table->getOption('subclasses') as $subClass) {
$subTable = $this->_conn->getTable($subClass);
if ($subTable->hasField($fieldName)) {
return $subTable;
}
}
throw new Doctrine_Mapper_Exception("Unable to find owner of field '$fieldName'.");
}
/** /**
* *
*/ */

View File

@ -1,15 +1,63 @@
<?php <?php
class Doctrine_Mapper_SingleTable extends Doctrine_Mapper class Doctrine_Mapper_SingleTable extends Doctrine_Mapper_Abstract
{ {
public function getDiscriminatorColumn($domainClassName) public function getDiscriminatorColumn()
{ {
$inheritanceMap = $this->_table->getOption('inheritanceMap'); $inheritanceMap = $this->_table->getOption('inheritanceMap');
return isset($inheritanceMap[$domainClassName]) ? $inheritanceMap[$domainClassName] : array(); return isset($inheritanceMap[$this->_domainClassName]) ? $inheritanceMap[$this->_domainClassName] : array();
} }
/*public function addToWhere($componentAlias, array &$sqlWhereParts, Doctrine_Query $query)
{
$array = array();
$componentParts = $query->getQueryComponent($componentAlias);
$sqlTableAlias = $query->getSqlTableAlias($componentAlias);
$array[$sqlTableAlias][] = $this->getDiscriminatorColumn();
// apply inheritance maps
$str = '';
$c = array();
$index = 0;
foreach ($array as $tableAlias => $maps) {
$a = array();
// don't use table aliases if the query isn't a select query
if ($query->getType() !== Doctrine_Query::SELECT) {
$tableAlias = '';
} else {
$tableAlias .= '.';
}
foreach ($maps as $map) {
$b = array();
foreach ($map as $field => $value) {
$identifier = $this->_conn->quoteIdentifier($tableAlias . $field);
if ($index > 0) {
$b[] = '(' . $identifier . ' = ' . $this->_conn->quote($value)
. ' OR ' . $identifier . ' IS NULL)';
} else {
$b[] = $identifier . ' = ' . $this->_conn->quote($value);
}
}
if ( ! empty($b)) {
$a[] = implode(' AND ', $b);
}
}
if ( ! empty($a)) {
$c[] = implode(' AND ', $a);
}
$index++;
}
$str .= implode(' AND ', $c);
return $str;
}*/
} }

View File

@ -1,6 +1,6 @@
<?php <?php
class Doctrine_Mapper_TablePerClass extends Doctrine_Mapper class Doctrine_Mapper_TablePerClass extends Doctrine_Mapper_Abstract
{ {

View File

@ -399,55 +399,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
throw new Doctrine_Query_Exception('Unknown aggregate alias: ' . $dqlAlias); throw new Doctrine_Query_Exception('Unknown aggregate alias: ' . $dqlAlias);
} }
} }
/**
* parseQueryPart
* parses given DQL query part
*
* @param string $queryPartName the name of the query part
* @param string $queryPart query part to be parsed
* @param boolean $append whether or not to append the query part to its stack
* if false is given, this method will overwrite
* the given query part stack with $queryPart
* @return Doctrine_Query this object
*/
/*protected function parseQueryPart($queryPartName, $queryPart, $append = false)
{
if ($this->_state === self::STATE_LOCKED) {
throw new Doctrine_Query_Exception('This query object is locked. No query parts can be manipulated.');
}
// sanity check
if ($queryPart === '' || $queryPart === null) {
throw new Doctrine_Query_Exception('Empty ' . $queryPartName . ' part given.');
}
// add query part to the dql part array
if ($append) {
$this->_dqlParts[$queryPartName][] = $queryPart;
} else {
$this->_dqlParts[$queryPartName] = array($queryPart);
}
if ($this->_state === self::STATE_DIRECT) {
$parser = $this->_getParser($queryPartName);
$sql = $parser->parse($queryPart);
if (isset($sql)) {
if ($append) {
$this->addSqlQueryPart($queryPartName, $sql);
} else {
$this->setSqlQueryPart($queryPartName, $sql);
}
}
}
$this->_state = Doctrine_Query::STATE_DIRTY;
return $this;
}*/
/** /**
* getDqlPart * getDqlPart
* returns a specific DQL query part. * returns a specific DQL query part.
@ -480,8 +432,9 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
*/ */
public function processPendingFields($componentAlias) public function processPendingFields($componentAlias)
{ {
$tableAlias = $this->getTableAlias($componentAlias); $tableAlias = $this->getSqlTableAlias($componentAlias);
$table = $this->_queryComponents[$componentAlias]['table']; $baseTable = $this->_queryComponents[$componentAlias]['table'];
$mapper = $this->_queryComponents[$componentAlias]['mapper'];
if ( ! isset($this->_pendingFields[$componentAlias])) { if ( ! isset($this->_pendingFields[$componentAlias])) {
return; return;
@ -489,41 +442,39 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$fields = $this->_pendingFields[$componentAlias]; $fields = $this->_pendingFields[$componentAlias];
// check for wildcards // check for wildcards
if (in_array('*', $fields)) { if (in_array('*', $fields)) {
//echo "<br />";Doctrine::dump($table->getColumnNames()); echo "<br />"; $fields = $mapper->getFieldNames();
$fields = $table->getFieldNames();
} else { } else {
// only auto-add the primary key fields if this query object is not // only auto-add the primary key fields if this query object is not
// a subquery of another query object // a subquery of another query object
if ( ! $this->_isSubquery) { if ( ! $this->_isSubquery) {
$fields = array_unique(array_merge((array) $table->getIdentifier(), $fields)); $fields = array_unique(array_merge((array) $baseTable->getIdentifier(), $fields));
} }
} }
$fields = array_unique(array_merge($fields, $mapper->getCustomFields()));
$sql = array(); $sql = array();
foreach ($fields as $fieldName) { foreach ($fields as $fieldName) {
$columnName = $table->getColumnName($fieldName); $table = $mapper->getOwningTable($fieldName);
if (($owner = $table->getColumnOwner($columnName)) !== null && if ($table !== $baseTable) {
$owner !== $table->getComponentName()) { $tableAlias = $this->getSqlTableAlias($componentAlias . '.' . $table->getComponentName());
$parent = $this->_conn->getTable($owner);
$columnName = $parent->getColumnName($fieldName);
$parentAlias = $this->getTableAlias($componentAlias . '.' . $parent->getComponentName());
$sql[] = $this->_conn->quoteIdentifier($parentAlias . '.' . $columnName)
. ' AS '
. $this->_conn->quoteIdentifier($tableAlias . '__' . $columnName);
} else { } else {
$columnName = $table->getColumnName($fieldName); $tableAlias = $this->getSqlTableAlias($componentAlias);
$sql[] = $this->_conn->quoteIdentifier($tableAlias . '.' . $columnName) }
. ' AS '
. $this->_conn->quoteIdentifier($tableAlias . '__' . $columnName); $columnName = $table->getColumnName($fieldName);
$columnName = $table->getColumnName($fieldName);
$sql[] = $this->_conn->quoteIdentifier($tableAlias . '.' . $columnName)
. ' AS '
. $this->_conn->quoteIdentifier($this->getSqlTableAlias($componentAlias) . '__' . $columnName);
if ( ! in_array($tableAlias, $this->_neededTables)) {
$this->_neededTables[] = $tableAlias;
} }
} }
$this->_neededTables[] = $tableAlias;
//Doctrine::dump(implode(', ', $sql));
//echo "<br /><br />";
return implode(', ', $sql); return implode(', ', $sql);
} }
@ -617,7 +568,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
// check for DISTINCT keyword // check for DISTINCT keyword
if ($first === 'DISTINCT') { if ($first === 'DISTINCT') {
$this->_sqlParts['distinct'] = true; $this->_sqlParts['distinct'] = true;
$refs[0] = substr($refs[0], ++$pos); $refs[0] = substr($refs[0], ++$pos);
} }
@ -632,7 +582,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$terms = $this->_tokenizer->sqlExplode($reference, ' '); $terms = $this->_tokenizer->sqlExplode($reference, ' ');
$pos = strpos($terms[0], '('); $pos = strpos($terms[0], '(');
if (count($terms) > 1 || $pos !== false) { if (count($terms) > 1 || $pos !== false) {
$expression = array_shift($terms); $expression = array_shift($terms);
@ -647,7 +597,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$tableAlias = $this->getTableAlias($componentAlias); $tableAlias = $this->getTableAlias($componentAlias);
$index = count($this->_aggregateAliasMap); $index = count($this->_aggregateAliasMap);
$sqlAlias = $this->_conn->quoteIdentifier($tableAlias . '__' . $index); $sqlAlias = $this->_conn->quoteIdentifier($tableAlias . '__' . $index);
@ -670,7 +620,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$componentAlias = key($this->_queryComponents); $componentAlias = key($this->_queryComponents);
$field = $e[0]; $field = $e[0];
} }
$this->_pendingFields[$componentAlias][] = $field; $this->_pendingFields[$componentAlias][] = $field;
} }
} }
@ -1156,7 +1105,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
} }
// append discriminator column conditions (if any) // append discriminator column conditions (if any)
$string = $this->_createDiscriminatorSql(); $string = $this->_createDiscriminatorConditionSql();
//echo "orig:$string<br /><br />";
if ( ! empty($string)) { if ( ! empty($string)) {
if (substr($string, 0, 1) === '(' && substr($string, -1) === ')') { if (substr($string, 0, 1) === '(' && substr($string, -1) === ')') {
$this->_sqlParts['where'][] = $string; $this->_sqlParts['where'][] = $string;
@ -1482,23 +1432,21 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$componentAlias = $prevPath; $componentAlias = $prevPath;
} }
// if the current alias already exists, skip it // if the current alias already exists, it's user error
if (isset($this->_queryComponents[$componentAlias])) { if (isset($this->_queryComponents[$componentAlias])) {
continue; throw new Doctrine_Query_Exception("Duplicate alias '$componentAlias' in query.");
} }
if ( ! isset($table)) { if ( ! isset($table)) {
// process the root of the path // process the root of the path
$table = $this->loadRoot($name, $componentAlias); $table = $this->loadRoot($name, $componentAlias);
} else { } else {
$join = ($delimeter == ':') ? 'INNER JOIN ' : 'LEFT JOIN '; $join = ($delimeter == ':') ? 'INNER JOIN ' : 'LEFT JOIN ';
//echo "!!!!!!" . $prevPath . "!!!!!<br />";
$relation = $table->getRelation($name); $relation = $table->getRelation($name);
$localTable = $table; $localTable = $table;
$table = $relation->getTable(); $table = $relation->getTable();
//echo "<br /><br />" . $table->getComponentName() . "------" . $relation->getForeignComponentName() . "<br /><br />"; //echo "<br /><br />" . $table->getComponentName() . "------" . $relation->getForeignComponentName() . "<br /><br />";
$this->_queryComponents[$componentAlias] = array( $this->_queryComponents[$componentAlias] = array(
'table' => $table, 'table' => $table,
'mapper' => $this->_conn->getMapper($relation->getForeignComponentName()), 'mapper' => $this->_conn->getMapper($relation->getForeignComponentName()),
@ -1536,7 +1484,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
} }
$assocPath = $prevPath . '.' . $asf->getComponentName(); $assocPath = $prevPath . '.' . $asf->getComponentName();
//var_dump($name); echo "hrrrr";
//echo "<br /><br />" . $asf->getComponentName() . "---2---" . $relation->getForeignComponentName() . "<br /><br />"; //echo "<br /><br />" . $asf->getComponentName() . "---2---" . $relation->getForeignComponentName() . "<br /><br />";
$this->_queryComponents[$assocPath] = array( $this->_queryComponents[$assocPath] = array(
'parent' => $prevPath, 'parent' => $prevPath,
@ -1592,7 +1539,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
} }
} }
} else { } else {
$queryPart = $join . $foreignSql; $queryPart = $join . $foreignSql;
if ( ! $overrideJoin) { if ( ! $overrideJoin) {
@ -1632,8 +1578,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
if (isset($e[1])) { if (isset($e[1])) {
$indexBy = $e[1]; $indexBy = $e[1];
} }
} else if ($mapper->getBoundQueryPart('indexBy') !== null) { } else if ($table->getBoundQueryPart('indexBy') !== null) {
$indexBy = $mapper->getBoundQueryPart('indexBy'); $indexBy = $table->getBoundQueryPart('indexBy');
} }
if ($indexBy !== null) { if ($indexBy !== null) {
@ -1733,7 +1679,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$q .= ' FROM ' . $this->_buildSqlFromPart(); $q .= ' FROM ' . $this->_buildSqlFromPart();
// append discriminator column conditions (if any) // append discriminator column conditions (if any)
$string = $this->_createDiscriminatorSql(); $string = $this->_createDiscriminatorConditionSql();
if ( ! empty($string)) { if ( ! empty($string)) {
$where[] = $string; $where[] = $string;
} }

View File

@ -532,11 +532,11 @@ abstract class Doctrine_Query_Abstract
$tableAlias = $this->getSqlTableAlias($componentAlias, $table->getTableName()); $tableAlias = $this->getSqlTableAlias($componentAlias, $table->getTableName());
$customJoins = $this->_conn->getMapper($componentName)->getCustomJoins(); $customJoins = $this->_conn->getMapper($componentName)->getCustomJoins();
$sql = ''; $sql = '';
foreach ($customJoins as $componentName) { foreach ($customJoins as $componentName => $joinType) {
$joinedTable = $this->_conn->getTable($componentName); $joinedTable = $this->_conn->getTable($componentName);
$joinedAlias = $componentAlias . '.' . $componentName; $joinedAlias = $componentAlias . '.' . $componentName;
$joinedTableAlias = $this->getSqlTableAlias($joinedAlias, $joinedTable->getTableName()); $joinedTableAlias = $this->getSqlTableAlias($joinedAlias, $joinedTable->getTableName());
$sql .= ' LEFT JOIN ' . $this->_conn->quoteIdentifier($joinedTable->getTableName()) $sql .= " $joinType JOIN " . $this->_conn->quoteIdentifier($joinedTable->getTableName())
. ' ' . $this->_conn->quoteIdentifier($joinedTableAlias) . ' ON '; . ' ' . $this->_conn->quoteIdentifier($joinedTableAlias) . ' ON ';
foreach ($table->getIdentifierColumnNames() as $column) { foreach ($table->getIdentifierColumnNames() as $column) {
@ -556,23 +556,16 @@ abstract class Doctrine_Query_Abstract
* *
* @return string The created SQL snippet. * @return string The created SQL snippet.
*/ */
protected function _createDiscriminatorSql() protected function _createDiscriminatorConditionSql()
{ {
$array = array(); $array = array();
foreach ($this->_queryComponents as $componentAlias => $data) { foreach ($this->_queryComponents as $componentAlias => $data) {
$tableAlias = $this->getSqlTableAlias($componentAlias); $sqlTableAlias = $this->getSqlTableAlias($componentAlias);
//echo $data['table']->getComponentName() . " -- "; if ( ! $data['mapper'] instanceof Doctrine_Mapper_SingleTable) {
/*if (!isset($data['mapper'])) { $array[$sqlTableAlias][] = array();
//echo $data['table']->getComponentName(); } else {
echo $this->getDql(); $array[$sqlTableAlias][] = $data['mapper']->getDiscriminatorColumn();
}*/ }
/*if ($data['mapper']->getComponentName() != $data['table']->getComponentName()) {
//echo $this->getDql() . "<br />";
}*/
//echo $data['mapper']->getComponentName() . "_<br />";
//var_dump($data['mapper']->getDiscriminatorColumn($data['mapper']->getComponentName()));
$array[$tableAlias][] = $data['mapper']->getDiscriminatorColumn($data['mapper']->getComponentName());
} }
//var_dump($array); //var_dump($array);
// apply inheritance maps // apply inheritance maps

View File

@ -238,7 +238,7 @@ class Doctrine_RawSql extends Doctrine_Query_Abstract
} }
} }
$string = $this->_createDiscriminatorSql(); $string = $this->_createDiscriminatorConditionSql();
if ( ! empty($string)) { if ( ! empty($string)) {
$this->_sqlParts['where'][] = $string; $this->_sqlParts['where'][] = $string;
} }

View File

@ -146,7 +146,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* open connections * open connections
* @throws Doctrine_Record_Exception if the cleanData operation fails somehow * @throws Doctrine_Record_Exception if the cleanData operation fails somehow
*/ */
public function __construct($mapper = null, $isNewEntry = false) public function __construct($mapper = null, $isNewEntry = false, array $data = array())
{ {
//echo get_class($this) . "<br />"; //echo get_class($this) . "<br />";
if (isset($mapper) && $mapper instanceof Doctrine_Table) { if (isset($mapper) && $mapper instanceof Doctrine_Table) {
@ -155,18 +155,10 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
//$this->_mapper = Doctrine_Manager::getInstance()->getMapper(get_class($this)); //$this->_mapper = Doctrine_Manager::getInstance()->getMapper(get_class($this));
$exists = ! $isNewEntry; $exists = ! $isNewEntry;
return; return;
} else if (isset($mapper) && $mapper instanceof Doctrine_Mapper) { } else if (isset($mapper) && $mapper instanceof Doctrine_Mapper_Abstract) {
//echo "two<br />"; //echo "two<br />";
$class = get_class($this); $class = get_class($this);
$this->_mapper = Doctrine_Manager::getInstance()->getMapper($class); $this->_mapper = Doctrine_Manager::getInstance()->getMapper($class);
if ($class != $this->_mapper->getComponentName()) {
try {
throw new Exception("ddd");
} catch (Exception $e) {
echo "MISMATCH: " . get_class($this) . "---" . $mapper->getComponentName();
echo $e->getTraceAsString() . "<br /><br />";
}
}
$this->_table = $this->_mapper->getTable(); $this->_table = $this->_mapper->getTable();
$exists = ! $isNewEntry; $exists = ! $isNewEntry;
} else { } else {
@ -182,7 +174,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
self::$_index++; self::$_index++;
// get the data array // get the data array
$this->_data = $this->_mapper->getData(); $this->_data = $data;
// get the column count // get the column count
$count = count($this->_data); $count = count($this->_data);
@ -202,7 +194,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$this->assignDefaultValues(); $this->assignDefaultValues();
} else { } else {
$this->_state = Doctrine_Record::STATE_CLEAN; $this->_state = Doctrine_Record::STATE_CLEAN;
// @TODO table->getColumnCount is not correct in CTI
if ($count < $this->_table->getColumnCount()) { if ($count < $this->_table->getColumnCount()) {
$this->_state = Doctrine_Record::STATE_PROXY; $this->_state = Doctrine_Record::STATE_PROXY;
} }
@ -213,7 +205,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$repository->add($this); $repository->add($this);
$this->construct(); $this->construct();
} }
/** /**
@ -256,11 +247,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
{ {
return $this->_oid; return $this->_oid;
} }
public function oid()
{
return $this->_oid;
}
/** /**
* isValid * isValid
@ -534,22 +520,22 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
} }
/** /**
* serialize * Serializes the entity.
* this method is automatically called when this Doctrine_Record is serialized * This method is automatically called when the entity is serialized.
*
* Part of the implementation of the Serializable interface.
* *
* @return array * @return array
*/ */
public function serialize() public function serialize()
{ {
$event = new Doctrine_Event($this, Doctrine_Event::RECORD_SERIALIZE); $event = new Doctrine_Event($this, Doctrine_Event::RECORD_SERIALIZE);
$this->preSerialize($event); $this->preSerialize($event);
$vars = get_object_vars($this); $vars = get_object_vars($this);
unset($vars['_references']); unset($vars['_references']);
unset($vars['_mapper']); unset($vars['_mapper']);
//unset($vars['_table']);
unset($vars['_errorStack']); unset($vars['_errorStack']);
unset($vars['_filter']); unset($vars['_filter']);
unset($vars['_node']); unset($vars['_node']);
@ -586,8 +572,8 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
} }
/** /**
* unseralize * Reconstructs the entity from it's serialized form.
* this method is automatically called everytime a Doctrine_Record object is unserialized * This method is automatically called everytime the entity is unserialized.
* *
* @param string $serialized Doctrine_Record as serialized string * @param string $serialized Doctrine_Record as serialized string
* @throws Doctrine_Record_Exception if the cleanData operation fails somehow * @throws Doctrine_Record_Exception if the cleanData operation fails somehow
@ -634,6 +620,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$this->_mapper->getRepository()->add($this); $this->_mapper->getRepository()->add($this);
$this->cleanData($this->_data); $this->cleanData($this->_data);
$this->prepareIdentifiers($this->exists()); $this->prepareIdentifiers($this->exists());
$this->postUnserialize($event); $this->postUnserialize($event);
} }
@ -676,7 +663,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
} }
if ($err) { if ($err) {
throw new Doctrine_Record_Exception('Unknown record state ' . $state); throw new Doctrine_Record_Exception("Unknown record state '$state'.");
} }
} }
@ -863,12 +850,8 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
if ( ! isset($this->_references[$fieldName]) && $load) { if ( ! isset($this->_references[$fieldName]) && $load) {
$rel = $this->_table->getRelation($fieldName); $rel = $this->_table->getRelation($fieldName);
$this->_references[$fieldName] = $rel->fetchRelatedFor($this); $this->_references[$fieldName] = $rel->fetchRelatedFor($this);
/*if (count($this->_references[$fieldName]) > 0) {
echo $this->_references[$fieldName][0]->state() . "<br />";
}*/
} }
return $this->_references[$fieldName]; return $this->_references[$fieldName];
} catch (Doctrine_Table_Exception $e) { } catch (Doctrine_Table_Exception $e) {
//echo $e->getTraceAsString(); //echo $e->getTraceAsString();
//echo "<br /><br />"; //echo "<br /><br />";
@ -937,12 +920,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$this->_modified[] = $fieldName; $this->_modified[] = $fieldName;
switch ($this->_state) { switch ($this->_state) {
case Doctrine_Record::STATE_CLEAN: case Doctrine_Record::STATE_CLEAN:
/*try {
throw new Exception();
} catch (Exception $e) {
echo $e->getTraceAsString() . "<br /><br />";
}
echo "setting dirty ... <br />";*/
$this->_state = Doctrine_Record::STATE_DIRTY; $this->_state = Doctrine_Record::STATE_DIRTY;
break; break;
case Doctrine_Record::STATE_TCLEAN: case Doctrine_Record::STATE_TCLEAN:
@ -1004,7 +981,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
} }
} }
} }
} else if ($rel instanceof Doctrine_Relation_Association) { } else if ($rel instanceof Doctrine_Relation_Association) {
// join table relation found // join table relation found
if ( ! ($value instanceof Doctrine_Collection)) { if ( ! ($value instanceof Doctrine_Collection)) {
@ -1070,7 +1046,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
*/ */
public function save(Doctrine_Connection $conn = null) public function save(Doctrine_Connection $conn = null)
{ {
$this->_mapper->saveGraph($this, $conn); $this->_mapper->save($this, $conn);
} }
/** /**
@ -1209,7 +1185,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
} }
} }
//$map = $this->_table->getOption('inheritanceMap'); //$map = $this->_table->getOption('inheritanceMap');
$map = $this->_mapper->getDiscriminatorColumn($this->_domainClassName); $map = $this->_mapper->getDiscriminatorColumn();
foreach ($map as $k => $v) { foreach ($map as $k => $v) {
$old = $this->get($k, false); $old = $this->get($k, false);
if ((string) $old !== (string) $v || $old === null) { if ((string) $old !== (string) $v || $old === null) {
@ -1225,6 +1201,8 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* count * count
* this class implements countable interface * this class implements countable interface
* *
* Implementation of the Countable interface.
*
* @return integer the number of columns in this record * @return integer the number of columns in this record
*/ */
public function count() public function count()
@ -1436,10 +1414,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
*/ */
public function delete(Doctrine_Connection $conn = null) public function delete(Doctrine_Connection $conn = null)
{ {
if ($conn == null) { return $this->_mapper->delete($this, $conn);
$conn = $this->_mapper->getConnection();
}
return $conn->unitOfWork->delete($this);
} }
/** /**

View File

@ -107,7 +107,10 @@ class Doctrine_Relation_Association extends Doctrine_Relation
public function fetchRelatedFor(Doctrine_Record $record) public function fetchRelatedFor(Doctrine_Record $record)
{ {
$id = $record->getIncremented(); $id = $record->getIncremented();
//var_dump($id);
//echo "<br /><br />";
if (empty($id) || ! $this->_foreignMapper->getAttribute(Doctrine::ATTR_LOAD_REFERENCES)) { if (empty($id) || ! $this->_foreignMapper->getAttribute(Doctrine::ATTR_LOAD_REFERENCES)) {
//echo "here" . $this->_foreignMapper->getAttribute(Doctrine::ATTR_LOAD_REFERENCES);
$coll = new Doctrine_Collection($this->getForeignComponentName()); $coll = new Doctrine_Collection($this->getForeignComponentName());
} else { } else {
$query = Doctrine_Query::create()->parseQuery($this->getRelationDql(1)); $query = Doctrine_Query::create()->parseQuery($this->getRelationDql(1));

View File

@ -47,10 +47,8 @@ class Doctrine_Sequence_Mysql extends Doctrine_Sequence
$query = 'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES (NULL)'; $query = 'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES (NULL)';
try { try {
$this->conn->exec($query); $this->conn->exec($query);
} catch (Doctrine_Connection_Exception $e) {
} catch(Doctrine_Connection_Exception $e) {
if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) { if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) {
try { try {
$this->conn->export->createSequence($seqName); $this->conn->export->createSequence($seqName);

View File

@ -47,7 +47,7 @@ class Doctrine_Sequence_Pgsql extends Doctrine_Sequence
$query = "SELECT NEXTVAL('" . $sequenceName . "')"; $query = "SELECT NEXTVAL('" . $sequenceName . "')";
try { try {
$result = (int) $this->conn->fetchOne($query); $result = (int) $this->conn->fetchOne($query);
} catch(Doctrine_Connection_Exception $e) { } catch (Doctrine_Connection_Exception $e) {
if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) { if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) {
try { try {
@ -70,6 +70,7 @@ class Doctrine_Sequence_Pgsql extends Doctrine_Sequence
* @param string name of the table into which a new row was inserted * @param string name of the table into which a new row was inserted
* @param string name of the field into which a new row was inserted * @param string name of the field into which a new row was inserted
* @return integer the autoincremented id * @return integer the autoincremented id
* @todo Why not use $this->conn->getDbh()->lastInsertId($sequenceName) ?
*/ */
public function lastInsertId($table = null, $field = null) public function lastInsertId($table = null, $field = null)
{ {

View File

@ -437,6 +437,11 @@ class Doctrine_Table extends Doctrine_Configurable implements Serializable
$fieldName = $parts[0]; $fieldName = $parts[0];
} }
$name = strtolower($parts[0]); $name = strtolower($parts[0]);
if (isset($this->_columnNames[$fieldName])) {
return;
}
if ($prepend) { if ($prepend) {
$this->_columnNames = array_merge(array($fieldName => $name), $this->_columnNames); $this->_columnNames = array_merge(array($fieldName => $name), $this->_columnNames);
$this->_fieldNames = array_merge(array($name => $fieldName), $this->_fieldNames); $this->_fieldNames = array_merge(array($name => $fieldName), $this->_fieldNames);
@ -493,6 +498,8 @@ class Doctrine_Table extends Doctrine_Configurable implements Serializable
if (isset($options['default'])) { if (isset($options['default'])) {
$this->hasDefaultValues = true; $this->hasDefaultValues = true;
} }
$this->columnCount++;
} }
/** /**
@ -633,11 +640,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Serializable
{ {
return $this->columnCount; return $this->columnCount;
} }
public function setColumnCount($count)
{
$this->columnCount = $count;
}
/** /**
* returns all columns and their definitions * returns all columns and their definitions

View File

@ -200,11 +200,9 @@ class Doctrine_Table_Factory
$table->setOption('declaringClass', $class); $table->setOption('declaringClass', $class);
// set the table definition for the given tree implementation // set the table definition for the given tree implementation
if ($table->isTree()) { /*if ($table->isTree()) {
$table->getTree()->setTableDefinition(); $table->getTree()->setTableDefinition();
} }*/
$table->setColumnCount(count($table->getColumns()));
$tableName = $table->getOption('tableName'); $tableName = $table->getOption('tableName');
if ( ! isset($tableName)) { if ( ! isset($tableName)) {
@ -217,9 +215,9 @@ class Doctrine_Table_Factory
$record->setUp(); $record->setUp();
// if tree, set up tree relations // if tree, set up tree relations
if ($table->isTree()) { /*if ($table->isTree()) {
$table->getTree()->setUp(); $table->getTree()->setUp();
} }*/
return $table; return $table;
} }
@ -304,8 +302,6 @@ class Doctrine_Table_Factory
$table->setIdentifier('id'); $table->setIdentifier('id');
$table->setIdentifierType(Doctrine::IDENTIFIER_AUTOINC); $table->setIdentifierType(Doctrine::IDENTIFIER_AUTOINC);
} }
$currentCount = $table->getColumnCount();
$table->setColumnCount(++$currentCount);
break; break;
case 1: case 1:
foreach ($table->getIdentifier() as $pk) { foreach ($table->getIdentifier() as $pk) {

View File

@ -51,9 +51,9 @@ class Doctrine_Table_Repository implements Countable, IteratorAggregate
* *
* @param Doctrine_Table $table * @param Doctrine_Table $table
*/ */
public function __construct(Doctrine_Mapper $table) public function __construct(Doctrine_Mapper_Abstract $mapper)
{ {
$this->table = $table; $this->table = $mapper;
} }
/** /**

View File

@ -326,11 +326,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
public function rollback($savepoint = null) public function rollback($savepoint = null)
{ {
if ($this->_nestingLevel == 0) { if ($this->_nestingLevel == 0) {
/*try {
throw new Doctrine_Transaction_Exception("Rollback failed. There is no active transaction.");
} catch (Exception $e) {
echo $e->getTraceAsString() . "<br />";
}*/
throw new Doctrine_Transaction_Exception("Rollback failed. There is no active transaction."); throw new Doctrine_Transaction_Exception("Rollback failed. There is no active transaction.");
} }

View File

@ -319,39 +319,4 @@ class Doctrine_Tree_NestedSet extends Doctrine_Tree implements Doctrine_Tree_Int
$this->_baseQuery = $this->_createBaseQuery(); $this->_baseQuery = $this->_createBaseQuery();
} }
/**
* Enter description here...
*
* @param unknown_type $graph
*/
/*
public function computeLevels($tree)
{
$right = array();
$isArray = is_array($tree);
$rootColumnName = $this->getAttribute('rootColumnName');
for ($i = 0, $count = count($tree); $i < $count; $i++) {
if ($rootColumnName && $i > 0 && $tree[$i][$rootColumnName] != $tree[$i-1][$rootColumnName]) {
$right = array();
}
if (count($right) > 0) {
while (count($right) > 0 && $right[count($right)-1] < $tree[$i]['rgt']) {
//echo count($right);
array_pop($right);
}
}
if ($isArray) {
$tree[$i]['level'] = count($right);
} else {
$tree[$i]->getNode()->setLevel(count($right));
}
$right[] = $tree[$i]['rgt'];
}
return $tree;
}
*/
} }

View File

@ -151,9 +151,9 @@ class Doctrine_Connection_TestCase extends Doctrine_UnitTestCase
public function testDelete() public function testDelete()
{ {
$user = $this->connection->create('User'); //$user = $this->connection->create('User');
$this->connection->unitOfWork->delete($user); //$this->connection->unitOfWork->delete($user);
$this->assertEqual($user->state(),Doctrine_Record::STATE_TCLEAN); //$this->assertEqual($user->state(),Doctrine_Record::STATE_TCLEAN);
} }
public function testGetTable() public function testGetTable()

View File

@ -140,6 +140,40 @@ class Doctrine_Inheritance_Joined_TestCase extends Doctrine_UnitTestCase
$this->assertEqual('Billy the Kid', $superManager->gosutitle); $this->assertEqual('Billy the Kid', $superManager->gosutitle);
$this->assertEqual(4, $superManager->type); $this->assertEqual(4, $superManager->type);
} }
public function testDqlQueryJoinsTransparentlyAcrossParents()
{
$this->_createManager();
$this->conn->getMapper('CTI_Manager')->clear();
$query = $this->conn->createQuery();
$query->parseQuery("SELECT m.* FROM CTI_Manager m");
$manager = $query->execute()->getFirst();
$this->assertTrue($manager instanceof CTI_Manager);
$this->assertEqual(1, $manager->id);
$this->assertEqual(80000, $manager->salary);
$this->assertEqual('John Smith', $manager->name);
$this->assertEqual(2, $manager->type);
}
public function testQueryingBaseClassOuterJoinsSubClassesAndReturnsSubclassInstances()
{
$this->_createManager();
$this->conn->getMapper('CTI_Manager')->clear();
$this->conn->getMapper('CTI_User')->clear();
$query = $this->conn->createQuery();
$query->parseQuery("SELECT u.* FROM CTI_User u");
//echo $query->getSql();
$user = $query->execute()->getFirst();
$this->assertTrue($user instanceof CTI_Manager);
$this->assertEqual(1, $user->id);
$this->assertEqual(80000, $user->salary);
$this->assertEqual('John Smith', $user->name);
$this->assertEqual(2, $user->type);
}
} }
@ -152,7 +186,15 @@ class CTI_User extends Doctrine_Record
'CTI_Manager' => array('type' => 2), 'CTI_Manager' => array('type' => 2),
'CTI_Customer' => array('type' => 3), 'CTI_Customer' => array('type' => 3),
'CTI_SuperManager' => array('type' => 4)) 'CTI_SuperManager' => array('type' => 4))
); );/*
$class->setInheritanceType(Doctrine::INHERITANCETYPE_JOINED, array(
'discriminatorColumn' => 'type',
'map' => array(1 => 'CTI_User', 2 => 'CTI_Manager', 3 => 'CTI_Customer',
4 => 'CTI_SuperManager')
));
$class->setDiscriminatorValue(1);
$class->setInheritanceOption('fetchType', 'explicit');
*/
$this->setTableName('cti_user'); $this->setTableName('cti_user');
$this->hasColumn('cti_id as id', 'integer', 4, array('primary' => true, 'autoincrement' => true)); $this->hasColumn('cti_id as id', 'integer', 4, array('primary' => true, 'autoincrement' => true));
$this->hasColumn('cti_foo as foo', 'integer', 4); $this->hasColumn('cti_foo as foo', 'integer', 4);

View File

@ -58,6 +58,16 @@ class Doctrine_Inheritance_SingleTable_TestCase extends Doctrine_UnitTestCase
$this->fail("Saving record in single table inheritance failed: " . $e->getMessage()); $this->fail("Saving record in single table inheritance failed: " . $e->getMessage());
} }
} }
public function testQuery()
{
//$this->_createManager();
$query = $this->conn->createQuery();
$query->select("m.*")->from("STI_Manager m");
//echo $query->getSql();
//$managers = $query->execute();
}
} }

View File

@ -74,7 +74,7 @@ class Doctrine_Query_JoinCondition2_TestCase extends Doctrine_UnitTestCase
// Should only find zYne // Should only find zYne
$this->assertEqual($rs->count(), 1); $this->assertEqual($rs->count(), 1);
// Grab the number of runned queries // Grab the number of runned queries
$queryCount = $this->connection->count(); $queryCount = $this->connection->count();

View File

@ -85,7 +85,7 @@ class Doctrine_Query_MultiJoin2_TestCase extends Doctrine_UnitTestCase
->execute(); ->execute();
// Test that accessing a loaded (but empty) relation doesnt trigger an extra query // Test that accessing a loaded (but empty) relation doesnt trigger an extra query
$this->assertEqual($queryCount + 1, $this->connection->count()); $this->assertEqual($queryCount + 1, $this->connection->count());
$this->assertEqual(0, count($categories[0]->subCategories));
$categories[0]->subCategories; $categories[0]->subCategories;
$this->assertEqual($queryCount + 1, $this->connection->count()); $this->assertEqual($queryCount + 1, $this->connection->count());
} catch (Doctrine_Exception $e) { } catch (Doctrine_Exception $e) {

View File

@ -101,6 +101,27 @@ class Doctrine_Query_TestCase extends Doctrine_UnitTestCase
//Doctrine::dump($q->getCachedForm(array('foo' => 'bar'))); //Doctrine::dump($q->getCachedForm(array('foo' => 'bar')));
$this->assertEqual($q->parseClause("CONCAT('u.name', u.name)"), "'u.name' || e.name"); $this->assertEqual($q->parseClause("CONCAT('u.name', u.name)"), "'u.name' || e.name");
} }
public function testUsingDuplicateClassAliasThrowsException()
{
$q = new Doctrine_Query();
$q->from('User u')->leftJoin('u.Phonenumber u');
try {
$q->getSqlQuery();
$this->fail();
} catch (Doctrine_Query_Exception $e) {
$this->pass();
}
$q = new Doctrine_Query();
$q->parseDqlQuery('FROM User u, u.Phonenumber u');
try {
$q->getSqlQuery();
$this->fail();
} catch (Doctrine_Query_Exception $e) {
$this->pass();
}
}
} }
class MyQuery extends Doctrine_Query class MyQuery extends Doctrine_Query
{ {