Skip to content

Commit

Permalink
Merge pull request #9326 from kimhemsoe/rsm-custom-type
Browse files Browse the repository at this point in the history
Add support for custom types with requireSQLConversion and ResultSetMappingBuilder::generateSelectClause()
  • Loading branch information
greg0ire authored Jan 9, 2022
2 parents fdd3d11 + f508a4b commit c6d8aec
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 7 deletions.
22 changes: 15 additions & 7 deletions lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Doctrine\ORM\Query;

use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Internal\SQLResultCasing;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
Expand Down Expand Up @@ -432,19 +433,26 @@ public function generateSelectClause($tableAliases = [])
foreach ($this->columnOwnerMap as $columnName => $dqlAlias) {
$tableAlias = $tableAliases[$dqlAlias] ?? $dqlAlias;

if ($sql) {
if ($sql !== '') {
$sql .= ', ';
}

$sql .= $tableAlias . '.';

if (isset($this->fieldMappings[$columnName])) {
$class = $this->em->getClassMetadata($this->declaringClasses[$columnName]);
$sql .= $class->fieldMappings[$this->fieldMappings[$columnName]]['columnName'];
$class = $this->em->getClassMetadata($this->declaringClasses[$columnName]);
$fieldName = $this->fieldMappings[$columnName];
$classFieldMapping = $class->fieldMappings[$fieldName];
$columnSql = $tableAlias . '.' . $classFieldMapping['columnName'];

if (isset($classFieldMapping['requireSQLConversion']) && $classFieldMapping['requireSQLConversion'] === true) {
$type = Type::getType($classFieldMapping['type']);
$columnSql = $type->convertToPHPValueSQL($columnSql, $this->em->getConnection()->getDatabasePlatform());
}

$sql .= $columnSql;
} elseif (isset($this->metaMappings[$columnName])) {
$sql .= $this->metaMappings[$columnName];
$sql .= $tableAlias . '.' . $this->metaMappings[$columnName];
} elseif (isset($this->discriminatorColumns[$dqlAlias])) {
$sql .= $this->discriminatorColumns[$dqlAlias];
$sql .= $tableAlias . '.' . $this->discriminatorColumns[$dqlAlias];
}

$sql .= ' AS ' . $columnName;
Expand Down
37 changes: 37 additions & 0 deletions tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
use Doctrine\ORM\Internal\Hydration\HydrationException;
use Doctrine\ORM\Internal\SQLResultCasing;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Query\Parameter;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\Tests\DbalTypes\UpperCaseStringType;
use Doctrine\Tests\Models\CMS\CmsAddress;
use Doctrine\Tests\Models\CMS\CmsEmail;
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
Expand All @@ -22,6 +24,7 @@
use Doctrine\Tests\Models\Company\CompanyFixContract;
use Doctrine\Tests\Models\Company\CompanyFlexContract;
use Doctrine\Tests\Models\Company\CompanyPerson;
use Doctrine\Tests\Models\CustomType\CustomTypeUpperCase;
use Doctrine\Tests\Models\DDC3899\DDC3899FixContract;
use Doctrine\Tests\Models\DDC3899\DDC3899User;
use Doctrine\Tests\OrmFunctionalTestCase;
Expand Down Expand Up @@ -796,4 +799,38 @@ public function testGenerateSelectClauseWithDiscriminatorColumn(): void

$this->assertSQLEquals('u1.id as id, c1.discr as discr', $selectClause);
}

public function testGenerateSelectClauseWithCustomTypeUsingEntityFromClassMetadata(): void
{
if (DBALType::hasType('upper_case_string')) {
DBALType::overrideType('upper_case_string', UpperCaseStringType::class);
} else {
DBALType::addType('upper_case_string', UpperCaseStringType::class);
}

$rsm = new ResultSetMappingBuilder($this->_em, ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT);

$rsm->addRootEntityFromClassMetadata(CustomTypeUpperCase::class, 'ct');

$selectClause = $rsm->generateSelectClause(['ct' => 'ct1']);

$this->assertSQLEquals('ct1.id as id0, lower(ct1.lowercasestring) as lowercasestring1, lower(ct1.named_lower_case_string) as named_lower_case_string2', $selectClause);
}

public function testGenerateSelectClauseWithCustomTypeUsingAddFieldResult(): void
{
if (DBALType::hasType('upper_case_string')) {
DBALType::overrideType('upper_case_string', UpperCaseStringType::class);
} else {
DBALType::addType('upper_case_string', UpperCaseStringType::class);
}

$rsm = new ResultSetMappingBuilder($this->_em, ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT);
$rsm->addEntityResult(CustomTypeUpperCase::class, 'ct');
$rsm->addFieldResult('ct', $this->getSQLResultCasing($this->platform, 'lowercasestring'), 'lowerCaseString');

$selectClause = $rsm->generateSelectClause(['ct' => 'ct1']);

$this->assertSQLEquals('lower(ct1.lowercasestring) as lowercasestring', $selectClause);
}
}

0 comments on commit c6d8aec

Please sign in to comment.