Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Implemented support to entities with association marked as @Id suppor…

…t in many situations. Fixed DDC-1435.
  • Loading branch information...
commit 0ec2cc557f51d6240396689e36101f62d84d2a38 1 parent 3745e94
Guilherme Blanco guilhermeblanco authored
72 lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -1111,25 +1111,25 @@ public function getColumnNames(array $fieldNames = null)
1111 1111 */
1112 1112 public function getIdentifierColumnNames()
1113 1113 {
1114   - if ($this->isIdentifierComposite) {
1115   - $columnNames = array();
1116   - foreach ($this->identifier as $idField) {
1117   - if (isset($this->associationMappings[$idField])) {
1118   - // no composite pk as fk entity assumption:
1119   - $columnNames[] = $this->associationMappings[$idField]['joinColumns'][0]['name'];
1120   - } else {
1121   - $columnNames[] = $this->fieldMappings[$idField]['columnName'];
1122   - }
  1114 + $columnNames = array();
  1115 +
  1116 + foreach ($this->identifier as $idProperty) {
  1117 + if (isset($this->fieldMappings[$idProperty])) {
  1118 + $columnNames[] = $this->fieldMappings[$idProperty]['columnName'];
  1119 +
  1120 + continue;
1123 1121 }
1124   - return $columnNames;
1125   - } else if(isset($this->fieldMappings[$this->identifier[0]])) {
1126   - return array($this->fieldMappings[$this->identifier[0]]['columnName']);
1127   - } else {
1128   - // no composite pk as fk entity assumption:
1129   - return array($this->associationMappings[$this->identifier[0]]['joinColumns'][0]['name']);
  1122 +
  1123 + // Association defined as Id field
  1124 + $joinColumns = $this->associationMappings[$idProperty]['joinColumns'];
  1125 + $assocColumnNames = array_map(function ($joinColumn) { return $joinColumn['name']; }, $joinColumns);
  1126 +
  1127 + $columnNames = array_merge($columnNames, $assocColumnNames);
1130 1128 }
  1129 +
  1130 + return $columnNames;
1131 1131 }
1132   -
  1132 +
1133 1133 /**
1134 1134 * Sets the type of Id generator to use for the mapped class.
1135 1135 */
@@ -1905,6 +1905,42 @@ public function getName()
1905 1905 }
1906 1906
1907 1907 /**
  1908 + * Gets the (possibly quoted) identifier column names for safe use in an SQL statement.
  1909 + *
  1910 + * @param AbstractPlatform $platform
  1911 + * @return array
  1912 + */
  1913 + public function getQuotedIdentifierColumnNames($platform)
  1914 + {
  1915 + $quotedColumnNames = array();
  1916 +
  1917 + foreach ($this->identifier as $idProperty) {
  1918 + if (isset($this->fieldMappings[$idProperty])) {
  1919 + $quotedColumnNames[] = isset($this->fieldMappings[$idProperty]['quoted'])
  1920 + ? $platform->quoteIdentifier($this->fieldMappings[$idProperty]['columnName'])
  1921 + : $this->fieldMappings[$idProperty]['columnName'];
  1922 +
  1923 + continue;
  1924 + }
  1925 +
  1926 + // Association defined as Id field
  1927 + $joinColumns = $this->associationMappings[$idProperty]['joinColumns'];
  1928 + $assocQuotedColumnNames = array_map(
  1929 + function ($joinColumn) {
  1930 + return isset($joinColumn['quoted'])
  1931 + ? $platform->quoteIdentifier($joinColumn['name'])
  1932 + : $joinColumn['name'];
  1933 + },
  1934 + $joinColumns
  1935 + );
  1936 +
  1937 + $quotedColumnNames = array_merge($quotedColumnNames, $assocQuotedColumnNames);
  1938 + }
  1939 +
  1940 + return $quotedColumnNames;
  1941 + }
  1942 +
  1943 + /**
1908 1944 * Gets the (possibly quoted) column name of a mapped field for safe use
1909 1945 * in an SQL statement.
1910 1946 *
@@ -1914,7 +1950,9 @@ public function getName()
1914 1950 */
1915 1951 public function getQuotedColumnName($field, $platform)
1916 1952 {
1917   - return isset($this->fieldMappings[$field]['quoted']) ? $platform->quoteIdentifier($this->fieldMappings[$field]['columnName']) : $this->fieldMappings[$field]['columnName'];
  1953 + return isset($this->fieldMappings[$field]['quoted'])
  1954 + ? $platform->quoteIdentifier($this->fieldMappings[$field]['columnName'])
  1955 + : $this->fieldMappings[$field]['columnName'];
1918 1956 }
1919 1957
1920 1958 /**
20 lib/Doctrine/ORM/Query/SqlWalker.php
@@ -248,10 +248,9 @@ private function _generateClassTableInheritanceJoins($class, $dqlAlias)
248 248 $sql .= 'JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
249 249 $first = true;
250 250
251   - foreach ($class->identifier as $idField) {
  251 + foreach ($class->getQuotedIdentifierColumnNames($this->_platform) as $columnName) {
252 252 if ($first) $first = false; else $sql .= ' AND ';
253 253
254   - $columnName = $class->getQuotedColumnName($idField, $this->_platform);
255 254 $sql .= $baseTableAlias . '.' . $columnName . ' = ' . $tableAlias . '.' . $columnName;
256 255 }
257 256 }
@@ -264,10 +263,9 @@ private function _generateClassTableInheritanceJoins($class, $dqlAlias)
264 263 $sql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
265 264 $first = true;
266 265
267   - foreach ($class->identifier as $idField) {
  266 + foreach ($class->getQuotedIdentifierColumnNames($this->_platform) as $columnName) {
268 267 if ($first) $first = false; else $sql .= ' AND ';
269 268
270   - $columnName = $class->getQuotedColumnName($idField, $this->_platform);
271 269 $sql .= $baseTableAlias . '.' . $columnName . ' = ' . $tableAlias . '.' . $columnName;
272 270 }
273 271 }
@@ -1346,8 +1344,8 @@ public function walkSimpleSelectExpression($simpleSelectExpression)
1346 1344 $tableAlias = $this->getSQLTableAlias($class->getTableName(), $expr);
1347 1345 $sqlParts = array();
1348 1346
1349   - foreach ($class->identifier as $identifier) {
1350   - $sqlParts[] = $tableAlias . '.' . $class->getQuotedColumnName($identifier, $this->_platform);
  1347 + foreach ($class->getQuotedIdentifierColumnNames($this->_platform) as $columnName) {
  1348 + $sqlParts[] = $tableAlias . '.' . $columnName;
1351 1349 }
1352 1350
1353 1351 $sql .= implode(', ', $sqlParts);
@@ -1634,12 +1632,11 @@ public function walkCollectionMemberExpression($collMemberExpr)
1634 1632 $sql .= ' AND ';
1635 1633 $first = true;
1636 1634
1637   - foreach ($targetClass->identifier as $idField) {
  1635 + foreach ($targetClass->getQuotedIdentifierColumnNames($this->_platform) as $targetColumnName) {
1638 1636 if ($first) $first = false; else $sql .= ' AND ';
1639 1637
1640 1638 $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
1641   - $sql .= $targetTableAlias . '.'
1642   - . $targetClass->getQuotedColumnName($idField, $this->_platform) . ' = ?';
  1639 + $sql .= $targetTableAlias . '.' . $targetColumnName . ' = ?';
1643 1640 }
1644 1641 } else { // many-to-many
1645 1642 $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']);
@@ -1684,12 +1681,11 @@ public function walkCollectionMemberExpression($collMemberExpr)
1684 1681 $sql .= ' AND ';
1685 1682 $first = true;
1686 1683
1687   - foreach ($targetClass->identifier as $idField) {
  1684 + foreach ($targetClass->getQuotedIdentifierColumnNames($this->_platform) as $targetColumnName) {
1688 1685 if ($first) $first = false; else $sql .= ' AND ';
1689 1686
1690 1687 $this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
1691   - $sql .= $targetTableAlias . '.'
1692   - . $targetClass->getQuotedColumnName($idField, $this->_platform) . ' = ?';
  1688 + $sql .= $targetTableAlias . '.' . $targetColumnName . ' = ?';
1693 1689 }
1694 1690 }
1695 1691
1  tests/Doctrine/Tests/Models/DDC117/DDC117Article.php
@@ -9,6 +9,7 @@ class DDC117Article
9 9 {
10 10 /** @Id @Column(type="integer", name="article_id") @GeneratedValue */
11 11 private $id;
  12 +
12 13 /** @Column */
13 14 private $title;
14 15
11 tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -1268,6 +1268,17 @@ public function testSelfReferenceWithOneToOneDoesNotDuplicateAlias()
1268 1268 array(Query::HINT_FORCE_PARTIAL_LOAD => false)
1269 1269 );
1270 1270 }
  1271 +
  1272 + /**
  1273 + * @group DDC-1435
  1274 + */
  1275 + public function testForeignKeyAsPrimaryKeySubselect()
  1276 + {
  1277 + $this->assertSqlGeneration(
  1278 + "SELECT s FROM Doctrine\Tests\Models\DDC117\DDC117Article s WHERE EXISTS (SELECT r FROM Doctrine\Tests\Models\DDC117\DDC117Reference r WHERE r.source = s)",
  1279 + "SELECT d0_.article_id AS article_id0, d0_.title AS title1 FROM DDC117Article d0_ WHERE EXISTS (SELECT d1_.source_id, d1_.target_id FROM DDC117Reference d1_ WHERE d1_.source_id = d0_.article_id)"
  1280 + );
  1281 + }
1271 1282 }
1272 1283
1273 1284

1 comment on commit 0ec2cc5

Benjamin Eberlei
Owner

Good refactoring. I was thinking to shortcut it again, but then the loop with isset and continue for the "default" case of 1 column is probably the fastest solution anyways.

Please sign in to comment.
Something went wrong with that request. Please try again.