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
be implemented by using the @columnDefinition annotation (or the approriate XML and YAML equivalents).
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.
The "default" option for database column defaults has been removed. If desired, database column defaults can
be implemented by using the columnDefinition attribute of the @Column annotation (or the approriate XML and YAML equivalents).
Prefer PHP default values, if possible.
## Partial Objects
xxx
## XML Mapping Driver
The 'inheritance-type' attribute changed to take last bit of ClassMetadata constant names, i.e.
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
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
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;
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
* @todo Rename: APCCache
*/
class ApcCache extends AbstractCache
{
......
......@@ -76,31 +76,4 @@ class Configuration
{
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
*/
const FETCH_ASSOC = 2;
const FETCH_BOTH = 4;
const FETCH_COLUMN = 7;
//const FETCH_COLUMN = 7; Apparently not used.
const FETCH_NUM = 3;
const ATTR_AUTOCOMMIT = 0;
......
......@@ -7,6 +7,7 @@ namespace Doctrine\DBAL\Logging;
*
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @todo Rename: EchoSQLLogger
*/
class EchoSqlLogger implements SqlLogger
{
......
......@@ -7,6 +7,7 @@ namespace Doctrine\DBAL\Logging;
*
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @todo Rename: SQLLogger
*/
interface SqlLogger
{
......
......@@ -579,7 +579,7 @@ abstract class AbstractPlatform
*/
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.");
}
......
......@@ -32,6 +32,7 @@ use Doctrine\DBAL\DBALException;
* @author Roman Borschel <roman@code-factory.org>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @todo Rename: MsSQLPlatform
*/
class MsSqlPlatform extends AbstractPlatform
{
......
......@@ -32,6 +32,7 @@ use Doctrine\DBAL\DBALException,
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @todo Rename: MySQLPlatform
*/
class MySqlPlatform extends AbstractPlatform
{
......
......@@ -21,7 +21,8 @@
namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\Schema\TableDiff,
Doctrine\DBAL\Schema\Table;
/**
* PostgreSqlPlatform.
......@@ -30,6 +31,7 @@ use Doctrine\DBAL\Schema\TableDiff;
* @author Roman Borschel <roman@code-factory.org>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @todo Rename: PostgreSQLPlatform
*/
class PostgreSqlPlatform extends AbstractPlatform
{
......@@ -295,7 +297,6 @@ class PostgreSqlPlatform extends AbstractPlatform
}
/**
* getAdvancedForeignKeyOptions
* Return the FOREIGN KEY query section dealing with non-standard options
* as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
*
......
......@@ -30,6 +30,7 @@ use Doctrine\DBAL\DBALException;
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @todo Rename: SQLitePlatform
*/
class SqlitePlatform extends AbstractPlatform
{
......
......@@ -21,9 +21,9 @@
namespace Doctrine\DBAL\Schema;
use \Doctrine\DBAL\Types;
use \Doctrine\DBAL\DBALException;
use \Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* Base class for schema managers. Schema managers are used to inspect and/or
......
<?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;
......
<?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;
......@@ -33,7 +52,6 @@ abstract class Type
'object' => 'Doctrine\DBAL\Types\ObjectType',
'boolean' => 'Doctrine\DBAL\Types\BooleanType',
'integer' => 'Doctrine\DBAL\Types\IntegerType',
'int' => 'Doctrine\DBAL\Types\IntegerType',
'smallint' => 'Doctrine\DBAL\Types\SmallIntType',
'bigint' => 'Doctrine\DBAL\Types\BigIntType',
'string' => 'Doctrine\DBAL\Types\StringType',
......@@ -41,12 +59,11 @@ abstract class Type
'datetime' => 'Doctrine\DBAL\Types\DateTimeType',
'date' => 'Doctrine\DBAL\Types\DateType',
'time' => 'Doctrine\DBAL\Types\TimeType',
'decimal' => 'Doctrine\DBAL\Types\DecimalType',
'double' => 'Doctrine\DBAL\Types\DoubleType'
'decimal' => 'Doctrine\DBAL\Types\DecimalType'
);
/* 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
......@@ -125,7 +142,6 @@ abstract class Type
if ( ! isset(self::$_typesMap[$name])) {
throw DBALException::unknownColumnType($name);
}
self::$_typeObjects[$name] = new self::$_typesMap[$name]();
}
......@@ -136,8 +152,7 @@ abstract class Type
* Adds a custom type to the type map.
*
* @static
* @param string $name Name of the type. This should correspond to what
* getName() returns.
* @param string $name Name of the type. This should correspond to what getName() returns.
* @param string $className The class name of the custom type.
* @throws DBALException
*/
......
......@@ -472,6 +472,9 @@ abstract class AbstractQuery
{
// If there are still pending insertions in the UnitOfWork we need to flush
// 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()) {
$this->_em->flush();
}
......
......@@ -38,7 +38,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
public function __construct()
{
parent::__construct();
$this->_attributes = array_merge($this->_attributes, array(
'resultCacheImpl' => null,
'queryCacheImpl' => null,
......@@ -46,11 +45,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
'metadataDriverImpl' => null,
'proxyDir' => null,
'useCExtension' => false,
'namedQueries' => array(),
'namedNativeQueries' => array(),
'autoGenerateProxyClasses' => true,
'proxyNamespace' => null,
'entityNamespaces' => array()
'proxyNamespace' => null
));
}
......@@ -96,11 +92,21 @@ class Configuration extends \Doctrine\DBAL\Configuration
$this->_attributes['autoGenerateProxyClasses'] = $bool;
}
/**
* Gets the namespace where proxy classes reside.
*
* @return string
*/
public function getProxyNamespace()
{
return $this->_attributes['proxyNamespace'];
}
/**
* Sets the namespace where proxy classes reside.
*
* @param string $ns
*/
public function setProxyNamespace($ns)
{
$this->_attributes['proxyNamespace'] = $ns;
......@@ -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 $namespace
......@@ -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
* @return string
......@@ -138,11 +144,11 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getEntityNamespace($entityNamespaceAlias)
{
if (isset($this->_attributes['entityNamespaces'][$entityNamespaceAlias])) {
return trim($this->_attributes['entityNamespaces'][$entityNamespaceAlias], '\\');
if ( ! isset($this->_attributes['entityNamespaces'][$entityNamespaceAlias])) {
throw ORMException::unknownEntityNamespace($entityNamespaceAlias);
}
throw ORMException::unknownEntityNamespace($entityNamespaceAlias);
return trim($this->_attributes['entityNamespaces'][$entityNamespaceAlias], '\\');
}
/**
......@@ -273,6 +279,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getNamedQuery($name)
{
if ( ! isset($this->_attributes['namedQueries'][$name])) {
throw ORMException::namedQueryNotFound($name);
}
return $this->_attributes['namedQueries'][$name];
}
......@@ -297,6 +306,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getNamedNativeQuery($name)
{
if ( ! isset($this->_attributes['namedNativeQueries'][$name])) {
throw ORMException::namedNativeQueryNotFound($name);
}
return $this->_attributes['namedNativeQueries'][$name];
}
......@@ -319,4 +331,79 @@ class Configuration extends \Doctrine\DBAL\Configuration
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
......@@ -354,6 +354,9 @@ class EntityManager
* The entity will be entered into the database at or before transaction
* 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.
*/
public function persist($entity)
......@@ -456,7 +459,7 @@ class EntityManager
}
$metadata = $this->getClassMetadata($entityName);
$customRepositoryClassName = $metadata->getCustomRepositoryClass();
$customRepositoryClassName = $metadata->customRepositoryClassName;
if ($customRepositoryClassName !== null) {
$repository = new $customRepositoryClassName($this, $metadata);
......
......@@ -57,7 +57,7 @@ class EntityRepository
* @param EntityManager $em The EntityManager to use.
* @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->_em = $em;
......
......@@ -254,7 +254,7 @@ abstract class AbstractHydrator
$fieldName = $this->_rsm->fieldMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
$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];
} else {
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
......
......@@ -83,8 +83,8 @@ class ObjectHydrator extends AbstractHydrator
}
if ( ! $assoc->isManyToMany()) {
// Mark any non-collection opposite sides as fetched, too.
if ($assoc->mappedByFieldName) {
$this->_hints['fetched'][$className][$assoc->mappedByFieldName] = true;
if ($assoc->mappedBy) {
$this->_hints['fetched'][$className][$assoc->mappedBy] = true;
} else {
if (isset($class->inverseMappings[$sourceClassName][$assoc->sourceFieldName])) {
$inverseAssoc = $class->inverseMappings[$sourceClassName][$assoc->sourceFieldName];
......@@ -353,14 +353,14 @@ class ObjectHydrator extends AbstractHydrator
$targetClass->reflFields[$inverseAssoc->sourceFieldName]->setValue($element, $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
$targetClass->reflFields[$relationField]->setValue($element, $parentObject);
}
} else {
// For sure bidirectional, as there is no inverse side in unidirectional mappings
$targetClass->reflFields[$relation->mappedByFieldName]->setValue($element, $parentObject);
$this->_uow->setOriginalEntityProperty(spl_object_hash($element), $relation->mappedByFieldName, $parentObject);
$targetClass->reflFields[$relation->mappedBy]->setValue($element, $parentObject);
$this->_uow->setOriginalEntityProperty(spl_object_hash($element), $relation->mappedBy, $parentObject);
}
// Update result pointer
$this->_resultPointers[$dqlAlias] = $element;
......
......@@ -51,21 +51,55 @@ abstract class AssociationMapping
*/
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;
/**
* READ-ONLY: Whether the association cascades save() operations from the source entity
* to the target entity/entities.
*
* @var boolean
*/
public $isCascadePersist;
/**
* READ-ONLY: Whether the association cascades refresh() operations from the source entity
* to the target entity/entities.
*
* @var boolean
*/
public $isCascadeRefresh;
/**
* READ-ONLY: Whether the association cascades merge() operations from the source entity
* to the target entity/entities.
*
* @var boolean
*/
public $isCascadeMerge;
/**
* READ-ONLY: Whether the association cascades detach() operations from the source entity
* to the target entity/entities.
*
* @var boolean
*/
public $isCascadeDetach;
/**
* The fetch mode used for the association.
* READ-ONLY: The fetch mode used for the association.
*
* @var integer
*/
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.
*
* @var boolean
......@@ -73,14 +107,14 @@ abstract class AssociationMapping
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
*/
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).
*
* @var string
......@@ -88,7 +122,7 @@ abstract class AssociationMapping
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
* other entity/entities.
*
......@@ -97,22 +131,29 @@ abstract class AssociationMapping
public $sourceFieldName;
/**
* Identifies the field on the owning side that controls the mapping for the
* association. This is only set on the inverse side of an association.
* READ-ONLY: Identifies the field on the owning side of a bidirectional association that
* controls the mapping for the association. This is only set on the inverse side
* of an association.
*
* @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
*/
public $joinTable = array();
//protected $_joinTableInsertSql;
/**
* Initializes a new instance of a class derived from AssociationMapping.
*
......@@ -159,9 +200,12 @@ abstract class AssociationMapping
}
$this->joinTable = $mapping['joinTable'];
}
if (isset($mapping['inversedBy'])) {
$this->inversedBy = $mapping['inversedBy'];
}
} else {
$this->isOwningSide = false;
$this->mappedByFieldName = $mapping['mappedBy'];
$this->mappedBy = $mapping['mappedBy'];
}
// Optional attributes for both sides
......@@ -185,61 +229,6 @@ abstract class AssociationMapping
$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.
*
......@@ -260,16 +249,6 @@ abstract class AssociationMapping
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.
*
......@@ -280,58 +259,6 @@ abstract class AssociationMapping
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.
*
......@@ -397,7 +324,7 @@ abstract class AssociationMapping
/**
*
* @param $platform
* @return unknown_type
* @return string
*/
public function getQuotedJoinTableName($platform)
{
......
......@@ -207,6 +207,17 @@ class ClassMetadata extends ClassMetadataInfo
$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.
*
......@@ -236,20 +247,6 @@ class ClassMetadata extends ClassMetadataInfo
$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
* in an SQL statement.
......@@ -316,7 +313,7 @@ class ClassMetadata extends ClassMetadataInfo
'idGenerator', //TODO: Does not really need to be serialized. Could be moved to runtime.
'inheritanceType',
'inheritedAssociationFields',
'inverseMappings', //TODO: Remove!
'inverseMappings', //TODO: Remove! DDC-193
'isIdentifierComposite',
'isMappedSuperclass',
'isVersioned',
......
......@@ -143,10 +143,8 @@ class ClassMetadataFactory
}
}
$cacheKey = "$realClassName\$CLASSMETADATA";
if ($this->_cacheDriver) {
if (($cached = $this->_cacheDriver->fetch($cacheKey)) !== false) {
if (($cached = $this->_cacheDriver->fetch("$realClassName\$CLASSMETADATA")) !== false) {
$this->_loadedMetadata[$realClassName] = $cached;
} else {
foreach ($this->_loadMetadata($realClassName) as $loadedClassName) {
......@@ -208,6 +206,7 @@ class ClassMetadataFactory
$loaded = array();
// Collect parent classes, ignoring transient (not-mapped) classes.
//TODO: Evaluate whether we can use class_parents() here.
$parentClass = $name;
$parentClasses = array();
while ($parentClass = get_parent_class($parentClass)) {
......@@ -258,15 +257,15 @@ class ClassMetadataFactory
}
if ($parent && ! $parent->isMappedSuperclass) {
if ($parent->isIdGeneratorSequence()) {
$class->setSequenceGeneratorDefinition($parent->getSequenceGeneratorDefinition());
$class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
} else if ($parent->isIdGeneratorTable()) {
$class->getTableGeneratorDefinition($parent->getTableGeneratorDefinition());
$class->getTableGeneratorDefinition($parent->tableGeneratorDefinition);
}
if ($generatorType = $parent->generatorType) {
$class->setIdGeneratorType($generatorType);
}
if ($idGenerator = $parent->getIdGenerator()) {
$class->setIdGenerator($idGenerator);
if ($parent->idGenerator) {
$class->setIdGenerator($parent->idGenerator);
}
} else {
$this->_completeIdGeneratorMapping($class);
......@@ -374,7 +373,7 @@ class ClassMetadataFactory
break;
case ClassMetadata::GENERATOR_TYPE_SEQUENCE:
// If there is no sequence definition yet, create a default definition
$definition = $class->getSequenceGeneratorDefinition();
$definition = $class->sequenceGeneratorDefinition;
if ( ! $definition) {
$sequenceName = $class->getTableName() . '_' . $class->getSingleIdentifierColumnName() . '_seq';
$definition['sequenceName'] = $this->_targetPlatform->fixSchemaElementName($sequenceName);
......
......@@ -114,12 +114,12 @@ class ClassMetadataInfo
const CHANGETRACKING_NOTIFY = 3;
/**
* The name of the entity class.
* READ-ONLY: The name of the entity class.
*/
public $name;
/**
* The namespace the entity class is contained in.
* READ-ONLY: The namespace the entity class is contained in.
*
* @var string
* @todo Not really needed. Usage could be localized.
......@@ -127,7 +127,7 @@ class ClassMetadataInfo
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
* as $_entityName.
*
......@@ -144,28 +144,28 @@ class ClassMetadataInfo
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
*/
public $isMappedSuperclass = false;
/**
* The names of the parent classes (ancestors).
* READ-ONLY: The names of the parent classes (ancestors).
*
* @var array
*/
public $parentClasses = array();
/**
* The names of all subclasses.
* READ-ONLY: The names of all subclasses.
*
* @var 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.
*
* @var array
......@@ -173,21 +173,21 @@ class ClassMetadataInfo
public $identifier = array();
/**
* The inheritance mapping type used by the class.
* READ-ONLY: The inheritance mapping type used by the class.
*
* @var integer
*/
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
*/
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.
*
* The mapping definition array has the following values:
......@@ -236,7 +236,7 @@ class ClassMetadataInfo
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.
* This is the reverse lookup map of $_columnNames.
*
......@@ -245,7 +245,7 @@ class ClassMetadataInfo
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.
* This is the reverse lookup map of $_fieldNames.
*
......@@ -255,7 +255,7 @@ class ClassMetadataInfo
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
* where a discriminator column is used.</b>
......@@ -266,7 +266,7 @@ class ClassMetadataInfo
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
* where a discriminator column is used.</b>
......@@ -277,7 +277,7 @@ class ClassMetadataInfo
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.
*
* @var array
......@@ -285,7 +285,7 @@ class ClassMetadataInfo
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:
*
* name => <tableName>
......@@ -298,21 +298,21 @@ class ClassMetadataInfo
public $primaryTable;
/**
* The registered lifecycle callbacks for entities of this class.
* READ-ONLY: The registered lifecycle callbacks for entities of this class.
*
* @var 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
*/
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
* @todo Remove! See http://www.doctrine-project.org/jira/browse/DDC-193
......@@ -320,29 +320,38 @@ class ClassMetadataInfo
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
*/
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
*/
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.
*
* The definition has the following structure:
* <code>
* array(
* 'sequenceName' => 'name',
* 'allocationSize' => 20,
* 'initialValue' => 1
* )
* </code>
*
* @var array
*/
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.
*
* @var array
......@@ -350,14 +359,14 @@ class ClassMetadataInfo
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
*/
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
* of the classes that define the association.
*
......@@ -366,14 +375,15 @@ class ClassMetadataInfo
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
*/
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
*/
......@@ -391,16 +401,6 @@ class ClassMetadataInfo
$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.
*
......@@ -441,50 +441,6 @@ class ClassMetadataInfo
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).
*
......@@ -500,17 +456,6 @@ class ClassMetadataInfo
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.
*
......@@ -623,18 +568,6 @@ class ClassMetadataInfo
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.
* If no field name can be found the column name is returned.
......@@ -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.
*
......@@ -770,16 +692,6 @@ class ClassMetadataInfo
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.
*
......@@ -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.
*/
......@@ -979,16 +871,6 @@ class ClassMetadataInfo
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.
*
......@@ -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.
*
......@@ -1025,16 +897,6 @@ class ClassMetadataInfo
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.
* Assumes that the class names in the passed array are in the order:
......@@ -1118,17 +980,6 @@ class ClassMetadataInfo
$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.
*
......@@ -1247,7 +1098,7 @@ class ClassMetadataInfo
private function _registerMappingIfInverse(AssociationMapping $assoc)
{
if ($assoc->isInverseSide()) {
$this->inverseMappings[$assoc->targetEntityName][$assoc->mappedByFieldName] = $assoc;
$this->inverseMappings[$assoc->targetEntityName][$assoc->mappedBy] = $assoc;
}
}
......@@ -1311,17 +1162,6 @@ class ClassMetadataInfo
$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
* lifecycle callbacks and lifecycle listeners.
......@@ -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.
* Used for JOINED and SINGLE_TABLE inheritance mapping strategies.
......@@ -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.
*
......@@ -1505,18 +1316,6 @@ class ClassMetadataInfo
! $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.
*
......@@ -1527,36 +1326,6 @@ class ClassMetadataInfo
$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.
*
......@@ -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.
*
......@@ -1618,17 +1377,6 @@ class ClassMetadataInfo
$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
* versioned for optimistic locking.
......
......@@ -78,7 +78,6 @@ class AnnotationDriver implements Driver
public function __construct(AnnotationReader $reader, $paths = null)
{
$this->_reader = $reader;
if ($paths) {
$this->addPaths((array) $paths);
}
......@@ -292,6 +291,7 @@ class AnnotationDriver implements Driver
$mapping['targetEntity'] = $oneToOneAnnot->targetEntity;
$mapping['joinColumns'] = $joinColumns;
$mapping['mappedBy'] = $oneToOneAnnot->mappedBy;
$mapping['inversedBy'] = $oneToOneAnnot->inversedBy;
$mapping['cascade'] = $oneToOneAnnot->cascade;
$mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $oneToOneAnnot->fetch);
......@@ -311,6 +311,7 @@ class AnnotationDriver implements Driver
} else if ($manyToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) {
$mapping['joinColumns'] = $joinColumns;
$mapping['cascade'] = $manyToOneAnnot->cascade;
$mapping['inversedBy'] = $manyToOneAnnot->inversedBy;
$mapping['targetEntity'] = $manyToOneAnnot->targetEntity;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $manyToOneAnnot->fetch);
$metadata->mapManyToOne($mapping);
......@@ -351,6 +352,7 @@ class AnnotationDriver implements Driver
$mapping['joinTable'] = $joinTable;
$mapping['targetEntity'] = $manyToManyAnnot->targetEntity;
$mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
$mapping['inversedBy'] = $manyToManyAnnot->inversedBy;
$mapping['cascade'] = $manyToManyAnnot->cascade;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $manyToManyAnnot->fetch);
......@@ -362,7 +364,7 @@ class AnnotationDriver implements Driver
}
}
// Evaluate HasLifecycleCallbacks annotation
// Evaluate @HasLifecycleCallbacks annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) {
foreach ($class->getMethods() as $method) {
if ($method->isPublic()) {
......
......@@ -70,9 +70,9 @@ final class Column extends Annotation {
final class OneToOne extends Annotation {
public $targetEntity;
public $mappedBy;
public $inversedBy;
public $cascade;
public $fetch = 'LAZY';
public $optional;
public $orphanRemoval = false;
}
final class OneToMany extends Annotation {
......@@ -86,11 +86,12 @@ final class ManyToOne extends Annotation {
public $targetEntity;
public $cascade;
public $fetch = 'LAZY';
public $optional;
public $inversedBy;
}
final class ManyToMany extends Annotation {
public $targetEntity;
public $mappedBy;
public $inversedBy;
public $cascade;
public $fetch = 'LAZY';
}
......
......@@ -28,7 +28,7 @@ namespace Doctrine\ORM\Mapping;
* <b>IMPORTANT NOTE:</b>
*
* 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
* get the whole class name, namespace inclusive, prepended to every property in
* the serialized representation).
......@@ -43,17 +43,17 @@ namespace Doctrine\ORM\Mapping;
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();
/**
* 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();
/**
* List of aggregated column names on the join table.
* READ-ONLY: List of aggregated column names on the join table.
*/
public $joinTableColumns = array();
......@@ -61,23 +61,13 @@ class ManyToManyMapping extends AssociationMapping
//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
*
* @var array
*/
public $orderBy = null;
/**
* Initializes a new ManyToManyMapping.
*
* @param array $mapping The mapping definition.
*/
public function __construct(array $mapping)
{
parent::__construct($mapping);
}
public $orderBy;
/**
* Validates and completes the mapping.
......@@ -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.
* The data of $sourceEntity are used to restrict the collection
......@@ -186,7 +160,7 @@ class ManyToManyMapping extends AssociationMapping
}
}
} 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
foreach ($owningAssoc->relationToTargetKeyColumns as $relationKeyColumn => $sourceKeyColumn) {
// getting id
......
......@@ -32,7 +32,7 @@ namespace Doctrine\ORM\Mapping;
* <b>IMPORTANT NOTE:</b>
*
* 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
* get the whole class name, namespace inclusive, prepended to every property in
* the serialized representation).
......@@ -46,26 +46,21 @@ namespace Doctrine\ORM\Mapping;
*/
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;
/** FUTURE: The key column mapping, if any. The key column holds the keys of the Collection. */
//public $keyColumn;
/**
* Order this collection by the given SQL snippet.
* READ-ONLY: Order this collection by the given SQL snippet.
*/
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.
*
......@@ -82,6 +77,7 @@ class OneToManyMapping extends AssociationMapping
throw MappingException::oneToManyRequiresMappedBy($mapping['fieldName']);
}
//TODO: if orphanRemoval, cascade=remove is implicit!
$this->orphanRemoval = isset($mapping['orphanRemoval']) ?
(bool) $mapping['orphanRemoval'] : false;
......@@ -127,7 +123,7 @@ class OneToManyMapping extends AssociationMapping
$persister = $em->getUnitOfWork()->getEntityPersister($this->targetEntityName);
// a one-to-many is always inverse (does not have foreign key)
$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
foreach ($owningAssoc->targetToSourceKeyColumns as $sourceKeyColumn => $targetKeyColumn) {
// getting id
......
......@@ -28,7 +28,7 @@ namespace Doctrine\ORM\Mapping;
* <b>IMPORTANT NOTE:</b>
*
* 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
* get the whole class name, namespace inclusive, prepended to every property in
* the serialized representation).
......@@ -43,59 +43,41 @@ namespace Doctrine\ORM\Mapping;
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).
* Reverse mapping of _targetToSourceKeyColumns.
*/
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).
* Reverse mapping of _sourceToTargetKeyColumns.
*/
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
*/
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
*/
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.
*
* @var array
*/
public $joinColumnFieldNames = array();
/**
* Creates a new OneToOneMapping.
*
* @param array $mapping The mapping info.
*/
public function __construct(array $mapping)
{
parent::__construct($mapping);
}
/**
* {@inheritdoc}
*
......@@ -128,58 +110,13 @@ class OneToOneMapping extends AssociationMapping
$this->targetToSourceKeyColumns = array_flip($this->sourceToTargetKeyColumns);
}
$this->isOptional = isset($mapping['optional']) ?
(bool) $mapping['optional'] : true;
//TODO: if orphanRemoval, cascade=remove is implicit!
$this->orphanRemoval = isset($mapping['orphanRemoval']) ?
(bool) $mapping['orphanRemoval'] : false;
/*if ($this->isOptional) {
$this->fetchMode = self::FETCH_EAGER;
}*/
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}
*
......@@ -233,7 +170,7 @@ class OneToOneMapping extends AssociationMapping
} else {
$conditions = array();
$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
foreach ($owningAssoc->targetToSourceKeyColumns as $sourceKeyColumn => $targetKeyColumn) {
if (isset($sourceClass->fieldNames[$sourceKeyColumn])) {
......@@ -248,40 +185,10 @@ class OneToOneMapping extends AssociationMapping
$targetEntity = $em->getUnitOfWork()->getEntityPersister($this->targetEntityName)->load($conditions, $targetEntity, $this);
if ($targetEntity !== null) {
$targetClass->setFieldValue($targetEntity, $this->mappedByFieldName, $sourceEntity);
$targetClass->setFieldValue($targetEntity, $this->mappedBy, $sourceEntity);
}
}
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
$this->_association = $assoc;
// Check for bidirectionality
//$this->_backRefFieldName = $assoc->inversedBy ?: $assoc->mappedBy;
if ( ! $assoc->isOwningSide) {
// For sure bi-directional
$this->_backRefFieldName = $assoc->mappedByFieldName;
$this->_backRefFieldName = $assoc->mappedBy;
} else {
if (isset($this->_typeClass->inverseMappings[$assoc->sourceEntityName][$assoc->sourceFieldName])) {
// Bi-directional
......@@ -523,9 +524,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect
public function map(Closure $func)
{
$this->_initialize();
$result = $this->_coll->map($func);
$this->_changed();
return $result;
return $this->_coll->map($func);
}
/**
......
......@@ -39,8 +39,8 @@ class ManyToManyPersister extends AbstractCollectionPersister
protected function _getDeleteRowSql(PersistentCollection $coll)
{
$mapping = $coll->getMapping();
$joinTable = $mapping->getJoinTable();
$columns = $mapping->getJoinTableColumnNames();
$joinTable = $mapping->joinTable;
$columns = $mapping->joinTableColumns;
return 'DELETE FROM ' . $joinTable['name'] . ' WHERE ' . implode(' = ? AND ', $columns) . ' = ?';
}
......@@ -74,7 +74,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
protected function _getInsertRowSql(PersistentCollection $coll)
{
$mapping = $coll->getMapping();
$joinTable = $mapping->getJoinTable();
$joinTable = $mapping->joinTable;
$columns = $mapping->joinTableColumns;
return 'INSERT INTO ' . $joinTable['name'] . ' (' . implode(', ', $columns) . ')'
. ' VALUES (' . implode(', ', array_fill(0, count($columns), '?')) . ')';
......@@ -141,7 +141,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
protected function _getDeleteSql(PersistentCollection $coll)
{
$mapping = $coll->getMapping();
$joinTable = $mapping->getJoinTable();
$joinTable = $mapping->joinTable;
$whereClause = '';
foreach ($mapping->relationToSourceKeyColumns as $relationColumn => $srcColumn) {
if ($whereClause !== '') $whereClause .= ' AND ';
......
......@@ -32,8 +32,7 @@ use Doctrine\ORM\PersistentCollection;
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @todo Complete implementation when the support for uni-directional one-to-many mappings
* on a foreign key gets added.
* @todo Remove
*/
class OneToManyPersister extends AbstractCollectionPersister
{
......@@ -51,10 +50,10 @@ class OneToManyPersister extends AbstractCollectionPersister
$targetClass = $this->_em->getClassMetadata($mapping->getTargetEntityName());
$table = $targetClass->getTableName();
$ownerMapping = $targetClass->getAssociationMapping($mapping->getMappedByFieldName());
$ownerMapping = $targetClass->getAssociationMapping($mapping->mappedBy);
$setClause = '';
foreach ($ownerMapping->getSourceToTargetKeyColumns() as $sourceCol => $targetCol) {
foreach ($ownerMapping->sourceToTargetKeyColumns as $sourceCol => $targetCol) {
if ($setClause != '') $setClause .= ', ';
$setClause .= "$sourceCol = NULL";
}
......
......@@ -573,7 +573,7 @@ class StandardEntityPersister
*/
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);
......@@ -782,7 +782,7 @@ class StandardEntityPersister
$owningAssoc = $manyToMany;
$joinClauses = $manyToMany->relationToTargetKeyColumns;
} else {
$owningAssoc = $this->_em->getClassMetadata($manyToMany->targetEntityName)->associationMappings[$manyToMany->mappedByFieldName];
$owningAssoc = $this->_em->getClassMetadata($manyToMany->targetEntityName)->associationMappings[$manyToMany->mappedBy];
$joinClauses = $owningAssoc->relationToSourceKeyColumns;
}
......
......@@ -55,7 +55,7 @@ class SizeFunction extends FunctionNode
if ($assoc->isOneToMany()) {
$targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc->targetEntityName);
$targetAssoc = $targetClass->associationMappings[$assoc->mappedByFieldName];
$targetAssoc = $targetClass->associationMappings[$assoc->mappedBy];
$targetTableAlias = $sqlWalker->getSqlTableAlias($targetClass->primaryTable['name']);
$sourceTableAlias = $sqlWalker->getSqlTableAlias($qComp['metadata']->primaryTable['name'], $dqlAlias);
......
......@@ -53,9 +53,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
$conn = $em->getConnection();
$platform = $conn->getDatabasePlatform();
$primaryClass = $sqlWalker->getEntityManager()->getClassMetadata(
$AST->deleteClause->abstractSchemaName
);
$primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName);
$primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable;
$rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
......@@ -96,7 +94,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
);
}
$this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' ('
. $conn->getDatabasePlatform()->getColumnDeclarationListSQL($columnDefinitions)
. $platform->getColumnDeclarationListSQL($columnDefinitions)
. ', PRIMARY KEY(' . $idColumnList . '))';
$this->_dropTempTableSql = 'DROP TABLE ' . $tempTable;
}
......
......@@ -38,7 +38,7 @@ use Doctrine\ORM\Query;
*/
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(
'concat' => 'Doctrine\ORM\Query\AST\Functions\ConcatFunction',
'substring' => 'Doctrine\ORM\Query\AST\Functions\SubstringFunction',
......@@ -47,7 +47,7 @@ class Parser
'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(
'length' => 'Doctrine\ORM\Query\AST\Functions\LengthFunction',
'locate' => 'Doctrine\ORM\Query\AST\Functions\LocateFunction',
......@@ -57,7 +57,7 @@ class Parser
'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(
'current_date' => 'Doctrine\ORM\Query\AST\Functions\CurrentDateFunction',
'current_time' => 'Doctrine\ORM\Query\AST\Functions\CurrentTimeFunction',
......@@ -193,39 +193,6 @@ class Parser
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.
*
......@@ -358,7 +325,7 @@ class Parser
$message .= "'{$token['value']}'";
}
throw \Doctrine\ORM\Query\QueryException::syntaxError($message);
throw QueryException::syntaxError($message);
}
/**
......@@ -428,39 +395,6 @@ class Parser
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.
*
......@@ -2624,17 +2558,27 @@ class Parser
*/
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();
} else if ($this->_isNumericFunction($funcName)) {
} else if ($config->getCustomNumericFunction($funcName) !== null) {
return $this->FunctionsReturningNumerics();
} else if ($this->_isDatetimeFunction($funcName)) {
} else if ($config->getCustomDatetimeFunction($funcName) !== null) {
return $this->FunctionsReturningDatetime();
}
$this->syntaxError('Known function.');
$this->syntaxError('Known function.', $funcName);
}
/**
......@@ -2681,6 +2625,7 @@ class Parser
{
$funcNameLower = strtolower($this->_lexer->lookahead['value']);
$funcClass = self::$_STRING_FUNCTIONS[$funcNameLower];
//$funcClass = $this->_em->getConfiguration()->getDQLStringFunctionClassName($funcNameLower);
$function = new $funcClass($funcNameLower);
$function->parse($this);
......
......@@ -696,7 +696,7 @@ class SqlWalker implements TreeWalker
// Ensure we got the owning side, since it has all mapping info
if ( ! $relation->isOwningSide) {
$assoc = $targetClass->associationMappings[$relation->mappedByFieldName];
$assoc = $targetClass->associationMappings[$relation->mappedBy];
} else {
$assoc = $relation;
}
......@@ -728,7 +728,7 @@ class SqlWalker implements TreeWalker
}
} else if ($assoc->isManyToMany()) {
// Join relation table
$joinTable = $assoc->getJoinTable();
$joinTable = $assoc->joinTable;
$joinTableAlias = $this->getSqlTableAlias($joinTable['name'], $joinedDqlAlias);
$sql .= $assoc->getQuotedJoinTableName($this->_platform) . ' ' . $joinTableAlias . ' ON ';
......@@ -1304,7 +1304,7 @@ class SqlWalker implements TreeWalker
$sql .= $targetClass->getQuotedTableName($this->_platform)
. ' ' . $targetTableAlias . ' WHERE ';
$owningAssoc = $targetClass->associationMappings[$assoc->mappedByFieldName];
$owningAssoc = $targetClass->associationMappings[$assoc->mappedBy];
$first = true;
......@@ -1329,7 +1329,7 @@ class SqlWalker implements TreeWalker
} else { // many-to-many
$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;
// SQL table aliases
......
......@@ -415,8 +415,8 @@ class AnnotationExporter extends AbstractExporter
if (isset($associationMapping->targetEntityName)) {
$typeOptions[] = 'targetEntity="' . $associationMapping->targetEntityName . '"';
}
if (isset($associationMapping->mappedByFieldName)) {
$typeOptions[] = 'mappedBy="' . $associationMapping->mappedByFieldName . '"';
if (isset($associationMapping->mappedBy)) {
$typeOptions[] = 'mappedBy="' . $associationMapping->mappedBy . '"';
}
if ($associationMapping->hasCascades()) {
$cascades = array();
......
......@@ -104,7 +104,7 @@ class PhpExporter extends AbstractExporter
if ($associationMapping instanceof \Doctrine\ORM\Mapping\OneToOneMapping) {
$method = 'mapOneToOne';
$oneToOneMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName,
'mappedBy' => $associationMapping->mappedBy,
'joinColumns' => $associationMapping->joinColumns,
'orphanRemoval' => $associationMapping->orphanRemoval,
);
......@@ -113,7 +113,7 @@ class PhpExporter extends AbstractExporter
} else if ($associationMapping instanceof \Doctrine\ORM\Mapping\OneToManyMapping) {
$method = 'mapOneToMany';
$oneToManyMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName,
'mappedBy' => $associationMapping->mappedBy,
'orphanRemoval' => $associationMapping->orphanRemoval,
);
......@@ -121,7 +121,7 @@ class PhpExporter extends AbstractExporter
} else if ($associationMapping instanceof \Doctrine\ORM\Mapping\ManyToManyMapping) {
$method = 'mapManyToMany';
$manyToManyMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName,
'mappedBy' => $associationMapping->mappedBy,
'joinTable' => $associationMapping->joinTable,
);
......
......@@ -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;
}
......@@ -190,8 +190,8 @@ class XmlExporter extends AbstractExporter
$associationMappingXml->addAttribute('field', $associationMapping->sourceFieldName);
$associationMappingXml->addAttribute('target-entity', $associationMapping->targetEntityName);
if (isset($associationMapping->mappedByFieldName)) {
$associationMappingXml->addAttribute('mapped-by', $associationMapping->mappedByFieldName);
if (isset($associationMapping->mappedBy)) {
$associationMappingXml->addAttribute('mapped-by', $associationMapping->mappedBy);
}
if (isset($associationMapping->orphanRemoval)) {
$associationMappingXml->addAttribute('orphan-removal', $associationMapping->orphanRemoval);
......
......@@ -70,12 +70,12 @@ class YamlExporter extends AbstractExporter
$array['schema'] = $metadata->primaryTable['schema'];
}
$inheritanceType = $metadata->getInheritanceType();
$inheritanceType = $metadata->inheritanceType;
if ($inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
$array['inheritanceType'] = $this->_getInheritanceTypeString($inheritanceType);
}
if ($column = $metadata->getDiscriminatorColumn()) {
if ($column = $metadata->discriminatorColumn) {
$array['discriminatorColumn'] = $column;
}
......@@ -158,7 +158,7 @@ class YamlExporter extends AbstractExporter
$newJoinColumns[$joinColumn['name']]['referencedColumnName'] = $joinColumn['referencedColumnName'];
}
$oneToOneMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName,
'mappedBy' => $associationMapping->mappedBy,
'joinColumns' => $newJoinColumns,
'orphanRemoval' => $associationMapping->orphanRemoval,
);
......@@ -167,7 +167,7 @@ class YamlExporter extends AbstractExporter
$array['oneToOne'][$name] = $associationMappingArray;
} else if ($associationMapping instanceof OneToManyMapping) {
$oneToManyMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName,
'mappedBy' => $associationMapping->mappedBy,
'orphanRemoval' => $associationMapping->orphanRemoval,
);
......@@ -175,7 +175,7 @@ class YamlExporter extends AbstractExporter
$array['oneToMany'][$name] = $associationMappingArray;
} else if ($associationMapping instanceof ManyToManyMapping) {
$manyToManyMappingArray = array(
'mappedBy' => $associationMapping->mappedByFieldName,
'mappedBy' => $associationMapping->mappedBy,
'joinTable' => $associationMapping->joinTable,
);
......
......@@ -213,7 +213,7 @@ class SchemaTool
$processedClasses[$class->name] = true;
if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) {
$seqDef = $class->getSequenceGeneratorDefinition();
$seqDef = $class->sequenceGeneratorDefinition;
if (!$schema->hasSequence($seqDef['sequenceName'])) {
$schema->createSequence(
......@@ -322,7 +322,7 @@ class SchemaTool
}
if ($table->hasColumn($columnName)) {
// required in some inheritence scenarios
// required in some inheritance scenarios
$table->changeColumn($columnName, $options);
} else {
$table->addColumn($columnName, $columnType, $options);
......@@ -355,13 +355,13 @@ class SchemaTool
if ($mapping->isOneToOne() && $mapping->isOwningSide) {
$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) {
//... create join table, one-many through join table supported later
throw ORMException::notSupported();
} else if ($mapping->isManyToMany() && $mapping->isOwningSide) {
// create join table
$joinTable = $mapping->getJoinTable();
$joinTable = $mapping->joinTable;
$theJoinTable = $schema->createTable($mapping->getQuotedJoinTableName($this->_platform));
......
......@@ -1177,7 +1177,8 @@ class UnitOfWork implements PropertyChangedListener
* This method is internally called during save() cascades as it tracks
* 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 array $visited The already visited entities.
......@@ -1405,7 +1406,7 @@ class UnitOfWork implements PropertyChangedListener
} else {
$prevClass->reflFields[$assocField]->getValue($prevManagedCopy)->unwrap()->add($managedCopy);
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
if ( ! $assoc->isCascadeRemove) {
continue;
}
//TODO: If $entity instanceof Proxy => Initialize ?
$relatedEntities = $class->reflFields[$assoc->sourceFieldName]->getValue($entity);
if ($relatedEntities instanceof Collection || is_array($relatedEntities)) {
// If its a PersistentCollection initialization is intended! No unwrap!
......
......@@ -297,10 +297,10 @@ class TableTest extends \PHPUnit_Framework_TestCase
$this->setExpectedException("Doctrine\DBAL\Schema\SchemaException");
$table = new Table("foo");
$table->addColumn("id", 'int');
$table->addColumn("id", 'integer');
$foreignTable = new Table("bar");
$foreignTable->addColumn("id", 'int');
$foreignTable->addColumn("id", 'integer');
$table->addForeignKeyConstraint($foreignTable, array("foo"), array("id"));
}
......
......@@ -17,12 +17,12 @@ class OneToOneMappingTest extends \Doctrine\Tests\OrmTestCase
$oneToOneMapping = new \Doctrine\ORM\Mapping\OneToOneMapping($owningSideMapping);
$this->assertEquals(array('address_id' => 'id'), $oneToOneMapping->getSourceToTargetKeyColumns());
$this->assertEquals(array('id' => 'address_id'), $oneToOneMapping->getTargetToSourceKeyColumns());
$this->assertEquals('Address', $oneToOneMapping->getTargetEntityName());
$this->assertEquals('Person', $oneToOneMapping->getSourceEntityName());
$this->assertEquals('address', $oneToOneMapping->getSourceFieldName());
$this->assertTrue($oneToOneMapping->isOwningSide());
$this->assertEquals(array('address_id' => 'id'), $oneToOneMapping->sourceToTargetKeyColumns);
$this->assertEquals(array('id' => 'address_id'), $oneToOneMapping->targetToSourceKeyColumns);
$this->assertEquals('Address', $oneToOneMapping->targetEntityName);
$this->assertEquals('Person', $oneToOneMapping->sourceEntityName);
$this->assertEquals('address', $oneToOneMapping->sourceFieldName);
$this->assertTrue($oneToOneMapping->isOwningSide);
$inverseSideMapping = array(
'fieldName' => 'person',
......@@ -32,9 +32,9 @@ class OneToOneMappingTest extends \Doctrine\Tests\OrmTestCase
);
$oneToOneMapping = new \Doctrine\ORM\Mapping\OneToOneMapping($inverseSideMapping);
$this->assertEquals('address', $oneToOneMapping->getMappedByFieldName());
$this->assertEquals('Address', $oneToOneMapping->getSourceEntityName());
$this->assertEquals('Person', $oneToOneMapping->getTargetEntityName());
$this->assertEquals('address', $oneToOneMapping->mappedBy);
$this->assertEquals('Address', $oneToOneMapping->sourceEntityName);
$this->assertEquals('Person', $oneToOneMapping->targetEntityName);
$this->assertTrue($oneToOneMapping->isInverseSide());
}
}
\ No newline at end of file
......@@ -30,7 +30,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
public function testEntityTableNameAndInheritance($class)
{
$this->assertEquals('cms_users', $class->getTableName());
$this->assertEquals(ClassMetadata::INHERITANCE_TYPE_NONE, $class->getInheritanceType());
$this->assertEquals(ClassMetadata::INHERITANCE_TYPE_NONE, $class->inheritanceType);
return $class;
}
......@@ -61,7 +61,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
public function testIdentifier($class)
{
$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;
}
......
......@@ -40,13 +40,13 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$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('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->assertTrue($cm->getAssociationMapping('phonenumbers') instanceof \Doctrine\ORM\Mapping\OneToOneMapping);
$this->assertEquals(1, count($cm->associationMappings));
$oneOneMapping = $cm->getAssociationMapping('phonenumbers');
$this->assertEquals('phonenumbers', $oneOneMapping->getSourceFieldName());
$this->assertEquals('Doctrine\Tests\Models\CMS\Bar', $oneOneMapping->getTargetEntityName());
$this->assertEquals('phonenumbers', $oneOneMapping->sourceFieldName);
$this->assertEquals('Doctrine\Tests\Models\CMS\Bar', $oneOneMapping->targetEntityName);
}
public function testFieldIsNullable()
......
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