mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a65377a570 | ||
|
|
09d900f89f | ||
|
|
6dfd812d3b | ||
|
|
14d6f364bb | ||
|
|
0add6635c5 | ||
|
|
03622158f9 | ||
|
|
e6512209c4 | ||
|
|
63e7a0a83d | ||
|
|
fe6018ce9b | ||
|
|
c84607c3aa | ||
|
|
5d2a3bcb3b | ||
|
|
5739c069d3 | ||
|
|
e8f4c299b5 | ||
|
|
e123931e92 | ||
|
|
98ee3180f3 | ||
|
|
e1e2248dfd | ||
|
|
a86bfada8b | ||
|
|
5f66c65c9a | ||
|
|
9126f751fd | ||
|
|
627a5a43f9 | ||
|
|
f60096240d | ||
|
|
1916349f6f | ||
|
|
cb4e14e86d | ||
|
|
7ada288b9b | ||
|
|
b7bcbc20b6 | ||
|
|
9dbf747bd0 | ||
|
|
dfd734010c | ||
|
|
f2bcb19956 | ||
|
|
1f9435de5c | ||
|
|
a0f4bd1134 | ||
|
|
ef79c1c9e8 | ||
|
|
36cac855dc | ||
|
|
8abe8fe15b | ||
|
|
202e675d2b | ||
|
|
7a10e03507 | ||
|
|
159b6f8947 | ||
|
|
6db528e713 | ||
|
|
6babe26941 | ||
|
|
62a72603bd |
@@ -73,4 +73,9 @@ Will now return a collection of arrays with index "user" pointing to the User ob
|
||||
|
||||
Thousands of lines were completely reviewed and optimized for best performance.
|
||||
Removed redundancy and improved code readability made now internal Doctrine code easier to understand.
|
||||
Also, Doctrine 2.2 now is around 10-15% faster than 2.1.
|
||||
Also, Doctrine 2.2 now is around 10-15% faster than 2.1.
|
||||
|
||||
# EntityManager#find(null)
|
||||
|
||||
Previously EntityManager#find(null) returned null. It now throws an exception.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "doctrine/orm",
|
||||
"type": "library","version":"2.2.2",
|
||||
"type": "library","version":"2.2.3",
|
||||
"description": "Object-Relational-Mapper for PHP",
|
||||
"keywords": ["orm", "database"],
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
@@ -14,8 +14,8 @@
|
||||
"require": {
|
||||
"php": ">=5.3.2",
|
||||
"ext-pdo": "*",
|
||||
"doctrine/common": ">=2.2.0,<2.2.99",
|
||||
"doctrine/dbal": ">=2.2.1,<2.2.99"
|
||||
"doctrine/common": "2.2.*",
|
||||
"doctrine/dbal": "2.2.*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Doctrine\\ORM": "lib/" }
|
||||
|
||||
@@ -124,8 +124,15 @@ class EntityRepository implements ObjectRepository
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($lockMode !== LockMode::NONE) {
|
||||
$this->_em->lock($entity, $lockMode, $lockVersion);
|
||||
switch ($lockMode) {
|
||||
case LockMode::OPTIMISTIC:
|
||||
$this->_em->lock($entity, $lockMode, $lockVersion);
|
||||
break;
|
||||
case LockMode::PESSIMISTIC_READ:
|
||||
case LockMode::PESSIMISTIC_WRITE:
|
||||
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
|
||||
$persister->refresh($sortedId, $entity, $lockMode);
|
||||
break;
|
||||
}
|
||||
|
||||
return $entity; // Hit!
|
||||
|
||||
@@ -23,6 +23,7 @@ use PDO,
|
||||
Doctrine\DBAL\Connection,
|
||||
Doctrine\DBAL\Types\Type,
|
||||
Doctrine\ORM\EntityManager,
|
||||
Doctrine\ORM\Events,
|
||||
Doctrine\ORM\Mapping\ClassMetadata;
|
||||
|
||||
/**
|
||||
@@ -83,6 +84,9 @@ abstract class AbstractHydrator
|
||||
$this->_rsm = $resultSetMapping;
|
||||
$this->_hints = $hints;
|
||||
|
||||
$evm = $this->_em->getEventManager();
|
||||
$evm->addEventListener(array(Events::onClear), $this);
|
||||
|
||||
$this->prepare();
|
||||
|
||||
return new IterableResult($this);
|
||||
@@ -374,4 +378,12 @@ abstract class AbstractHydrator
|
||||
|
||||
$this->_em->getUnitOfWork()->registerManaged($entity, $id, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* When executed in a hydrate() loop we have to clear internal state to
|
||||
* decrease memory consumption.
|
||||
*/
|
||||
public function onClear($eventArgs)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ class ObjectHydrator extends AbstractHydrator
|
||||
private $_rootAliases = array();
|
||||
private $_initializedCollections = array();
|
||||
private $_existingCollections = array();
|
||||
//private $_createdEntities;
|
||||
|
||||
|
||||
/** @override */
|
||||
@@ -518,4 +517,20 @@ class ObjectHydrator extends AbstractHydrator
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When executed in a hydrate() loop we may have to clear internal state to
|
||||
* decrease memory consumption.
|
||||
*/
|
||||
public function onClear($eventArgs)
|
||||
{
|
||||
parent::onClear($eventArgs);
|
||||
|
||||
$aliases = array_keys($this->_identifierMap);
|
||||
$this->_identifierMap = array();
|
||||
|
||||
foreach ($aliases as $alias) {
|
||||
$this->_identifierMap[$alias] = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,8 +142,12 @@ class AnnotationDriver implements Driver
|
||||
|
||||
$classAnnotations = $this->_reader->getClassAnnotations($class);
|
||||
|
||||
if ($classAnnotations && is_numeric(key($classAnnotations))) {
|
||||
foreach ($classAnnotations as $annot) {
|
||||
if ($classAnnotations) {
|
||||
foreach ($classAnnotations as $key => $annot) {
|
||||
if ( ! is_numeric($key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$classAnnotations[get_class($annot)] = $annot;
|
||||
}
|
||||
}
|
||||
@@ -432,8 +436,11 @@ class AnnotationDriver implements Driver
|
||||
if ($method->isPublic() && $method->getDeclaringClass()->getName() == $class->name) {
|
||||
$annotations = $this->_reader->getMethodAnnotations($method);
|
||||
|
||||
if ($annotations && is_numeric(key($annotations))) {
|
||||
foreach ($annotations as $annot) {
|
||||
if ($annotations) {
|
||||
foreach ($annotations as $key => $annot) {
|
||||
if ( ! is_numeric($key)) {
|
||||
continue;
|
||||
}
|
||||
$annotations[get_class($annot)] = $annot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ final class PersistentCollection implements Collection
|
||||
/**
|
||||
* INTERNAL: Gets the association mapping of the collection.
|
||||
*
|
||||
* @return \Doctrine\ORM\Mapping\AssociationMapping
|
||||
* @return array
|
||||
*/
|
||||
public function getMapping()
|
||||
{
|
||||
@@ -389,6 +389,7 @@ final class PersistentCollection implements Collection
|
||||
|
||||
if ($this->association !== null &&
|
||||
$this->association['type'] & ClassMetadata::TO_MANY &&
|
||||
$this->owner &&
|
||||
$this->association['orphanRemoval']) {
|
||||
$this->em->getUnitOfWork()->scheduleOrphanRemoval($removed);
|
||||
}
|
||||
@@ -427,6 +428,7 @@ final class PersistentCollection implements Collection
|
||||
|
||||
if ($this->association !== null &&
|
||||
$this->association['type'] & ClassMetadata::TO_MANY &&
|
||||
$this->owner &&
|
||||
$this->association['orphanRemoval']) {
|
||||
$this->em->getUnitOfWork()->scheduleOrphanRemoval($element);
|
||||
}
|
||||
@@ -631,7 +633,9 @@ final class PersistentCollection implements Collection
|
||||
|
||||
$uow = $this->em->getUnitOfWork();
|
||||
|
||||
if ($this->association['type'] & ClassMetadata::TO_MANY && $this->association['orphanRemoval']) {
|
||||
if ($this->association['type'] & ClassMetadata::TO_MANY &&
|
||||
$this->association['orphanRemoval'] &&
|
||||
$this->owner) {
|
||||
// we need to initialize here, as orphan removal acts like implicit cascadeRemove,
|
||||
// hence for event listeners we need the objects in memory.
|
||||
$this->initialize();
|
||||
@@ -774,13 +778,15 @@ final class PersistentCollection implements Collection
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->initialize();
|
||||
$this->owner = null;
|
||||
|
||||
if (is_object($this->coll)) {
|
||||
$this->coll = clone $this->coll;
|
||||
}
|
||||
|
||||
$this->initialize();
|
||||
$this->owner = null;
|
||||
|
||||
$this->snapshot = array();
|
||||
|
||||
$this->changed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,7 +364,19 @@ class BasicEntityPersister
|
||||
$targetMapping = $this->_em->getClassMetadata($this->_class->associationMappings[$idField]['targetEntity']);
|
||||
$where[] = $this->_class->associationMappings[$idField]['joinColumns'][0]['name'];
|
||||
$params[] = $id[$idField];
|
||||
$types[] = $targetMapping->fieldMappings[$targetMapping->identifier[0]]['type'];
|
||||
|
||||
switch (true) {
|
||||
case (isset($targetMapping->fieldMappings[$targetMapping->identifier[0]])):
|
||||
$types[] = $targetMapping->fieldMappings[$targetMapping->identifier[0]]['type'];
|
||||
break;
|
||||
|
||||
case (isset($targetMapping->associationMappings[$targetMapping->identifier[0]])):
|
||||
$types[] = $targetMapping->associationMappings[$targetMapping->identifier[0]]['type'];
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ORMException::unrecognizedField($targetMapping->identifier[0]);
|
||||
}
|
||||
} else {
|
||||
$where[] = $this->_class->getQuotedColumnName($idField, $this->_platform);
|
||||
$params[] = $id[$idField];
|
||||
@@ -690,9 +702,9 @@ class BasicEntityPersister
|
||||
* column or field names to values.
|
||||
* @param object $entity The entity to refresh.
|
||||
*/
|
||||
public function refresh(array $id, $entity)
|
||||
public function refresh(array $id, $entity, $lockMode = 0)
|
||||
{
|
||||
$sql = $this->_getSelectEntitiesSQL($id);
|
||||
$sql = $this->_getSelectEntitiesSQL($id, null, $lockMode);
|
||||
list($params, $types) = $this->expandParameters($id);
|
||||
$stmt = $this->_conn->executeQuery($sql, $params, $types);
|
||||
|
||||
@@ -1525,6 +1537,10 @@ class BasicEntityPersister
|
||||
{
|
||||
$criteria = $this->_class->getIdentifierValues($entity);
|
||||
|
||||
if ( ! $criteria) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($extraConditions) {
|
||||
$criteria = array_merge($criteria, $extraConditions);
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
}
|
||||
|
||||
// Composite identifier
|
||||
$sourceClass = $this->_em->getClassMetadata(get_class($mapping->getOwner()));
|
||||
$sourceClass = $this->_em->getClassMetadata(get_class($coll->getOwner()));
|
||||
|
||||
foreach ($mapping['relationToSourceKeyColumns'] as $relColumn => $srcColumn) {
|
||||
$params[] = $identifier[$sourceClass->fieldNames[$srcColumn]];
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace Doctrine\ORM\Proxy;
|
||||
|
||||
use Doctrine\ORM\EntityManager,
|
||||
Doctrine\ORM\Mapping\ClassMetadata,
|
||||
Doctrine\ORM\Mapping\AssociationMapping,
|
||||
Doctrine\Common\Util\ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -184,7 +183,19 @@ class ProxyFactory
|
||||
|
||||
$file = str_replace($placeholders, $replacements, $file);
|
||||
|
||||
file_put_contents($fileName, $file, LOCK_EX);
|
||||
$parentDirectory = dirname($fileName);
|
||||
|
||||
if ( ! is_dir($parentDirectory)) {
|
||||
if (false === @mkdir($parentDirectory, 0775, true)) {
|
||||
throw ProxyException::proxyDirectoryNotWritable();
|
||||
}
|
||||
} else if ( ! is_writable($parentDirectory)) {
|
||||
throw ProxyException::proxyDirectoryNotWritable();
|
||||
}
|
||||
|
||||
$tmpFileName = $fileName . '.' . uniqid("", true);
|
||||
file_put_contents($tmpFileName, $file);
|
||||
rename($tmpFileName, $fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace Doctrine\ORM;
|
||||
|
||||
use Doctrine\DBAL\LockMode,
|
||||
Doctrine\ORM\Query\Parser,
|
||||
Doctrine\ORM\Query\ParserResult,
|
||||
Doctrine\ORM\Query\QueryException;
|
||||
|
||||
/**
|
||||
@@ -218,7 +219,7 @@ final class Query extends AbstractQuery
|
||||
$hash = $this->_getQueryCacheId();
|
||||
$cached = $this->_expireQueryCache ? false : $queryCache->fetch($hash);
|
||||
|
||||
if ($cached !== false) {
|
||||
if ($cached instanceof ParserResult) {
|
||||
// Cache hit.
|
||||
$this->_parserResult = $cached;
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ class QueryException extends \Doctrine\ORM\ORMException
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\Mapping\AssociationMapping $assoc
|
||||
* @param array $assoc
|
||||
*/
|
||||
public static function iterateWithFetchJoinCollectionNotAllowed($assoc)
|
||||
{
|
||||
@@ -151,4 +151,4 @@ class QueryException extends \Doctrine\ORM\ORMException
|
||||
return new self("Cannot check if a child of '" . $rootClass . "' is instanceof '" . $className . "', " .
|
||||
"inheritance hierachy exists between these two classes.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,6 @@ EOT
|
||||
$output->write('<info>[Database] OK - The database schema is in sync with the mapping files.</info>' . "\n");
|
||||
}
|
||||
|
||||
exit($exit);
|
||||
return $exit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
namespace Doctrine\ORM\Tools;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo,
|
||||
Doctrine\ORM\Mapping\AssociationMapping,
|
||||
Doctrine\Common\Util\Inflector;
|
||||
Doctrine\Common\Util\Inflector,
|
||||
Doctrine\DBAL\Types\Type;
|
||||
|
||||
/**
|
||||
* Generic class used to generate PHP5 entity classes from ClassMetadataInfo instances
|
||||
@@ -136,6 +136,23 @@ public function <methodName>(<methodTypeHint>$<variableName>)
|
||||
<spaces>return $this;
|
||||
}';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $_removeMethodTemplate =
|
||||
'/**
|
||||
* <description>
|
||||
*
|
||||
* @param <variableType>$<variableName>
|
||||
*/
|
||||
public function <methodName>(<methodTypeHint>$<variableName>)
|
||||
{
|
||||
<spaces>$this-><fieldName>->removeElement($<variableName>);
|
||||
}';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $_lifecycleCallbackMethodTemplate =
|
||||
'/**
|
||||
* @<name>
|
||||
@@ -672,6 +689,9 @@ public function <methodName>()
|
||||
if ($code = $this->_generateEntityStubMethod($metadata, 'add', $associationMapping['fieldName'], $associationMapping['targetEntity'])) {
|
||||
$methods[] = $code;
|
||||
}
|
||||
if ($code = $this->_generateEntityStubMethod($metadata, 'remove', $associationMapping['fieldName'], $associationMapping['targetEntity'])) {
|
||||
$methods[] = $code;
|
||||
}
|
||||
if ($code = $this->_generateEntityStubMethod($metadata, 'get', $associationMapping['fieldName'], 'Doctrine\Common\Collections\Collection')) {
|
||||
$methods[] = $code;
|
||||
}
|
||||
@@ -756,12 +776,9 @@ public function <methodName>()
|
||||
|
||||
private function _generateEntityStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null, $defaultValue = null)
|
||||
{
|
||||
if ($type == "add") {
|
||||
$addMethod = explode("\\", $typeHint);
|
||||
$addMethod = end($addMethod);
|
||||
$methodName = $type . $addMethod;
|
||||
} else {
|
||||
$methodName = $type . Inflector::classify($fieldName);
|
||||
$methodName = $type . Inflector::classify($fieldName);
|
||||
if (in_array($type, array("add", "remove")) && substr($methodName, -1) == "s") {
|
||||
$methodName = substr($methodName, 0, -1);
|
||||
}
|
||||
|
||||
if ($this->_hasMethod($methodName, $metadata)) {
|
||||
@@ -805,7 +822,7 @@ public function <methodName>()
|
||||
$this->_staticReflection[$metadata->name]['methods'][] = $methodName;
|
||||
|
||||
$replacements = array(
|
||||
'<name>' => $this->_annotationsPrefix . $name,
|
||||
'<name>' => $this->_annotationsPrefix . ucfirst($name),
|
||||
'<methodName>' => $methodName,
|
||||
);
|
||||
|
||||
@@ -1035,11 +1052,11 @@ public function <methodName>()
|
||||
}
|
||||
|
||||
if (isset($metadata->sequenceGeneratorDefinition['allocationSize'])) {
|
||||
$sequenceGenerator[] = 'allocationSize="' . $metadata->sequenceGeneratorDefinition['allocationSize'] . '"';
|
||||
$sequenceGenerator[] = 'allocationSize=' . $metadata->sequenceGeneratorDefinition['allocationSize'];
|
||||
}
|
||||
|
||||
if (isset($metadata->sequenceGeneratorDefinition['initialValue'])) {
|
||||
$sequenceGenerator[] = 'initialValue="' . $metadata->sequenceGeneratorDefinition['initialValue'] . '"';
|
||||
$sequenceGenerator[] = 'initialValue=' . $metadata->sequenceGeneratorDefinition['initialValue'];
|
||||
}
|
||||
|
||||
$lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'SequenceGenerator(' . implode(', ', $sequenceGenerator) . ')';
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
namespace Doctrine\ORM\Tools\Export\Driver;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo,
|
||||
Doctrine\ORM\Mapping\AssociationMapping,
|
||||
Doctrine\ORM\Tools\EntityGenerator;
|
||||
|
||||
/**
|
||||
@@ -69,4 +68,4 @@ class AnnotationExporter extends AbstractExporter
|
||||
{
|
||||
$this->_entityGenerator = $entityGenerator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ class PhpExporter extends AbstractExporter
|
||||
$lines[] = '$metadata->mapField(' . $this->_varExport($fieldMapping) . ');';
|
||||
}
|
||||
|
||||
if ($generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
|
||||
if ( ! $metadata->isIdentifierComposite && $generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
|
||||
$lines[] = '$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_' . $generatorType . ');';
|
||||
}
|
||||
|
||||
@@ -166,4 +166,4 @@ class PhpExporter extends AbstractExporter
|
||||
|
||||
return $export;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ class XmlExporter extends AbstractExporter
|
||||
}
|
||||
}
|
||||
|
||||
if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
|
||||
if ( ! $metadata->isIdentifierComposite && $idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
|
||||
$id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType;
|
||||
}
|
||||
|
||||
@@ -317,4 +317,4 @@ class XmlExporter extends AbstractExporter
|
||||
$result = $dom->saveXML();
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,8 +114,8 @@ class YamlExporter extends AbstractExporter
|
||||
$fieldMappings[$name] = $fieldMapping;
|
||||
}
|
||||
|
||||
if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
|
||||
$ids[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $this->_getIdGeneratorTypeString($metadata->generatorType);
|
||||
if ( ! $metadata->isIdentifierComposite && $idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
|
||||
$ids[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType;
|
||||
}
|
||||
|
||||
if ($ids) {
|
||||
@@ -172,7 +172,13 @@ class YamlExporter extends AbstractExporter
|
||||
);
|
||||
|
||||
$associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray);
|
||||
$array['oneToOne'][$name] = $associationMappingArray;
|
||||
|
||||
if ($associationMapping['type'] & ClassMetadataInfo::ONE_TO_ONE) {
|
||||
$array['oneToOne'][$name] = $associationMappingArray;
|
||||
} else {
|
||||
$array['manyToOne'][$name] = $associationMappingArray;
|
||||
}
|
||||
|
||||
} else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
|
||||
$oneToManyMappingArray = array(
|
||||
'mappedBy' => $associationMapping['mappedBy'],
|
||||
|
||||
@@ -152,16 +152,18 @@ class SchemaValidator
|
||||
}
|
||||
|
||||
// Verify inverse side/owning side match each other
|
||||
$targetAssoc = $targetMetadata->associationMappings[$assoc['inversedBy']];
|
||||
if ($assoc['type'] == ClassMetadataInfo::ONE_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_ONE){
|
||||
$ce[] = "If association " . $class->name . "#" . $fieldName . " is one-to-one, then the inversed " .
|
||||
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-one as well.";
|
||||
} else if ($assoc['type'] == ClassMetadataInfo::MANY_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_MANY){
|
||||
$ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-one, then the inversed " .
|
||||
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-many.";
|
||||
} else if ($assoc['type'] == ClassMetadataInfo::MANY_TO_MANY && $targetAssoc['type'] !== ClassMetadataInfo::MANY_TO_MANY){
|
||||
$ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-many, then the inversed " .
|
||||
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be many-to-many as well.";
|
||||
if (array_key_exists($assoc['inversedBy'], $targetMetadata->associationMappings)) {
|
||||
$targetAssoc = $targetMetadata->associationMappings[$assoc['inversedBy']];
|
||||
if ($assoc['type'] == ClassMetadataInfo::ONE_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_ONE){
|
||||
$ce[] = "If association " . $class->name . "#" . $fieldName . " is one-to-one, then the inversed " .
|
||||
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-one as well.";
|
||||
} else if ($assoc['type'] == ClassMetadataInfo::MANY_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_MANY){
|
||||
$ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-one, then the inversed " .
|
||||
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-many.";
|
||||
} else if ($assoc['type'] == ClassMetadataInfo::MANY_TO_MANY && $targetAssoc['type'] !== ClassMetadataInfo::MANY_TO_MANY){
|
||||
$ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-many, then the inversed " .
|
||||
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be many-to-many as well.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1118,6 +1118,10 @@ class UnitOfWork implements PropertyChangedListener
|
||||
if (isset($this->entityIdentifiers[$oid])) {
|
||||
$this->addToIdentityMap($entity);
|
||||
}
|
||||
|
||||
if ($entity instanceof NotifyPropertyChanged) {
|
||||
$entity->addPropertyChangedListener($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1296,10 +1300,6 @@ class UnitOfWork implements PropertyChangedListener
|
||||
|
||||
$this->identityMap[$className][$idHash] = $entity;
|
||||
|
||||
if ($entity instanceof NotifyPropertyChanged) {
|
||||
$entity->addPropertyChangedListener($this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1649,7 +1649,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$oid = spl_object_hash($entity);
|
||||
|
||||
if (isset($visited[$oid])) {
|
||||
return; // Prevent infinite recursion
|
||||
return $visited[$oid]; // Prevent infinite recursion
|
||||
}
|
||||
|
||||
$visited[$oid] = $entity; // mark visited
|
||||
@@ -2356,11 +2356,12 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
} else {
|
||||
$entity = $this->newInstance($class);
|
||||
$oid = spl_object_hash($entity);
|
||||
$oid = spl_object_hash($entity);
|
||||
|
||||
$this->entityIdentifiers[$oid] = $id;
|
||||
$this->entityStates[$oid] = self::STATE_MANAGED;
|
||||
$this->entityIdentifiers[$oid] = $id;
|
||||
$this->entityStates[$oid] = self::STATE_MANAGED;
|
||||
$this->originalEntityData[$oid] = $data;
|
||||
|
||||
$this->identityMap[$class->rootEntityName][$idHash] = $entity;
|
||||
|
||||
if ($entity instanceof NotifyPropertyChanged) {
|
||||
@@ -2790,6 +2791,10 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$this->originalEntityData[$oid] = $data;
|
||||
|
||||
$this->addToIdentityMap($entity);
|
||||
|
||||
if ($entity instanceof NotifyPropertyChanged) {
|
||||
$entity->addPropertyChangedListener($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@ class Version
|
||||
/**
|
||||
* Current Doctrine Version
|
||||
*/
|
||||
const VERSION = '2.2.2';
|
||||
const VERSION = '2.2.3';
|
||||
|
||||
/**
|
||||
* Compares a Doctrine version with the current one.
|
||||
|
||||
@@ -30,12 +30,25 @@ class NavPointOfInterest
|
||||
*/
|
||||
private $country;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="NavUser", cascade={"persist"})
|
||||
* @JoinTable(name="navigation_pois_visitors",
|
||||
* inverseJoinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
|
||||
* joinColumns={
|
||||
* @JoinColumn(name="poi_long", referencedColumnName="nav_long"),
|
||||
* @JoinColumn(name="poi_lat", referencedColumnName="nav_lat")
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
private $visitors;
|
||||
|
||||
public function __construct($lat, $long, $name, $country)
|
||||
{
|
||||
$this->lat = $lat;
|
||||
$this->long = $long;
|
||||
$this->name = $name;
|
||||
$this->country = $country;
|
||||
$this->visitors = new \Doctrine\Common\Collections\ArrayCollection;
|
||||
}
|
||||
|
||||
public function getLong() {
|
||||
@@ -53,4 +66,14 @@ class NavPointOfInterest
|
||||
public function getCountry() {
|
||||
return $this->country;
|
||||
}
|
||||
|
||||
public function addVisitor(NavUser $user)
|
||||
{
|
||||
$this->visitors[] = $user;
|
||||
}
|
||||
|
||||
public function getVisitors()
|
||||
{
|
||||
return $this->visitors;
|
||||
}
|
||||
}
|
||||
|
||||
28
tests/Doctrine/Tests/Models/Navigation/NavUser.php
Normal file
28
tests/Doctrine/Tests/Models/Navigation/NavUser.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\Navigation;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="navigation_users")
|
||||
*/
|
||||
class NavUser
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
* @generatedValue
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @column(type="string")
|
||||
*/
|
||||
private $name;
|
||||
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,4 +448,23 @@ class ClassTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $manager->getId());
|
||||
$this->assertEquals(1, count($manager->getFriends()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1777
|
||||
*/
|
||||
public function testExistsSubclass()
|
||||
{
|
||||
$manager = new CompanyManager();
|
||||
$manager->setName('gblanco');
|
||||
$manager->setSalary(1234);
|
||||
$manager->setTitle('Awesome!');
|
||||
$manager->setDepartment('IT');
|
||||
|
||||
$this->assertFalse($this->_em->getUnitOfWork()->getEntityPersister(get_class($manager))->exists($manager));
|
||||
|
||||
$this->_em->persist($manager);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertTrue($this->_em->getUnitOfWork()->getEntityPersister(get_class($manager))->exists($manager));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use Doctrine\Tests\Models\Navigation\NavCountry;
|
||||
use Doctrine\Tests\Models\Navigation\NavPointOfInterest;
|
||||
use Doctrine\Tests\Models\Navigation\NavTour;
|
||||
use Doctrine\Tests\Models\Navigation\NavPhotos;
|
||||
use Doctrine\Tests\Models\Navigation\NavUser;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
@@ -118,4 +119,26 @@ class CompositePrimaryKeyTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->setExpectedException('Doctrine\ORM\ORMException', 'The identifier long is missing for a query of Doctrine\Tests\Models\Navigation\NavPointOfInterest');
|
||||
$poi = $this->_em->find('Doctrine\Tests\Models\Navigation\NavPointOfInterest', array('key1' => 100));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1939
|
||||
*/
|
||||
public function testDeleteCompositePersistentCollection()
|
||||
{
|
||||
$this->putGermanysBrandenburderTor();
|
||||
|
||||
$poi = $this->_em->find('Doctrine\Tests\Models\Navigation\NavPointOfInterest', array('lat' => 100, 'long' => 200));
|
||||
$poi->addVisitor(new NavUser("test1"));
|
||||
$poi->addVisitor(new NavUser("test2"));
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
$poi->getVisitors()->clear();
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$poi = $this->_em->find('Doctrine\Tests\Models\Navigation\NavPointOfInterest', array('lat' => 100, 'long' => 200));
|
||||
$this->assertEquals(0, count($poi->getVisitors()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,9 +40,16 @@ class NotifyPolicyTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
$this->_em->persist($user);
|
||||
$this->_em->persist($group);
|
||||
|
||||
$this->assertEquals(1, count($user->listeners));
|
||||
$this->assertEquals(1, count($group->listeners));
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->assertEquals(1, count($user->listeners));
|
||||
$this->assertEquals(1, count($group->listeners));
|
||||
|
||||
$userId = $user->getId();
|
||||
$groupId = $group->getId();
|
||||
unset($user, $group);
|
||||
@@ -52,6 +59,9 @@ class NotifyPolicyTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$group = $this->_em->find(__NAMESPACE__.'\NotifyGroup', $groupId);
|
||||
$this->assertEquals(1, $group->getUsers()->count());
|
||||
|
||||
$this->assertEquals(1, count($user->listeners));
|
||||
$this->assertEquals(1, count($group->listeners));
|
||||
|
||||
$group2 = new NotifyGroup();
|
||||
$group2->setName('nerds');
|
||||
$this->_em->persist($group2);
|
||||
@@ -63,6 +73,9 @@ class NotifyPolicyTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->assertEquals(1, count($user->listeners));
|
||||
$this->assertEquals(1, count($group->listeners));
|
||||
|
||||
$group2Id = $group2->getId();
|
||||
unset($group2, $user);
|
||||
|
||||
@@ -77,7 +90,7 @@ class NotifyPolicyTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
}
|
||||
|
||||
class NotifyBaseEntity implements NotifyPropertyChanged {
|
||||
private $listeners = array();
|
||||
public $listeners = array();
|
||||
|
||||
public function addPropertyChangedListener(PropertyChangedListener $listener) {
|
||||
$this->listeners[] = $listener;
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Common\Persistence\PersistentObject;
|
||||
|
||||
/**
|
||||
*/
|
||||
class PersistentCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
try {
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\PersistentCollectionHolder'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\PersistentCollectionContent'),
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
|
||||
}
|
||||
PersistentObject::setObjectManager($this->_em);
|
||||
}
|
||||
|
||||
public function testPersist()
|
||||
{
|
||||
$collectionHolder = new PersistentCollectionHolder();
|
||||
$content = new PersistentCollectionContent('first element');
|
||||
$collectionHolder->addElement($content);
|
||||
|
||||
$this->_em->persist($collectionHolder);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$collectionHolder = $this->_em->find(__NAMESPACE__ . '\PersistentCollectionHolder', $collectionHolder->getId());
|
||||
$collectionHolder->getCollection();
|
||||
|
||||
$content = new PersistentCollectionContent('second element');
|
||||
$collectionHolder->addElement($content);
|
||||
|
||||
$this->assertEquals(2, $collectionHolder->getCollection()->count());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class PersistentCollectionHolder extends PersistentObject
|
||||
{
|
||||
/**
|
||||
* @Id @Column(type="integer") @GeneratedValue
|
||||
* @var int
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\Common\Collections\Collection
|
||||
* @ManyToMany(targetEntity="PersistentCollectionContent", cascade={"all"})
|
||||
*/
|
||||
protected $collection;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->collection = new \Doctrine\Common\Collections\ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PersistentCollectionContent $element
|
||||
*/
|
||||
public function addElement(PersistentCollectionContent $element)
|
||||
{
|
||||
$this->collection->add($element);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Doctrine\Common\Collections\Collection
|
||||
*/
|
||||
public function getCollection()
|
||||
{
|
||||
return clone $this->collection;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class PersistentCollectionContent extends PersistentObject
|
||||
{
|
||||
|
||||
/**
|
||||
* @Id @Column(type="integer") @GeneratedValue
|
||||
* @var int
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
}
|
||||
@@ -227,6 +227,42 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
public function testIterateResultClearEveryCycle()
|
||||
{
|
||||
$article1 = new CmsArticle;
|
||||
$article1->topic = "Doctrine 2";
|
||||
$article1->text = "This is an introduction to Doctrine 2.";
|
||||
|
||||
$article2 = new CmsArticle;
|
||||
$article2->topic = "Symfony 2";
|
||||
$article2->text = "This is an introduction to Symfony 2.";
|
||||
|
||||
$this->_em->persist($article1);
|
||||
$this->_em->persist($article2);
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$query = $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a");
|
||||
$articles = $query->iterate();
|
||||
|
||||
$iteratedCount = 0;
|
||||
$topics = array();
|
||||
foreach($articles AS $row) {
|
||||
$article = $row[0];
|
||||
$topics[] = $article->topic;
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
$iteratedCount++;
|
||||
}
|
||||
|
||||
$this->assertEquals(array("Doctrine 2", "Symfony 2"), $topics);
|
||||
$this->assertEquals(2, $iteratedCount);
|
||||
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Doctrine\ORM\Query\QueryException
|
||||
*/
|
||||
|
||||
74
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1778Test.php
Normal file
74
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1778Test.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
|
||||
|
||||
/**
|
||||
* @group DDC-1778
|
||||
*/
|
||||
class DDC1778Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
private $user;
|
||||
private $phone;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->useModelSet('cms');
|
||||
parent::setUp();
|
||||
|
||||
$this->user = new CmsUser();
|
||||
$this->user->username = "beberlei";
|
||||
$this->user->name = "Benjamin";
|
||||
$this->user->status = "active";
|
||||
|
||||
$this->phone = new CmsPhoneNumber();
|
||||
$this->phone->phonenumber = '0123456789';
|
||||
$this->user->addPhoneNumber($this->phone);
|
||||
|
||||
$this->_em->persist($this->user);
|
||||
$this->_em->persist($this->phone);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->user = $this->_em->find('Doctrine\\Tests\\Models\\CMS\\CmsUser', $this->user->getId());
|
||||
$this->phone = $this->_em->find('Doctrine\\Tests\\Models\\CMS\\CmsPhonenumber', $this->phone->phonenumber);
|
||||
}
|
||||
|
||||
public function testClear()
|
||||
{
|
||||
$clonedNumbers = clone $this->user->getPhonenumbers();
|
||||
$clonedNumbers->clear();
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->user = $this->_em->find('Doctrine\\Tests\\Models\\CMS\\CmsUser', $this->user->getId());
|
||||
|
||||
$this->assertCount(1, $this->user->getPhonenumbers());
|
||||
}
|
||||
|
||||
public function testRemove()
|
||||
{
|
||||
$clonedNumbers = clone $this->user->getPhonenumbers();
|
||||
$clonedNumbers->remove(0);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->user = $this->_em->find('Doctrine\\Tests\\Models\\CMS\\CmsUser', $this->user->getId());
|
||||
|
||||
$this->assertCount(1, $this->user->getPhonenumbers());
|
||||
}
|
||||
|
||||
public function testRemoveElement()
|
||||
{
|
||||
$clonedNumbers = clone $this->user->getPhonenumbers();
|
||||
$clonedNumbers->removeElement($this->phone);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->user = $this->_em->find('Doctrine\\Tests\\Models\\CMS\\CmsUser', $this->user->getId());
|
||||
|
||||
$this->assertCount(1, $this->user->getPhonenumbers());
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,8 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'setAuthor'), "EntityGeneratorBook::setAuthor() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getAuthor'), "EntityGeneratorBook::getAuthor() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'getComments'), "EntityGeneratorBook::getComments() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'addEntityGeneratorComment'), "EntityGeneratorBook::addEntityGeneratorComment() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'addComment'), "EntityGeneratorBook::addComment() missing.");
|
||||
$this->assertTrue(method_exists($metadata->namespace . '\EntityGeneratorBook', 'removeComment'), "EntityGeneratorBook::removeComment() missing.");
|
||||
|
||||
$this->assertEquals('published', $book->getStatus());
|
||||
|
||||
@@ -113,9 +114,11 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals($author, $book->getAuthor());
|
||||
|
||||
$comment = new EntityGeneratorComment();
|
||||
$book->addEntityGeneratorComment($comment);
|
||||
$book->addComment($comment);
|
||||
$this->assertInstanceOf('Doctrine\Common\Collections\ArrayCollection', $book->getComments());
|
||||
$this->assertEquals(new \Doctrine\Common\Collections\ArrayCollection(array($comment)), $book->getComments());
|
||||
$book->removeComment($comment);
|
||||
$this->assertEquals(new \Doctrine\Common\Collections\ArrayCollection(array()), $book->getComments());
|
||||
}
|
||||
|
||||
public function testEntityUpdatingWorks()
|
||||
@@ -221,6 +224,39 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals($classes, array_keys($p->getValue($this->_generator)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1784
|
||||
*/
|
||||
public function testGenerateEntityWithSequenceGenerator()
|
||||
{
|
||||
$metadata = new ClassMetadataInfo($this->_namespace . '\DDC1784Entity');
|
||||
$metadata->namespace = $this->_namespace;
|
||||
$metadata->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
|
||||
$metadata->setSequenceGeneratorDefinition(array(
|
||||
'sequenceName' => 'DDC1784_ID_SEQ',
|
||||
'allocationSize' => 1,
|
||||
'initialValue' => 2
|
||||
));
|
||||
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
|
||||
|
||||
$filename = $this->_tmpDir . DIRECTORY_SEPARATOR
|
||||
. $this->_namespace . DIRECTORY_SEPARATOR . 'DDC1784Entity.php';
|
||||
|
||||
$this->assertFileExists($filename);
|
||||
require_once $filename;
|
||||
|
||||
|
||||
$reflection = new \ReflectionProperty($metadata->name, 'id');
|
||||
$docComment = $reflection->getDocComment();
|
||||
|
||||
$this->assertContains('@Id', $docComment);
|
||||
$this->assertContains('@Column(name="id", type="integer")', $docComment);
|
||||
$this->assertContains('@GeneratedValue(strategy="SEQUENCE")', $docComment);
|
||||
$this->assertContains('@SequenceGenerator(sequenceName="DDC1784_ID_SEQ", allocationSize=1, initialValue=2)', $docComment);
|
||||
}
|
||||
|
||||
|
||||
public function getParseTokensInEntityFileData()
|
||||
{
|
||||
return array(
|
||||
|
||||
@@ -68,10 +68,10 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
|
||||
protected function _createMetadataDriver($type, $path)
|
||||
{
|
||||
$mappingDriver = array(
|
||||
'php' => 'PHPDriver',
|
||||
'php' => 'PHPDriver',
|
||||
'annotation' => 'AnnotationDriver',
|
||||
'xml' => 'XmlDriver',
|
||||
'yaml' => 'YamlDriver',
|
||||
'xml' => 'XmlDriver',
|
||||
'yaml' => 'YamlDriver',
|
||||
);
|
||||
$this->assertArrayHasKey($type, $mappingDriver, "There is no metadata driver for the type '" . $type . "'.");
|
||||
$driverName = $mappingDriver[$type];
|
||||
@@ -190,7 +190,7 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
|
||||
* @depends testIdentifierIsExported
|
||||
* @param ClassMetadataInfo $class
|
||||
*/
|
||||
public function testFieldsAreExpored($class)
|
||||
public function testFieldsAreExported($class)
|
||||
{
|
||||
$this->assertTrue(isset($class->fieldMappings['id']['id']) && $class->fieldMappings['id']['id'] === true);
|
||||
$this->assertEquals('id', $class->fieldMappings['id']['fieldName']);
|
||||
@@ -211,13 +211,12 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFieldsAreExpored
|
||||
* @depends testFieldsAreExported
|
||||
* @param ClassMetadataInfo $class
|
||||
*/
|
||||
public function testOneToOneAssociationsAreExported($class)
|
||||
{
|
||||
$this->assertTrue(isset($class->associationMappings['address']));
|
||||
//$this->assertInstanceOf('Doctrine\ORM\Mapping\OneToOneMapping', $class->associationMappings['address']);
|
||||
$this->assertEquals('Doctrine\Tests\ORM\Tools\Export\Address', $class->associationMappings['address']['targetEntity']);
|
||||
$this->assertEquals('address_id', $class->associationMappings['address']['joinColumns'][0]['name']);
|
||||
$this->assertEquals('id', $class->associationMappings['address']['joinColumns'][0]['referencedColumnName']);
|
||||
@@ -233,6 +232,15 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFieldsAreExported
|
||||
*/
|
||||
public function testManyToOneAssociationsAreExported($class)
|
||||
{
|
||||
$this->assertTrue(isset($class->associationMappings['mainGroup']));
|
||||
$this->assertEquals('Doctrine\Tests\ORM\Tools\Export\Group', $class->associationMappings['mainGroup']['targetEntity']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testOneToOneAssociationsAreExported
|
||||
* @param ClassMetadataInfo $class
|
||||
|
||||
@@ -28,6 +28,11 @@ class User
|
||||
*/
|
||||
public $address;
|
||||
|
||||
/**
|
||||
* @ManyToOne(targetEntity="Doctrine\Tests\ORM\Tools\Export\Group")
|
||||
*/
|
||||
public $mainGroup;
|
||||
|
||||
/**
|
||||
*
|
||||
* @OneToMany(targetEntity="Doctrine\Tests\ORM\Tools\Export\Phonenumber", mappedBy="user", cascade={"persist", "merge"}, orphanRemoval=true)
|
||||
@@ -65,4 +70,4 @@ class User
|
||||
public function doStuffOnPostPersist()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@ $metadata->mapField(array(
|
||||
'columnDefinition' => 'CHAR(32) NOT NULL',
|
||||
));
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
|
||||
$metadata->mapManyToOne(array(
|
||||
'fieldName' => 'mainGroup',
|
||||
'targetEntity' => 'Doctrine\\Tests\\ORM\Tools\\Export\\Group',
|
||||
));
|
||||
$metadata->mapOneToOne(array(
|
||||
'fieldName' => 'address',
|
||||
'targetEntity' => 'Doctrine\\Tests\\ORM\\Tools\\Export\\Address',
|
||||
@@ -102,4 +106,4 @@ $metadata->mapManyToMany(array(
|
||||
),
|
||||
),
|
||||
'orderBy' => NULL,
|
||||
));
|
||||
));
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
|
||||
|
||||
|
||||
<entity name="Doctrine\Tests\ORM\Tools\Export\User" table="cms_users">
|
||||
|
||||
|
||||
<lifecycle-callbacks>
|
||||
<lifecycle-callback type="prePersist" method="doStuffOnPrePersist"/>
|
||||
<lifecycle-callback type="prePersist" method="doOtherStuffOnPrePersistToo"/>
|
||||
@@ -16,15 +16,17 @@
|
||||
<id name="id" type="integer" column="id">
|
||||
<generator strategy="AUTO"/>
|
||||
</id>
|
||||
|
||||
|
||||
<field name="name" column="name" type="string" length="50" nullable="true" unique="true" />
|
||||
<field name="email" column="user_email" type="string" column-definition="CHAR(32) NOT NULL" />
|
||||
|
||||
|
||||
<one-to-one field="address" target-entity="Doctrine\Tests\ORM\Tools\Export\Address" inversed-by="user" orphan-removal="true">
|
||||
<cascade><cascade-persist /></cascade>
|
||||
<join-column name="address_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE"/>
|
||||
</one-to-one>
|
||||
|
||||
|
||||
<many-to-one field="mainGroup" target-entity="Doctrine\Tests\ORM\Tools\Export\Group" />
|
||||
|
||||
<one-to-many field="phonenumbers" target-entity="Doctrine\Tests\ORM\Tools\Export\Phonenumber" mapped-by="user" orphan-removal="true">
|
||||
<cascade>
|
||||
<cascade-persist/>
|
||||
@@ -34,7 +36,7 @@
|
||||
<order-by-field name="number" direction="ASC" />
|
||||
</order-by>
|
||||
</one-to-many>
|
||||
|
||||
|
||||
<one-to-many field="interests" target-entity="Doctrine\Tests\ORM\Tools\Export\Interests" mapped-by="user" orphan-removal="true">
|
||||
<cascade>
|
||||
<cascade-refresh/>
|
||||
@@ -44,7 +46,7 @@
|
||||
<cascade-remove/>
|
||||
</cascade>
|
||||
</one-to-many>
|
||||
|
||||
|
||||
<many-to-many field="groups" target-entity="Doctrine\Tests\ORM\Tools\Export\Group">
|
||||
<cascade>
|
||||
<cascade-all/>
|
||||
@@ -58,7 +60,7 @@
|
||||
</inverse-join-columns>
|
||||
</join-table>
|
||||
</many-to-many>
|
||||
|
||||
|
||||
</entity>
|
||||
|
||||
</doctrine-mapping>
|
||||
|
||||
@@ -26,6 +26,9 @@ Doctrine\Tests\ORM\Tools\Export\User:
|
||||
cascade: [ persist ]
|
||||
inversedBy: user
|
||||
orphanRemoval: true
|
||||
manyToOne:
|
||||
mainGroup:
|
||||
targetEntity: Doctrine\Tests\ORM\Tools\Export\Group
|
||||
oneToMany:
|
||||
phonenumbers:
|
||||
targetEntity: Doctrine\Tests\ORM\Tools\Export\Phonenumber
|
||||
@@ -57,4 +60,4 @@ Doctrine\Tests\ORM\Tools\Export\User:
|
||||
- all
|
||||
lifecycleCallbacks:
|
||||
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ]
|
||||
postPersist: [ doStuffOnPostPersist ]
|
||||
postPersist: [ doStuffOnPostPersist ]
|
||||
|
||||
@@ -88,6 +88,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
'Doctrine\Tests\Models\Routing\RoutingRouteBooking',
|
||||
),
|
||||
'navigation' => array(
|
||||
'Doctrine\Tests\Models\Navigation\NavUser',
|
||||
'Doctrine\Tests\Models\Navigation\NavCountry',
|
||||
'Doctrine\Tests\Models\Navigation\NavPhotos',
|
||||
'Doctrine\Tests\Models\Navigation\NavTour',
|
||||
|
||||
Reference in New Issue
Block a user