diff --git a/lib/Doctrine/Cache.php b/lib/Doctrine/Cache.php index 17bf575dc..5bcd64463 100644 --- a/lib/Doctrine/Cache.php +++ b/lib/Doctrine/Cache.php @@ -28,7 +28,8 @@ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link www.phpdoctrine.org * @since 1.0 - * @version $Revision$ + * @version $Revision$ + * @todo Can this be removed? */ class Doctrine_Cache extends Doctrine_EventListener implements Countable, IteratorAggregate { diff --git a/lib/Doctrine/ClassMetadata.php b/lib/Doctrine/ClassMetadata.php index 3e6a2d6e5..0a0fda8e8 100644 --- a/lib/Doctrine/ClassMetadata.php +++ b/lib/Doctrine/ClassMetadata.php @@ -60,7 +60,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable * * @var Doctrine_Connection */ - protected $_conn; + protected $_em; /** * The names of the parent classes (ancestors). @@ -114,14 +114,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable */ protected $_generators = array(); - /** - * An array containing all filters attached to the class. - * - * @see Doctrine_Record_Filter - * @var array $_filters - */ - protected $_filters = array(); - /** * The mapped columns and their mapping definitions. * Keys are column names and values are mapping definitions. @@ -156,6 +148,13 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable * @var array */ protected $_fieldNames = array(); + + /** + * Enter description here... + * + * @var unknown_type + */ + protected $_attributes = array('loadReferences' => true); /** * An array of column names. Keys are field names and values column names. @@ -165,6 +164,13 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable * @var array */ protected $_columnNames = array(); + + /** + * Enter description here... + * + * @var unknown_type + */ + protected $_subclassFieldNames = array(); /** * Caches enum value mappings. Keys are field names and values arrays with the @@ -278,7 +284,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable { $this->_entityName = $entityName; $this->_rootEntityName = $entityName; - $this->_conn = $em; + $this->_em = $em; $this->_parser = new Doctrine_Relation_Parser($this); } @@ -287,12 +293,12 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable */ public function getConnection() { - return $this->_conn; + return $this->_em; } public function getEntityManager() { - return $this->_conn; + return $this->_em; } /** @@ -348,11 +354,11 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable */ public function isIdentifierComposite() { - return ($this->_identifierType == Doctrine::IDENTIFIER_COMPOSITE); + return $this->_identifierType == Doctrine::IDENTIFIER_COMPOSITE; } /** - * Check if the field is unique + * Check if the field is unique. * * @param string $fieldName The field name * @return boolean TRUE if the field is unique, FALSE otherwise. @@ -369,7 +375,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable } /** - * Check if the field is not null + * Check if the field is not null. * * @param string $fieldName The field name * @return boolean TRUE if the field is not null, FALSE otherwise. @@ -391,6 +397,8 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable * adds an index to this table * * @return void + * @deprecated + * @todo Should be done through setTableOption(). */ public function addIndex($index, array $definition) { @@ -401,6 +409,8 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable * getIndex * * @return array|boolean array on success, FALSE on failure + * @todo Should be done through getTableOption(). + * @deprecated */ public function getIndex($index) { @@ -424,19 +434,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable */ public function setOption($name, $value) { - /*switch ($name) { - case 'tableName': - case 'index': - case 'sequenceName': - case 'type': - case 'charset': - case 'collation': - case 'collate': - return $this->setTableOption($name, $value); - case 'enumMap': - $this->_enumMap = $value; - return; - }*/ $this->_options[$name] = $value; } @@ -468,7 +465,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable return (isset($this->_invokedMethods[$method])) ? $this->_invokedMethods[$method] : false; } - public function addBehaviorMethod($method, $behavior) { $this->_invokedMethods[$method] = $class; @@ -540,7 +536,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable public function getColumnMapping($columnName) { return isset($this->_mappedColumns[$columnName]) ? - $this->_mappedColumns[$columnName] : false; + $this->_mappedColumns[$columnName] : false; } /** @@ -555,11 +551,9 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable public function getFieldName($columnName) { return isset($this->_fieldNames[$columnName]) ? - $this->_fieldNames[$columnName] : $columnName; + $this->_fieldNames[$columnName] : $columnName; } - private $_subclassFieldNames = array(); - /** * */ @@ -572,7 +566,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable } $classMetadata = $this; - $conn = $this->_conn; + $conn = $this->_em; foreach ($classMetadata->getSubclasses() as $subClass) { $subClassMetadata = $conn->getClassMetadata($subClass); @@ -882,7 +876,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable } $columnName = $this->getColumnName($fieldName); - if ( ! $this->_conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM) && + if ( ! $this->_em->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM) && isset($this->_mappedColumns[$columnName]['values'][$index])) { $enumValue = $this->_mappedColumns[$columnName]['values'][$index]; } else { @@ -904,7 +898,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable { $values = $this->getEnumValues($fieldName); $index = array_search($value, $values); - if ($index === false || ! $this->_conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM)) { + if ($index === false || ! $this->_em->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM)) { return $index; } @@ -1288,7 +1282,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable public function setInheritanceType($type, array $options = array()) { if ($parentClassNames = $this->getParentClasses()) { - if ($this->_conn->getClassMetadata($parentClassNames[0])->getInheritanceType() != $type) { + if ($this->_em->getClassMetadata($parentClassNames[0])->getInheritanceType() != $type) { throw new Doctrine_ClassMetadata_Exception("All classes in an inheritance hierarchy" . " must share the same inheritance mapping type. Mixing is not allowed."); } @@ -1388,7 +1382,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable */ public function export() { - $this->_conn->export->exportTable($this); + $this->_em->export->exportTable($this); } /** @@ -1409,13 +1403,13 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable if ($this->_inheritanceType == Doctrine::INHERITANCE_TYPE_SINGLE_TABLE) { $parents = $this->getParentClasses(); if ($parents) { - $rootClass = $this->_conn->getClassMetadata(array_pop($parents)); + $rootClass = $this->_em->getClassMetadata(array_pop($parents)); } else { $rootClass = $this; } $subClasses = $rootClass->getSubclasses(); foreach ($subClasses as $subClass) { - $subClassMetadata = $this->_conn->getClassMetadata($subClass); + $subClassMetadata = $this->_em->getClassMetadata($subClass); $allColumns = array_merge($allColumns, $subClassMetadata->getColumns()); } } else if ($this->_inheritanceType == Doctrine::INHERITANCE_TYPE_JOINED) { @@ -1454,7 +1448,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable break; case 'boolean': if (isset($definition['default'])) { - $definition['default'] = $this->_conn->convertBooleans($definition['default']); + $definition['default'] = $this->_em->convertBooleans($definition['default']); } break; } @@ -1608,21 +1602,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable $this->addGenerator($generator, get_class($generator)); } - /** - * unshiftFilter - * - * @param object Doctrine_Record_Filter $filter - * @return object $this - * @todo Remove filters, if possible. - */ - public function unshiftFilter(Doctrine_Record_Filter $filter) - { - $filter->setTable($this); - array_unshift($this->_filters, $filter); - - return $this; - } - /** * getTree * @@ -1657,17 +1636,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable return ( ! is_null($this->getOption('treeImpl'))) ? true : false; } - /** - * getFilters - * - * @return array $filters - * @todo Remove filters, if possible. - */ - public function getFilters() - { - return $this->_filters; - } - /** * Checks whether a persistent field is inherited from a superclass. * @@ -1726,8 +1694,8 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable */ public function setTableName($tableName) { - $this->setTableOption('tableName', $this->_conn->getConnection() - ->formatter->getTableName($tableName)); + $this->setTableOption('tableName', $this->_em->getConnection() + ->getFormatter()->getTableName($tableName)); } /** @@ -1740,7 +1708,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable public function serialize() { //$contents = get_object_vars($this); - /* @TODO How to handle $this->_conn and $this->_parser ? */ + /* @TODO How to handle $this->_em and $this->_parser ? */ //return serialize($contents); return ""; } @@ -1834,6 +1802,7 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable * @param string $name optional constraint name * @return Doctrine_Entity this object * @todo Should be done through $_tableOptions + * @deprecated */ public function check($constraint, $name = null) { @@ -1847,7 +1816,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable return $this; } - protected function _addCheckConstraint($definition, $name) { if (is_string($name)) { @@ -1856,21 +1824,6 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable $this->_tableOptions['checks'][] = $definition; } } - - /** - * Registers a custom mapper for the entity class. - * - * @param string $mapperClassName The class name of the custom mapper. - * @deprecated - */ - public function setCustomMapperClass($mapperClassName) - { - if ( ! is_subclass_of($mapperClassName, 'Doctrine_Mapper')) { - throw new Doctrine_ClassMetadata_Exception("The custom mapper must be a subclass" - . " of Doctrine_Mapper."); - } - $this->_customRepositoryClassName = $mapperClassName; - } /** * Registers a custom mapper for the entity class. @@ -1886,19 +1839,13 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable } $this->_customRepositoryClassName = $repositoryClassName; } - - /** - * Gets the name of the custom mapper class used for the entity class. - * - * @return string|null The name of the custom mapper class or NULL if the entity - * class does not have a custom mapper class. - * @deprecated - */ - public function getCustomMapperClass() - { - return $this->_customRepositoryClassName; - } + /** + * Gets the name of the custom repository class used for the entity class. + * + * @return string|null The name of the custom repository class or NULL if the entity + * class does not have a custom repository class. + */ public function getCustomRepositoryClass() { return $this->_customRepositoryClassName; @@ -1909,13 +1856,14 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable */ public function setEntityType($type) { - //Doctrine::CLASSTYPE_ENTITY - //Doctrine::CLASSTYPE_MAPPED_SUPERCLASS - //Doctrine::CLASSTYPE_TRANSIENT + //Entity::TYPE_ENTITY + //Entity::TYPE_MAPPED_SUPERCLASS + //Entity::TYPE_TRANSIENT } /** - * + * Binds the entity instance of this class to a specific EntityManager. + * * @todo Implementation. Replaces the bindComponent() methods on the old Doctrine_Manager. * Binding an Entity to a specific EntityManager in 2.0 is the same as binding * it to a Connection in 1.0. @@ -1974,17 +1922,21 @@ class Doctrine_ClassMetadata implements Doctrine_Configurable, Serializable public function hasAttribute($name) { - return false; + return isset($this->_attributes[$name]); } public function getAttribute($name) { - return null; + if ($this->hasAttribute($name)) { + return $this->_attributes[$name]; + } } public function setAttribute($name, $value) { - ; + if ($this->hasAttribute($name)) { + $this->_attributes[$name] = $value; + } } diff --git a/lib/Doctrine/Collection.php b/lib/Doctrine/Collection.php index dfb5a0ca1..9505f107e 100644 --- a/lib/Doctrine/Collection.php +++ b/lib/Doctrine/Collection.php @@ -97,10 +97,6 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator /** * 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_Mapper|string $mapper The mapper used by the collection. * @param string $keyColumn The field name that will be used as the key @@ -120,7 +116,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator } if ($keyField === null) { - $keyField = $mapper->getClassMetadata()->getAttribute(Doctrine::ATTR_COLL_KEY); + //$keyField = $mapper->getClassMetadata()->getAttribute(Doctrine::ATTR_COLL_KEY); } if ($keyField !== null) { @@ -366,6 +362,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator * * @param mixed $key the key of the element * @return boolean + * @todo Rename to containsKey(). */ public function contains($key) { @@ -432,6 +429,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator * Returns the primary keys of all records in the collection. * * @return array An array containing all primary keys. + * @todo Rename. */ public function getPrimaryKeys() { @@ -626,7 +624,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator foreach ($this->data as $key => $record) { foreach ($coll as $k => $related) { if ($related[$foreign] == $record[$local]) { - $this->data[$key]->setRelated($name, $related); + $this->data[$key]->_setRelated($name, $related); } } } @@ -644,7 +642,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator } } - $this->data[$key]->setRelated($name, $sub); + $this->data[$key]->_setRelated($name, $sub); } } else if ($rel instanceof Doctrine_Relation_Association) { // @TODO composite key support @@ -663,7 +661,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator $sub->add($related->get($name)); } } - $this->data[$key]->setRelated($name, $sub); + $this->data[$key]->_setRelated($name, $sub); } } @@ -799,6 +797,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator * @param string $type * @param string $deep * @return void + * @todo Move elsewhere. */ public function exportTo($type, $deep = false) { @@ -817,6 +816,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator * @param string $type * @param string $data * @return void + * @todo Move elsewhere. */ public function importFrom($type, $data) { @@ -868,11 +868,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator * @param Doctrine_Connection $conn optional connection parameter * @return Doctrine_Collection */ - public function save(Doctrine_Connection $conn = null) + public function save() { - if ($conn == null) { - $conn = $this->_mapper->getConnection(); - } + $conn = $this->_mapper->getConnection(); try { $conn->beginInternalTransaction(); @@ -893,18 +891,13 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator } /** - * delete - * single shot delete - * deletes all records from this collection - * and uses only one database query to perform this operation + * Deletes all records from the collection. * - * @return Doctrine_Collection + * @return void */ - public function delete(Doctrine_Connection $conn = null) - { - if ($conn == null) { - $conn = $this->_mapper->getConnection(); - } + public function delete($clearColl = false) + { + $conn = $this->_mapper->getConnection(); try { $conn->beginInternalTransaction(); @@ -919,9 +912,10 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator $conn->rollback(); throw $e; } - - $this->data = array(); - return $this; + + if ($clearColl) { + $this->clear(); + } } @@ -968,4 +962,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator { return $this->relation; } + + public function clear() + { + $this->data = array(); + } } diff --git a/lib/Doctrine/Configurable.php b/lib/Doctrine/Configurable.php index 841781e88..f0d47344d 100644 --- a/lib/Doctrine/Configurable.php +++ b/lib/Doctrine/Configurable.php @@ -19,7 +19,7 @@ * . */ -#namespace Doctrine::Core; +#namespace Doctrine::Common; /** * Doctrine_Configurable diff --git a/lib/Doctrine/Configuration.php b/lib/Doctrine/Configuration.php index ec881ace6..d5985a85c 100644 --- a/lib/Doctrine/Configuration.php +++ b/lib/Doctrine/Configuration.php @@ -1,4 +1,23 @@ . + */ #namespace Doctrine::Common; @@ -6,8 +25,7 @@ /** * The Configuration is the container for all configuration options of Doctrine. - * It combines all configuration options from DBAL & ORM to make it easy for the - * user. + * It combines all configuration options from DBAL & ORM. * * @since 2.0 */ @@ -33,12 +51,20 @@ class Doctrine_Configuration 'metadataCacheLifeSpan' => null ); + /** + * Creates a new configuration that can be used for Doctrine. + */ public function __construct() { $this->_nullObject = Doctrine_Null::$INSTANCE; $this->_initAttributes(); } + /** + * Initializes the attributes. + * + * @return void + */ private function _initAttributes() { // Change null default values to references to the Null object to allow @@ -50,6 +76,12 @@ class Doctrine_Configuration } } + /** + * Gets the value of a configuration attribute. + * + * @param string $name + * @return mixed + */ public function get($name) { if ( ! $this->hasAttribute($name)) { @@ -61,6 +93,12 @@ class Doctrine_Configuration return $this->_attributes[$name]; } + /** + * Sets the value of a configuration attribute. + * + * @param string $name + * @param mixed $value + */ public function set($name, $value) { if ( ! $this->hasAttribute($name)) { @@ -70,6 +108,12 @@ class Doctrine_Configuration $this->_attributes[$name] = $value; } + /** + * Checks whether the configuration contains/supports an attribute. + * + * @param string $name + * @return boolean + */ public function has($name) { return isset($this->_attributes[$name]); diff --git a/lib/Doctrine/Connection.php b/lib/Doctrine/Connection.php index 7342f381b..4a822dccd 100644 --- a/lib/Doctrine/Connection.php +++ b/lib/Doctrine/Connection.php @@ -73,7 +73,7 @@ * Doctrine::DBAL could ship with a simple standard resolver that uses a primitive * round-robin approach to distribution. User can provide its own resolvers. */ -abstract class Doctrine_Connection implements Doctrine_Configurable, Countable +abstract class Doctrine_Connection implements Countable { /** * The PDO database handle. @@ -226,7 +226,7 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable public function __construct(array $params) { if (isset($params['pdo'])) { - $this->dbh = $pdo; + $this->dbh = $params['pdo']; $this->isConnected = true; } $this->_params = $params; @@ -278,6 +278,14 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable return $this->_eventManager; } + public function getProperty($name) + { + if ( ! isset($this->properties[$name])) { + throw Doctrine_Connection_Exception::unknownProperty($name); + } + return $this->properties[$name]; + } + /** * returns an array of available PDO drivers */ @@ -626,10 +634,10 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable if (strpos($str, '.')) { $e = explode('.', $str); - return $this->formatter->quoteIdentifier($e[0], $checkOption) . '.' - . $this->formatter->quoteIdentifier($e[1], $checkOption); + return $this->getFormatter()->quoteIdentifier($e[0], $checkOption) . '.' + . $this->getFormatter()->quoteIdentifier($e[1], $checkOption); } - return $this->formatter->quoteIdentifier($str, $checkOption); + return $this->getFormatter()->quoteIdentifier($str, $checkOption); } /** @@ -644,7 +652,7 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable */ public function convertBooleans($item) { - return $this->formatter->convertBooleans($item); + return $this->getFormatter()->convertBooleans($item); } /** @@ -915,8 +923,8 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable */ public function rethrowException(Exception $e, $invoker) { - $event = new Doctrine_Event($this, Doctrine_Event::CONN_ERROR); - $this->getListener()->preError($event); + //$event = new Doctrine_Event($this, Doctrine_Event::CONN_ERROR); + //$this->getListener()->preError($event); $name = 'Doctrine_Connection_' . $this->driverName . '_Exception'; @@ -930,7 +938,7 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable throw $exc; } - $this->getListener()->postError($event); + //$this->getListener()->postError($event); } /** @@ -951,15 +959,15 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable */ public function close() { - $event = new Doctrine_Event($this, Doctrine_Event::CONN_CLOSE); - $this->getAttribute(Doctrine::ATTR_LISTENER)->preClose($event); + //$event = new Doctrine_Event($this, Doctrine_Event::CONN_CLOSE); + //this->getAttribute(Doctrine::ATTR_LISTENER)->preClose($event); $this->clear(); unset($this->dbh); $this->isConnected = false; - $this->getAttribute(Doctrine::ATTR_LISTENER)->postClose($event); + //$this->getAttribute(Doctrine::ATTR_LISTENER)->postClose($event); } /** @@ -1052,7 +1060,6 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable } /** - * rollback * Cancel any database changes done during a transaction or since a specific * savepoint that is in progress. This function may only be called when * auto-committing is disabled, otherwise it will fail. Therefore, a new @@ -1061,9 +1068,9 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable * this method can be listened with onPreTransactionRollback and onTransactionRollback * eventlistener methods * - * @param string $savepoint name of a savepoint to rollback to - * @throws Doctrine_Transaction_Exception if the rollback operation fails at database level - * @return boolean false if rollback couldn't be performed, true otherwise + * @param string $savepoint Name of a savepoint to rollback to. + * @throws Doctrine_Transaction_Exception If the rollback operation fails at database level. + * @return boolean FALSE if rollback couldn't be performed, TRUE otherwise. */ public function rollback($savepoint = null) { @@ -1071,11 +1078,11 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable } /** - * createDatabase + * Creates the database for the connection instance. * - * Method for creating the database for the connection instance - * - * @return mixed Will return an instance of the exception thrown if the create database fails, otherwise it returns a string detailing the success + * @return mixed Will return an instance of the exception thrown if the + * create database fails, otherwise it returns a string + * detailing the success. */ public function createDatabase() { @@ -1116,7 +1123,8 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable * * Method for dropping the database for the connection instance * - * @return mixed Will return an instance of the exception thrown if the drop database fails, otherwise it returns a string detailing the success + * @return mixed Will return an instance of the exception thrown if the drop + * database fails, otherwise it returns a string detailing the success. */ public function dropDatabase() { @@ -1154,104 +1162,22 @@ abstract class Doctrine_Connection implements Doctrine_Configurable, Countable * * @param integer $attribute * @return mixed + * @todo Implementation or remove if not needed. Configuration is the main + * container for all the attributes now. */ public function getAttribute($attribute) { if ($attribute == Doctrine::ATTR_QUOTE_IDENTIFIER) { return false; } - - /* legacy */ - if ($attribute >= 100) { - if ( ! isset($this->_attributes[$attribute])) { - return null; - } - return $this->_attributes[$attribute]; - } - - if ($this->isConnected) { - try { - return $this->dbh->getAttribute($attribute); - } catch (Exception $e) { - throw new Doctrine_Connection_Exception('Attribute ' . $attribute . ' not found.'); - } - } else { - if ( ! isset($this->pendingAttributes[$attribute])) { - $this->connect(); - $this->getAttribute($attribute); - } - - return $this->pendingAttributes[$attribute]; - } } - /** - * setAttribute - * sets an attribute - * - * @todo why check for >= 100? has this any special meaning when creating - * attributes? - * - * @param integer $attribute - * @param mixed $value - * @return boolean - */ - public function setAttribute($attribute, $value) - { - if ($attribute >= 100) { - parent::setAttribute($attribute, $value); - } else { - if ($this->isConnected) { - $this->dbh->setAttribute($attribute, $value); - } else { - $this->pendingAttributes[$attribute] = $value; - } - } - return $this; - } - public function hasAttribute($name) + public function getFormatter() { - return false; + if ( ! $this->modules['formatter']) { + $this->modules['formatter'] = new Doctrine_Formatter($this); + } + return $this->modules['formatter']; } - - /** - * __get - * lazy loads given module and returns it - * - * @see Doctrine_DataDict - * @see Doctrine_Expression - * @see Doctrine_Export - * @see Doctrine_Transaction - * @see Doctrine_Connection::$modules all availible modules - * @param string $name the name of the module to get - * @throws Doctrine_Connection_Exception if trying to get an unknown module - * @return Doctrine_Connection_Module connection module - */ - public function __get($name) - { - if (isset($this->properties[$name])) { - return $this->properties[$name]; - } - - if ( ! isset($this->modules[$name])) { - throw new Doctrine_Connection_Exception('Unknown module / property ' . $name); - } - if ($this->modules[$name] === false) { - switch ($name) { - case 'unitOfWork': - $this->modules[$name] = new Doctrine_Connection_UnitOfWork($this); - break; - case 'formatter': - $this->modules[$name] = new Doctrine_Formatter($this); - break; - default: - $class = 'Doctrine_' . ucwords($name) . '_' . $this->getDriverName(); - $this->modules[$name] = new $class($this); - } - } - - return $this->modules[$name]; - } - } diff --git a/lib/Doctrine/Connection/Firebird.php b/lib/Doctrine/Connection/Firebird.php index 5755712a7..8afa0edde 100644 --- a/lib/Doctrine/Connection/Firebird.php +++ b/lib/Doctrine/Connection/Firebird.php @@ -18,7 +18,7 @@ * and is licensed under the LGPL. For more information, see * . */ -Doctrine::autoload('Doctrine_Connection'); + /** * Doctrine_Connection_Firebird * @@ -101,7 +101,10 @@ class Doctrine_Connection_Firebird extends Doctrine_Connection * @return string modified query */ public function modifyLimitQuery($query, $limit, $offset) - { + { + if ( ! $offset) { + $offset = 0; + } if ($limit > 0) { $query = preg_replace('/^([\s(])*SELECT(?!\s*FIRST\s*\d+)/i', "SELECT FIRST $limit SKIP $offset", $query); diff --git a/lib/Doctrine/Connection/Mysql.php b/lib/Doctrine/Connection/Mysql.php index a3f4159b2..b01aed9a5 100644 --- a/lib/Doctrine/Connection/Mysql.php +++ b/lib/Doctrine/Connection/Mysql.php @@ -35,8 +35,10 @@ */ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common { - /** - * @var string $driverName the name of this connection driver + /** + * Driver name. + * + * @var string */ protected $driverName = 'Mysql'; @@ -46,11 +48,8 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common * @param Doctrine_Manager $manager * @param PDO|Doctrine_Adapter $adapter database handler */ - public function __construct($adapter, $user = null, $pass = null) + public function __construct(array $params) { - $this->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); - $this->setAttribute(Doctrine::ATTR_DEFAULT_TABLE_TYPE, 'INNODB'); - $this->supported = array( 'sequences' => 'emulated', 'indexes' => true, @@ -91,7 +90,7 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common $this->properties['varchar_max_length'] = 255; - parent::__construct($adapter, $user, $pass); + parent::__construct($params); } /** diff --git a/lib/Doctrine/Connection/Sqlite.php b/lib/Doctrine/Connection/Sqlite.php index 8d437026e..8910ef875 100644 --- a/lib/Doctrine/Connection/Sqlite.php +++ b/lib/Doctrine/Connection/Sqlite.php @@ -17,9 +17,9 @@ * This software consists of voluntary contributions made by many individuals * and is licensed under the LGPL. For more information, see * . - */ - -Doctrine::autoload("Doctrine_Connection_Common"); + */ + +#namespace Doctrine::DBAL::Connections; /** * Doctrine_Connection_Sqlite @@ -46,9 +46,10 @@ class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common * @param Doctrine_Manager $manager * @param PDO $pdo database handle */ - public function __construct($adapter, $user = null, $pass = null) + public function __construct(array $params) { - $this->supported = array('sequences' => 'emulated', + $this->supported = array( + 'sequences' => 'emulated', 'indexes' => true, 'affected_rows' => true, 'summary_functions' => true, @@ -67,10 +68,10 @@ class Doctrine_Connection_Sqlite extends Doctrine_Connection_Common 'identifier_quoting' => true, 'pattern_escaping' => false, ); - parent::__construct($adapter, $user, $pass); + parent::__construct($params); if ($this->isConnected) { - $this->dbh->sqliteCreateFunction('mod', array('Doctrine_Expression_Sqlite', 'modImpl'), 2); + $this->dbh->sqliteCreateFunction('mod', array('Doctrine_Expression_Sqlite', 'modImpl'), 2); $this->dbh->sqliteCreateFunction('md5', 'md5', 1); $this->dbh->sqliteCreateFunction('now', 'time', 0); } diff --git a/lib/Doctrine/Connection/UnitOfWork.php b/lib/Doctrine/Connection/UnitOfWork.php index 9d561942e..1590d49e6 100644 --- a/lib/Doctrine/Connection/UnitOfWork.php +++ b/lib/Doctrine/Connection/UnitOfWork.php @@ -54,16 +54,7 @@ * @todo package:orm. Figure out a useful implementation. */ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module -{ - /** - * A map of all currently managed entities. - * - * @var array - * @deprecated Only here to keep the saveAll() functionality working. We don't need - * this in the future. - */ - protected $_managedEntities = array(); - +{ /** * The identity map that holds references to all managed entities that have * an identity. The entities are grouped by their class name. @@ -131,7 +122,9 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module throw new Doctrine_Connection_Exception("Entity without identity " . "can't be registered as new."); } + $oid = $entity->getOid(); + if (isset($this->_dirtyEntities[$oid])) { throw new Doctrine_Connection_Exception("Dirty object can't be registered as new."); } else if (isset($this->_removedEntities[$oid])) { @@ -139,6 +132,8 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module } else if (isset($this->_newEntities[$oid])) { throw new Doctrine_Connection_Exception("Object already registered as new. Can't register twice."); } + + $this->registerIdentity($entity); $this->_newEntities[$oid] = $entity; } @@ -216,10 +211,10 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module * @param array $tables an array of Doctrine_Table objects or component names * @return array an array of component names in flushing order */ - public function buildFlushTree(array $mappers) + public function buildFlushTree(array $entityNames) { $tree = array(); - foreach ($mappers as $k => $mapper) { + foreach ($entityNames as $k => $entity) { if ( ! ($mapper instanceof Doctrine_Mapper)) { $mapper = $this->conn->getMapper($mapper); } @@ -487,6 +482,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module if ( ! $idHash) { return false; } + return isset($this->_identityMap [$entity->getClassMetadata()->getRootClassName()] [$idHash]); diff --git a/lib/Doctrine/ConnectionFactory.php b/lib/Doctrine/ConnectionFactory.php index e2f296671..0e3b6dd99 100644 --- a/lib/Doctrine/ConnectionFactory.php +++ b/lib/Doctrine/ConnectionFactory.php @@ -1,9 +1,39 @@ . + */ #namespace Doctrine::DBAL; +/** + * Factory for creating dbms-specific Connection instances. + * + * @author Roman Borschel + * @since 2.0 + */ class Doctrine_ConnectionFactory { + /** + * List of supported drivers and their mappings to the driver class. + * + * @var array + */ private $_drivers = array( 'mysql' => 'Doctrine_Connection_Mysql', 'sqlite' => 'Doctrine_Connection_Sqlite', @@ -24,13 +54,26 @@ class Doctrine_ConnectionFactory public function createConnection(array $params) { - $this->_checkParams($params); + // check for existing pdo object + if (isset($params['pdo']) && ! $params['pdo'] instanceof PDO) { + throw Doctrine_ConnectionFactory_Exception::invalidPDOInstance(); + } else if (isset($params['pdo'])) { + $params['driver'] = $params['pdo']->getAttribute(PDO::ATTR_DRIVER_NAME); + } else { + $this->_checkParams($params); + } $className = $this->_drivers[$params['driver']]; + return new $className($params); } + /** + * Checks the list of parameters. + * + * @param array $params + */ private function _checkParams(array $params) - { + { // check existance of mandatory parameters // driver @@ -52,10 +95,6 @@ class Doctrine_ConnectionFactory if ( ! isset($this->_drivers[$params['driver']])) { throw Doctrine_ConnectionFactory_Exception::unknownDriver($driverName); } - // existing pdo object - if (isset($params['pdo']) && ! $params['pdo'] instanceof PDO) { - throw Doctrine_ConnectionFactory_Exception::invalidPDOInstance(); - } } } diff --git a/lib/Doctrine/Entity.php b/lib/Doctrine/Entity.php index 68df602e8..e394970a4 100644 --- a/lib/Doctrine/Entity.php +++ b/lib/Doctrine/Entity.php @@ -23,7 +23,11 @@ /** * Doctrine_Entity - * All record classes should inherit this super class + * All record classes should inherit this super class. + * + * NOTE: Methods that are intended for internal use only but must be public + * are marked INTERNAL: and begin with an underscore "_" to indicate that they + * ideally would not be public and to minimize naming collisions. * * @package Doctrine * @subpackage Entity @@ -33,53 +37,50 @@ * @link www.phpdoctrine.org * @since 2.0 * @version $Revision: 4342 $ - * @todo Rename to "Entity". Split up into "Entity" and "ActiveEntity (extends Entity)"??? + * @todo Split up into "Entity" and "ActiveEntity (extends Entity)"??? * @todo Remove as many methods as possible. */ -abstract class Doctrine_Entity extends Doctrine_Access implements Countable, IteratorAggregate, Serializable +abstract class Doctrine_Entity extends Doctrine_Access implements Serializable { - /** - * STATE CONSTANTS - */ - /** * DIRTY STATE - * a Doctrine_Entity is in dirty state when its properties are changed + * An Entity is in dirty state when its properties are changed. */ const STATE_DIRTY = 1; /** * TDIRTY STATE - * a Doctrine_Entity is in transient dirty state when it is created - * and some of its fields are modified but it is NOT yet persisted into database + * An Entity is in transient dirty state when it is created and some of its + * fields are modified but it is NOT yet persisted into database. */ const STATE_TDIRTY = 2; /** * CLEAN STATE - * a Doctrine_Entity is in clean state when all of its properties are loaded from the database - * and none of its properties are changed + * An Entity is in clean state when all of its properties are loaded from the database + * and none of its properties are changed. */ const STATE_CLEAN = 3; /** * PROXY STATE - * a Doctrine_Entity is in proxy state when its properties are not fully loaded + * An Entity is in proxy state when its properties are not fully loaded. */ const STATE_PROXY = 4; /** * NEW TCLEAN - * a Doctrine_Entity is in transient clean state when it is created and none of its fields are modified + * An Entity is in transient clean state when it is created and none of its + * fields are modified. */ const STATE_TCLEAN = 5; /** * LOCKED STATE - * a Doctrine_Entity is temporarily locked during deletes and saves + * An Entity is temporarily locked during deletes and saves. * * This state is used internally to ensure that circular deletes - * and saves will not cause infinite loops + * and saves will not cause infinite loops. */ const STATE_LOCKED = 6; @@ -98,63 +99,52 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite private static $_useAutoAccessorOverride; /** - * The accessor cache is used as a memory for the existance of custom accessors - * for fields. + * The accessor cache is used as a memory for the existance of custom accessors. * * @var array */ private static $_accessorCache = array(); /** - * The mutator cache is used as a memory for the existance of custom mutators - * for fields. + * The mutator cache is used as a memory for the existance of custom mutators. * * @var array */ private static $_mutatorCache = array(); /** - * The metadata container that describes the entity class. + * The class descriptor. * - * @var Doctrine_ClassMetadata - * @todo Lazy initialization. + * @var ClassMetadata */ - protected $_class; + private $_class; /** * The name of the Entity. * * @var string */ - protected $_entityName; + private $_entityName; /** * @var Doctrine_Node_ node object * @todo Specific to the NestedSet Behavior plugin. Move outta here. */ - protected $_node; + //protected $_node; /** - * The values that make up the ID/primary key of the object. + * The values that make up the ID/primary key of the entity. * * @var array */ - protected $_id = array(); + private $_id = array(); /** - * The record data. + * The entity data. * * @var array */ - protected $_data = array(); - - /** - * The values array, aggregate values and such are mapped into this array. - * - * @var array - * @todo Remove. - */ - protected $_values = array(); + private $_data = array(); /** * The state of the object. @@ -162,7 +152,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @var integer * @see STATE_* constants */ - protected $_state; + private $_state; /** * The names of fields that have been modified but not yet persisted. @@ -170,33 +160,25 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @var array * @todo Better name? $_modifiedFields? */ - protected $_modified = array(); - - /** - * The error stack used to collect errors during validation. - * - * @var Doctrine_Validator_ErrorStack - * @internal Uses lazy initialization to reduce memory usage. - */ - protected $_errorStack; + private $_modified = array(); /** * The references for all associations of the entity to other entities. * * @var array */ - protected $_references = array(); + private $_references = array(); /** * The EntityManager that is responsible for the persistence of the entity. * * @var Doctrine_EntityManager - * @todo Lazy initialization. */ - protected $_em; + private $_em; /** - * The object identifier of the object. Each object has a unique identifier during runtime. + * The object identifier of the object. Each object has a unique identifier + * during script execution. * * @var integer */ @@ -204,53 +186,23 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite /** * Constructor. - * - * @param Doctrine_Table|null $table a Doctrine_Table object or null, - * if null the table object is retrieved from current connection - * - * @param boolean $isNewEntry whether or not this record is transient - * - * @throws Doctrine_Connection_Exception if object is created using the new operator and there are no - * open connections - * @throws Doctrine_Record_Exception if the cleanData operation fails somehow - * @todo Remove all parameters. */ - public function __construct($isNewEntry = true, array $data = array()) + public function __construct() { $this->_entityName = get_class($this); $this->_em = Doctrine_EntityManagerFactory::getManager($this->_entityName); $this->_class = $this->_em->getClassMetadata($this->_entityName); $this->_oid = self::$_index++; - - - // The following code inits data, id and state - - // get the data array - $this->_data = $data; - - // get the column count - $count = count($this->_data); - - $this->_extractIdentifier( ! $isNewEntry); - - if ($isNewEntry) { - if ($count > 0) { - $this->_state = Doctrine_Entity::STATE_TDIRTY; - } else { - $this->_state = Doctrine_Entity::STATE_TCLEAN; - } - // set the default values for this record - $this->assignDefaultValues(); + $this->_data = $this->_em->_getTmpEntityData(); + if ($this->_data) { + $this->_extractIdentifier(); + $this->_state = self::STATE_CLEAN; } else { - // TODO: registerClean() on UnitOfWork - $this->_state = Doctrine_Entity::STATE_CLEAN; - if ($count < $this->_class->getColumnCount()) { - $this->_state = Doctrine_Entity::STATE_PROXY; - } + $this->_state = self::STATE_TCLEAN; } - //-- - self::$_useAutoAccessorOverride = true; // @todo read from attribute the first time + // @todo read from attribute the first time and move this initialization elsewhere. + self::$_useAutoAccessorOverride = true; } /** @@ -258,24 +210,13 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * * @return integer */ - public static function _index() + /*public static function _index() { return self::$_index; - } + }*/ /** - * construct - * Empty template method to provide concrete Record classes with the possibility - * to hook into the constructor procedure - * - * @return void - */ - public function construct() - { } - - /** - * getOid - * returns the object identifier + * Returns the object identifier. * * @return integer */ @@ -283,64 +224,6 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite { return $this->_oid; } - - /** - * isValid - * - * @return boolean whether or not this record is valid - * @todo Move to new Validator implementation (once we have it). - */ - public function isValid() - { - if ( ! $this->_class->getAttribute(Doctrine::ATTR_VALIDATE)) { - return true; - } - - // Clear the stack from any previous errors. - $this->getErrorStack()->clear(); - - // Run validation process - $validator = new Doctrine_Validator(); - $validator->validateRecord($this); - $this->validate(); - if ($this->_state == self::STATE_TDIRTY || $this->_state == self::STATE_TCLEAN) { - $this->validateOnInsert(); - } else { - $this->validateOnUpdate(); - } - - return $this->getErrorStack()->count() == 0 ? true : false; - } - - /** - * Empty template method to provide concrete Record classes with the possibility - * to hook into the validation procedure, doing any custom / specialized - * validations that are neccessary. - * - * @todo Move to new Validator implementation (once we have it). - */ - protected function validate() - { } - - /** - * Empty template method to provide concrete Record classes with the possibility - * to hook into the validation procedure only when the record is going to be - * updated. - * - * @todo Move to new Validator implementation (once we have it). - */ - protected function validateOnUpdate() - { } - - /** - * Empty template method to provide concrete Record classes with the possibility - * to hook into the validation procedure only when the record is going to be - * inserted into the data store the first time. - * - * @todo Move to new Validator implementation (once we have it). - */ - protected function validateOnInsert() - { } /** * Empty template method to provide concrete Record classes with the possibility @@ -429,40 +312,6 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite */ public function postInsert() { } - - /** - * getErrorStack - * - * @return Doctrine_Validator_ErrorStack returns the errorStack associated with this record - * @todo Move to new Validator implementation (once we have it). - */ - public function getErrorStack() - { - if (is_null($this->_errorStack)) { - $this->_errorStack = new Doctrine_Validator_ErrorStack(); - } - return $this->_errorStack; - } - - /** - * errorStack - * assigns / returns record errorStack - * - * @param Doctrine_Validator_ErrorStack errorStack to be assigned for this record - * @return void|Doctrine_Validator_ErrorStack returns the errorStack associated with this record - * @todo Move to new Validator implementation (once we have it). - */ - public function errorStack($stack = null) - { - if ($stack !== null) { - if ( ! ($stack instanceof Doctrine_Validator_ErrorStack)) { - throw new Doctrine_Entity_Exception('Argument should be an instance of Doctrine_Validator_ErrorStack.'); - } - $this->_errorStack = $stack; - } else { - return $this->getErrorStack(); - } - } /** * setDefaultValues @@ -471,8 +320,11 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @param boolean $overwrite whether or not to overwrite the already set values * @return boolean * @todo Job of EntityManager. + * @deprecated + * Setting object-level default field values is much more natural to do in + * the constructor and database-level default values are set by the database. */ - public function assignDefaultValues($overwrite = false) + /*public function assignDefaultValues($overwrite = false) { if ( ! $this->_class->hasDefaultValues()) { return false; @@ -490,7 +342,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite $this->_state = Doctrine_Entity::STATE_TDIRTY; } } - } + }*/ /** * cleanData @@ -502,7 +354,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @return array $tmp values cleaned from data * @todo Remove. Should not be necessary. Slows down instantiation. */ - public function cleanData(&$data) + /*public function cleanData(&$data) { $tmp = $data; $data = array(); @@ -520,7 +372,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } return $tmp; - } + }*/ /** * hydrate @@ -528,24 +380,21 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * * @param array $data * @return boolean - * @todo ActiveRecord method */ public function hydrate(array $data) { - $this->_values = array_merge($this->_values, $this->cleanData($data)); - $this->_data = array_merge($this->_data, $data); - $this->_extractIdentifier(true); + $this->_data = array_merge($this->_data, $data); + //$this->_extractIdentifier(true); } /** - * prepareIdentifiers - * prepares identifiers for later use + * Copies the identifier names and values from _data into _id. * * @param boolean $exists whether or not this record exists in persistent data store * @return void - * @todo Maybe better placed in the Mapper? + * @todo Looks like its better placed elsewhere (EntityManager?) */ - private function _extractIdentifier($exists = true) + private function _extractIdentifier() { switch ($this->_class->getIdentifierType()) { case Doctrine::IDENTIFIER_AUTOINC: @@ -553,15 +402,12 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite case Doctrine::IDENTIFIER_NATURAL: $name = $this->_class->getIdentifier(); $name = $name[0]; - if ($exists) { - if (isset($this->_data[$name]) && $this->_data[$name] !== Doctrine_Null::$INSTANCE) { - $this->_id[$name] = $this->_data[$name]; - } + if (isset($this->_data[$name]) && $this->_data[$name] !== Doctrine_Null::$INSTANCE) { + $this->_id[$name] = $this->_data[$name]; } break; case Doctrine::IDENTIFIER_COMPOSITE: $names = $this->_class->getIdentifier(); - foreach ($names as $name) { if ($this->_data[$name] === Doctrine_Null::$INSTANCE) { $this->_id[$name] = null; @@ -576,7 +422,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite /** * INTERNAL: */ - final public function setIdentifier(array $identifier) + final public function _setIdentifier(array $identifier) { $this->_id = $identifier; } @@ -680,14 +526,13 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } } - $this->cleanData($this->_data); - $this->_extractIdentifier($this->exists()); + $this->_extractIdentifier(!$this->isNew()); //$this->postUnserialize($event); } /** - * state + * INTERNAL: * returns / assigns the state of this record * * @param integer|string $state if set, this method tries to set the record state to $state @@ -696,41 +541,33 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @throws Doctrine_Record_State_Exception if trying to set an unknown state * @return null|integer */ - public function state($state = null) + final public function _state($state = null) { if ($state == null) { return $this->_state; } - $err = false; - if (is_integer($state)) { - if ($state >= 1 && $state <= 6) { + + /* TODO: Do we really need this check? This is only for internal use after all. */ + switch ($state) { + case self::STATE_TCLEAN: + case self::STATE_CLEAN: + case self::STATE_TDIRTY: + case self::STATE_DIRTY: + case self::STATE_PROXY: + case self::STATE_LOCKED: $this->_state = $state; - } else { - $err = true; - } - } else if (is_string($state)) { - $upper = strtoupper($state); - - $const = 'Doctrine_Entity::STATE_' . $upper; - if (defined($const)) { - $this->_state = constant($const); - } else { - $err = true; - } + break; + default: + throw Doctrine_Entity_Exception::invalidState($state); } if ($this->_state === Doctrine_Entity::STATE_TCLEAN || $this->_state === Doctrine_Entity::STATE_CLEAN) { $this->_modified = array(); } - - if ($err) { - throw new Doctrine_Record_Exception("Unknown record state '$state'."); - } } /** - * refresh * refresh internal data from the database * * @param bool $deep If true, fetch also current relations. Caution: this deletes @@ -754,7 +591,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite $id = array_values($id); if ($deep) { - $query = $this->_class->getConnection()->createQuery()->from($this->_entityName); + $query = $this->_em->createQuery()->from($this->_entityName); foreach (array_keys($this->_references) as $name) { $query->leftJoin(get_class($this) . '.' . $name); } @@ -793,7 +630,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @todo Implementation to EntityManager. * @todo ActiveEntity method. */ - public function refreshRelated($name = null) + /*public function refreshRelated($name = null) { if (is_null($name)) { foreach ($this->_class->getRelations() as $rel) { @@ -803,7 +640,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite $rel = $this->_class->getRelation($name); $this->_references[$name] = $rel->fetchRelatedFor($this); } - } + }*/ /** * clearRelated @@ -811,30 +648,33 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * * (references to related objects still remain on Table objects) */ - public function clearRelated() + /*public function clearRelated() { $this->_references = array(); - } + }*/ /** - * Gets the current property values. + * Gets the current field values. * - * @return array The current properties and their values. + * @return array The fields and their values. */ - public function getData() + final public function getData() { return $this->_data; } /** - * @todo Remove. + * INTERNAL: + * For internal hydration purposes only. */ - public function getValues() + /*final public function _setData(array $data) { - return $this->_values; - } + $this->_data = $data; + $this->_extractIdentifier(); + }*/ /** + * INTERNAL: (Usage from within extending classes is fine) * Gets the value of a field (regular field or reference). * If the property is not yet loaded this method does NOT load it. * @@ -845,28 +685,53 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @throws Doctrine_Entity_Exception if trying to get an unknown field * @return mixed */ - public function rawGet($fieldName) + final public function _rawGet($fieldName) { if (isset($this->_data[$fieldName])) { - return $this->rawGetField($fieldName); + return $this->_rawGetField($fieldName); } else if (isset($this->_references[$fieldName])) { - return $this->rawGetReference($fieldName); + return $this->_rawGetReference($fieldName); } else { throw Doctrine_Entity_Exception::unknownField($fieldName); } } /** + * INTERNAL: (Usage from within extending classes is fine) + * Sets the value of a field (regular field or reference). + * If the field is not yet loaded this method does NOT load it. + * + * NOTE: Use of this method from outside the scope of an extending class + * is strongly discouraged. + * + * @param $name name of the field + * @throws Doctrine_Entity_Exception if trying to get an unknown field + * @return mixed + */ + final public function _rawSet($fieldName, $value) + { + if (isset($this->_data[$fieldName])) { + return $this->_rawSetField($fieldName, $value); + } else if (isset($this->_references[$fieldName])) { + return $this->_rawSetReference($fieldName, $value); + } else { + throw Doctrine_Entity_Exception::unknownField($fieldName); + } + } + + /** + * INTERNAL: * Gets the value of a field. * * NOTE: Use of this method from outside the scope of an extending class * is strongly discouraged. This method does NOT check whether the field - * exists. + * exists. _rawGet() in extending classes should be preferred. * * @param string $fieldName * @return mixed + * @todo Rename to _unsafeGetField() */ - public function rawGetField($fieldName) + final public function _rawGetField($fieldName) { if ($this->_data[$fieldName] === Doctrine_Null::$INSTANCE) { return null; @@ -875,16 +740,18 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } /** + * INTERNAL: * Sets the value of a field. * * NOTE: Use of this method from outside the scope of an extending class * is strongly discouraged. This method does NOT check whether the field - * exists. + * exists. _rawSet() in extending classes should be preferred. * * @param string $fieldName * @param mixed $value + * @todo Rename to _unsafeSetField() */ - public function rawSetField($fieldName, $value) + final public function _rawSetField($fieldName, $value) { $this->_data[$fieldName] = $value; } @@ -897,8 +764,9 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * exists. * * @param unknown_type $fieldName + * @todo Rename to _unsafeGetReference(). */ - public function rawGetReference($fieldName) + final public function _rawGetReference($fieldName) { if ($this->_references[$fieldName] === Doctrine_Null::$INSTANCE) { return null; @@ -907,16 +775,18 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } /** + * INTERNAL: * Sets a reference to another Entity. * * NOTE: Use of this method from outside the scope of an extending class * is strongly discouraged. * - * @param unknown_type $fieldName - * @param unknown_type $value + * @param string $fieldName + * @param mixed $value * @todo Refactor. What about composite keys? + * @todo Rename to _unsafeSetReference() */ - public function rawSetReference($name, $value) + final public function _rawSetReference($name, $value) { if ($value === Doctrine_Null::$INSTANCE) { $this->_references[$name] = $value; @@ -949,7 +819,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite if ($rel instanceof Doctrine_Relation_LocalKey) { $idFieldNames = $value->getTable()->getIdentifier(); if ( ! empty($foreignFieldName) && $foreignFieldName != $idFieldNames[0]) { - $this->set($localFieldName, $value->rawGet($foreignFieldName), false); + $this->set($localFieldName, $value->_rawGet($foreignFieldName), false); } else { $this->set($localFieldName, $value, false); } @@ -967,13 +837,12 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } /** - * load - * loads all the uninitialized properties from the database + * loads all the uninitialized properties from the database. * * @return boolean * @todo ActiveRecord method. */ - public function load() + /*public function load() { // only load the data from database if the Doctrine_Entity is in proxy state if ($this->_state == Doctrine_Entity::STATE_PROXY) { @@ -982,18 +851,17 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite return true; } return false; - } + }*/ /** - * get - * returns a value of a property or a related component + * Generic getter. * * @param mixed $name name of the property or related component * @param boolean $load whether or not to invoke the loading procedure * @throws Doctrine_Record_Exception if trying to get a value of unknown property / related component * @return mixed */ - public function get($fieldName, $load = false) + final public function get($fieldName) { if ($getter = $this->_getCustomAccessor($fieldName)) { return $this->$getter(); @@ -1008,17 +876,13 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite return $this->_references[$fieldName] !== $nullObj ? $this->_references[$fieldName] : null; } else { - if ($this->_class->hasField($fieldName)) { - if ($load) { - $this->load(); - return $this->get($fieldName); - } else { - return null; - } - } else if ($this->_class->hasRelation($fieldName)) { - if ($load) { - $rel = $this->_class->getRelation($fieldName); - $this->_references[$fieldName] = $rel->fetchRelatedFor($this); + $class = $this->_class; + if ($class->hasField($fieldName)) { + return null; + } else if ($class->hasRelation($fieldName)) { + $rel = $class->getRelation($fieldName); + if ($rel->isLazilyLoaded()) { + $this->_references[$fieldName] = $rel->lazyLoadFor($this); return $this->_references[$fieldName] !== $nullObj ? $this->_references[$fieldName] : null; } else { @@ -1073,15 +937,18 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite return self::$_accessorCache[$this->_entityName][$fieldName]; } - public function getClassName() + /** + * Gets the entity class name. + * + * @return string + */ + final public function getClassName() { return $this->_entityName; } /** - * set - * method for altering properties and Doctrine_Entity references - * if the load parameter is set to false this method will not try to load uninitialized record data + * Generic setter. * * @param mixed $name name of the property or reference * @param mixed $value value of the property or reference @@ -1089,18 +956,17 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * * @throws Doctrine_Record_Exception if trying to set a value for unknown property / related component * @throws Doctrine_Record_Exception if trying to set a value of wrong type for related component - * - * @return Doctrine_Entity */ - public function set($fieldName, $value, $load = false) + final public function set($fieldName, $value) { if ($setter = $this->_getCustomMutator($fieldName)) { return $this->$setter($value); } - if ($this->_class->hasField($fieldName)) { + $class = $this->_class; + if ($class->hasField($fieldName)) { if ($value instanceof Doctrine_Entity) { - $type = $this->_class->getTypeOf($fieldName); + $type = $class->getTypeOf($fieldName); // FIXME: composite key support $ids = $value->identifier(); $id = count($ids) > 0 ? array_pop($ids) : null; @@ -1109,11 +975,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } } - if ($load) { - $old = $this->get($fieldName, true); - } else { - $old = isset($this->_data[$fieldName]) ? $this->_data[$fieldName] : null; - } + $old = isset($this->_data[$fieldName]) ? $this->_data[$fieldName] : null; if ($old !== $value) { $this->_data[$fieldName] = $value; @@ -1121,7 +983,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite /* We can't do this currently because there are tests that change * the primary key of already persisted entities (ugh). */ - if ($this->isTransient() && $this->_class->isIdentifier($fieldName)) { + if ($this->isTransient() && $class->isIdentifier($fieldName)) { $this->_id[$fieldName] = $value; } @@ -1134,8 +996,8 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite break; } } - } else if ($this->_class->hasRelation($fieldName)) { - $this->rawSetReference($fieldName, $value); + } else if ($class->hasRelation($fieldName)) { + $this->_rawSetReference($fieldName, $value); } else { throw Doctrine_Entity_Exception::invalidField($fieldName); } @@ -1147,7 +1009,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @param string $name * @return boolean */ - public function contains($fieldName) + final public function contains($fieldName) { if (isset($this->_data[$fieldName])) { if ($this->_data[$fieldName] === Doctrine_Null::$INSTANCE) { @@ -1158,9 +1020,6 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite if (isset($this->_id[$fieldName])) { return true; } - if (isset($this->_values[$fieldName])) { - return true; - } if (isset($this->_references[$fieldName]) && $this->_references[$fieldName] !== Doctrine_Null::$INSTANCE) { return true; @@ -1172,7 +1031,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @param string $name * @return void */ - public function remove($fieldName) + final public function remove($fieldName) { if (isset($this->_data[$fieldName])) { $this->_data[$fieldName] = array(); @@ -1192,35 +1051,15 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * * @param Doctrine_Connection $conn optional connection parameter * @return void - * @todo ActiveRecord method. + * @todo ActiveEntity method. */ - public function save(Doctrine_Connection $conn = null) + public function save() { // TODO: Forward to EntityManager. There: registerNew() OR registerDirty() on UnitOfWork. - $this->_em->save($this, $conn); + $this->_em->save($this); } /** - * Tries to save the object and all its related objects. - * In contrast to Doctrine_Entity::save(), this method does not - * throw an exception when validation fails but returns TRUE on - * success or FALSE on failure. - * - * @param Doctrine_Connection $conn optional connection parameter - * @return TRUE if the record was saved sucessfully without errors, FALSE otherwise. - * @todo ActiveRecord method. Find new place in new Validation system. - */ - public function trySave(Doctrine_Connection $conn = null) { - try { - $this->save($conn); - return true; - } catch (Doctrine_Validator_Exception $ignored) { - return false; - } - } - - /** - * replace * Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT * query, except that if there is already a row in the table with the same * key field values, the REPLACE query just updates its values instead of @@ -1236,25 +1075,14 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @throws Doctrine_Connection_Exception if there were no key fields * @throws Doctrine_Connection_Exception if something fails at database level * @return integer number of rows affected - * @todo ActiveRecord method. + * @todo ActiveEntity method. */ - public function replace(Doctrine_Connection $conn = null) + public function replace() { - if ($conn === null) { - $conn = $this->_em; - } - - return $conn->replace($this->_class, $this->getPrepared(), $this->_id); - } - - /** - * returns an array of modified fields and associated values - * @return array - * @deprecated - */ - public function getModified() - { - return $this->getModifiedFields(); + return $this->_em->replace( + $this->_class, + $this->getPrepared(), + $this->_id); } /** @@ -1263,7 +1091,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * * @return array */ - public function getModifiedFields() + final public function getModifiedFields() { $a = array(); foreach ($this->_modified as $k => $v) { @@ -1273,17 +1101,15 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } /** - * getPrepared - * - * returns an array of modified fields and values with data preparation + * Returns an array of modified fields and values with data preparation * adds column aggregation inheritance and converts Records into primary key values * * @param array $array * @return array * @todo What about a little bit more expressive name? getPreparedData? - * @todo Maybe not the best place here ... need to think about it. + * @todo Does not look like the best place here ... */ - public function getPrepared(array $array = array()) + final public function getPrepared(array $array = array()) { $dataSet = array(); @@ -1308,7 +1134,8 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite $dataSet[$field] = gzcompress($this->_data[$field],5); break; case 'boolean': - $dataSet[$field] = $this->getTable()->getConnection()->convertBooleans($this->_data[$field]); + $dataSet[$field] = $this->_em->getConnection() + ->convertBooleans($this->_data[$field]); break; case 'enum': $dataSet[$field] = $this->_class->enumIndex($field, $this->_data[$field]); @@ -1332,10 +1159,11 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite // @todo cleanup // populates the discriminator field in Single & Class Table Inheritance - if ($this->_class->getInheritanceType() == Doctrine::INHERITANCE_TYPE_JOINED || - $this->_class->getInheritanceType() == Doctrine::INHERITANCE_TYPE_SINGLE_TABLE) { - $discCol = $this->_class->getInheritanceOption('discriminatorColumn'); - $discMap = $this->_class->getInheritanceOption('discriminatorMap'); + $class = $this->_class; + if ($class->getInheritanceType() == Doctrine::INHERITANCE_TYPE_JOINED || + $class->getInheritanceType() == Doctrine::INHERITANCE_TYPE_SINGLE_TABLE) { + $discCol = $class->getInheritanceOption('discriminatorColumn'); + $discMap = $class->getInheritanceOption('discriminatorMap'); $old = $this->get($discCol, false); $discValue = array_search($this->_entityName, $discMap); if ((string) $old !== (string) $discValue || $old === null) { @@ -1347,27 +1175,12 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite return $dataSet; } - /** - * count - * this class implements countable interface - * - * Implementation of the Countable interface. - * - * @return integer the number of columns in this record - * @todo IMHO this is unintuitive. - * @todo ActiveRecord method. (if at all) - */ - public function count() - { - return count($this->_data); - } - /** * Creates an array representation of the object's data. * * @param boolean $deep - Return also the relations * @return array - * @todo ActiveRecord method. + * @todo ActiveEntity method. */ public function toArray($deep = true, $prefixKey = false) { @@ -1381,7 +1194,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } if ($this->_class->getIdentifierType() == Doctrine::IDENTIFIER_AUTOINC) { - $idFieldNames = (array)$this->_class->getIdentifier(); + $idFieldNames = $this->_class->getIdentifier(); $idFieldName = $idFieldNames[0]; $ids = $this->identifier(); @@ -1417,7 +1230,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @param mixed $data Data to merge. Either another instance of this model or an array * @param bool $deep Bool value for whether or not to merge the data deep * @return void - * @todo ActiveRecord method. + * @todo ActiveEntity method. */ public function merge($data, $deep = true) { @@ -1438,7 +1251,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @param string $array * @param bool $deep Bool value for whether or not to merge the data deep * @return void - * @todo ActiveRecord method. + * @todo ActiveEntity method. */ public function fromArray($array, $deep = true) { @@ -1454,16 +1267,15 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } /** - * synchronizeFromArray - * synchronizes a Doctrine_Entity and its relations with data from an array + * Synchronizes a Doctrine_Entity and its relations with data from an array * - * it expects an array representation of a Doctrine_Entity similar to the return + * It expects an array representation of a Doctrine_Entity similar to the return * value of the toArray() method. If the array contains relations it will create * those that don't exist, update the ones that do, and delete the ones missing * on the array but available on the Doctrine_Entity * * @param array $array representation of a Doctrine_Entity - * @todo ActiveRecord method. + * @todo ActiveEntity method. */ public function synchronizeFromArray(array $array) { @@ -1488,7 +1300,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @param string $type * @param string $deep * @return void - * @todo ActiveRecord method. + * @todo ActiveEntity method. */ public function exportTo($type, $deep = true) { @@ -1506,7 +1318,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @param string $data * @return void * @author Jonathan H. Wage - * @todo ActiveRecord method. + * @todo ActiveEntity method. */ public function importFrom($type, $data) { @@ -1523,11 +1335,11 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @return boolean TRUE if the object is managed and has persistent state, FALSE otherwise. * @deprecated */ - public function exists() + /*public function exists() { return ($this->_state !== Doctrine_Entity::STATE_TCLEAN && $this->_state !== Doctrine_Entity::STATE_TDIRTY); - } + }*/ /** * Checks whether the entity already has a persistent state. @@ -1535,7 +1347,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @return boolean TRUE if the object is new, FALSE otherwise. * @deprecated Use isTransient() */ - public function isNew() + final public function isNew() { return $this->_state == self::STATE_TCLEAN || $this->_state == self::STATE_TDIRTY; } @@ -1545,7 +1357,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * * @return boolean TRUE if the object is new, FALSE otherwise. */ - public function isTransient() + final public function isTransient() { return $this->_state == self::STATE_TCLEAN || $this->_state == self::STATE_TDIRTY; } @@ -1556,7 +1368,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * * @return boolean TRUE if the object has been modified, FALSE otherwise. */ - public function isDirty() + final public function isDirty() { return ($this->_state === Doctrine_Entity::STATE_DIRTY || $this->_state === Doctrine_Entity::STATE_TDIRTY); @@ -1569,7 +1381,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @return boolean TRUE if the object has been modified, FALSE otherwise. * @deprecated Use isDirty() */ - public function isModified() + final public function isModified() { return ($this->_state === Doctrine_Entity::STATE_DIRTY || $this->_state === Doctrine_Entity::STATE_TDIRTY); @@ -1582,23 +1394,23 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * @return boolean * @todo Method name does not reflect the purpose. */ - public function hasRelation($fieldName) + /*public function hasRelation($fieldName) { if (isset($this->_data[$fieldName]) || isset($this->_id[$fieldName])) { return true; } return $this->_class->hasRelation($fieldName); - } + }*/ /** * getIterator * @return Doctrine_Record_Iterator a Doctrine_Record_Iterator that iterates through the data * @todo Really needed/useful? */ - public function getIterator() + /*public function getIterator() { return new Doctrine_Record_Iterator($this); - } + }*/ /** * Deletes the entity. @@ -1618,7 +1430,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * Creates a copy of the entity. * * @return Doctrine_Entity - * @todo ActiveRecord method. Implementation to EntityManager. + * @todo ActiveEntity method. Implementation to EntityManager. */ public function copy($deep = true) { @@ -1655,17 +1467,16 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } /** - * assignIdentifier + * INTERNAL: * * @param integer $id * @return void * @todo Not sure this is the right place here. */ - public function assignIdentifier($id = false) + final public function assignIdentifier($id = false) { if ($id === false) { $this->_id = array(); - $this->_data = $this->cleanData($this->_data); $this->_state = Doctrine_Entity::STATE_TCLEAN; $this->_modified = array(); } else if ($id === true) { @@ -1684,7 +1495,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite $this->_id[$name] = $id; $this->_data[$name] = $id; } - $this->_state = Doctrine_Entity::STATE_CLEAN; + $this->_state = self::STATE_CLEAN; $this->_modified = array(); } } @@ -1694,7 +1505,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * * @return array */ - public function identifier() + final public function identifier() { return $this->_id; } @@ -1710,18 +1521,6 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite return isset($this->_references[$name]); } - /** - * reference - * - * @param string $name - */ - public function reference($name) - { - if (isset($this->_references[$name])) { - return $this->_references[$name]; - } - } - /** * obtainReference * @@ -1737,72 +1536,35 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } /** + * INTERNAL: + * * getReferences * @return array all references */ - public function getReferences() + final public function _getReferences() { return $this->_references; } /** + * INTERNAL: * setRelated * * @param string $alias * @param Doctrine_Access $coll */ - final public function setRelated($alias, Doctrine_Access $coll) + final public function _setRelated($alias, Doctrine_Access $coll) { $this->_references[$alias] = $coll; } - /** - * loadReference - * loads a related component - * - * @throws Doctrine_Table_Exception if trying to load an unknown related component - * @param string $name - * @return void - */ - public function loadReference($name) - { - $rel = $this->_class->getRelation($name); - $this->_references[$name] = $rel->fetchRelatedFor($this); - } - - /** - * call - * - * @param string|array $callback valid callback - * @param string $column column name - * @param mixed arg1 ... argN optional callback arguments - * @return Doctrine_Entity - * @todo Really needed/used? If not, remove. - * @todo ActiveRecord method. (if at all) - */ - public function call($callback, $column) - { - $args = func_get_args(); - array_shift($args); - - if (isset($args[0])) { - $fieldName = $args[0]; - $args[0] = $this->get($fieldName); - - $newvalue = call_user_func_array($callback, $args); - - $this->_data[$fieldName] = $newvalue; - } - return $this; - } - /** * getter for node assciated with this record * * @return mixed if tree returns Doctrine_Node otherwise returns false * @todo Should go to the NestedSet Behavior plugin. */ - public function getNode() + /*public function getNode() { if ( ! $this->_class->isTree()) { return false; @@ -1815,7 +1577,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } return $this->_node; - } + }*/ /** * revert @@ -1844,22 +1606,13 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } /** - * @todo get rid of filters. at least the way they're implemented atm. - */ - public function unshiftFilter(Doctrine_Record_Filter $filter) - { - return $this->_class->unshiftFilter($filter); - } - - /** - * unlink - * removes links from this record to given records + * Removes links from this record to given records * if no ids are given, it removes all links * * @param string $alias related component alias * @param array $ids the identifiers of the related records * @return Doctrine_Entity this object - * @todo ActiveRecord method. + * @todo ActiveEntity method. */ public function unlink($alias, $ids = array()) { @@ -1908,13 +1661,12 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite /** - * link - * creates links from this record to given records + * Creates links from this record to given records. * * @param string $alias related component alias * @param array $ids the identifiers of the related records * @return Doctrine_Entity this object - * @todo ActiveRecord method. + * @todo ActiveEntity method. */ public function link($alias, array $ids) { @@ -1963,9 +1715,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite $q->execute(); } else if ($rel instanceof Doctrine_Relation_LocalKey) { - $q = new Doctrine_Query(); - $q->update($this->getTable()->getComponentName()) ->set($rel->getLocalFieldName(), '?', $ids); @@ -1998,7 +1748,7 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * we decided that all behaviors should be accessed through getBehavior($name) * before they're used. */ - public function __call($method, $args) + /*public function __call($method, $args) { if (($behavior = $this->_class->getBehaviorForMethod($method)) !== false) { $behavior->setInvoker($this); @@ -2014,34 +1764,22 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite } throw new Doctrine_Record_Exception(sprintf('Unknown method %s::%s', get_class($this), $method)); - } + }*/ /** * used to delete node from tree - MUST BE USE TO DELETE RECORD IF TABLE ACTS AS TREE * * @todo Should go to the NestedSet Behavior plugin. */ - public function deleteNode() + /*public function deleteNode() { $this->getNode()->delete(); - } - - /** - * getTable - * returns the table object for this record - * - * @return Doctrine_Table a Doctrine_Table object - * @deprecated - */ - public function getTable() - { - return $this->getClassMetadata(); - } + }*/ /** * Gets the ClassMetadata object that describes the entity class. */ - public function getClassMetadata() + final public function getClassMetadata() { return $this->_class; } @@ -2051,17 +1789,19 @@ abstract class Doctrine_Entity extends Doctrine_Access implements Countable, Ite * * @return unknown */ - public function getEntityManager() + final public function getEntityManager() { - if ( ! $this->_em) { - $this->_em = Doctrine_EntityManager::getManager($this->_entityName); - } return $this->_em; } - public function getRepository() + /** + * Enter description here... + * + * @return unknown + */ + final public function getRepository() { - return $this->_class->getConnection()->getRepository($this->_entityName); + return $this->_em->getRepository($this->_entityName); } /** diff --git a/lib/Doctrine/EntityManager.php b/lib/Doctrine/EntityManager.php index 180ec4aeb..62d5df0cb 100644 --- a/lib/Doctrine/EntityManager.php +++ b/lib/Doctrine/EntityManager.php @@ -42,7 +42,7 @@ * @author Roman Borschel * @todo package:orm */ -class Doctrine_EntityManager implements Doctrine_Configurable +class Doctrine_EntityManager { /** * The unique name of the EntityManager. The name is used to bind entity classes @@ -57,29 +57,9 @@ class Doctrine_EntityManager implements Doctrine_Configurable * * @var Configuration */ - private $_configuration; + private $_config; - // -- configuration stuff to be removed. replaced by Configuration. - private $_nullObject; - /** - * The attributes. - * - * @var array - */ - private $_attributes = array( - 'quoteIdentifier' => false, - 'indexNameFormat' => '%s_idx', - 'sequenceNameFormat' => '%s_seq', - 'tableNameFormat' => '%s', - 'resultCache' => null, - 'resultCacheLifeSpan' => null, - 'queryCache' => null, - 'queryCacheLifeSpan' => null, - 'metadataCache' => null, - 'metadataCacheLifeSpan' => null - ); - /** * The database connection used by the EntityManager. * @@ -150,6 +130,13 @@ class Doctrine_EntityManager implements Doctrine_Configurable */ //private $_dataTemplates = array(); + /** + * Container that is used temporarily during hydration. + * + * @var array + */ + private $_tmpEntityData = array(); + /** * Creates a new EntityManager that operates on the given database connection. * @@ -164,18 +151,6 @@ class Doctrine_EntityManager implements Doctrine_Configurable $this, new Doctrine_ClassMetadata_CodeDriver()); $this->_unitOfWork = new Doctrine_Connection_UnitOfWork($conn); $this->_nullObject = Doctrine_Null::$INSTANCE; - $this->_initAttributes(); - } - - private function _initAttributes() - { - // Change null default values to references to the Null object to allow - // fast isset() checks instead of array_key_exists(). - foreach ($this->_attributes as $key => $value) { - if ($value === null) { - $this->_attributes[$key] = $this->_nullObject; - } - } } /** @@ -338,6 +313,17 @@ class Doctrine_EntityManager implements Doctrine_Configurable $this->commit(); } + /** + * Enter description here... + * + * @param unknown_type $entityName + * @param unknown_type $identifier + */ + public function find($entityName, $identifier) + { + return $this->getRepository($entityName)->find($identifier); + } + /** * Sets the flush mode. * @@ -459,7 +445,7 @@ class Doctrine_EntityManager implements Doctrine_Configurable } /** - * Creates an entity. Used to reconstitution as well as new creation. + * Creates an entity. Used for reconstitution as well as initial creation. * * @param * @param @@ -467,7 +453,8 @@ class Doctrine_EntityManager implements Doctrine_Configurable */ public function createEntity($className, array $data) { - $className = $this->_getClassnameToReturn($data, $className); + $this->_tmpEntityData = $data; + $className = $this->_inferCorrectClassName($data, $className); $classMetadata = $this->getClassMetadata($className); if ( ! empty($data)) { $identifierFieldNames = $classMetadata->getIdentifier(); @@ -480,27 +467,45 @@ class Doctrine_EntityManager implements Doctrine_Configurable } $id[] = $data[$fieldName]; } + if ($isNew) { - return new $className(true, $data); - } - - $idHash = $this->_unitOfWork->getIdentifierHash($id); - - if ($entity = $this->_unitOfWork->tryGetByIdHash($idHash, - $classMetadata->getRootClassName())) { - return $entity; + $entity = new $className(true); + //$entity->_setData($data); } else { - $entity = new $className(false, $data); - $this->_unitOfWork->registerIdentity($entity); + $idHash = $this->_unitOfWork->getIdentifierHash($id); + if ($entity = $this->_unitOfWork->tryGetByIdHash($idHash, + $classMetadata->getRootClassName())) { + return $entity; + } else { + $entity = new $className(false); + //$entity->_setData($data); + $this->_unitOfWork->registerIdentity($entity); + } } - $data = array(); } else { - $entity = new $className(true, $data); + $entity = new $className(true); + //$entity->_setData($data); } + + /*if (count($data) < $classMetadata->getMappedColumnCount()) { + $entity->_state(Doctrine_Entity::STATE_PROXY); + } else { + $entity->_state(Doctrine_Entity::STATE_CLEAN); + }*/ + $this->_tmpEntityData = array(); return $entity; } + /** + * INTERNAL: + * For internal hydration purposes only. + */ + public function _getTmpEntityData() + { + return $this->_tmpEntityData; + } + /** * Check the dataset for a discriminator column to determine the correct * class to instantiate. If no discriminator column is found, the given @@ -508,9 +513,8 @@ class Doctrine_EntityManager implements Doctrine_Configurable * * @return string The name of the class to instantiate. * @todo Can be optimized performance-wise. - * @todo Move to EntityManager::createEntity() */ - private function _getClassnameToReturn(array $data, $className) + private function _inferCorrectClassName(array $data, $className) { $class = $this->getClassMetadata($className); @@ -565,35 +569,19 @@ class Doctrine_EntityManager implements Doctrine_Configurable */ public function setConfiguration(Doctrine_Configuration $config) { - $this->_configuration = $config; + $this->_config = $config; } - /* Configurable implementation */ - - public function hasAttribute($name) + /** + * Gets the COnfiguration used by the EntityManager. + * + * @return Configuration + */ + public function getConfiguration() { - return isset($this->_attributes[$name]); + return $this->_config; } - public function getAttribute($name) - { - if ( ! $this->hasAttribute($name)) { - throw Doctrine_EntityManager_Exception::unknownAttribute($name); - } - if ($this->_attributes[$name] === $this->_nullObject) { - return null; - } - return $this->_attributes[$name]; - } - - public function setAttribute($name, $value) - { - if ( ! $this->hasAttribute($name)) { - throw Doctrine_EntityManager_Exception::unknownAttribute($name); - } - // TODO: do some value checking depending on the attribute - $this->_attributes[$name] = $value; - } } ?> \ No newline at end of file diff --git a/lib/Doctrine/EntityPersister/Abstract.php b/lib/Doctrine/EntityPersister/Abstract.php index 9f17d3687..89d1d4d21 100644 --- a/lib/Doctrine/EntityPersister/Abstract.php +++ b/lib/Doctrine/EntityPersister/Abstract.php @@ -132,7 +132,7 @@ abstract class Doctrine_EntityPersister_Abstract if ($fk->isComposite()) { $obj = $record->get($fk->getAlias()); if ($obj instanceof Doctrine_Entity && - $obj->state() != Doctrine_Entity::STATE_LOCKED) { + $obj->_state() != Doctrine_Entity::STATE_LOCKED) { $obj->delete($this->_mapper->getConnection()); } } @@ -266,18 +266,18 @@ abstract class Doctrine_EntityPersister_Abstract $conn = $this->_conn; } - $state = $record->state(); + $state = $record->_state(); if ($state === Doctrine_Entity::STATE_LOCKED) { return false; } - $record->state(Doctrine_Entity::STATE_LOCKED); + $record->_state(Doctrine_Entity::STATE_LOCKED); try { $conn->beginInternalTransaction(); $saveLater = $this->_saveRelated($record); - $record->state($state); + $record->_state($state); if ($record->isValid()) { $this->_insertOrUpdate($record); @@ -285,8 +285,8 @@ abstract class Doctrine_EntityPersister_Abstract $conn->transaction->addInvalid($record); } - $state = $record->state(); - $record->state(Doctrine_Entity::STATE_LOCKED); + $state = $record->_state(); + $record->_state(Doctrine_Entity::STATE_LOCKED); foreach ($saveLater as $fk) { $alias = $fk->getAlias(); @@ -302,7 +302,7 @@ abstract class Doctrine_EntityPersister_Abstract // save the MANY-TO-MANY associations $this->saveAssociations($record); // reset state - $record->state($state); + $record->_state($state); $conn->commit(); } catch (Exception $e) { $conn->rollback(); @@ -322,7 +322,7 @@ abstract class Doctrine_EntityPersister_Abstract $record->preSave(); $this->notifyEntityListeners($record, 'preSave', Doctrine_Event::RECORD_SAVE); - switch ($record->state()) { + switch ($record->_state()) { case Doctrine_Entity::STATE_TDIRTY: $this->_insert($record); break; @@ -361,7 +361,7 @@ abstract class Doctrine_EntityPersister_Abstract protected function _saveRelated(Doctrine_Entity $record) { $saveLater = array(); - foreach ($record->getReferences() as $k => $v) { + foreach ($record->_getReferences() as $k => $v) { $rel = $record->getTable()->getRelation($k); $local = $rel->getLocal(); @@ -408,7 +408,7 @@ abstract class Doctrine_EntityPersister_Abstract */ public function saveAssociations(Doctrine_Entity $record) { - foreach ($record->getReferences() as $relationName => $relatedObject) { + foreach ($record->_getReferences() as $relationName => $relatedObject) { if ($relatedObject === Doctrine_Null::$INSTANCE) { continue; } @@ -514,8 +514,8 @@ abstract class Doctrine_EntityPersister_Abstract $table = $this->_classMetadata; - $state = $record->state(); - $record->state(Doctrine_Entity::STATE_LOCKED); + $state = $record->_state(); + $record->_state(Doctrine_Entity::STATE_LOCKED); $this->_doDelete($record); diff --git a/lib/Doctrine/EntityPersister/JoinedSubclass.php b/lib/Doctrine/EntityPersister/JoinedSubclass.php index 05ea1117c..9b8b706a2 100644 --- a/lib/Doctrine/EntityPersister/JoinedSubclass.php +++ b/lib/Doctrine/EntityPersister/JoinedSubclass.php @@ -138,7 +138,7 @@ class Doctrine_EntityPersister_JoinedSubclass extends Doctrine_EntityPersister_A $conn->beginInternalTransaction(); $this->_deleteComposites($record); - $record->state(Doctrine_Entity::STATE_TDIRTY); + $record->_state(Doctrine_Entity::STATE_TDIRTY); $identifier = $this->_convertFieldToColumnNames($record->identifier(), $class); @@ -149,7 +149,7 @@ class Doctrine_EntityPersister_JoinedSubclass extends Doctrine_EntityPersister_A $this->_deleteRow($parentClass->getTableName(), $identifier); } - $record->state(Doctrine_Entity::STATE_TCLEAN); + $record->_state(Doctrine_Entity::STATE_TCLEAN); $this->removeRecord($record); // @todo should be done in the unitofwork $conn->commit(); diff --git a/lib/Doctrine/EntityPersister/Standard.php b/lib/Doctrine/EntityPersister/Standard.php index 8c5076960..f7cec527c 100644 --- a/lib/Doctrine/EntityPersister/Standard.php +++ b/lib/Doctrine/EntityPersister/Standard.php @@ -44,11 +44,11 @@ class Doctrine_EntityPersister_Standard extends Doctrine_EntityPersister_Abstrac $conn->beginInternalTransaction(); $this->_deleteComposites($record); - $record->state(Doctrine_Entity::STATE_TDIRTY); + $record->_state(Doctrine_Entity::STATE_TDIRTY); $identifier = $this->_convertFieldToColumnNames($record->identifier(), $metadata); $this->_deleteRow($metadata->getTableName(), $identifier); - $record->state(Doctrine_Entity::STATE_TCLEAN); + $record->_state(Doctrine_Entity::STATE_TCLEAN); $this->removeRecord($record); $conn->commit(); diff --git a/lib/Doctrine/Event.php b/lib/Doctrine/Event.php index 21c4cd066..49bea5c6a 100644 --- a/lib/Doctrine/Event.php +++ b/lib/Doctrine/Event.php @@ -29,7 +29,7 @@ * @package Doctrine * @subpackage Event * @link www.phpdoctrine.org - * @since 1.0 + * @since 2.0 * @version $Revision$ */ class Doctrine_Event diff --git a/lib/Doctrine/EventManager.php b/lib/Doctrine/EventManager.php index da8bbd969..11094a080 100644 --- a/lib/Doctrine/EventManager.php +++ b/lib/Doctrine/EventManager.php @@ -1,4 +1,23 @@ . + */ #namespace Doctrine::Common; diff --git a/lib/Doctrine/Formatter.php b/lib/Doctrine/Formatter.php index 2abc4f7db..7dbfa146d 100644 --- a/lib/Doctrine/Formatter.php +++ b/lib/Doctrine/Formatter.php @@ -48,7 +48,8 @@ class Doctrine_Formatter extends Doctrine_Connection_Module */ public function escapePattern($text) { - if ( ! $this->string_quoting['escape_pattern']) { + return $text; + /*if ( ! $this->string_quoting['escape_pattern']) { return $text; } $tmp = $this->conn->string_quoting; @@ -60,7 +61,7 @@ class Doctrine_Formatter extends Doctrine_Connection_Module foreach ($this->wildcards as $wildcard) { $text = str_replace($wildcard, $tmp['escape_pattern'] . $wildcard, $text); } - return $text; + return $text;*/ } /** diff --git a/lib/Doctrine/Hydrator/RecordDriver.php b/lib/Doctrine/Hydrator/RecordDriver.php index 7a8a181be..e0688b575 100644 --- a/lib/Doctrine/Hydrator/RecordDriver.php +++ b/lib/Doctrine/Hydrator/RecordDriver.php @@ -76,7 +76,7 @@ class Doctrine_Hydrator_RecordDriver $relatedClass = $relation->getTable(); $coll = $this->getElementCollection($relatedClass->getClassName()); $coll->setReference($entity, $relation); - $entity->rawSetReference($name, $coll); + $entity->_rawSetReference($name, $coll); $this->_initializedRelations[$entity->getOid()][$name] = true; } } @@ -99,23 +99,23 @@ class Doctrine_Hydrator_RecordDriver public function addRelatedIndexedElement(Doctrine_Entity $entity1, $property, Doctrine_Entity $entity2, $indexField) { - $entity1->rawGetReference($property)->add($entity2, $entity2->rawGetField($indexField)); + $entity1->_rawGetReference($property)->add($entity2, $entity2->_rawGetField($indexField)); } public function addRelatedElement(Doctrine_Entity $entity1, $property, Doctrine_Entity $entity2) { - $entity1->rawGetReference($property)->add($entity2); + $entity1->_rawGetReference($property)->add($entity2); } public function setRelatedElement(Doctrine_Entity $entity1, $property, $entity2) { - $entity1->rawSetReference($property, $entity2); + $entity1->_rawSetReference($property, $entity2); } public function isIndexKeyInUse(Doctrine_Entity $entity, $assocField, $indexField) { - return $entity->rawGetReference($assocField)->contains($indexField); + return $entity->_rawGetReference($assocField)->contains($indexField); } public function isFieldSet(Doctrine_Entity $entity, $field) @@ -125,17 +125,17 @@ class Doctrine_Hydrator_RecordDriver public function getFieldValue(Doctrine_Entity $entity, $field) { - return $entity->rawGetField($field); + return $entity->_rawGetField($field); } public function getReferenceValue(Doctrine_Entity $entity, $field) { - return $entity->rawGetReference($field); + return $entity->_rawGetReference($field); } public function addElementToIndexedCollection($coll, $entity, $keyField) { - $coll->add($entity, $entity->rawGetField($keyField)); + $coll->add($entity, $entity->_rawGetField($keyField)); } public function addElementToCollection($coll, $entity) diff --git a/lib/Doctrine/HydratorNew.php b/lib/Doctrine/HydratorNew.php index 8d94ff0c8..80583247b 100644 --- a/lib/Doctrine/HydratorNew.php +++ b/lib/Doctrine/HydratorNew.php @@ -71,7 +71,7 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract * @param array $tableAliases Array that maps table aliases (SQL alias => DQL alias) * @param array $aliasMap Array that maps DQL aliases to their components * (DQL alias => array( - * 'table' => Table object, + * 'metadata' => Table object, * 'parent' => Parent DQL alias (if any), * 'relation' => Relation object (if any), * 'map' => Custom index to use as the key in the result (if any), @@ -109,7 +109,7 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract // Used variables during hydration reset($this->_queryComponents); $rootAlias = key($this->_queryComponents); - $rootComponentName = $this->_queryComponents[$rootAlias]['table']->getClassName(); + $rootComponentName = $this->_queryComponents[$rootAlias]['metadata']->getClassName(); // if only one class is involved we can make our lives easier $isSimpleQuery = count($this->_queryComponents) <= 1; // Lookup map to quickly discover/lookup existing records in the result @@ -138,8 +138,8 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract // Initialize foreach ($this->_queryComponents as $dqlAlias => $component) { // disable lazy-loading of related elements during hydration - $component['table']->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, false); - $componentName = $component['table']->getClassName(); + $component['metadata']->setAttribute('loadReferences', false); + $componentName = $component['metadata']->getClassName(); $identifierMap[$dqlAlias] = array(); $resultPointers[$dqlAlias] = array(); $idTemplate[$dqlAlias] = ''; @@ -170,7 +170,7 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract // // hydrate the data of the root entity from the current row // - $class = $this->_queryComponents[$rootAlias]['table']; + $class = $this->_queryComponents[$rootAlias]['metadata']; $componentName = $class->getComponentName(); // Check for an existing element @@ -180,17 +180,10 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract // do we need to index by a custom field? if ($field = $this->_getCustomIndexField($rootAlias)) { - // TODO: must be checked in the parser. fields used in INDEXBY - // must be a) the primary key or b) unique & notnull - /*if (isset($result[$field])) { - throw Doctrine_Hydrator_Exception::nonUniqueKeyMapping(); - } else if ( ! isset($element[$field])) { - throw Doctrine_Hydrator_Exception::nonExistantFieldUsedAsIndex($field); - }*/ if ($parserResult->isMixedQuery()) { $result[] = array( - $driver->getFieldValue($element, $field) => $element - ); + $driver->getFieldValue($element, $field) => $element + ); } else { $driver->addElementToIndexedCollection($result, $element, $field); } @@ -220,7 +213,7 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract foreach ($rowData as $dqlAlias => $data) { $index = false; $map = $this->_queryComponents[$dqlAlias]; - $componentName = $map['table']->getClassName(); + $componentName = $map['metadata']->getClassName(); $parent = $map['parent']; $relation = $map['relation']; $relationAlias = $relation->getAlias(); @@ -258,7 +251,7 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract } } else if ( ! isset($baseElement[$relationAlias])) { $driver->setRelatedElement($baseElement, $relationAlias, - $driver->getNullPointer()); + $driver->getElementCollection($componentName)); } } else { // x-1 relation @@ -290,7 +283,7 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract // re-enable lazy loading foreach ($this->_queryComponents as $dqlAlias => $data) { - $data['table']->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, true); + $data['metadata']->setAttribute('loadReferences', true); } $e = microtime(true); @@ -370,7 +363,7 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract $e = explode('__', $key); $columnName = strtolower(array_pop($e)); $cache[$key]['dqlAlias'] = $this->_tableAliases[strtolower(implode('__', $e))]; - $classMetadata = $this->_queryComponents[$cache[$key]['dqlAlias']]['table']; + $classMetadata = $this->_queryComponents[$cache[$key]['dqlAlias']]['metadata']; // check whether it's an aggregate value or a regular field if (isset($this->_queryComponents[$cache[$key]['dqlAlias']]['agg'][$columnName])) { $fieldName = $this->_queryComponents[$cache[$key]['dqlAlias']]['agg'][$columnName]; @@ -399,7 +392,7 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract } } - $class = $this->_queryComponents[$cache[$key]['dqlAlias']]['table']; + $class = $this->_queryComponents[$cache[$key]['dqlAlias']]['metadata']; $dqlAlias = $cache[$key]['dqlAlias']; $fieldName = $cache[$key]['fieldName']; @@ -454,7 +447,7 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract $e = explode('__', $key); $columnName = strtolower(array_pop($e)); $cache[$key]['dqlAlias'] = $this->_tableAliases[strtolower(implode('__', $e))]; - $classMetadata = $this->_queryComponents[$cache[$key]['dqlAlias']]['table']; + $classMetadata = $this->_queryComponents[$cache[$key]['dqlAlias']]['metadata']; // check whether it's an aggregate value or a regular field if (isset($this->_queryComponents[$cache[$key]['dqlAlias']]['agg'][$columnName])) { $fieldName = $this->_queryComponents[$cache[$key]['dqlAlias']]['agg'][$columnName]; @@ -476,7 +469,7 @@ class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract } } - $class = $this->_queryComponents[$cache[$key]['dqlAlias']]['table']; + $class = $this->_queryComponents[$cache[$key]['dqlAlias']]['metadata']; $dqlAlias = $cache[$key]['dqlAlias']; $fieldName = $cache[$key]['fieldName']; diff --git a/lib/Doctrine/Lib.php b/lib/Doctrine/Lib.php index 6dbc16e21..c1ae1cf7e 100644 --- a/lib/Doctrine/Lib.php +++ b/lib/Doctrine/Lib.php @@ -76,7 +76,7 @@ class Doctrine_Lib $r[] = '
';
         $r[] = 'Component  : ' . $record->getTable()->getComponentName();
         $r[] = 'ID         : ' . $record->obtainIdentifier();
-        $r[] = 'References : ' . count($record->getReferences());
+        $r[] = 'References : ' . count($record->_getReferences());
         $r[] = 'State      : ' . Doctrine_Lib::getRecordStateAsString($record->getState());
         $r[] = 'OID        : ' . $record->getOID();
         $r[] = 'data       : ' . Doctrine::dump($record->getData(), false);
diff --git a/lib/Doctrine/Query/Parser.php b/lib/Doctrine/Query/Parser.php
index 01639fb6c..dd836a829 100644
--- a/lib/Doctrine/Query/Parser.php
+++ b/lib/Doctrine/Query/Parser.php
@@ -154,7 +154,6 @@ class Doctrine_Query_Parser
             $isMatch = ($this->lookahead['type'] === $token);
         }
 
-
         if ( ! $isMatch) {
             // No definition for value checking.
             $this->syntaxError($this->_keywordTable->getLiteral($token));
diff --git a/lib/Doctrine/Query/Printer.php b/lib/Doctrine/Query/Printer.php
index d68cc5fc6..e2244975a 100644
--- a/lib/Doctrine/Query/Printer.php
+++ b/lib/Doctrine/Query/Printer.php
@@ -27,7 +27,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Printer
diff --git a/lib/Doctrine/Query/Production.php b/lib/Doctrine/Query/Production.php
index dbfe2ab8d..f6e1098ff 100644
--- a/lib/Doctrine/Query/Production.php
+++ b/lib/Doctrine/Query/Production.php
@@ -148,28 +148,6 @@ abstract class Doctrine_Query_Production
         return new $class($this->_parser);
     }
 
-
-    /**
-     * Executes a production with specified name and parameters.
-     *
-     * @param string $name production name
-     * @param array $params an associative array containing parameter names and
-     * their values
-     * @return mixed
-     */
-    public function __call($method, $args)
-    {
-        if (substr($method, 0, 3) === 'get') {
-            $var = '_' . substr($method, 3);
-            $var[1] = strtolower($var[1]);
-
-            return $this->$var;
-        }
-
-        return null;
-    }
-
-
     /**
      * Executes this production using the specified parameters.
      *
@@ -233,4 +211,9 @@ abstract class Doctrine_Query_Production
     public function semantical($paramHolder)
     {
     }
+    
+    public function getParser()
+    {
+        return $this->_parser;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/AggregateExpression.php b/lib/Doctrine/Query/Production/AggregateExpression.php
index 42b1321ae..311dde66a 100644
--- a/lib/Doctrine/Query/Production/AggregateExpression.php
+++ b/lib/Doctrine/Query/Production/AggregateExpression.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_AggregateExpression extends Doctrine_Query_Production
@@ -87,4 +87,32 @@ class Doctrine_Query_Production_AggregateExpression extends Doctrine_Query_Produ
              . $this->_expression->buildSql()
              . ')';
     }
+    
+    /**
+     * Visitor support.
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_expression->accept($visitor);
+        $visitor->visitAggregateExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function getExpression()
+    {
+        return $this->_expression;
+    }
+    
+    public function getFunctionName()
+    {
+        return $this->_functionName;
+    }
+    
+    public function isDistinct()
+    {
+        return $this->_isDistinct;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/Atom.php b/lib/Doctrine/Query/Production/Atom.php
index 142f3ae41..9ee0d2281 100644
--- a/lib/Doctrine/Query/Production/Atom.php
+++ b/lib/Doctrine/Query/Production/Atom.php
@@ -86,10 +86,33 @@ class Doctrine_Query_Production_Atom extends Doctrine_Query_Production
             break;
 
             default:
-                return $conn->string_quoting['start']
+                $stringQuoting = $conn->getProperty('string_quoting');
+                return $stringQuoting['start']
                      . $conn->quote($this->_value, $this->_type)
-                     . $conn->string_quoting['end'];
+                     . $stringQuoting['end'];
             break;
         }
     }
+    
+    /**
+     * Visitor support.
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitAtom($this);
+    }
+    
+    /* Getters */
+    
+    public function getType()
+    {
+        return $this->_type;
+    }
+    
+    public function getValue()
+    {
+        return $this->_value;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/BetweenExpression.php b/lib/Doctrine/Query/Production/BetweenExpression.php
index 9952552c7..c94d74f4b 100644
--- a/lib/Doctrine/Query/Production/BetweenExpression.php
+++ b/lib/Doctrine/Query/Production/BetweenExpression.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_BetweenExpression extends Doctrine_Query_Production
@@ -65,4 +65,33 @@ class Doctrine_Query_Production_BetweenExpression extends Doctrine_Query_Product
         return (($this->_not) ? 'NOT ' : '') . 'BETWEEN '
              . $this->_fromExpression->buildSql() . ' AND ' . $this->_toExpression->buildSql();
     }
+    
+    /**
+     * Visitor support.
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_fromExpression->accept($visitor);
+        $this->_toExpression->accept($visitor);
+        $visitor->visitBetweenExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function isNot()
+    {
+        return $this->_not;
+    }
+    
+    public function getFromExpression()
+    {
+        return $this->_fromExpression;
+    }
+    
+    public function getToExpression()
+    {
+        return $this->_toExpression;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/ComparisonExpression.php b/lib/Doctrine/Query/Production/ComparisonExpression.php
index 8aa27c3a0..cf43da9ec 100644
--- a/lib/Doctrine/Query/Production/ComparisonExpression.php
+++ b/lib/Doctrine/Query/Production/ComparisonExpression.php
@@ -27,7 +27,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_ComparisonExpression extends Doctrine_Query_Production
@@ -65,11 +65,38 @@ class Doctrine_Query_Production_ComparisonExpression extends Doctrine_Query_Prod
         }
     }
 
-
     public function buildSql()
     {
         return $this->_operator . ' ' . (($this->_isSubselect) ?
             '(' . $this->_expression->buildSql() . ')' : $this->_expression->buildSql()
         );
     }
+    
+    /**
+     * Visitor support.
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_expression->accept($visitor);
+        $visitor->visitComparisonExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function getOperator()
+    {
+        return $this->_operator;
+    }
+    
+    public function getExpression()
+    {
+        return $this->_expression;
+    }
+    
+    public function isSubselect()
+    {
+        return $this->_isSubselect;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/ComparisonOperator.php b/lib/Doctrine/Query/Production/ComparisonOperator.php
index d096e0267..06b79e476 100644
--- a/lib/Doctrine/Query/Production/ComparisonOperator.php
+++ b/lib/Doctrine/Query/Production/ComparisonOperator.php
@@ -27,7 +27,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_ComparisonOperator extends Doctrine_Query_Production
@@ -78,4 +78,14 @@ class Doctrine_Query_Production_ComparisonOperator extends Doctrine_Query_Produc
             break;
         }
     }
+    
+    /**
+     * Visitor support.
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitComparisonOperator($this);
+    }
 }
diff --git a/lib/Doctrine/Query/Production/ConditionalExpression.php b/lib/Doctrine/Query/Production/ConditionalExpression.php
index b15333bc3..6bafbb7f1 100644
--- a/lib/Doctrine/Query/Production/ConditionalExpression.php
+++ b/lib/Doctrine/Query/Production/ConditionalExpression.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_ConditionalExpression extends Doctrine_Query_Production
@@ -69,4 +69,24 @@ class Doctrine_Query_Production_ConditionalExpression extends Doctrine_Query_Pro
     {
         return $value->buildSql();
     }
+    
+    /**
+     * Visitor support.
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        foreach ($this->_conditionalTerms as $term) {
+            $term->accept($visitor);
+        }
+        $visitor->visitConditionalExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function getConditionalTerms()
+    {
+        return $this->_conditionalTerms;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/ConditionalFactor.php b/lib/Doctrine/Query/Production/ConditionalFactor.php
index efce96b02..370926049 100644
--- a/lib/Doctrine/Query/Production/ConditionalFactor.php
+++ b/lib/Doctrine/Query/Production/ConditionalFactor.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_ConditionalFactor extends Doctrine_Query_Production
@@ -60,4 +60,22 @@ class Doctrine_Query_Production_ConditionalFactor extends Doctrine_Query_Product
         // Do not need to check $notFactor. It'll be always present if we have this instance.
         return 'NOT ' . $this->_conditionalPrimary->buildSql();
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_conditionalPrimary->accept($visitor);
+        $visitor->visitConditionalFactor($this);
+    }
+    
+    /* Getters */
+    
+    public function getConditionalPrimary()
+    {
+        return $this->_conditionalPrimary;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/ConditionalPrimary.php b/lib/Doctrine/Query/Production/ConditionalPrimary.php
index 028e11c5d..0edb88246 100644
--- a/lib/Doctrine/Query/Production/ConditionalPrimary.php
+++ b/lib/Doctrine/Query/Production/ConditionalPrimary.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_ConditionalPrimary extends Doctrine_Query_Production
@@ -98,4 +98,10 @@ class Doctrine_Query_Production_ConditionalPrimary extends Doctrine_Query_Produc
 
         return false;
     }
+    
+    public function accept($visitor)
+    {
+        $this->_conditionalExpression->accept($visitor);
+        $visitor->visitConditionalPrimary($this);
+    }
 }
diff --git a/lib/Doctrine/Query/Production/ConditionalTerm.php b/lib/Doctrine/Query/Production/ConditionalTerm.php
index 5c0a2d4ab..5dafb3517 100644
--- a/lib/Doctrine/Query/Production/ConditionalTerm.php
+++ b/lib/Doctrine/Query/Production/ConditionalTerm.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_ConditionalTerm extends Doctrine_Query_Production
@@ -69,4 +69,24 @@ class Doctrine_Query_Production_ConditionalTerm extends Doctrine_Query_Productio
     {
         return $value->buildSql();
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        foreach ($this->_conditionalFactors as $factor) {
+            $factor->accept($visitor);
+        }
+        $visitor->visitConditionalTerm($this);
+    }
+    
+    /* Getters */
+    
+    public function getConditionalFactors()
+    {
+        return $this->_conditionalFactors;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/DeleteClause.php b/lib/Doctrine/Query/Production/DeleteClause.php
index 4d38f4a68..13d80936d 100644
--- a/lib/Doctrine/Query/Production/DeleteClause.php
+++ b/lib/Doctrine/Query/Production/DeleteClause.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_DeleteClause extends Doctrine_Query_Production
@@ -48,9 +48,26 @@ class Doctrine_Query_Production_DeleteClause extends Doctrine_Query_Production
         $this->_variableDeclaration = $this->AST('VariableDeclaration', $paramHolder);
     }
 
-
     public function buildSql()
     {
         return 'DELETE FROM ' . $this->_variableDeclaration->buildSql();
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_variableDeclaration->accept($visitor);
+        $visitor->visitDeleteClause($this);
+    }
+    
+    /* Getters */
+    
+    public function getVariableDeclaration()
+    {
+        return $this->_variableDeclaration;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/DeleteStatement.php b/lib/Doctrine/Query/Production/DeleteStatement.php
index fdbc0cf3b..b048d6ad2 100644
--- a/lib/Doctrine/Query/Production/DeleteStatement.php
+++ b/lib/Doctrine/Query/Production/DeleteStatement.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_DeleteStatement extends Doctrine_Query_Production
@@ -56,4 +56,30 @@ class Doctrine_Query_Production_DeleteStatement extends Doctrine_Query_Productio
         return $this->_deleteClause->buildSql() . (($this->_whereClause !== null)
              ? ' ' . $this->_whereClause->buildSql() : ' WHERE 1 = 1');
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_deleteClause->accept($visitor);
+        if ($this->_whereClause) {
+            $this->_whereClause->accept($visitor);
+        }
+        $visitor->visitDeleteStatement($this);
+    }
+    
+    /* Getters */
+    
+    public function getDeleteClause()
+    {
+        return $this->_deleteClause;
+    }
+    
+    public function getWhereClause()
+    {
+        return $this->_whereClause;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/ExistsExpression.php b/lib/Doctrine/Query/Production/ExistsExpression.php
index 155074f74..31f13ddfb 100644
--- a/lib/Doctrine/Query/Production/ExistsExpression.php
+++ b/lib/Doctrine/Query/Production/ExistsExpression.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_ExistsExpression extends Doctrine_Query_Production
@@ -51,4 +51,22 @@ class Doctrine_Query_Production_ExistsExpression extends Doctrine_Query_Producti
     {
         return 'EXISTS (' . $this->_subselect->buildSql() . ')';
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_subselect->accept($visitor);
+        $visitor->visitExistsExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function getSubselect()
+    {
+        return $this->_subselect;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/Expression.php b/lib/Doctrine/Query/Production/Expression.php
index 259c1da91..48843775a 100644
--- a/lib/Doctrine/Query/Production/Expression.php
+++ b/lib/Doctrine/Query/Production/Expression.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_Expression extends Doctrine_Query_Production
@@ -86,4 +86,24 @@ class Doctrine_Query_Production_Expression extends Doctrine_Query_Production
     {
         return (is_string($value) ? $value : $value->buildSql());
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        foreach ($this->_terms as $term) {
+            $term->accept($visitor);
+        }
+        $visitor->visitExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function getTerms()
+    {
+        return $this->_terms;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/Factor.php b/lib/Doctrine/Query/Production/Factor.php
index 62660a1a6..b4d585861 100644
--- a/lib/Doctrine/Query/Production/Factor.php
+++ b/lib/Doctrine/Query/Production/Factor.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_Factor extends Doctrine_Query_Production
@@ -68,4 +68,27 @@ class Doctrine_Query_Production_Factor extends Doctrine_Query_Production
     {
         return $this->_type . ' ' . $this->_primary->buildSql();
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_primary->accept($visitor);
+        $visitor->visitFactor($this);
+    }
+    
+    /* Getters */
+    
+    public function getType()
+    {
+        return $this->_type;
+    }
+    
+    public function getPrimary()
+    {
+        return $this->_primary;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/FieldIdentificationVariable.php b/lib/Doctrine/Query/Production/FieldIdentificationVariable.php
index 521aa7b0e..2919ac51d 100755
--- a/lib/Doctrine/Query/Production/FieldIdentificationVariable.php
+++ b/lib/Doctrine/Query/Production/FieldIdentificationVariable.php
@@ -27,7 +27,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_FieldIdentificationVariable extends Doctrine_Query_Production
@@ -74,4 +74,26 @@ class Doctrine_Query_Production_FieldIdentificationVariable extends Doctrine_Que
         $this->_columnAlias = $parserResult->getTableAliasFromComponentAlias($componentAlias)
                             . Doctrine_Query_Production::SQLALIAS_SEPARATOR . $idx;
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitFieldIdentificationVariable($this);
+    }
+    
+    /* Getters */
+    
+    public function getFieldAlias()
+    {
+        return $this->_fieldAlias;
+    }
+    
+    public function getColumnAlias()
+    {
+        return $this->_columnAlias;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/FromClause.php b/lib/Doctrine/Query/Production/FromClause.php
index 308979b22..f2a70d030 100644
--- a/lib/Doctrine/Query/Production/FromClause.php
+++ b/lib/Doctrine/Query/Production/FromClause.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_FromClause extends Doctrine_Query_Production
@@ -71,4 +71,24 @@ class Doctrine_Query_Production_FromClause extends Doctrine_Query_Production
     {
         return $value->buildSql();
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        foreach ($this->_identificationVariableDeclaration as $decl) {
+            $decl->accept($visitor);
+        }
+        $visitor->visitFromClause($this);
+    }
+    
+    /* Getters */
+    
+    public function getIdentificationVariableDeclarations()
+    {
+        return $this->_identificationVariableDeclaration;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/Function.php b/lib/Doctrine/Query/Production/Function.php
index 44363adf7..4e37d3ef0 100644
--- a/lib/Doctrine/Query/Production/Function.php
+++ b/lib/Doctrine/Query/Production/Function.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_Function extends Doctrine_Query_Production
@@ -76,4 +76,29 @@ class Doctrine_Query_Production_Function extends Doctrine_Query_Production
     {
         return $value->buildSql();
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        foreach ($this->_arguments as $argument) {
+            $argument->accept($visitor);
+        }
+        $visitor->visitFunction($this);
+    }
+    
+    /* Getters */
+    
+    public function getFunctionName()
+    {
+        return $this->_functionName;
+    }
+    
+    public function getArguments()
+    {
+        return $this->_arguments;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/GroupByClause.php b/lib/Doctrine/Query/Production/GroupByClause.php
index df28312f8..f9afdfa2d 100644
--- a/lib/Doctrine/Query/Production/GroupByClause.php
+++ b/lib/Doctrine/Query/Production/GroupByClause.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_GroupByClause extends Doctrine_Query_Production
@@ -66,4 +66,24 @@ class Doctrine_Query_Production_GroupByClause extends Doctrine_Query_Production
     {
         return $value->buildSql();
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        foreach ($this->_groupByItems as $item) {
+            $item->accept($visitor);
+        }
+        $visitor->visitGroupByClause($this);
+    }
+    
+    /* Getters */
+    
+    public function getGroupByItems()
+    {
+        return $this->_groupByItems;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/GroupByItem.php b/lib/Doctrine/Query/Production/GroupByItem.php
index 3c74bb3fe..bb441f7df 100644
--- a/lib/Doctrine/Query/Production/GroupByItem.php
+++ b/lib/Doctrine/Query/Production/GroupByItem.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_GroupByItem extends Doctrine_Query_Production
@@ -37,4 +37,14 @@ class Doctrine_Query_Production_GroupByItem extends Doctrine_Query_Production
     {
         return $this->AST('PathExpression', $paramHolder);
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitGroupByItem($this);
+    }
 }
diff --git a/lib/Doctrine/Query/Production/HavingClause.php b/lib/Doctrine/Query/Production/HavingClause.php
index 3a095d8ad..1c5817d82 100644
--- a/lib/Doctrine/Query/Production/HavingClause.php
+++ b/lib/Doctrine/Query/Production/HavingClause.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_HavingClause extends Doctrine_Query_Production
@@ -49,4 +49,22 @@ class Doctrine_Query_Production_HavingClause extends Doctrine_Query_Production
     {
         return 'HAVING ' . $this->_conditionalExpression->buildSql();
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_conditionalExpression->accept($visitor);
+        $visitor->visitHavingClause($this);
+    }
+    
+    /* Getters */
+    
+    public function getConditionalExpression()
+    {
+        return $this->_conditionalExpression;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/IdentificationVariable.php b/lib/Doctrine/Query/Production/IdentificationVariable.php
index 6a7ecc7cd..bf67b5c5b 100644
--- a/lib/Doctrine/Query/Production/IdentificationVariable.php
+++ b/lib/Doctrine/Query/Production/IdentificationVariable.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_IdentificationVariable extends Doctrine_Query_Production
@@ -62,4 +62,21 @@ class Doctrine_Query_Production_IdentificationVariable extends Doctrine_Query_Pr
 
         return $this->_componentAlias;
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitIdentificationVariable($this);
+    }
+    
+    /* Getters */
+    
+    public function getComponentAlias()
+    {
+        return $this->_componentAlias;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/IdentificationVariableDeclaration.php b/lib/Doctrine/Query/Production/IdentificationVariableDeclaration.php
index c8bb8735e..c774bb4eb 100644
--- a/lib/Doctrine/Query/Production/IdentificationVariableDeclaration.php
+++ b/lib/Doctrine/Query/Production/IdentificationVariableDeclaration.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_IdentificationVariableDeclaration extends Doctrine_Query_Production
@@ -92,4 +92,43 @@ class Doctrine_Query_Production_IdentificationVariableDeclaration extends Doctri
 
         return $str;
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_rangeVariableDeclaration->accept($visitor);
+        if ($this->_indexBy) {
+            $this->_indexBy->accept($visitor);
+        }
+        foreach ($this->_relations as $relation) {
+            if ($relation['join']) {
+                $relation['join']->accept($visitor);
+            }
+            if ($relation['indexby']) {
+                $relation['indexby']->accept($visitor);
+            }
+        }
+        $visitor->visitIdentificationVariable($this);
+    }
+    
+    /* Getters */
+    
+    public function getRangeVariableDeclaration()
+    {
+        return $this->_rangeVariableDeclaration;
+    }
+    
+    public function getIndexBy()
+    {
+        return $this->_indexBy;
+    }
+    
+    public function getRelations()
+    {
+        return $this->_relations;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/InExpression.php b/lib/Doctrine/Query/Production/InExpression.php
index 788c8f8b4..4ead9cede 100644
--- a/lib/Doctrine/Query/Production/InExpression.php
+++ b/lib/Doctrine/Query/Production/InExpression.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_InExpression extends Doctrine_Query_Production
@@ -87,4 +87,38 @@ class Doctrine_Query_Production_InExpression extends Doctrine_Query_Production
     {
         return $value->buildSql();
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        if ($this->_subselect !== null) {
+            $this->_subselect->accept($visitor);
+        } else {
+            foreach ($this->_atoms as $atom) {
+                $atom->accept($visitor);
+            }
+        }
+        $visitor->visitInExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function isNot()
+    {
+        return $this->_not;
+    }
+    
+    public function getSubselect()
+    {
+        return $this->_subselect;
+    }
+    
+    public function getAtoms()
+    {
+        return $this->_atoms;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/IndexBy.php b/lib/Doctrine/Query/Production/IndexBy.php
index adbd7e653..6bde673f9 100644
--- a/lib/Doctrine/Query/Production/IndexBy.php
+++ b/lib/Doctrine/Query/Production/IndexBy.php
@@ -27,7 +27,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_IndexBy extends Doctrine_Query_Production
@@ -105,4 +105,26 @@ class Doctrine_Query_Production_IndexBy extends Doctrine_Query_Production
     {
         return '';
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitIndexBy($this);
+    }
+    
+    /* Getters */
+    
+    public function getComponentAlias()
+    {
+        return $this->_componentAlias;
+    }
+    
+    public function getFieldName()
+    {
+        return $this->_fieldName;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/Join.php b/lib/Doctrine/Query/Production/Join.php
index ae7c6a37e..0967dc83f 100644
--- a/lib/Doctrine/Query/Production/Join.php
+++ b/lib/Doctrine/Query/Production/Join.php
@@ -27,7 +27,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_Join extends Doctrine_Query_Production
@@ -76,4 +76,36 @@ class Doctrine_Query_Production_Join extends Doctrine_Query_Production
     {
         return '';
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitJoin($this);
+    }
+    
+    /* Getters */
+    
+    public function getJoinType()
+    {
+        return $this->_joinType;
+    }
+    
+    public function getRangeVariableDeclaration()
+    {
+        return $this->_rangeVariableDeclaration;
+    }
+    
+    public function getWhereType()
+    {
+        return $this->_whereType;
+    }
+    
+    public function getConditionalExpression()
+    {
+        return $this->_conditionalExpression;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/LikeExpression.php b/lib/Doctrine/Query/Production/LikeExpression.php
index e31cb3dd8..73d94c427 100644
--- a/lib/Doctrine/Query/Production/LikeExpression.php
+++ b/lib/Doctrine/Query/Production/LikeExpression.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_LikeExpression extends Doctrine_Query_Production
@@ -69,4 +69,32 @@ class Doctrine_Query_Production_LikeExpression extends Doctrine_Query_Production
         return (($this->_not) ? 'NOT ' : '') . 'LIKE ' . $this->_expression->buildSql()
              . (($this->_escapeString !== null) ? ' ESCAPE ' . $this->_escapeString : '');
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_expression->accept($visitor);
+        $visitor->visitLikeExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function isNot()
+    {
+        return $this->_not;
+    }
+    
+    public function getExpression()
+    {
+        return $this->_expression;
+    }
+    
+    public function getEscapeString()
+    {
+        return $this->_escapeString;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/LimitClause.php b/lib/Doctrine/Query/Production/LimitClause.php
index aa6bc6487..969152501 100644
--- a/lib/Doctrine/Query/Production/LimitClause.php
+++ b/lib/Doctrine/Query/Production/LimitClause.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_LimitClause extends Doctrine_Query_Production
@@ -45,4 +45,21 @@ class Doctrine_Query_Production_LimitClause extends Doctrine_Query_Production
 
         return $this;
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitLimitClause($this);
+    }
+    
+    /* Getters */
+    
+    public function getLimit()
+    {
+        return $this->_limit;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/NullComparisonExpression.php b/lib/Doctrine/Query/Production/NullComparisonExpression.php
index 10ee9c099..83cfa1361 100755
--- a/lib/Doctrine/Query/Production/NullComparisonExpression.php
+++ b/lib/Doctrine/Query/Production/NullComparisonExpression.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_NullComparisonExpression extends Doctrine_Query_Production
@@ -55,4 +55,21 @@ class Doctrine_Query_Production_NullComparisonExpression extends Doctrine_Query_
     {
         return 'IS ' . (($this->_not) ? 'NOT ' : '') . 'NULL';
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitNullComparisonExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function isNot()
+    {
+        return $this->_not;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/OffsetClause.php b/lib/Doctrine/Query/Production/OffsetClause.php
index c7c78d423..b8d689343 100644
--- a/lib/Doctrine/Query/Production/OffsetClause.php
+++ b/lib/Doctrine/Query/Production/OffsetClause.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_OffsetClause extends Doctrine_Query_Production
@@ -54,4 +54,21 @@ class Doctrine_Query_Production_OffsetClause extends Doctrine_Query_Production
         // SelectStatement, not this object's one.
         return ' OFFSET ' . $this->_offset;
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitOffsetClause($this);
+    }
+    
+    /* Getters */
+    
+    public function getOffset()
+    {
+        return $this->_offset;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/OrderByClause.php b/lib/Doctrine/Query/Production/OrderByClause.php
index 3e8cd5565..bfee179f7 100644
--- a/lib/Doctrine/Query/Production/OrderByClause.php
+++ b/lib/Doctrine/Query/Production/OrderByClause.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_OrderByClause extends Doctrine_Query_Production
@@ -65,4 +65,24 @@ class Doctrine_Query_Production_OrderByClause extends Doctrine_Query_Production
 
         return $str;
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        foreach ($this->_orderByItems as $item) {
+            $item->accept($visitor);
+        }
+        $visitor->visitOrderByClause($this);
+    }
+    
+    /* Getters */
+    
+    public function getOrderByItems()
+    {
+        return $this->_orderByItems;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/OrderByItem.php b/lib/Doctrine/Query/Production/OrderByItem.php
index e9ea65a7d..76a27553a 100644
--- a/lib/Doctrine/Query/Production/OrderByItem.php
+++ b/lib/Doctrine/Query/Production/OrderByItem.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_OrderByItem extends Doctrine_Query_Production
@@ -56,4 +56,27 @@ class Doctrine_Query_Production_OrderByItem extends Doctrine_Query_Production
     {
         return $this->_expression->buildSql() . ' ' . $this->_orderType;
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_expression->accept($visitor);
+        $visitor->visitOrderByItem($this);
+    }
+    
+    /* Getters */
+    
+    public function getExpression()
+    {
+        return $this->_expression;
+    }
+    
+    public function getOrderType()
+    {
+        return $this->_orderType;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/PathExpression.php b/lib/Doctrine/Query/Production/PathExpression.php
index 9f6fe049b..ee8ea35ec 100644
--- a/lib/Doctrine/Query/Production/PathExpression.php
+++ b/lib/Doctrine/Query/Production/PathExpression.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_PathExpression extends Doctrine_Query_Production
@@ -142,4 +142,31 @@ class Doctrine_Query_Production_PathExpression extends Doctrine_Query_Production
 
         return $conn->quoteIdentifier($str);
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitPathExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function getIdentifiers()
+    {
+        return $this->_identifiers;
+    }
+    
+    public function getFieldName()
+    {
+        return $this->_fieldName;
+    }
+    
+    public function getComponentAlias()
+    {
+        return $this->_componentAlias;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/PathExpressionEndingWithAsterisk.php b/lib/Doctrine/Query/Production/PathExpressionEndingWithAsterisk.php
index c24fdaae0..bbfcb0030 100644
--- a/lib/Doctrine/Query/Production/PathExpressionEndingWithAsterisk.php
+++ b/lib/Doctrine/Query/Production/PathExpressionEndingWithAsterisk.php
@@ -27,7 +27,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_PathExpressionEndingWithAsterisk extends Doctrine_Query_Production
@@ -154,4 +154,26 @@ class Doctrine_Query_Production_PathExpressionEndingWithAsterisk extends Doctrin
 
         return $str;
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitPathExpressionEndingWithAsterisk($this);
+    }
+    
+    /* Getters */
+    
+    public function getIdentifiers()
+    {
+        return $this->_identifiers;
+    }
+    
+    public function getQueryComponent()
+    {
+        return  $this->_queryComponent;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/Primary.php b/lib/Doctrine/Query/Production/Primary.php
index 6b2aab67d..1049bc157 100644
--- a/lib/Doctrine/Query/Production/Primary.php
+++ b/lib/Doctrine/Query/Production/Primary.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_Primary extends Doctrine_Query_Production
@@ -88,4 +88,23 @@ class Doctrine_Query_Production_Primary extends Doctrine_Query_Production
     {
         return '(' . $this->_expression->buildSql() . ')';
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_expression->accept($visitor);
+        $visitor->visitPrimary($this);
+    }
+    
+    /* Getters */
+    
+    public function getExpression()
+    {
+        return $this->_expression;
+    }
+    
 }
diff --git a/lib/Doctrine/Query/Production/QuantifiedExpression.php b/lib/Doctrine/Query/Production/QuantifiedExpression.php
index 44bf66b0b..1bb81c191 100644
--- a/lib/Doctrine/Query/Production/QuantifiedExpression.php
+++ b/lib/Doctrine/Query/Production/QuantifiedExpression.php
@@ -27,7 +27,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_QuantifiedExpression extends Doctrine_Query_Production
@@ -69,4 +69,27 @@ class Doctrine_Query_Production_QuantifiedExpression extends Doctrine_Query_Prod
     {
         return $this->_type . ' (' . $this->_subselect->buildSql() . ')';
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_subselect->accept($visitor);
+        $visitor->visitQuantifiedExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function getType()
+    {
+        return $this->_type;
+    }
+    
+    public function getSubselect()
+    {
+        return $this->_subselect;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/QueryLanguage.php b/lib/Doctrine/Query/Production/QueryLanguage.php
index 0f507295b..80413792c 100644
--- a/lib/Doctrine/Query/Production/QueryLanguage.php
+++ b/lib/Doctrine/Query/Production/QueryLanguage.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_QueryLanguage extends Doctrine_Query_Production
diff --git a/lib/Doctrine/Query/Production/RangeVariableDeclaration.php b/lib/Doctrine/Query/Production/RangeVariableDeclaration.php
index cebc9f826..8fd63725a 100644
--- a/lib/Doctrine/Query/Production/RangeVariableDeclaration.php
+++ b/lib/Doctrine/Query/Production/RangeVariableDeclaration.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_Production
@@ -235,4 +235,26 @@ class Doctrine_Query_Production_RangeVariableDeclaration extends Doctrine_Query_
         $parserResult->setQueryComponent($this->_identificationVariable, $queryComponent);
         $parserResult->setTableAlias($tableAlias, $this->_identificationVariable);
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitRangeVariableDeclaration($this);
+    }
+    
+    /* Getters */
+    
+    public function getIdentifiers()
+    {
+        return $this->_identifiers;
+    }
+    
+    public function getIdentificationVariable()
+    {
+        return $this->_identificationVariable;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/SelectClause.php b/lib/Doctrine/Query/Production/SelectClause.php
index f40c4475d..0d3fd6a7e 100644
--- a/lib/Doctrine/Query/Production/SelectClause.php
+++ b/lib/Doctrine/Query/Production/SelectClause.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_SelectClause extends Doctrine_Query_Production
@@ -85,4 +85,29 @@ class Doctrine_Query_Production_SelectClause extends Doctrine_Query_Production
     {
         return $value->buildSql();
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        foreach ($this->_selectExpressions as $expression) {
+            $expression->accept($visitor);
+        }
+        $visitor->visitSelectClause($this);
+    }
+    
+    /* Getters */
+    
+    public function isDistinct()
+    {
+        return $this->_isDistinct;
+    }
+    
+    public function getSelectExpressions()
+    {
+        return $this->_selectExpressions;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/SelectExpression.php b/lib/Doctrine/Query/Production/SelectExpression.php
index 150de0139..f362066f3 100644
--- a/lib/Doctrine/Query/Production/SelectExpression.php
+++ b/lib/Doctrine/Query/Production/SelectExpression.php
@@ -53,7 +53,7 @@ class Doctrine_Query_Production_SelectExpression extends Doctrine_Query_Producti
             $this->_leftExpression = $this->AST('PathExpressionEndingWithAsterisk', $paramHolder);
 
             $fieldName = implode('.', $this->_leftExpression->getIdentifiers()) . '.*';
-        } elseif(($this->_isSubselect = $this->_isSubselect()) === true) {
+        } else if (($this->_isSubselect = $this->_isSubselect()) === true) {
             $this->_parser->match('(');
             $this->_leftExpression = $this->AST('Subselect', $paramHolder);
             $this->_parser->match(')');
@@ -87,14 +87,16 @@ class Doctrine_Query_Production_SelectExpression extends Doctrine_Query_Producti
         $parserResult = $this->_parser->getParserResult();
 
         // We cannot have aliases for foo.*
-        if ($this->_leftExpression instanceof Doctrine_Query_Production_PathExpressionEndingWithAsterisk && $this->_fieldIdentificationVariable !== null) {
+        if ($this->_leftExpression instanceof Doctrine_Query_Production_PathExpressionEndingWithAsterisk
+                && $this->_fieldIdentificationVariable !== null) {
             $this->_parser->semanticalError(
                 "Cannot assign an identification variable to a path expression ending with asterisk (ie. foo.bar.* AS foobaz)."
             );
         }
 
         // Also, we cannot have aliases for path expressions: foo.bar
-        if ($this->_leftExpression instanceof Doctrine_Query_Production_PathExpressionEndingWithAsterisk && $this->_fieldIdentificationVariable !== null) {
+        if ($this->_leftExpression instanceof Doctrine_Query_Production_PathExpressionEndingWithAsterisk
+                && $this->_fieldIdentificationVariable !== null) {
             $this->_parser->semanticalError(
                 "Cannot assign an identification variable to a path expression (ie. foo.bar AS foobaz)."
             );
diff --git a/lib/Doctrine/Query/Production/SelectStatement.php b/lib/Doctrine/Query/Production/SelectStatement.php
index bba523c5b..63d13cd8c 100644
--- a/lib/Doctrine/Query/Production/SelectStatement.php
+++ b/lib/Doctrine/Query/Production/SelectStatement.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_SelectStatement extends Doctrine_Query_Production
@@ -93,4 +93,60 @@ class Doctrine_Query_Production_SelectStatement extends Doctrine_Query_Productio
              . (($this->_havingClause !== null) ? ' ' . $this->_havingClause->buildSql() : '')
              . (($this->_orderByClause !== null) ? ' ' . $this->_orderByClause->buildSql() : '');
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_selectClause->accept($visitor);
+        $this->_fromClause->accept($visitor);
+        if ($this->_whereClause) {
+            $this->_whereClause->accept($visitor);
+        }
+        if ($this->_groupByClause) {
+            $this->_groupByClause->accept($visitor);
+        }
+        if ($this->_havingClause) {
+            $this->_havingClause->accept($visitor);
+        }
+        if ($this->_orderByClause) {
+            $this->_orderByClause->accept($visitor);
+        }
+        $visitor->visitSelectStatement($this);
+    }
+    
+    /* Getters */
+    
+    public function getSelectClause()
+    {
+        return $this->_selectClause;
+    }
+    
+    public function getFromClause()
+    {
+        return $this->_fromClause;
+    }
+    
+    public function getWhereClause()
+    {
+        return $this->_whereClause;
+    }
+    
+    public function getGroupByClause()
+    {
+        return $this->_groupByClause;
+    }
+    
+    public function getHavingClause()
+    {
+        return $this->_havingClause;
+    }
+    
+    public function getOrderByClause()
+    {
+        return $this->_orderByClause;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/SimpleConditionalExpression.php b/lib/Doctrine/Query/Production/SimpleConditionalExpression.php
index 35c484e8e..ce3f58076 100644
--- a/lib/Doctrine/Query/Production/SimpleConditionalExpression.php
+++ b/lib/Doctrine/Query/Production/SimpleConditionalExpression.php
@@ -30,7 +30,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_SimpleConditionalExpression extends Doctrine_Query_Production
@@ -106,4 +106,28 @@ class Doctrine_Query_Production_SimpleConditionalExpression extends Doctrine_Que
 
         return $token['type'];
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_leftExpression->accept($visitor);
+        $this->_rightExpression->accept($visitor);
+        $visitor->visitSimpleConditionalExpression($this);
+    }
+    
+    /* Getters */
+    
+    public function getLeftExpression()
+    {
+        return $this->_leftExpression;
+    }
+    
+    public function getRightExpression()
+    {
+        return $this->_rightExpression;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/SimpleSelectClause.php b/lib/Doctrine/Query/Production/SimpleSelectClause.php
index 017aa9400..e014fe439 100644
--- a/lib/Doctrine/Query/Production/SimpleSelectClause.php
+++ b/lib/Doctrine/Query/Production/SimpleSelectClause.php
@@ -27,7 +27,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_SimpleSelectClause extends Doctrine_Query_Production
@@ -65,4 +65,27 @@ class Doctrine_Query_Production_SimpleSelectClause extends Doctrine_Query_Produc
         return 'SELECT ' . (($this->_isDistinct) ? 'DISTINCT ' : '')
              . $this->_selectExpression->buildSql();
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function acccept($visitor)
+    {
+        $this->_selectExpression->accept($visitor);
+        $visitor->visitSimpleSelectClause($this);
+    }
+    
+    /* Getters */
+    
+    public function isDistinct()
+    {
+        return $this->_isDistinct;
+    }
+    
+    public function getSelectExpression()
+    {
+        return $this->_selectExpression;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/Subselect.php b/lib/Doctrine/Query/Production/Subselect.php
index 4015b9d26..15a70843b 100644
--- a/lib/Doctrine/Query/Production/Subselect.php
+++ b/lib/Doctrine/Query/Production/Subselect.php
@@ -29,7 +29,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_Subselect extends Doctrine_Query_Production
@@ -101,5 +101,61 @@ class Doctrine_Query_Production_Subselect extends Doctrine_Query_Production
              . (($this->_havingClause !== null) ? ' ' . $this->_havingClause->buildSql() : '')
              . (($this->_orderByClause !== null) ? ' ' . $this->_orderByClause->buildSql() : '');
     }
+    
+    /**
+     * Visitor support
+     *
+     * @param object $visitor
+     */
+    public function accept($visitor)
+    {
+        $this->_simpleSelectClause->accept($visitor);
+        $this->_fromClause->accept($visitor);
+        if ($this->_whereClause) {
+            $this->_whereClause->accept($visitor);
+        }
+        if ($this->_groupByClause) {
+            $this->_groupByClause->accept($visitor);
+        }
+        if ($this->_havingClause) {
+            $this->_havingClause->accept($visitor);
+        }
+        if ($this->_orderByClause) {
+            $this->_orderByClause->accept($visitor);
+        }
+        $visitor->visitSubselect($this);
+    }
+    
+    /* Getters */
+    
+    public function getSimpleSelectClause()
+    {
+        return $this->_simpleSelectClause;
+    }
+    
+    public function getFromClause()
+    {
+        return $this->_fromClause;
+    }
+    
+    public function getWhereClause()
+    {
+        return $this->_whereClause;
+    }
+    
+    public function getGroupByClause()
+    {
+        return $this->_groupByClause;
+    }
+    
+    public function getHavingClause()
+    {
+        return $this->_havingClause;
+    }
+    
+    public function getOrderByClause()
+    {
+        return $this->_orderByClause;
+    }
 
 }
diff --git a/lib/Doctrine/Query/Production/Term.php b/lib/Doctrine/Query/Production/Term.php
index 9456e7df7..45e1b1d27 100644
--- a/lib/Doctrine/Query/Production/Term.php
+++ b/lib/Doctrine/Query/Production/Term.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_Term extends Doctrine_Query_Production
@@ -86,4 +86,22 @@ class Doctrine_Query_Production_Term extends Doctrine_Query_Production
     {
         return (is_string($value) ? $value : $value->buildSql());
     }
+    
+    /**
+     * Visitor support.
+     */
+    public function accept($visitor)
+    {
+        foreach ($this->_factors as $factor) {
+            $factor->accept($visitor);
+        }
+        $visitor->visitTerm($this);
+    }
+    
+    /* Getters */
+    
+    public function getFactors()
+    {
+        return $this->_factors;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/UpdateClause.php b/lib/Doctrine/Query/Production/UpdateClause.php
index 68c8d9592..5ff5d2ab1 100644
--- a/lib/Doctrine/Query/Production/UpdateClause.php
+++ b/lib/Doctrine/Query/Production/UpdateClause.php
@@ -74,4 +74,28 @@ class Doctrine_Query_Production_UpdateClause extends Doctrine_Query_Production
     {
         return $value->buildSql();
     }
+    
+    /**
+     * Visitor support.
+     */
+    public function accept($visitor)
+    {
+        $this->_variableDeclaration->accept($visitor);
+        foreach ($this->_updateItems as $item) {
+            $item->accept($visitor);
+        }
+        $visitor->visitUpdateClause($this);
+    }
+    
+    /* Getters */
+    
+    public function getVariableDeclaration()
+    {
+        return $this->_variableDeclaration;
+    }
+    
+    public function getUpdateItems()
+    {
+        return $this->_updateItems;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/UpdateItem.php b/lib/Doctrine/Query/Production/UpdateItem.php
index a08a43a43..1c9546643 100644
--- a/lib/Doctrine/Query/Production/UpdateItem.php
+++ b/lib/Doctrine/Query/Production/UpdateItem.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_UpdateItem extends Doctrine_Query_Production
@@ -59,4 +59,28 @@ class Doctrine_Query_Production_UpdateItem extends Doctrine_Query_Production
         return $this->_pathExpression->buildSql() . ' = ' 
              . ($this->_expression === null ? 'NULL' : $this->_expression->buildSql());
     }
+    
+    /**
+     * Visitor support.
+     */
+    public function accept($visitor)
+    {
+        $this->_pathExpression->accept($visitor);
+        if ($this->_expression) {
+            $this->_expression->accept($visitor);
+        }
+        $visitor->visitUpdateItem($this);
+    }
+    
+    /* Getters */
+    
+    public function getPathExpression()
+    {
+        return $this->_pathExpression;
+    }
+    
+    public function getExpression()
+    {
+        return $this->_expression;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/UpdateStatement.php b/lib/Doctrine/Query/Production/UpdateStatement.php
index 25cff2a95..cbb9eb373 100644
--- a/lib/Doctrine/Query/Production/UpdateStatement.php
+++ b/lib/Doctrine/Query/Production/UpdateStatement.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_UpdateStatement extends Doctrine_Query_Production
@@ -56,4 +56,28 @@ class Doctrine_Query_Production_UpdateStatement extends Doctrine_Query_Productio
         return $this->_updateClause->buildSql() . (($this->_whereClause !== null)
              ? ' ' . $this->_whereClause->buildSql() : ' WHERE 1 = 1');
     }
+    
+    /**
+     * Visitor support.
+     */
+    public function accept($visitor)
+    {
+        $this->_updateClause->accept($visitor);
+        if ($this->_whereClause) {
+            $this->_whereClause->accept($visitor);
+        }
+        $visitor->visitUpdateStatment($this);
+    }
+    
+    /* Getters */
+    
+    public function getUpdateClause()
+    {
+        return $this->_updateClause;
+    }
+    
+    public function getWhereClause()
+    {
+        return $this->_whereClause;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/VariableDeclaration.php b/lib/Doctrine/Query/Production/VariableDeclaration.php
index 1528d6102..b133c326e 100644
--- a/lib/Doctrine/Query/Production/VariableDeclaration.php
+++ b/lib/Doctrine/Query/Production/VariableDeclaration.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_VariableDeclaration extends Doctrine_Query_Production
@@ -130,4 +130,24 @@ class Doctrine_Query_Production_VariableDeclaration extends Doctrine_Query_Produ
         return $conn->quoteIdentifier($queryComponent['metadata']->getTableName()) . ' '
              . $conn->quoteIdentifier($parserResult->getTableAliasFromComponentAlias($this->_componentAlias));
     }
+    
+    /**
+     * Visitor support.
+     */
+    public function accept($visitor)
+    {
+        $visitor->visitVariableDeclaration($this);
+    }
+    
+    /* Getters */
+    
+    public function getComponentName()
+    {
+        return $this->_componentName;
+    }
+    
+    public function getComponentAlias()
+    {
+        return $this->_componentAlias;
+    }
 }
diff --git a/lib/Doctrine/Query/Production/WhereClause.php b/lib/Doctrine/Query/Production/WhereClause.php
index c683da523..ac14267d2 100644
--- a/lib/Doctrine/Query/Production/WhereClause.php
+++ b/lib/Doctrine/Query/Production/WhereClause.php
@@ -28,7 +28,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Production_WhereClause extends Doctrine_Query_Production
@@ -49,4 +49,20 @@ class Doctrine_Query_Production_WhereClause extends Doctrine_Query_Production
     {
         return 'WHERE ' . $this->_conditionalExpression->buildSql();
     }
+    
+    /**
+     * Visitor support.
+     */
+    public function accept($visitor)
+    {
+        $this->_conditionalExpression->accept($visitor);
+        $visitor->visitWhereClause($this);
+    }
+    
+    /* Getters */
+    
+    public function getConditionalExpression()
+    {
+        return $this->_conditionalExpression;
+    }
 }
diff --git a/lib/Doctrine/Query/ProductionParamHolder.php b/lib/Doctrine/Query/ProductionParamHolder.php
index 786dd9069..488583537 100644
--- a/lib/Doctrine/Query/ProductionParamHolder.php
+++ b/lib/Doctrine/Query/ProductionParamHolder.php
@@ -29,7 +29,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_ProductionParamHolder
diff --git a/lib/Doctrine/Query/Scanner.php b/lib/Doctrine/Query/Scanner.php
index f4c7bd63a..075f65f18 100644
--- a/lib/Doctrine/Query/Scanner.php
+++ b/lib/Doctrine/Query/Scanner.php
@@ -27,7 +27,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Doctrine_Query_Scanner
@@ -150,7 +150,7 @@ class Doctrine_Query_Scanner
 
         // World number: 1.000.000,02 or -1,234e-2
         $worldnum = strtr($value, array('.' => '', ',' => '.'));
-        if(is_numeric($worldnum)) {
+        if (is_numeric($worldnum)) {
             return $worldnum;
         }
 
diff --git a/lib/Doctrine/Query/SqlBuilder.php b/lib/Doctrine/Query/SqlBuilder.php
index 48dfbc1a8..e2d65089c 100755
--- a/lib/Doctrine/Query/SqlBuilder.php
+++ b/lib/Doctrine/Query/SqlBuilder.php
@@ -29,7 +29,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 abstract class Doctrine_Query_SqlBuilder
@@ -82,4 +82,199 @@ abstract class Doctrine_Query_SqlBuilder
     
 
     // End of Common SQL generations
+ 
+    
+      
+    /** The following is just test/draft code for now. */
+    
+    /*private $_sql;
+    private $_conditionalTerms = array();
+    private $_conditionalFactors = array();
+    private $_conditionalPrimaries = array();
+    private $_variableDeclaration = array();
+    private $_expressions = array();
+    private $_deleteClause;
+    private $_whereClause;
+    
+    public function visitVariableDeclaration($variableDeclaration)
+    {
+        echo " VariableDeclaration ";
+        // Basic handy variables
+        $parserResult = $variableDeclaration->getParser()->getParserResult();
+        $queryComponent = $parserResult->getQueryComponent($variableDeclaration->getComponentAlias());
+
+        // Retrieving connection
+        $manager = Doctrine_EntityManagerFactory::getManager();
+        $conn = $manager->getConnection();
+
+        $this->_variableDeclaration[] = $conn->quoteIdentifier($queryComponent['metadata']->getTableName()) . ' '
+             . $conn->quoteIdentifier($parserResult->getTableAliasFromComponentAlias(
+                    $variableDeclaration->getComponentAlias()));
+    }
+    
+    public function visitDeleteClause($deleteClause)
+    {
+        echo " DeleteClause ";
+        $this->_deleteClause = 'DELETE FROM ' . array_pop($this->_variableDeclaration);
+    }
+    
+    public function visitDeleteStatement($deleteStatement)
+    {
+        echo " DeleteStatement ";
+        $this->_sql = $this->_deleteClause;
+        if ($this->_whereClause) {
+            $this->_sql .= $this->_whereClause;
+        } else {
+            $this->_sql .= " WHERE 1 = 1";
+        }
+    }
+    
+    public function visitWhereClause($whereClause)
+    {
+        echo " WhereClause ";
+        if ($this->_expressions) {
+            $this->_whereClause = ' WHERE ' . array_pop($this->_expressions);
+        }
+    }
+    
+    public function visitConditionalExpression($conditionalExpression)
+    {
+        echo " ConditionalExpression ";
+        $count = count($conditionalExpression->getConditionalTerms());
+        $terms = array();
+        for ($i=0; $i<$count; $i++) {
+            $terms[] = array_pop($this->_conditionalTerms);
+        }
+        
+        $this->_expressions[] = implode(' OR ', $terms);
+    }
+    
+    public function visitSimpleConditionalExpression($simpleConditionalExpression)
+    {
+        //var_dump($this->_expressions);
+        echo " SimpleConditionalExpression ";
+        $rightExpr = array_pop($this->_expressions);
+        $leftExpr = array_pop($this->_expressions); 
+        $this->_expressions[] = $leftExpr . ' ' . $rightExpr;
+    }
+    
+    public function visitConditionalPrimary($conditionalPrimary)
+    {
+        echo " ConditionalPrimary ";
+        if ($this->_expressions) {
+            $this->_conditionalPrimaries[] = '(' . array_pop($this->_expressions) . ')';
+        }
+    }
+    
+    public function visitConditionalTerm($conditionalTerm)
+    {
+        echo " ConditionalTerm ";
+        $count = count($conditionalTerm->getConditionalFactors());
+        $factors = array();
+        for ($i=0; $i<$count; $i++) {
+            $factors[] = array_pop($this->_conditionalFactors);
+        }
+        
+        $this->_conditionalTerms[] = implode(' AND ', $factors);
+    }
+    
+    public function visitConditionalFactor($conditionalFactor)
+    {
+        echo " ConditionalFactor ";
+        if ($this->_conditionalPrimaries) {
+            $this->_conditionalFactors[] = 'NOT ' . array_pop($this->_conditionalPrimaries);
+        }
+    }
+    
+    public function visitBetweenExpression($betweenExpression)
+    {
+        $this->_expressions[] = (($betweenExpression->getNot()) ? 'NOT ' : '') . 'BETWEEN '
+             . array_pop($this->_expressions) . ' AND ' . array_pop($this->_expressions);
+    }
+    
+    public function visitLikeExpression($likeExpression)
+    {
+        $this->_expressions[] = (($likeExpression->getNot()) ? 'NOT ' : '') . 'LIKE ' .
+                array_pop($this->_expressions)
+             . (($likeExpression->getEscapeString() !== null) ? ' ESCAPE ' . $likeExpression->getEscapeString() : '');
+    }
+    
+    public function visitInExpression($inExpression)
+    {
+        $count = count($inExpression->getAtoms());
+        $atoms = array();
+        for ($i=0; $i<$count; $i++) {
+            $atoms[] = array_pop($this->_expressions);
+        }
+        
+        $this->_expressions[] = (($inExpression->getNot()) ? 'NOT ' : '') . 'IN ('
+             . (($inExpression->getSubselect() !== null) ? array_pop($this->_expressions) :
+                    implode(', ', $atoms))
+             . ')';
+    }
+    
+    public function visitNullComparisonExpression($nullComparisonExpression)
+    {
+        $this->_expressions[] = 'IS ' . (($nullComparisonExpression->getNot()) ? 'NOT ' : '') . 'NULL';
+    }
+    
+    public function visitAtom($atom)
+    {
+        $conn = $atom->getParser()->getSqlBuilder()->getConnection();
+        switch ($atom->getType()) {
+            case 'param':
+                $this->_expressions[] = $atom->getValue();
+            break;
+            case 'integer':
+            case 'float':
+                $this->_expressions[] = $conn->quote($atom->getValue(), $atom->getType());
+            break;
+            default:
+                $stringQuoting = $this->_conn->getProperty('string_quoting');
+                $this->_expressions[] = $stringQuoting['start']
+                     . $conn->quote($this->_value, $this->_type)
+                     . $stringQuoting['end'];
+            break;
+        }
+    }
+    
+    public function visitPathExpression($pathExpression)
+    {
+        echo " PathExpression ";
+                // Basic handy variables
+        $parserResult = $pathExpression->getParser()->getParserResult();
+
+        // Retrieving connection
+        $manager = Doctrine_EntityManagerFactory::getManager(); 
+        $conn = $manager->getConnection();
+
+        // Looking for queryComponent to fetch
+        $queryComponent = $parserResult->getQueryComponent($pathExpression->getComponentAlias());
+
+        // Generating the SQL piece
+        $str = $parserResult->getTableAliasFromComponentAlias($pathExpression->getComponentAlias()) . '.'
+             . $queryComponent['metadata']->getColumnName($pathExpression->getFieldName());
+
+        $this->_expressions[] = $conn->quoteIdentifier($str);
+    }
+    
+    public function visitComparisonExpression($comparisonExpression)
+    {
+        echo " ComparisonExpression ";
+        
+        $expr = $comparisonExpression->getOperator() . ' ';
+        if ($comparisonExpression->getIsSubselect()) {
+            $expr .= '(' . array_pop($this->_expressions) . ')';
+        } else {
+            $expr .= array_pop($this->_expressions);
+        }
+        $this->_expressions[] = $expr;
+    }
+    
+    
+    
+    public function getSql()
+    {
+        return $this->_sql;
+    }*/
 }
diff --git a/lib/Doctrine/Query/SqlExecutor/SingleTableDeleteUpdate.php b/lib/Doctrine/Query/SqlExecutor/SingleTableDeleteUpdate.php
index 09e01b006..102954012 100644
--- a/lib/Doctrine/Query/SqlExecutor/SingleTableDeleteUpdate.php
+++ b/lib/Doctrine/Query/SqlExecutor/SingleTableDeleteUpdate.php
@@ -36,6 +36,13 @@ class Doctrine_Query_SqlExecutor_SingleTableDeleteUpdate extends Doctrine_Query_
     public function __construct(Doctrine_Query_Production $AST)
     {
         parent::__construct($AST);
+        
+        /*if ($AST instanceof Doctrine_Query_Production_DeleteStatement) {
+            $builder = new Doctrine_Query_SqlBuilder_MySql(Doctrine_EntityManagerFactory::getManager());
+            $AST->accept($builder);
+            echo PHP_EOL . "SQL:" . $builder->getSql() . PHP_EOL . PHP_EOL;
+        }*/
+        
         $this->_sqlStatements = $AST->buildSql();
     }
     
diff --git a/lib/Doctrine/Query/Token.php b/lib/Doctrine/Query/Token.php
index 92b6cbe10..6eb1e8e37 100644
--- a/lib/Doctrine/Query/Token.php
+++ b/lib/Doctrine/Query/Token.php
@@ -27,7 +27,7 @@
  * @author      Janne Vanhala 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 final class Doctrine_Query_Token
diff --git a/lib/Doctrine/Relation/LocalKey.php b/lib/Doctrine/Relation/LocalKey.php
index 623ba9276..9590b2069 100644
--- a/lib/Doctrine/Relation/LocalKey.php
+++ b/lib/Doctrine/Relation/LocalKey.php
@@ -18,7 +18,7 @@
  * and is licensed under the LGPL. For more information, see
  * .
  */
-Doctrine::autoload('Doctrine_Relation');
+
 /**
  * Doctrine_Relation_LocalKey
  * This class represents a local key relation
diff --git a/tests/Orm/AllTests.php b/tests/Orm/AllTests.php
index 7535e4afe..c8746fc14 100644
--- a/tests/Orm/AllTests.php
+++ b/tests/Orm/AllTests.php
@@ -10,9 +10,10 @@ require_once 'Orm/Component/AllTests.php';
 require_once 'Orm/Query/AllTests.php';
 require_once 'Orm/Hydration/AllTests.php';
 require_once 'Orm/Ticket/AllTests.php';
+require_once 'Orm/Entity/AllTests.php';
 
 // Tests
-require_once 'Orm/UnitOfWorkTestCase.php';
+require_once 'Orm/UnitOfWorkTest.php';
 require_once 'Orm/EntityManagerFactoryTest.php';
 
 class Orm_AllTests
@@ -26,13 +27,14 @@ class Orm_AllTests
     {
         $suite = new Doctrine_OrmTestSuite('Doctrine Orm');
 
-        $suite->addTestSuite('Orm_UnitOfWorkTestCase');
+        $suite->addTestSuite('Orm_UnitOfWorkTest');
         $suite->addTestSuite('Orm_EntityManagerFactoryTest');
         //$suite->addTestSuite('Orm_ConfigurableTestCase');
         
         $suite->addTest(Orm_Component_AllTests::suite());
         $suite->addTest(Orm_Query_AllTests::suite());
         $suite->addTest(Orm_Hydration_AllTests::suite());
+        $suite->addTest(Orm_Entity_AllTests::suite());
         $suite->addTest(Orm_Ticket_AllTests::suite());
 
         return $suite;
diff --git a/tests/Orm/Component/CollectionTest.php b/tests/Orm/Component/CollectionTest.php
index 223909fe3..49e264be1 100644
--- a/tests/Orm/Component/CollectionTest.php
+++ b/tests/Orm/Component/CollectionTest.php
@@ -27,7 +27,7 @@
  * @author      Bjarte Stien Karlsen 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision: 3754 $
  */
 require_once 'lib/DoctrineTestInit.php';
diff --git a/tests/Orm/Entity/AccessorTestCase.php b/tests/Orm/Entity/AccessorTestCase.php
index d2d076fda..0bee542de 100644
--- a/tests/Orm/Entity/AccessorTestCase.php
+++ b/tests/Orm/Entity/AccessorTestCase.php
@@ -29,12 +29,12 @@ class CustomAccessorMutatorTestEntity extends Doctrine_Entity
     
     public function getUsernameCustom()
     {
-        return $this->rawGetField('username') . "!";
+        return $this->_rawGetField('username') . "!";
     }
     
     public function setUsernameCustom($username)
     {
-        $this->rawSetField('username', $username . "?");
+        $this->_rawSetField('username', $username . "?");
     }
 }
 
@@ -47,11 +47,11 @@ class MagicAccessorMutatorTestEntity extends Doctrine_Entity
     
     public function getUsername()
     {
-        return $this->rawGetField('username') . "!";
+        return $this->_rawGetField('username') . "!";
     }
     
     public function setUsername($username)
     {
-        $this->rawSetField('username', $username . "?");
+        $this->_rawSetField('username', $username . "?");
     } 
 }
\ No newline at end of file
diff --git a/tests/Orm/EntityManagerFactoryTest.php b/tests/Orm/EntityManagerFactoryTest.php
index 5f508381b..903ee60c3 100644
--- a/tests/Orm/EntityManagerFactoryTest.php
+++ b/tests/Orm/EntityManagerFactoryTest.php
@@ -8,14 +8,8 @@ require_once 'lib/DoctrineTestInit.php';
  */
 class Orm_EntityManagerFactoryTest extends Doctrine_OrmTestCase
 {
-    private $_emf;
     private $_mockOptions = array('driver' => 'mock', 'user' => '', 'password' => '');
     
-    protected function setUp() {
-        parent::setUp();
-        $this->_emf = $this->sharedFixture['emf'];
-    }
-    
     protected function tearDown() {
         parent::tearDown();
     }
diff --git a/tests/Orm/Hydration/BasicHydrationTest.php b/tests/Orm/Hydration/BasicHydrationTest.php
index c7eecf758..38411990d 100644
--- a/tests/Orm/Hydration/BasicHydrationTest.php
+++ b/tests/Orm/Hydration/BasicHydrationTest.php
@@ -45,8 +45,7 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
         // Faked query components
         $queryComponents = array(
             'u' => array(
-                'table' => $this->_em->getClassMetadata('CmsUser'),
-                'mapper' => $this->_em->getEntityPersister('CmsUser'),
+                'metadata' => $this->_em->getClassMetadata('CmsUser'),
                 'parent' => null,
                 'relation' => null,
                 'map' => null
@@ -115,16 +114,14 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
         // Faked query components
         $queryComponents = array(
             'u' => array(
-                'table' => $this->_em->getClassMetadata('CmsUser'),
-                'mapper' => $this->_em->getEntityPersister('CmsUser'),
+                'metadata' => $this->_em->getClassMetadata('CmsUser'),
                 'parent' => null,
                 'relation' => null,
                 'map' => null,
                 'agg' => array('0' => 'nameUpper')
                 ),
             'p' => array(
-                'table' => $this->_em->getClassMetadata('CmsPhonenumber'),
-                'mapper' => $this->_em->getEntityPersister('CmsPhonenumber'),
+                'metadata' => $this->_em->getClassMetadata('CmsPhonenumber'),
                 'parent' => 'u',
                 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
                 'map' => null
@@ -198,7 +195,6 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
         } else if ($hydrationMode == Doctrine::HYDRATE_SCALAR) {
             $this->assertTrue(is_array($result));
             $this->assertEquals(3, count($result));
-
             $this->assertEquals(1, $result[0]['u_id']);
             $this->assertEquals('developer', $result[0]['u_status']);
             $this->assertEquals('ROMANB', $result[0]['u_nameUpper']);
@@ -222,15 +218,13 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
         // Faked query components
         $queryComponents = array(
             'u' => array(
-                'table' => $this->_em->getClassMetadata('CmsUser'),
-                'mapper' => $this->_em->getEntityPersister('CmsUser'),
+                'metadata' => $this->_em->getClassMetadata('CmsUser'),
                 'parent' => null,
                 'relation' => null,
                 'map' => null
                 ),
             'p' => array(
-                'table' => $this->_em->getClassMetadata('CmsPhonenumber'),
-                'mapper' => $this->_em->getEntityPersister('CmsPhonenumber'),
+                'metadata' => $this->_em->getClassMetadata('CmsPhonenumber'),
                 'parent' => 'u',
                 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
                 'map' => null,
@@ -308,16 +302,14 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
         // Faked query components
         $queryComponents = array(
             'u' => array(
-                'table' => $this->_em->getClassMetadata('CmsUser'),
-                'mapper' => $this->_em->getEntityPersister('CmsUser'),
+                'metadata' => $this->_em->getClassMetadata('CmsUser'),
                 'parent' => null,
                 'relation' => null,
                 'agg' => array('0' => 'nameUpper'),
                 'map' => 'id'
                 ),
             'p' => array(
-                'table' => $this->_em->getClassMetadata('CmsPhonenumber'),
-                'mapper' => $this->_em->getEntityPersister('CmsPhonenumber'),
+                'metadata' => $this->_em->getClassMetadata('CmsPhonenumber'),
                 'parent' => 'u',
                 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
                 'map' => 'phonenumber'
@@ -414,23 +406,20 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
         // Faked query components
         $queryComponents = array(
             'u' => array(
-                'table' => $this->_em->getClassMetadata('CmsUser'),
-                'mapper' => $this->_em->getEntityPersister('CmsUser'),
+                'metadata' => $this->_em->getClassMetadata('CmsUser'),
                 'parent' => null,
                 'relation' => null,
                 'map' => null,
                 'agg' => array('0' => 'nameUpper')
                 ),
             'p' => array(
-                'table' => $this->_em->getClassMetadata('CmsPhonenumber'),
-                'mapper' => $this->_em->getEntityPersister('CmsPhonenumber'),
+                'metadata' => $this->_em->getClassMetadata('CmsPhonenumber'),
                 'parent' => 'u',
                 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
                 'map' => null
                 ),
             'a' => array(
-                'table' => $this->_em->getClassMetadata('CmsArticle'),
-                'mapper' => $this->_em->getEntityPersister('CmsArticle'),
+                'metadata' => $this->_em->getClassMetadata('CmsArticle'),
                 'parent' => 'u',
                 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('articles'),
                 'map' => null
@@ -573,30 +562,26 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
         // Faked query components
         $queryComponents = array(
             'u' => array(
-                'table' => $this->_em->getClassMetadata('CmsUser'),
-                'mapper' => $this->_em->getEntityPersister('CmsUser'),
+                'metadata' => $this->_em->getClassMetadata('CmsUser'),
                 'parent' => null,
                 'relation' => null,
                 'map' => null,
                 'agg' => array('0' => 'nameUpper')
                 ),
             'p' => array(
-                'table' => $this->_em->getClassMetadata('CmsPhonenumber'),
-                'mapper' => $this->_em->getEntityPersister('CmsPhonenumber'),
+                'metadata' => $this->_em->getClassMetadata('CmsPhonenumber'),
                 'parent' => 'u',
                 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
                 'map' => null
                 ),
             'a' => array(
-                'table' => $this->_em->getClassMetadata('CmsArticle'),
-                'mapper' => $this->_em->getEntityPersister('CmsArticle'),
+                'metadata' => $this->_em->getClassMetadata('CmsArticle'),
                 'parent' => 'u',
                 'relation' => $this->_em->getClassMetadata('CmsUser')->getRelation('articles'),
                 'map' => null
                 ),
             'c' => array(
-                'table' => $this->_em->getClassMetadata('CmsComment'),
-                'mapper' => $this->_em->getEntityPersister('CmsComment'),
+                'metadata' => $this->_em->getClassMetadata('CmsComment'),
                 'parent' => 'a',
                 'relation' => $this->_em->getClassMetadata('CmsArticle')->getRelation('comments'),
                 'map' => null
@@ -713,9 +698,10 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
             $this->assertEquals('First!', $result[0][0]['articles'][0]['comments'][0]['topic']);
     
             $this->assertTrue(isset($result[0][0]['articles'][0]['comments']));
-            $this->assertFalse(isset($result[0][0]['articles'][1]['comments']));
-            $this->assertFalse(isset($result[1][0]['articles'][0]['comments']));
-            $this->assertFalse(isset($result[1][0]['articles'][1]['comments']));
+            // empty collections/arrays
+            $this->assertTrue(isset($result[0][0]['articles'][1]['comments']));
+            $this->assertTrue(isset($result[1][0]['articles'][0]['comments']));
+            $this->assertTrue(isset($result[1][0]['articles'][1]['comments']));
         }
 
         if ($hydrationMode == Doctrine::HYDRATE_RECORD) {
@@ -736,8 +722,25 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
             // article comments
             $this->assertTrue($result[0][0]['articles'][0]['comments'] instanceof Doctrine_Collection);
             $this->assertTrue($result[0][0]['articles'][0]['comments'][0] instanceof Doctrine_Entity);
+            // empty comment collections
+            $this->assertTrue($result[0][0]['articles'][1]['comments'] instanceof Doctrine_Collection);
+            $this->assertEquals(0, count($result[0][0]['articles'][1]['comments']));
+            $this->assertTrue($result[1][0]['articles'][0]['comments'] instanceof Doctrine_Collection);
+            $this->assertEquals(0, count($result[1][0]['articles'][0]['comments']));
+            $this->assertTrue($result[1][0]['articles'][1]['comments'] instanceof Doctrine_Collection);
+            $this->assertEquals(0, count($result[1][0]['articles'][1]['comments']));
         } else if ($hydrationMode == Doctrine::HYDRATE_SCALAR) {
             //...
+        } else if ($hydrationMode == Doctrine::HYDRATE_ARRAY) {
+            //...
+            
+            // empty comment collections
+            $this->assertTrue(is_array($result[0][0]['articles'][1]['comments']));
+            $this->assertEquals(0, count($result[0][0]['articles'][1]['comments']));
+            $this->assertTrue(is_array($result[1][0]['articles'][0]['comments']));
+            $this->assertEquals(0, count($result[1][0]['articles'][0]['comments']));
+            $this->assertTrue(is_array($result[1][0]['articles'][1]['comments']));
+            $this->assertEquals(0, count($result[1][0]['articles'][1]['comments']));
         }
     }
     
@@ -768,15 +771,13 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
         // Faked query components
         $queryComponents = array(
             'c' => array(
-                'table' => $this->_em->getClassMetadata('ForumCategory'),
-                'mapper' => $this->_em->getEntityPersister('ForumCategory'),
+                'metadata' => $this->_em->getClassMetadata('ForumCategory'),
                 'parent' => null,
                 'relation' => null,
                 'map' => null
                 ),
             'b' => array(
-                'table' => $this->_em->getClassMetadata('ForumBoard'),
-                'mapper' => $this->_em->getEntityPersister('ForumBoard'),
+                'metadata' => $this->_em->getClassMetadata('ForumBoard'),
                 'parent' => 'c',
                 'relation' => $this->_em->getClassMetadata('ForumCategory')->getRelation('boards'),
                 'map' => null
@@ -904,8 +905,7 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
         // Faked query components
         $queryComponents = array(
             'u' => array(
-                'table' => $this->_em->getClassMetadata('CmsUser'),
-                'mapper' => $this->_em->getEntityPersister('CmsUser'),
+                'metadata' => $this->_em->getClassMetadata('CmsUser'),
                 'parent' => null,
                 'relation' => null,
                 'map' => null
diff --git a/tests/Orm/Query/DeleteSqlGenerationTest.php b/tests/Orm/Query/DeleteSqlGenerationTest.php
index aeb36d668..8c123a558 100755
--- a/tests/Orm/Query/DeleteSqlGenerationTest.php
+++ b/tests/Orm/Query/DeleteSqlGenerationTest.php
@@ -29,7 +29,7 @@ require_once 'lib/DoctrineTestInit.php';
  * @author      Konsta Vesterinen 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  * @todo        1) [romanb] We  might want to split the SQL generation tests into multiple
  *              testcases later since we'll have a lot of them and we might want to have special SQL
@@ -40,7 +40,7 @@ class Orm_Query_DeleteSqlGenerationTest extends Doctrine_OrmTestCase
     public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed)
     {
         try {
-            $entityManager = $this->sharedFixture['em'];
+            $entityManager = $this->_em;
             $query = $entityManager->createQuery($dqlToBeTested);
 
             parent::assertEquals($sqlToBeConfirmed, $query->getSql());
diff --git a/tests/Orm/Query/DqlGenerationTest.php b/tests/Orm/Query/DqlGenerationTest.php
index 6b1202ef8..959a4c409 100755
--- a/tests/Orm/Query/DqlGenerationTest.php
+++ b/tests/Orm/Query/DqlGenerationTest.php
@@ -36,7 +36,7 @@ class Orm_Query_DqlGenerationTest extends Doctrine_OrmTestCase
 {
     protected function createQuery()
     {
-        $entityManager = $this->sharedFixture['em'];
+        $entityManager = $this->_em;
         return $entityManager->createQuery();
     }
 
diff --git a/tests/Orm/Query/IdentifierRecognitionTest.php b/tests/Orm/Query/IdentifierRecognitionTest.php
index 338d32385..c12b290d8 100755
--- a/tests/Orm/Query/IdentifierRecognitionTest.php
+++ b/tests/Orm/Query/IdentifierRecognitionTest.php
@@ -31,7 +31,7 @@ require_once 'lib/DoctrineTestInit.php';
  * @author      Konsta Vesterinen 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  */
 class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
@@ -39,7 +39,7 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
 
     public function testSingleAliasDeclarationIsSupported()
     {
-        $entityManager = $this->sharedFixture['em'];
+        $entityManager = $this->_em;
         $query = $entityManager->createQuery('SELECT u.* FROM CmsUser u');
         $parserResult = $query->parse();
 
@@ -54,7 +54,7 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
 
     public function testSingleAliasDeclarationWithIndexByIsSupported()
     {
-        $entityManager = $this->sharedFixture['em'];
+        $entityManager = $this->_em;
         $query = $entityManager->createQuery('SELECT u.* FROM CmsUser u INDEX BY id');
         $parserResult = $query->parse();
 
@@ -69,7 +69,7 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
 
     public function testQueryParserSupportsMultipleAliasDeclarations()
     {
-        $entityManager = $this->sharedFixture['em'];
+        $entityManager = $this->_em;
         $query = $entityManager->createQuery('SELECT u.* FROM CmsUser u INDEX BY id LEFT JOIN u.phonenumbers p');
         $parserResult = $query->parse();
 
@@ -93,7 +93,7 @@ class Orm_Query_IdentifierRecognitionTest extends Doctrine_OrmTestCase
 
     public function testQueryParserSupportsMultipleAliasDeclarationsWithIndexBy()
     {
-        $entityManager = $this->sharedFixture['em'];
+        $entityManager = $this->_em;
         $query = $entityManager->createQuery('SELECT u.* FROM CmsUser u INDEX BY id LEFT JOIN u.articles a INNER JOIN u.phonenumbers pn INDEX BY phonenumber');
         $parserResult = $query->parse();
 
diff --git a/tests/Orm/Query/LanguageRecognitionTest.php b/tests/Orm/Query/LanguageRecognitionTest.php
index 97798bcc4..51a9cfbfd 100755
--- a/tests/Orm/Query/LanguageRecognitionTest.php
+++ b/tests/Orm/Query/LanguageRecognitionTest.php
@@ -30,7 +30,7 @@ require_once 'lib/DoctrineTestInit.php';
  * @author      Konsta Vesterinen 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  * @todo        1) [romanb] We  might want to split the SQL generation tests into multiple
  *              testcases later since we'll have a lot of them and we might want to have special SQL
@@ -41,7 +41,7 @@ class Orm_Query_LanguageRecognitionTest extends Doctrine_OrmTestCase
     public function assertValidDql($dql)
     {
         try {
-            $entityManager = $this->sharedFixture['em'];
+            $entityManager = $this->_em;
             $query = $entityManager->createQuery($dql);
             $parserResult = $query->parse();
         } catch (Doctrine_Exception $e) {
@@ -52,7 +52,7 @@ class Orm_Query_LanguageRecognitionTest extends Doctrine_OrmTestCase
     public function assertInvalidDql($dql)
     {
         try {
-            $entityManager = $this->sharedFixture['em'];
+            $entityManager = $this->_em;
             $query = $entityManager->createQuery($dql);
             $query->setDql($dql);
             $parserResult = $query->parse();
diff --git a/tests/Orm/Query/SelectSqlGenerationTest.php b/tests/Orm/Query/SelectSqlGenerationTest.php
index 1dd6a6b65..b8183b371 100755
--- a/tests/Orm/Query/SelectSqlGenerationTest.php
+++ b/tests/Orm/Query/SelectSqlGenerationTest.php
@@ -29,7 +29,7 @@ require_once 'lib/DoctrineTestInit.php';
  * @author      Konsta Vesterinen 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  * @todo        1) [romanb] We  might want to split the SQL generation tests into multiple
  *              testcases later since we'll have a lot of them and we might want to have special SQL
@@ -40,7 +40,7 @@ class Orm_Query_SelectSqlGenerationTest extends Doctrine_OrmTestCase
     public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed)
     {
         try {
-            $entityManager = $this->sharedFixture['em'];
+            $entityManager = $this->_em;
             $query = $entityManager->createQuery($dqlToBeTested);
             //echo print_r($query->parse()->getQueryFields(), true) . "\n";
 
diff --git a/tests/Orm/Query/UpdateSqlGenerationTest.php b/tests/Orm/Query/UpdateSqlGenerationTest.php
index c8b6f5762..4a61f1512 100755
--- a/tests/Orm/Query/UpdateSqlGenerationTest.php
+++ b/tests/Orm/Query/UpdateSqlGenerationTest.php
@@ -29,7 +29,7 @@
  * @author      Konsta Vesterinen 
  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  * @link        http://www.phpdoctrine.org
- * @since       1.0
+ * @since       2.0
  * @version     $Revision$
  * @todo        1) [romanb] We  might want to split the SQL generation tests into multiple
  *              testcases later since we'll have a lot of them and we might want to have special SQL
@@ -40,7 +40,7 @@ class Orm_Query_UpdateSqlGenerationTest extends Doctrine_OrmTestCase
     public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed)
     {
         try {
-            $entityManager = $this->sharedFixture['em'];
+            $entityManager = $this->_em;
             $query = $entityManager->createQuery($dqlToBeTested);
 
             parent::assertEquals($sqlToBeConfirmed, $query->getSql());
diff --git a/tests/Orm/UnitOfWorkTestCase.php b/tests/Orm/UnitOfWorkTestCase.php
deleted file mode 100644
index b03efda2e..000000000
--- a/tests/Orm/UnitOfWorkTestCase.php
+++ /dev/null
@@ -1,59 +0,0 @@
-_user = new ForumUser();
-        $this->_unitOfWork = $em->getUnitOfWork();
-    }
-    
-    protected function tearDown() {
-        $this->_user->free();
-    }
-    
-    public function testRegisterNew()
-    {
-        $this->_user->username = 'romanb';
-        $this->_user->id = 1;
-        $this->_unitOfWork->registerNew($this->_user);
-        $this->assertFalse($this->_unitOfWork->contains($this->_user));
-        $this->assertTrue($this->_unitOfWork->isRegisteredNew($this->_user));
-        $this->assertFalse($this->_unitOfWork->isRegisteredDirty($this->_user));
-        $this->assertFalse($this->_unitOfWork->isRegisteredRemoved($this->_user));
-    }
-    
-    public function testRegisterDirty()
-    {
-        $this->_user->username = 'romanb';
-        $this->_user->id = 1;
-        $this->assertEquals(Doctrine_Entity::STATE_TDIRTY, $this->_user->state());
-        $this->assertFalse($this->_unitOfWork->contains($this->_user));
-        $this->_unitOfWork->registerDirty($this->_user);
-        $this->assertTrue($this->_unitOfWork->isRegisteredDirty($this->_user));
-        $this->assertFalse($this->_unitOfWork->isRegisteredNew($this->_user));
-        $this->assertFalse($this->_unitOfWork->isRegisteredRemoved($this->_user));
-    }
-    
-    public function testRegisterRemovedOnTransientEntityIsIgnored()
-    {
-        $this->_user->username = 'romanb';
-        $this->_user->id = 1;
-        $this->assertFalse($this->_unitOfWork->isRegisteredRemoved($this->_user));
-        $this->_unitOfWork->registerRemoved($this->_user);
-        $this->assertFalse($this->_unitOfWork->isRegisteredRemoved($this->_user));        
-    }
-    
-    /*public function testSavedEntityHasIdentityAndIsManaged()
-    {
-        $this->_user->username = 'romanb';
-        $this->_user->save();
-        $this->assertTrue($this->_unitOfWork->hasIdentity($this->_user));
-        $this->assertTrue($this->_unitOfWork->isManaged($this->_user));
-    }*/
-}
\ No newline at end of file
diff --git a/tests/lib/Doctrine_DbalTestCase.php b/tests/lib/Doctrine_DbalTestCase.php
index ffc6de2d6..38bbcf0f5 100644
--- a/tests/lib/Doctrine_DbalTestCase.php
+++ b/tests/lib/Doctrine_DbalTestCase.php
@@ -4,6 +4,8 @@
  */
 class Doctrine_DbalTestCase extends Doctrine_TestCase
 {
+    protected $_conn;
+    
     /**
      * setUp()
      *
@@ -16,8 +18,11 @@ class Doctrine_DbalTestCase extends Doctrine_TestCase
     {
         // Setup a db connection if there is none, yet. This makes it possible
         // to run tests that use a connection standalone.
-        if ( ! isset($this->sharedFixture['connection'])) {
-            $this->sharedFixture['connection'] = Doctrine_TestUtil::getConnection();
+        if (isset($this->sharedFixture['conn'])) {
+            $this->_conn = $this->sharedFixture['conn'];
+        } else {
+            $this->sharedFixture['conn'] = Doctrine_TestUtil::getConnection();
+            $this->_conn = $this->sharedFixture['conn'];
         }
     }
 }
\ No newline at end of file
diff --git a/tests/lib/Doctrine_DbalTestSuite.php b/tests/lib/Doctrine_DbalTestSuite.php
index 99e86945b..cd3ec889a 100644
--- a/tests/lib/Doctrine_DbalTestSuite.php
+++ b/tests/lib/Doctrine_DbalTestSuite.php
@@ -11,7 +11,7 @@ class Doctrine_DbalTestSuite extends Doctrine_TestSuite
     
     protected function setUp()
     {
-        $this->sharedFixture['connection'] = Doctrine_TestUtil::getConnection();
+        $this->sharedFixture['conn'] = Doctrine_TestUtil::getConnection();
     }
     
     protected function tearDown()
diff --git a/tests/lib/Doctrine_OrmTestCase.php b/tests/lib/Doctrine_OrmTestCase.php
index d3a0fc2da..ca0beb46f 100644
--- a/tests/lib/Doctrine_OrmTestCase.php
+++ b/tests/lib/Doctrine_OrmTestCase.php
@@ -6,8 +6,24 @@
 class Doctrine_OrmTestCase extends Doctrine_TestCase
 {
     protected $_em;
+    protected $_emf;
     
     protected function setUp() {
-        $this->_em = new Doctrine_EntityManager(new Doctrine_Connection_Mock());
+        if (isset($this->sharedFixture['emf'], $this->sharedFixture['em'])) {
+            $this->_emf = $this->sharedFixture['emf'];
+            $this->_em = $this->sharedFixture['em'];
+        } else {
+            $emf = new Doctrine_EntityManagerFactory();
+            $emf->setConfiguration(new Doctrine_Configuration());
+            $emf->setEventManager(new Doctrine_EventManager());
+            $connectionOptions = array(
+                'driver' => 'mock',
+                'user' => 'john',
+                'password' => 'wayne'      
+            );      
+            $em = $emf->createEntityManager($connectionOptions, 'mockEM');
+            $this->_emf = $emf;
+            $this->_em = $em;
+        }
     }
 }
diff --git a/tests/lib/Doctrine_TestUtil.php b/tests/lib/Doctrine_TestUtil.php
index f5a80611c..9bdd47976 100644
--- a/tests/lib/Doctrine_TestUtil.php
+++ b/tests/lib/Doctrine_TestUtil.php
@@ -4,15 +4,28 @@ class Doctrine_TestUtil
 {    
     public static function getConnection()
     {
+        $connFactory = new Doctrine_ConnectionFactory();
+        
         if (isset($GLOBALS['db_type'], $GLOBALS['db_username'], $GLOBALS['db_password'],
                 $GLOBALS['db_host'], $GLOBALS['db_name'])) {
-            $dsn = "{$GLOBALS['db_type']}://{$GLOBALS['db_username']}:{$GLOBALS['db_password']}@{$GLOBALS['db_host']}/{$GLOBALS['db_name']}";
-            return Doctrine_Manager::connection($dsn, 'testconn');
+            $params = array(
+                'driver' => $GLOBALS['db_type'],
+                'user' => $GLOBALS['db_username'],
+                'password' => $GLOBALS['db_password'],
+                'host' => $GLOBALS['db_host'],
+                'database' => $GLOBALS['db_name']
+            );
+            //$dsn = "{$GLOBALS['db_type']}://{$GLOBALS['db_username']}:{$GLOBALS['db_password']}@{$GLOBALS['db_host']}/{$GLOBALS['db_name']}";
+            //return Doctrine_Manager::connection($dsn, 'testconn');
         } else {
-            return Doctrine_Manager::connection(new PDO('sqlite::memory:'), 'testconn');
-        }        
+            $params = array(
+                'pdo' => new PDO('sqlite::memory:')
+            );
+        }
+        
+        return $connFactory->createConnection($params);
     }
-    
+    /*
     public static function autoloadModel($className)
     {
         $modelDir = dirname(__CLASS__) . '/../models/';
@@ -20,5 +33,5 @@ class Doctrine_TestUtil
         if (file_exists($fileName)) {
             require $fileName;
         }
-    }
+    }*/
 }
\ No newline at end of file