1
0
mirror of synced 2025-01-18 06:21:40 +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_Collection
* Collection of Doctrine_Record objects.
* A Doctrine_Collection represents a collection of 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
* @subpackage Collection
@ -34,57 +35,74 @@ Doctrine::autoload('Doctrine_Access');
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();
/**
* The mapper object used to map the records of this collection to the database.
*
* @var Doctrine_Mapper
*/
protected $_mapper;
/**
* @var array $_snapshot a snapshot of the fetched data
* A snapshot of the fetched data.
*
* @var 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;
/**
* @var string $referenceField the reference field of the collection
* The reference field of the collection.
*
* @var string $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;
/**
* @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;
/**
* @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;
/**
* 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)
{
if ($mapper instanceof Doctrine_Table) {
try {
throw new Exception();
} catch (Exception $e) {
echo $e->getTraceAsString();
}
}
if (is_string($mapper)) {
$mapper = Doctrine_Manager::getInstance()->getMapper($mapper);
}
@ -105,7 +123,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
/**
* initNullObject
* initializes the null object for this collection
* Initializes the null object for this collection.
*
* @return void
*/
@ -116,7 +134,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
/**
* getTable
* returns the table this collection belongs to
* Returns the table of the mapper of the collection.
*
* @return Doctrine_Table
*/
@ -124,6 +142,17 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{
return $this->_mapper->getTable();
}
/**
* getMapper
* Returns the mapper of this collection.
*
* @return Doctrine_Mapper
*/
public function getMapper()
{
return $this->_mapper;
}
/**
* 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
*/
@ -158,15 +190,17 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
}
/**
* unseralize
* this method is automatically called everytime a Doctrine_Collection object is unserialized
* Reconstitutes the collection object from it's serialized form.
* This method is automatically called everytime a Doctrine_Collection object is unserialized.
*
* Part of the implementation of the Serializable interface.
*
* @return void
*/
public function unserialize($serialized)
{
$manager = Doctrine_Manager::getInstance();
$connection = $manager->getCurrentConnection();
$manager = Doctrine_Manager::getInstance();
$connection = $manager->getCurrentConnection();
$array = unserialize($serialized);
@ -196,7 +230,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
public function setKeyColumn($column)
{
$this->keyColumn = $column;
return $this;
}
@ -243,6 +276,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{
return end($this->data);
}
/**
* returns the last record in the collection
*
@ -252,6 +286,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{
return end($this->data);
}
/**
* returns the current key
*
@ -261,6 +296,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{
return key($this->data);
}
/**
* setReference
* 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)
{
/*try {
throw new Exception();
} catch (Exception $e) {
echo "relation set on collection: " . get_class($relation) . "<br />";
echo $e->getTraceAsString() . "<br />";
}*/
$this->reference = $record;
$this->relation = $relation;
if ($relation instanceof Doctrine_Relation_ForeignKey ||
$relation instanceof Doctrine_Relation_LocalKey) {
$this->referenceField = $relation->getForeignFieldName();
$value = $record->get($relation->getLocalFieldName());
foreach ($this->data as $record) {
@ -331,6 +360,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
return isset($this->data[$key]);
}
/**
*
*/
public function search(Doctrine_Record $record)
{
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);
}
}
if ($key === null) {
$this->data[] = $record;
} else {
@ -374,7 +407,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
}
if (isset($this->keyColumn)) {
$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()
{
@ -412,11 +446,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
}
/**
* count
* this class implements interface countable
* returns the number of records in this collection
* 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()
{
@ -434,7 +468,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
if (isset($this->referenceField)) {
$record->set($this->referenceField, $this->reference, false);
}
$this->data[$key] = $record;
}
@ -455,7 +488,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
$record->set($this->referenceField, $this->reference, false);
}
}
/**
/*
* for some weird reason in_array cannot be used here (php bug ?)
*
* 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)
{
$list = array();
$query = new Doctrine_Query($this->_mapper->getConnection());
$query = new Doctrine_Query($this->_mapper->getConnection());
if ( ! isset($name)) {
foreach ($this->data as $record) {
@ -510,7 +543,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
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) {
foreach ($this->data as $record) {
@ -525,9 +558,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
}
}
$dql = $rel->getRelationDql(count($list), 'collection');
$coll = $query->query($dql, $list);
$dql = $rel->getRelationDql(count($list), 'collection');
$coll = $query->query($dql, $list);
$this->populateRelated($name, $coll);
}
@ -618,7 +650,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
public function takeSnapshot()
{
$this->_snapshot = $this->data;
return $this;
}
@ -647,7 +678,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/
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();
}
return $this;
@ -663,9 +694,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
{
$data = array();
foreach ($this as $key => $record) {
$key = $prefixKey ? get_class($record) . '_' .$key:$key;
$data[$key] = $record->toArray($deep, $prefixKey);
}
@ -758,7 +787,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
*/
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()
{
return array_udiff($this->data, $this->_snapshot, array($this, "compareRecords"));
return array_udiff($this->data, $this->_snapshot, array($this, "_compareRecords"));
}
/**
* compareRecords
* Compares two records. To be used on _snapshot diffs using array_udiff
* _compareRecords
* 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()) {
return 0;
@ -786,8 +815,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
/**
* save
* saves all records of this collection and processes the
* difference of the last snapshot and the current data
* Saves all records of this collection and processes the
* difference of the last snapshot and the current data.
*
* @param Doctrine_Connection $conn optional connection parameter
* @return Doctrine_Collection

View File

@ -60,6 +60,9 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/
protected $dbh;
/**
*
*/
protected $_tableFactory;
/**
@ -169,6 +172,12 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
'Sqlite',
'Firebird'
);
/**
* The query count. Represents the number of executed database queries by the connection.
*
* @var integer
*/
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');
}
$this->dbh = $adapter;
$this->isConnected = true;
} else if (is_array($adapter)) {
$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)
{
if ($attribute >= 100) {
if ( ! isset($this->attributes[$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
*/
public function getDbh()
{
$this->connect();
return $this->dbh;
}
@ -372,13 +377,11 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/
public function connect()
{
if ($this->isConnected) {
return false;
}
$event = new Doctrine_Event($this, Doctrine_Event::CONN_CONNECT);
$this->getListener()->preConnect($event);
$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
* @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
*/
public function delete(Doctrine_Table $table, array $identifier)
{
$tmp = array();
$criteria = array();
foreach (array_keys($identifier) as $id) {
$tmp[] = $table->getColumnName($id) . ' = ?';
$criteria[] = $table->getColumnName($id) . ' = ?';
}
$query = 'DELETE FROM '
. $this->quoteIdentifier($table->getTableName())
. ' WHERE ' . implode(' AND ', $tmp);
. ' WHERE ' . implode(' AND ', $criteria);
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.
*
* @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,
* otherwise returns the number of affected rows
*/
@ -606,53 +607,9 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$query .= implode(', ', $a) . ')';
// prepare and execute the statement
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
@ -661,11 +618,11 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/
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.
*
@ -1032,7 +989,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
public function rethrowException(Exception $e, $invoker)
{
$event = new Doctrine_Event($this, Doctrine_Event::CONN_ERROR);
$this->getListener()->preError($event);
$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.
*
* @return Doctrine_Mapper_Abstract The mapper object.
@ -1092,9 +1048,9 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$customMapperClass = $className . 'Mapper';
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);
$mapper = new $customMapperClass($className, $this);
$mapper = new $customMapperClass($className, $table);
} else {
// instantiate correct mapper type
$table = $this->getTable($className);
@ -1250,7 +1206,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
public function close()
{
$event = new Doctrine_Event($this, Doctrine_Event::CONN_CLOSE);
$this->getAttribute(Doctrine::ATTR_LISTENER)->preClose($event);
$this->clear();

View File

@ -73,7 +73,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
{
$tree = array();
foreach ($tables as $k => $table) {
if ( ! ($table instanceof Doctrine_Mapper)) {
if ( ! ($table instanceof Doctrine_Mapper_Abstract)) {
$table = $this->conn->getMapper($table);
}
$nm = $table->getComponentName();
@ -281,7 +281,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
* @return boolean true on success, false on failure
* @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) {
return true;
@ -331,7 +331,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$this->conn->commit();
return true;
}
}*/
/**
* @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
* 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.
* This should be changed.
*/
public function deleteMultiple(array $records)
/*public function deleteMultiple(array $records)
{
foreach ($this->delete as $name => $deletes) {
$record = false;
@ -414,7 +416,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
}
}
}
}
}*/
/**
* saveRelated
@ -498,7 +500,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
* @throws PDOException if something went wrong at database level
* @return void
*/
public function deleteComposites(Doctrine_Record $record)
/*public function deleteComposites(Doctrine_Record $record)
{
foreach ($record->getTable()->getRelations() as $fk) {
if ($fk->isComposite()) {
@ -509,7 +511,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
}
}
}
}
}*/
/**
* saveAll
@ -554,22 +556,19 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
//echo "<br /><br />flushin all.<br /><br />";
// get the flush tree
$tree = $this->buildFlushTree($this->conn->getMappers());
//foreach ($tree as $name) echo $name . "<br />";
// save all records
foreach ($tree as $name) {
$mapper = $this->conn->getMapper($name);
foreach ($mapper->getRepository() as $record) {
//echo $record->getOid() . "<br />";
$mapper->save($record);
$mapper->saveSingleRecord($record);
}
}
// save all associations
foreach ($tree as $name) {
$mapper = $this->conn->getMapper($name);
foreach ($mapper->getRepository() as $record) {
$mapper->saveAssociations($record);
}

View File

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

View File

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

View File

@ -20,8 +20,8 @@
*/
/**
* Doctrine_Hydrate_Record
* defines a record fetching strategy for Doctrine_Hydrate
* Doctrine_Hydrate_RecordDriver
* Hydration strategy used for creating collections of entity objects.
*
* @package Doctrine
* @subpackage Hydrate
@ -30,14 +30,13 @@
* @since 1.0
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
*/
class Doctrine_Hydrator_RecordDriver extends Doctrine_Locator_Injectable
{
protected $_collections = array();
protected $_records = array();
protected $_tables = array();
protected $_mappers = array();
public function getElementCollection($component)
{
@ -105,13 +104,12 @@ class Doctrine_Hydrator_RecordDriver extends Doctrine_Locator_Injectable
public function getElement(array $data, $component)
{
if ( ! isset($this->_tables[$component])) {
$this->_tables[$component] = Doctrine_Manager::getInstance()->getMapper($component);
$this->_tables[$component]->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, false);
if ( ! isset($this->_mappers[$component])) {
$this->_mappers[$component] = Doctrine_Manager::getInstance()->getMapper($component);
}
$this->_tables[$component]->setData($data);
$record = $this->_tables[$component]->getRecord();
$component = $this->_getClassnameToReturn($data, $component);
$record = $this->_mappers[$component]->getRecord($data);
if ( ! isset($this->_records[$record->getOid()]) ) {
$record->clearRelated();
@ -127,8 +125,38 @@ class Doctrine_Hydrator_RecordDriver extends Doctrine_Locator_Injectable
foreach ($this->_collections as $key => $coll) {
$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);
} elseif (is_array($adapter)) {
} else if (is_array($adapter)) {
if ( ! isset($adapter[0])) {
throw new Doctrine_Manager_Exception('Empty data source name given.');
}

View File

@ -31,7 +31,8 @@
* @link www.phpdoctrine.org
* @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
@ -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.
*/
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.
@ -372,10 +366,9 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
*
* @return Doctrine_Record
*/
public function getRecord()
public function getRecord(array $data)
{
if ( ! empty($this->_data)) {
if ( ! empty($data)) {
$identifierFieldNames = $this->_table->getIdentifier();
if ( ! is_array($identifierFieldNames)) {
@ -384,18 +377,19 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
$found = false;
foreach ($identifierFieldNames as $fieldName) {
if ( ! isset($this->_data[$fieldName])) {
if ( ! isset($data[$fieldName])) {
// primary key column not found return new record
$found = true;
break;
}
$id[] = $this->_data[$fieldName];
$id[] = $data[$fieldName];
}
if ($found) {
$recordName = $this->getClassnameToReturn();
$record = new $recordName($this, true);
$this->_data = array();
//$recordName = $this->getClassnameToReturn();
//$record = new $recordName($this, true);
$record = new $this->_domainClassName($this, true, $data);
$data = array();
return $record;
}
@ -404,16 +398,18 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
if (isset($this->_identityMap[$id])) {
$record = $this->_identityMap[$id];
$record->hydrate($this->_data);
$record->hydrate($data);
} else {
$recordName = $this->getClassnameToReturn();
$record = new $recordName($this);
//$recordName = $this->getClassnameToReturn();
//$record = new $recordName($this);
$record = new $this->_domainClassName($this, false, $data);
$this->_identityMap[$id] = $record;
}
$this->_data = array();
$data = array();
} else {
$recordName = $this->getClassnameToReturn();
$record = new $recordName($this, true);
//$recordName = $this->getClassnameToReturn();
//$record = new $recordName($this, true);
$record = new $this->_domainClassName($this, true, $data);
}
return $record;
@ -435,7 +431,7 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
* @return string The name of the class to create
*
*/
public function getClassnameToReturn()
/*public function getClassnameToReturn()
{
$subClasses = $this->_table->getOption('subclasses');
if ( ! isset($subClasses)) {
@ -457,7 +453,7 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
}
}
return $this->_domainClassName;
}
}*/
/**
* @param $id database row id
@ -472,15 +468,15 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
. ' WHERE ' . implode(' = ? && ', $identifierColumnNames) . ' = ?';
$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 $this->getRecord();
return $this->getRecord($data);
}
/**
@ -490,7 +486,7 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
*/
final public function applyInheritance($where)
{
$inheritanceMap = $this->getDiscriminatorColumn($this->_domainClassName);
$inheritanceMap = $this->getDiscriminatorColumn();
if ( ! empty($inheritanceMap)) {
$a = array();
foreach ($inheritanceMap as $field => $value) {
@ -523,30 +519,6 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
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
* 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)) {
echo "mismatch: " . $this->_domainClassName . " <-> " . get_class($record) . "<br />";
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) {
@ -798,9 +776,8 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
// save the MANY-TO-MANY associations
$this->saveAssociations($record);
// reset state
$record->state($state);
$conn->commit();
} catch (Exception $e) {
// 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;
}
/**
* 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
*
* @param Doctrine_Record $record
* @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);
$record->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->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
* @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);
$record->preUpdate($event);
@ -946,10 +973,7 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
$this->getRecordListener()->preUpdate($event);
if ( ! $event->skipOperation) {
$identifier = $record->identifier();
$array = $record->getPrepared();
$this->_conn->update($table, $array, $identifier);
$record->assignIdentifier(true);
$this->_doUpdate($record);
}
$this->getRecordListener()->postUpdate($event);
@ -958,22 +982,29 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
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
*
* @param Doctrine_Record $record record to be inserted
* @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
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_INSERT);
$record->preInsert($event);
$this->getRecordListener()->preInsert($event);
if ( ! $event->skipOperation) {
$this->_conn->processSingleInsert($record);
$this->_doInsert($record);
}
// trigger event
@ -984,9 +1015,95 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
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)
@ -998,15 +1115,10 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
{
return $this->_table;
}
public function getCustomJoins()
public function getFieldName($columnName)
{
return array();
}
public function getDiscriminatorColumn($domainClassName)
{
return array();
return $this->_table->getFieldName($columnName);
}
public function getFieldNames()
@ -1014,15 +1126,14 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
if ($this->_fieldNames) {
return $this->_fieldNames;
}
$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()
{
@ -1034,4 +1145,31 @@ class Doctrine_Mapper extends Doctrine_Configurable implements Countable
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
class Doctrine_Mapper_Joined extends Doctrine_Mapper
class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
{
protected $_columnNameFieldNameMap = array();
/**
* inserts a record into database
@ -10,7 +11,7 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
* @return boolean
* @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;
@ -19,19 +20,39 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
$classes = $table->getOption('joinedParents');
array_unshift($classes, $component);
foreach (array_reverse($classes) as $k => $parent) {
if ($k === 0) {
$rootRecord = new $parent();
$rootRecord->merge($dataSet[$parent]);
parent::insert($rootRecord);
$record->assignIdentifier($rootRecord->identifier());
} else {
foreach ((array) $rootRecord->identifier() as $id => $value) {
$dataSet[$parent][$id] = $value;
try {
$this->_conn->beginInternalTransaction();
$identifier = null;
foreach (array_reverse($classes) as $k => $parent) {
$parentTable = $this->_conn->getTable($parent);
if ($k == 0) {
$identifierType = $parentTable->getIdentifierType();
if ($identifierType == Doctrine::IDENTIFIER_AUTOINC) {
$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;
@ -44,39 +65,58 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
* @return boolean whether or not the update was successful
* @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;
$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) {
$identifier = $record->identifier();
$dataSet = $this->_formatDataSet($record);
$component = $table->getComponentName();
$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());
foreach ($record as $field => $value) {
if ($value instanceof Doctrine_Record) {
if ( ! $value->exists()) {
$value->save();
}
$record->set($field, $value->getIncremented());
}
}
foreach (array_reverse($classes) as $class) {
$parentTable = $this->_conn->getTable($class);
$this->_conn->update($parentTable, $dataSet[$class], $identifier);
}
$record->assignIdentifier(true);
foreach (array_reverse($classes) as $class) {
$parentTable = $this->_conn->getTable($class);
$this->_conn->update($parentTable, $dataSet[$class], $identifier);
}
$this->getRecordListener()->postUpdate($event);
$record->postUpdate($event);
$record->assignIdentifier(true);
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;
}
@ -87,13 +127,33 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
*/
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');
if (count($joinedParents) <= 0) {
@ -101,7 +161,7 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
} else {
$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();
foreach ($this->_table->getOption('joinedParents') as $parent) {
$fieldNames = array_merge($this->_conn->getTable($parent)->getFieldNames(),
$fieldNames);
$parentTable = $this->_conn->getTable($parent);
$fieldNames = array_merge($parentTable->getFieldNames(), $fieldNames);
}
$this->_fieldNames = $fieldNames;
$this->_fieldNames = array_unique($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
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');
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
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);
}
}
/**
* 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
* returns a specific DQL query part.
@ -480,8 +432,9 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
*/
public function processPendingFields($componentAlias)
{
$tableAlias = $this->getTableAlias($componentAlias);
$table = $this->_queryComponents[$componentAlias]['table'];
$tableAlias = $this->getSqlTableAlias($componentAlias);
$baseTable = $this->_queryComponents[$componentAlias]['table'];
$mapper = $this->_queryComponents[$componentAlias]['mapper'];
if ( ! isset($this->_pendingFields[$componentAlias])) {
return;
@ -489,41 +442,39 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$fields = $this->_pendingFields[$componentAlias];
// check for wildcards
if (in_array('*', $fields)) {
//echo "<br />";Doctrine::dump($table->getColumnNames()); echo "<br />";
$fields = $table->getFieldNames();
$fields = $mapper->getFieldNames();
} else {
// only auto-add the primary key fields if this query object is not
// a subquery of another query object
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();
foreach ($fields as $fieldName) {
$columnName = $table->getColumnName($fieldName);
if (($owner = $table->getColumnOwner($columnName)) !== null &&
$owner !== $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);
$table = $mapper->getOwningTable($fieldName);
if ($table !== $baseTable) {
$tableAlias = $this->getSqlTableAlias($componentAlias . '.' . $table->getComponentName());
} else {
$columnName = $table->getColumnName($fieldName);
$sql[] = $this->_conn->quoteIdentifier($tableAlias . '.' . $columnName)
. ' AS '
. $this->_conn->quoteIdentifier($tableAlias . '__' . $columnName);
$tableAlias = $this->getSqlTableAlias($componentAlias);
}
$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);
}
@ -617,7 +568,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
// check for DISTINCT keyword
if ($first === 'DISTINCT') {
$this->_sqlParts['distinct'] = true;
$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, ' ');
$pos = strpos($terms[0], '(');
$pos = strpos($terms[0], '(');
if (count($terms) > 1 || $pos !== false) {
$expression = array_shift($terms);
@ -647,7 +597,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$tableAlias = $this->getTableAlias($componentAlias);
$index = count($this->_aggregateAliasMap);
$index = count($this->_aggregateAliasMap);
$sqlAlias = $this->_conn->quoteIdentifier($tableAlias . '__' . $index);
@ -670,7 +620,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$componentAlias = key($this->_queryComponents);
$field = $e[0];
}
$this->_pendingFields[$componentAlias][] = $field;
}
}
@ -1156,7 +1105,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
}
// append discriminator column conditions (if any)
$string = $this->_createDiscriminatorSql();
$string = $this->_createDiscriminatorConditionSql();
//echo "orig:$string<br /><br />";
if ( ! empty($string)) {
if (substr($string, 0, 1) === '(' && substr($string, -1) === ')') {
$this->_sqlParts['where'][] = $string;
@ -1482,23 +1432,21 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$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])) {
continue;
throw new Doctrine_Query_Exception("Duplicate alias '$componentAlias' in query.");
}
if ( ! isset($table)) {
// process the root of the path
$table = $this->loadRoot($name, $componentAlias);
} else {
$join = ($delimeter == ':') ? 'INNER JOIN ' : 'LEFT JOIN ';
//echo "!!!!!!" . $prevPath . "!!!!!<br />";
$relation = $table->getRelation($name);
$localTable = $table;
$table = $relation->getTable();
//echo "<br /><br />" . $table->getComponentName() . "------" . $relation->getForeignComponentName() . "<br /><br />";
$table = $relation->getTable();
//echo "<br /><br />" . $table->getComponentName() . "------" . $relation->getForeignComponentName() . "<br /><br />";
$this->_queryComponents[$componentAlias] = array(
'table' => $table,
'mapper' => $this->_conn->getMapper($relation->getForeignComponentName()),
@ -1536,7 +1484,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
}
$assocPath = $prevPath . '.' . $asf->getComponentName();
//var_dump($name); echo "hrrrr";
//echo "<br /><br />" . $asf->getComponentName() . "---2---" . $relation->getForeignComponentName() . "<br /><br />";
$this->_queryComponents[$assocPath] = array(
'parent' => $prevPath,
@ -1592,7 +1539,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
}
}
} else {
$queryPart = $join . $foreignSql;
if ( ! $overrideJoin) {
@ -1632,8 +1578,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
if (isset($e[1])) {
$indexBy = $e[1];
}
} else if ($mapper->getBoundQueryPart('indexBy') !== null) {
$indexBy = $mapper->getBoundQueryPart('indexBy');
} else if ($table->getBoundQueryPart('indexBy') !== null) {
$indexBy = $table->getBoundQueryPart('indexBy');
}
if ($indexBy !== null) {
@ -1733,7 +1679,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$q .= ' FROM ' . $this->_buildSqlFromPart();
// append discriminator column conditions (if any)
$string = $this->_createDiscriminatorSql();
$string = $this->_createDiscriminatorConditionSql();
if ( ! empty($string)) {
$where[] = $string;
}

View File

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

View File

@ -146,7 +146,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* open connections
* @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 />";
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));
$exists = ! $isNewEntry;
return;
} else if (isset($mapper) && $mapper instanceof Doctrine_Mapper) {
} else if (isset($mapper) && $mapper instanceof Doctrine_Mapper_Abstract) {
//echo "two<br />";
$class = get_class($this);
$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();
$exists = ! $isNewEntry;
} else {
@ -182,7 +174,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
self::$_index++;
// get the data array
$this->_data = $this->_mapper->getData();
$this->_data = $data;
// get the column count
$count = count($this->_data);
@ -202,7 +194,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$this->assignDefaultValues();
} else {
$this->_state = Doctrine_Record::STATE_CLEAN;
// @TODO table->getColumnCount is not correct in CTI
if ($count < $this->_table->getColumnCount()) {
$this->_state = Doctrine_Record::STATE_PROXY;
}
@ -213,7 +205,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$repository->add($this);
$this->construct();
}
/**
@ -256,11 +247,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
{
return $this->_oid;
}
public function oid()
{
return $this->_oid;
}
/**
* isValid
@ -534,22 +520,22 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
}
/**
* serialize
* this method is automatically called when this Doctrine_Record is serialized
* Serializes the entity.
* This method is automatically called when the entity is serialized.
*
* Part of the implementation of the Serializable interface.
*
* @return array
*/
public function serialize()
{
$event = new Doctrine_Event($this, Doctrine_Event::RECORD_SERIALIZE);
$this->preSerialize($event);
$vars = get_object_vars($this);
unset($vars['_references']);
unset($vars['_mapper']);
//unset($vars['_table']);
unset($vars['_errorStack']);
unset($vars['_filter']);
unset($vars['_node']);
@ -586,8 +572,8 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
}
/**
* unseralize
* this method is automatically called everytime a Doctrine_Record object is unserialized
* Reconstructs the entity from it's serialized form.
* This method is automatically called everytime the entity is unserialized.
*
* @param string $serialized Doctrine_Record as serialized string
* @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->cleanData($this->_data);
$this->prepareIdentifiers($this->exists());
$this->postUnserialize($event);
}
@ -676,7 +663,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
}
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) {
$rel = $this->_table->getRelation($fieldName);
$this->_references[$fieldName] = $rel->fetchRelatedFor($this);
/*if (count($this->_references[$fieldName]) > 0) {
echo $this->_references[$fieldName][0]->state() . "<br />";
}*/
}
return $this->_references[$fieldName];
} catch (Doctrine_Table_Exception $e) {
//echo $e->getTraceAsString();
//echo "<br /><br />";
@ -937,12 +920,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$this->_modified[] = $fieldName;
switch ($this->_state) {
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;
break;
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) {
// join table relation found
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)
{
$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->_mapper->getDiscriminatorColumn($this->_domainClassName);
$map = $this->_mapper->getDiscriminatorColumn();
foreach ($map as $k => $v) {
$old = $this->get($k, false);
if ((string) $old !== (string) $v || $old === null) {
@ -1225,6 +1201,8 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* count
* this class implements countable interface
*
* Implementation of the Countable interface.
*
* @return integer the number of columns in this record
*/
public function count()
@ -1436,10 +1414,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
*/
public function delete(Doctrine_Connection $conn = null)
{
if ($conn == null) {
$conn = $this->_mapper->getConnection();
}
return $conn->unitOfWork->delete($this);
return $this->_mapper->delete($this, $conn);
}
/**

View File

@ -107,7 +107,10 @@ class Doctrine_Relation_Association extends Doctrine_Relation
public function fetchRelatedFor(Doctrine_Record $record)
{
$id = $record->getIncremented();
//var_dump($id);
//echo "<br /><br />";
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());
} else {
$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)';
try {
$this->conn->exec($query);
} catch(Doctrine_Connection_Exception $e) {
} catch (Doctrine_Connection_Exception $e) {
if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) {
try {
$this->conn->export->createSequence($seqName);

View File

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

View File

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

View File

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

View File

@ -51,9 +51,9 @@ class Doctrine_Table_Repository implements Countable, IteratorAggregate
*
* @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)
{
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.");
}

View File

@ -319,39 +319,4 @@ class Doctrine_Tree_NestedSet extends Doctrine_Tree implements Doctrine_Tree_Int
$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()
{
$user = $this->connection->create('User');
$this->connection->unitOfWork->delete($user);
$this->assertEqual($user->state(),Doctrine_Record::STATE_TCLEAN);
//$user = $this->connection->create('User');
//$this->connection->unitOfWork->delete($user);
//$this->assertEqual($user->state(),Doctrine_Record::STATE_TCLEAN);
}
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(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_Customer' => array('type' => 3),
'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->hasColumn('cti_id as id', 'integer', 4, array('primary' => true, 'autoincrement' => true));
$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());
}
}
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
$this->assertEqual($rs->count(), 1);
// Grab the number of runned queries
$queryCount = $this->connection->count();

View File

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

View File

@ -101,6 +101,27 @@ class Doctrine_Query_TestCase extends Doctrine_UnitTestCase
//Doctrine::dump($q->getCachedForm(array('foo' => 'bar')));
$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
{