1
0
mirror of synced 2025-01-18 22:41:43 +03:00

Merge remote branch 'origin/master'

This commit is contained in:
Jonathan H. Wage 2010-04-13 14:14:02 -04:00
commit 12c9ca971b
6 changed files with 284 additions and 17 deletions

View File

@ -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

View File

@ -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

View File

@ -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);
}

View 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
{
}

View 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;
}

View 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;
}