Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove SQL resultset mapping #10114

Merged
merged 1 commit into from
Oct 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 0 additions & 136 deletions docs/en/reference/annotations-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ Index
-----

- :ref:`@Column <annref_column>`
- :ref:`@ColumnResult <annref_column_result>`
- :ref:`@Cache <annref_cache>`
- :ref:`@ChangeTrackingPolicy <annref_changetrackingpolicy>`
- :ref:`@CustomIdGenerator <annref_customidgenerator>`
Expand All @@ -56,8 +55,6 @@ Index
- :ref:`@Embeddable <annref_embeddable>`
- :ref:`@Embedded <annref_embedded>`
- :ref:`@Entity <annref_entity>`
- :ref:`@EntityResult <annref_entity_result>`
- :ref:`@FieldResult <annref_field_result>`
- :ref:`@GeneratedValue <annref_generatedvalue>`
- :ref:`@HasLifecycleCallbacks <annref_haslifecyclecallbacks>`
- :ref:`@Index <annref_index>`
Expand All @@ -80,7 +77,6 @@ Index
- :ref:`@PreRemove <annref_preremove>`
- :ref:`@PreUpdate <annref_preupdate>`
- :ref:`@SequenceGenerator <annref_sequencegenerator>`
- :ref:`@SqlResultSetMapping <annref_sql_resultset_mapping>`
- :ref:`@Table <annref_table>`
- :ref:`@UniqueConstraint <annref_uniqueconstraint>`
- :ref:`@Version <annref_version>`
Expand Down Expand Up @@ -216,17 +212,6 @@ Examples:
*/
protected $fullname;

.. _annref_column_result:

@ColumnResult
~~~~~~~~~~~~~~
References name of a column in the SELECT clause of a SQL query.
Scalar result types can be included in the query result by specifying this annotation in the metadata.

Required attributes:

- **name**: The name of a column in the SELECT clause of a SQL query

.. _annref_cache:

@Cache
Expand Down Expand Up @@ -436,39 +421,6 @@ Example:
// ...
}

.. _annref_entity_result:

@EntityResult
~~~~~~~~~~~~~~
References an entity in the SELECT clause of a SQL query.
If this annotation is used, the SQL statement should select all of the columns that are mapped to the entity object.
This should include foreign key columns to related entities.
The results obtained when insufficient data is available are undefined.

Required attributes:

- **entityClass**: The class of the result.

Optional attributes:

- **fields**: Array of @FieldResult, Maps the columns specified in the SELECT list of the query to the properties or fields of the entity class.
- **discriminatorColumn**: Specifies the column name of the column in the SELECT list that is used to determine the type of the entity instance.

.. _annref_field_result:

@FieldResult
~~~~~~~~~~~~~
Is used to map the columns specified in the SELECT list of the query to the properties or fields of the entity class.

Required attributes:

- **name**: Name of the persistent field or property of the class.


Optional attributes:

- **column**: Name of the column in the SELECT clause.

.. _annref_generatedvalue:

@GeneratedValue
Expand Down Expand Up @@ -1088,94 +1040,6 @@ Example:
*/
protected $id = null;

.. _annref_sql_resultset_mapping:

@SqlResultSetMapping
~~~~~~~~~~~~~~~~~~~~
The SqlResultSetMapping annotation is used to specify the mapping of the result of a native SQL query.
The SqlResultSetMapping annotation can be applied to an entity or mapped superclass.

Required attributes:

- **name**: The name given to the result set mapping, and used to refer to it in the methods of the Query API.


Optional attributes:

- **entities**: Array of @EntityResult, Specifies the result set mapping to entities.
- **columns**: Array of @ColumnResult, Specifies the result set mapping to scalar values.

Example:

.. code-block:: php

<?php
/**
* @SqlResultSetMappings({
* @SqlResultSetMapping(
* name = "mappingUserPhonenumberCount",
* entities= {
* @EntityResult(
* entityClass = "User",
* fields = {
* @FieldResult(name = "id"),
* @FieldResult(name = "name"),
* @FieldResult(name = "status"),
* }
* )
* },
* columns = {
* @ColumnResult("numphones")
* }
* ),
* @SqlResultSetMapping(
* name = "mappingMultipleJoinsEntityResults",
* entities= {
* @EntityResult(
* entityClass = "__CLASS__",
* fields = {
* @FieldResult(name = "id", column="u_id"),
* @FieldResult(name = "name", column="u_name"),
* @FieldResult(name = "status", column="u_status"),
* }
* ),
* @EntityResult(
* entityClass = "Address",
* fields = {
* @FieldResult(name = "id", column="a_id"),
* @FieldResult(name = "zip", column="a_zip"),
* @FieldResult(name = "country", column="a_country"),
* }
* )
* },
* columns = {
* @ColumnResult("numphones")
* }
* )
*})
*/
class User
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;

/** @Column(type="string", length=50, nullable=true) */
public $status;

/** @Column(type="string", length=255, unique=true) */
public $username;

/** @Column(type="string", length=255) */
public $name;

/** @OneToMany(targetEntity="Phonenumber") */
public $phonenumbers;

/** @OneToOne(targetEntity="Address") */
public $address;

// ....
}
.. _annref_table:

@Table
Expand Down
19 changes: 0 additions & 19 deletions doctrine-mapping.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -113,24 +113,6 @@
<xs:attribute name="discriminator-column" type="xs:string" use="optional" />
</xs:complexType>

<xs:complexType name="sql-result-set-mapping">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="entity-result" type="orm:entity-result"/>
<xs:element name="column-result" type="orm:column-result"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:choice>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:choice>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>

<xs:complexType name="sql-result-set-mappings">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="sql-result-set-mapping" type="orm:sql-result-set-mapping" minOccurs="1" maxOccurs="unbounded" />
</xs:choice>
</xs:complexType>

<xs:complexType name="cache">
<xs:attribute name="usage" type="orm:cache-usage-type" />
<xs:attribute name="region" type="xs:string" />
Expand All @@ -146,7 +128,6 @@
<xs:element name="discriminator-map" type="orm:discriminator-map" minOccurs="0"/>
<xs:element name="lifecycle-callbacks" type="orm:lifecycle-callbacks" minOccurs="0" maxOccurs="1" />
<xs:element name="entity-listeners" type="orm:entity-listeners" minOccurs="0" maxOccurs="1" />
<xs:element name="sql-result-set-mappings" type="orm:sql-result-set-mappings" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="id" type="orm:id" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="field" type="orm:field" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="embedded" type="orm:embedded" minOccurs="0" maxOccurs="unbounded"/>
Expand Down
32 changes: 0 additions & 32 deletions lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,6 @@ protected function doLoadMetadata(
$class->containsEnumIdentifier = true;
}

if (! empty($parent->sqlResultSetMappings)) {
$this->addInheritedSqlResultSetMappings($class, $parent);
}

if (! empty($parent->entityListeners) && empty($class->entityListeners)) {
$class->entityListeners = $parent->entityListeners;
}
Expand Down Expand Up @@ -443,34 +439,6 @@ private function addInheritedIndexes(ClassMetadata $subClass, ClassMetadata $par
}
}

/**
* Adds inherited sql result set mappings to the subclass mapping.
*/
private function addInheritedSqlResultSetMappings(ClassMetadata $subClass, ClassMetadata $parentClass): void
{
foreach ($parentClass->sqlResultSetMappings as $name => $mapping) {
if (! isset($subClass->sqlResultSetMappings[$name])) {
$entities = [];
foreach ($mapping['entities'] as $entity) {
$entities[] = [
'fields' => $entity['fields'],
'isSelfClass' => $entity['isSelfClass'],
'discriminatorColumn' => $entity['discriminatorColumn'],
'entityClass' => $entity['isSelfClass'] ? $subClass->name : $entity['entityClass'],
];
}

$subClass->addSqlResultSetMapping(
[
'name' => $mapping['name'],
'columns' => $mapping['columns'],
'entities' => $entities,
],
);
}
}
}

/**
* Completes the ID generator mapping. If "auto" is specified we choose the generator
* most appropriate for the targeted database platform.
Expand Down
111 changes: 0 additions & 111 deletions lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -372,26 +372,6 @@ class ClassMetadataInfo implements ClassMetadata, Stringable
*/
public array $embeddedClasses = [];

/**
* READ-ONLY: The mappings of the results of native SQL queries.
*
* A native result mapping definition has the following structure:
* <pre>
* array(
* 'name' => <result name>,
* 'entities' => array(<entity result mapping>),
* 'columns' => array(<column result mapping>)
* )
* </pre>
*
* @psalm-var array<string, array{
* name: string,
* entities: mixed[],
* columns: mixed[]
* }>
*/
public array $sqlResultSetMappings = [];

/**
* READ-ONLY: The field names of all fields that are part of the identifier/primary key
* of the mapped entity class.
Expand Down Expand Up @@ -917,10 +897,6 @@ public function __sleep()
$serialized[] = 'entityListeners';
}

if ($this->sqlResultSetMappings) {
$serialized[] = 'sqlResultSetMappings';
}

if ($this->isReadOnly) {
$serialized[] = 'isReadOnly';
}
Expand Down Expand Up @@ -1280,36 +1256,6 @@ public function getFieldName(string $columnName): string
return $this->fieldNames[$columnName] ?? $columnName;
}

/**
* Gets the result set mapping.
*
* @see ClassMetadataInfo::$sqlResultSetMappings
*
* @return mixed[]
* @psalm-return array{name: string, entities: array, columns: array}
*
* @throws MappingException
*/
public function getSqlResultSetMapping(string $name): array
{
if (! isset($this->sqlResultSetMappings[$name])) {
throw MappingException::resultMappingNotFound($this->name, $name);
}

return $this->sqlResultSetMappings[$name];
}

/**
* Gets all sql result set mappings of the class.
*
* @return mixed[]
* @psalm-return array<string, array{name: string, entities: array, columns: array}>
*/
public function getSqlResultSetMappings(): array
{
return $this->sqlResultSetMappings;
}

/**
* Checks whether given property has type
*/
Expand Down Expand Up @@ -2447,63 +2393,6 @@ public function addInheritedFieldMapping(array $fieldMapping): void
$this->fieldNames[$fieldMapping['columnName']] = $fieldMapping['fieldName'];
}

/**
* INTERNAL:
* Adds a sql result set mapping to this class.
*
* @psalm-param array<string, mixed> $resultMapping
*
* @throws MappingException
*/
public function addSqlResultSetMapping(array $resultMapping): void
{
if (! isset($resultMapping['name'])) {
throw MappingException::nameIsMandatoryForSqlResultSetMapping($this->name);
}

if (isset($this->sqlResultSetMappings[$resultMapping['name']])) {
throw MappingException::duplicateResultSetMapping($this->name, $resultMapping['name']);
}

if (isset($resultMapping['entities'])) {
foreach ($resultMapping['entities'] as $key => $entityResult) {
if (! isset($entityResult['entityClass'])) {
throw MappingException::missingResultSetMappingEntity($this->name, $resultMapping['name']);
}

$entityResult['isSelfClass'] = false;
if ($entityResult['entityClass'] === '__CLASS__') {
$entityResult['isSelfClass'] = true;
$entityResult['entityClass'] = $this->name;
}

$entityResult['entityClass'] = $this->fullyQualifiedClassName($entityResult['entityClass']);

$resultMapping['entities'][$key]['entityClass'] = ltrim($entityResult['entityClass'], '\\');
$resultMapping['entities'][$key]['isSelfClass'] = $entityResult['isSelfClass'];

if (isset($entityResult['fields'])) {
foreach ($entityResult['fields'] as $k => $field) {
if (! isset($field['name'])) {
throw MappingException::missingResultSetMappingFieldName($this->name, $resultMapping['name']);
}

if (! isset($field['column'])) {
$fieldName = $field['name'];
if (str_contains($fieldName, '.')) {
[, $fieldName] = explode('.', $fieldName);
}

$resultMapping['entities'][$key]['fields'][$k]['column'] = $fieldName;
}
}
}
}
}

$this->sqlResultSetMappings[$resultMapping['name']] = $resultMapping;
}

/**
* Adds a one-to-one mapping.
*
Expand Down
Loading