Merge remote branch 'origin/master'
This commit is contained in:
commit
12c9ca971b
@ -1,6 +1,62 @@
|
||||
|
||||
# Upgrade from 2.0-ALPHA4 to 2.0-BETA1
|
||||
|
||||
## Console migrated to Symfony Console
|
||||
|
||||
The Doctrine Cli has been replaced by Symfony Console Configuration
|
||||
|
||||
Instead of having to specifiy:
|
||||
|
||||
[php]
|
||||
$cliConfig = new CliConfiguration();
|
||||
$cliConfig->setAttribute('em', $entityManager);
|
||||
|
||||
You now have to configure the script like:
|
||||
|
||||
[php]
|
||||
$helperSet = new \Symfony\Components\Console\Helper\HelperSet(array(
|
||||
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
|
||||
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
|
||||
));
|
||||
|
||||
## Console: No need for Mapping Paths anymore
|
||||
|
||||
In previous versions you had to specify the --from and --from-path options
|
||||
to show where your mapping paths are from the console. However this information
|
||||
is already known from the Mapping Driver configuration, so the requirement
|
||||
for this options were dropped.
|
||||
|
||||
Instead for each console command all the entities are loaded and to
|
||||
restrict the operation to one or more sub-groups you can use the --filter flag.
|
||||
|
||||
## AnnotationDriver is not a default mapping driver anymore
|
||||
|
||||
In conjunction with the recent changes to Console we realized that the
|
||||
annotations driver being a default metadata driver lead to lots of glue
|
||||
code in the console components to detect where entities lie and how to load
|
||||
them for batch updates like SchemaTool and other commands. However the
|
||||
annotations driver being a default driver does not really help that much
|
||||
anyways.
|
||||
|
||||
Therefore we decided to break backwards compability in this issue and drop
|
||||
the support for Annotations as Default Driver and require our users to
|
||||
specify the driver explicitly (which allows us to ask for the path to all
|
||||
entities).
|
||||
|
||||
If you are using the annotations metadata driver as default driver, you
|
||||
have to add the following lines to your bootstrap code:
|
||||
|
||||
$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
|
||||
$config->setMetadataDriverImpl($driverImpl);
|
||||
|
||||
You have to specify the path to your entities as either string of a single
|
||||
path or array of multiple paths
|
||||
to your entities. This information will be used by all console commands to
|
||||
access all entities.
|
||||
|
||||
Xml and Yaml Drivers work as before!
|
||||
|
||||
|
||||
## New inversedBy attribute
|
||||
|
||||
It is now *mandatory* that the owning side of a bidirectional association specifies the
|
||||
|
@ -465,6 +465,11 @@ class SqlWalker implements TreeWalker
|
||||
$fieldName = array_pop($parts);
|
||||
$dqlAlias = $pathExpr->identificationVariable;
|
||||
$class = $this->_queryComponents[$dqlAlias]['metadata'];
|
||||
|
||||
if (isset($class->inheritedAssociationFields[$fieldName])) {
|
||||
$class = $this->_em->getClassMetadata($class->inheritedAssociationFields[$fieldName]);
|
||||
}
|
||||
|
||||
$assoc = $class->associationMappings[$fieldName];
|
||||
|
||||
if ($assoc->isOwningSide) {
|
||||
@ -472,8 +477,8 @@ class SqlWalker implements TreeWalker
|
||||
if (count($assoc->sourceToTargetKeyColumns) > 1) {
|
||||
throw QueryException::associationPathCompositeKeyNotSupported();
|
||||
}
|
||||
$sql .= $this->walkIdentificationVariable($dqlAlias) . '.'
|
||||
. reset($assoc->targetToSourceKeyColumns);
|
||||
$sql .= $this->getSqlTableAlias($class->table['name'], $dqlAlias) . '.'
|
||||
. reset($assoc->targetToSourceKeyColumns);
|
||||
} else {
|
||||
// 2- Inverse side: NOT (YET?) SUPPORTED
|
||||
throw QueryException::associationPathInverseSideNotSupported();
|
||||
@ -683,23 +688,15 @@ class SqlWalker implements TreeWalker
|
||||
|
||||
$joinAssocPathExpr = $join->joinAssociationPathExpression;
|
||||
$joinedDqlAlias = $join->aliasIdentificationVariable;
|
||||
$targetQComp = $this->_queryComponents[$joinedDqlAlias];
|
||||
$targetClass = $targetQComp['metadata'];
|
||||
$relation = $targetQComp['relation'];
|
||||
$sourceClass = $this->_queryComponents[$joinAssocPathExpr->identificationVariable]['metadata'];
|
||||
|
||||
$relation = $this->_queryComponents[$joinedDqlAlias]['relation'];
|
||||
$targetClass = $this->_em->getClassMetadata($relation->targetEntityName);
|
||||
$sourceClass = $this->_em->getClassMetadata($relation->sourceEntityName);
|
||||
$targetTableName = $targetClass->getQuotedTableName($this->_platform);
|
||||
$targetTableAlias = $this->getSqlTableAlias($targetClass->getTableName(), $joinedDqlAlias);
|
||||
$sourceTableAlias = $this->getSqlTableAlias(
|
||||
$sourceClass->getTableName(), $joinAssocPathExpr->identificationVariable
|
||||
);
|
||||
$targetTableAlias = $this->getSqlTableAlias($targetClass->table['name'], $joinedDqlAlias);
|
||||
$sourceTableAlias = $this->getSqlTableAlias($sourceClass->table['name'], $joinAssocPathExpr->identificationVariable);
|
||||
|
||||
// Ensure we got the owning side, since it has all mapping info
|
||||
if ( ! $relation->isOwningSide) {
|
||||
$assoc = $targetClass->associationMappings[$relation->mappedBy];
|
||||
} else {
|
||||
$assoc = $relation;
|
||||
}
|
||||
$assoc = ( ! $relation->isOwningSide) ? $targetClass->associationMappings[$relation->mappedBy] : $relation;
|
||||
|
||||
if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true) {
|
||||
if ($relation->isOneToMany() || $relation->isManyToMany()) {
|
||||
@ -713,7 +710,7 @@ class SqlWalker implements TreeWalker
|
||||
|
||||
foreach ($assoc->sourceToTargetKeyColumns as $sourceColumn => $targetColumn) {
|
||||
if ( ! $first) $sql .= ' AND '; else $first = false;
|
||||
|
||||
|
||||
if ($relation->isOwningSide) {
|
||||
$quotedTargetColumn = $targetClass->getQuotedColumnName($targetClass->fieldNames[$targetColumn], $this->_platform);
|
||||
$sql .= $sourceTableAlias . '.' . $sourceColumn
|
||||
|
@ -933,6 +933,9 @@ public function <methodName>()
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
|
||||
return 'IDENTITY';
|
||||
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_NONE:
|
||||
return 'NONE';
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type);
|
||||
}
|
||||
|
71
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC448Test.php
Normal file
71
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC448Test.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
class DDC448Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC448MainTable'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC448ConnectedClass'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC448SubTable'),
|
||||
));
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$q = $this->_em->createQuery("select b from ".__NAMESPACE__."\\DDC448SubTable b where b.connectedClassId = ?1");
|
||||
$this->assertEquals('SELECT d0_.id AS id0, d0_.discr AS discr1, d0_.connectedClassId AS connectedClassId2 FROM SubTable s1_ INNER JOIN DDC448MainTable d0_ ON s1_.id = d0_.id WHERE d0_.connectedClassId = ?', $q->getSQL());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorColumn(name="discr", type="smallint")
|
||||
* @DiscriminatorMap({
|
||||
* "0" = "DDC448MainTable",
|
||||
* "1" = "DDC448SubTable"
|
||||
* })
|
||||
*/
|
||||
class DDC448MainTable
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(name="id", type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ManyToOne(targetEntity="DDC448ConnectedClass", cascade={"all"}, fetch="EAGER")
|
||||
* @JoinColumn(name="connectedClassId", referencedColumnName="id", onDelete="CASCADE", onUpdate="CASCADE", nullable=true)
|
||||
*/
|
||||
private $connectedClassId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="connectedClass")
|
||||
* @HasLifecycleCallbacks
|
||||
*/
|
||||
class DDC448ConnectedClass
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(name="id", type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $id; // connected with DDC448MainTable
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="SubTable")
|
||||
*/
|
||||
class DDC448SubTable extends DDC448MainTable
|
||||
{
|
||||
}
|
69
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC493Test.php
Normal file
69
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC493Test.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
class DDC493Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC493Customer'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC493Distributor'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC493Contact')
|
||||
));
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$q = $this->_em->createQuery("select u, u.contact.data from ".__NAMESPACE__."\\DDC493Distributor u");
|
||||
$this->assertEquals('SELECT d0_.id AS id0, d1_.data AS data1, d0_.discr AS discr2, d0_.contact AS contact3 FROM DDC493Distributor d2_ INNER JOIN DDC493Customer d0_ ON d2_.id = d0_.id INNER JOIN DDC493Contact d1_ ON d0_.contact = d1_.id', $q->getSQL());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorColumn(name="discr", type="string")
|
||||
* @DiscriminatorMap({"distributor" = "DDC493Distributor", "customer" = "DDC493Customer"})
|
||||
*/
|
||||
class DDC493Customer {
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
* @OneToOne(targetEntity="DDC493Contact", cascade={"remove","persist"})
|
||||
* @JoinColumn(name="contact", referencedColumnName="id")
|
||||
*/
|
||||
public $contact;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC493Distributor extends DDC493Customer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC493Contact
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
public $id;
|
||||
/** @Column(type="string") */
|
||||
public $data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
71
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC513Test.php
Normal file
71
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC513Test.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
class DDC513Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC513OfferItem'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC513Item'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC513Price'),
|
||||
));
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$q = $this->_em->createQuery("select u from ".__NAMESPACE__."\\DDC513OfferItem u left join u.price p");
|
||||
$this->assertEquals('SELECT d0_.id AS id0, d0_.discr AS discr1, d0_.price AS price2 FROM DDC513OfferItem d1_ INNER JOIN DDC513Item d0_ ON d1_.id = d0_.id LEFT JOIN DDC513Price d2_ ON d0_.price = d2_.id', $q->getSQL());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC513OfferItem extends DDC513Item
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorColumn(name="discr", type="string")
|
||||
* @DiscriminatorMap({"item" = "DDC513Item", "offerItem" = "DDC513OfferItem"})
|
||||
*/
|
||||
class DDC513Item
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @OneToOne(targetEntity="DDC513Price", cascade={"remove","persist"})
|
||||
* @JoinColumn(name="price", referencedColumnName="id")
|
||||
*/
|
||||
public $price;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC513Price {
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/** @Column(type="string") */
|
||||
public $data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user