Merge doctrine/master
This commit is contained in:
commit
59e9d55077
@ -1,7 +1,8 @@
|
||||
# Doctrine 2 ORM
|
||||
|
||||
Master: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=master)](http://travis-ci.org/doctrine/doctrine2)
|
||||
2.1.x: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.1.x)](http://travis-ci.org/doctrine/doctrine2)
|
||||
2.2: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.2)](http://travis-ci.org/doctrine/doctrine2)
|
||||
2.1: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.1.x)](http://travis-ci.org/doctrine/doctrine2)
|
||||
|
||||
Doctrine 2 is an object-relational mapper (ORM) for PHP 5.3.2+ that provides transparent persistence
|
||||
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
|
||||
|
@ -2,8 +2,8 @@
|
||||
project.name=DoctrineORM
|
||||
|
||||
# Dependency minimum versions
|
||||
dependencies.common=2.1.0
|
||||
dependencies.dbal=2.1.0
|
||||
dependencies.common=2.2.0beta1
|
||||
dependencies.dbal=2.2.0beta1
|
||||
dependencies.sfconsole=2.0.0
|
||||
|
||||
# Version class and file
|
||||
|
@ -94,8 +94,8 @@
|
||||
<pear minimum_version="1.6.0" recommended_version="1.6.1" />
|
||||
<package name="DoctrineCommon" channel="pear.doctrine-project.org" minimum_version="${dependencies.common}" />
|
||||
<package name="DoctrineDBAL" channel="pear.doctrine-project.org" minimum_version="${dependencies.dbal}" />
|
||||
<package name="Console" channel="pear.symfony.org" minimum_version="2.0.0" />
|
||||
<package name="Yaml" channel="pear.symfony.org" minimum_version="2.0.0" />
|
||||
<package name="Console" channel="pear.symfony.com" minimum_version="2.0.0" />
|
||||
<package name="Yaml" channel="pear.symfony.com" minimum_version="2.0.0" />
|
||||
</dependencies>
|
||||
<dirroles key="bin">script</dirroles>
|
||||
<ignore>Doctrine/Common/</ignore>
|
||||
|
@ -605,7 +605,7 @@ abstract class AbstractQuery
|
||||
|
||||
/**
|
||||
* Set the result cache id to use to store the result set cache entry.
|
||||
* If this is not explicitely set by the developer then a hash is automatically
|
||||
* If this is not explicitly set by the developer then a hash is automatically
|
||||
* generated for you.
|
||||
*
|
||||
* @param string $id
|
||||
|
@ -24,7 +24,9 @@ use Doctrine\Common\Cache\Cache,
|
||||
Doctrine\Common\Annotations\AnnotationRegistry,
|
||||
Doctrine\Common\Annotations\AnnotationReader,
|
||||
Doctrine\ORM\Mapping\Driver\Driver,
|
||||
Doctrine\ORM\Mapping\Driver\AnnotationDriver;
|
||||
Doctrine\ORM\Mapping\Driver\AnnotationDriver,
|
||||
Doctrine\ORM\Mapping\NamingStrategy,
|
||||
Doctrine\ORM\Mapping\DefaultNamingStrategy;
|
||||
|
||||
/**
|
||||
* Configuration container for all configuration options of Doctrine.
|
||||
@ -548,4 +550,29 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
return isset($this->_attributes['defaultRepositoryClassName']) ?
|
||||
$this->_attributes['defaultRepositoryClassName'] : 'Doctrine\ORM\EntityRepository';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set naming strategy.
|
||||
*
|
||||
* @since 2.3
|
||||
* @param NamingStrategy $namingStrategy
|
||||
*/
|
||||
public function setNamingStrategy(NamingStrategy $namingStrategy)
|
||||
{
|
||||
$this->_attributes['namingStrategy'] = $namingStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get naming strategy..
|
||||
*
|
||||
* @since 2.3
|
||||
* @return NamingStrategy
|
||||
*/
|
||||
public function getNamingStrategy()
|
||||
{
|
||||
if (!isset($this->_attributes['namingStrategy'])) {
|
||||
$this->_attributes['namingStrategy'] = new DefaultNamingStrategy();
|
||||
}
|
||||
return $this->_attributes['namingStrategy'];
|
||||
}
|
||||
}
|
||||
|
@ -488,7 +488,7 @@ class EntityManager implements ObjectManager
|
||||
public function persist($entity)
|
||||
{
|
||||
if ( ! is_object($entity)) {
|
||||
throw new \InvalidArgumentException(gettype($entity));
|
||||
throw ORMInvalidArgumentException::invalidObject('EntityManager#persist()' , $entity);
|
||||
}
|
||||
|
||||
$this->errorIfClosed();
|
||||
@ -507,7 +507,7 @@ class EntityManager implements ObjectManager
|
||||
public function remove($entity)
|
||||
{
|
||||
if ( ! is_object($entity)) {
|
||||
throw new \InvalidArgumentException(gettype($entity));
|
||||
throw ORMInvalidArgumentException::invalidObject('EntityManager#remove()' , $entity);
|
||||
}
|
||||
|
||||
$this->errorIfClosed();
|
||||
@ -524,7 +524,7 @@ class EntityManager implements ObjectManager
|
||||
public function refresh($entity)
|
||||
{
|
||||
if ( ! is_object($entity)) {
|
||||
throw new \InvalidArgumentException(gettype($entity));
|
||||
throw ORMInvalidArgumentException::invalidObject('EntityManager#refresh()' , $entity);
|
||||
}
|
||||
|
||||
$this->errorIfClosed();
|
||||
@ -544,7 +544,7 @@ class EntityManager implements ObjectManager
|
||||
public function detach($entity)
|
||||
{
|
||||
if ( ! is_object($entity)) {
|
||||
throw new \InvalidArgumentException(gettype($entity));
|
||||
throw ORMInvalidArgumentException::invalidObject('EntityManager#detach()' , $entity);
|
||||
}
|
||||
|
||||
$this->unitOfWork->detach($entity);
|
||||
@ -561,7 +561,7 @@ class EntityManager implements ObjectManager
|
||||
public function merge($entity)
|
||||
{
|
||||
if ( ! is_object($entity)) {
|
||||
throw new \InvalidArgumentException(gettype($entity));
|
||||
throw ORMInvalidArgumentException::invalidObject('EntityManager#merge()' , $entity);
|
||||
}
|
||||
|
||||
$this->errorIfClosed();
|
||||
|
@ -36,22 +36,22 @@ use PDO,
|
||||
*/
|
||||
abstract class AbstractHydrator
|
||||
{
|
||||
/** @var ResultSetMapping The ResultSetMapping. */
|
||||
/** @var \Doctrine\ORM\Query\ResultSetMapping The ResultSetMapping. */
|
||||
protected $_rsm;
|
||||
|
||||
/** @var EntityManager The EntityManager instance. */
|
||||
protected $_em;
|
||||
|
||||
/** @var AbstractPlatform The dbms Platform instance */
|
||||
/** @var \Doctrine\DBAL\Platforms\AbstractPlatform The dbms Platform instance */
|
||||
protected $_platform;
|
||||
|
||||
/** @var UnitOfWork The UnitOfWork of the associated EntityManager. */
|
||||
/** @var \Doctrine\ORM\UnitOfWork The UnitOfWork of the associated EntityManager. */
|
||||
protected $_uow;
|
||||
|
||||
/** @var array The cache used during row-by-row hydration. */
|
||||
protected $_cache = array();
|
||||
|
||||
/** @var Statement The statement that provides the data to hydrate. */
|
||||
/** @var \Doctrine\DBAL\Driver\Statement The statement that provides the data to hydrate. */
|
||||
protected $_stmt;
|
||||
|
||||
/** @var array The query hints. */
|
||||
@ -93,6 +93,7 @@ abstract class AbstractHydrator
|
||||
*
|
||||
* @param object $stmt
|
||||
* @param object $resultSetMapping
|
||||
* @param array $hints
|
||||
* @return mixed
|
||||
*/
|
||||
public function hydrateAll($stmt, $resultSetMapping, array $hints = array())
|
||||
|
@ -208,8 +208,8 @@ class ObjectHydrator extends AbstractHydrator
|
||||
/**
|
||||
* Gets an entity instance.
|
||||
*
|
||||
* @param $data The instance data.
|
||||
* @param $dqlAlias The DQL alias of the entity's class.
|
||||
* @param array $data The instance data.
|
||||
* @param string $dqlAlias The DQL alias of the entity's class.
|
||||
* @return object The entity.
|
||||
*/
|
||||
private function _getEntity(array $data, $dqlAlias)
|
||||
|
@ -20,7 +20,6 @@
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use ReflectionClass, ReflectionProperty;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata AS IClassMetadata;
|
||||
|
||||
/**
|
||||
* A <tt>ClassMetadata</tt> instance holds all the object-relational mapping metadata
|
||||
@ -40,325 +39,6 @@ use Doctrine\Common\Persistence\Mapping\ClassMetadata AS IClassMetadata;
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ClassMetadata extends ClassMetadataInfo implements IClassMetadata
|
||||
class ClassMetadata extends ClassMetadataInfo
|
||||
{
|
||||
/**
|
||||
* The ReflectionProperty instances of the mapped class.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $reflFields = array();
|
||||
|
||||
/**
|
||||
* The prototype from which new instances of the mapped class are created.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private $_prototype;
|
||||
|
||||
/**
|
||||
* Initializes a new ClassMetadata instance that will hold the object-relational mapping
|
||||
* metadata of the class with the given name.
|
||||
*
|
||||
* @param string $entityName The name of the entity class the new instance is used for.
|
||||
*/
|
||||
public function __construct($entityName)
|
||||
{
|
||||
$this->reflClass = new ReflectionClass($entityName);
|
||||
$this->namespace = $this->reflClass->getNamespaceName();
|
||||
$this->table['name'] = $this->reflClass->getShortName();
|
||||
parent::__construct($this->reflClass->getName()); // do not use $entityName, possible case-problems
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ReflectionPropertys of the mapped class.
|
||||
*
|
||||
* @return array An array of ReflectionProperty instances.
|
||||
*/
|
||||
public function getReflectionProperties()
|
||||
{
|
||||
return $this->reflFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a ReflectionProperty for a specific field of the mapped class.
|
||||
*
|
||||
* @param string $name
|
||||
* @return ReflectionProperty
|
||||
*/
|
||||
public function getReflectionProperty($name)
|
||||
{
|
||||
return $this->reflFields[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ReflectionProperty for the single identifier field.
|
||||
*
|
||||
* @return ReflectionProperty
|
||||
* @throws BadMethodCallException If the class has a composite identifier.
|
||||
*/
|
||||
public function getSingleIdReflectionProperty()
|
||||
{
|
||||
if ($this->isIdentifierComposite) {
|
||||
throw new \BadMethodCallException("Class " . $this->name . " has a composite identifier.");
|
||||
}
|
||||
return $this->reflFields[$this->identifier[0]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates & completes the given field mapping.
|
||||
*
|
||||
* @param array $mapping The field mapping to validated & complete.
|
||||
* @return array The validated and completed field mapping.
|
||||
*
|
||||
* @throws MappingException
|
||||
*/
|
||||
protected function _validateAndCompleteFieldMapping(array &$mapping)
|
||||
{
|
||||
parent::_validateAndCompleteFieldMapping($mapping);
|
||||
|
||||
// Store ReflectionProperty of mapped field
|
||||
$refProp = $this->reflClass->getProperty($mapping['fieldName']);
|
||||
$refProp->setAccessible(true);
|
||||
$this->reflFields[$mapping['fieldName']] = $refProp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the identifier values of an entity of this class.
|
||||
*
|
||||
* For composite identifiers, the identifier values are returned as an array
|
||||
* with the same order as the field order in {@link identifier}.
|
||||
*
|
||||
* @param object $entity
|
||||
* @return array
|
||||
*/
|
||||
public function getIdentifierValues($entity)
|
||||
{
|
||||
if ($this->isIdentifierComposite) {
|
||||
$id = array();
|
||||
|
||||
foreach ($this->identifier as $idField) {
|
||||
$value = $this->reflFields[$idField]->getValue($entity);
|
||||
|
||||
if ($value !== null) {
|
||||
$id[$idField] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
$value = $this->reflFields[$this->identifier[0]]->getValue($entity);
|
||||
|
||||
if ($value !== null) {
|
||||
return array($this->identifier[0] => $value);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the entity identifier of an entity.
|
||||
*
|
||||
* @param object $entity
|
||||
* @param mixed $id
|
||||
* @todo Rename to assignIdentifier()
|
||||
*/
|
||||
public function setIdentifierValues($entity, array $id)
|
||||
{
|
||||
foreach ($id as $idField => $idValue) {
|
||||
$this->reflFields[$idField]->setValue($entity, $idValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified field to the specified value on the given entity.
|
||||
*
|
||||
* @param object $entity
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setFieldValue($entity, $field, $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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the association mapping.
|
||||
*
|
||||
* @param AssociationMapping $assocMapping
|
||||
*/
|
||||
protected function _storeAssociationMapping(array $assocMapping)
|
||||
{
|
||||
parent::_storeAssociationMapping($assocMapping);
|
||||
|
||||
// Store ReflectionProperty of mapped field
|
||||
$sourceFieldName = $assocMapping['fieldName'];
|
||||
|
||||
$refProp = $this->reflClass->getProperty($sourceFieldName);
|
||||
$refProp->setAccessible(true);
|
||||
$this->reflFields[$sourceFieldName] = $refProp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string representation of this instance.
|
||||
*
|
||||
* @return string The string representation of this instance.
|
||||
* @todo Construct meaningful string representation.
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return __CLASS__ . '@' . spl_object_hash($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines which fields get serialized.
|
||||
*
|
||||
* It is only serialized what is necessary for best unserialization performance.
|
||||
* That means any metadata properties that are not set or empty or simply have
|
||||
* their default value are NOT serialized.
|
||||
*
|
||||
* Parts that are also NOT serialized because they can not be properly unserialized:
|
||||
* - reflClass (ReflectionClass)
|
||||
* - reflFields (ReflectionProperty array)
|
||||
*
|
||||
* @return array The names of all the fields that should be serialized.
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
// This metadata is always serialized/cached.
|
||||
$serialized = array(
|
||||
'associationMappings',
|
||||
'columnNames', //TODO: Not really needed. Can use fieldMappings[$fieldName]['columnName']
|
||||
'fieldMappings',
|
||||
'fieldNames',
|
||||
'identifier',
|
||||
'isIdentifierComposite', // TODO: REMOVE
|
||||
'name',
|
||||
'namespace', // TODO: REMOVE
|
||||
'table',
|
||||
'rootEntityName',
|
||||
'idGenerator', //TODO: Does not really need to be serialized. Could be moved to runtime.
|
||||
);
|
||||
|
||||
// The rest of the metadata is only serialized if necessary.
|
||||
if ($this->changeTrackingPolicy != self::CHANGETRACKING_DEFERRED_IMPLICIT) {
|
||||
$serialized[] = 'changeTrackingPolicy';
|
||||
}
|
||||
|
||||
if ($this->customRepositoryClassName) {
|
||||
$serialized[] = 'customRepositoryClassName';
|
||||
}
|
||||
|
||||
if ($this->inheritanceType != self::INHERITANCE_TYPE_NONE) {
|
||||
$serialized[] = 'inheritanceType';
|
||||
$serialized[] = 'discriminatorColumn';
|
||||
$serialized[] = 'discriminatorValue';
|
||||
$serialized[] = 'discriminatorMap';
|
||||
$serialized[] = 'parentClasses';
|
||||
$serialized[] = 'subClasses';
|
||||
}
|
||||
|
||||
if ($this->generatorType != self::GENERATOR_TYPE_NONE) {
|
||||
$serialized[] = 'generatorType';
|
||||
if ($this->generatorType == self::GENERATOR_TYPE_SEQUENCE) {
|
||||
$serialized[] = 'sequenceGeneratorDefinition';
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->isMappedSuperclass) {
|
||||
$serialized[] = 'isMappedSuperclass';
|
||||
}
|
||||
|
||||
if ($this->containsForeignIdentifier) {
|
||||
$serialized[] = 'containsForeignIdentifier';
|
||||
}
|
||||
|
||||
if ($this->isVersioned) {
|
||||
$serialized[] = 'isVersioned';
|
||||
$serialized[] = 'versionField';
|
||||
}
|
||||
|
||||
if ($this->lifecycleCallbacks) {
|
||||
$serialized[] = 'lifecycleCallbacks';
|
||||
}
|
||||
|
||||
if ($this->namedQueries) {
|
||||
$serialized[] = 'namedQueries';
|
||||
}
|
||||
|
||||
if ($this->isReadOnly) {
|
||||
$serialized[] = 'isReadOnly';
|
||||
}
|
||||
|
||||
return $serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores some state that can not be serialized/unserialized.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
// Restore ReflectionClass and properties
|
||||
$this->reflClass = new ReflectionClass($this->name);
|
||||
|
||||
foreach ($this->fieldMappings as $field => $mapping) {
|
||||
$reflField = isset($mapping['declared'])
|
||||
? new ReflectionProperty($mapping['declared'], $field)
|
||||
: $this->reflClass->getProperty($field);
|
||||
|
||||
$reflField->setAccessible(true);
|
||||
$this->reflFields[$field] = $reflField;
|
||||
}
|
||||
|
||||
foreach ($this->associationMappings as $field => $mapping) {
|
||||
$reflField = isset($mapping['declared'])
|
||||
? new ReflectionProperty($mapping['declared'], $field)
|
||||
: $this->reflClass->getProperty($field);
|
||||
|
||||
$reflField->setAccessible(true);
|
||||
$this->reflFields[$field] = $reflField;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the mapped class, without invoking the constructor.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function newInstance()
|
||||
{
|
||||
if ($this->_prototype === null) {
|
||||
$this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
|
||||
}
|
||||
|
||||
return clone $this->_prototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $callback
|
||||
* @param string $event
|
||||
*/
|
||||
public function addLifecycleCallback($callback, $event)
|
||||
{
|
||||
if ( !$this->reflClass->hasMethod($callback) ||
|
||||
($this->reflClass->getMethod($callback)->getModifiers() & \ReflectionMethod::IS_PUBLIC) == 0) {
|
||||
throw MappingException::lifecycleCallbackMethodNotFound($this->name, $callback);
|
||||
}
|
||||
|
||||
return parent::addLifecycleCallback($callback, $event);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ use ReflectionException,
|
||||
Doctrine\ORM\EntityManager,
|
||||
Doctrine\DBAL\Platforms,
|
||||
Doctrine\ORM\Events,
|
||||
Doctrine\Common\Persistence\Mapping\RuntimeReflectionService,
|
||||
Doctrine\Common\Persistence\Mapping\ReflectionService,
|
||||
Doctrine\Common\Persistence\Mapping\ClassMetadataFactory as ClassMetadataFactoryInterface;
|
||||
|
||||
/**
|
||||
@ -74,6 +76,11 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
*/
|
||||
private $initialized = false;
|
||||
|
||||
/**
|
||||
* @var ReflectionService
|
||||
*/
|
||||
private $reflectionService;
|
||||
|
||||
/**
|
||||
* @param EntityManager $$em
|
||||
*/
|
||||
@ -165,6 +172,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
|
||||
if ($this->cacheDriver) {
|
||||
if (($cached = $this->cacheDriver->fetch("$realClassName\$CLASSMETADATA")) !== false) {
|
||||
$this->wakeupReflection($cached, $this->getReflectionService());
|
||||
$this->loadedMetadata[$realClassName] = $cached;
|
||||
} else {
|
||||
foreach ($this->loadMetadata($realClassName) as $loadedClassName) {
|
||||
@ -220,7 +228,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
{
|
||||
// Collect parent classes, ignoring transient (not-mapped) classes.
|
||||
$parentClasses = array();
|
||||
foreach (array_reverse(class_parents($name)) as $parentClass) {
|
||||
foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) {
|
||||
if ( ! $this->driver->isTransient($parentClass)) {
|
||||
$parentClasses[] = $parentClass;
|
||||
}
|
||||
@ -261,6 +269,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
}
|
||||
|
||||
$class = $this->newClassMetadataInstance($className);
|
||||
$this->initializeReflection($class, $this->getReflectionService());
|
||||
|
||||
if ($parent) {
|
||||
$class->setInheritanceType($parent->inheritanceType);
|
||||
@ -282,6 +291,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
// Invoke driver
|
||||
try {
|
||||
$this->driver->loadMetadataForClass($className, $class);
|
||||
$this->wakeupReflection($class, $this->getReflectionService());
|
||||
} catch (ReflectionException $e) {
|
||||
throw MappingException::reflectionFailure($className, $e);
|
||||
}
|
||||
@ -349,11 +359,15 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
*/
|
||||
protected function validateRuntimeMetadata($class, $parent)
|
||||
{
|
||||
// Verify & complete identifier mapping
|
||||
if ( ! $class->identifier && ! $class->isMappedSuperclass) {
|
||||
throw MappingException::identifierRequired($class->name);
|
||||
if ( ! $class->reflClass ) {
|
||||
// only validate if there is a reflection class instance
|
||||
return;
|
||||
}
|
||||
|
||||
$class->validateIdentifier();
|
||||
$class->validateAssocations();
|
||||
$class->validateLifecycleCallbacks($this->getReflectionService());
|
||||
|
||||
// verify inheritance
|
||||
if (!$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
|
||||
if (!$parent) {
|
||||
@ -371,10 +385,6 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
// second condition is necessary for mapped superclasses in the middle of an inheritance hierachy
|
||||
throw MappingException::noInheritanceOnMappedSuperClass($class->name);
|
||||
}
|
||||
|
||||
if ($class->usesIdGenerator() && $class->isIdentifierComposite) {
|
||||
throw MappingException::compositeKeyAssignedIdGeneratorRequired($class->name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -385,7 +395,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
*/
|
||||
protected function newClassMetadataInstance($className)
|
||||
{
|
||||
return new ClassMetadata($className);
|
||||
return new ClassMetadata($className, $this->em->getConfiguration()->getNamingStrategy());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -546,4 +556,51 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
|
||||
|
||||
return $this->driver->isTransient($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reflectionService.
|
||||
*
|
||||
* @return \Doctrine\Common\Persistence\Mapping\ReflectionService
|
||||
*/
|
||||
public function getReflectionService()
|
||||
{
|
||||
if ($this->reflectionService === null) {
|
||||
$this->reflectionService = new RuntimeReflectionService();
|
||||
}
|
||||
return $this->reflectionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set reflectionService.
|
||||
*
|
||||
* @param reflectionService the value to set.
|
||||
*/
|
||||
public function setReflectionService(ReflectionService $reflectionService)
|
||||
{
|
||||
$this->reflectionService = $reflectionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wakeup reflection after ClassMetadata gets unserialized from cache.
|
||||
*
|
||||
* @param ClassMetadataInfo $class
|
||||
* @param ReflectionService $reflService
|
||||
* @return void
|
||||
*/
|
||||
protected function wakeupReflection(ClassMetadataInfo $class, ReflectionService $reflService)
|
||||
{
|
||||
$class->wakeupReflection($reflService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Reflection after ClassMetadata was constructed.
|
||||
*
|
||||
* @param ClassMetadataInfo $class
|
||||
* @param ReflectionService $reflService
|
||||
* @return void
|
||||
*/
|
||||
protected function initializeReflection(ClassMetadataInfo $class, ReflectionService $reflService)
|
||||
{
|
||||
$class->initializeReflection($reflService);
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use ReflectionClass;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
|
||||
/**
|
||||
* A <tt>ClassMetadata</tt> instance holds all the object-relational mapping metadata
|
||||
@ -40,7 +41,7 @@ use ReflectionClass;
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ClassMetadataInfo
|
||||
class ClassMetadataInfo implements ClassMetadata
|
||||
{
|
||||
/* The inheritance mapping types */
|
||||
/**
|
||||
@ -443,7 +444,7 @@ class ClassMetadataInfo
|
||||
/**
|
||||
* READ-ONLY: The ID generator used for generating IDs for this class.
|
||||
*
|
||||
* @var AbstractIdGenerator
|
||||
* @var \Doctrine\ORM\Id\AbstractIdGenerator
|
||||
* @todo Remove!
|
||||
*/
|
||||
public $idGenerator;
|
||||
@ -515,16 +516,341 @@ class ClassMetadataInfo
|
||||
*/
|
||||
public $isReadOnly = false;
|
||||
|
||||
/**
|
||||
* NamingStrategy determining the default column and table names
|
||||
*
|
||||
* @var \Doctrine\ORM\NamingStrategy
|
||||
*/
|
||||
protected $namingStrategy;
|
||||
|
||||
/**
|
||||
* The ReflectionProperty instances of the mapped class.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $reflFields = array();
|
||||
|
||||
/**
|
||||
* The prototype from which new instances of the mapped class are created.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private $_prototype;
|
||||
|
||||
/**
|
||||
* Initializes a new ClassMetadata instance that will hold the object-relational mapping
|
||||
* metadata of the class with the given name.
|
||||
*
|
||||
* @param string $entityName The name of the entity class the new instance is used for.
|
||||
* @param NamingStrategy $namingStrategy
|
||||
*/
|
||||
public function __construct($entityName, NamingStrategy $namingStrategy = null)
|
||||
{
|
||||
$this->name = $entityName;
|
||||
$this->rootEntityName = $entityName;
|
||||
$this->namingStrategy = $namingStrategy ?: new DefaultNamingStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ReflectionPropertys of the mapped class.
|
||||
*
|
||||
* @return array An array of ReflectionProperty instances.
|
||||
*/
|
||||
public function getReflectionProperties()
|
||||
{
|
||||
return $this->reflFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a ReflectionProperty for a specific field of the mapped class.
|
||||
*
|
||||
* @param string $name
|
||||
* @return ReflectionProperty
|
||||
*/
|
||||
public function getReflectionProperty($name)
|
||||
{
|
||||
return $this->reflFields[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ReflectionProperty for the single identifier field.
|
||||
*
|
||||
* @return ReflectionProperty
|
||||
* @throws BadMethodCallException If the class has a composite identifier.
|
||||
*/
|
||||
public function getSingleIdReflectionProperty()
|
||||
{
|
||||
if ($this->isIdentifierComposite) {
|
||||
throw new \BadMethodCallException("Class " . $this->name . " has a composite identifier.");
|
||||
}
|
||||
return $this->reflFields[$this->identifier[0]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the identifier values of an entity of this class.
|
||||
*
|
||||
* For composite identifiers, the identifier values are returned as an array
|
||||
* with the same order as the field order in {@link identifier}.
|
||||
*
|
||||
* @param object $entity
|
||||
* @return array
|
||||
*/
|
||||
public function getIdentifierValues($entity)
|
||||
{
|
||||
if ($this->isIdentifierComposite) {
|
||||
$id = array();
|
||||
|
||||
foreach ($this->identifier as $idField) {
|
||||
$value = $this->reflFields[$idField]->getValue($entity);
|
||||
|
||||
if ($value !== null) {
|
||||
$id[$idField] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
$value = $this->reflFields[$this->identifier[0]]->getValue($entity);
|
||||
|
||||
if ($value !== null) {
|
||||
return array($this->identifier[0] => $value);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the entity identifier of an entity.
|
||||
*
|
||||
* @param object $entity
|
||||
* @param mixed $id
|
||||
* @todo Rename to assignIdentifier()
|
||||
*/
|
||||
public function setIdentifierValues($entity, array $id)
|
||||
{
|
||||
foreach ($id as $idField => $idValue) {
|
||||
$this->reflFields[$idField]->setValue($entity, $idValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified field to the specified value on the given entity.
|
||||
*
|
||||
* @param object $entity
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setFieldValue($entity, $field, $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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string representation of this instance.
|
||||
*
|
||||
* @return string The string representation of this instance.
|
||||
* @todo Construct meaningful string representation.
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return __CLASS__ . '@' . spl_object_hash($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines which fields get serialized.
|
||||
*
|
||||
* It is only serialized what is necessary for best unserialization performance.
|
||||
* That means any metadata properties that are not set or empty or simply have
|
||||
* their default value are NOT serialized.
|
||||
*
|
||||
* Parts that are also NOT serialized because they can not be properly unserialized:
|
||||
* - reflClass (ReflectionClass)
|
||||
* - reflFields (ReflectionProperty array)
|
||||
*
|
||||
* @return array The names of all the fields that should be serialized.
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
// This metadata is always serialized/cached.
|
||||
$serialized = array(
|
||||
'associationMappings',
|
||||
'columnNames', //TODO: Not really needed. Can use fieldMappings[$fieldName]['columnName']
|
||||
'fieldMappings',
|
||||
'fieldNames',
|
||||
'identifier',
|
||||
'isIdentifierComposite', // TODO: REMOVE
|
||||
'name',
|
||||
'namespace', // TODO: REMOVE
|
||||
'table',
|
||||
'rootEntityName',
|
||||
'idGenerator', //TODO: Does not really need to be serialized. Could be moved to runtime.
|
||||
);
|
||||
|
||||
// The rest of the metadata is only serialized if necessary.
|
||||
if ($this->changeTrackingPolicy != self::CHANGETRACKING_DEFERRED_IMPLICIT) {
|
||||
$serialized[] = 'changeTrackingPolicy';
|
||||
}
|
||||
|
||||
if ($this->customRepositoryClassName) {
|
||||
$serialized[] = 'customRepositoryClassName';
|
||||
}
|
||||
|
||||
if ($this->inheritanceType != self::INHERITANCE_TYPE_NONE) {
|
||||
$serialized[] = 'inheritanceType';
|
||||
$serialized[] = 'discriminatorColumn';
|
||||
$serialized[] = 'discriminatorValue';
|
||||
$serialized[] = 'discriminatorMap';
|
||||
$serialized[] = 'parentClasses';
|
||||
$serialized[] = 'subClasses';
|
||||
}
|
||||
|
||||
if ($this->generatorType != self::GENERATOR_TYPE_NONE) {
|
||||
$serialized[] = 'generatorType';
|
||||
if ($this->generatorType == self::GENERATOR_TYPE_SEQUENCE) {
|
||||
$serialized[] = 'sequenceGeneratorDefinition';
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->isMappedSuperclass) {
|
||||
$serialized[] = 'isMappedSuperclass';
|
||||
}
|
||||
|
||||
if ($this->containsForeignIdentifier) {
|
||||
$serialized[] = 'containsForeignIdentifier';
|
||||
}
|
||||
|
||||
if ($this->isVersioned) {
|
||||
$serialized[] = 'isVersioned';
|
||||
$serialized[] = 'versionField';
|
||||
}
|
||||
|
||||
if ($this->lifecycleCallbacks) {
|
||||
$serialized[] = 'lifecycleCallbacks';
|
||||
}
|
||||
|
||||
if ($this->namedQueries) {
|
||||
$serialized[] = 'namedQueries';
|
||||
}
|
||||
|
||||
if ($this->isReadOnly) {
|
||||
$serialized[] = 'isReadOnly';
|
||||
}
|
||||
|
||||
return $serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the mapped class, without invoking the constructor.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function newInstance()
|
||||
{
|
||||
if ($this->_prototype === null) {
|
||||
$this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
|
||||
}
|
||||
|
||||
return clone $this->_prototype;
|
||||
}
|
||||
/**
|
||||
* Restores some state that can not be serialized/unserialized.
|
||||
*
|
||||
* @param ReflectionService $reflService
|
||||
* @return void
|
||||
*/
|
||||
public function wakeupReflection($reflService)
|
||||
{
|
||||
// Restore ReflectionClass and properties
|
||||
$this->reflClass = $reflService->getClass($this->name);
|
||||
|
||||
foreach ($this->fieldMappings as $field => $mapping) {
|
||||
$this->reflFields[$field] = isset($mapping['declared'])
|
||||
? $reflService->getAccessibleProperty($mapping['declared'], $field)
|
||||
: $reflService->getAccessibleProperty($this->name, $field);
|
||||
}
|
||||
|
||||
foreach ($this->associationMappings as $field => $mapping) {
|
||||
$this->reflFields[$field] = isset($mapping['declared'])
|
||||
? $reflService->getAccessibleProperty($mapping['declared'], $field)
|
||||
: $reflService->getAccessibleProperty($this->name, $field);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new ClassMetadata instance that will hold the object-relational mapping
|
||||
* metadata of the class with the given name.
|
||||
*
|
||||
* @param string $entityName The name of the entity class the new instance is used for.
|
||||
*/
|
||||
public function __construct($entityName)
|
||||
public function initializeReflection($reflService)
|
||||
{
|
||||
$this->name = $entityName;
|
||||
$this->rootEntityName = $entityName;
|
||||
$this->reflClass = $reflService->getClass($this->name);
|
||||
$this->namespace = $reflService->getClassNamespace($this->name);
|
||||
$this->table['name'] = $this->namingStrategy->classToTableName($reflService->getClassShortName($this->name));
|
||||
|
||||
if ($this->reflClass) {
|
||||
$this->name = $this->rootEntityName = $this->reflClass->getName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Identifier
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validateIdentifier()
|
||||
{
|
||||
// Verify & complete identifier mapping
|
||||
if ( ! $this->identifier && ! $this->isMappedSuperclass) {
|
||||
throw MappingException::identifierRequired($this->name);
|
||||
}
|
||||
|
||||
if ($this->usesIdGenerator() && $this->isIdentifierComposite) {
|
||||
throw MappingException::compositeKeyAssignedIdGeneratorRequired($this->name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate association targets actually exist.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function validateAssocations()
|
||||
{
|
||||
foreach ($this->associationMappings as $field => $mapping) {
|
||||
if ( ! \Doctrine\Common\ClassLoader::classExists($mapping['targetEntity']) ) {
|
||||
throw MappingException::invalidTargetEntityClass($mapping['targetEntity'], $this->name, $mapping['fieldName']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate lifecycle callbacks
|
||||
*
|
||||
* @param ReflectionService $reflService
|
||||
* @return void
|
||||
*/
|
||||
public function validateLifecycleCallbacks($reflService)
|
||||
{
|
||||
foreach ($this->lifecycleCallbacks as $event => $callbacks) {
|
||||
foreach ($callbacks as $callbackFuncName) {
|
||||
if ( ! $reflService->hasPublicMethod($this->name, $callbackFuncName)) {
|
||||
throw MappingException::lifecycleCallbackMethodNotFound($this->name, $callbackFuncName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -534,9 +860,6 @@ class ClassMetadataInfo
|
||||
*/
|
||||
public function getReflectionClass()
|
||||
{
|
||||
if ( ! $this->reflClass) {
|
||||
$this->reflClass = new ReflectionClass($this->name);
|
||||
}
|
||||
return $this->reflClass;
|
||||
}
|
||||
|
||||
@ -738,7 +1061,7 @@ class ClassMetadataInfo
|
||||
|
||||
// Complete fieldName and columnName mapping
|
||||
if ( ! isset($mapping['columnName'])) {
|
||||
$mapping['columnName'] = $mapping['fieldName'];
|
||||
$mapping['columnName'] = $this->namingStrategy->propertyToColumnName($mapping['fieldName']);
|
||||
} else {
|
||||
if ($mapping['columnName'][0] == '`') {
|
||||
$mapping['columnName'] = trim($mapping['columnName'], '`');
|
||||
@ -907,8 +1230,8 @@ class ClassMetadataInfo
|
||||
if ( ! isset($mapping['joinColumns']) || ! $mapping['joinColumns']) {
|
||||
// Apply default join column
|
||||
$mapping['joinColumns'] = array(array(
|
||||
'name' => $mapping['fieldName'] . '_id',
|
||||
'referencedColumnName' => 'id'
|
||||
'name' => $this->namingStrategy->joinColumnName($mapping['fieldName']),
|
||||
'referencedColumnName' => $this->namingStrategy->referenceColumnName()
|
||||
));
|
||||
}
|
||||
|
||||
@ -922,10 +1245,10 @@ class ClassMetadataInfo
|
||||
}
|
||||
}
|
||||
if (empty($joinColumn['name'])) {
|
||||
$joinColumn['name'] = $mapping['fieldName'] . '_id';
|
||||
$joinColumn['name'] = $this->namingStrategy->joinColumnName($mapping['fieldName']);
|
||||
}
|
||||
if (empty($joinColumn['referencedColumnName'])) {
|
||||
$joinColumn['referencedColumnName'] = 'id';
|
||||
$joinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName();
|
||||
}
|
||||
$mapping['sourceToTargetKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName'];
|
||||
$mapping['joinColumnFieldNames'][$joinColumn['name']] = isset($joinColumn['fieldName'])
|
||||
@ -986,40 +1309,29 @@ class ClassMetadataInfo
|
||||
{
|
||||
$mapping = $this->_validateAndCompleteAssociationMapping($mapping);
|
||||
if ($mapping['isOwningSide']) {
|
||||
if (strpos($mapping['sourceEntity'], '\\') !== false) {
|
||||
$sourceShortName = strtolower(substr($mapping['sourceEntity'], strrpos($mapping['sourceEntity'], '\\') + 1));
|
||||
} else {
|
||||
$sourceShortName = strtolower($mapping['sourceEntity']);
|
||||
}
|
||||
if (strpos($mapping['targetEntity'], '\\') !== false) {
|
||||
$targetShortName = strtolower(substr($mapping['targetEntity'], strrpos($mapping['targetEntity'], '\\') + 1));
|
||||
} else {
|
||||
$targetShortName = strtolower($mapping['targetEntity']);
|
||||
}
|
||||
|
||||
// owning side MUST have a join table
|
||||
if ( ! isset($mapping['joinTable']['name'])) {
|
||||
$mapping['joinTable']['name'] = $sourceShortName .'_' . $targetShortName;
|
||||
$mapping['joinTable']['name'] = $this->namingStrategy->joinTableName($mapping['sourceEntity'], $mapping['targetEntity'], $mapping['fieldName']);
|
||||
}
|
||||
if ( ! isset($mapping['joinTable']['joinColumns'])) {
|
||||
$mapping['joinTable']['joinColumns'] = array(array(
|
||||
'name' => $sourceShortName . '_id',
|
||||
'referencedColumnName' => 'id',
|
||||
'name' => $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity']),
|
||||
'referencedColumnName' => $this->namingStrategy->referenceColumnName(),
|
||||
'onDelete' => 'CASCADE'));
|
||||
}
|
||||
if ( ! isset($mapping['joinTable']['inverseJoinColumns'])) {
|
||||
$mapping['joinTable']['inverseJoinColumns'] = array(array(
|
||||
'name' => $targetShortName . '_id',
|
||||
'referencedColumnName' => 'id',
|
||||
'name' => $this->namingStrategy->joinKeyColumnName($mapping['targetEntity']),
|
||||
'referencedColumnName' => $this->namingStrategy->referenceColumnName(),
|
||||
'onDelete' => 'CASCADE'));
|
||||
}
|
||||
|
||||
foreach ($mapping['joinTable']['joinColumns'] as &$joinColumn) {
|
||||
if (empty($joinColumn['name'])) {
|
||||
$joinColumn['name'] = $sourceShortName . '_id';
|
||||
$joinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity'], $joinColumn['referencedColumnName']);
|
||||
}
|
||||
if (empty($joinColumn['referencedColumnName'])) {
|
||||
$joinColumn['referencedColumnName'] = 'id';
|
||||
$joinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName();
|
||||
}
|
||||
if (isset($joinColumn['onDelete']) && strtolower($joinColumn['onDelete']) == 'cascade') {
|
||||
$mapping['isOnDeleteCascade'] = true;
|
||||
@ -1030,10 +1342,10 @@ class ClassMetadataInfo
|
||||
|
||||
foreach ($mapping['joinTable']['inverseJoinColumns'] as &$inverseJoinColumn) {
|
||||
if (empty($inverseJoinColumn['name'])) {
|
||||
$inverseJoinColumn['name'] = $targetShortName . '_id';
|
||||
$inverseJoinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['targetEntity'], $inverseJoinColumn['referencedColumnName']);
|
||||
}
|
||||
if (empty($inverseJoinColumn['referencedColumnName'])) {
|
||||
$inverseJoinColumn['referencedColumnName'] = 'id';
|
||||
$inverseJoinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName();
|
||||
}
|
||||
if (isset($inverseJoinColumn['onDelete']) && strtolower($inverseJoinColumn['onDelete']) == 'cascade') {
|
||||
$mapping['isOnDeleteCascade'] = true;
|
||||
@ -1399,7 +1711,7 @@ class ClassMetadataInfo
|
||||
{
|
||||
if (isset($table['name'])) {
|
||||
if ($table['name'][0] == '`') {
|
||||
$this->table['name'] = trim($table['name'], '`');
|
||||
$this->table['name'] = str_replace("`", "", $table['name']);
|
||||
$this->table['quoted'] = true;
|
||||
} else {
|
||||
$this->table['name'] = $table['name'];
|
||||
|
86
lib/Doctrine/ORM/Mapping/DefaultNamingStrategy.php
Normal file
86
lib/Doctrine/ORM/Mapping/DefaultNamingStrategy.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* 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\ORM\Mapping;
|
||||
|
||||
/**
|
||||
* The default NamingStrategy
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.3
|
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||
*/
|
||||
class DefaultNamingStrategy implements NamingStrategy
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function classToTableName($className)
|
||||
{
|
||||
if (strpos($className, '\\') !== false) {
|
||||
return substr($className, strrpos($className, '\\') + 1);
|
||||
}
|
||||
|
||||
return $className;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function propertyToColumnName($propertyName)
|
||||
{
|
||||
return $propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function referenceColumnName()
|
||||
{
|
||||
return 'id';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function joinColumnName($propertyName)
|
||||
{
|
||||
return $propertyName . '_' . $this->referenceColumnName();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function joinTableName($sourceEntity, $targetEntity, $propertyName = null)
|
||||
{
|
||||
return strtolower($this->classToTableName($sourceEntity) . '_' .
|
||||
$this->classToTableName($targetEntity));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function joinKeyColumnName($entityName, $referencedColumnName = null)
|
||||
{
|
||||
return strtolower($this->classToTableName($entityName) . '_' .
|
||||
($referencedColumnName ?: $this->referenceColumnName()));
|
||||
}
|
||||
}
|
@ -61,7 +61,6 @@ class SimplifiedYamlDriver extends YamlDriver
|
||||
$this->_prefixes[$path] = $prefix;
|
||||
}
|
||||
|
||||
|
||||
public function getNamespacePrefixes()
|
||||
{
|
||||
return $this->_prefixes;
|
||||
|
@ -324,4 +324,9 @@ class MappingException extends \Doctrine\ORM\ORMException
|
||||
{
|
||||
return new self("Entity '". $className . "' has a composite identifier but uses an ID generator other than manually assigning (Identity, Sequence). This is not supported.");
|
||||
}
|
||||
|
||||
public static function invalidTargetEntityClass($targetEntity, $sourceEntity, $associationName)
|
||||
{
|
||||
return new self("The target-entity " . $targetEntity . " cannot be found in '" . $sourceEntity."#".$associationName."'.");
|
||||
}
|
||||
}
|
||||
|
82
lib/Doctrine/ORM/Mapping/NamingStrategy.php
Normal file
82
lib/Doctrine/ORM/Mapping/NamingStrategy.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* 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\ORM\Mapping;
|
||||
|
||||
/**
|
||||
* A set of rules for determining the physical column and table names
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.3
|
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||
*/
|
||||
interface NamingStrategy
|
||||
{
|
||||
/**
|
||||
* Return a table name for an entity class
|
||||
*
|
||||
* @param string $className The fully-qualified class name
|
||||
* @return string A table name
|
||||
*/
|
||||
function classToTableName($className);
|
||||
|
||||
/**
|
||||
* Return a column name for a property
|
||||
*
|
||||
* @param string $propertyName A property
|
||||
* @return string A column name
|
||||
*/
|
||||
function propertyToColumnName($propertyName);
|
||||
|
||||
/**
|
||||
* Return the default reference column name
|
||||
*
|
||||
* @return string A column name
|
||||
*/
|
||||
function referenceColumnName();
|
||||
|
||||
/**
|
||||
* Return a join column name for a property
|
||||
*
|
||||
* @param string $propertyName A property
|
||||
* @return string A join column name
|
||||
*/
|
||||
function joinColumnName($propertyName);
|
||||
|
||||
/**
|
||||
* Return a join table name
|
||||
*
|
||||
* @param string $sourceEntity The source entity
|
||||
* @param string $targetEntity The target entity
|
||||
* @param string $propertyName A property
|
||||
* @return string A join table name
|
||||
*/
|
||||
function joinTableName($sourceEntity, $targetEntity, $propertyName = null);
|
||||
|
||||
/**
|
||||
* Return the foreign key column name for the given parameters
|
||||
*
|
||||
* @param string $entityName A entity
|
||||
* @param string $referencedColumnName A property
|
||||
* @return string A join column name
|
||||
*/
|
||||
function joinKeyColumnName($entityName, $referencedColumnName = null);
|
||||
}
|
135
lib/Doctrine/ORM/Mapping/UnderscoreNamingStrategy.php
Normal file
135
lib/Doctrine/ORM/Mapping/UnderscoreNamingStrategy.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* 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\ORM\Mapping;
|
||||
|
||||
/**
|
||||
* Naming strategy implementing the underscore naming convention.
|
||||
* Converts 'MyEntity' to 'my_entity' or 'MY_ENTITY'.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.3
|
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||
*/
|
||||
class UnderscoreNamingStrategy implements NamingStrategy
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
private $case;
|
||||
|
||||
/**
|
||||
* Underscore naming strategy construct
|
||||
*
|
||||
* @param integer $case CASE_LOWER | CASE_UPPER
|
||||
*/
|
||||
public function __construct($case = CASE_LOWER)
|
||||
{
|
||||
$this->case = $case;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getCase()
|
||||
{
|
||||
return $this->case;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets string case CASE_LOWER | CASE_UPPER
|
||||
* Alphabetic characters converted to lowercase or uppercase
|
||||
*
|
||||
* @param integer $case
|
||||
*/
|
||||
public function setCase($case)
|
||||
{
|
||||
$this->case = $case;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function classToTableName($className)
|
||||
{
|
||||
if (strpos($className, '\\') !== false) {
|
||||
$className = substr($className, strrpos($className, '\\') + 1);
|
||||
}
|
||||
|
||||
return $this->underscore($className);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function propertyToColumnName($propertyName)
|
||||
{
|
||||
return $this->underscore($propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function referenceColumnName()
|
||||
{
|
||||
return $this->case === CASE_UPPER ? 'ID' : 'id';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function joinColumnName($propertyName)
|
||||
{
|
||||
return $this->underscore($propertyName) . '_' . $this->referenceColumnName();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function joinTableName($sourceEntity, $targetEntity, $propertyName = null)
|
||||
{
|
||||
return $this->classToTableName($sourceEntity) . '_' . $this->classToTableName($targetEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function joinKeyColumnName($entityName, $referencedColumnName = null)
|
||||
{
|
||||
return $this->classToTableName($entityName) . '_' .
|
||||
($referencedColumnName ?: $this->referenceColumnName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
private function underscore($string)
|
||||
{
|
||||
$string = preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $string);
|
||||
|
||||
if ($this->case === CASE_UPPER) {
|
||||
return strtoupper($string);
|
||||
}
|
||||
|
||||
return strtolower($string);
|
||||
}
|
||||
}
|
113
lib/Doctrine/ORM/ORMInvalidArgumentException.php
Normal file
113
lib/Doctrine/ORM/ORMInvalidArgumentException.php
Normal file
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/*
|
||||
* 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\ORM;
|
||||
|
||||
/**
|
||||
* Contains exception messages for all invalid lifecycle state exceptions inside UnitOfWork
|
||||
*
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class ORMInvalidArgumentException extends \InvalidArgumentException
|
||||
{
|
||||
static public function scheduleInsertForManagedEntity($entity)
|
||||
{
|
||||
return new self("A managed+dirty entity " . self::objToStr($entity) . " can not be scheduled for insertion.");
|
||||
}
|
||||
|
||||
static public function scheduleInsertForRemovedEntity($entity)
|
||||
{
|
||||
return new self("Removed entity " . self::objToStr($entity) . " can not be scheduled for insertion.");
|
||||
}
|
||||
|
||||
static public function scheduleInsertTwice($entity)
|
||||
{
|
||||
return new self("Entity " . self::objToStr($entity) . " can not be scheduled for insertion twice.");
|
||||
}
|
||||
|
||||
static public function entityWithoutIdentity($className, $entity)
|
||||
{
|
||||
throw new self(
|
||||
"The given entity of type '" . $className . "' (".self::objToStr($entity).") has no identity/no " .
|
||||
"id values set. It cannot be added to the identity map."
|
||||
);
|
||||
}
|
||||
|
||||
static public function readOnlyRequiresManagedEntity($entity)
|
||||
{
|
||||
return new self("Only managed entities can be marked or checked as read only. But " . self::objToStr($entity) . " is not");
|
||||
}
|
||||
|
||||
static public function newEntityFoundThroughRelationship(array $assoc, $entry)
|
||||
{
|
||||
return new self("A new entity was found through the relationship '"
|
||||
. $assoc['sourceEntity'] . "#" . $assoc['fieldName'] . "' that was not"
|
||||
. " configured to cascade persist operations for entity: " . self::objToStr($entry) . "."
|
||||
. " To solve this issue: Either explicitly call EntityManager#persist()"
|
||||
. " on this unknown entity or configure cascade persist "
|
||||
. " this association in the mapping for example @ManyToOne(..,cascade={\"persist\"}). "
|
||||
. " If you cannot find out which entity causes the problem"
|
||||
. " implement '" . $assoc['targetEntity'] . "#__toString()' to get a clue.");
|
||||
}
|
||||
|
||||
static public function detachedEntityFoundThroughRelationship(array $assoc, $entry)
|
||||
{
|
||||
throw new self("A detached entity of type " . $assoc['targetEntity'] . " (" . self::objToStr($entry) . ") "
|
||||
. " was found through the relationship '" . $assoc['sourceEntity'] . "#" . $assoc['fieldName'] . "' "
|
||||
. "during cascading a persist operation.");
|
||||
}
|
||||
|
||||
static public function entityNotManaged($entity)
|
||||
{
|
||||
throw new self("Entity " . self::objToStr($entity) . " is not managed. An entity is managed if its fetched " .
|
||||
"from the database or registered as new through EntityManager#persist");
|
||||
}
|
||||
|
||||
static public function entityHasNoIdentity($entity, $operation)
|
||||
{
|
||||
throw new self("Entity has no identity, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
|
||||
}
|
||||
|
||||
static public function entityIsRemoved($entity, $operation)
|
||||
{
|
||||
throw new self("Entity is removed, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
|
||||
}
|
||||
|
||||
static public function detachedEntityCannot($entity, $operation)
|
||||
{
|
||||
throw new self("A detached entity was found during " . $operation . " " . self::objToStr($entity));
|
||||
}
|
||||
|
||||
public static function invalidObject($context, $given, $parameterIndex = 1)
|
||||
{
|
||||
return new self($context .' expects parameter ' . $parameterIndex .
|
||||
' to be an entity object, '. gettype($given) . ' given.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to show an object as string.
|
||||
*
|
||||
* @param object $obj
|
||||
* @return string
|
||||
*/
|
||||
private static function objToStr($obj)
|
||||
{
|
||||
return method_exists($obj, '__toString') ? (string)$obj : get_class($obj).'@'.spl_object_hash($obj);
|
||||
}
|
||||
}
|
@ -192,7 +192,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
*/
|
||||
public function count(PersistentCollection $coll)
|
||||
{
|
||||
$mapping = $coll->getMapping();
|
||||
$mapping = $filterMapping = $coll->getMapping();
|
||||
$class = $this->_em->getClassMetadata($mapping['sourceEntity']);
|
||||
$id = $this->_em->getUnitOfWork()->getEntityIdentifier($coll->getOwner());
|
||||
|
||||
@ -218,7 +218,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
: $id[$class->fieldNames[$joinColumns[$joinTableColumn]]];
|
||||
}
|
||||
|
||||
list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($mapping);
|
||||
list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($filterMapping);
|
||||
if ($filterSql) {
|
||||
$whereClauses[] = $filterSql;
|
||||
}
|
||||
@ -295,7 +295,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
private function getJoinTableRestrictions(PersistentCollection $coll, $element, $addFilters)
|
||||
{
|
||||
$uow = $this->_em->getUnitOfWork();
|
||||
$mapping = $coll->getMapping();
|
||||
$mapping = $filterMapping = $coll->getMapping();
|
||||
|
||||
if ( ! $mapping['isOwningSide']) {
|
||||
$sourceClass = $this->_em->getClassMetadata($mapping['targetEntity']);
|
||||
@ -332,7 +332,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
}
|
||||
|
||||
if ($addFilters) {
|
||||
list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($mapping);
|
||||
list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($filterMapping);
|
||||
if ($filterSql) {
|
||||
$quotedJoinTable .= ' t ' . $joinTargetEntitySQL;
|
||||
$whereClauses[] = $filterSql;
|
||||
@ -351,13 +351,21 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* have to join in the actual entities table leading to additional
|
||||
* JOIN.
|
||||
*
|
||||
* @param array $targetEntity Array containing mapping information.
|
||||
* @param array $mapping Array containing mapping information.
|
||||
*
|
||||
* @return string The SQL query part to add to a query.
|
||||
*/
|
||||
public function getFilterSql($mapping)
|
||||
{
|
||||
$targetClass = $this->_em->getClassMetadata($mapping['targetEntity']);
|
||||
|
||||
if ($mapping['isOwningSide']) {
|
||||
$joinColumns = $mapping['relationToTargetKeyColumns'];
|
||||
} else {
|
||||
$mapping = $targetClass->associationMappings[$mapping['mappedBy']];
|
||||
$joinColumns = $mapping['relationToSourceKeyColumns'];
|
||||
}
|
||||
|
||||
$targetClass = $this->_em->getClassMetadata($targetClass->rootEntityName);
|
||||
|
||||
// A join is needed if there is filtering on the target entity
|
||||
@ -368,7 +376,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
. ' ON';
|
||||
|
||||
$joinTargetEntitySQLClauses = array();
|
||||
foreach ($mapping['relationToTargetKeyColumns'] as $joinTableColumn => $targetTableColumn) {
|
||||
foreach ($joinColumns as $joinTableColumn => $targetTableColumn) {
|
||||
$joinTargetEntitySQLClauses[] = ' t.' . $joinTableColumn . ' = ' . 'te.' . $targetTableColumn;
|
||||
}
|
||||
|
||||
|
@ -119,8 +119,9 @@ class OneToManyPersister extends AbstractCollectionPersister
|
||||
: $id[$sourceClass->fieldNames[$joinColumn['referencedColumnName']]];
|
||||
}
|
||||
|
||||
$filterTargetClass = $this->_em->getClassMetadata($targetClass->rootEntityName);
|
||||
foreach ($this->_em->getFilters()->getEnabledFilters() as $filter) {
|
||||
if ($filterExpr = $filter->addFilterConstraint($targetClass, 't')) {
|
||||
if ($filterExpr = $filter->addFilterConstraint($filterTargetClass, 't')) {
|
||||
$whereClauses[] = '(' . $filterExpr . ')';
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ class Expr
|
||||
* Creates an ASCending order expression.
|
||||
*
|
||||
* @param $sort
|
||||
* @return OrderBy
|
||||
* @return Expr\OrderBy
|
||||
*/
|
||||
public function asc($expr)
|
||||
{
|
||||
@ -86,7 +86,7 @@ class Expr
|
||||
* Creates a DESCending order expression.
|
||||
*
|
||||
* @param $sort
|
||||
* @return OrderBy
|
||||
* @return Expr\OrderBy
|
||||
*/
|
||||
public function desc($expr)
|
||||
{
|
||||
|
@ -1981,9 +1981,10 @@ class Parser
|
||||
}
|
||||
|
||||
/**
|
||||
* SimpleSelectExpression ::=
|
||||
* StateFieldPathExpression | IdentificationVariable |
|
||||
* ((AggregateExpression | "(" Subselect ")" | ScalarExpression) [["AS"] AliasResultVariable])
|
||||
* SimpleSelectExpression ::= (
|
||||
* StateFieldPathExpression | IdentificationVariable | FunctionDeclaration |
|
||||
* AggregateExpression | "(" Subselect ")" | ScalarExpression
|
||||
* ) [["AS"] AliasResultVariable]
|
||||
*
|
||||
* @return \Doctrine\ORM\Query\AST\SimpleSelectExpression
|
||||
*/
|
||||
@ -2004,6 +2005,18 @@ class Parser
|
||||
|
||||
return new AST\SimpleSelectExpression($expression);
|
||||
|
||||
case ($this->_isFunction()):
|
||||
// SUM(u.id) + COUNT(u.id)
|
||||
if ($this->_isMathOperator($this->_peekBeyondClosingParenthesis())) {
|
||||
return new AST\SimpleSelectExpression($this->ScalarExpression());
|
||||
}
|
||||
// COUNT(u.id)
|
||||
if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) {
|
||||
return new AST\SimpleSelectExpression($this->AggregateExpression());
|
||||
}
|
||||
// IDENTITY(u)
|
||||
return new AST\SimpleSelectExpression($this->FunctionDeclaration());
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
}
|
||||
@ -2151,7 +2164,8 @@ class Parser
|
||||
$peek = $this->_peekBeyondClosingParenthesis();
|
||||
|
||||
if (in_array($peek['value'], array("=", "<", "<=", "<>", ">", ">=", "!=")) ||
|
||||
in_array($peek['type'], array(Lexer::T_NOT, Lexer::T_BETWEEN, Lexer::T_LIKE, Lexer::T_IN, Lexer::T_IS, Lexer::T_EXISTS))) {
|
||||
in_array($peek['type'], array(Lexer::T_NOT, Lexer::T_BETWEEN, Lexer::T_LIKE, Lexer::T_IN, Lexer::T_IS, Lexer::T_EXISTS)) ||
|
||||
$this->_isMathOperator($peek)) {
|
||||
$condPrimary->simpleConditionalExpression = $this->SimpleConditionalExpression();
|
||||
|
||||
return $condPrimary;
|
||||
@ -2812,7 +2826,7 @@ class Parser
|
||||
}
|
||||
|
||||
/**
|
||||
* LikeExpression ::= StringExpression ["NOT"] "LIKE" (string | input_parameter) ["ESCAPE" char]
|
||||
* LikeExpression ::= StringExpression ["NOT"] "LIKE" StringPrimary ["ESCAPE" char]
|
||||
*
|
||||
* @return \Doctrine\ORM\Query\AST\LikeExpression
|
||||
*/
|
||||
@ -2832,8 +2846,7 @@ class Parser
|
||||
$this->match(Lexer::T_INPUT_PARAMETER);
|
||||
$stringPattern = new AST\InputParameter($this->_lexer->token['value']);
|
||||
} else {
|
||||
$this->match(Lexer::T_STRING);
|
||||
$stringPattern = $this->_lexer->token['value'];
|
||||
$stringPattern = $this->StringPrimary();
|
||||
}
|
||||
|
||||
$escapeChar = null;
|
||||
|
@ -1947,6 +1947,10 @@ class SqlWalker implements TreeWalker
|
||||
$dqlParamKey = $inputParam->name;
|
||||
$this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
|
||||
$sql .= '?';
|
||||
} elseif ($likeExpr->stringPattern instanceof AST\Functions\FunctionNode ) {
|
||||
$sql .= $this->walkFunction($likeExpr->stringPattern);
|
||||
} elseif ($likeExpr->stringPattern instanceof AST\PathExpression) {
|
||||
$sql .= $this->walkPathExpression($likeExpr->stringPattern);
|
||||
} else {
|
||||
$sql .= $this->_conn->quote($likeExpr->stringPattern);
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ class QueryBuilder
|
||||
* For more complex expression construction, consider storing the expression
|
||||
* builder object in a local variable.
|
||||
*
|
||||
* @return Expr
|
||||
* @return Query\Expr
|
||||
*/
|
||||
public function expr()
|
||||
{
|
||||
|
@ -38,36 +38,8 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
*/
|
||||
class DisconnectedClassMetadataFactory extends ClassMetadataFactory
|
||||
{
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
protected function newClassMetadataInstance($className)
|
||||
public function getReflectionService()
|
||||
{
|
||||
$metadata = new ClassMetadataInfo($className);
|
||||
if (strpos($className, "\\") !== false) {
|
||||
$metadata->namespace = strrev(substr( strrev($className), strpos(strrev($className), "\\")+1 ));
|
||||
} else {
|
||||
$metadata->namespace = "";
|
||||
}
|
||||
return $metadata;
|
||||
return new \Doctrine\Common\Persistence\Mapping\StaticReflectionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate runtime metadata is correctly defined.
|
||||
*
|
||||
* @param ClassMetadata $class
|
||||
* @param ClassMetadata $parent
|
||||
*/
|
||||
protected function validateRuntimeMetadata($class, $parent)
|
||||
{
|
||||
// validate nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
protected function getParentClasses($name)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,16 +111,18 @@ abstract class AbstractExporter
|
||||
}
|
||||
|
||||
foreach ($this->_metadata as $metadata) {
|
||||
$output = $this->exportClassMetadata($metadata);
|
||||
$path = $this->_generateOutputPath($metadata);
|
||||
$dir = dirname($path);
|
||||
if ( ! is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
//In case output is returned, write it to a file, skip otherwise
|
||||
if($output = $this->exportClassMetadata($metadata)){
|
||||
$path = $this->_generateOutputPath($metadata);
|
||||
$dir = dirname($path);
|
||||
if ( ! is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
if (file_exists($path) && !$this->_overwriteExistingFiles) {
|
||||
throw ExportException::attemptOverwriteExistingFile($path);
|
||||
}
|
||||
file_put_contents($path, $output);
|
||||
}
|
||||
if (file_exists($path) && !$this->_overwriteExistingFiles) {
|
||||
throw ExportException::attemptOverwriteExistingFile($path);
|
||||
}
|
||||
file_put_contents($path, $output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -710,14 +710,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
switch ($state) {
|
||||
case self::STATE_NEW:
|
||||
if ( ! $assoc['isCascadePersist']) {
|
||||
$message = "A new entity was found through the relationship '%s#%s' that was not configured " .
|
||||
' to cascade persist operations for entity: %s. Explicitly persist the new entity or ' .
|
||||
'configure cascading persist operations on the relationship. If you cannot find out ' .
|
||||
'which entity causes the problem, implement %s#__toString() to get a clue.';
|
||||
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
$message, $assoc['sourceEntity'], $assoc['fieldName'], self::objToStr($entry), $assoc['targetEntity']
|
||||
));
|
||||
throw ORMInvalidArgumentException::newEntityFoundThroughRelationship($assoc, $entry);
|
||||
}
|
||||
|
||||
$this->persistNew($targetClass, $entry);
|
||||
@ -735,9 +728,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
case self::STATE_DETACHED:
|
||||
// Can actually not happen right now as we assume STATE_NEW,
|
||||
// so the exception will be raised from the DBAL layer (constraint violation).
|
||||
$message = 'A detached entity was found through a relationship during cascading a persist operation.';
|
||||
|
||||
throw new InvalidArgumentException($message);
|
||||
throw ORMInvalidArgumentException::detachedEntityFoundThroughRelationship($assoc, $entry);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -797,7 +788,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$oid = spl_object_hash($entity);
|
||||
|
||||
if ( ! isset($this->entityStates[$oid]) || $this->entityStates[$oid] != self::STATE_MANAGED) {
|
||||
throw new InvalidArgumentException('Entity must be managed.');
|
||||
throw ORMInvalidArgumentException::entityNotManaged($entity);
|
||||
}
|
||||
|
||||
// skip if change tracking is "NOTIFY"
|
||||
@ -1077,11 +1068,14 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
|
||||
if (isset($this->entityDeletions[$oid])) {
|
||||
throw new InvalidArgumentException("Removed entity can not be scheduled for insertion.");
|
||||
throw ORMInvalidArgumentException::scheduleInsertForRemovedEntity($entity);
|
||||
}
|
||||
if (isset($this->originalEntityData[$oid]) && ! isset($this->entityInsertions[$oid])) {
|
||||
throw ORMInvalidArgumentException::scheduleInsertForManagedEntity($entity);
|
||||
}
|
||||
|
||||
if (isset($this->entityInsertions[$oid])) {
|
||||
throw new InvalidArgumentException("Entity can not be scheduled for insertion twice.");
|
||||
throw ORMInvalidArgumentException::scheduleInsertTwice($entity);
|
||||
}
|
||||
|
||||
$this->entityInsertions[$oid] = $entity;
|
||||
@ -1112,11 +1106,11 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$oid = spl_object_hash($entity);
|
||||
|
||||
if ( ! isset($this->entityIdentifiers[$oid])) {
|
||||
throw new InvalidArgumentException("Entity has no identity.");
|
||||
throw ORMInvalidArgumentException::entityHasNoIdentity($entity, "scheduling for update");
|
||||
}
|
||||
|
||||
if (isset($this->entityDeletions[$oid])) {
|
||||
throw new InvalidArgumentException("Entity is removed.");
|
||||
throw ORMInvalidArgumentException::entityIsRemoved($entity, "schedule for update");
|
||||
}
|
||||
|
||||
if ( ! isset($this->entityUpdates[$oid]) && ! isset($this->entityInsertions[$oid])) {
|
||||
@ -1256,7 +1250,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$idHash = implode(' ', $this->entityIdentifiers[spl_object_hash($entity)]);
|
||||
|
||||
if ($idHash === '') {
|
||||
throw new InvalidArgumentException('The given entity has no identity.');
|
||||
throw ORMInvalidArgumentException::entityWithoutIdentity($classMetadata->name, $entity);
|
||||
}
|
||||
|
||||
$className = $classMetadata->rootEntityName;
|
||||
@ -1366,7 +1360,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$idHash = implode(' ', $this->entityIdentifiers[$oid]);
|
||||
|
||||
if ($idHash === '') {
|
||||
throw new InvalidArgumentException('The given entity has no identity.');
|
||||
throw ORMInvalidArgumentException::entityHasNoIdentity($entity, "remove from identity map");
|
||||
}
|
||||
|
||||
$className = $classMetadata->rootEntityName;
|
||||
@ -1513,10 +1507,10 @@ class UnitOfWork implements PropertyChangedListener
|
||||
|
||||
case self::STATE_DETACHED:
|
||||
// Can actually not happen right now since we assume STATE_NEW.
|
||||
throw new InvalidArgumentException('Detached entity passed to persist().');
|
||||
throw ORMInvalidArgumentException::detachedEntityCannot($entity, "persisted");
|
||||
|
||||
default:
|
||||
throw new UnexpectedValueException(sprintf('Unexpected entity state: %s', $entityState));
|
||||
throw new UnexpectedValueException("Unexpected entity state: $entityState." . self::objToStr($entity));
|
||||
}
|
||||
|
||||
$this->cascadePersist($entity, $visited);
|
||||
@ -1580,10 +1574,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
break;
|
||||
|
||||
case self::STATE_DETACHED:
|
||||
throw new InvalidArgumentException('A detached entity can not be removed.');
|
||||
|
||||
throw ORMInvalidArgumentException::detachedEntityCannot($entity, "removed");
|
||||
default:
|
||||
throw new UnexpectedValueException(sprintf('Unexpected entity state: %s', $entityState));
|
||||
throw new UnexpectedValueException("Unexpected entity state: $entityState." . self::objToStr($entity));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1665,8 +1658,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
if ($managedCopy) {
|
||||
// We have the entity in-memory already, just make sure its not removed.
|
||||
if ($this->getEntityState($managedCopy) == self::STATE_REMOVED) {
|
||||
throw new InvalidArgumentException('Removed entity detected during merge.'
|
||||
. ' Can not merge with a removed entity.');
|
||||
throw ORMInvalidArgumentException::entityIsRemoved($managedCopy, "merge");
|
||||
}
|
||||
} else {
|
||||
// We need to fetch the managed copy in order to merge.
|
||||
@ -1883,7 +1875,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$class = $this->em->getClassMetadata(get_class($entity));
|
||||
|
||||
if ($this->getEntityState($entity) !== self::STATE_MANAGED) {
|
||||
throw new InvalidArgumentException("Entity is not MANAGED.");
|
||||
throw ORMInvalidArgumentException::entityNotManaged($entity);
|
||||
}
|
||||
|
||||
$this->getEntityPersister($class->name)->refresh(
|
||||
@ -2107,7 +2099,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
public function lock($entity, $lockMode, $lockVersion = null)
|
||||
{
|
||||
if ($this->getEntityState($entity, self::STATE_DETACHED) != self::STATE_MANAGED) {
|
||||
throw new InvalidArgumentException("Entity is not MANAGED.");
|
||||
throw ORMInvalidArgumentException::entityNotManaged($entity);
|
||||
}
|
||||
|
||||
$entityName = get_class($entity);
|
||||
@ -2881,7 +2873,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
public function markReadOnly($object)
|
||||
{
|
||||
if ( ! is_object($object) || ! $this->isInIdentityMap($object)) {
|
||||
throw new InvalidArgumentException("Managed entity required");
|
||||
throw ORMInvalidArgumentException::readOnlyRequiresManagedEntity($object);
|
||||
}
|
||||
|
||||
$this->readOnlyObjects[spl_object_hash($object)] = true;
|
||||
@ -2897,7 +2889,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
public function isReadOnly($object)
|
||||
{
|
||||
if ( ! is_object($object) ) {
|
||||
throw new InvalidArgumentException("Managed entity required");
|
||||
throw ORMInvalidArgumentException::readOnlyRequiresManagedEntity($object);
|
||||
}
|
||||
|
||||
return isset($this->readOnlyObjects[spl_object_hash($object)]);
|
||||
|
@ -36,7 +36,7 @@ class Version
|
||||
/**
|
||||
* Current Doctrine Version
|
||||
*/
|
||||
const VERSION = '2.2.0-DEV';
|
||||
const VERSION = '2.3.0-DEV';
|
||||
|
||||
/**
|
||||
* Compares a Doctrine version with the current one.
|
||||
|
2
lib/vendor/doctrine-build-common
vendored
2
lib/vendor/doctrine-build-common
vendored
@ -1 +1 @@
|
||||
Subproject commit 5c43f26f82bde0234c0645e349fb12a48bd39c7f
|
||||
Subproject commit 5812b7acdc962196140e6b9f7a4758fb6d6f4933
|
2
lib/vendor/doctrine-common
vendored
2
lib/vendor/doctrine-common
vendored
@ -1 +1 @@
|
||||
Subproject commit ef7382756672d99c92b746aea56f10295edfc96b
|
||||
Subproject commit cc04744bcf5a4743c46fae0487ac7a093a722856
|
2
lib/vendor/doctrine-dbal
vendored
2
lib/vendor/doctrine-dbal
vendored
@ -1 +1 @@
|
||||
Subproject commit 4410e4cec20b0f1f209578320e5b7d111e90c2a0
|
||||
Subproject commit 29b714b7fe72641d749ae90324a5759853fe09b0
|
@ -14,4 +14,4 @@ class CompanyAuction extends CompanyEvent {
|
||||
public function getData() {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ abstract class CompanyContract
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ManyToOne(targetEntity="CompanyEmployee")
|
||||
* @ManyToOne(targetEntity="CompanyEmployee", inversedBy="soldContracts")
|
||||
*/
|
||||
private $salesPerson;
|
||||
|
||||
@ -32,7 +32,7 @@ abstract class CompanyContract
|
||||
private $completed = false;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="CompanyEmployee")
|
||||
* @ManyToMany(targetEntity="CompanyEmployee", inversedBy="contracts")
|
||||
* @JoinTable(name="company_contract_employees",
|
||||
* joinColumns={@JoinColumn(name="contract_id", referencedColumnName="id", onDelete="CASCADE")},
|
||||
* inverseJoinColumns={@JoinColumn(name="employee_id", referencedColumnName="id")}
|
||||
@ -86,4 +86,4 @@ abstract class CompanyContract
|
||||
}
|
||||
|
||||
abstract public function calculatePrice();
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,16 @@ class CompanyEmployee extends CompanyPerson
|
||||
*/
|
||||
private $startDate;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="CompanyContract", mappedBy="engineers", fetch="EXTRA_LAZY")
|
||||
*/
|
||||
public $contracts;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="CompanyFlexUltraContract", mappedBy="salesPerson", fetch="EXTRA_LAZY")
|
||||
*/
|
||||
public $soldContracts;
|
||||
|
||||
public function getSalary() {
|
||||
return $this->salary;
|
||||
}
|
||||
@ -46,4 +56,4 @@ class CompanyEmployee extends CompanyPerson
|
||||
public function setStartDate($date) {
|
||||
$this->startDate = $date;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,15 @@ class CompanyFlexContract extends CompanyContract
|
||||
*/
|
||||
private $pricePerHour = 0;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="CompanyManager", inversedBy="managedContracts", fetch="EXTRA_LAZY")
|
||||
* @JoinTable(name="company_contract_managers",
|
||||
* joinColumns={@JoinColumn(name="contract_id", referencedColumnName="id", onDelete="CASCADE")},
|
||||
* inverseJoinColumns={@JoinColumn(name="employee_id", referencedColumnName="id")}
|
||||
* )
|
||||
*/
|
||||
public $managers;
|
||||
|
||||
public function calculatePrice()
|
||||
{
|
||||
return $this->hoursWorked * $this->pricePerHour;
|
||||
@ -42,4 +51,18 @@ class CompanyFlexContract extends CompanyContract
|
||||
{
|
||||
$this->pricePerHour = $pricePerHour;
|
||||
}
|
||||
}
|
||||
public function getManagers()
|
||||
{
|
||||
return $this->managers;
|
||||
}
|
||||
|
||||
public function addManager(CompanyManager $manager)
|
||||
{
|
||||
$this->managers[] = $manager;
|
||||
}
|
||||
|
||||
public function removeManager(CompanyManager $manager)
|
||||
{
|
||||
$this->managers->removeElement($manager);
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,11 @@ class CompanyManager extends CompanyEmployee
|
||||
*/
|
||||
private $car;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="CompanyFlexContract", mappedBy="managers", fetch="EXTRA_LAZY")
|
||||
*/
|
||||
public $managedContracts;
|
||||
|
||||
public function getTitle() {
|
||||
return $this->title;
|
||||
}
|
||||
@ -34,4 +39,4 @@ class CompanyManager extends CompanyEmployee
|
||||
public function setCar(CompanyCar $car) {
|
||||
$this->car = $car;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,9 +11,9 @@ class CompanyOrganization {
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="CompanyEvent", mappedBy="organization", cascade={"persist"})
|
||||
* @OneToMany(targetEntity="CompanyEvent", mappedBy="organization", cascade={"persist"}, fetch="EXTRA_LAZY")
|
||||
*/
|
||||
private $events;
|
||||
public $events;
|
||||
|
||||
public function getId() {
|
||||
return $this->id;
|
||||
@ -41,4 +41,4 @@ class CompanyOrganization {
|
||||
public function setMainEvent($event) {
|
||||
$this->mainevent = $event;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,10 +114,10 @@ class EntityManagerTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
/**
|
||||
* @dataProvider dataMethodsAffectedByNoObjectArguments
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @param string $methodName
|
||||
*/
|
||||
public function testThrowsExceptionOnNonObjectValues($methodName) {
|
||||
$this->setExpectedException('Doctrine\ORM\ORMInvalidArgumentException',
|
||||
'EntityManager#'.$methodName.'() expects parameter 1 to be an entity object, NULL given.');
|
||||
$this->_em->$methodName(null);
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ class LockTest extends \Doctrine\Tests\OrmFunctionalTestCase {
|
||||
public function testLockUnmanagedEntity_ThrowsException() {
|
||||
$article = new CmsArticle();
|
||||
|
||||
$this->setExpectedException('InvalidArgumentException', 'Entity is not MANAGED.');
|
||||
$this->setExpectedException('InvalidArgumentException', 'Entity Doctrine\Tests\Models\CMS\CmsArticle');
|
||||
$this->_em->lock($article, LockMode::OPTIMISTIC, $article->version + 1);
|
||||
}
|
||||
|
||||
|
@ -167,20 +167,21 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
public function testFunctionSubstring()
|
||||
{
|
||||
$dql = "SELECT m, SUBSTRING(m.name, 1, 3) AS str1, SUBSTRING(m.name, 5) AS str2 ".
|
||||
"FROM Doctrine\Tests\Models\Company\CompanyManager m";
|
||||
"FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.name";
|
||||
|
||||
$result = $this->_em->createQuery($dql)
|
||||
->getArrayResult();
|
||||
|
||||
$this->assertEquals(4, count($result));
|
||||
$this->assertEquals('Rom', $result[0]['str1']);
|
||||
$this->assertEquals('Ben', $result[1]['str1']);
|
||||
$this->assertEquals('Gui', $result[2]['str1']);
|
||||
$this->assertEquals('Jon', $result[3]['str1']);
|
||||
$this->assertEquals('n B.', $result[0]['str2']);
|
||||
$this->assertEquals('amin E.', $result[1]['str2']);
|
||||
$this->assertEquals('herme B.', $result[2]['str2']);
|
||||
$this->assertEquals('than W.', $result[3]['str2']);
|
||||
$this->assertEquals('Ben', $result[0]['str1']);
|
||||
$this->assertEquals('Gui', $result[1]['str1']);
|
||||
$this->assertEquals('Jon', $result[2]['str1']);
|
||||
$this->assertEquals('Rom', $result[3]['str1']);
|
||||
|
||||
$this->assertEquals('amin E.', $result[0]['str2']);
|
||||
$this->assertEquals('herme B.', $result[1]['str2']);
|
||||
$this->assertEquals('than W.', $result[2]['str2']);
|
||||
$this->assertEquals('n B.', $result[3]['str2']);
|
||||
}
|
||||
|
||||
public function testFunctionTrim()
|
||||
|
@ -87,7 +87,7 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$query = $this->_em->createQuery("select u, a from Doctrine\Tests\Models\CMS\CmsUser u join u.articles a");
|
||||
$query = $this->_em->createQuery("select u, a from Doctrine\Tests\Models\CMS\CmsUser u join u.articles a ORDER BY a.topic");
|
||||
$users = $query->getResult();
|
||||
$this->assertEquals(1, count($users));
|
||||
$this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $users[0]);
|
||||
|
@ -19,6 +19,8 @@ use Doctrine\Tests\Models\CMS\CmsComment;
|
||||
use Doctrine\Tests\Models\Company\CompanyPerson;
|
||||
use Doctrine\Tests\Models\Company\CompanyManager;
|
||||
use Doctrine\Tests\Models\Company\CompanyEmployee;
|
||||
use Doctrine\Tests\Models\Company\CompanyOrganization;
|
||||
use Doctrine\Tests\Models\Company\CompanyAuction;
|
||||
|
||||
use Doctrine\Tests\Models\Company\CompanyFlexContract;
|
||||
use Doctrine\Tests\Models\Company\CompanyFlexUltraContract;
|
||||
@ -34,6 +36,8 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
private $userId, $userId2, $articleId, $articleId2;
|
||||
private $groupId, $groupId2;
|
||||
private $managerId, $managerId2, $contractId1, $contractId2;
|
||||
private $organizationId, $eventId1, $eventId2;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
@ -552,11 +556,7 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->assertEquals(2, count($this->_em->createQuery("SELECT cm FROM Doctrine\Tests\Models\Company\CompanyManager cm")->getResult()));
|
||||
|
||||
// Enable the filter
|
||||
$conf = $this->_em->getConfiguration();
|
||||
$conf->addFilter("person_name", "\Doctrine\Tests\ORM\Functional\CompanyPersonNameFilter");
|
||||
$this->_em->getFilters()
|
||||
->enable("person_name")
|
||||
->setParameter("name", "Guilh%", DBALType::STRING);
|
||||
$this->usePersonNameFilter('Guilh%');
|
||||
|
||||
$managers = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyManager')->findAll();
|
||||
$this->assertEquals(1, count($managers));
|
||||
@ -572,11 +572,7 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->assertEquals(3, count($this->_em->createQuery("SELECT cp FROM Doctrine\Tests\Models\Company\CompanyPerson cp")->getResult()));
|
||||
|
||||
// Enable the filter
|
||||
$conf = $this->_em->getConfiguration();
|
||||
$conf->addFilter("person_name", "\Doctrine\Tests\ORM\Functional\CompanyPersonNameFilter");
|
||||
$this->_em->getFilters()
|
||||
->enable("person_name")
|
||||
->setParameter("name", "Guilh%", DBALType::STRING);
|
||||
$this->usePersonNameFilter('Guilh%');
|
||||
|
||||
$persons = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyPerson')->findAll();
|
||||
$this->assertEquals(1, count($persons));
|
||||
@ -655,12 +651,302 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$contract4 = new CompanyFlexContract;
|
||||
$contract4->markCompleted();
|
||||
|
||||
$manager = new CompanyManager;
|
||||
$manager->setName('Alexander');
|
||||
$manager->setSalary(42);
|
||||
$manager->setDepartment('Doctrine');
|
||||
$manager->setTitle('Filterer');
|
||||
|
||||
$manager2 = new CompanyManager;
|
||||
$manager2->setName('Benjamin');
|
||||
$manager2->setSalary(1337);
|
||||
$manager2->setDepartment('Doctrine');
|
||||
$manager2->setTitle('Maintainer');
|
||||
|
||||
$contract1->addManager($manager);
|
||||
$contract2->addManager($manager);
|
||||
$contract3->addManager($manager);
|
||||
$contract4->addManager($manager);
|
||||
|
||||
$contract1->addManager($manager2);
|
||||
|
||||
$contract1->setSalesPerson($manager);
|
||||
$contract2->setSalesPerson($manager);
|
||||
|
||||
$this->_em->persist($manager);
|
||||
$this->_em->persist($manager2);
|
||||
$this->_em->persist($contract1);
|
||||
$this->_em->persist($contract2);
|
||||
$this->_em->persist($contract3);
|
||||
$this->_em->persist($contract4);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->managerId = $manager->getId();
|
||||
$this->managerId2 = $manager2->getId();
|
||||
$this->contractId1 = $contract1->getId();
|
||||
$this->contractId2 = $contract2->getId();
|
||||
}
|
||||
|
||||
private function useCompletedContractFilter()
|
||||
{
|
||||
$conf = $this->_em->getConfiguration();
|
||||
$conf->addFilter("completed_contract", "\Doctrine\Tests\ORM\Functional\CompletedContractFilter");
|
||||
$this->_em->getFilters()
|
||||
->enable("completed_contract")
|
||||
->setParameter("completed", true, DBALType::BOOLEAN);
|
||||
}
|
||||
|
||||
public function testManyToMany_ExtraLazyCountWithFilterOnSTI()
|
||||
{
|
||||
$this->loadCompanySingleTableInheritanceFixtureData();
|
||||
|
||||
$manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
|
||||
|
||||
$this->assertFalse($manager->managedContracts->isInitialized());
|
||||
$this->assertEquals(4, count($manager->managedContracts));
|
||||
|
||||
// Enable the filter
|
||||
$this->useCompletedContractFilter();
|
||||
|
||||
$this->assertFalse($manager->managedContracts->isInitialized());
|
||||
$this->assertEquals(2, count($manager->managedContracts));
|
||||
}
|
||||
|
||||
public function testManyToMany_ExtraLazyContainsWithFilterOnSTI()
|
||||
{
|
||||
$this->loadCompanySingleTableInheritanceFixtureData();
|
||||
|
||||
$manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
|
||||
$contract1 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->contractId1);
|
||||
$contract2 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->contractId2);
|
||||
|
||||
$this->assertFalse($manager->managedContracts->isInitialized());
|
||||
$this->assertTrue($manager->managedContracts->contains($contract1));
|
||||
$this->assertTrue($manager->managedContracts->contains($contract2));
|
||||
|
||||
// Enable the filter
|
||||
$this->useCompletedContractFilter();
|
||||
|
||||
$this->assertFalse($manager->managedContracts->isInitialized());
|
||||
$this->assertFalse($manager->managedContracts->contains($contract1));
|
||||
$this->assertTrue($manager->managedContracts->contains($contract2));
|
||||
}
|
||||
|
||||
public function testManyToMany_ExtraLazySliceWithFilterOnSTI()
|
||||
{
|
||||
$this->loadCompanySingleTableInheritanceFixtureData();
|
||||
|
||||
$manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
|
||||
|
||||
$this->assertFalse($manager->managedContracts->isInitialized());
|
||||
$this->assertEquals(4, count($manager->managedContracts->slice(0, 10)));
|
||||
|
||||
// Enable the filter
|
||||
$this->useCompletedContractFilter();
|
||||
|
||||
$this->assertFalse($manager->managedContracts->isInitialized());
|
||||
$this->assertEquals(2, count($manager->managedContracts->slice(0, 10)));
|
||||
}
|
||||
|
||||
private function usePersonNameFilter($name)
|
||||
{
|
||||
// Enable the filter
|
||||
$conf = $this->_em->getConfiguration();
|
||||
$conf->addFilter("person_name", "\Doctrine\Tests\ORM\Functional\CompanyPersonNameFilter");
|
||||
$this->_em->getFilters()
|
||||
->enable("person_name")
|
||||
->setParameter("name", $name, DBALType::STRING);
|
||||
}
|
||||
|
||||
public function testManyToMany_ExtraLazyCountWithFilterOnCTI()
|
||||
{
|
||||
$this->loadCompanySingleTableInheritanceFixtureData();
|
||||
|
||||
$contract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyFlexUltraContract', $this->contractId1);
|
||||
|
||||
$this->assertFalse($contract->managers->isInitialized());
|
||||
$this->assertEquals(2, count($contract->managers));
|
||||
|
||||
// Enable the filter
|
||||
$this->usePersonNameFilter('Benjamin');
|
||||
|
||||
$this->assertFalse($contract->managers->isInitialized());
|
||||
$this->assertEquals(1, count($contract->managers));
|
||||
}
|
||||
|
||||
public function testManyToMany_ExtraLazyContainsWithFilterOnCTI()
|
||||
{
|
||||
$this->loadCompanySingleTableInheritanceFixtureData();
|
||||
|
||||
$contract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyFlexUltraContract', $this->contractId1);
|
||||
$manager1 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
|
||||
$manager2 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId2);
|
||||
|
||||
$this->assertFalse($contract->managers->isInitialized());
|
||||
$this->assertTrue($contract->managers->contains($manager1));
|
||||
$this->assertTrue($contract->managers->contains($manager2));
|
||||
|
||||
// Enable the filter
|
||||
$this->usePersonNameFilter('Benjamin');
|
||||
|
||||
$this->assertFalse($contract->managers->isInitialized());
|
||||
$this->assertFalse($contract->managers->contains($manager1));
|
||||
$this->assertTrue($contract->managers->contains($manager2));
|
||||
}
|
||||
|
||||
public function testManyToMany_ExtraLazySliceWithFilterOnCTI()
|
||||
{
|
||||
$this->loadCompanySingleTableInheritanceFixtureData();
|
||||
|
||||
$contract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyFlexUltraContract', $this->contractId1);
|
||||
|
||||
$this->assertFalse($contract->managers->isInitialized());
|
||||
$this->assertEquals(2, count($contract->managers->slice(0, 10)));
|
||||
|
||||
// Enable the filter
|
||||
$this->usePersonNameFilter('Benjamin');
|
||||
|
||||
$this->assertFalse($contract->managers->isInitialized());
|
||||
$this->assertEquals(1, count($contract->managers->slice(0, 10)));
|
||||
}
|
||||
|
||||
public function testOneToMany_ExtraLazyCountWithFilterOnSTI()
|
||||
{
|
||||
$this->loadCompanySingleTableInheritanceFixtureData();
|
||||
|
||||
$manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
|
||||
|
||||
$this->assertFalse($manager->soldContracts->isInitialized());
|
||||
$this->assertEquals(2, count($manager->soldContracts));
|
||||
|
||||
// Enable the filter
|
||||
$this->useCompletedContractFilter();
|
||||
|
||||
$this->assertFalse($manager->soldContracts->isInitialized());
|
||||
$this->assertEquals(1, count($manager->soldContracts));
|
||||
}
|
||||
|
||||
public function testOneToMany_ExtraLazyContainsWithFilterOnSTI()
|
||||
{
|
||||
$this->loadCompanySingleTableInheritanceFixtureData();
|
||||
|
||||
$manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
|
||||
$contract1 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->contractId1);
|
||||
$contract2 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->contractId2);
|
||||
|
||||
$this->assertFalse($manager->soldContracts->isInitialized());
|
||||
$this->assertTrue($manager->soldContracts->contains($contract1));
|
||||
$this->assertTrue($manager->soldContracts->contains($contract2));
|
||||
|
||||
// Enable the filter
|
||||
$this->useCompletedContractFilter();
|
||||
|
||||
$this->assertFalse($manager->soldContracts->isInitialized());
|
||||
$this->assertFalse($manager->soldContracts->contains($contract1));
|
||||
$this->assertTrue($manager->soldContracts->contains($contract2));
|
||||
}
|
||||
|
||||
public function testOneToMany_ExtraLazySliceWithFilterOnSTI()
|
||||
{
|
||||
|
||||
$this->loadCompanySingleTableInheritanceFixtureData();
|
||||
|
||||
$manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
|
||||
|
||||
$this->assertFalse($manager->soldContracts->isInitialized());
|
||||
$this->assertEquals(2, count($manager->soldContracts->slice(0, 10)));
|
||||
|
||||
// Enable the filter
|
||||
$this->useCompletedContractFilter();
|
||||
|
||||
$this->assertFalse($manager->soldContracts->isInitialized());
|
||||
$this->assertEquals(1, count($manager->soldContracts->slice(0, 10)));
|
||||
}
|
||||
private function loadCompanyOrganizationEventJoinedSubclassFixtureData()
|
||||
{
|
||||
$organization = new CompanyOrganization;
|
||||
|
||||
$event1 = new CompanyAuction;
|
||||
$event1->setData('foo');
|
||||
|
||||
$event2 = new CompanyAuction;
|
||||
$event2->setData('bar');
|
||||
|
||||
$organization->addEvent($event1);
|
||||
$organization->addEvent($event2);
|
||||
|
||||
$this->_em->persist($organization);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->organizationId = $organization->getId();
|
||||
$this->eventId1 = $event1->getId();
|
||||
$this->eventId2 = $event2->getId();
|
||||
}
|
||||
|
||||
private function useCompanyEventIdFilter()
|
||||
{
|
||||
// Enable the filter
|
||||
$conf = $this->_em->getConfiguration();
|
||||
$conf->addFilter("event_id", "\Doctrine\Tests\ORM\Functional\CompanyEventFilter");
|
||||
$this->_em->getFilters()
|
||||
->enable("event_id")
|
||||
->setParameter("id", $this->eventId2);
|
||||
}
|
||||
|
||||
|
||||
public function testOneToMany_ExtraLazyCountWithFilterOnCTI()
|
||||
{
|
||||
$this->loadCompanyOrganizationEventJoinedSubclassFixtureData();
|
||||
|
||||
$organization = $this->_em->find('Doctrine\Tests\Models\Company\CompanyOrganization', $this->organizationId);
|
||||
|
||||
$this->assertFalse($organization->events->isInitialized());
|
||||
$this->assertEquals(2, count($organization->events));
|
||||
|
||||
// Enable the filter
|
||||
$this->useCompanyEventIdFilter();
|
||||
|
||||
$this->assertFalse($organization->events->isInitialized());
|
||||
$this->assertEquals(1, count($organization->events));
|
||||
}
|
||||
|
||||
public function testOneToMany_ExtraLazyContainsWithFilterOnCTI()
|
||||
{
|
||||
$this->loadCompanyOrganizationEventJoinedSubclassFixtureData();
|
||||
|
||||
$organization = $this->_em->find('Doctrine\Tests\Models\Company\CompanyOrganization', $this->organizationId);
|
||||
|
||||
$event1 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyEvent', $this->eventId1);
|
||||
$event2 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyEvent', $this->eventId2);
|
||||
|
||||
$this->assertFalse($organization->events->isInitialized());
|
||||
$this->assertTrue($organization->events->contains($event1));
|
||||
$this->assertTrue($organization->events->contains($event2));
|
||||
|
||||
// Enable the filter
|
||||
$this->useCompanyEventIdFilter();
|
||||
|
||||
$this->assertFalse($organization->events->isInitialized());
|
||||
$this->assertFalse($organization->events->contains($event1));
|
||||
$this->assertTrue($organization->events->contains($event2));
|
||||
}
|
||||
|
||||
public function testOneToMany_ExtraLazySliceWithFilterOnCTI()
|
||||
{
|
||||
$this->loadCompanyOrganizationEventJoinedSubclassFixtureData();
|
||||
|
||||
$organization = $this->_em->find('Doctrine\Tests\Models\Company\CompanyOrganization', $this->organizationId);
|
||||
|
||||
$this->assertFalse($organization->events->isInitialized());
|
||||
$this->assertEquals(2, count($organization->events->slice(0, 10)));
|
||||
|
||||
// Enable the filter
|
||||
$this->useCompanyEventIdFilter();
|
||||
|
||||
$this->assertFalse($organization->events->isInitialized());
|
||||
$this->assertEquals(1, count($organization->events->slice(0, 10)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -747,3 +1033,15 @@ class CompletedContractFilter extends SQLFilter
|
||||
return $targetTableAlias.'.completed = ' . $this->getParameter('completed');
|
||||
}
|
||||
}
|
||||
|
||||
class CompanyEventFilter extends SQLFilter
|
||||
{
|
||||
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
|
||||
{
|
||||
if ($targetEntity->name != "Doctrine\Tests\Models\Company\CompanyEvent") {
|
||||
return "";
|
||||
}
|
||||
|
||||
return $targetTableAlias.'.id = ' . $this->getParameter('id');
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,6 @@ class CompanySchemaTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$sql = $this->_schemaTool->getDropSchemaSQL(array(
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyManager'),
|
||||
));
|
||||
$this->assertEquals(3, count($sql));
|
||||
$this->assertEquals(4, count($sql));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ class DDC214Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
'Doctrine\Tests\Models\CMS\CmsPhonenumber',
|
||||
'Doctrine\Tests\Models\CMS\CmsAddress',
|
||||
'Doctrine\Tests\Models\CMS\CmsGroup',
|
||||
'Doctrine\Tests\Models\CMS\CmsArticle'
|
||||
'Doctrine\Tests\Models\CMS\CmsArticle',
|
||||
'Doctrine\Tests\Models\CMS\CmsEmail',
|
||||
);
|
||||
|
||||
$this->assertCreatedSchemaNeedsNoUpdates($this->classes);
|
||||
|
37
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1360Test.php
Normal file
37
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1360Test.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
/**
|
||||
* @group DDC-1360
|
||||
*/
|
||||
class DDC1360Test extends OrmFunctionalTestCase
|
||||
{
|
||||
public function testSchemaDoubleQuotedCreate()
|
||||
{
|
||||
if ($this->_em->getConnection()->getDatabasePlatform()->getName() != "postgresql") {
|
||||
$this->markTestSkipped("PostgreSQL only test.");
|
||||
}
|
||||
|
||||
$sql = $this->_schemaTool->getCreateSchemaSQL(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1360DoubleQuote')
|
||||
));
|
||||
|
||||
$this->assertEquals(array(
|
||||
'CREATE TABLE "user"."user" (id INT NOT NULL, PRIMARY KEY(id))',
|
||||
'CREATE SEQUENCE "user".user_id_seq INCREMENT BY 1 MINVALUE 1 START 1',
|
||||
), $sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity @Table(name="`user`.`user`")
|
||||
*/
|
||||
class DDC1360DoubleQuote
|
||||
{
|
||||
/** @Id @GeneratedValue @Column(type="integer") */
|
||||
public $id;
|
||||
}
|
||||
|
@ -2,14 +2,12 @@
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\Models\Qelista\User;
|
||||
|
||||
use Doctrine\Tests\Models\Qelista\ShoppingList;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
use Doctrine\Tests\Models\CMS\CmsComment;
|
||||
use Doctrine\Tests\Models\CMS\CmsArticle;
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
/**
|
||||
|
@ -46,6 +46,7 @@ class DDC1548E1
|
||||
*/
|
||||
public $rel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
|
@ -61,4 +61,4 @@ class DDC168Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyEmployee', $theEmployee);
|
||||
$this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyEmployee', $theEmployee->getSpouse());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
|
||||
class UnitOfWorkLifecycleTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->useModelSet('cms');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testScheduleInsertManaged()
|
||||
{
|
||||
$user = new CmsUser();
|
||||
$user->username = "beberlei";
|
||||
$user->name = "Benjamin";
|
||||
$user->status = "active";
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->setExpectedException("Doctrine\ORM\ORMInvalidArgumentException", "A managed+dirty entity Doctrine\Tests\Models\CMS\CmsUser");
|
||||
$this->_em->getUnitOfWork()->scheduleForInsert($user);
|
||||
}
|
||||
|
||||
public function testScheduleInsertDeleted()
|
||||
{
|
||||
$user = new CmsUser();
|
||||
$user->username = "beberlei";
|
||||
$user->name = "Benjamin";
|
||||
$user->status = "active";
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->_em->remove($user);
|
||||
|
||||
$this->setExpectedException("Doctrine\ORM\ORMInvalidArgumentException", "Removed entity Doctrine\Tests\Models\CMS\CmsUser");
|
||||
$this->_em->getUnitOfWork()->scheduleForInsert($user);
|
||||
}
|
||||
|
||||
public function testScheduleInsertTwice()
|
||||
{
|
||||
$user = new CmsUser();
|
||||
$user->username = "beberlei";
|
||||
$user->name = "Benjamin";
|
||||
$user->status = "active";
|
||||
|
||||
$this->_em->getUnitOfWork()->scheduleForInsert($user);
|
||||
|
||||
$this->setExpectedException("Doctrine\ORM\ORMInvalidArgumentException", "Entity Doctrine\Tests\Models\CMS\CmsUser");
|
||||
$this->_em->getUnitOfWork()->scheduleForInsert($user);
|
||||
}
|
||||
|
||||
public function testAddToIdentityMapWithoutIdentity()
|
||||
{
|
||||
$user = new CmsUser();
|
||||
|
||||
$this->setExpectedException("Doctrine\ORM\ORMInvalidArgumentException", "The given entity of type 'Doctrine\Tests\Models\CMS\CmsUser' (Doctrine\Tests\Models\CMS\CmsUser@");
|
||||
$this->_em->getUnitOfWork()->registerManaged($user, array(), array());
|
||||
}
|
||||
|
||||
public function testMarkReadOnlyNonManaged()
|
||||
{
|
||||
$user = new CmsUser();
|
||||
|
||||
$this->setExpectedException("Doctrine\ORM\ORMInvalidArgumentException", "Only managed entities can be marked or checked as read only. But Doctrine\Tests\Models\CMS\CmsUser@");
|
||||
$this->_em->getUnitOfWork()->markReadOnly($user);
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||
$mappingDriver = $this->_loadDriver();
|
||||
|
||||
$class = new ClassMetadata($entityClassName);
|
||||
$class->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$mappingDriver->loadMetadataForClass($entityClassName, $class);
|
||||
|
||||
return $class;
|
||||
@ -404,6 +405,29 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals("INT unsigned NOT NULL", $class->fieldMappings['id']['columnDefinition']);
|
||||
$this->assertEquals("VARCHAR(255) NOT NULL", $class->fieldMappings['value']['columnDefinition']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-559
|
||||
*/
|
||||
public function testNamingStrategy()
|
||||
{
|
||||
$driver = $this->_loadDriver();
|
||||
$em = $this->_getTestEntityManager();
|
||||
$factory = new \Doctrine\ORM\Mapping\ClassMetadataFactory();
|
||||
$em->getConfiguration()->setMetadataDriverImpl($driver);
|
||||
$factory->setEntityManager($em);
|
||||
|
||||
|
||||
$this->assertInstanceOf('Doctrine\ORM\Mapping\DefaultNamingStrategy', $em->getConfiguration()->getNamingStrategy());
|
||||
$em->getConfiguration()->setNamingStrategy(new \Doctrine\ORM\Mapping\UnderscoreNamingStrategy(CASE_UPPER));
|
||||
$this->assertInstanceOf('Doctrine\ORM\Mapping\UnderscoreNamingStrategy', $em->getConfiguration()->getNamingStrategy());
|
||||
|
||||
$class = $factory->getMetadataFor('Doctrine\Tests\Models\DDC1476\DDC1476EntityWithDefaultFieldType');
|
||||
|
||||
$this->assertEquals('ID', $class->columnNames['id']);
|
||||
$this->assertEquals('NAME', $class->columnNames['name']);
|
||||
$this->assertEquals('DDC1476ENTITY_WITH_DEFAULT_FIELD_TYPE', $class->table['name']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -691,4 +715,8 @@ class DDC1170Entity
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_NONE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Address {}
|
||||
class Phonenumber {}
|
||||
class Group {}
|
||||
|
@ -15,6 +15,7 @@ class AnnotationDriverTest extends AbstractMappingDriverTest
|
||||
public function testLoadMetadataForNonEntityThrowsException()
|
||||
{
|
||||
$cm = new ClassMetadata('stdClass');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$reader = new \Doctrine\Common\Annotations\AnnotationReader(new \Doctrine\Common\Cache\ArrayCache());
|
||||
$annotationDriver = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader);
|
||||
|
||||
@ -28,6 +29,7 @@ class AnnotationDriverTest extends AbstractMappingDriverTest
|
||||
public function testColumnWithMissingTypeDefaultsToString()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\ORM\Mapping\ColumnWithoutType');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$annotationDriver = $this->_loadDriver();
|
||||
|
||||
$annotationDriver->loadMetadataForClass('Doctrine\Tests\ORM\Mapping\InvalidColumn', $cm);
|
||||
|
@ -91,6 +91,7 @@ class BasicInheritanceMappingTest extends \Doctrine\Tests\OrmTestCase
|
||||
$class = $this->_factory->getMetadataFor(__NAMESPACE__ . '\\EntitySubClass2');
|
||||
|
||||
$class2 = unserialize(serialize($class));
|
||||
$class2->wakeupReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$this->assertTrue(isset($class2->reflFields['mapped1']));
|
||||
$this->assertTrue(isset($class2->reflFields['mapped2']));
|
||||
@ -197,6 +198,7 @@ class MappedSuperclassBase {
|
||||
private $mappedRelated1;
|
||||
private $transient;
|
||||
}
|
||||
class MappedSuperclassRelated1 {}
|
||||
|
||||
/** @Entity */
|
||||
class EntitySubClass2 extends MappedSuperclassBase {
|
||||
@ -314,4 +316,4 @@ class MediumSuperclassEntity extends MediumSuperclassBase
|
||||
class SubclassWithRepository extends \Doctrine\Tests\Models\DDC869\DDC869Payment
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ class ClassMetadataBuilderTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function setUp()
|
||||
{
|
||||
$this->cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$this->cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$this->builder = new ClassMetadataBuilder($this->cm);
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,9 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
|
||||
$cm1 = $this->_createValidClassMetadata();
|
||||
|
||||
// SUT
|
||||
$cmf = new ClassMetadataFactoryTestSubject();
|
||||
$cmf = new \Doctrine\ORM\Mapping\ClassMetadataFactory();
|
||||
$cmf->setEntityManager($entityManager);
|
||||
$cmf->setMetadataForClass($cm1->name, $cm1);
|
||||
$cmf->setMetadataFor($cm1->name, $cm1);
|
||||
|
||||
// Prechecks
|
||||
$this->assertEquals(array(), $cm1->parentClasses);
|
||||
@ -37,15 +37,16 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertTrue($cm1->hasField('name'));
|
||||
$this->assertEquals(2, count($cm1->associationMappings));
|
||||
$this->assertEquals(ClassMetadata::GENERATOR_TYPE_AUTO, $cm1->generatorType);
|
||||
$this->assertEquals('group', $cm1->table['name']);
|
||||
|
||||
// Go
|
||||
$cm1 = $cmf->getMetadataFor($cm1->name);
|
||||
$cmMap1 = $cmf->getMetadataFor($cm1->name);
|
||||
|
||||
$this->assertEquals('group', $cm1->table['name']);
|
||||
$this->assertTrue($cm1->table['quoted']);
|
||||
$this->assertEquals(array(), $cm1->parentClasses);
|
||||
$this->assertTrue($cm1->hasField('name'));
|
||||
$this->assertEquals(ClassMetadata::GENERATOR_TYPE_SEQUENCE, $cm1->generatorType);
|
||||
$this->assertSame($cm1, $cmMap1);
|
||||
$this->assertEquals('group', $cmMap1->table['name']);
|
||||
$this->assertTrue($cmMap1->table['quoted']);
|
||||
$this->assertEquals(array(), $cmMap1->parentClasses);
|
||||
$this->assertTrue($cmMap1->hasField('name'));
|
||||
}
|
||||
|
||||
public function testGetMetadataFor_ReturnsLoadedCustomIdGenerator()
|
||||
@ -202,6 +203,7 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
|
||||
*/
|
||||
protected function _createValidClassMetadata()
|
||||
{
|
||||
// Self-made metadata
|
||||
$cm1 = new ClassMetadata('Doctrine\Tests\ORM\Mapping\TestEntity1');
|
||||
$cm1->setPrimaryTable(array('name' => '`group`'));
|
||||
// Add a mapped field
|
||||
|
@ -13,6 +13,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testClassMetadataInstanceSerialization()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
// Test initial state
|
||||
$this->assertTrue(count($cm->getReflectionProperties()) == 0);
|
||||
@ -29,13 +30,14 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
$cm->setParentClasses(array("UserParent"));
|
||||
$cm->setCustomRepositoryClass("UserRepository");
|
||||
$cm->setDiscriminatorColumn(array('name' => 'disc', 'type' => 'integer'));
|
||||
$cm->mapOneToOne(array('fieldName' => 'phonenumbers', 'targetEntity' => 'Bar', 'mappedBy' => 'foo'));
|
||||
$cm->mapOneToOne(array('fieldName' => 'phonenumbers', 'targetEntity' => 'CmsAddress', 'mappedBy' => 'foo'));
|
||||
$cm->markReadOnly();
|
||||
$cm->addNamedQuery(array('name' => 'dql', 'query' => 'foo'));
|
||||
$this->assertEquals(1, count($cm->associationMappings));
|
||||
|
||||
$serialized = serialize($cm);
|
||||
$cm = unserialize($serialized);
|
||||
$cm->wakeupReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
// Check state
|
||||
$this->assertTrue(count($cm->getReflectionProperties()) > 0);
|
||||
@ -52,7 +54,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
$oneOneMapping = $cm->getAssociationMapping('phonenumbers');
|
||||
$this->assertTrue($oneOneMapping['fetch'] == ClassMetadata::FETCH_LAZY);
|
||||
$this->assertEquals('phonenumbers', $oneOneMapping['fieldName']);
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\Bar', $oneOneMapping['targetEntity']);
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddress', $oneOneMapping['targetEntity']);
|
||||
$this->assertTrue($cm->isReadOnly);
|
||||
$this->assertEquals(array('dql' => array('name'=>'dql','query'=>'foo','dql'=>'foo')), $cm->namedQueries);
|
||||
}
|
||||
@ -60,6 +62,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testFieldIsNullable()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
// Explicit Nullable
|
||||
$cm->mapField(array('fieldName' => 'status', 'nullable' => true, 'type' => 'string', 'length' => 50));
|
||||
@ -82,6 +85,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
require_once __DIR__."/../../Models/Global/GlobalNamespaceModel.php";
|
||||
|
||||
$cm = new ClassMetadata('DoctrineGlobal_Article');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$cm->mapManyToMany(array(
|
||||
'fieldName' => 'author',
|
||||
'targetEntity' => 'DoctrineGlobal_User',
|
||||
@ -98,6 +102,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testMapManyToManyJoinTableDefaults()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$cm->mapManyToMany(
|
||||
array(
|
||||
'fieldName' => 'groups',
|
||||
@ -117,6 +122,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testSerializeManyToManyJoinTableCascade()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$cm->mapManyToMany(
|
||||
array(
|
||||
'fieldName' => 'groups',
|
||||
@ -138,6 +144,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
require_once __DIR__."/../../Models/Global/GlobalNamespaceModel.php";
|
||||
|
||||
$cm = new ClassMetadata('DoctrineGlobal_User');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$cm->setDiscriminatorMap(array('descr' => 'DoctrineGlobal_Article', 'foo' => 'DoctrineGlobal_User'));
|
||||
|
||||
$this->assertEquals("DoctrineGlobal_Article", $cm->discriminatorMap['descr']);
|
||||
@ -152,6 +159,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
require_once __DIR__."/../../Models/Global/GlobalNamespaceModel.php";
|
||||
|
||||
$cm = new ClassMetadata('DoctrineGlobal_User');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$cm->setSubclasses(array('DoctrineGlobal_Article'));
|
||||
|
||||
$this->assertEquals("DoctrineGlobal_Article", $cm->subClasses[0]);
|
||||
@ -167,6 +175,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
$field['type'] = 'string';
|
||||
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
|
||||
$cm->setVersionMapping($field);
|
||||
@ -175,6 +184,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testGetSingleIdentifierFieldName_MultipleIdentifierEntity_ThrowsException()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$cm->isIdentifierComposite = true;
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
|
||||
@ -184,6 +194,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testDuplicateAssociationMappingException()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$a1 = array('fieldName' => 'foo', 'sourceEntity' => 'stdClass', 'targetEntity' => 'stdClass', 'mappedBy' => 'foo');
|
||||
$a2 = array('fieldName' => 'foo', 'sourceEntity' => 'stdClass', 'targetEntity' => 'stdClass', 'mappedBy' => 'foo');
|
||||
|
||||
@ -195,6 +207,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testDuplicateColumnName_ThrowsMappingException()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->mapField(array('fieldName' => 'name', 'columnName' => 'name'));
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
|
||||
@ -204,6 +218,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testDuplicateColumnName_DiscriminatorColumn_ThrowsMappingException()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->mapField(array('fieldName' => 'name', 'columnName' => 'name'));
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
|
||||
@ -213,6 +229,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testDuplicateColumnName_DiscriminatorColumn2_ThrowsMappingException()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->setDiscriminatorColumn(array('name' => 'name'));
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
|
||||
@ -222,6 +240,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testDuplicateFieldAndAssocationMapping1_ThrowsException()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->mapField(array('fieldName' => 'name', 'columnName' => 'name'));
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
|
||||
@ -231,6 +251,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testDuplicateFieldAndAssocationMapping2_ThrowsException()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->mapOneToOne(array('fieldName' => 'name', 'targetEntity' => 'CmsUser'));
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
|
||||
@ -243,6 +265,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testGetTemporaryTableNameSchema()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->setTableName('foo.bar');
|
||||
|
||||
$this->assertEquals('foo_bar_id_tmp', $cm->getTemporaryIdTableName());
|
||||
@ -251,6 +275,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testDefaultTableName()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
// When table's name is not given
|
||||
$primaryTable = array();
|
||||
@ -260,6 +285,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals('CmsUser', $cm->table['name']);
|
||||
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
// When joinTable's name is not given
|
||||
$cm->mapManyToMany(array(
|
||||
'fieldName' => 'user',
|
||||
@ -273,6 +299,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testDefaultJoinColumnName()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
// this is really dirty, but it's the simpliest way to test whether
|
||||
// joinColumn's name will be automatically set to user_id
|
||||
$cm->mapOneToOne(array(
|
||||
@ -282,6 +310,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals('user_id', $cm->associationMappings['user']['joinColumns'][0]['name']);
|
||||
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$cm->mapManyToMany(array(
|
||||
'fieldName' => 'user',
|
||||
'targetEntity' => 'CmsUser',
|
||||
@ -293,12 +322,59 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals('cmsuser_id', $cm->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-559
|
||||
*/
|
||||
public function testUnderscoreNamingStrategyDefaults()
|
||||
{
|
||||
$namingStrategy = new \Doctrine\ORM\Mapping\UnderscoreNamingStrategy(CASE_UPPER);
|
||||
$oneToOneMetadata = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', $namingStrategy);
|
||||
$manyToManyMetadata = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', $namingStrategy);
|
||||
|
||||
$oneToOneMetadata->mapOneToOne(array(
|
||||
'fieldName' => 'user',
|
||||
'targetEntity' => 'CmsUser'
|
||||
));
|
||||
|
||||
$manyToManyMetadata->mapManyToMany(array(
|
||||
'fieldName' => 'user',
|
||||
'targetEntity' => 'CmsUser'
|
||||
));
|
||||
|
||||
$this->assertEquals(array('USER_ID'=>'ID'), $oneToOneMetadata->associationMappings['user']['sourceToTargetKeyColumns']);
|
||||
$this->assertEquals(array('USER_ID'=>'USER_ID'), $oneToOneMetadata->associationMappings['user']['joinColumnFieldNames']);
|
||||
$this->assertEquals(array('ID'=>'USER_ID'), $oneToOneMetadata->associationMappings['user']['targetToSourceKeyColumns']);
|
||||
|
||||
$this->assertEquals('USER_ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['name']);
|
||||
$this->assertEquals('ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['referencedColumnName']);
|
||||
|
||||
|
||||
$this->assertEquals('CMS_ADDRESS_CMS_USER', $manyToManyMetadata->associationMappings['user']['joinTable']['name']);
|
||||
|
||||
$this->assertEquals(array('CMS_ADDRESS_ID','CMS_USER_ID'), $manyToManyMetadata->associationMappings['user']['joinTableColumns']);
|
||||
$this->assertEquals(array('CMS_ADDRESS_ID'=>'ID'), $manyToManyMetadata->associationMappings['user']['relationToSourceKeyColumns']);
|
||||
$this->assertEquals(array('CMS_USER_ID'=>'ID'), $manyToManyMetadata->associationMappings['user']['relationToTargetKeyColumns']);
|
||||
|
||||
$this->assertEquals('CMS_ADDRESS_ID', $manyToManyMetadata->associationMappings['user']['joinTable']['joinColumns'][0]['name']);
|
||||
$this->assertEquals('CMS_USER_ID', $manyToManyMetadata->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['name']);
|
||||
|
||||
$this->assertEquals('ID', $manyToManyMetadata->associationMappings['user']['joinTable']['joinColumns'][0]['referencedColumnName']);
|
||||
$this->assertEquals('ID', $manyToManyMetadata->associationMappings['user']['joinTable']['inverseJoinColumns'][0]['referencedColumnName']);
|
||||
|
||||
|
||||
$cm = new ClassMetadata('DoctrineGlobal_Article', $namingStrategy);
|
||||
$cm->mapManyToMany(array('fieldName' => 'author', 'targetEntity' => 'Doctrine\Tests\Models\CMS\CmsUser'));
|
||||
$this->assertEquals('DOCTRINE_GLOBAL_ARTICLE_CMS_USER', $cm->associationMappings['author']['joinTable']['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-886
|
||||
*/
|
||||
public function testSetMultipleIdentifierSetsComposite()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->mapField(array('fieldName' => 'name'));
|
||||
$cm->mapField(array('fieldName' => 'username'));
|
||||
|
||||
@ -312,6 +388,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testMappingNotFound()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException', "No mapping found for field 'foo' on class 'Doctrine\Tests\Models\CMS\CmsUser'.");
|
||||
$cm->getFieldMapping('foo');
|
||||
@ -323,6 +400,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testJoinTableMappingDefaults()
|
||||
{
|
||||
$cm = new ClassMetadata('DoctrineGlobal_Article');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->mapManyToMany(array('fieldName' => 'author', 'targetEntity' => 'Doctrine\Tests\Models\CMS\CmsUser'));
|
||||
|
||||
$this->assertEquals('doctrineglobal_article_cmsuser', $cm->associationMappings['author']['joinTable']['name']);
|
||||
@ -334,6 +413,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testMapIdentifierAssociation()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->mapOneToOne(array(
|
||||
'fieldName' => 'article',
|
||||
'id' => true,
|
||||
@ -351,6 +432,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testOrphanRemovalIdentifierAssociation()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException', 'The orphan removal option is not allowed on an association that');
|
||||
$cm->mapOneToOne(array(
|
||||
@ -368,6 +450,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testInverseIdentifierAssocation()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException', 'An inverse association is not allowed to be identifier in');
|
||||
$cm->mapOneToOne(array(
|
||||
@ -385,6 +469,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testIdentifierAssocationManyToMany()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException', 'Many-to-many or one-to-many associations are not allowed to be identifier in');
|
||||
$cm->mapManyToMany(array(
|
||||
@ -403,12 +489,16 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException',
|
||||
"The field or association mapping misses the 'fieldName' attribute in entity 'Doctrine\Tests\Models\CMS\CmsUser'.");
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->mapField(array('fieldName' => ''));
|
||||
}
|
||||
|
||||
public function testRetrievalOfNamedQueries()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
|
||||
$this->assertEquals(0, count($cm->getNamedQueries()));
|
||||
|
||||
@ -423,6 +513,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testExistanceOfNamedQuery()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
|
||||
$cm->addNamedQuery(array(
|
||||
'name' => 'all',
|
||||
@ -436,6 +528,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testRetrieveOfNamedQuery()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
|
||||
$cm->addNamedQuery(array(
|
||||
'name' => 'userById',
|
||||
@ -448,6 +542,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testNamingCollisionNamedQueryShouldThrowException()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
|
||||
|
||||
@ -469,6 +565,8 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
$user = new \Doctrine\Tests\Models\CMS\CmsUser();
|
||||
$cm = new ClassMetadata('DOCTRINE\TESTS\MODELS\CMS\CMSUSER');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $cm->name);
|
||||
}
|
||||
|
||||
@ -478,8 +576,23 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testLifecycleCallbackNotFound()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$cm->addLifecycleCallback('notfound', 'postLoad');
|
||||
|
||||
$this->setExpectedException("Doctrine\ORM\Mapping\MappingException", "Entity 'Doctrine\Tests\Models\CMS\CmsUser' has no method 'notfound' to be registered as lifecycle callback.");
|
||||
$cm->addLifecycleCallback('notfound', 'postLoad');
|
||||
$cm->validateLifecycleCallbacks(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group ImproveErrorMessages
|
||||
*/
|
||||
public function testTargetEntityNotFound()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$cm->mapManyToOne(array('fieldName' => 'address', 'targetEntity' => 'UnknownClass'));
|
||||
|
||||
$this->setExpectedException("Doctrine\ORM\Mapping\MappingException", "The target-entity Doctrine\Tests\Models\CMS\UnknownClass cannot be found in 'Doctrine\Tests\Models\CMS\CmsUser#address'.");
|
||||
$cm->validateAssocations();
|
||||
}
|
||||
}
|
||||
|
298
tests/Doctrine/Tests/ORM/Mapping/NamingStrategyTest.php
Normal file
298
tests/Doctrine/Tests/ORM/Mapping/NamingStrategyTest.php
Normal file
@ -0,0 +1,298 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Mapping;
|
||||
|
||||
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
|
||||
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
|
||||
use Doctrine\ORM\Mapping\NamingStrategy;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
/**
|
||||
* @group DDC-559
|
||||
*/
|
||||
class NamingStrategyTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
/**
|
||||
* @return DefaultNamingStrategy
|
||||
*/
|
||||
static private function defaultNaming()
|
||||
{
|
||||
return new DefaultNamingStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UnderscoreNamingStrategy
|
||||
*/
|
||||
static private function underscoreNamingLower()
|
||||
{
|
||||
return new UnderscoreNamingStrategy(CASE_LOWER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UnderscoreNamingStrategy
|
||||
*/
|
||||
static private function underscoreNamingUpper()
|
||||
{
|
||||
return new UnderscoreNamingStrategy(CASE_UPPER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data Provider for NamingStrategy#classToTableName
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function dataClassToTableName()
|
||||
{
|
||||
return array(
|
||||
// DefaultNamingStrategy
|
||||
array(self::defaultNaming(), 'SomeClassName',
|
||||
'SomeClassName'
|
||||
),
|
||||
array(self::defaultNaming(), 'SomeClassName',
|
||||
'\SomeClassName'
|
||||
),
|
||||
array(self::defaultNaming(), 'Name',
|
||||
'\Some\Class\Name'
|
||||
),
|
||||
|
||||
// UnderscoreNamingStrategy
|
||||
array(self::underscoreNamingLower(), 'some_class_name',
|
||||
'\Name\Space\SomeClassName'
|
||||
),
|
||||
array(self::underscoreNamingLower(), 'name',
|
||||
'\Some\Class\Name'
|
||||
),
|
||||
array(self::underscoreNamingUpper(), 'SOME_CLASS_NAME',
|
||||
'\Name\Space\SomeClassName'
|
||||
),
|
||||
array(self::underscoreNamingUpper(), 'NAME',
|
||||
'\Some\Class\Name'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataClassToTableName
|
||||
*/
|
||||
public function testClassToTableName(NamingStrategy $strategy, $expected, $className)
|
||||
{
|
||||
$this->assertEquals($expected, $strategy->classToTableName($className));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data Provider for NamingStrategy#propertyToColumnName
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function dataPropertyToColumnName()
|
||||
{
|
||||
return array(
|
||||
// DefaultNamingStrategy
|
||||
array(self::defaultNaming(), 'someProperty',
|
||||
'someProperty'
|
||||
),
|
||||
array(self::defaultNaming(), 'SOME_PROPERTY',
|
||||
'SOME_PROPERTY'
|
||||
),
|
||||
array(self::defaultNaming(), 'some_property',
|
||||
'some_property'
|
||||
),
|
||||
|
||||
// UnderscoreNamingStrategy
|
||||
array(self::underscoreNamingLower(), 'some_property',
|
||||
'someProperty'
|
||||
),
|
||||
array(self::underscoreNamingUpper(), 'SOME_PROPERTY',
|
||||
'someProperty'
|
||||
),
|
||||
array(self::underscoreNamingUpper(), 'SOME_PROPERTY',
|
||||
'some_property'
|
||||
),
|
||||
array(self::underscoreNamingUpper(), 'SOME_PROPERTY',
|
||||
'SOME_PROPERTY'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataPropertyToColumnName
|
||||
*
|
||||
* @param NamingStrategy $strategy
|
||||
* @param string $expected
|
||||
* @param string $propertyName
|
||||
*/
|
||||
public function testPropertyToColumnName(NamingStrategy $strategy, $expected, $propertyName)
|
||||
{
|
||||
$this->assertEquals($expected, $strategy->propertyToColumnName($propertyName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data Provider for NamingStrategy#referenceColumnName
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function dataReferenceColumnName()
|
||||
{
|
||||
return array(
|
||||
// DefaultNamingStrategy
|
||||
array(self::defaultNaming(), 'id'),
|
||||
|
||||
// UnderscoreNamingStrategy
|
||||
array(self::underscoreNamingLower(), 'id'),
|
||||
array(self::underscoreNamingUpper(), 'ID'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataReferenceColumnName
|
||||
*
|
||||
* @param NamingStrategy $strategy
|
||||
* @param string $expected
|
||||
*/
|
||||
public function testReferenceColumnName(NamingStrategy $strategy, $expected)
|
||||
{
|
||||
$this->assertEquals($expected, $strategy->referenceColumnName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data Provider for NamingStrategy#joinColumnName
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function dataJoinColumnName()
|
||||
{
|
||||
return array(
|
||||
// DefaultNamingStrategy
|
||||
array(self::defaultNaming(), 'someColumn_id',
|
||||
'someColumn', null,
|
||||
),
|
||||
array(self::defaultNaming(), 'some_column_id',
|
||||
'some_column', null,
|
||||
),
|
||||
|
||||
// UnderscoreNamingStrategy
|
||||
array(self::underscoreNamingLower(), 'some_column_id',
|
||||
'someColumn', null,
|
||||
),
|
||||
array(self::underscoreNamingUpper(), 'SOME_COLUMN_ID',
|
||||
'someColumn', null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataJoinColumnName
|
||||
*
|
||||
* @param NamingStrategy $strategy
|
||||
* @param string $expected
|
||||
* @param string $propertyName
|
||||
*/
|
||||
public function testJoinColumnName(NamingStrategy $strategy, $expected, $propertyName)
|
||||
{
|
||||
$this->assertEquals($expected, $strategy->joinColumnName($propertyName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data Provider for NamingStrategy#joinTableName
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function dataJoinTableName()
|
||||
{
|
||||
return array(
|
||||
// DefaultNamingStrategy
|
||||
array(self::defaultNaming(), 'someclassname_classname',
|
||||
'SomeClassName', 'Some\ClassName', null,
|
||||
),
|
||||
array(self::defaultNaming(), 'someclassname_classname',
|
||||
'\SomeClassName', 'ClassName', null,
|
||||
),
|
||||
array(self::defaultNaming(), 'name_classname',
|
||||
'\Some\Class\Name', 'ClassName', null,
|
||||
),
|
||||
|
||||
// UnderscoreNamingStrategy
|
||||
array(self::underscoreNamingLower(), 'some_class_name_class_name',
|
||||
'SomeClassName', 'Some\ClassName', null,
|
||||
),
|
||||
array(self::underscoreNamingLower(), 'some_class_name_class_name',
|
||||
'\SomeClassName', 'ClassName', null,
|
||||
),
|
||||
array(self::underscoreNamingLower(), 'name_class_name',
|
||||
'\Some\Class\Name', 'ClassName', null,
|
||||
),
|
||||
|
||||
array(self::underscoreNamingUpper(), 'SOME_CLASS_NAME_CLASS_NAME',
|
||||
'SomeClassName', 'Some\ClassName', null,
|
||||
),
|
||||
array(self::underscoreNamingUpper(), 'SOME_CLASS_NAME_CLASS_NAME',
|
||||
'\SomeClassName', 'ClassName', null,
|
||||
),
|
||||
array(self::underscoreNamingUpper(), 'NAME_CLASS_NAME',
|
||||
'\Some\Class\Name', 'ClassName', null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataJoinTableName
|
||||
*
|
||||
* @param NamingStrategy $strategy
|
||||
* @param string $expected
|
||||
* @param string $ownerEntity
|
||||
* @param string $associatedEntity
|
||||
* @param string $propertyName
|
||||
*/
|
||||
public function testJoinTableName(NamingStrategy $strategy, $expected, $ownerEntity, $associatedEntity, $propertyName = null)
|
||||
{
|
||||
$this->assertEquals($expected, $strategy->joinTableName($ownerEntity, $associatedEntity, $propertyName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data Provider for NamingStrategy#joinKeyColumnName
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function dataJoinKeyColumnName()
|
||||
{
|
||||
return array(
|
||||
// DefaultNamingStrategy
|
||||
array(self::defaultNaming(), 'someclassname_id',
|
||||
'SomeClassName', null, null,
|
||||
),
|
||||
array(self::defaultNaming(), 'name_identifier',
|
||||
'\Some\Class\Name', 'identifier', null,
|
||||
),
|
||||
|
||||
// UnderscoreNamingStrategy
|
||||
array(self::underscoreNamingLower(), 'some_class_name_id',
|
||||
'SomeClassName', null, null,
|
||||
),
|
||||
array(self::underscoreNamingLower(), 'class_name_identifier',
|
||||
'\Some\Class\ClassName', 'identifier', null,
|
||||
),
|
||||
|
||||
array(self::underscoreNamingUpper(), 'SOME_CLASS_NAME_ID',
|
||||
'SomeClassName', null, null,
|
||||
),
|
||||
array(self::underscoreNamingUpper(), 'CLASS_NAME_IDENTIFIER',
|
||||
'\Some\Class\ClassName', 'IDENTIFIER', null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataJoinKeyColumnName
|
||||
*
|
||||
* @param NamingStrategy $strategy
|
||||
* @param string $expected
|
||||
* @param string $propertyEntityName
|
||||
* @param string $referencedColumnName
|
||||
* @param string $propertyName
|
||||
*/
|
||||
public function testJoinKeyColumnName(NamingStrategy $strategy, $expected, $propertyEntityName, $referencedColumnName = null, $propertyName = null)
|
||||
{
|
||||
$this->assertEquals($expected, $strategy->joinKeyColumnName($propertyEntityName, $referencedColumnName, $propertyName));
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ class XmlMappingDriverTest extends AbstractMappingDriverTest
|
||||
$mappingDriver = $this->_loadDriver();
|
||||
|
||||
$class = new ClassMetadata($className);
|
||||
$class->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$mappingDriver->loadMetadataForClass($className, $class);
|
||||
|
||||
$expectedMap = array(
|
||||
@ -92,4 +93,4 @@ class CTI
|
||||
|
||||
class CTIFoo extends CTI {}
|
||||
class CTIBar extends CTI {}
|
||||
class CTIBaz extends CTI {}
|
||||
class CTIBaz extends CTI {}
|
||||
|
@ -127,6 +127,7 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$className = "\DoctrineOrmTestEntity";
|
||||
$proxyName = "DoctrineOrmTestEntityProxy";
|
||||
$classMetadata = new \Doctrine\ORM\Mapping\ClassMetadata($className);
|
||||
$classMetadata->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$classMetadata->mapField(array('fieldName' => 'id', 'type' => 'integer'));
|
||||
$classMetadata->setIdentifier(array('id'));
|
||||
|
||||
@ -143,6 +144,7 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$className = "\Doctrine\Tests\ORM\Proxy\SleepClass";
|
||||
$proxyName = "DoctrineTestsORMProxySleepClassProxy";
|
||||
$classMetadata = new \Doctrine\ORM\Mapping\ClassMetadata($className);
|
||||
$classMetadata->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
$classMetadata->mapField(array('fieldName' => 'id', 'type' => 'integer'));
|
||||
$classMetadata->setIdentifier(array('id'));
|
||||
|
||||
|
@ -822,6 +822,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
/**
|
||||
* @group DDC-339
|
||||
* @group DDC-1572
|
||||
*/
|
||||
public function testStringFunctionLikeExpression()
|
||||
{
|
||||
@ -837,6 +838,20 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
"SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(UPPER(u.name), '_moo') LIKE :str",
|
||||
"SELECT c0_.name AS name0 FROM cms_users c0_ WHERE UPPER(c0_.name) || '_moo' LIKE ?"
|
||||
);
|
||||
|
||||
// DDC-1572
|
||||
$this->assertSqlGeneration(
|
||||
"SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(u.name) LIKE UPPER(:str)",
|
||||
"SELECT c0_.name AS name0 FROM cms_users c0_ WHERE UPPER(c0_.name) LIKE UPPER(?)"
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
"SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(LOWER(u.name)) LIKE UPPER(LOWER(:str))",
|
||||
"SELECT c0_.name AS name0 FROM cms_users c0_ WHERE UPPER(LOWER(c0_.name)) LIKE UPPER(LOWER(?))"
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
"SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE u.name",
|
||||
"SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ LEFT JOIN cms_articles c1_ ON c0_.id = c1_.user_id AND (c1_.topic LIKE c0_.name)"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1415,6 +1430,56 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1539
|
||||
*/
|
||||
public function testParenthesesOnTheLeftHandOfComparison()
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where ( (u.id + u.id) * u.id ) > 100',
|
||||
'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id + c0_.id) * c0_.id > 100'
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where (u.id + u.id) * u.id > 100',
|
||||
'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id + c0_.id) * c0_.id > 100'
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where 100 < (u.id + u.id) * u.id ',
|
||||
'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE 100 < (c0_.id + c0_.id) * c0_.id'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1557
|
||||
*/
|
||||
public function testSupportsSubSqlFunction()
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.name IN ( SELECT TRIM(u2.name) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
|
||||
'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.name IN (SELECT TRIM(c1_.name) AS sclr4 FROM cms_users c1_)'
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.name IN ( SELECT TRIM(u2.name) FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE LOWER(u2.name) LIKE \'%fabio%\')',
|
||||
'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.name IN (SELECT TRIM(c1_.name) AS sclr4 FROM cms_users c1_ WHERE LOWER(c1_.name) LIKE \'%fabio%\')'
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.email IN ( SELECT TRIM(IDENTITY(u2.email)) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
|
||||
'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.email_id IN (SELECT TRIM(c1_.email_id) AS sclr4 FROM cms_users c1_)'
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.email IN ( SELECT IDENTITY(u2.email) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
|
||||
'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.email_id IN (SELECT c1_.email_id AS sclr4 FROM cms_users c1_)'
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE COUNT(u1.id) = ( SELECT SUM(u2.id) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
|
||||
'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE COUNT(c0_.id) = (SELECT SUM(c1_.id) AS dctrn__1 FROM cms_users c1_)'
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE COUNT(u1.id) <= ( SELECT SUM(u2.id) + COUNT(u2.email) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
|
||||
'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE COUNT(c0_.id) <= (SELECT SUM(c1_.id) + COUNT(c1_.email_id) AS sclr4 FROM cms_users c1_)'
|
||||
);
|
||||
}
|
||||
|
||||
public function testCustomTypeValueSql()
|
||||
{
|
||||
if (DBALType::hasType('negative_to_positive')) {
|
||||
|
@ -167,6 +167,8 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$book = $this->newInstance($metadata);
|
||||
|
||||
$cm = new \Doctrine\ORM\Mapping\ClassMetadata($metadata->name);
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$driver = $this->createAnnotationDriver();
|
||||
$driver->loadMetadataForClass($cm->name, $cm);
|
||||
|
||||
@ -189,6 +191,8 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$book = $this->newInstance($metadata);
|
||||
|
||||
$cm = new \Doctrine\ORM\Mapping\ClassMetadata($metadata->name);
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$driver->loadMetadataForClass($cm->name, $cm);
|
||||
|
||||
$this->assertEquals($cm->columnNames, $metadata->columnNames);
|
||||
@ -249,4 +253,4 @@ class
|
||||
}
|
||||
|
||||
class EntityGeneratorAuthor {}
|
||||
class EntityGeneratorComment {}
|
||||
class EntityGeneratorComment {}
|
||||
|
@ -368,4 +368,17 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
|
||||
return rmdir($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Address
|
||||
{
|
||||
|
||||
}
|
||||
class Phonenumber
|
||||
{
|
||||
|
||||
}
|
||||
class Group
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -158,6 +158,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
|
||||
if (isset($this->_usedModelSets['company'])) {
|
||||
$conn->executeUpdate('DELETE FROM company_contract_employees');
|
||||
$conn->executeUpdate('DELETE FROM company_contract_managers');
|
||||
$conn->executeUpdate('DELETE FROM company_contracts');
|
||||
$conn->executeUpdate('DELETE FROM company_persons_friends');
|
||||
$conn->executeUpdate('DELETE FROM company_managers');
|
||||
@ -294,7 +295,11 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
// the actual database platform used during execution has effect on some
|
||||
// metadata mapping behaviors (like the choice of the ID generation).
|
||||
if (is_null(self::$_metadataCacheImpl)) {
|
||||
self::$_metadataCacheImpl = new \Doctrine\Common\Cache\ArrayCache;
|
||||
if (isset($GLOBALS['DOCTRINE_CACHE_IMPL'])) {
|
||||
self::$_metadataCacheImpl = new $GLOBALS['DOCTRINE_CACHE_IMPL'];
|
||||
} else {
|
||||
self::$_metadataCacheImpl = new \Doctrine\Common\Cache\ArrayCache;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null(self::$_queryCacheImpl)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user