1
0
mirror of synced 2024-12-12 22:36:02 +03:00

Merge remote-tracking branch 'upstream/master' into avoid-update-on-delete

This commit is contained in:
flack 2013-11-17 11:36:06 +01:00
commit ffd858b238
17 changed files with 154 additions and 31 deletions

View File

@ -1,6 +1,7 @@
# Doctrine 2 ORM
Master: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=master)](http://travis-ci.org/doctrine/doctrine2)
2.4: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.4)](http://travis-ci.org/doctrine/doctrine2)
2.3: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.3)](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)

View File

@ -67,7 +67,7 @@ Advanced Topics
* :doc:`Architecture <reference/architecture>`
* :doc:`Advanced Configuration <reference/advanced-configuration>`
* :doc:`Limitations and knowns issues <reference/limitations-and-known-issues>`
* :doc:`Limitations and known issues <reference/limitations-and-known-issues>`
* :doc:`Commandline Tools <reference/tools>`
* :doc:`Transactions and Concurrency <reference/transactions-and-concurrency>`
* :doc:`Filters <reference/filters>`
@ -78,6 +78,7 @@ Advanced Topics
* :doc:`Change Tracking Policies <reference/change-tracking-policies>`
* :doc:`Best Practices <reference/best-practices>`
* :doc:`Metadata Drivers <reference/metadata-drivers>`
* :doc:`Batch Processing <reference/batch-processing>`
Tutorials
---------

View File

@ -519,7 +519,7 @@ details of the database join table. If you do not specify
@JoinTable on these relations reasonable mapping defaults apply
using the affected table and the column names.
Required attributes:
Optional attributes:
- **name**: Database name of the join-table

View File

@ -70,7 +70,6 @@ looks like this:
$em->getConnection()->commit();
} catch (Exception $e) {
$em->getConnection()->rollback();
$em->close();
throw $e;
}
@ -81,14 +80,12 @@ require an active transaction. Such methods will throw a
``TransactionRequiredException`` to inform you of that
requirement.
A more convenient alternative for explicit transaction demarcation
is the use of provided control abstractions in the form of
``Connection#transactional($func)`` and
``EntityManager#transactional($func)``. When used, these control
abstractions ensure that you never forget to rollback the
transaction or close the ``EntityManager``, apart from the obvious
code reduction. An example that is functionally equivalent to the
previously shown code looks as follows:
A more convenient alternative for explicit transaction demarcation is the use
of provided control abstractions in the form of
``Connection#transactional($func)`` and ``EntityManager#transactional($func)``.
When used, these control abstractions ensure that you never forget to rollback
the transaction, in addition to the obvious code reduction. An example that is
functionally equivalent to the previously shown code looks as follows:
.. code-block:: php
@ -104,8 +101,8 @@ previously shown code looks as follows:
The difference between ``Connection#transactional($func)`` and
``EntityManager#transactional($func)`` is that the latter
abstraction flushes the ``EntityManager`` prior to transaction
commit and also closes the ``EntityManager`` properly when an
exception occurs (in addition to rolling back the transaction).
commit and rolls back the transaction when an
exception occurs.
Exception Handling
~~~~~~~~~~~~~~~~~~

View File

@ -157,7 +157,7 @@ wishes to be hydrated. Default result-types include:
- SQL to a single result variable
Hydration to entities and arrays is one of most complex parts of Doctrine
algorithm-wise. It can built results with for example:
algorithm-wise. It can build results with for example:
- Single table selects
- Joins with n:1 or 1:n cardinality, grouping belonging to the same parent.

View File

@ -72,6 +72,7 @@ of several common elements:
# Doctrine.Tests.ORM.Mapping.User.dcm.yml
Doctrine\Tests\ORM\Mapping\User:
type: entity
repositoryClass: Doctrine\Tests\ORM\Mapping\UserRepository
table: cms_users
indexes:
name_index:

View File

@ -381,7 +381,7 @@ better than in a scenario where updates are done for each entity in isolation.
Doctrine follows the UnitOfWork pattern which additionally detects all entities
that were fetched and have changed during the request. You don't have to keep track of
entities yourself, when Doctrine already knowns about them.
entities yourself, when Doctrine already knows about them.
As a next step we want to fetch a list of all the products. Let's create a
new script for this:

View File

@ -190,17 +190,14 @@ class ArrayHydrator extends AbstractHydrator
( ! isset($baseElement[$relationAlias]))
) {
$baseElement[$relationAlias] = null;
} else if (
( ! isset($baseElement[$relationAlias])) ||
( ! isset($this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]]))
) {
} else if ( ! isset($baseElement[$relationAlias])) {
$baseElement[$relationAlias] = $data;
}
}
$coll =& $baseElement[$relationAlias];
if ($coll !== null) {
if (is_array($coll)) {
$this->updateResultPointer($coll, $index, $dqlAlias, $oneToOne);
}
} else {

View File

@ -477,7 +477,7 @@ class ObjectHydrator extends AbstractHydrator
$targetClass = $this->ce[$relation['targetEntity']];
if ($relation['isOwningSide']) {
//TODO: Just check hints['fetched'] here?
// TODO: Just check hints['fetched'] here?
// If there is an inverse mapping on the target class its bidirectional
if ($relation['inversedBy']) {
$inverseAssoc = $targetClass->associationMappings[$relation['inversedBy']];

View File

@ -328,7 +328,7 @@ class BasicEntityPersister
$identifier = $this->quoteStrategy->getIdentifierColumnNames($versionedClass, $this->platform);
$columnName = $this->quoteStrategy->getColumnName($versionField, $versionedClass, $this->platform);
//FIXME: Order with composite keys might not be correct
// FIXME: Order with composite keys might not be correct
$sql = 'SELECT ' . $columnName
. ' FROM ' . $tableName
. ' WHERE ' . implode(' = ? AND ', $identifier) . ' = ?';
@ -1976,4 +1976,4 @@ class BasicEntityPersister
$sql = implode(' AND ', $filterClauses);
return $sql ? "(" . $sql . ")" : ""; // Wrap again to avoid "X or Y and FilterConditionSQL"
}
}
}

View File

@ -82,7 +82,7 @@ class IdentityFunction extends FunctionNode
}
}
//The table with the relation may be a subclass, so get the table name from the association definition
// The table with the relation may be a subclass, so get the table name from the association definition
$tableName = $sqlWalker->getEntityManager()->getClassMetadata($assoc['sourceEntity'])->getTableName();
$tableAlias = $sqlWalker->getSQLTableAlias($tableName, $dqlAlias);

View File

@ -1878,7 +1878,7 @@ class Parser
case ($lookahead === Lexer::T_OPEN_PARENTHESIS):
return $this->SimpleArithmeticExpression();
//this check must be done before checking for a filed path expression
// this check must be done before checking for a filed path expression
case ($this->isFunction()):
$this->lexer->peek(); // "("
@ -1896,7 +1896,7 @@ class Parser
}
break;
//it is no function, so it must be a field path
// it is no function, so it must be a field path
case ($lookahead === Lexer::T_IDENTIFIER):
$this->lexer->peek(); // lookahead => '.'
$this->lexer->peek(); // lookahead => token after '.'
@ -2431,7 +2431,7 @@ class Parser
switch ($peek['value']) {
case '(':
//Peeks beyond the matched closing parenthesis.
// Peeks beyond the matched closing parenthesis.
$token = $this->peekBeyondClosingParenthesis(false);
if ($token['type'] === Lexer::T_NOT) {

View File

@ -134,7 +134,7 @@ abstract class AbstractExporter
}
foreach ($this->_metadata as $metadata) {
//In case output is returned, write it to a file, skip otherwise
// In case output is returned, write it to a file, skip otherwise
if($output = $this->exportClassMetadata($metadata)){
$path = $this->_generateOutputPath($metadata);
$dir = dirname($path);

View File

@ -166,7 +166,7 @@ class LimitSubqueryOutputWalker extends SqlWalker
if ($this->platform instanceof PostgreSqlPlatform ||
$this->platform instanceof OraclePlatform) {
//http://www.doctrine-project.org/jira/browse/DDC-1958
// http://www.doctrine-project.org/jira/browse/DDC-1958
$this->preserveSqlOrdering($AST, $sqlIdentifier, $innerSql, $sql);
}
@ -215,7 +215,7 @@ class LimitSubqueryOutputWalker extends SqlWalker
}
}
}
//remove identifier aliases
// remove identifier aliases
$sqlOrderColumns = array_diff($sqlOrderColumns, $sqlIdentifier);
}

View File

@ -2406,7 +2406,7 @@ class UnitOfWork implements PropertyChangedListener
{
$coid = spl_object_hash($coll);
//TODO: if $coll is already scheduled for recreation ... what to do?
// TODO: if $coll is already scheduled for recreation ... what to do?
// Just remove $coll from the scheduled recreations?
if (isset($this->collectionUpdates[$coid])) {
unset($this->collectionUpdates[$coid]);

View File

@ -85,4 +85,9 @@ class DriverMock implements \Doctrine\DBAL\Driver
{
return;
}
public function convertExceptionCode(\Exception $exception)
{
return 0;
}
}

View File

@ -0,0 +1,121 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
/**
* @group DDC-2759
*/
class DDC2759Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
/**
* {@inheritDoc}
*/
protected function setup()
{
parent::setup();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2759Qualification'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2759Category'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2759QualificationMetadata'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2759MetadataCategory'),
));
} catch(\Exception $e) {
return;
}
$qualification = new DDC2759Qualification();
$qualificationMetadata = new DDC2759QualificationMetadata($qualification);
$category1 = new DDC2759Category();
$category2 = new DDC2759Category();
$metadataCategory1 = new DDC2759MetadataCategory($qualificationMetadata, $category1);
$metadataCategory2 = new DDC2759MetadataCategory($qualificationMetadata, $category2);
$this->_em->persist($qualification);
$this->_em->persist($qualificationMetadata);
$this->_em->persist($category1);
$this->_em->persist($category2);
$this->_em->persist($metadataCategory1);
$this->_em->persist($metadataCategory2);
$this->_em->flush();
$this->_em->clear();
}
public function testCorrectNumberOfAssociationsIsReturned()
{
$repository = $this->_em->getRepository(__NAMESPACE__ . '\DDC2759Qualification');
$builder = $repository->createQueryBuilder('q')
->select('q, qm, qmc')
->innerJoin('q.metadata', 'qm')
->innerJoin('qm.metadataCategories', 'qmc');
$result = $builder->getQuery()
->getArrayResult();
$this->assertCount(2, $result[0]['metadata']['metadataCategories']);
}
}
/** @Entity @Table(name="ddc_2759_qualification") */
class DDC2759Qualification
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;
/** @OneToOne(targetEntity="DDC2759QualificationMetadata", mappedBy="content") */
public $metadata;
}
/** @Entity @Table(name="ddc_2759_category") */
class DDC2759Category
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;
/** @OneToMany(targetEntity="DDC2759MetadataCategory", mappedBy="category") */
public $metadataCategories;
}
/** @Entity @Table(name="ddc_2759_qualification_metadata") */
class DDC2759QualificationMetadata
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;
/** @OneToOne(targetEntity="DDC2759Qualification", inversedBy="metadata") */
public $content;
/** @OneToMany(targetEntity="DDC2759MetadataCategory", mappedBy="metadata") */
protected $metadataCategories;
public function __construct(DDC2759Qualification $content)
{
$this->content = $content;
}
}
/** @Entity @Table(name="ddc_2759_metadata_category") */
class DDC2759MetadataCategory
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;
/** @ManyToOne(targetEntity="DDC2759QualificationMetadata", inversedBy="metadataCategories") */
public $metadata;
/** @ManyToOne(targetEntity="DDC2759Category", inversedBy="metadataCategories") */
public $category;
public function __construct(DDC2759QualificationMetadata $metadata, DDC2759Category $category)
{
$this->metadata = $metadata;
$this->category = $category;
}
}