Commit a53c2fbd authored by romanb's avatar romanb

[2.0] Code cleanups. Preparations for DDC-193. Fixed DDC-399, type...

[2.0] Code cleanups. Preparations for DDC-193. Fixed DDC-399, type configuration remains global for now but the irritating instance methods on the Configuration have been removed. Use Type::addType et al. Added TODOs for naming standards.
parent ed94a34f
> **NOTE**
> This document does not describe how to upgrade from Doctrine 1.x to Doctrine 2 as this is a more
> complicated process.
# Upgrade from 2.0-ALPHA4 to 2.0 ... # Upgrade from 2.0-ALPHA4 to 2.0-BETA1
## Default Property for Field Mappings removed ## Default Property for Field Mappings
The "default" option for database column defaults has been removed. If desired database column defaults can The "default" option for database column defaults has been removed. If desired, database column defaults can
be implemented by using the @columnDefinition annotation (or the approriate XML and YAML equivalents). be implemented by using the columnDefinition attribute of the @Column annotation (or the approriate XML and YAML equivalents).
Prefer PHP default values, if possible.
Additionally keep in mind that Doctrine's focus in on objects and you can specifiy default values for an Entitiy's
mapped fields inside PHP easily. Upon persist() invocation these values are saved as if they were default values.
## Partial Objects ## Partial Objects
xxx
## XML Mapping Driver ## XML Mapping Driver
The 'inheritance-type' attribute changed to take last bit of ClassMetadata constant names, i.e. The 'inheritance-type' attribute changed to take last bit of ClassMetadata constant names, i.e.
NONE, SINGLE_TABLE, INHERITANCE_TYPE_JOINED NONE, SINGLE_TABLE, INHERITANCE_TYPE_JOINED
## Change of PreUpdate Event Listener ## PreUpdate Event Listeners
Event Listeners listening to the 'preUpdate' event can only affect the primitive values of entity changesets Event Listeners listening to the 'preUpdate' event can only affect the primitive values of entity changesets
by using the API on the `PreUpdateEventArgs` instance passed to the preUpdate listener method. Any changes by using the API on the `PreUpdateEventArgs` instance passed to the preUpdate listener method. Any changes
to the state of the entitys properties won't affect the database UPDATE statement anymore. This gives drastic to the state of the entitys properties won't affect the database UPDATE statement anymore. This gives drastic
performance benefits for the preUpdate event. performance benefits for the preUpdate event.
# Upgrade from 2.0-ALPHA3 to 2.0-ALPHA4
## CLI Controller changes
CLI main object changed its name and namespace. Renamed from Doctrine\ORM\Tools\Cli to Doctrine\Common\Cli\CliController.
Doctrine\Common\Cli\CliController now only deals with namespaces. Ready to go, Core, Dbal and Orm are available and you can subscribe new tasks by retrieving the namespace and including new task. Example:
[php]
$cli->getNamespace('Core')->addTask('my-example', '\MyProject\Tools\Cli\Tasks\MyExampleTask');
## CLI Tasks documentation
Tasks have implemented a new way to build documentation. Although it is still possible to define the help manually by extending the basicHelp and extendedHelp, they are now optional.
With new required method AbstractTask::buildDocumentation, its implementation defines the TaskDocumentation instance (accessible through AbstractTask::getDocumentation()), basicHelp and extendedHelp are now not necessary to be implemented.
## Changes in Method Signatures
* A bunch of Methods on both Doctrine\DBAL\Platforms\AbstractPlatform and Doctrine\DBAL\Schema\AbstractSchemaManager
have changed quite significantly by adopting the new Schema instance objects.
## Renamed Methods
* Doctrine\ORM\AbstractQuery::setExpireResultCache() -> expireResultCache()
* Doctrine\ORM\Query::setExpireQueryCache() -> expireQueryCache()
## SchemaTool Changes
* "doctrine schema-tool --drop" now always drops the complete database instead of
only those tables defined by the current database model. The previous method had
problems when foreign keys of orphaned tables pointed to tables that were schedulded
for deletion.
* Use "doctrine schema-tool --update" to get a save incremental update for your
database schema without deleting any unused tables, sequences or foreign keys.
* Use "doctrine schema-tool --complete-update" to do a full incremental update of
your schema.
# Upgrade from 2.0-ALPHA2 to 2.0-ALPHA3
This section details the changes made to Doctrine 2.0-ALPHA3 to make it easier for you
to upgrade your projects to use this version.
## CLI Changes
The $args variable used in the cli-config.php for configuring the Doctrine CLI has been renamed to $globalArguments.
## Proxy class changes
You are now required to make supply some minimalist configuration with regards to proxy objects. That involves 2 new configuration options. First, the directory where generated proxy classes should be placed needs to be specified. Secondly, you need to configure the namespace used for proxy classes. The following snippet shows an example:
[php]
// step 1: configure directory for proxy classes
// $config instanceof Doctrine\ORM\Configuration
$config->setProxyDir('/path/to/myproject/lib/MyProject/Generated/Proxies');
$config->setProxyNamespace('MyProject\Generated\Proxies');
Note that proxy classes behave exactly like any other classes when it comes to class loading. Therefore you need to make sure the proxy classes can be loaded by some class loader. If you place the generated proxy classes in a namespace and directory under your projects class files, like in the example above, it would be sufficient to register the MyProject namespace on a class loader. Since the proxy classes are contained in that namespace and adhere to the standards for class loading, no additional work is required.
Generating the proxy classes into a namespace within your class library is the recommended setup.
Entities with initialized proxy objects can now be serialized and unserialized properly from within the same application.
For more details refer to the Configuration section of the manual.
## Removed allowPartialObjects configuration option
The allowPartialObjects configuration option together with the `Configuration#getAllowPartialObjects` and `Configuration#setAllowPartialObjects` methods have been removed.
The new behavior is as if the option were set to FALSE all the time, basically disallowing partial objects globally. However, you can still use the `Query::HINT_FORCE_PARTIAL_LOAD` query hint to force a query to return partial objects for optimization purposes.
## Renamed Methods
* Doctrine\ORM\Configuration#getCacheDir() to getProxyDir()
* Doctrine\ORM\Configuration#setCacheDir($dir) to setProxyDir($dir)
# Upgrade from 2.0-ALPHA2 to 2.0-ALPHA3
This section details the changes made to Doctrine 2.0-ALPHA3 to make it easier for you
to upgrade your projects to use this version.
## CLI Changes
The $args variable used in the cli-config.php for configuring the Doctrine CLI has been renamed to $globalArguments.
## Proxy class changes
You are now required to make supply some minimalist configuration with regards to proxy objects. That involves 2 new configuration options. First, the directory where generated proxy classes should be placed needs to be specified. Secondly, you need to configure the namespace used for proxy classes. The following snippet shows an example:
[php]
// step 1: configure directory for proxy classes
// $config instanceof Doctrine\ORM\Configuration
$config->setProxyDir('/path/to/myproject/lib/MyProject/Generated/Proxies');
$config->setProxyNamespace('MyProject\Generated\Proxies');
Note that proxy classes behave exactly like any other classes when it comes to class loading. Therefore you need to make sure the proxy classes can be loaded by some class loader. If you place the generated proxy classes in a namespace and directory under your projects class files, like in the example above, it would be sufficient to register the MyProject namespace on a class loader. Since the proxy classes are contained in that namespace and adhere to the standards for class loading, no additional work is required.
Generating the proxy classes into a namespace within your class library is the recommended setup.
Entities with initialized proxy objects can now be serialized and unserialized properly from within the same application.
For more details refer to the Configuration section of the manual.
## Removed allowPartialObjects configuration option
The allowPartialObjects configuration option together with the `Configuration#getAllowPartialObjects` and `Configuration#setAllowPartialObjects` methods have been removed.
The new behavior is as if the option were set to FALSE all the time, basically disallowing partial objects globally. However, you can still use the `Query::HINT_FORCE_PARTIAL_LOAD` query hint to force a query to return partial objects for optimization purposes.
## Renamed Methods
* Doctrine\ORM\Configuration#getCacheDir() to getProxyDir()
* Doctrine\ORM\Configuration#setCacheDir($dir) to setProxyDir($dir)
\ No newline at end of file
# Upgrade from 2.0-ALPHA3 to 2.0-ALPHA4
## CLI Controller changes
CLI main object changed its name and namespace. Renamed from Doctrine\ORM\Tools\Cli to Doctrine\Common\Cli\CliController.
Doctrine\Common\Cli\CliController now only deals with namespaces. Ready to go, Core, Dbal and Orm are available and you can subscribe new tasks by retrieving the namespace and including new task. Example:
[php]
$cli->getNamespace('Core')->addTask('my-example', '\MyProject\Tools\Cli\Tasks\MyExampleTask');
## CLI Tasks documentation
Tasks have implemented a new way to build documentation. Although it is still possible to define the help manually by extending the basicHelp and extendedHelp, they are now optional.
With new required method AbstractTask::buildDocumentation, its implementation defines the TaskDocumentation instance (accessible through AbstractTask::getDocumentation()), basicHelp and extendedHelp are now not necessary to be implemented.
## Changes in Method Signatures
* A bunch of Methods on both Doctrine\DBAL\Platforms\AbstractPlatform and Doctrine\DBAL\Schema\AbstractSchemaManager
have changed quite significantly by adopting the new Schema instance objects.
## Renamed Methods
* Doctrine\ORM\AbstractQuery::setExpireResultCache() -> expireResultCache()
* Doctrine\ORM\Query::setExpireQueryCache() -> expireQueryCache()
## SchemaTool Changes
* "doctrine schema-tool --drop" now always drops the complete database instead of
only those tables defined by the current database model. The previous method had
problems when foreign keys of orphaned tables pointed to tables that were schedulded
for deletion.
* Use "doctrine schema-tool --update" to get a save incremental update for your
database schema without deleting any unused tables, sequences or foreign keys.
* Use "doctrine schema-tool --complete-update" to do a full incremental update of
your schema.
...@@ -32,6 +32,7 @@ namespace Doctrine\Common\Cache; ...@@ -32,6 +32,7 @@ namespace Doctrine\Common\Cache;
* @author Jonathan Wage <jonwage@gmail.com> * @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com> * @author David Abdemoulaie <dave@hobodave.com>
* @todo Rename: APCCache
*/ */
class ApcCache extends AbstractCache class ApcCache extends AbstractCache
{ {
......
...@@ -46,7 +46,7 @@ class Configuration ...@@ -46,7 +46,7 @@ class Configuration
* @var array * @var array
*/ */
protected $_attributes = array(); protected $_attributes = array();
/** /**
* Creates a new DBAL configuration instance. * Creates a new DBAL configuration instance.
*/ */
...@@ -56,7 +56,7 @@ class Configuration ...@@ -56,7 +56,7 @@ class Configuration
'sqlLogger' => null 'sqlLogger' => null
); );
} }
/** /**
* Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled. * Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled.
* *
...@@ -66,7 +66,7 @@ class Configuration ...@@ -66,7 +66,7 @@ class Configuration
{ {
$this->_attributes['sqlLogger'] = $logger; $this->_attributes['sqlLogger'] = $logger;
} }
/** /**
* Gets the SQL logger that is used. * Gets the SQL logger that is used.
* *
...@@ -76,31 +76,4 @@ class Configuration ...@@ -76,31 +76,4 @@ class Configuration
{ {
return $this->_attributes['sqlLogger']; return $this->_attributes['sqlLogger'];
} }
/**
* Defines new custom types to be supported by Doctrine
*
* @param array $types Key-value map of types to include
* @param boolean $override Optional flag to support only inclusion or also override
*/
public function setCustomTypes(array $types, $override = false)
{
foreach ($types as $name => $typeClassName) {
$method = (Type::hasType($name) && $override ? 'override' : 'add') . 'Type';
Type::$method($name, $typeClassName);
}
}
/**
* Overrides existent types in Doctrine
*
* @param array $types Key-value map of types to override
*/
public function setTypeOverrides(array $overrides)
{
foreach ($override as $name => $typeClassName) {
Type::overrideType($name, $typeClassName);
}
}
} }
\ No newline at end of file
...@@ -66,7 +66,7 @@ class Connection ...@@ -66,7 +66,7 @@ class Connection
*/ */
const FETCH_ASSOC = 2; const FETCH_ASSOC = 2;
const FETCH_BOTH = 4; const FETCH_BOTH = 4;
const FETCH_COLUMN = 7; //const FETCH_COLUMN = 7; Apparently not used.
const FETCH_NUM = 3; const FETCH_NUM = 3;
const ATTR_AUTOCOMMIT = 0; const ATTR_AUTOCOMMIT = 0;
......
...@@ -7,6 +7,7 @@ namespace Doctrine\DBAL\Logging; ...@@ -7,6 +7,7 @@ namespace Doctrine\DBAL\Logging;
* *
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @since 2.0 * @since 2.0
* @todo Rename: EchoSQLLogger
*/ */
class EchoSqlLogger implements SqlLogger class EchoSqlLogger implements SqlLogger
{ {
......
...@@ -7,6 +7,7 @@ namespace Doctrine\DBAL\Logging; ...@@ -7,6 +7,7 @@ namespace Doctrine\DBAL\Logging;
* *
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @since 2.0 * @since 2.0
* @todo Rename: SQLLogger
*/ */
interface SqlLogger interface SqlLogger
{ {
......
...@@ -579,7 +579,7 @@ abstract class AbstractPlatform ...@@ -579,7 +579,7 @@ abstract class AbstractPlatform
*/ */
public function getCreateTableSQL(Table $table, $createFlags=self::CREATE_INDEXES) public function getCreateTableSQL(Table $table, $createFlags=self::CREATE_INDEXES)
{ {
if (!is_int($createFlags)) { if ( ! is_int($createFlags)) {
throw new \InvalidArgumentException("Second argument of AbstractPlatform::getCreateTableSQL() has to be integer."); throw new \InvalidArgumentException("Second argument of AbstractPlatform::getCreateTableSQL() has to be integer.");
} }
......
...@@ -32,6 +32,7 @@ use Doctrine\DBAL\DBALException; ...@@ -32,6 +32,7 @@ use Doctrine\DBAL\DBALException;
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @author Jonathan H. Wage <jonwage@gmail.com> * @author Jonathan H. Wage <jonwage@gmail.com>
* @author Benjamin Eberlei <kontakt@beberlei.de> * @author Benjamin Eberlei <kontakt@beberlei.de>
* @todo Rename: MsSQLPlatform
*/ */
class MsSqlPlatform extends AbstractPlatform class MsSqlPlatform extends AbstractPlatform
{ {
......
...@@ -32,6 +32,7 @@ use Doctrine\DBAL\DBALException, ...@@ -32,6 +32,7 @@ use Doctrine\DBAL\DBALException,
* @since 2.0 * @since 2.0
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @author Benjamin Eberlei <kontakt@beberlei.de> * @author Benjamin Eberlei <kontakt@beberlei.de>
* @todo Rename: MySQLPlatform
*/ */
class MySqlPlatform extends AbstractPlatform class MySqlPlatform extends AbstractPlatform
{ {
......
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
namespace Doctrine\DBAL\Platforms; namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\Schema\TableDiff,
Doctrine\DBAL\Schema\Table;
/** /**
* PostgreSqlPlatform. * PostgreSqlPlatform.
...@@ -30,6 +31,7 @@ use Doctrine\DBAL\Schema\TableDiff; ...@@ -30,6 +31,7 @@ use Doctrine\DBAL\Schema\TableDiff;
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library) * @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @author Benjamin Eberlei <kontakt@beberlei.de> * @author Benjamin Eberlei <kontakt@beberlei.de>
* @todo Rename: PostgreSQLPlatform
*/ */
class PostgreSqlPlatform extends AbstractPlatform class PostgreSqlPlatform extends AbstractPlatform
{ {
...@@ -281,7 +283,7 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -281,7 +283,7 @@ class PostgreSqlPlatform extends AbstractPlatform
{ {
return 'CREATE DATABASE ' . $name; return 'CREATE DATABASE ' . $name;
} }
/** /**
* drop an existing database * drop an existing database
* *
...@@ -293,9 +295,8 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -293,9 +295,8 @@ class PostgreSqlPlatform extends AbstractPlatform
{ {
return 'DROP DATABASE ' . $name; return 'DROP DATABASE ' . $name;
} }
/** /**
* getAdvancedForeignKeyOptions
* Return the FOREIGN KEY query section dealing with non-standard options * Return the FOREIGN KEY query section dealing with non-standard options
* as MATCH, INITIALLY DEFERRED, ON UPDATE, ... * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
* *
......
...@@ -30,6 +30,7 @@ use Doctrine\DBAL\DBALException; ...@@ -30,6 +30,7 @@ use Doctrine\DBAL\DBALException;
* @since 2.0 * @since 2.0
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @author Benjamin Eberlei <kontakt@beberlei.de> * @author Benjamin Eberlei <kontakt@beberlei.de>
* @todo Rename: SQLitePlatform
*/ */
class SqlitePlatform extends AbstractPlatform class SqlitePlatform extends AbstractPlatform
{ {
......
...@@ -21,9 +21,9 @@ ...@@ -21,9 +21,9 @@
namespace Doctrine\DBAL\Schema; namespace Doctrine\DBAL\Schema;
use \Doctrine\DBAL\Types; use Doctrine\DBAL\Types;
use \Doctrine\DBAL\DBALException; use Doctrine\DBAL\DBALException;
use \Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\AbstractPlatform;
/** /**
* Base class for schema managers. Schema managers are used to inspect and/or * Base class for schema managers. Schema managers are used to inspect and/or
......
<?php <?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Types; namespace Doctrine\DBAL\Types;
......
<?php <?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Types; namespace Doctrine\DBAL\Types;
...@@ -33,7 +52,6 @@ abstract class Type ...@@ -33,7 +52,6 @@ abstract class Type
'object' => 'Doctrine\DBAL\Types\ObjectType', 'object' => 'Doctrine\DBAL\Types\ObjectType',
'boolean' => 'Doctrine\DBAL\Types\BooleanType', 'boolean' => 'Doctrine\DBAL\Types\BooleanType',
'integer' => 'Doctrine\DBAL\Types\IntegerType', 'integer' => 'Doctrine\DBAL\Types\IntegerType',
'int' => 'Doctrine\DBAL\Types\IntegerType',
'smallint' => 'Doctrine\DBAL\Types\SmallIntType', 'smallint' => 'Doctrine\DBAL\Types\SmallIntType',
'bigint' => 'Doctrine\DBAL\Types\BigIntType', 'bigint' => 'Doctrine\DBAL\Types\BigIntType',
'string' => 'Doctrine\DBAL\Types\StringType', 'string' => 'Doctrine\DBAL\Types\StringType',
...@@ -41,12 +59,11 @@ abstract class Type ...@@ -41,12 +59,11 @@ abstract class Type
'datetime' => 'Doctrine\DBAL\Types\DateTimeType', 'datetime' => 'Doctrine\DBAL\Types\DateTimeType',
'date' => 'Doctrine\DBAL\Types\DateType', 'date' => 'Doctrine\DBAL\Types\DateType',
'time' => 'Doctrine\DBAL\Types\TimeType', 'time' => 'Doctrine\DBAL\Types\TimeType',
'decimal' => 'Doctrine\DBAL\Types\DecimalType', 'decimal' => 'Doctrine\DBAL\Types\DecimalType'
'double' => 'Doctrine\DBAL\Types\DoubleType'
); );
/* Prevent instantiation and force use of the factory method. */ /* Prevent instantiation and force use of the factory method. */
private function __construct() {} final private function __construct() {}
/** /**
* Converts a value from its PHP representation to its database representation * Converts a value from its PHP representation to its database representation
...@@ -125,7 +142,6 @@ abstract class Type ...@@ -125,7 +142,6 @@ abstract class Type
if ( ! isset(self::$_typesMap[$name])) { if ( ! isset(self::$_typesMap[$name])) {
throw DBALException::unknownColumnType($name); throw DBALException::unknownColumnType($name);
} }
self::$_typeObjects[$name] = new self::$_typesMap[$name](); self::$_typeObjects[$name] = new self::$_typesMap[$name]();
} }
...@@ -136,8 +152,7 @@ abstract class Type ...@@ -136,8 +152,7 @@ abstract class Type
* Adds a custom type to the type map. * Adds a custom type to the type map.
* *
* @static * @static
* @param string $name Name of the type. This should correspond to what * @param string $name Name of the type. This should correspond to what getName() returns.
* getName() returns.
* @param string $className The class name of the custom type. * @param string $className The class name of the custom type.
* @throws DBALException * @throws DBALException
*/ */
......
...@@ -472,6 +472,9 @@ abstract class AbstractQuery ...@@ -472,6 +472,9 @@ abstract class AbstractQuery
{ {
// If there are still pending insertions in the UnitOfWork we need to flush // If there are still pending insertions in the UnitOfWork we need to flush
// in order to guarantee a correct result. // in order to guarantee a correct result.
//TODO: Think this over. Its tricky. Not doing this can lead to strange results
// potentially, but doing it could result in endless loops when querying during
// a flush, i.e. inside an event listener.
if ($this->_em->getUnitOfWork()->hasPendingInsertions()) { if ($this->_em->getUnitOfWork()->hasPendingInsertions()) {
$this->_em->flush(); $this->_em->flush();
} }
......
...@@ -38,7 +38,6 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -38,7 +38,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
public function __construct() public function __construct()
{ {
parent::__construct(); parent::__construct();
$this->_attributes = array_merge($this->_attributes, array( $this->_attributes = array_merge($this->_attributes, array(
'resultCacheImpl' => null, 'resultCacheImpl' => null,
'queryCacheImpl' => null, 'queryCacheImpl' => null,
...@@ -46,11 +45,8 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -46,11 +45,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
'metadataDriverImpl' => null, 'metadataDriverImpl' => null,
'proxyDir' => null, 'proxyDir' => null,
'useCExtension' => false, 'useCExtension' => false,
'namedQueries' => array(),
'namedNativeQueries' => array(),
'autoGenerateProxyClasses' => true, 'autoGenerateProxyClasses' => true,
'proxyNamespace' => null, 'proxyNamespace' => null
'entityNamespaces' => array()
)); ));
} }
...@@ -96,11 +92,21 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -96,11 +92,21 @@ class Configuration extends \Doctrine\DBAL\Configuration
$this->_attributes['autoGenerateProxyClasses'] = $bool; $this->_attributes['autoGenerateProxyClasses'] = $bool;
} }
/**
* Gets the namespace where proxy classes reside.
*
* @return string
*/
public function getProxyNamespace() public function getProxyNamespace()
{ {
return $this->_attributes['proxyNamespace']; return $this->_attributes['proxyNamespace'];
} }
/**
* Sets the namespace where proxy classes reside.
*
* @param string $ns
*/
public function setProxyNamespace($ns) public function setProxyNamespace($ns)
{ {
$this->_attributes['proxyNamespace'] = $ns; $this->_attributes['proxyNamespace'] = $ns;
...@@ -119,7 +125,7 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -119,7 +125,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
} }
/** /**
* Add a namespace alias for entities. * Adds a namespace under a certain alias.
* *
* @param string $alias * @param string $alias
* @param string $namespace * @param string $namespace
...@@ -130,7 +136,7 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -130,7 +136,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
} }
/** /**
* Get the namespace of a given entity namespace * Resolves a registered namespace alias to the full namespace.
* *
* @param string $entityNamespaceAlias * @param string $entityNamespaceAlias
* @return string * @return string
...@@ -138,11 +144,11 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -138,11 +144,11 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/ */
public function getEntityNamespace($entityNamespaceAlias) public function getEntityNamespace($entityNamespaceAlias)
{ {
if (isset($this->_attributes['entityNamespaces'][$entityNamespaceAlias])) { if ( ! isset($this->_attributes['entityNamespaces'][$entityNamespaceAlias])) {
return trim($this->_attributes['entityNamespaces'][$entityNamespaceAlias], '\\'); throw ORMException::unknownEntityNamespace($entityNamespaceAlias);
} }
throw ORMException::unknownEntityNamespace($entityNamespaceAlias); return trim($this->_attributes['entityNamespaces'][$entityNamespaceAlias], '\\');
} }
/** /**
...@@ -153,7 +159,7 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -153,7 +159,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/ */
public function setEntityNamespaces(array $entityNamespaces) public function setEntityNamespaces(array $entityNamespaces)
{ {
$this->_attributes['entityNamespaces'] = $entityNamespaces; $this->_attributes['entityNamespaces'] = $entityNamespaces;
} }
/** /**
...@@ -273,6 +279,9 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -273,6 +279,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/ */
public function getNamedQuery($name) public function getNamedQuery($name)
{ {
if ( ! isset($this->_attributes['namedQueries'][$name])) {
throw ORMException::namedQueryNotFound($name);
}
return $this->_attributes['namedQueries'][$name]; return $this->_attributes['namedQueries'][$name];
} }
...@@ -297,6 +306,9 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -297,6 +306,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/ */
public function getNamedNativeQuery($name) public function getNamedNativeQuery($name)
{ {
if ( ! isset($this->_attributes['namedNativeQueries'][$name])) {
throw ORMException::namedNativeQueryNotFound($name);
}
return $this->_attributes['namedNativeQueries'][$name]; return $this->_attributes['namedNativeQueries'][$name];
} }
...@@ -319,4 +331,79 @@ class Configuration extends \Doctrine\DBAL\Configuration ...@@ -319,4 +331,79 @@ class Configuration extends \Doctrine\DBAL\Configuration
throw ORMException::proxyClassesAlwaysRegenerating(); throw ORMException::proxyClassesAlwaysRegenerating();
} }
} }
/**
* Registers a custom DQL function that produces a string value.
* Such a function can then be used in any DQL statement in any place where string
* functions are allowed.
*
* @param string $name
* @param string $className
*/
public function addCustomStringFunction($name, $className)
{
$this->_attributes['customStringFunctions'][strtolower($name)] = $className;
}
/**
* Gets the implementation class name of a registered custom string DQL function.
*
* @param string $name
* @return string
*/
public function getCustomStringFunction($name)
{
return isset($this->_attributes['customStringFunctions'][$name]) ?
$this->_attributes['customStringFunctions'][$name] : null;
}
/**
* Registers a custom DQL function that produces a numeric value.
* Such a function can then be used in any DQL statement in any place where numeric
* functions are allowed.
*
* @param string $name
* @param string $className
*/
public function addCustomNumericFunction($name, $className)
{
$this->_attributes['customNumericFunctions'][strtolower($name)] = $className;
}
/**
* Gets the implementation class name of a registered custom numeric DQL function.
*
* @param string $name
* @return string
*/
public function getCustomNumericFunction($name)
{
return isset($this->_attributes['customNumericFunctions'][$name]) ?
$this->_attributes['customNumericFunctions'][$name] : null;
}
/**
* Registers a custom DQL function that produces a date/time value.
* Such a function can then be used in any DQL statement in any place where date/time
* functions are allowed.
*
* @param string $name
* @param string $className
*/
public function addCustomDatetimeFunction($name, $className)
{
$this->_attributes['customDatetimeFunctions'][strtolower($name)] = $className;
}
/**
* Gets the implementation class name of a registered custom date/time DQL function.
*
* @param string $name
* @return string
*/
public function getCustomDatetimeFunction($name)
{
return isset($this->_attributes['customDatetimeFunctions'][$name]) ?
$this->_attributes['customDatetimeFunctions'][$name] : null;
}
} }
\ No newline at end of file
...@@ -353,6 +353,9 @@ class EntityManager ...@@ -353,6 +353,9 @@ class EntityManager
* *
* The entity will be entered into the database at or before transaction * The entity will be entered into the database at or before transaction
* commit or as a result of the flush operation. * commit or as a result of the flush operation.
*
* NOTE: The persist operation always considers entities that are not yet known to
* this EntityManager as NEW. Do not pass detached entities to the persist operation.
* *
* @param object $object The instance to make managed and persistent. * @param object $object The instance to make managed and persistent.
*/ */
...@@ -456,7 +459,7 @@ class EntityManager ...@@ -456,7 +459,7 @@ class EntityManager
} }
$metadata = $this->getClassMetadata($entityName); $metadata = $this->getClassMetadata($entityName);
$customRepositoryClassName = $metadata->getCustomRepositoryClass(); $customRepositoryClassName = $metadata->customRepositoryClassName;
if ($customRepositoryClassName !== null) { if ($customRepositoryClassName !== null) {
$repository = new $customRepositoryClassName($this, $metadata); $repository = new $customRepositoryClassName($this, $metadata);
......
...@@ -57,7 +57,7 @@ class EntityRepository ...@@ -57,7 +57,7 @@ class EntityRepository
* @param EntityManager $em The EntityManager to use. * @param EntityManager $em The EntityManager to use.
* @param ClassMetadata $classMetadata The class descriptor. * @param ClassMetadata $classMetadata The class descriptor.
*/ */
public function __construct($em, \Doctrine\ORM\Mapping\ClassMetadata $class) public function __construct($em, Mapping\ClassMetadata $class)
{ {
$this->_entityName = $class->name; $this->_entityName = $class->name;
$this->_em = $em; $this->_em = $em;
......
...@@ -254,7 +254,7 @@ abstract class AbstractHydrator ...@@ -254,7 +254,7 @@ abstract class AbstractHydrator
$fieldName = $this->_rsm->fieldMappings[$key]; $fieldName = $this->_rsm->fieldMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]); $classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
$cache[$key]['fieldName'] = $fieldName; $cache[$key]['fieldName'] = $fieldName;
$cache[$key]['type'] = Type::getType($classMetadata->getTypeOfField($fieldName)); $cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key]; $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
} else { } else {
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns). // Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
......
...@@ -83,8 +83,8 @@ class ObjectHydrator extends AbstractHydrator ...@@ -83,8 +83,8 @@ class ObjectHydrator extends AbstractHydrator
} }
if ( ! $assoc->isManyToMany()) { if ( ! $assoc->isManyToMany()) {
// Mark any non-collection opposite sides as fetched, too. // Mark any non-collection opposite sides as fetched, too.
if ($assoc->mappedByFieldName) { if ($assoc->mappedBy) {
$this->_hints['fetched'][$className][$assoc->mappedByFieldName] = true; $this->_hints['fetched'][$className][$assoc->mappedBy] = true;
} else { } else {
if (isset($class->inverseMappings[$sourceClassName][$assoc->sourceFieldName])) { if (isset($class->inverseMappings[$sourceClassName][$assoc->sourceFieldName])) {
$inverseAssoc = $class->inverseMappings[$sourceClassName][$assoc->sourceFieldName]; $inverseAssoc = $class->inverseMappings[$sourceClassName][$assoc->sourceFieldName];
...@@ -353,14 +353,14 @@ class ObjectHydrator extends AbstractHydrator ...@@ -353,14 +353,14 @@ class ObjectHydrator extends AbstractHydrator
$targetClass->reflFields[$inverseAssoc->sourceFieldName]->setValue($element, $parentObject); $targetClass->reflFields[$inverseAssoc->sourceFieldName]->setValue($element, $parentObject);
$this->_uow->setOriginalEntityProperty(spl_object_hash($element), $inverseAssoc->sourceFieldName, $parentObject); $this->_uow->setOriginalEntityProperty(spl_object_hash($element), $inverseAssoc->sourceFieldName, $parentObject);
} }
} else if ($parentClass === $targetClass && $relation->mappedByFieldName) { } else if ($parentClass === $targetClass && $relation->mappedBy) {
// Special case: bi-directional self-referencing one-one on the same class // Special case: bi-directional self-referencing one-one on the same class
$targetClass->reflFields[$relationField]->setValue($element, $parentObject); $targetClass->reflFields[$relationField]->setValue($element, $parentObject);
} }
} else { } else {
// For sure bidirectional, as there is no inverse side in unidirectional mappings // For sure bidirectional, as there is no inverse side in unidirectional mappings
$targetClass->reflFields[$relation->mappedByFieldName]->setValue($element, $parentObject); $targetClass->reflFields[$relation->mappedBy]->setValue($element, $parentObject);
$this->_uow->setOriginalEntityProperty(spl_object_hash($element), $relation->mappedByFieldName, $parentObject); $this->_uow->setOriginalEntityProperty(spl_object_hash($element), $relation->mappedBy, $parentObject);
} }
// Update result pointer // Update result pointer
$this->_resultPointers[$dqlAlias] = $element; $this->_resultPointers[$dqlAlias] = $element;
......
...@@ -50,69 +50,110 @@ abstract class AssociationMapping ...@@ -50,69 +50,110 @@ abstract class AssociationMapping
* @var integer * @var integer
*/ */
const FETCH_EAGER = 3; const FETCH_EAGER = 3;
/**
* READ-ONLY: Whether the association cascades delete() operations from the source entity
* to the target entity/entities.
*
* @var boolean
*/
public $isCascadeRemove; public $isCascadeRemove;
/**
* READ-ONLY: Whether the association cascades save() operations from the source entity
* to the target entity/entities.
*
* @var boolean
*/
public $isCascadePersist; public $isCascadePersist;
/**
* READ-ONLY: Whether the association cascades refresh() operations from the source entity
* to the target entity/entities.
*
* @var boolean
*/
public $isCascadeRefresh; public $isCascadeRefresh;
/**
* READ-ONLY: Whether the association cascades merge() operations from the source entity
* to the target entity/entities.
*
* @var boolean
*/
public $isCascadeMerge; public $isCascadeMerge;
/**
* READ-ONLY: Whether the association cascades detach() operations from the source entity
* to the target entity/entities.
*
* @var boolean
*/
public $isCascadeDetach; public $isCascadeDetach;
/** /**
* The fetch mode used for the association. * READ-ONLY: The fetch mode used for the association.
* *
* @var integer * @var integer
*/ */
public $fetchMode; public $fetchMode;
/** /**
* Flag that indicates whether the class that defines this mapping is * READ-ONLY: Flag that indicates whether the class that defines this mapping is
* the owning side of the association. * the owning side of the association.
* *
* @var boolean * @var boolean
*/ */
public $isOwningSide = true; public $isOwningSide = true;
/** /**
* The name of the source Entity (the Entity that defines this mapping). * READ-ONLY: The name of the source Entity (the Entity that defines this mapping).
* *
* @var string * @var string
*/ */
public $sourceEntityName; public $sourceEntityName;
/** /**
* The name of the target Entity (the Enitity that is the target of the * READ-ONLY: The name of the target Entity (the Enitity that is the target of the
* association). * association).
* *
* @var string * @var string
*/ */
public $targetEntityName; public $targetEntityName;
/** /**
* Identifies the field on the source class (the class this AssociationMapping * READ-ONLY: Identifies the field on the source class (the class this AssociationMapping
* belongs to) that represents the association and stores the reference to the * belongs to) that represents the association and stores the reference to the
* other entity/entities. * other entity/entities.
* *
* @var string * @var string
*/ */
public $sourceFieldName; public $sourceFieldName;
/** /**
* Identifies the field on the owning side that controls the mapping for the * READ-ONLY: Identifies the field on the owning side of a bidirectional association that
* association. This is only set on the inverse side of an association. * controls the mapping for the association. This is only set on the inverse side
* of an association.
* *
* @var string * @var string
*/ */
public $mappedByFieldName; public $mappedBy;
/** /**
* The join table definition, if any. * READ-ONLY: Identifies the field on the inverse side of a bidirectional association.
* This is only set on the owning side of an association.
*
* @var string
*/
public $inversedBy;
/**
* READ-ONLY: The join table definition, if any.
* *
* @var array * @var array
*/ */
public $joinTable = array(); public $joinTable = array();
//protected $_joinTableInsertSql;
/** /**
* Initializes a new instance of a class derived from AssociationMapping. * Initializes a new instance of a class derived from AssociationMapping.
* *
...@@ -124,7 +165,7 @@ abstract class AssociationMapping ...@@ -124,7 +165,7 @@ abstract class AssociationMapping
$this->_validateAndCompleteMapping($mapping); $this->_validateAndCompleteMapping($mapping);
} }
} }
/** /**
* Validates & completes the mapping. Mapping defaults are applied here. * Validates & completes the mapping. Mapping defaults are applied here.
* *
...@@ -159,9 +200,12 @@ abstract class AssociationMapping ...@@ -159,9 +200,12 @@ abstract class AssociationMapping
} }
$this->joinTable = $mapping['joinTable']; $this->joinTable = $mapping['joinTable'];
} }
if (isset($mapping['inversedBy'])) {
$this->inversedBy = $mapping['inversedBy'];
}
} else { } else {
$this->isOwningSide = false; $this->isOwningSide = false;
$this->mappedByFieldName = $mapping['mappedBy']; $this->mappedBy = $mapping['mappedBy'];
} }
// Optional attributes for both sides // Optional attributes for both sides
...@@ -184,62 +228,7 @@ abstract class AssociationMapping ...@@ -184,62 +228,7 @@ abstract class AssociationMapping
$this->isCascadeMerge = in_array('merge', $cascades); $this->isCascadeMerge = in_array('merge', $cascades);
$this->isCascadeDetach = in_array('detach', $cascades); $this->isCascadeDetach = in_array('detach', $cascades);
} }
/**
* Whether the association cascades delete() operations from the source entity
* to the target entity/entities.
*
* @return boolean
*/
public function isCascadeRemove()
{
return $this->isCascadeRemove;
}
/**
* Whether the association cascades save() operations from the source entity
* to the target entity/entities.
*
* @return boolean
*/
public function isCascadePersist()
{
return $this->isCascadePersist;
}
/**
* Whether the association cascades refresh() operations from the source entity
* to the target entity/entities.
*
* @return boolean
*/
public function isCascadeRefresh()
{
return $this->isCascadeRefresh;
}
/**
* Whether the association cascades merge() operations from the source entity
* to the target entity/entities.
*
* @return boolean
*/
public function isCascadeMerge()
{
return $this->isCascadeMerge;
}
/**
* Whether the association cascades detach() operations from the source entity
* to the target entity/entities.
*
* @return boolean
*/
public function isCascadeDetach()
{
return $this->isCascadeDetach;
}
/** /**
* Whether the target entity/entities of the association are eagerly fetched. * Whether the target entity/entities of the association are eagerly fetched.
* *
...@@ -249,7 +238,7 @@ abstract class AssociationMapping ...@@ -249,7 +238,7 @@ abstract class AssociationMapping
{ {
return $this->fetchMode == self::FETCH_EAGER; return $this->fetchMode == self::FETCH_EAGER;
} }
/** /**
* Whether the target entity/entities of the association are lazily fetched. * Whether the target entity/entities of the association are lazily fetched.
* *
...@@ -259,17 +248,7 @@ abstract class AssociationMapping ...@@ -259,17 +248,7 @@ abstract class AssociationMapping
{ {
return $this->fetchMode == self::FETCH_LAZY; return $this->fetchMode == self::FETCH_LAZY;
} }
/**
* Whether the source entity of this association represents the owning side.
*
* @return boolean
*/
public function isOwningSide()
{
return $this->isOwningSide;
}
/** /**
* Whether the source entity of this association represents the inverse side. * Whether the source entity of this association represents the inverse side.
* *
...@@ -279,58 +258,6 @@ abstract class AssociationMapping ...@@ -279,58 +258,6 @@ abstract class AssociationMapping
{ {
return ! $this->isOwningSide; return ! $this->isOwningSide;
} }
/**
* Gets the name of the source entity class.
*
* @return string
*/
public function getSourceEntityName()
{
return $this->sourceEntityName;
}
/**
* Gets the name of the target entity class.
*
* @return string
*/
public function getTargetEntityName()
{
return $this->targetEntityName;
}
/**
* Gets the join table definition, if any.
*
* @return array
*/
public function getJoinTable()
{
return $this->joinTable;
}
/**
* Get the name of the field the association is mapped into.
*
* @return string
*/
public function getSourceFieldName()
{
return $this->sourceFieldName;
}
/**
* Gets the field name of the owning side in a bi-directional association.
* This is only set on the inverse side. When invoked on the owning side,
* NULL is returned.
*
* @return string
*/
public function getMappedByFieldName()
{
return $this->mappedByFieldName;
}
/** /**
* Whether the association is a one-to-one association. * Whether the association is a one-to-one association.
...@@ -397,7 +324,7 @@ abstract class AssociationMapping ...@@ -397,7 +324,7 @@ abstract class AssociationMapping
/** /**
* *
* @param $platform * @param $platform
* @return unknown_type * @return string
*/ */
public function getQuotedJoinTableName($platform) public function getQuotedJoinTableName($platform)
{ {
......
...@@ -207,6 +207,17 @@ class ClassMetadata extends ClassMetadataInfo ...@@ -207,6 +207,17 @@ class ClassMetadata extends ClassMetadataInfo
$this->reflFields[$field]->setValue($entity, $value); $this->reflFields[$field]->setValue($entity, $value);
} }
/**
* Gets the specified field's value off the given entity.
*
* @param object $entity
* @param string $field
*/
public function getFieldValue($entity, $field)
{
return $this->reflFields[$field]->getValue($entity);
}
/** /**
* Sets the field mapped to the specified column to the specified value on the given entity. * Sets the field mapped to the specified column to the specified value on the given entity.
* *
...@@ -235,21 +246,7 @@ class ClassMetadata extends ClassMetadataInfo ...@@ -235,21 +246,7 @@ class ClassMetadata extends ClassMetadataInfo
$refProp->setAccessible(true); $refProp->setAccessible(true);
$this->reflFields[$sourceFieldName] = $refProp; $this->reflFields[$sourceFieldName] = $refProp;
} }
/**
* Dispatches the lifecycle event of the given entity to the registered
* lifecycle callbacks and lifecycle listeners.
*
* @param string $event The lifecycle event.
* @param Entity $entity The Entity on which the event occured.
*/
public function invokeLifecycleCallbacks($lifecycleEvent, $entity)
{
foreach ($this->lifecycleCallbacks[$lifecycleEvent] as $callback) {
$entity->$callback();
}
}
/** /**
* Gets the (possibly quoted) column name of a mapped field for safe use * Gets the (possibly quoted) column name of a mapped field for safe use
* in an SQL statement. * in an SQL statement.
...@@ -316,7 +313,7 @@ class ClassMetadata extends ClassMetadataInfo ...@@ -316,7 +313,7 @@ class ClassMetadata extends ClassMetadataInfo
'idGenerator', //TODO: Does not really need to be serialized. Could be moved to runtime. 'idGenerator', //TODO: Does not really need to be serialized. Could be moved to runtime.
'inheritanceType', 'inheritanceType',
'inheritedAssociationFields', 'inheritedAssociationFields',
'inverseMappings', //TODO: Remove! 'inverseMappings', //TODO: Remove! DDC-193
'isIdentifierComposite', 'isIdentifierComposite',
'isMappedSuperclass', 'isMappedSuperclass',
'isVersioned', 'isVersioned',
......
...@@ -143,10 +143,8 @@ class ClassMetadataFactory ...@@ -143,10 +143,8 @@ class ClassMetadataFactory
} }
} }
$cacheKey = "$realClassName\$CLASSMETADATA";
if ($this->_cacheDriver) { if ($this->_cacheDriver) {
if (($cached = $this->_cacheDriver->fetch($cacheKey)) !== false) { if (($cached = $this->_cacheDriver->fetch("$realClassName\$CLASSMETADATA")) !== false) {
$this->_loadedMetadata[$realClassName] = $cached; $this->_loadedMetadata[$realClassName] = $cached;
} else { } else {
foreach ($this->_loadMetadata($realClassName) as $loadedClassName) { foreach ($this->_loadMetadata($realClassName) as $loadedClassName) {
...@@ -206,8 +204,9 @@ class ClassMetadataFactory ...@@ -206,8 +204,9 @@ class ClassMetadataFactory
} }
$loaded = array(); $loaded = array();
// Collect parent classes, ignoring transient (not-mapped) classes. // Collect parent classes, ignoring transient (not-mapped) classes.
//TODO: Evaluate whether we can use class_parents() here.
$parentClass = $name; $parentClass = $name;
$parentClasses = array(); $parentClasses = array();
while ($parentClass = get_parent_class($parentClass)) { while ($parentClass = get_parent_class($parentClass)) {
...@@ -258,15 +257,15 @@ class ClassMetadataFactory ...@@ -258,15 +257,15 @@ class ClassMetadataFactory
} }
if ($parent && ! $parent->isMappedSuperclass) { if ($parent && ! $parent->isMappedSuperclass) {
if ($parent->isIdGeneratorSequence()) { if ($parent->isIdGeneratorSequence()) {
$class->setSequenceGeneratorDefinition($parent->getSequenceGeneratorDefinition()); $class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
} else if ($parent->isIdGeneratorTable()) { } else if ($parent->isIdGeneratorTable()) {
$class->getTableGeneratorDefinition($parent->getTableGeneratorDefinition()); $class->getTableGeneratorDefinition($parent->tableGeneratorDefinition);
} }
if ($generatorType = $parent->generatorType) { if ($generatorType = $parent->generatorType) {
$class->setIdGeneratorType($generatorType); $class->setIdGeneratorType($generatorType);
} }
if ($idGenerator = $parent->getIdGenerator()) { if ($parent->idGenerator) {
$class->setIdGenerator($idGenerator); $class->setIdGenerator($parent->idGenerator);
} }
} else { } else {
$this->_completeIdGeneratorMapping($class); $this->_completeIdGeneratorMapping($class);
...@@ -374,7 +373,7 @@ class ClassMetadataFactory ...@@ -374,7 +373,7 @@ class ClassMetadataFactory
break; break;
case ClassMetadata::GENERATOR_TYPE_SEQUENCE: case ClassMetadata::GENERATOR_TYPE_SEQUENCE:
// If there is no sequence definition yet, create a default definition // If there is no sequence definition yet, create a default definition
$definition = $class->getSequenceGeneratorDefinition(); $definition = $class->sequenceGeneratorDefinition;
if ( ! $definition) { if ( ! $definition) {
$sequenceName = $class->getTableName() . '_' . $class->getSingleIdentifierColumnName() . '_seq'; $sequenceName = $class->getTableName() . '_' . $class->getSingleIdentifierColumnName() . '_seq';
$definition['sequenceName'] = $this->_targetPlatform->fixSchemaElementName($sequenceName); $definition['sequenceName'] = $this->_targetPlatform->fixSchemaElementName($sequenceName);
......
...@@ -114,12 +114,12 @@ class ClassMetadataInfo ...@@ -114,12 +114,12 @@ class ClassMetadataInfo
const CHANGETRACKING_NOTIFY = 3; const CHANGETRACKING_NOTIFY = 3;
/** /**
* The name of the entity class. * READ-ONLY: The name of the entity class.
*/ */
public $name; public $name;
/** /**
* The namespace the entity class is contained in. * READ-ONLY: The namespace the entity class is contained in.
* *
* @var string * @var string
* @todo Not really needed. Usage could be localized. * @todo Not really needed. Usage could be localized.
...@@ -127,7 +127,7 @@ class ClassMetadataInfo ...@@ -127,7 +127,7 @@ class ClassMetadataInfo
public $namespace; public $namespace;
/** /**
* The name of the entity class that is at the root of the entity inheritance * READ-ONLY: The name of the entity class that is at the root of the entity inheritance
* hierarchy. If the entity is not part of an inheritance hierarchy this is the same * hierarchy. If the entity is not part of an inheritance hierarchy this is the same
* as $_entityName. * as $_entityName.
* *
...@@ -144,28 +144,28 @@ class ClassMetadataInfo ...@@ -144,28 +144,28 @@ class ClassMetadataInfo
public $customRepositoryClassName; public $customRepositoryClassName;
/** /**
* Whether this class describes the mapping of a mapped superclass. * READ-ONLY: Whether this class describes the mapping of a mapped superclass.
* *
* @var boolean * @var boolean
*/ */
public $isMappedSuperclass = false; public $isMappedSuperclass = false;
/** /**
* The names of the parent classes (ancestors). * READ-ONLY: The names of the parent classes (ancestors).
* *
* @var array * @var array
*/ */
public $parentClasses = array(); public $parentClasses = array();
/** /**
* The names of all subclasses. * READ-ONLY: The names of all subclasses.
* *
* @var array * @var array
*/ */
public $subClasses = array(); public $subClasses = array();
/** /**
* The field names of all fields that are part of the identifier/primary key * READ-ONLY: The field names of all fields that are part of the identifier/primary key
* of the mapped entity class. * of the mapped entity class.
* *
* @var array * @var array
...@@ -173,21 +173,21 @@ class ClassMetadataInfo ...@@ -173,21 +173,21 @@ class ClassMetadataInfo
public $identifier = array(); public $identifier = array();
/** /**
* The inheritance mapping type used by the class. * READ-ONLY: The inheritance mapping type used by the class.
* *
* @var integer * @var integer
*/ */
public $inheritanceType = self::INHERITANCE_TYPE_NONE; public $inheritanceType = self::INHERITANCE_TYPE_NONE;
/** /**
* The Id generator type used by the class. * READ-ONLY: The Id generator type used by the class.
* *
* @var string * @var string
*/ */
public $generatorType = self::GENERATOR_TYPE_NONE; public $generatorType = self::GENERATOR_TYPE_NONE;
/** /**
* The field mappings of the class. * READ-ONLY: The field mappings of the class.
* Keys are field names and values are mapping definitions. * Keys are field names and values are mapping definitions.
* *
* The mapping definition array has the following values: * The mapping definition array has the following values:
...@@ -236,7 +236,7 @@ class ClassMetadataInfo ...@@ -236,7 +236,7 @@ class ClassMetadataInfo
public $fieldMappings = array(); public $fieldMappings = array();
/** /**
* An array of field names. Used to look up field names from column names. * READ-ONLY: An array of field names. Used to look up field names from column names.
* Keys are column names and values are field names. * Keys are column names and values are field names.
* This is the reverse lookup map of $_columnNames. * This is the reverse lookup map of $_columnNames.
* *
...@@ -245,7 +245,7 @@ class ClassMetadataInfo ...@@ -245,7 +245,7 @@ class ClassMetadataInfo
public $fieldNames = array(); public $fieldNames = array();
/** /**
* A map of field names to column names. Keys are field names and values column names. * READ-ONLY: A map of field names to column names. Keys are field names and values column names.
* Used to look up column names from field names. * Used to look up column names from field names.
* This is the reverse lookup map of $_fieldNames. * This is the reverse lookup map of $_fieldNames.
* *
...@@ -255,7 +255,7 @@ class ClassMetadataInfo ...@@ -255,7 +255,7 @@ class ClassMetadataInfo
public $columnNames = array(); public $columnNames = array();
/** /**
* The discriminator value of this class. * READ-ONLY: The discriminator value of this class.
* *
* <b>This does only apply to the JOINED and SINGLE_TABLE inheritance mapping strategies * <b>This does only apply to the JOINED and SINGLE_TABLE inheritance mapping strategies
* where a discriminator column is used.</b> * where a discriminator column is used.</b>
...@@ -266,7 +266,7 @@ class ClassMetadataInfo ...@@ -266,7 +266,7 @@ class ClassMetadataInfo
public $discriminatorValue; public $discriminatorValue;
/** /**
* The discriminator map of all mapped classes in the hierarchy. * READ-ONLY: The discriminator map of all mapped classes in the hierarchy.
* *
* <b>This does only apply to the JOINED and SINGLE_TABLE inheritance mapping strategies * <b>This does only apply to the JOINED and SINGLE_TABLE inheritance mapping strategies
* where a discriminator column is used.</b> * where a discriminator column is used.</b>
...@@ -277,7 +277,7 @@ class ClassMetadataInfo ...@@ -277,7 +277,7 @@ class ClassMetadataInfo
public $discriminatorMap = array(); public $discriminatorMap = array();
/** /**
* The definition of the descriminator column used in JOINED and SINGLE_TABLE * READ-ONLY: The definition of the descriminator column used in JOINED and SINGLE_TABLE
* inheritance mappings. * inheritance mappings.
* *
* @var array * @var array
...@@ -285,7 +285,7 @@ class ClassMetadataInfo ...@@ -285,7 +285,7 @@ class ClassMetadataInfo
public $discriminatorColumn; public $discriminatorColumn;
/** /**
* The primary table definition. The definition is an array with the * READ-ONLY: The primary table definition. The definition is an array with the
* following entries: * following entries:
* *
* name => <tableName> * name => <tableName>
...@@ -298,21 +298,21 @@ class ClassMetadataInfo ...@@ -298,21 +298,21 @@ class ClassMetadataInfo
public $primaryTable; public $primaryTable;
/** /**
* The registered lifecycle callbacks for entities of this class. * READ-ONLY: The registered lifecycle callbacks for entities of this class.
* *
* @var array * @var array
*/ */
public $lifecycleCallbacks = array(); public $lifecycleCallbacks = array();
/** /**
* The association mappings. All mappings, inverse and owning side. * READ-ONLY: The association mappings. All mappings, inverse and owning side.
* *
* @var array * @var array
*/ */
public $associationMappings = array(); public $associationMappings = array();
/** /**
* List of inverse association mappings, indexed by mappedBy field name. * READ-ONLY: List of inverse association mappings, indexed by mappedBy field name.
* *
* @var array * @var array
* @todo Remove! See http://www.doctrine-project.org/jira/browse/DDC-193 * @todo Remove! See http://www.doctrine-project.org/jira/browse/DDC-193
...@@ -320,29 +320,38 @@ class ClassMetadataInfo ...@@ -320,29 +320,38 @@ class ClassMetadataInfo
public $inverseMappings = array(); public $inverseMappings = array();
/** /**
* Flag indicating whether the identifier/primary key of the class is composite. * READ-ONLY: Flag indicating whether the identifier/primary key of the class is composite.
* *
* @var boolean * @var boolean
*/ */
public $isIdentifierComposite = false; public $isIdentifierComposite = false;
/** /**
* The ID generator used for generating IDs for this class. * READ-ONLY: The ID generator used for generating IDs for this class.
* *
* @var AbstractIdGenerator * @var AbstractIdGenerator
*/ */
public $idGenerator; public $idGenerator;
/** /**
* The definition of the sequence generator of this class. Only used for the * READ-ONLY: The definition of the sequence generator of this class. Only used for the
* SEQUENCE generation strategy. * SEQUENCE generation strategy.
*
* The definition has the following structure:
* <code>
* array(
* 'sequenceName' => 'name',
* 'allocationSize' => 20,
* 'initialValue' => 1
* )
* </code>
* *
* @var array * @var array
*/ */
public $sequenceGeneratorDefinition; public $sequenceGeneratorDefinition;
/** /**
* The definition of the table generator of this class. Only used for the * READ-ONLY: The definition of the table generator of this class. Only used for the
* TABLE generation strategy. * TABLE generation strategy.
* *
* @var array * @var array
...@@ -350,14 +359,14 @@ class ClassMetadataInfo ...@@ -350,14 +359,14 @@ class ClassMetadataInfo
public $tableGeneratorDefinition; public $tableGeneratorDefinition;
/** /**
* The policy used for change-tracking on entities of this class. * READ-ONLY: The policy used for change-tracking on entities of this class.
* *
* @var integer * @var integer
*/ */
public $changeTrackingPolicy = self::CHANGETRACKING_DEFERRED_IMPLICIT; public $changeTrackingPolicy = self::CHANGETRACKING_DEFERRED_IMPLICIT;
/** /**
* A map of field names to class names, where the field names are association * READ-ONLY: A map of field names to class names, where the field names are association
* fields that have been inherited from another class and values are the names * fields that have been inherited from another class and values are the names
* of the classes that define the association. * of the classes that define the association.
* *
...@@ -366,14 +375,15 @@ class ClassMetadataInfo ...@@ -366,14 +375,15 @@ class ClassMetadataInfo
public $inheritedAssociationFields = array(); public $inheritedAssociationFields = array();
/** /**
* A flag for whether or not instances of this class are to be versioned with optimistic locking. * READ-ONLY: A flag for whether or not instances of this class are to be versioned
* with optimistic locking.
* *
* @var boolean $isVersioned * @var boolean $isVersioned
*/ */
public $isVersioned; public $isVersioned;
/** /**
* The name of the field which is used for versioning in optimistic locking (if any). * READ-ONLY: The name of the field which is used for versioning in optimistic locking (if any).
* *
* @var mixed $versionField * @var mixed $versionField
*/ */
...@@ -391,16 +401,6 @@ class ClassMetadataInfo ...@@ -391,16 +401,6 @@ class ClassMetadataInfo
$this->rootEntityName = $entityName; $this->rootEntityName = $entityName;
} }
/**
* Gets the change tracking policy used by this class.
*
* @return integer
*/
public function getChangeTrackingPolicy()
{
return $this->changeTrackingPolicy;
}
/** /**
* Sets the change tracking policy used by this class. * Sets the change tracking policy used by this class.
* *
...@@ -441,50 +441,6 @@ class ClassMetadataInfo ...@@ -441,50 +441,6 @@ class ClassMetadataInfo
return $this->changeTrackingPolicy == self::CHANGETRACKING_NOTIFY; return $this->changeTrackingPolicy == self::CHANGETRACKING_NOTIFY;
} }
/**
* Gets the name of the mapped class.
*
* @return string
*/
public function getClassName()
{
return $this->name;
}
/**
* Gets the name of the class in the entity hierarchy that owns the field with
* the given name. The owning class is the one that defines the field.
*
* @param string $fieldName
* @return string
*/
/*public function getOwningClass($fieldName)
{
if ($this->inheritanceType == self::INHERITANCE_TYPE_NONE) {
return $this->name;
} else {
$mapping = $this->getFieldMapping($fieldName);
return $mapping['inherited'];
}
}*/
/**
* Gets the name of the root class of the mapped entity hierarchy. If the entity described
* by this ClassMetadata instance is not participating in a hierarchy, this is the same as the
* name returned by {@link getClassName()}.
*
* @return string The name of the root class of the entity hierarchy.
*/
public function getRootClassName()
{
return $this->rootEntityName;
}
public function setResultColumnNames(array $resultColumnNames)
{
$this->resultColumnNames = $resultColumnNames;
}
/** /**
* Checks whether a field is part of the identifier/primary key field(s). * Checks whether a field is part of the identifier/primary key field(s).
* *
...@@ -500,17 +456,6 @@ class ClassMetadataInfo ...@@ -500,17 +456,6 @@ class ClassMetadataInfo
return in_array($fieldName, $this->identifier); return in_array($fieldName, $this->identifier);
} }
/**
* Checks if the class has a composite identifier.
*
* @param string $fieldName The field name
* @return boolean TRUE if the identifier is composite, FALSE otherwise.
*/
public function isIdentifierComposite()
{
return $this->isIdentifierComposite;
}
/** /**
* Check if the field is unique. * Check if the field is unique.
* *
...@@ -623,18 +568,6 @@ class ClassMetadataInfo ...@@ -623,18 +568,6 @@ class ClassMetadataInfo
return $this->associationMappings; return $this->associationMappings;
} }
/**
* Gets all association mappings of the class.
*
* Alias for getAssociationMappings().
*
* @return array
*/
public function getAssociations()
{
return $this->associationMappings;
}
/** /**
* Gets the field name for a column name. * Gets the field name for a column name.
* If no field name can be found the column name is returned. * If no field name can be found the column name is returned.
...@@ -700,17 +633,6 @@ class ClassMetadataInfo ...@@ -700,17 +633,6 @@ class ClassMetadataInfo
//... //...
}*/ }*/
/**
* Gets the identifier (primary key) field names of the class.
*
* @return mixed
* @deprecated Use getIdentifierFieldNames()
*/
public function getIdentifier()
{
return $this->identifier;
}
/** /**
* Gets the identifier (primary key) field names of the class. * Gets the identifier (primary key) field names of the class.
* *
...@@ -770,16 +692,6 @@ class ClassMetadataInfo ...@@ -770,16 +692,6 @@ class ClassMetadataInfo
return isset($this->fieldMappings[$fieldName]); return isset($this->fieldMappings[$fieldName]);
} }
/**
* Gets all field mappings.
*
* @return array
*/
public function getFieldMappings()
{
return $this->fieldMappings;
}
/** /**
* Gets an array containing all the column names. * Gets an array containing all the column names.
* *
...@@ -816,26 +728,6 @@ class ClassMetadataInfo ...@@ -816,26 +728,6 @@ class ClassMetadataInfo
} }
} }
/**
* Returns an array containing all the field names.
*
* @return array
*/
public function getFieldNames()
{
return array_values($this->fieldNames);
}
/**
* Gets the Id generator type used by the class.
*
* @return string
*/
public function getIdGeneratorType()
{
return $this->generatorType;
}
/** /**
* Sets the type of Id generator to use for the mapped class. * Sets the type of Id generator to use for the mapped class.
*/ */
...@@ -979,16 +871,6 @@ class ClassMetadataInfo ...@@ -979,16 +871,6 @@ class ClassMetadataInfo
return $this->primaryTable['name'] . '_id_tmp'; return $this->primaryTable['name'] . '_id_tmp';
} }
/**
* Gets the inheritance mapping type used by the mapped class.
*
* @return string
*/
public function getInheritanceType()
{
return $this->inheritanceType;
}
/** /**
* Sets the mapped subclasses of this class. * Sets the mapped subclasses of this class.
* *
...@@ -1005,16 +887,6 @@ class ClassMetadataInfo ...@@ -1005,16 +887,6 @@ class ClassMetadataInfo
} }
} }
/**
* Gets the names of all subclasses.
*
* @return array The names of all subclasses.
*/
public function getSubclasses()
{
return $this->subClasses;
}
/** /**
* Checks whether the class has any persistent subclasses. * Checks whether the class has any persistent subclasses.
* *
...@@ -1025,16 +897,6 @@ class ClassMetadataInfo ...@@ -1025,16 +897,6 @@ class ClassMetadataInfo
return ! $this->subClasses; return ! $this->subClasses;
} }
/**
* Gets the names of all parent classes.
*
* @return array The names of all parent classes.
*/
public function getParentClasses()
{
return $this->parentClasses;
}
/** /**
* Sets the parent class names. * Sets the parent class names.
* Assumes that the class names in the passed array are in the order: * Assumes that the class names in the passed array are in the order:
...@@ -1118,17 +980,6 @@ class ClassMetadataInfo ...@@ -1118,17 +980,6 @@ class ClassMetadataInfo
$this->primaryTable = $primaryTableDefinition; $this->primaryTable = $primaryTableDefinition;
} }
/**
* Gets the primary table definition.
*
* @see setPrimaryTable()
* @return array
*/
public function getPrimaryTable()
{
return $this->primaryTable;
}
/** /**
* Checks whether the given type identifies an inheritance type. * Checks whether the given type identifies an inheritance type.
* *
...@@ -1247,7 +1098,7 @@ class ClassMetadataInfo ...@@ -1247,7 +1098,7 @@ class ClassMetadataInfo
private function _registerMappingIfInverse(AssociationMapping $assoc) private function _registerMappingIfInverse(AssociationMapping $assoc)
{ {
if ($assoc->isInverseSide()) { if ($assoc->isInverseSide()) {
$this->inverseMappings[$assoc->targetEntityName][$assoc->mappedByFieldName] = $assoc; $this->inverseMappings[$assoc->targetEntityName][$assoc->mappedBy] = $assoc;
} }
} }
...@@ -1311,17 +1162,6 @@ class ClassMetadataInfo ...@@ -1311,17 +1162,6 @@ class ClassMetadataInfo
$this->customRepositoryClassName = $repositoryClassName; $this->customRepositoryClassName = $repositoryClassName;
} }
/**
* 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;
}
/** /**
* Dispatches the lifecycle event of the given entity to the registered * Dispatches the lifecycle event of the given entity to the registered
* lifecycle callbacks and lifecycle listeners. * lifecycle callbacks and lifecycle listeners.
...@@ -1402,24 +1242,6 @@ class ClassMetadataInfo ...@@ -1402,24 +1242,6 @@ class ClassMetadataInfo
} }
} }
/**
* Gets the discriminator column definition.
*
* The discriminator column definition is an array with the following keys:
* name: The name of the column
* type: The type of the column (only integer and string supported)
* length: The length of the column (applies only if type is string)
*
* A discriminator column is used for JOINED and SINGLE_TABLE inheritance mappings.
*
* @return array
* @see setDiscriminatorColumn()
*/
public function getDiscriminatorColumn()
{
return $this->discriminatorColumn;
}
/** /**
* Sets the discriminator values used by this class. * Sets the discriminator values used by this class.
* Used for JOINED and SINGLE_TABLE inheritance mapping strategies. * Used for JOINED and SINGLE_TABLE inheritance mapping strategies.
...@@ -1446,17 +1268,6 @@ class ClassMetadataInfo ...@@ -1446,17 +1268,6 @@ class ClassMetadataInfo
} }
} }
/**
* Gets the discriminator value of this class.
* Used for JOINED and SINGLE_TABLE inheritance mapping strategies.
*
* @return array
*/
public function getDiscriminatorValue()
{
return $this->discriminatorValue;
}
/** /**
* Checks whether the given column name is the discriminator column. * Checks whether the given column name is the discriminator column.
* *
...@@ -1505,18 +1316,6 @@ class ClassMetadataInfo ...@@ -1505,18 +1316,6 @@ class ClassMetadataInfo
! $this->associationMappings[$fieldName]->isOneToOne(); ! $this->associationMappings[$fieldName]->isOneToOne();
} }
/**
* Gets the name of the ID generator used for this class.
* Only classes that use a SEQUENCE or TABLE ID generation strategy have a generator name.
*
* @return string|null The name of the ID generator or NULL if this class does not
* use a named ID generator.
*/
/*public function getIdGeneratorName()
{
return $this->idGeneratorName;
}*/
/** /**
* Sets the ID generator used to generate IDs for instances of this class. * Sets the ID generator used to generate IDs for instances of this class.
* *
...@@ -1527,36 +1326,6 @@ class ClassMetadataInfo ...@@ -1527,36 +1326,6 @@ class ClassMetadataInfo
$this->idGenerator = $generator; $this->idGenerator = $generator;
} }
/**
* Gets the ID generator used to generate IDs for instances of this class.
*
* @return AbstractIdGenerator
*/
public function getIdGenerator()
{
return $this->idGenerator;
}
/**
* Gets the definition of the sequence ID generator for this class.
*
* The definition has the following structure:
* <code>
* array(
* 'sequenceName' => 'name',
* 'allocationSize' => 20,
* 'initialValue' => 1
* )
* </code>
*
* @return array|null An array with the generator definition or NULL if this class
* has no sequence generator definition.
*/
public function getSequenceGeneratorDefinition()
{
return $this->sequenceGeneratorDefinition;
}
/** /**
* Sets the definition of the sequence ID generator for this class. * Sets the definition of the sequence ID generator for this class.
* *
...@@ -1598,16 +1367,6 @@ class ClassMetadataInfo ...@@ -1598,16 +1367,6 @@ class ClassMetadataInfo
} }
} }
/**
* Checks whether this class is versioned for optimistic locking.
*
* @return boolean TRUE if this class is versioned for optimistic locking, FALSE otherwise.
*/
public function isVersioned()
{
return $this->isVersioned;
}
/** /**
* Sets whether this class is to be versioned for optimistic locking. * Sets whether this class is to be versioned for optimistic locking.
* *
...@@ -1618,17 +1377,6 @@ class ClassMetadataInfo ...@@ -1618,17 +1377,6 @@ class ClassMetadataInfo
$this->isVersioned = $bool; $this->isVersioned = $bool;
} }
/**
* Gets the name of the field that is used for versioning if this class is versioned
* for optimistic locking.
*
* @return string
*/
public function getVersionField()
{
return $this->versionField;
}
/** /**
* Sets the name of the field that is to be used for versioning if this class is * Sets the name of the field that is to be used for versioning if this class is
* versioned for optimistic locking. * versioned for optimistic locking.
......
...@@ -78,7 +78,6 @@ class AnnotationDriver implements Driver ...@@ -78,7 +78,6 @@ class AnnotationDriver implements Driver
public function __construct(AnnotationReader $reader, $paths = null) public function __construct(AnnotationReader $reader, $paths = null)
{ {
$this->_reader = $reader; $this->_reader = $reader;
if ($paths) { if ($paths) {
$this->addPaths((array) $paths); $this->addPaths((array) $paths);
} }
...@@ -292,6 +291,7 @@ class AnnotationDriver implements Driver ...@@ -292,6 +291,7 @@ class AnnotationDriver implements Driver
$mapping['targetEntity'] = $oneToOneAnnot->targetEntity; $mapping['targetEntity'] = $oneToOneAnnot->targetEntity;
$mapping['joinColumns'] = $joinColumns; $mapping['joinColumns'] = $joinColumns;
$mapping['mappedBy'] = $oneToOneAnnot->mappedBy; $mapping['mappedBy'] = $oneToOneAnnot->mappedBy;
$mapping['inversedBy'] = $oneToOneAnnot->inversedBy;
$mapping['cascade'] = $oneToOneAnnot->cascade; $mapping['cascade'] = $oneToOneAnnot->cascade;
$mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval; $mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $oneToOneAnnot->fetch); $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $oneToOneAnnot->fetch);
...@@ -311,6 +311,7 @@ class AnnotationDriver implements Driver ...@@ -311,6 +311,7 @@ class AnnotationDriver implements Driver
} else if ($manyToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) { } else if ($manyToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) {
$mapping['joinColumns'] = $joinColumns; $mapping['joinColumns'] = $joinColumns;
$mapping['cascade'] = $manyToOneAnnot->cascade; $mapping['cascade'] = $manyToOneAnnot->cascade;
$mapping['inversedBy'] = $manyToOneAnnot->inversedBy;
$mapping['targetEntity'] = $manyToOneAnnot->targetEntity; $mapping['targetEntity'] = $manyToOneAnnot->targetEntity;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $manyToOneAnnot->fetch); $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $manyToOneAnnot->fetch);
$metadata->mapManyToOne($mapping); $metadata->mapManyToOne($mapping);
...@@ -351,6 +352,7 @@ class AnnotationDriver implements Driver ...@@ -351,6 +352,7 @@ class AnnotationDriver implements Driver
$mapping['joinTable'] = $joinTable; $mapping['joinTable'] = $joinTable;
$mapping['targetEntity'] = $manyToManyAnnot->targetEntity; $mapping['targetEntity'] = $manyToManyAnnot->targetEntity;
$mapping['mappedBy'] = $manyToManyAnnot->mappedBy; $mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
$mapping['inversedBy'] = $manyToManyAnnot->inversedBy;
$mapping['cascade'] = $manyToManyAnnot->cascade; $mapping['cascade'] = $manyToManyAnnot->cascade;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $manyToManyAnnot->fetch); $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $manyToManyAnnot->fetch);
...@@ -362,7 +364,7 @@ class AnnotationDriver implements Driver ...@@ -362,7 +364,7 @@ class AnnotationDriver implements Driver
} }
} }
// Evaluate HasLifecycleCallbacks annotation // Evaluate @HasLifecycleCallbacks annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) { if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) {
foreach ($class->getMethods() as $method) { foreach ($class->getMethods() as $method) {
if ($method->isPublic()) { if ($method->isPublic()) {
......
...@@ -70,9 +70,9 @@ final class Column extends Annotation { ...@@ -70,9 +70,9 @@ final class Column extends Annotation {
final class OneToOne extends Annotation { final class OneToOne extends Annotation {
public $targetEntity; public $targetEntity;
public $mappedBy; public $mappedBy;
public $inversedBy;
public $cascade; public $cascade;
public $fetch = 'LAZY'; public $fetch = 'LAZY';
public $optional;
public $orphanRemoval = false; public $orphanRemoval = false;
} }
final class OneToMany extends Annotation { final class OneToMany extends Annotation {
...@@ -86,11 +86,12 @@ final class ManyToOne extends Annotation { ...@@ -86,11 +86,12 @@ final class ManyToOne extends Annotation {
public $targetEntity; public $targetEntity;
public $cascade; public $cascade;
public $fetch = 'LAZY'; public $fetch = 'LAZY';
public $optional; public $inversedBy;
} }
final class ManyToMany extends Annotation { final class ManyToMany extends Annotation {
public $targetEntity; public $targetEntity;
public $mappedBy; public $mappedBy;
public $inversedBy;
public $cascade; public $cascade;
public $fetch = 'LAZY'; public $fetch = 'LAZY';
} }
......
...@@ -28,7 +28,7 @@ namespace Doctrine\ORM\Mapping; ...@@ -28,7 +28,7 @@ namespace Doctrine\ORM\Mapping;
* <b>IMPORTANT NOTE:</b> * <b>IMPORTANT NOTE:</b>
* *
* The fields of this class are only public for 2 reasons: * The fields of this class are only public for 2 reasons:
* 1) To allow fast, internal READ access. * 1) To allow fast READ access.
* 2) To drastically reduce the size of a serialized instance (private/protected members * 2) To drastically reduce the size of a serialized instance (private/protected members
* get the whole class name, namespace inclusive, prepended to every property in * get the whole class name, namespace inclusive, prepended to every property in
* the serialized representation). * the serialized representation).
...@@ -43,17 +43,17 @@ namespace Doctrine\ORM\Mapping; ...@@ -43,17 +43,17 @@ namespace Doctrine\ORM\Mapping;
class ManyToManyMapping extends AssociationMapping class ManyToManyMapping extends AssociationMapping
{ {
/** /**
* Maps the columns in the relational table to the columns in the source table. * READ-ONLY: Maps the columns in the relational table to the columns in the source table.
*/ */
public $relationToSourceKeyColumns = array(); public $relationToSourceKeyColumns = array();
/** /**
* Maps the columns in the relation table to the columns in the target table. * READ-ONLY: Maps the columns in the relation table to the columns in the target table.
*/ */
public $relationToTargetKeyColumns = array(); public $relationToTargetKeyColumns = array();
/** /**
* List of aggregated column names on the join table. * READ-ONLY: List of aggregated column names on the join table.
*/ */
public $joinTableColumns = array(); public $joinTableColumns = array();
...@@ -61,24 +61,14 @@ class ManyToManyMapping extends AssociationMapping ...@@ -61,24 +61,14 @@ class ManyToManyMapping extends AssociationMapping
//public $keyColumn; //public $keyColumn;
/** /**
* Order this collection by the given DQL snippet. * READ-ONLY: Order this collection by the given DQL snippet.
* *
* Only simple unqualified field names and ASC|DESC are allowed * Only simple unqualified field names and ASC|DESC are allowed
* *
* @var array * @var array
*/ */
public $orderBy = null; public $orderBy;
/**
* Initializes a new ManyToManyMapping.
*
* @param array $mapping The mapping definition.
*/
public function __construct(array $mapping)
{
parent::__construct($mapping);
}
/** /**
* Validates and completes the mapping. * Validates and completes the mapping.
* *
...@@ -145,22 +135,6 @@ class ManyToManyMapping extends AssociationMapping ...@@ -145,22 +135,6 @@ class ManyToManyMapping extends AssociationMapping
} }
} }
public function getJoinTableColumnNames()
{
return $this->joinTableColumns;
//return array_merge(array_keys($this->relationToSourceKeyColumns), array_keys($this->relationToTargetKeyColumns));
}
public function getRelationToSourceKeyColumns()
{
return $this->relationToSourceKeyColumns;
}
public function getRelationToTargetKeyColumns()
{
return $this->relationToTargetKeyColumns;
}
/** /**
* Loads entities in $targetCollection using $em. * Loads entities in $targetCollection using $em.
* The data of $sourceEntity are used to restrict the collection * The data of $sourceEntity are used to restrict the collection
...@@ -186,7 +160,7 @@ class ManyToManyMapping extends AssociationMapping ...@@ -186,7 +160,7 @@ class ManyToManyMapping extends AssociationMapping
} }
} }
} else { } else {
$owningAssoc = $em->getClassMetadata($this->targetEntityName)->associationMappings[$this->mappedByFieldName]; $owningAssoc = $em->getClassMetadata($this->targetEntityName)->associationMappings[$this->mappedBy];
// TRICKY: since the association is inverted source and target are flipped // TRICKY: since the association is inverted source and target are flipped
foreach ($owningAssoc->relationToTargetKeyColumns as $relationKeyColumn => $sourceKeyColumn) { foreach ($owningAssoc->relationToTargetKeyColumns as $relationKeyColumn => $sourceKeyColumn) {
// getting id // getting id
......
...@@ -32,7 +32,7 @@ namespace Doctrine\ORM\Mapping; ...@@ -32,7 +32,7 @@ namespace Doctrine\ORM\Mapping;
* <b>IMPORTANT NOTE:</b> * <b>IMPORTANT NOTE:</b>
* *
* The fields of this class are only public for 2 reasons: * The fields of this class are only public for 2 reasons:
* 1) To allow fast, internal READ access. * 1) To allow fast READ access.
* 2) To drastically reduce the size of a serialized instance (private/protected members * 2) To drastically reduce the size of a serialized instance (private/protected members
* get the whole class name, namespace inclusive, prepended to every property in * get the whole class name, namespace inclusive, prepended to every property in
* the serialized representation). * the serialized representation).
...@@ -46,26 +46,21 @@ namespace Doctrine\ORM\Mapping; ...@@ -46,26 +46,21 @@ namespace Doctrine\ORM\Mapping;
*/ */
class OneToManyMapping extends AssociationMapping class OneToManyMapping extends AssociationMapping
{ {
/** Whether to delete orphaned elements (removed from the collection) */ /**
* READ-ONLY: Whether to delete orphaned elements (removed from the collection)
*
* @var boolean
*/
public $orphanRemoval = false; public $orphanRemoval = false;
/** FUTURE: The key column mapping, if any. The key column holds the keys of the Collection. */ /** FUTURE: The key column mapping, if any. The key column holds the keys of the Collection. */
//public $keyColumn; //public $keyColumn;
/** /**
* Order this collection by the given SQL snippet. * READ-ONLY: Order this collection by the given SQL snippet.
*/ */
public $orderBy; public $orderBy;
/**
* Initializes a new OneToManyMapping.
*
* @param array $mapping The mapping information.
*/
public function __construct(array $mapping)
{
parent::__construct($mapping);
}
/** /**
* Validates and completes the mapping. * Validates and completes the mapping.
* *
...@@ -82,6 +77,7 @@ class OneToManyMapping extends AssociationMapping ...@@ -82,6 +77,7 @@ class OneToManyMapping extends AssociationMapping
throw MappingException::oneToManyRequiresMappedBy($mapping['fieldName']); throw MappingException::oneToManyRequiresMappedBy($mapping['fieldName']);
} }
//TODO: if orphanRemoval, cascade=remove is implicit!
$this->orphanRemoval = isset($mapping['orphanRemoval']) ? $this->orphanRemoval = isset($mapping['orphanRemoval']) ?
(bool) $mapping['orphanRemoval'] : false; (bool) $mapping['orphanRemoval'] : false;
...@@ -127,7 +123,7 @@ class OneToManyMapping extends AssociationMapping ...@@ -127,7 +123,7 @@ class OneToManyMapping extends AssociationMapping
$persister = $em->getUnitOfWork()->getEntityPersister($this->targetEntityName); $persister = $em->getUnitOfWork()->getEntityPersister($this->targetEntityName);
// a one-to-many is always inverse (does not have foreign key) // a one-to-many is always inverse (does not have foreign key)
$sourceClass = $em->getClassMetadata($this->sourceEntityName); $sourceClass = $em->getClassMetadata($this->sourceEntityName);
$owningAssoc = $em->getClassMetadata($this->targetEntityName)->associationMappings[$this->mappedByFieldName]; $owningAssoc = $em->getClassMetadata($this->targetEntityName)->associationMappings[$this->mappedBy];
// TRICKY: since the association is specular source and target are flipped // TRICKY: since the association is specular source and target are flipped
foreach ($owningAssoc->targetToSourceKeyColumns as $sourceKeyColumn => $targetKeyColumn) { foreach ($owningAssoc->targetToSourceKeyColumns as $sourceKeyColumn => $targetKeyColumn) {
// getting id // getting id
......
...@@ -28,7 +28,7 @@ namespace Doctrine\ORM\Mapping; ...@@ -28,7 +28,7 @@ namespace Doctrine\ORM\Mapping;
* <b>IMPORTANT NOTE:</b> * <b>IMPORTANT NOTE:</b>
* *
* The fields of this class are only public for 2 reasons: * The fields of this class are only public for 2 reasons:
* 1) To allow fast, internal READ access. * 1) To allow fast READ access.
* 2) To drastically reduce the size of a serialized instance (private/protected members * 2) To drastically reduce the size of a serialized instance (private/protected members
* get the whole class name, namespace inclusive, prepended to every property in * get the whole class name, namespace inclusive, prepended to every property in
* the serialized representation). * the serialized representation).
...@@ -43,59 +43,41 @@ namespace Doctrine\ORM\Mapping; ...@@ -43,59 +43,41 @@ namespace Doctrine\ORM\Mapping;
class OneToOneMapping extends AssociationMapping class OneToOneMapping extends AssociationMapping
{ {
/** /**
* Maps the source foreign/primary key columns to the target primary/foreign key columns. * READ-ONLY: Maps the source foreign/primary key columns to the target primary/foreign key columns.
* i.e. source.id (pk) => target.user_id (fk). * i.e. source.id (pk) => target.user_id (fk).
* Reverse mapping of _targetToSourceKeyColumns. * Reverse mapping of _targetToSourceKeyColumns.
*/ */
public $sourceToTargetKeyColumns = array(); public $sourceToTargetKeyColumns = array();
/** /**
* Maps the target primary/foreign key columns to the source foreign/primary key columns. * READ-ONLY: Maps the target primary/foreign key columns to the source foreign/primary key columns.
* i.e. target.user_id (fk) => source.id (pk). * i.e. target.user_id (fk) => source.id (pk).
* Reverse mapping of _sourceToTargetKeyColumns. * Reverse mapping of _sourceToTargetKeyColumns.
*/ */
public $targetToSourceKeyColumns = array(); public $targetToSourceKeyColumns = array();
/** /**
* Whether to delete orphaned elements (when nulled out, i.e. $foo->other = null) * READ-ONLY: Whether to delete orphaned elements (when nulled out, i.e. $foo->other = null)
* *
* @var boolean * @var boolean
*/ */
public $orphanRemoval = false; public $orphanRemoval = false;
/**
* Whether the association is optional (0..1) or not (1..1).
* By default all associations are optional.
*
* @var boolean
*/
public $isOptional = true;
/** /**
* The join column definitions. * READ-ONLY: The join column definitions. Only present on the owning side.
* *
* @var array * @var array
*/ */
public $joinColumns = array(); public $joinColumns = array();
/** /**
* A map of join column names to field names that are used in cases * READ-ONLY: A map of join column names to field names that are used in cases
* when the join columns are fetched as part of the query result. * when the join columns are fetched as part of the query result.
* *
* @var array * @var array
*/ */
public $joinColumnFieldNames = array(); public $joinColumnFieldNames = array();
/**
* Creates a new OneToOneMapping.
*
* @param array $mapping The mapping info.
*/
public function __construct(array $mapping)
{
parent::__construct($mapping);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
* *
...@@ -127,59 +109,14 @@ class OneToOneMapping extends AssociationMapping ...@@ -127,59 +109,14 @@ class OneToOneMapping extends AssociationMapping
$this->joinColumns = $mapping['joinColumns']; $this->joinColumns = $mapping['joinColumns'];
$this->targetToSourceKeyColumns = array_flip($this->sourceToTargetKeyColumns); $this->targetToSourceKeyColumns = array_flip($this->sourceToTargetKeyColumns);
} }
$this->isOptional = isset($mapping['optional']) ? //TODO: if orphanRemoval, cascade=remove is implicit!
(bool) $mapping['optional'] : true;
$this->orphanRemoval = isset($mapping['orphanRemoval']) ? $this->orphanRemoval = isset($mapping['orphanRemoval']) ?
(bool) $mapping['orphanRemoval'] : false; (bool) $mapping['orphanRemoval'] : false;
/*if ($this->isOptional) {
$this->fetchMode = self::FETCH_EAGER;
}*/
return $mapping; return $mapping;
} }
/**
* Whether the association is optional (0..1), or not (1..1).
*
* @return boolean TRUE if the association is optional, FALSE otherwise.
*/
public function isOptional()
{
return $this->isOptional;
}
/**
* Gets the join column definitions for this mapping.
*
* @return array
*/
public function getJoinColumns()
{
return $this->joinColumns;
}
/**
* Gets the source-to-target key column mapping.
*
* @return array
*/
public function getSourceToTargetKeyColumns()
{
return $this->sourceToTargetKeyColumns;
}
/**
* Gets the target-to-source key column mapping.
*
* @return array
*/
public function getTargetToSourceKeyColumns()
{
return $this->targetToSourceKeyColumns;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
* *
...@@ -233,7 +170,7 @@ class OneToOneMapping extends AssociationMapping ...@@ -233,7 +170,7 @@ class OneToOneMapping extends AssociationMapping
} else { } else {
$conditions = array(); $conditions = array();
$sourceClass = $em->getClassMetadata($this->sourceEntityName); $sourceClass = $em->getClassMetadata($this->sourceEntityName);
$owningAssoc = $targetClass->getAssociationMapping($this->mappedByFieldName); $owningAssoc = $targetClass->getAssociationMapping($this->mappedBy);
// TRICKY: since the association is specular source and target are flipped // TRICKY: since the association is specular source and target are flipped
foreach ($owningAssoc->targetToSourceKeyColumns as $sourceKeyColumn => $targetKeyColumn) { foreach ($owningAssoc->targetToSourceKeyColumns as $sourceKeyColumn => $targetKeyColumn) {
if (isset($sourceClass->fieldNames[$sourceKeyColumn])) { if (isset($sourceClass->fieldNames[$sourceKeyColumn])) {
...@@ -244,44 +181,14 @@ class OneToOneMapping extends AssociationMapping ...@@ -244,44 +181,14 @@ class OneToOneMapping extends AssociationMapping
); );
} }
} }
$targetEntity = $em->getUnitOfWork()->getEntityPersister($this->targetEntityName)->load($conditions, $targetEntity, $this); $targetEntity = $em->getUnitOfWork()->getEntityPersister($this->targetEntityName)->load($conditions, $targetEntity, $this);
if ($targetEntity !== null) { if ($targetEntity !== null) {
$targetClass->setFieldValue($targetEntity, $this->mappedByFieldName, $sourceEntity); $targetClass->setFieldValue($targetEntity, $this->mappedBy, $sourceEntity);
} }
} }
return $targetEntity; return $targetEntity;
} }
/**
* @internal Experimental. For MetaModel API, Doctrine 2.1 or later.
*/
/*public static function __set_state(array $state)
{
$assoc = new self(array());
$assoc->isOptional = $state['isOptional'];
$assoc->joinColumnFieldNames = $state['joinColumnFieldNames'];
$assoc->joinColumns = $state['joinColumns'];
$assoc->orphanRemoval = $state['orphanRemoval'];
$assoc->sourceToTargetKeyColumns = $state['sourceToTargetKeyColumns'];
$assoc->targetToSourceKeyColumns = $state['targetToSourceKeyColumns'];
$assoc->fetchMode = $state['fetchMode'];
$assoc->isCascadeDetach = $state['isCascadeDetach'];
$assoc->isCascadeRefresh = $state['isCascadeRefresh'];
$assoc->isCascadeRemove = $state['isCascadeRemove'];
$assoc->isCascadePersist = $state['isCascadePersist'];
$assoc->isCascadeMerge = $state['isCascadeMerge'];
$assoc->isOwningSide = $state['isOwningSide'];
$assoc->joinTable = $state['joinTable'];
$assoc->mappedByFieldName = $state['mappedByFieldName'];
$assoc->sourceEntityName = $state['sourceEntityName'];
$assoc->targetEntityName = $state['targetEntityName'];
$assoc->sourceFieldName = $state['sourceFieldName'];
return $assoc;
}*/
} }
...@@ -135,9 +135,10 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect ...@@ -135,9 +135,10 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect
$this->_association = $assoc; $this->_association = $assoc;
// Check for bidirectionality // Check for bidirectionality
//$this->_backRefFieldName = $assoc->inversedBy ?: $assoc->mappedBy;
if ( ! $assoc->isOwningSide) { if ( ! $assoc->isOwningSide) {
// For sure bi-directional // For sure bi-directional
$this->_backRefFieldName = $assoc->mappedByFieldName; $this->_backRefFieldName = $assoc->mappedBy;
} else { } else {
if (isset($this->_typeClass->inverseMappings[$assoc->sourceEntityName][$assoc->sourceFieldName])) { if (isset($this->_typeClass->inverseMappings[$assoc->sourceEntityName][$assoc->sourceFieldName])) {
// Bi-directional // Bi-directional
...@@ -523,9 +524,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect ...@@ -523,9 +524,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect
public function map(Closure $func) public function map(Closure $func)
{ {
$this->_initialize(); $this->_initialize();
$result = $this->_coll->map($func); return $this->_coll->map($func);
$this->_changed();
return $result;
} }
/** /**
......
...@@ -39,8 +39,8 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -39,8 +39,8 @@ class ManyToManyPersister extends AbstractCollectionPersister
protected function _getDeleteRowSql(PersistentCollection $coll) protected function _getDeleteRowSql(PersistentCollection $coll)
{ {
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
$joinTable = $mapping->getJoinTable(); $joinTable = $mapping->joinTable;
$columns = $mapping->getJoinTableColumnNames(); $columns = $mapping->joinTableColumns;
return 'DELETE FROM ' . $joinTable['name'] . ' WHERE ' . implode(' = ? AND ', $columns) . ' = ?'; return 'DELETE FROM ' . $joinTable['name'] . ' WHERE ' . implode(' = ? AND ', $columns) . ' = ?';
} }
...@@ -74,7 +74,7 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -74,7 +74,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
protected function _getInsertRowSql(PersistentCollection $coll) protected function _getInsertRowSql(PersistentCollection $coll)
{ {
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
$joinTable = $mapping->getJoinTable(); $joinTable = $mapping->joinTable;
$columns = $mapping->joinTableColumns; $columns = $mapping->joinTableColumns;
return 'INSERT INTO ' . $joinTable['name'] . ' (' . implode(', ', $columns) . ')' return 'INSERT INTO ' . $joinTable['name'] . ' (' . implode(', ', $columns) . ')'
. ' VALUES (' . implode(', ', array_fill(0, count($columns), '?')) . ')'; . ' VALUES (' . implode(', ', array_fill(0, count($columns), '?')) . ')';
...@@ -141,7 +141,7 @@ class ManyToManyPersister extends AbstractCollectionPersister ...@@ -141,7 +141,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
protected function _getDeleteSql(PersistentCollection $coll) protected function _getDeleteSql(PersistentCollection $coll)
{ {
$mapping = $coll->getMapping(); $mapping = $coll->getMapping();
$joinTable = $mapping->getJoinTable(); $joinTable = $mapping->joinTable;
$whereClause = ''; $whereClause = '';
foreach ($mapping->relationToSourceKeyColumns as $relationColumn => $srcColumn) { foreach ($mapping->relationToSourceKeyColumns as $relationColumn => $srcColumn) {
if ($whereClause !== '') $whereClause .= ' AND '; if ($whereClause !== '') $whereClause .= ' AND ';
......
...@@ -32,8 +32,7 @@ use Doctrine\ORM\PersistentCollection; ...@@ -32,8 +32,7 @@ use Doctrine\ORM\PersistentCollection;
* *
* @since 2.0 * @since 2.0
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @todo Complete implementation when the support for uni-directional one-to-many mappings * @todo Remove
* on a foreign key gets added.
*/ */
class OneToManyPersister extends AbstractCollectionPersister class OneToManyPersister extends AbstractCollectionPersister
{ {
...@@ -51,10 +50,10 @@ class OneToManyPersister extends AbstractCollectionPersister ...@@ -51,10 +50,10 @@ class OneToManyPersister extends AbstractCollectionPersister
$targetClass = $this->_em->getClassMetadata($mapping->getTargetEntityName()); $targetClass = $this->_em->getClassMetadata($mapping->getTargetEntityName());
$table = $targetClass->getTableName(); $table = $targetClass->getTableName();
$ownerMapping = $targetClass->getAssociationMapping($mapping->getMappedByFieldName()); $ownerMapping = $targetClass->getAssociationMapping($mapping->mappedBy);
$setClause = ''; $setClause = '';
foreach ($ownerMapping->getSourceToTargetKeyColumns() as $sourceCol => $targetCol) { foreach ($ownerMapping->sourceToTargetKeyColumns as $sourceCol => $targetCol) {
if ($setClause != '') $setClause .= ', '; if ($setClause != '') $setClause .= ', ';
$setClause .= "$sourceCol = NULL"; $setClause .= "$sourceCol = NULL";
} }
......
...@@ -446,7 +446,7 @@ class StandardEntityPersister ...@@ -446,7 +446,7 @@ class StandardEntityPersister
return $this->_createEntity($result, $entity, $hints); return $this->_createEntity($result, $entity, $hints);
} }
/** /**
* Refreshes an entity. * Refreshes an entity.
* *
...@@ -457,11 +457,11 @@ class StandardEntityPersister ...@@ -457,11 +457,11 @@ class StandardEntityPersister
{ {
$sql = $this->_getSelectEntitiesSQL($id); $sql = $this->_getSelectEntitiesSQL($id);
$params = array_values($id); $params = array_values($id);
if ($this->_sqlLogger !== null) { if ($this->_sqlLogger !== null) {
$this->_sqlLogger->logSql($sql, $params); $this->_sqlLogger->logSql($sql, $params);
} }
$stmt = $this->_conn->prepare($sql); $stmt = $this->_conn->prepare($sql);
$stmt->execute($params); $stmt->execute($params);
$result = $stmt->fetch(Connection::FETCH_ASSOC); $result = $stmt->fetch(Connection::FETCH_ASSOC);
...@@ -573,7 +573,7 @@ class StandardEntityPersister ...@@ -573,7 +573,7 @@ class StandardEntityPersister
*/ */
public function loadOneToManyCollection($assoc, array $criteria, PersistentCollection $coll) public function loadOneToManyCollection($assoc, array $criteria, PersistentCollection $coll)
{ {
$owningAssoc = $this->_class->associationMappings[$coll->getMapping()->mappedByFieldName]; $owningAssoc = $this->_class->associationMappings[$coll->getMapping()->mappedBy];
$sql = $this->_getSelectEntitiesSQL($criteria, $owningAssoc, $assoc->orderBy); $sql = $this->_getSelectEntitiesSQL($criteria, $owningAssoc, $assoc->orderBy);
...@@ -782,7 +782,7 @@ class StandardEntityPersister ...@@ -782,7 +782,7 @@ class StandardEntityPersister
$owningAssoc = $manyToMany; $owningAssoc = $manyToMany;
$joinClauses = $manyToMany->relationToTargetKeyColumns; $joinClauses = $manyToMany->relationToTargetKeyColumns;
} else { } else {
$owningAssoc = $this->_em->getClassMetadata($manyToMany->targetEntityName)->associationMappings[$manyToMany->mappedByFieldName]; $owningAssoc = $this->_em->getClassMetadata($manyToMany->targetEntityName)->associationMappings[$manyToMany->mappedBy];
$joinClauses = $owningAssoc->relationToSourceKeyColumns; $joinClauses = $owningAssoc->relationToSourceKeyColumns;
} }
...@@ -969,7 +969,7 @@ class StandardEntityPersister ...@@ -969,7 +969,7 @@ class StandardEntityPersister
} }
$tableAlias = $class->primaryTable['name'][0] . $this->_sqlAliasCounter++; $tableAlias = $class->primaryTable['name'][0] . $this->_sqlAliasCounter++;
$this->_sqlTableAliases[$class->name] = $tableAlias; $this->_sqlTableAliases[$class->name] = $tableAlias;
return $tableAlias; return $tableAlias;
} }
} }
...@@ -55,7 +55,7 @@ class SizeFunction extends FunctionNode ...@@ -55,7 +55,7 @@ class SizeFunction extends FunctionNode
if ($assoc->isOneToMany()) { if ($assoc->isOneToMany()) {
$targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc->targetEntityName); $targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc->targetEntityName);
$targetAssoc = $targetClass->associationMappings[$assoc->mappedByFieldName]; $targetAssoc = $targetClass->associationMappings[$assoc->mappedBy];
$targetTableAlias = $sqlWalker->getSqlTableAlias($targetClass->primaryTable['name']); $targetTableAlias = $sqlWalker->getSqlTableAlias($targetClass->primaryTable['name']);
$sourceTableAlias = $sqlWalker->getSqlTableAlias($qComp['metadata']->primaryTable['name'], $dqlAlias); $sourceTableAlias = $sqlWalker->getSqlTableAlias($qComp['metadata']->primaryTable['name'], $dqlAlias);
......
...@@ -53,9 +53,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor ...@@ -53,9 +53,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
$conn = $em->getConnection(); $conn = $em->getConnection();
$platform = $conn->getDatabasePlatform(); $platform = $conn->getDatabasePlatform();
$primaryClass = $sqlWalker->getEntityManager()->getClassMetadata( $primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName);
$AST->deleteClause->abstractSchemaName
);
$primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable; $primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable;
$rootClass = $em->getClassMetadata($primaryClass->rootEntityName); $rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
...@@ -96,7 +94,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor ...@@ -96,7 +94,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
); );
} }
$this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' $this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' ('
. $conn->getDatabasePlatform()->getColumnDeclarationListSQL($columnDefinitions) . $platform->getColumnDeclarationListSQL($columnDefinitions)
. ', PRIMARY KEY(' . $idColumnList . '))'; . ', PRIMARY KEY(' . $idColumnList . '))';
$this->_dropTempTableSql = 'DROP TABLE ' . $tempTable; $this->_dropTempTableSql = 'DROP TABLE ' . $tempTable;
} }
......
...@@ -38,7 +38,7 @@ use Doctrine\ORM\Query; ...@@ -38,7 +38,7 @@ use Doctrine\ORM\Query;
*/ */
class Parser class Parser
{ {
/** Maps registered string function names to class names. */ /** Maps BUILT-IN string function names to AST class names. */
private static $_STRING_FUNCTIONS = array( private static $_STRING_FUNCTIONS = array(
'concat' => 'Doctrine\ORM\Query\AST\Functions\ConcatFunction', 'concat' => 'Doctrine\ORM\Query\AST\Functions\ConcatFunction',
'substring' => 'Doctrine\ORM\Query\AST\Functions\SubstringFunction', 'substring' => 'Doctrine\ORM\Query\AST\Functions\SubstringFunction',
...@@ -47,7 +47,7 @@ class Parser ...@@ -47,7 +47,7 @@ class Parser
'upper' => 'Doctrine\ORM\Query\AST\Functions\UpperFunction' 'upper' => 'Doctrine\ORM\Query\AST\Functions\UpperFunction'
); );
/** Maps registered numeric function names to class names. */ /** Maps BUILT-IN numeric function names to AST class names. */
private static $_NUMERIC_FUNCTIONS = array( private static $_NUMERIC_FUNCTIONS = array(
'length' => 'Doctrine\ORM\Query\AST\Functions\LengthFunction', 'length' => 'Doctrine\ORM\Query\AST\Functions\LengthFunction',
'locate' => 'Doctrine\ORM\Query\AST\Functions\LocateFunction', 'locate' => 'Doctrine\ORM\Query\AST\Functions\LocateFunction',
...@@ -57,7 +57,7 @@ class Parser ...@@ -57,7 +57,7 @@ class Parser
'size' => 'Doctrine\ORM\Query\AST\Functions\SizeFunction' 'size' => 'Doctrine\ORM\Query\AST\Functions\SizeFunction'
); );
/** Maps registered datetime function names to class names. */ /** Maps BUILT-IN datetime function names to AST class names. */
private static $_DATETIME_FUNCTIONS = array( private static $_DATETIME_FUNCTIONS = array(
'current_date' => 'Doctrine\ORM\Query\AST\Functions\CurrentDateFunction', 'current_date' => 'Doctrine\ORM\Query\AST\Functions\CurrentDateFunction',
'current_time' => 'Doctrine\ORM\Query\AST\Functions\CurrentTimeFunction', 'current_time' => 'Doctrine\ORM\Query\AST\Functions\CurrentTimeFunction',
...@@ -193,39 +193,6 @@ class Parser ...@@ -193,39 +193,6 @@ class Parser
return $this->_em; return $this->_em;
} }
/**
* Registers a custom function that returns strings.
*
* @param string $name The function name.
* @param string $class The class name of the function implementation.
*/
public static function registerStringFunction($name, $class)
{
self::$_STRING_FUNCTIONS[strtolower($name)] = $class;
}
/**
* Registers a custom function that returns numerics.
*
* @param string $name The function name.
* @param string $class The class name of the function implementation.
*/
public static function registerNumericFunction($name, $class)
{
self::$_NUMERIC_FUNCTIONS[strtolower($name)] = $class;
}
/**
* Registers a custom function that returns date/time values.
*
* @param string $name The function name.
* @param string $class The class name of the function implementation.
*/
public static function registerDatetimeFunction($name, $class)
{
self::$_DATETIME_FUNCTIONS[strtolower($name)] = $class;
}
/** /**
* Attempts to match the given token with the current lookahead token. * Attempts to match the given token with the current lookahead token.
* *
...@@ -358,7 +325,7 @@ class Parser ...@@ -358,7 +325,7 @@ class Parser
$message .= "'{$token['value']}'"; $message .= "'{$token['value']}'";
} }
throw \Doctrine\ORM\Query\QueryException::syntaxError($message); throw QueryException::syntaxError($message);
} }
/** /**
...@@ -428,39 +395,6 @@ class Parser ...@@ -428,39 +395,6 @@ class Parser
return ($peek['value'] === '(' && $nextpeek['type'] !== Lexer::T_SELECT); return ($peek['value'] === '(' && $nextpeek['type'] !== Lexer::T_SELECT);
} }
/**
* Checks whether the function with the given name is a string function
* (a function that returns strings).
*
* @return boolean TRUE if the token type is a string function, FALSE otherwise.
*/
private function _isStringFunction($funcName)
{
return isset(self::$_STRING_FUNCTIONS[strtolower($funcName)]);
}
/**
* Checks whether the function with the given name is a numeric function
* (a function that returns numerics).
*
* @return boolean TRUE if the token type is a numeric function, FALSE otherwise.
*/
private function _isNumericFunction($funcName)
{
return isset(self::$_NUMERIC_FUNCTIONS[strtolower($funcName)]);
}
/**
* Checks whether the function with the given name is a datetime function
* (a function that returns date/time values).
*
* @return boolean TRUE if the token type is a datetime function, FALSE otherwise.
*/
private function _isDatetimeFunction($funcName)
{
return isset(self::$_DATETIME_FUNCTIONS[strtolower($funcName)]);
}
/** /**
* Checks whether the given token type indicates an aggregate function. * Checks whether the given token type indicates an aggregate function.
* *
...@@ -2624,17 +2558,27 @@ class Parser ...@@ -2624,17 +2558,27 @@ class Parser
*/ */
public function FunctionDeclaration() public function FunctionDeclaration()
{ {
$funcName = $this->_lexer->lookahead['value']; $funcName = strtolower($this->_lexer->lookahead['value']);
if ($this->_isStringFunction($funcName)) { // Check for built-in functions first!
if (isset(self::$_STRING_FUNCTIONS[$funcName])) {
return $this->FunctionsReturningStrings();
} else if (isset(self::$_NUMERIC_FUNCTIONS[$funcName])) {
return $this->FunctionsReturningNumerics();
} else if (isset(self::$_DATETIME_FUNCTIONS[$funcName])) {
return $this->FunctionsReturningDatetime();
}
// Check for custom functions afterwards
$config = $this->_em->getConfiguration();
if ($config->getCustomStringFunction($funcName) !== null) {
return $this->FunctionsReturningStrings(); return $this->FunctionsReturningStrings();
} else if ($this->_isNumericFunction($funcName)) { } else if ($config->getCustomNumericFunction($funcName) !== null) {
return $this->FunctionsReturningNumerics(); return $this->FunctionsReturningNumerics();
} else if ($this->_isDatetimeFunction($funcName)) { } else if ($config->getCustomDatetimeFunction($funcName) !== null) {
return $this->FunctionsReturningDatetime(); return $this->FunctionsReturningDatetime();
} }
$this->syntaxError('Known function.'); $this->syntaxError('Known function.', $funcName);
} }
/** /**
...@@ -2681,6 +2625,7 @@ class Parser ...@@ -2681,6 +2625,7 @@ class Parser
{ {
$funcNameLower = strtolower($this->_lexer->lookahead['value']); $funcNameLower = strtolower($this->_lexer->lookahead['value']);
$funcClass = self::$_STRING_FUNCTIONS[$funcNameLower]; $funcClass = self::$_STRING_FUNCTIONS[$funcNameLower];
//$funcClass = $this->_em->getConfiguration()->getDQLStringFunctionClassName($funcNameLower);
$function = new $funcClass($funcNameLower); $function = new $funcClass($funcNameLower);
$function->parse($this); $function->parse($this);
......
...@@ -696,7 +696,7 @@ class SqlWalker implements TreeWalker ...@@ -696,7 +696,7 @@ class SqlWalker implements TreeWalker
// Ensure we got the owning side, since it has all mapping info // Ensure we got the owning side, since it has all mapping info
if ( ! $relation->isOwningSide) { if ( ! $relation->isOwningSide) {
$assoc = $targetClass->associationMappings[$relation->mappedByFieldName]; $assoc = $targetClass->associationMappings[$relation->mappedBy];
} else { } else {
$assoc = $relation; $assoc = $relation;
} }
...@@ -728,7 +728,7 @@ class SqlWalker implements TreeWalker ...@@ -728,7 +728,7 @@ class SqlWalker implements TreeWalker
} }
} else if ($assoc->isManyToMany()) { } else if ($assoc->isManyToMany()) {
// Join relation table // Join relation table
$joinTable = $assoc->getJoinTable(); $joinTable = $assoc->joinTable;
$joinTableAlias = $this->getSqlTableAlias($joinTable['name'], $joinedDqlAlias); $joinTableAlias = $this->getSqlTableAlias($joinTable['name'], $joinedDqlAlias);
$sql .= $assoc->getQuotedJoinTableName($this->_platform) . ' ' . $joinTableAlias . ' ON '; $sql .= $assoc->getQuotedJoinTableName($this->_platform) . ' ' . $joinTableAlias . ' ON ';
...@@ -1304,7 +1304,7 @@ class SqlWalker implements TreeWalker ...@@ -1304,7 +1304,7 @@ class SqlWalker implements TreeWalker
$sql .= $targetClass->getQuotedTableName($this->_platform) $sql .= $targetClass->getQuotedTableName($this->_platform)
. ' ' . $targetTableAlias . ' WHERE '; . ' ' . $targetTableAlias . ' WHERE ';
$owningAssoc = $targetClass->associationMappings[$assoc->mappedByFieldName]; $owningAssoc = $targetClass->associationMappings[$assoc->mappedBy];
$first = true; $first = true;
...@@ -1329,7 +1329,7 @@ class SqlWalker implements TreeWalker ...@@ -1329,7 +1329,7 @@ class SqlWalker implements TreeWalker
} else { // many-to-many } else { // many-to-many
$targetClass = $this->_em->getClassMetadata($assoc->targetEntityName); $targetClass = $this->_em->getClassMetadata($assoc->targetEntityName);
$owningAssoc = $assoc->isOwningSide ? $assoc : $targetClass->associationMappings[$assoc->mappedByFieldName]; $owningAssoc = $assoc->isOwningSide ? $assoc : $targetClass->associationMappings[$assoc->mappedBy];
$joinTable = $assoc->isOwningSide ? $assoc->joinTable : $owningAssoc->joinTable; $joinTable = $assoc->isOwningSide ? $assoc->joinTable : $owningAssoc->joinTable;
// SQL table aliases // SQL table aliases
......
...@@ -415,8 +415,8 @@ class AnnotationExporter extends AbstractExporter ...@@ -415,8 +415,8 @@ class AnnotationExporter extends AbstractExporter
if (isset($associationMapping->targetEntityName)) { if (isset($associationMapping->targetEntityName)) {
$typeOptions[] = 'targetEntity="' . $associationMapping->targetEntityName . '"'; $typeOptions[] = 'targetEntity="' . $associationMapping->targetEntityName . '"';
} }
if (isset($associationMapping->mappedByFieldName)) { if (isset($associationMapping->mappedBy)) {
$typeOptions[] = 'mappedBy="' . $associationMapping->mappedByFieldName . '"'; $typeOptions[] = 'mappedBy="' . $associationMapping->mappedBy . '"';
} }
if ($associationMapping->hasCascades()) { if ($associationMapping->hasCascades()) {
$cascades = array(); $cascades = array();
......
...@@ -104,7 +104,7 @@ class PhpExporter extends AbstractExporter ...@@ -104,7 +104,7 @@ class PhpExporter extends AbstractExporter
if ($associationMapping instanceof \Doctrine\ORM\Mapping\OneToOneMapping) { if ($associationMapping instanceof \Doctrine\ORM\Mapping\OneToOneMapping) {
$method = 'mapOneToOne'; $method = 'mapOneToOne';
$oneToOneMappingArray = array( $oneToOneMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName, 'mappedBy' => $associationMapping->mappedBy,
'joinColumns' => $associationMapping->joinColumns, 'joinColumns' => $associationMapping->joinColumns,
'orphanRemoval' => $associationMapping->orphanRemoval, 'orphanRemoval' => $associationMapping->orphanRemoval,
); );
...@@ -113,7 +113,7 @@ class PhpExporter extends AbstractExporter ...@@ -113,7 +113,7 @@ class PhpExporter extends AbstractExporter
} else if ($associationMapping instanceof \Doctrine\ORM\Mapping\OneToManyMapping) { } else if ($associationMapping instanceof \Doctrine\ORM\Mapping\OneToManyMapping) {
$method = 'mapOneToMany'; $method = 'mapOneToMany';
$oneToManyMappingArray = array( $oneToManyMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName, 'mappedBy' => $associationMapping->mappedBy,
'orphanRemoval' => $associationMapping->orphanRemoval, 'orphanRemoval' => $associationMapping->orphanRemoval,
); );
...@@ -121,7 +121,7 @@ class PhpExporter extends AbstractExporter ...@@ -121,7 +121,7 @@ class PhpExporter extends AbstractExporter
} else if ($associationMapping instanceof \Doctrine\ORM\Mapping\ManyToManyMapping) { } else if ($associationMapping instanceof \Doctrine\ORM\Mapping\ManyToManyMapping) {
$method = 'mapManyToMany'; $method = 'mapManyToMany';
$manyToManyMappingArray = array( $manyToManyMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName, 'mappedBy' => $associationMapping->mappedBy,
'joinTable' => $associationMapping->joinTable, 'joinTable' => $associationMapping->joinTable,
); );
......
...@@ -127,7 +127,7 @@ class XmlExporter extends AbstractExporter ...@@ -127,7 +127,7 @@ class XmlExporter extends AbstractExporter
} }
} }
if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->getIdGeneratorType())) { if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
$id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType; $id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType;
} }
...@@ -190,8 +190,8 @@ class XmlExporter extends AbstractExporter ...@@ -190,8 +190,8 @@ class XmlExporter extends AbstractExporter
$associationMappingXml->addAttribute('field', $associationMapping->sourceFieldName); $associationMappingXml->addAttribute('field', $associationMapping->sourceFieldName);
$associationMappingXml->addAttribute('target-entity', $associationMapping->targetEntityName); $associationMappingXml->addAttribute('target-entity', $associationMapping->targetEntityName);
if (isset($associationMapping->mappedByFieldName)) { if (isset($associationMapping->mappedBy)) {
$associationMappingXml->addAttribute('mapped-by', $associationMapping->mappedByFieldName); $associationMappingXml->addAttribute('mapped-by', $associationMapping->mappedBy);
} }
if (isset($associationMapping->orphanRemoval)) { if (isset($associationMapping->orphanRemoval)) {
$associationMappingXml->addAttribute('orphan-removal', $associationMapping->orphanRemoval); $associationMappingXml->addAttribute('orphan-removal', $associationMapping->orphanRemoval);
......
...@@ -70,12 +70,12 @@ class YamlExporter extends AbstractExporter ...@@ -70,12 +70,12 @@ class YamlExporter extends AbstractExporter
$array['schema'] = $metadata->primaryTable['schema']; $array['schema'] = $metadata->primaryTable['schema'];
} }
$inheritanceType = $metadata->getInheritanceType(); $inheritanceType = $metadata->inheritanceType;
if ($inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) { if ($inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
$array['inheritanceType'] = $this->_getInheritanceTypeString($inheritanceType); $array['inheritanceType'] = $this->_getInheritanceTypeString($inheritanceType);
} }
if ($column = $metadata->getDiscriminatorColumn()) { if ($column = $metadata->discriminatorColumn) {
$array['discriminatorColumn'] = $column; $array['discriminatorColumn'] = $column;
} }
...@@ -158,7 +158,7 @@ class YamlExporter extends AbstractExporter ...@@ -158,7 +158,7 @@ class YamlExporter extends AbstractExporter
$newJoinColumns[$joinColumn['name']]['referencedColumnName'] = $joinColumn['referencedColumnName']; $newJoinColumns[$joinColumn['name']]['referencedColumnName'] = $joinColumn['referencedColumnName'];
} }
$oneToOneMappingArray = array( $oneToOneMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName, 'mappedBy' => $associationMapping->mappedBy,
'joinColumns' => $newJoinColumns, 'joinColumns' => $newJoinColumns,
'orphanRemoval' => $associationMapping->orphanRemoval, 'orphanRemoval' => $associationMapping->orphanRemoval,
); );
...@@ -167,7 +167,7 @@ class YamlExporter extends AbstractExporter ...@@ -167,7 +167,7 @@ class YamlExporter extends AbstractExporter
$array['oneToOne'][$name] = $associationMappingArray; $array['oneToOne'][$name] = $associationMappingArray;
} else if ($associationMapping instanceof OneToManyMapping) { } else if ($associationMapping instanceof OneToManyMapping) {
$oneToManyMappingArray = array( $oneToManyMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName, 'mappedBy' => $associationMapping->mappedBy,
'orphanRemoval' => $associationMapping->orphanRemoval, 'orphanRemoval' => $associationMapping->orphanRemoval,
); );
...@@ -175,7 +175,7 @@ class YamlExporter extends AbstractExporter ...@@ -175,7 +175,7 @@ class YamlExporter extends AbstractExporter
$array['oneToMany'][$name] = $associationMappingArray; $array['oneToMany'][$name] = $associationMappingArray;
} else if ($associationMapping instanceof ManyToManyMapping) { } else if ($associationMapping instanceof ManyToManyMapping) {
$manyToManyMappingArray = array( $manyToManyMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName, 'mappedBy' => $associationMapping->mappedBy,
'joinTable' => $associationMapping->joinTable, 'joinTable' => $associationMapping->joinTable,
); );
......
...@@ -213,7 +213,7 @@ class SchemaTool ...@@ -213,7 +213,7 @@ class SchemaTool
$processedClasses[$class->name] = true; $processedClasses[$class->name] = true;
if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) { if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) {
$seqDef = $class->getSequenceGeneratorDefinition(); $seqDef = $class->sequenceGeneratorDefinition;
if (!$schema->hasSequence($seqDef['sequenceName'])) { if (!$schema->hasSequence($seqDef['sequenceName'])) {
$schema->createSequence( $schema->createSequence(
...@@ -322,7 +322,7 @@ class SchemaTool ...@@ -322,7 +322,7 @@ class SchemaTool
} }
if ($table->hasColumn($columnName)) { if ($table->hasColumn($columnName)) {
// required in some inheritence scenarios // required in some inheritance scenarios
$table->changeColumn($columnName, $options); $table->changeColumn($columnName, $options);
} else { } else {
$table->addColumn($columnName, $columnType, $options); $table->addColumn($columnName, $columnType, $options);
...@@ -355,13 +355,13 @@ class SchemaTool ...@@ -355,13 +355,13 @@ class SchemaTool
if ($mapping->isOneToOne() && $mapping->isOwningSide) { if ($mapping->isOneToOne() && $mapping->isOwningSide) {
$primaryKeyColumns = $uniqueConstraints = array(); // unnecessary for this relation-type $primaryKeyColumns = $uniqueConstraints = array(); // unnecessary for this relation-type
$this->_gatherRelationJoinColumns($mapping->getJoinColumns(), $table, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints); $this->_gatherRelationJoinColumns($mapping->joinColumns, $table, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints);
} else if ($mapping->isOneToMany() && $mapping->isOwningSide) { } else if ($mapping->isOneToMany() && $mapping->isOwningSide) {
//... create join table, one-many through join table supported later //... create join table, one-many through join table supported later
throw ORMException::notSupported(); throw ORMException::notSupported();
} else if ($mapping->isManyToMany() && $mapping->isOwningSide) { } else if ($mapping->isManyToMany() && $mapping->isOwningSide) {
// create join table // create join table
$joinTable = $mapping->getJoinTable(); $joinTable = $mapping->joinTable;
$theJoinTable = $schema->createTable($mapping->getQuotedJoinTableName($this->_platform)); $theJoinTable = $schema->createTable($mapping->getQuotedJoinTableName($this->_platform));
......
...@@ -1177,7 +1177,8 @@ class UnitOfWork implements PropertyChangedListener ...@@ -1177,7 +1177,8 @@ class UnitOfWork implements PropertyChangedListener
* This method is internally called during save() cascades as it tracks * This method is internally called during save() cascades as it tracks
* the already visited entities to prevent infinite recursions. * the already visited entities to prevent infinite recursions.
* *
* NOTE: This method always considers entities with a manually assigned identifier as NEW. * NOTE: This method always considers entities that are not yet known to
* this UnitOfWork as NEW.
* *
* @param object $entity The entity to persist. * @param object $entity The entity to persist.
* @param array $visited The already visited entities. * @param array $visited The already visited entities.
...@@ -1405,7 +1406,7 @@ class UnitOfWork implements PropertyChangedListener ...@@ -1405,7 +1406,7 @@ class UnitOfWork implements PropertyChangedListener
} else { } else {
$prevClass->reflFields[$assocField]->getValue($prevManagedCopy)->unwrap()->add($managedCopy); $prevClass->reflFields[$assocField]->getValue($prevManagedCopy)->unwrap()->add($managedCopy);
if ($assoc->isOneToMany()) { if ($assoc->isOneToMany()) {
$class->reflFields[$assoc->mappedByFieldName]->setValue($managedCopy, $prevManagedCopy); $class->reflFields[$assoc->mappedBy]->setValue($managedCopy, $prevManagedCopy);
} }
} }
} }
...@@ -1627,6 +1628,7 @@ class UnitOfWork implements PropertyChangedListener ...@@ -1627,6 +1628,7 @@ class UnitOfWork implements PropertyChangedListener
if ( ! $assoc->isCascadeRemove) { if ( ! $assoc->isCascadeRemove) {
continue; continue;
} }
//TODO: If $entity instanceof Proxy => Initialize ?
$relatedEntities = $class->reflFields[$assoc->sourceFieldName]->getValue($entity); $relatedEntities = $class->reflFields[$assoc->sourceFieldName]->getValue($entity);
if ($relatedEntities instanceof Collection || is_array($relatedEntities)) { if ($relatedEntities instanceof Collection || is_array($relatedEntities)) {
// If its a PersistentCollection initialization is intended! No unwrap! // If its a PersistentCollection initialization is intended! No unwrap!
......
...@@ -297,10 +297,10 @@ class TableTest extends \PHPUnit_Framework_TestCase ...@@ -297,10 +297,10 @@ class TableTest extends \PHPUnit_Framework_TestCase
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException"); $this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
$table = new Table("foo"); $table = new Table("foo");
$table->addColumn("id", 'int'); $table->addColumn("id", 'integer');
$foreignTable = new Table("bar"); $foreignTable = new Table("bar");
$foreignTable->addColumn("id", 'int'); $foreignTable->addColumn("id", 'integer');
$table->addForeignKeyConstraint($foreignTable, array("foo"), array("id")); $table->addForeignKeyConstraint($foreignTable, array("foo"), array("id"));
} }
......
...@@ -17,12 +17,12 @@ class OneToOneMappingTest extends \Doctrine\Tests\OrmTestCase ...@@ -17,12 +17,12 @@ class OneToOneMappingTest extends \Doctrine\Tests\OrmTestCase
$oneToOneMapping = new \Doctrine\ORM\Mapping\OneToOneMapping($owningSideMapping); $oneToOneMapping = new \Doctrine\ORM\Mapping\OneToOneMapping($owningSideMapping);
$this->assertEquals(array('address_id' => 'id'), $oneToOneMapping->getSourceToTargetKeyColumns()); $this->assertEquals(array('address_id' => 'id'), $oneToOneMapping->sourceToTargetKeyColumns);
$this->assertEquals(array('id' => 'address_id'), $oneToOneMapping->getTargetToSourceKeyColumns()); $this->assertEquals(array('id' => 'address_id'), $oneToOneMapping->targetToSourceKeyColumns);
$this->assertEquals('Address', $oneToOneMapping->getTargetEntityName()); $this->assertEquals('Address', $oneToOneMapping->targetEntityName);
$this->assertEquals('Person', $oneToOneMapping->getSourceEntityName()); $this->assertEquals('Person', $oneToOneMapping->sourceEntityName);
$this->assertEquals('address', $oneToOneMapping->getSourceFieldName()); $this->assertEquals('address', $oneToOneMapping->sourceFieldName);
$this->assertTrue($oneToOneMapping->isOwningSide()); $this->assertTrue($oneToOneMapping->isOwningSide);
$inverseSideMapping = array( $inverseSideMapping = array(
'fieldName' => 'person', 'fieldName' => 'person',
...@@ -32,9 +32,9 @@ class OneToOneMappingTest extends \Doctrine\Tests\OrmTestCase ...@@ -32,9 +32,9 @@ class OneToOneMappingTest extends \Doctrine\Tests\OrmTestCase
); );
$oneToOneMapping = new \Doctrine\ORM\Mapping\OneToOneMapping($inverseSideMapping); $oneToOneMapping = new \Doctrine\ORM\Mapping\OneToOneMapping($inverseSideMapping);
$this->assertEquals('address', $oneToOneMapping->getMappedByFieldName()); $this->assertEquals('address', $oneToOneMapping->mappedBy);
$this->assertEquals('Address', $oneToOneMapping->getSourceEntityName()); $this->assertEquals('Address', $oneToOneMapping->sourceEntityName);
$this->assertEquals('Person', $oneToOneMapping->getTargetEntityName()); $this->assertEquals('Person', $oneToOneMapping->targetEntityName);
$this->assertTrue($oneToOneMapping->isInverseSide()); $this->assertTrue($oneToOneMapping->isInverseSide());
} }
} }
\ No newline at end of file
...@@ -30,7 +30,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase ...@@ -30,7 +30,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
public function testEntityTableNameAndInheritance($class) public function testEntityTableNameAndInheritance($class)
{ {
$this->assertEquals('cms_users', $class->getTableName()); $this->assertEquals('cms_users', $class->getTableName());
$this->assertEquals(ClassMetadata::INHERITANCE_TYPE_NONE, $class->getInheritanceType()); $this->assertEquals(ClassMetadata::INHERITANCE_TYPE_NONE, $class->inheritanceType);
return $class; return $class;
} }
...@@ -61,7 +61,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase ...@@ -61,7 +61,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
public function testIdentifier($class) public function testIdentifier($class)
{ {
$this->assertEquals(array('id'), $class->identifier); $this->assertEquals(array('id'), $class->identifier);
$this->assertEquals(ClassMetadata::GENERATOR_TYPE_AUTO, $class->getIdGeneratorType(), "ID-Generator is not ClassMetadata::GENERATOR_TYPE_AUTO"); $this->assertEquals(ClassMetadata::GENERATOR_TYPE_AUTO, $class->generatorType, "ID-Generator is not ClassMetadata::GENERATOR_TYPE_AUTO");
return $class; return $class;
} }
......
...@@ -40,13 +40,13 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase ...@@ -40,13 +40,13 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('UserParent', $cm->rootEntityName); $this->assertEquals('UserParent', $cm->rootEntityName);
$this->assertEquals(array('Doctrine\Tests\Models\CMS\One', 'Doctrine\Tests\Models\CMS\Two', 'Doctrine\Tests\Models\CMS\Three'), $cm->subClasses); $this->assertEquals(array('Doctrine\Tests\Models\CMS\One', 'Doctrine\Tests\Models\CMS\Two', 'Doctrine\Tests\Models\CMS\Three'), $cm->subClasses);
$this->assertEquals(array('UserParent'), $cm->parentClasses); $this->assertEquals(array('UserParent'), $cm->parentClasses);
$this->assertEquals('UserRepository', $cm->getCustomRepositoryClass()); $this->assertEquals('UserRepository', $cm->customRepositoryClassName);
$this->assertEquals(array('name' => 'disc', 'type' => 'integer', 'fieldName' => 'disc'), $cm->discriminatorColumn); $this->assertEquals(array('name' => 'disc', 'type' => 'integer', 'fieldName' => 'disc'), $cm->discriminatorColumn);
$this->assertTrue($cm->getAssociationMapping('phonenumbers') instanceof \Doctrine\ORM\Mapping\OneToOneMapping); $this->assertTrue($cm->getAssociationMapping('phonenumbers') instanceof \Doctrine\ORM\Mapping\OneToOneMapping);
$this->assertEquals(1, count($cm->associationMappings)); $this->assertEquals(1, count($cm->associationMappings));
$oneOneMapping = $cm->getAssociationMapping('phonenumbers'); $oneOneMapping = $cm->getAssociationMapping('phonenumbers');
$this->assertEquals('phonenumbers', $oneOneMapping->getSourceFieldName()); $this->assertEquals('phonenumbers', $oneOneMapping->sourceFieldName);
$this->assertEquals('Doctrine\Tests\Models\CMS\Bar', $oneOneMapping->getTargetEntityName()); $this->assertEquals('Doctrine\Tests\Models\CMS\Bar', $oneOneMapping->targetEntityName);
} }
public function testFieldIsNullable() public function testFieldIsNullable()
......
...@@ -205,7 +205,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase ...@@ -205,7 +205,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
if (is_null(self::$_metadataCacheImpl)) { if (is_null(self::$_metadataCacheImpl)) {
self::$_metadataCacheImpl = new \Doctrine\Common\Cache\ArrayCache; self::$_metadataCacheImpl = new \Doctrine\Common\Cache\ArrayCache;
} }
if (is_null(self::$_queryCacheImpl)) { if (is_null(self::$_queryCacheImpl)) {
self::$_queryCacheImpl = new \Doctrine\Common\Cache\ArrayCache; self::$_queryCacheImpl = new \Doctrine\Common\Cache\ArrayCache;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment