mirror of
https://github.com/doctrine/orm.git
synced 2026-04-25 23:48:05 +02:00
Compare commits
68 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cccb2e2fdf | |||
| 18138d895e | |||
| fa2b52c974 | |||
| 5bf814032f | |||
| 02a4e4099d | |||
| 12a70bbefb | |||
| 5a4ddb2870 | |||
| 68fa55f310 | |||
| 0b0c3e7e58 | |||
| 92434f91c7 | |||
| 6414ad4cbb | |||
| 7b24275346 | |||
| ed1a576305 | |||
| 8b6fe52f74 | |||
| 15ec77fa79 | |||
| 32cd2106d0 | |||
| cac2acae07 | |||
| 146b465ec1 | |||
| 5aba762a33 | |||
| 77b7107d05 | |||
| a663dda869 | |||
| db14f0fa89 | |||
| 9a74ae6280 | |||
| 32eb38ebd9 | |||
| 2dde65c4ba | |||
| 176fbedc69 | |||
| 1b15af44b6 | |||
| 8336420a26 | |||
| a6b7569d7a | |||
| 9e37c788ef | |||
| ca0a6bbf71 | |||
| a3da3d78d4 | |||
| e1c2d2e65d | |||
| 6f194eeabf | |||
| 16cbc16998 | |||
| 5e6608b48e | |||
| 94bc137526 | |||
| 276a0f55ee | |||
| dbaf99f3d9 | |||
| 97411f5567 | |||
| 641330baa6 | |||
| 35e680cd3f | |||
| 705d88eaba | |||
| 3271d8f6e2 | |||
| 3622381f8c | |||
| f2729b0610 | |||
| cd44547573 | |||
| 81d472f6f9 | |||
| d458968cee | |||
| 5eb01da0a0 | |||
| 5aaf361139 | |||
| 6a8dcbc392 | |||
| 12babcc1c2 | |||
| 416aa1d2d7 | |||
| 8e16bb4ddc | |||
| e1dee439bb | |||
| e313d012ae | |||
| dede619b9e | |||
| 142cfb39fc | |||
| 53d41a456a | |||
| 95b34ca940 | |||
| 3eaf76eebd | |||
| 5c12d36be3 | |||
| 1ee68eb318 | |||
| 705c7f0a4b | |||
| 8c5e49efc0 | |||
| 483e09cf1c | |||
| bbb68d0072 |
@@ -10,30 +10,6 @@ on:
|
||||
|
||||
jobs:
|
||||
coding-standards:
|
||||
name: "Coding Standards"
|
||||
runs-on: "ubuntu-20.04"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- "7.4"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2"
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
coverage: "none"
|
||||
php-version: "${{ matrix.php-version }}"
|
||||
tools: "cs2pr"
|
||||
|
||||
- name: "Install dependencies with Composer"
|
||||
uses: "ramsey/composer-install@v1"
|
||||
with:
|
||||
dependency-versions: "highest"
|
||||
|
||||
# https://github.com/doctrine/.github/issues/3
|
||||
- name: "Run PHP_CodeSniffer"
|
||||
run: "vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr"
|
||||
uses: "doctrine/.github/.github/workflows/coding-standards.yml@1.1.1"
|
||||
with:
|
||||
php-version: "7.4"
|
||||
|
||||
@@ -7,40 +7,10 @@ on:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: "Git tag, release & create merge-up PR"
|
||||
runs-on: "ubuntu-20.04"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v2"
|
||||
|
||||
- name: "Release"
|
||||
uses: "laminas/automatic-releases@v1"
|
||||
with:
|
||||
command-name: "laminas:automatic-releases:release"
|
||||
env:
|
||||
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
|
||||
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
"SHELL_VERBOSITY": "3"
|
||||
|
||||
- name: "Create Merge-Up Pull Request"
|
||||
uses: "laminas/automatic-releases@v1"
|
||||
with:
|
||||
command-name: "laminas:automatic-releases:create-merge-up-pull-request"
|
||||
env:
|
||||
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
|
||||
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
|
||||
- name: "Create new milestones"
|
||||
uses: "laminas/automatic-releases@v1"
|
||||
with:
|
||||
command-name: "laminas:automatic-releases:create-milestones"
|
||||
env:
|
||||
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
|
||||
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@1.1.1"
|
||||
secrets:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
ORGANIZATION_ADMIN_TOKEN: ${{ secrets.ORGANIZATION_ADMIN_TOKEN }}
|
||||
SIGNING_SECRET_KEY: ${{ secrets.SIGNING_SECRET_KEY }}
|
||||
|
||||
+10
-7
@@ -1,5 +1,12 @@
|
||||
# Upgrade to 2.10
|
||||
|
||||
## BC Break: `UnitOfWork` now relies on SPL object IDs, not hashes
|
||||
|
||||
When calling the following methods, you are now supposed to use the result of
|
||||
`spl_object_id()`, and not `spl_object_hash()`:
|
||||
- `UnitOfWork::clearEntityChangeSet()`
|
||||
- `UnitOfWork::setOriginalEntityProperty()`
|
||||
|
||||
## BC Break: Removed `TABLE` id generator strategy
|
||||
|
||||
The implementation was unfinished for 14 years.
|
||||
@@ -9,10 +16,6 @@ It is now deprecated to rely on:
|
||||
- `Doctrine\ORM\Mapping\ClassMetadata::$tableGeneratorDefinition`;
|
||||
- or `Doctrine\ORM\Mapping\ClassMetadata::isIdGeneratorTable()`.
|
||||
|
||||
## BC Break: Removed possibility to extend the doctrine mapping xml schema with anything
|
||||
|
||||
If you want to extend it now you have to provide your own validation schema.
|
||||
|
||||
## New method `Doctrine\ORM\EntityManagerInterface#wrapInTransaction($func)`
|
||||
|
||||
Works the same as `Doctrine\ORM\EntityManagerInterface#transactional()` but returns any value returned from `$func` closure rather than just _non-empty value returned from the closure or true_.
|
||||
@@ -108,10 +111,10 @@ now always cleared regardless of the cache adapter being used.
|
||||
Method `Doctrine\ORM\UnitOfWork#commit()` can throw an OptimisticLockException when a commit silently fails and returns false
|
||||
since `Doctrine\DBAL\Connection#commit()` signature changed from returning void to boolean
|
||||
|
||||
## Deprecated: `Doctrine\ORM\AbstractQuery#iterator()`
|
||||
## Deprecated: `Doctrine\ORM\AbstractQuery#iterate()`
|
||||
|
||||
The method `Doctrine\ORM\AbstractQuery#iterator()` is deprecated in favor of `Doctrine\ORM\AbstractQuery#toIterable()`.
|
||||
Note that `toIterable()` yields results of the query, unlike `iterator()` which yielded each result wrapped into an array.
|
||||
The method `Doctrine\ORM\AbstractQuery#iterate()` is deprecated in favor of `Doctrine\ORM\AbstractQuery#toIterable()`.
|
||||
Note that `toIterable()` yields results of the query, unlike `iterate()` which yielded each result wrapped into an array.
|
||||
|
||||
# Upgrade to 2.7
|
||||
|
||||
|
||||
+3
-3
@@ -39,12 +39,12 @@
|
||||
"doctrine/annotations": "^1.13",
|
||||
"doctrine/coding-standard": "^9.0",
|
||||
"phpbench/phpbench": "^0.16.10 || ^1.0",
|
||||
"phpstan/phpstan": "0.12.99",
|
||||
"phpstan/phpstan": "1.2.0",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.4",
|
||||
"squizlabs/php_codesniffer": "3.6.0",
|
||||
"squizlabs/php_codesniffer": "3.6.2",
|
||||
"symfony/cache": "^4.4 || ^5.2",
|
||||
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0",
|
||||
"vimeo/psalm": "4.10.0"
|
||||
"vimeo/psalm": "4.15.0"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/annotations": "<1.13 || >= 2.0"
|
||||
|
||||
@@ -4,7 +4,7 @@ Advanced field value conversion using custom mapping types
|
||||
.. sectionauthor:: Jan Sorgalla <jsorgalla@googlemail.com>
|
||||
|
||||
When creating entities, you sometimes have the need to transform field values
|
||||
before they are saved to the database. In Doctrine you can use Custom Mapping
|
||||
before they are saved to the database. In Doctrine you can use Custom Mapping
|
||||
Types to solve this (see: :ref:`reference-basic-mapping-custom-mapping-types`).
|
||||
|
||||
There are several ways to achieve this: converting the value inside the Type
|
||||
@@ -15,7 +15,7 @@ type `Point <https://dev.mysql.com/doc/refman/8.0/en/gis-class-point.html>`_.
|
||||
|
||||
The ``Point`` type is part of the `Spatial extension <https://dev.mysql.com/doc/refman/8.0/en/spatial-extensions.html>`_
|
||||
of MySQL and enables you to store a single location in a coordinate space by
|
||||
using x and y coordinates. You can use the Point type to store a
|
||||
using x and y coordinates. You can use the Point type to store a
|
||||
longitude/latitude pair to represent a geographic location.
|
||||
|
||||
The entity
|
||||
@@ -29,9 +29,9 @@ The entity class:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
namespace Geo\Entity;
|
||||
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
@@ -84,7 +84,7 @@ The entity class:
|
||||
}
|
||||
}
|
||||
|
||||
We use the custom type ``point`` in the ``@Column`` docblock annotation of the
|
||||
We use the custom type ``point`` in the ``@Column`` docblock annotation of the
|
||||
``$point`` field. We will create this custom mapping type in the next chapter.
|
||||
|
||||
The point class:
|
||||
@@ -92,7 +92,7 @@ The point class:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
namespace Geo\ValueObject;
|
||||
|
||||
class Point
|
||||
@@ -196,7 +196,7 @@ The format of the string representation format is called
|
||||
`Well-known text (WKT) <https://en.wikipedia.org/wiki/Well-known_text>`_.
|
||||
The advantage of this format is, that it is both human readable and parsable by MySQL.
|
||||
|
||||
Internally, MySQL stores geometry values in a binary format that is not
|
||||
Internally, MySQL stores geometry values in a binary format that is not
|
||||
identical to the WKT format. So, we need to let MySQL transform the WKT
|
||||
representation into its internal format.
|
||||
|
||||
@@ -210,13 +210,13 @@ which convert WKT strings to and from the internal format of MySQL.
|
||||
|
||||
.. note::
|
||||
|
||||
When using DQL queries, the ``convertToPHPValueSQL`` and
|
||||
When using DQL queries, the ``convertToPHPValueSQL`` and
|
||||
``convertToDatabaseValueSQL`` methods only apply to identification variables
|
||||
and path expressions in SELECT clauses. Expressions in WHERE clauses are
|
||||
and path expressions in SELECT clauses. Expressions in WHERE clauses are
|
||||
**not** wrapped!
|
||||
|
||||
If you want to use Point values in WHERE clauses, you have to implement a
|
||||
:doc:`user defined function <dql-user-defined-functions>` for
|
||||
:doc:`user defined function <dql-user-defined-functions>` for
|
||||
``PointFromText``.
|
||||
|
||||
Example usage
|
||||
@@ -252,5 +252,5 @@ Example usage
|
||||
$query = $em->createQuery("SELECT l FROM Geo\Entity\Location l WHERE l.address = '1600 Amphitheatre Parkway, Mountain View, CA'");
|
||||
$location = $query->getSingleResult();
|
||||
|
||||
/* @var Geo\ValueObject\Point */
|
||||
/** @var Geo\ValueObject\Point */
|
||||
$point = $location->getPoint();
|
||||
|
||||
@@ -33,8 +33,8 @@ the DQL parser:
|
||||
is only ever one of them. We implemented the default SqlWalker
|
||||
implementation for it.
|
||||
- A tree walker. There can be many tree walkers, they cannot
|
||||
generate the sql, however they can modify the AST before its
|
||||
rendered to sql.
|
||||
generate the SQL, however they can modify the AST before its
|
||||
rendered to SQL.
|
||||
|
||||
Now this is all awfully technical, so let me come to some use-cases
|
||||
fast to keep you motivated. Using walker implementation you can for
|
||||
@@ -50,7 +50,7 @@ example:
|
||||
- Modify the Output walker to pretty print the SQL for debugging
|
||||
purposes.
|
||||
|
||||
In this cookbook-entry I will show examples on the first two
|
||||
In this cookbook-entry I will show examples of the first two
|
||||
points. There are probably much more use-cases.
|
||||
|
||||
Generic count query for pagination
|
||||
@@ -64,7 +64,7 @@ like:
|
||||
|
||||
SELECT p, c, a FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ...
|
||||
|
||||
Now in this query the blog post is the root entity, meaning its the
|
||||
Now in this query the blog post is the root entity, meaning it's the
|
||||
one that is hydrated directly from the query and returned as an
|
||||
array of blog posts. In contrast the comment and author are loaded
|
||||
for deeper use in the object tree.
|
||||
@@ -79,7 +79,7 @@ query for pagination would look like:
|
||||
SELECT count(DISTINCT p.id) FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ...
|
||||
|
||||
Now you could go and write each of these queries by hand, or you
|
||||
can use a tree walker to modify the AST for you. Lets see how the
|
||||
can use a tree walker to modify the AST for you. Let's see how the
|
||||
API would look for this use-case:
|
||||
|
||||
.. code-block:: php
|
||||
@@ -88,7 +88,7 @@ API would look for this use-case:
|
||||
$pageNum = 1;
|
||||
$query = $em->createQuery($dql);
|
||||
$query->setFirstResult( ($pageNum-1) * 20)->setMaxResults(20);
|
||||
|
||||
|
||||
$totalResults = Paginate::count($query);
|
||||
$results = $query->getResult();
|
||||
|
||||
@@ -101,12 +101,12 @@ The ``Paginate::count(Query $query)`` looks like:
|
||||
{
|
||||
static public function count(Query $query)
|
||||
{
|
||||
/* @var $countQuery Query */
|
||||
/** @var Query $countQuery */
|
||||
$countQuery = clone $query;
|
||||
|
||||
|
||||
$countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('DoctrineExtensions\Paginate\CountSqlWalker'));
|
||||
$countQuery->setFirstResult(null)->setMaxResults(null);
|
||||
|
||||
|
||||
return $countQuery->getSingleScalarResult();
|
||||
}
|
||||
}
|
||||
@@ -137,13 +137,13 @@ implementation is:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$pathExpression = new PathExpression(
|
||||
PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $parentName,
|
||||
$parent['metadata']->getSingleIdentifierFieldName()
|
||||
);
|
||||
$pathExpression->type = PathExpression::TYPE_STATE_FIELD;
|
||||
|
||||
|
||||
$AST->selectClause->selectExpressions = array(
|
||||
new SelectExpression(
|
||||
new AggregateExpression('count', $pathExpression, true), null
|
||||
@@ -196,7 +196,7 @@ modify the generation of the SELECT clause, adding the
|
||||
public function walkSelectClause($selectClause)
|
||||
{
|
||||
$sql = parent::walkSelectClause($selectClause);
|
||||
|
||||
|
||||
if ($this->getQuery()->getHint('mysqlWalker.sqlNoCache') === true) {
|
||||
if ($selectClause->isDistinct) {
|
||||
$sql = str_replace('SELECT DISTINCT', 'SELECT DISTINCT SQL_NO_CACHE', $sql);
|
||||
@@ -204,7 +204,7 @@ modify the generation of the SELECT clause, adding the
|
||||
$sql = str_replace('SELECT', 'SELECT SQL_NO_CACHE', $sql);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ configuration:
|
||||
$config->addCustomStringFunction($name, $class);
|
||||
$config->addCustomNumericFunction($name, $class);
|
||||
$config->addCustomDatetimeFunction($name, $class);
|
||||
|
||||
|
||||
$em = EntityManager::create($dbParams, $config);
|
||||
|
||||
The ``$name`` is the name the function will be referred to in the
|
||||
@@ -96,7 +96,7 @@ discuss it step by step:
|
||||
// (1)
|
||||
public $firstDateExpression = null;
|
||||
public $secondDateExpression = null;
|
||||
|
||||
|
||||
public function parse(\Doctrine\ORM\Query\Parser $parser)
|
||||
{
|
||||
$parser->match(Lexer::T_IDENTIFIER); // (2)
|
||||
@@ -106,7 +106,7 @@ discuss it step by step:
|
||||
$this->secondDateExpression = $parser->ArithmeticPrimary(); // (6)
|
||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS); // (3)
|
||||
}
|
||||
|
||||
|
||||
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
|
||||
{
|
||||
return 'DATEDIFF(' .
|
||||
@@ -180,28 +180,28 @@ I'll skip the blah and show the code for this function:
|
||||
public $firstDateExpression = null;
|
||||
public $intervalExpression = null;
|
||||
public $unit = null;
|
||||
|
||||
|
||||
public function parse(\Doctrine\ORM\Query\Parser $parser)
|
||||
{
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||
|
||||
|
||||
$this->firstDateExpression = $parser->ArithmeticPrimary();
|
||||
|
||||
|
||||
$parser->match(Lexer::T_COMMA);
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
|
||||
|
||||
$this->intervalExpression = $parser->ArithmeticPrimary();
|
||||
|
||||
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
|
||||
/* @var $lexer Lexer */
|
||||
|
||||
/** @var Lexer $lexer */
|
||||
$lexer = $parser->getLexer();
|
||||
$this->unit = $lexer->token['value'];
|
||||
|
||||
|
||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||
}
|
||||
|
||||
|
||||
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
|
||||
{
|
||||
return 'DATE_ADD(' .
|
||||
|
||||
@@ -16,7 +16,6 @@ Doctrine ORM don't panic. You can get help from different sources:
|
||||
- The `Doctrine Mailing List <https://groups.google.com/group/doctrine-user>`_
|
||||
- Slack chat room `#orm <https://www.doctrine-project.org/slack>`_
|
||||
- Report a bug on `GitHub <https://github.com/doctrine/orm/issues>`_.
|
||||
- On `Twitter <https://twitter.com/search/%23doctrine2>`_ with ``#doctrine2``
|
||||
- On `StackOverflow <https://stackoverflow.com/questions/tagged/doctrine-orm>`_
|
||||
|
||||
If you need more structure over the different topics you can browse the :doc:`table
|
||||
|
||||
@@ -184,6 +184,8 @@ in well defined units of work. Work with your objects and modify
|
||||
them as usual and when you're done call ``EntityManager#flush()``
|
||||
to make your changes persistent.
|
||||
|
||||
.. _unit-of-work:
|
||||
|
||||
The Unit of Work
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -59,12 +59,12 @@ inside the instance variables PHP DocBlock comment. Any value hold
|
||||
inside this variable will be saved to and loaded from the database
|
||||
as part of the lifecycle of the instance variables entity-class.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **type**: Name of the DBAL Type which does the conversion between PHP
|
||||
and Database representation.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **name**: By default the property name is used for the database
|
||||
column name also, however the ``name`` attribute allows you to
|
||||
@@ -165,7 +165,7 @@ Examples:
|
||||
~~~~~~~~
|
||||
Add caching strategy to a root entity or a collection.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **usage**: One of ``READ_ONLY``, ``READ_WRITE`` or ``NONSTRICT_READ_WRITE``, By default this is ``READ_ONLY``.
|
||||
- **region**: An specific region name
|
||||
@@ -210,7 +210,7 @@ Example:
|
||||
|
||||
This attribute allows you to specify a user-provided class to generate identifiers. This attribute only works when both :ref:`#[Id] <attrref_id>` and :ref:`#[GeneratedValue(strategy: "CUSTOM")] <attrref_generatedvalue>` are specified.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **class**: name of the class which should extend Doctrine\ORM\Id\AbstractIdGenerator
|
||||
|
||||
@@ -244,13 +244,13 @@ actually instantiated as.
|
||||
If this attribute is not specified, the discriminator column defaults
|
||||
to a string column of length 255 called ``dtype``.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
|
||||
- **name**: The column name of the discriminator. This name is also
|
||||
used during Array hydration as key to specify the class-name.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
|
||||
- **type**: By default this is string.
|
||||
@@ -319,7 +319,7 @@ attribute to establish the relationship between the two classes.
|
||||
The embedded attribute is required on an entity's member variable,
|
||||
in order to specify that it is an embedded class.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **class**: The embeddable class
|
||||
|
||||
@@ -331,7 +331,7 @@ Required attributes:
|
||||
Required attribute to mark a PHP class as an entity. Doctrine manages
|
||||
the persistence of all classes marked as entities.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **repositoryClass**: Specifies the FQCN of a subclass of the
|
||||
``EntityRepository``. Use of repositories for entities is encouraged to keep
|
||||
@@ -368,7 +368,7 @@ conjunction with #[Id].
|
||||
If this attribute is not specified with ``#[Id]`` the ``NONE`` strategy is
|
||||
used as default.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **strategy**: Set the name of the identifier generation strategy.
|
||||
Valid values are ``AUTO``, ``SEQUENCE``, ``IDENTITY``, ``UUID``
|
||||
@@ -424,14 +424,14 @@ Attribute is used on the entity-class level. It provides a hint to the SchemaToo
|
||||
generate a database index on the specified table columns. It only
|
||||
has meaning in the ``SchemaTool`` schema generation context.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **name**: Name of the Index
|
||||
- **fields**: Array of fields. Exactly one of **fields, columns** is required.
|
||||
- **columns**: Array of columns. Exactly one of **fields, columns** is required.
|
||||
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **options**: Array of platform specific options:
|
||||
|
||||
@@ -548,7 +548,7 @@ The ``#[InverseJoinColumn]`` is the same as ``#[JoinColumn]`` and is used in the
|
||||
of a ``#[ManyToMany]`` attribute declaration to specifiy the details of the join table's
|
||||
column information used for the join to the inverse entity.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **name**: Column name that holds the foreign key identifier for
|
||||
this relation. In the context of ``#[JoinTable]`` it specifies the column
|
||||
@@ -623,14 +623,14 @@ Example:
|
||||
Defines that the annotated instance variable holds a reference that
|
||||
describes a many-to-one relationship between two entities.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
|
||||
- **targetEntity**: FQCN of the referenced target entity. Can be the
|
||||
unqualified class name if both classes are in the same namespace.
|
||||
*IMPORTANT:* No leading backslash!
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
|
||||
- **cascade**: Cascade Option
|
||||
@@ -659,14 +659,14 @@ additional, optional attribute that has reasonable default
|
||||
configuration values using the table and names of the two related
|
||||
entities.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
|
||||
- **targetEntity**: FQCN of the referenced target entity. Can be the
|
||||
unqualified class name if both classes are in the same namespace.
|
||||
*IMPORTANT:* No leading backslash!
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
|
||||
- **mappedBy**: This option specifies the property name on the
|
||||
@@ -720,7 +720,7 @@ The ``#[MappedSuperclass]`` attribute cannot be used in conjunction with
|
||||
``#[Entity]``. See the Inheritance Mapping section for
|
||||
:doc:`more details on the restrictions of mapped superclasses <inheritance-mapping>`.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **repositoryClass**: Specifies the FQCN of a subclass of the EntityRepository.
|
||||
That will be inherited for all subclasses of that Mapped Superclass.
|
||||
@@ -756,13 +756,13 @@ be specified. When no
|
||||
:ref:`#[JoinColumn] <attrref_joincolumn>` is specified it defaults to using the target entity table and
|
||||
primary key column names and the current naming strategy to determine a name for the join column.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **targetEntity**: FQCN of the referenced target entity. Can be the
|
||||
unqualified class name if both classes are in the same namespace.
|
||||
*IMPORTANT:* No leading backslash!
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **cascade**: Cascade Option
|
||||
- **fetch**: One of LAZY or EAGER
|
||||
@@ -786,13 +786,13 @@ Example:
|
||||
#[OneToMany]
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **targetEntity**: FQCN of the referenced target entity. Can be the
|
||||
unqualified class name if both classes are in the same namespace.
|
||||
*IMPORTANT:* No leading backslash!
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **cascade**: Cascade Option
|
||||
- **orphanRemoval**: Boolean that specifies if orphans, inverse
|
||||
@@ -916,11 +916,11 @@ For use with ``#[GeneratedValue(strategy: "SEQUENCE")]`` this
|
||||
attribute allows to specify details about the sequence, such as
|
||||
the increment size and initial values of the sequence.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **sequenceName**: Name of the sequence
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **allocationSize**: Increment the sequence by the allocation size
|
||||
when its fetched. A value larger than 1 allows optimization for
|
||||
@@ -954,11 +954,11 @@ placed on the entity-class level and is optional. If it is
|
||||
not specified the table name will default to the entity's
|
||||
unqualified classname.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **name**: Name of the table
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **schema**: Name of the schema the table lies in.
|
||||
|
||||
@@ -985,12 +985,12 @@ generate a database unique constraint on the specified table
|
||||
columns. It only has meaning in the SchemaTool schema generation
|
||||
context.
|
||||
|
||||
Required attributes:
|
||||
Required parameters:
|
||||
|
||||
- **name**: Name of the Index
|
||||
- **columns**: Array of columns.
|
||||
|
||||
Optional attributes:
|
||||
Optional parameters:
|
||||
|
||||
- **options**: Array of platform specific options:
|
||||
|
||||
|
||||
@@ -85,9 +85,9 @@ Or if you prefer YAML:
|
||||
|
||||
Inside the ``Setup`` methods several assumptions are made:
|
||||
|
||||
- If `$isDevMode` is true caching is done in memory with the ``ArrayCache``. Proxy objects are recreated on every request.
|
||||
- If `$isDevMode` is false, check for Caches in the order APC, Xcache, Memcache (127.0.0.1:11211), Redis (127.0.0.1:6379) unless `$cache` is passed as fourth argument.
|
||||
- If `$isDevMode` is false, set then proxy classes have to be explicitly created through the command line.
|
||||
- If ``$isDevMode`` is true caching is done in memory with the ``ArrayCache``. Proxy objects are recreated on every request.
|
||||
- If ``$isDevMode`` is false, check for Caches in the order APC, Xcache, Memcache (127.0.0.1:11211), Redis (127.0.0.1:6379) unless `$cache` is passed as fourth argument.
|
||||
- If ``$isDevMode`` is false, set then proxy classes have to be explicitly created through the command line.
|
||||
- If third argument `$proxyDir` is not set, use the systems temporary directory.
|
||||
|
||||
If you want to configure Doctrine in more detail, take a look at the :doc:`Advanced Configuration <reference/advanced-configuration>` section.
|
||||
|
||||
+187
-129
@@ -121,6 +121,53 @@ Now you can test the ``$eventSubscriber`` instance to see if the
|
||||
echo 'pre foo invoked!';
|
||||
}
|
||||
|
||||
Registering Events
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are two ways to register an event:
|
||||
|
||||
* *All events* can be registered by calling ``$eventManager->addEventListener()``
|
||||
or ``eventManager->addEventSubscriber()``, see
|
||||
:ref:`Listening and subscribing to Lifecycle Events<listening-and-subscribing-to-lifecycle-events>`
|
||||
* *Lifecycle Callbacks* can also be registered in the entity mapping (annotation, attribute, etc.),
|
||||
see :ref:`Lifecycle Callbacks<lifecycle-callbacks>`
|
||||
|
||||
Events Overview
|
||||
---------------
|
||||
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| Event | Dispatched by | Lifecycle | Passed |
|
||||
| | | Callback | Argument |
|
||||
+=================================================================+=======================+===========+=====================================+
|
||||
| :ref:`preRemove<reference-events-pre-remove>` | ``$em->remove()`` | Yes | `_LifecycleEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`postRemove<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes | `_LifecycleEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`prePersist<reference-events-pre-persist>` | ``$em->persist()`` | Yes | `_LifecycleEventArgs`_ |
|
||||
| | on *initial* persist | | |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`postPersist<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes | `_LifecycleEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`preUpdate<reference-events-pre-update>` | ``$em->flush()`` | Yes | `_PreUpdateEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`postUpdate<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes | `_LifecycleEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`postLoad<reference-events-post-load>` | Loading from database | Yes | `_LifecycleEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`loadClassMetadata<reference-events-load-class-metadata>` | Loading of mapping | No | `_LoadClassMetadataEventArgs` |
|
||||
| | metadata | | |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| ``onClassMetadataNotFound`` | ``MappingException`` | No | `_OnClassMetadataNotFoundEventArgs` |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`preFlush<reference-events-pre-flush>` | ``$em->flush()`` | Yes | `_PreFlushEventArgs`_ |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`onFlush<reference-events-on-flush>` | ``$em->flush()`` | No | `_OnFlushEventArgs` |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| :ref:`postFlush<reference-events-post-flush>` | ``$em->flush()`` | No | `_PostFlushEventArgs` |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
| ``onClear`` | ``$em->clear()`` | No | `_OnClearEventArgs` |
|
||||
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
|
||||
|
||||
Naming convention
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -208,15 +255,6 @@ events during the life-time of their registered entities.
|
||||
cascade remove relations. In this case, you should load yourself the proxy in
|
||||
the associated pre event.
|
||||
|
||||
You can access the Event constants from the ``Events`` class in the
|
||||
ORM package.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\ORM\Events;
|
||||
echo Events::preUpdate;
|
||||
|
||||
These can be hooked into by two different types of event
|
||||
listeners:
|
||||
|
||||
@@ -237,6 +275,7 @@ The ``EventArgs`` instance received by the listener gives access to the entity,
|
||||
:ref:`reference-events-implementing-listeners` section very carefully
|
||||
to understand which operations are allowed in which lifecycle event.
|
||||
|
||||
.. _lifecycle-callbacks:
|
||||
|
||||
Lifecycle Callbacks
|
||||
-------------------
|
||||
@@ -250,135 +289,109 @@ specific to a particular entity class's lifecycle.
|
||||
|
||||
.. note::
|
||||
|
||||
Note that Licecycle Callbacks are not supported for Embeddables.
|
||||
Lifecycle Callbacks are not supported for :doc:`Embeddables </tutorials/embeddables>`.
|
||||
|
||||
.. code-block:: php
|
||||
.. configuration-block::
|
||||
|
||||
<?php
|
||||
.. code-block:: attribute
|
||||
|
||||
/** @Entity @HasLifecycleCallbacks */
|
||||
class User
|
||||
{
|
||||
// ...
|
||||
<?php
|
||||
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\Persistence\Event\LifecycleEventArgs;
|
||||
|
||||
/**
|
||||
* @Column(type="string", length=255)
|
||||
* #[Entity]
|
||||
* #[HasLifecycleCallbacks]
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/** @Column(name="created_at", type="string", length=255) */
|
||||
private $createdAt;
|
||||
|
||||
/** @PrePersist */
|
||||
public function doStuffOnPrePersist()
|
||||
{
|
||||
$this->createdAt = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
/** @PrePersist */
|
||||
public function doOtherStuffOnPrePersist()
|
||||
{
|
||||
$this->value = 'changed from prePersist callback!';
|
||||
}
|
||||
|
||||
/** @PostPersist */
|
||||
public function doStuffOnPostPersist()
|
||||
{
|
||||
$this->value = 'changed from postPersist callback!';
|
||||
}
|
||||
|
||||
/** @PostLoad */
|
||||
public function doStuffOnPostLoad()
|
||||
{
|
||||
$this->value = 'changed from postLoad callback!';
|
||||
}
|
||||
|
||||
/** @PreUpdate */
|
||||
public function doStuffOnPreUpdate()
|
||||
{
|
||||
$this->value = 'changed from preUpdate callback!';
|
||||
}
|
||||
}
|
||||
|
||||
Note that the methods set as lifecycle callbacks need to be public and,
|
||||
when using these annotations, you have to apply the
|
||||
``@HasLifecycleCallbacks`` marker annotation on the entity class.
|
||||
|
||||
If you want to register lifecycle callbacks from YAML or XML you
|
||||
can do it with the following.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
User:
|
||||
type: entity
|
||||
fields:
|
||||
# ...
|
||||
name:
|
||||
type: string(50)
|
||||
lifecycleCallbacks:
|
||||
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersist ]
|
||||
postPersist: [ doStuffOnPostPersist ]
|
||||
|
||||
In YAML the ``key`` of the lifecycleCallbacks entry is the event that you
|
||||
are triggering on and the value is the method (or methods) to call. The allowed
|
||||
event types are the ones listed in the previous Lifecycle Events section.
|
||||
|
||||
XML would look something like this:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
|
||||
|
||||
<entity name="User">
|
||||
|
||||
<lifecycle-callbacks>
|
||||
<lifecycle-callback type="prePersist" method="doStuffOnPrePersist"/>
|
||||
<lifecycle-callback type="postPersist" method="doStuffOnPostPersist"/>
|
||||
</lifecycle-callbacks>
|
||||
|
||||
</entity>
|
||||
|
||||
</doctrine-mapping>
|
||||
|
||||
In XML the ``type`` of the lifecycle-callback entry is the event that you
|
||||
are triggering on and the ``method`` is the method to call. The allowed event
|
||||
types are the ones listed in the previous Lifecycle Events section.
|
||||
|
||||
When using YAML or XML you need to remember to create public methods to match the
|
||||
callback names you defined. E.g. in these examples ``doStuffOnPrePersist()``,
|
||||
``doOtherStuffOnPrePersist()`` and ``doStuffOnPostPersist()`` methods need to be
|
||||
defined on your ``User`` model.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// ...
|
||||
|
||||
class User
|
||||
{
|
||||
// ...
|
||||
|
||||
public function doStuffOnPrePersist()
|
||||
class User
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
public function doOtherStuffOnPrePersist()
|
||||
#[Column(type: Types::STRING, length: 255)]
|
||||
public $value;
|
||||
|
||||
#[PrePersist]
|
||||
public function doStuffOnPrePersist(LifecycleEventArgs $eventArgs)
|
||||
{
|
||||
$this->createdAt = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
#[PrePersist]
|
||||
public function doOtherStuffOnPrePersist()
|
||||
{
|
||||
$this->value = 'changed from prePersist callback!';
|
||||
}
|
||||
|
||||
#[PreUpdate]
|
||||
public function doStuffOnPreUpdate(PreUpdateEventArgs $eventArgs)
|
||||
{
|
||||
$this->value = 'changed from preUpdate callback!';
|
||||
}
|
||||
}
|
||||
.. code-block:: annotation
|
||||
|
||||
<?php
|
||||
|
||||
use Doctrine\Persistence\Event\LifecycleEventArgs;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @HasLifecycleCallbacks
|
||||
*/
|
||||
class User
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
public function doStuffOnPostPersist()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
/** @Column(type="string", length=255) */
|
||||
public $value;
|
||||
|
||||
/** @PrePersist */
|
||||
public function doStuffOnPrePersist(LifecycleEventArgs $eventArgs)
|
||||
{
|
||||
$this->createdAt = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
/** @PrePersist */
|
||||
public function doOtherStuffOnPrePersist()
|
||||
{
|
||||
$this->value = 'changed from prePersist callback!';
|
||||
}
|
||||
|
||||
/** @PreUpdate */
|
||||
public function doStuffOnPreUpdate(PreUpdateEventArgs $eventArgs)
|
||||
{
|
||||
$this->value = 'changed from preUpdate callback!';
|
||||
}
|
||||
}
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
|
||||
<entity name="User">
|
||||
<!-- ... -->
|
||||
<lifecycle-callbacks>
|
||||
<lifecycle-callback type="prePersist" method="doStuffOnPrePersist"/>
|
||||
<lifecycle-callback type="prePersist" method="doOtherStuffOnPrePersist"/>
|
||||
<lifecycle-callback type="preUpdate" method="doStuffOnPreUpdate"/>
|
||||
</lifecycle-callbacks>
|
||||
</entity>
|
||||
</doctrine-mapping>
|
||||
.. code-block:: yaml
|
||||
|
||||
User:
|
||||
type: entity
|
||||
fields:
|
||||
# ...
|
||||
value:
|
||||
type: string(255)
|
||||
lifecycleCallbacks:
|
||||
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersist ]
|
||||
preUpdate: [ doStuffOnPreUpdate ]
|
||||
|
||||
Lifecycle Callbacks Event Argument
|
||||
----------------------------------
|
||||
@@ -403,6 +416,8 @@ With the additional argument you have access to the
|
||||
}
|
||||
}
|
||||
|
||||
.. _listening-and-subscribing-to-lifecycle-events:
|
||||
|
||||
Listening and subscribing to Lifecycle Events
|
||||
---------------------------------------------
|
||||
|
||||
@@ -413,7 +428,7 @@ behaviors across different entity classes.
|
||||
|
||||
Note that they require much more detailed knowledge about the inner
|
||||
workings of the ``EntityManager`` and ``UnitOfWork`` classes. Please
|
||||
read the :ref:`reference-events-implementing-listeners` section
|
||||
read the :ref:`Implementing Event Listeners<reference-events-implementing-listeners>` section
|
||||
carefully if you are trying to write your own listener.
|
||||
|
||||
For event subscribers, there are no surprises. They declare the
|
||||
@@ -482,8 +497,10 @@ EventManager that is passed to the EntityManager factory:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\ORM\Events;
|
||||
|
||||
$eventManager = new EventManager();
|
||||
$eventManager->addEventListener(array(Events::preUpdate), new MyEventListener());
|
||||
$eventManager->addEventListener([Events::preUpdate], new MyEventListener());
|
||||
$eventManager->addEventSubscriber(new MyEventSubscriber());
|
||||
|
||||
$entityManager = EntityManager::create($dbOpts, $config, $eventManager);
|
||||
@@ -494,7 +511,9 @@ EntityManager was created:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$entityManager->getEventManager()->addEventListener(array(Events::preUpdate), new MyEventListener());
|
||||
use Doctrine\ORM\Events;
|
||||
|
||||
$entityManager->getEventManager()->addEventListener([Events::preUpdate], new MyEventListener());
|
||||
$entityManager->getEventManager()->addEventSubscriber(new MyEventSubscriber());
|
||||
|
||||
.. _reference-events-implementing-listeners:
|
||||
@@ -514,6 +533,8 @@ the restrictions apply as well, with the additional restriction
|
||||
that (prior to version 2.4) you do not have access to the
|
||||
``EntityManager`` or ``UnitOfWork`` APIs inside these events.
|
||||
|
||||
.. _reference-events-pre-persist:
|
||||
|
||||
prePersist
|
||||
~~~~~~~~~~
|
||||
|
||||
@@ -539,6 +560,8 @@ The following restrictions apply to ``prePersist``:
|
||||
- Doctrine will not recognize changes made to relations in a prePersist
|
||||
event. This includes modifications to
|
||||
collections such as additions, removals or replacement.
|
||||
|
||||
.. _reference-events-pre-remove:
|
||||
|
||||
preRemove
|
||||
~~~~~~~~~
|
||||
@@ -551,6 +574,8 @@ There are no restrictions to what methods can be called inside the
|
||||
``preRemove`` event, except when the remove method itself was
|
||||
called during a flush operation.
|
||||
|
||||
.. _reference-events-pre-flush:
|
||||
|
||||
preFlush
|
||||
~~~~~~~~
|
||||
|
||||
@@ -573,6 +598,8 @@ result in infinite loop.
|
||||
}
|
||||
}
|
||||
|
||||
.. _reference-events-on-flush:
|
||||
|
||||
onFlush
|
||||
~~~~~~~
|
||||
|
||||
@@ -636,6 +663,8 @@ The following restrictions apply to the onFlush event:
|
||||
affected entity. This can be done by calling
|
||||
``$unitOfWork->recomputeSingleEntityChangeSet($classMetadata, $entity)``.
|
||||
|
||||
.. _reference-events-post-flush:
|
||||
|
||||
postFlush
|
||||
~~~~~~~~~
|
||||
|
||||
@@ -656,6 +685,8 @@ postFlush
|
||||
}
|
||||
}
|
||||
|
||||
.. _reference-events-pre-update:
|
||||
|
||||
preUpdate
|
||||
~~~~~~~~~
|
||||
|
||||
@@ -740,6 +771,8 @@ Restrictions for this event:
|
||||
API are strongly discouraged and don't work as expected outside the
|
||||
flush operation.
|
||||
|
||||
.. _reference-events-post-update-remove-persist:
|
||||
|
||||
postUpdate, postRemove, postPersist
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -749,6 +782,8 @@ database, but you can use these events to alter non-persistable items,
|
||||
like non-mapped fields, logging or even associated classes that are
|
||||
not directly mapped by Doctrine.
|
||||
|
||||
.. _reference-events-post-load:
|
||||
|
||||
postLoad
|
||||
~~~~~~~~
|
||||
|
||||
@@ -765,7 +800,19 @@ An entity listener is a lifecycle listener class used for an entity.
|
||||
|
||||
.. configuration-block::
|
||||
|
||||
.. code-block:: php
|
||||
.. code-block:: attribute
|
||||
|
||||
<?php
|
||||
namespace MyProject\Entity;
|
||||
use App\EventListener\UserListener;
|
||||
|
||||
#[Entity]
|
||||
#[EntityListeners([UserListener::class])]
|
||||
class User
|
||||
{
|
||||
// ....
|
||||
}
|
||||
.. code-block:: annotation
|
||||
|
||||
<?php
|
||||
namespace MyProject\Entity;
|
||||
@@ -961,6 +1008,8 @@ Implementing your own resolver :
|
||||
$configurations->setEntityListenerResolver(new MyEntityListenerResolver);
|
||||
EntityManager::create(.., $configurations, ..);
|
||||
|
||||
.. _reference-events-load-class-metadata:
|
||||
|
||||
Load ClassMetadata Event
|
||||
------------------------
|
||||
|
||||
@@ -1041,3 +1090,12 @@ and the EntityManager.
|
||||
$em = $eventArgs->getEntityManager();
|
||||
}
|
||||
}
|
||||
|
||||
.. _LifecycleEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/LifecycleEventArgs.php
|
||||
.. _PreUpdateEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php
|
||||
.. _PreFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PreFlushEventArgs.php
|
||||
.. _PostFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PostFlushEventArgs.php
|
||||
.. _OnFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/OnFlushEventArgs.php
|
||||
.. _OnClearEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/OnClearEventArgs.php
|
||||
.. _LoadClassMetadataEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php
|
||||
.. _OnClassMetadataNotFoundEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/OnClassMetadataNotFoundEventArgs.php
|
||||
|
||||
@@ -31,31 +31,31 @@ Each cache region resides in a specific cache namespace and has its own lifetime
|
||||
Notice that when caching collection and queries only identifiers are stored.
|
||||
The entity values will be stored in its own region
|
||||
|
||||
Something like below for an entity region :
|
||||
Something like below for an entity region:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
[
|
||||
'region_name:entity_1_hash' => ['id'=> 1, 'name' => 'FooBar', 'associationName'=>null],
|
||||
'region_name:entity_2_hash' => ['id'=> 2, 'name' => 'Foo', 'associationName'=>['id'=>11]],
|
||||
'region_name:entity_3_hash' => ['id'=> 3, 'name' => 'Bar', 'associationName'=>['id'=>22]]
|
||||
'region_name:entity_1_hash' => ['id' => 1, 'name' => 'FooBar', 'associationName' => null],
|
||||
'region_name:entity_2_hash' => ['id' => 2, 'name' => 'Foo', 'associationName' => ['id' => 11]],
|
||||
'region_name:entity_3_hash' => ['id' => 3, 'name' => 'Bar', 'associationName' => ['id' => 22]]
|
||||
];
|
||||
|
||||
|
||||
If the entity holds a collection that also needs to be cached.
|
||||
An collection region could look something like :
|
||||
An collection region could look something like:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
[
|
||||
'region_name:entity_1_coll_assoc_name_hash' => ['ownerId'=> 1, 'list' => [1, 2, 3]],
|
||||
'region_name:entity_2_coll_assoc_name_hash' => ['ownerId'=> 2, 'list' => [2, 3]],
|
||||
'region_name:entity_3_coll_assoc_name_hash' => ['ownerId'=> 3, 'list' => [2, 4]]
|
||||
'region_name:entity_1_coll_assoc_name_hash' => ['ownerId' => 1, 'list' => [1, 2, 3]],
|
||||
'region_name:entity_2_coll_assoc_name_hash' => ['ownerId' => 2, 'list' => [2, 3]],
|
||||
'region_name:entity_3_coll_assoc_name_hash' => ['ownerId' => 3, 'list' => [2, 4]]
|
||||
];
|
||||
|
||||
A query region might be something like :
|
||||
A query region might be something like:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
@@ -93,8 +93,6 @@ Cache region
|
||||
``Doctrine\ORM\Cache\Region`` defines a contract for accessing a particular
|
||||
cache region.
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/Region.html>`_.
|
||||
|
||||
Concurrent cache region
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -105,8 +103,6 @@ If you want to use an ``READ_WRITE`` cache, you should consider providing your o
|
||||
|
||||
``Doctrine\ORM\Cache\ConcurrentRegion`` defines a contract for concurrently managed data region.
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/ConcurrentRegion.html>`_.
|
||||
|
||||
Timestamp region
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -114,8 +110,6 @@ Timestamp region
|
||||
|
||||
Tracks the timestamps of the most recent updates to particular entity.
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/TimestampRegion.html>`_.
|
||||
|
||||
.. _reference-second-level-cache-mode:
|
||||
|
||||
Caching mode
|
||||
@@ -132,7 +126,7 @@ Caching mode
|
||||
|
||||
* Read Write Cache doesn’t employ any locks but can do reads, inserts, updates and deletes.
|
||||
* Good if the application needs to update data rarely.
|
||||
|
||||
|
||||
|
||||
* ``READ_WRITE``
|
||||
|
||||
@@ -147,21 +141,21 @@ Built-in cached persisters
|
||||
|
||||
Cached persisters are responsible to access cache regions.
|
||||
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| Cache Usage | Persister |
|
||||
+=======================+===========================================================================================+
|
||||
| READ_ONLY | Doctrine\\ORM\\Cache\\Persister\\Entity\\ReadOnlyCachedEntityPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Entity\\ReadWriteCachedEntityPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| NONSTRICT_READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Entity\\NonStrictReadWriteCachedEntityPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| READ_ONLY | Doctrine\\ORM\\Cache\\Persister\\Collection\\ReadOnlyCachedCollectionPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Collection\\ReadWriteCachedCollectionPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
| NONSTRICT_READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Collection\\NonStrictReadWriteCachedCollectionPersister |
|
||||
+-----------------------+-------------------------------------------------------------------------------------------+
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| Cache Usage | Persister |
|
||||
+=======================+==========================================================================================+
|
||||
| READ_ONLY | ``Doctrine\ORM\Cache\Persister\Entity\ReadOnlyCachedEntityPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| READ_WRITE | ``Doctrine\ORM\Cache\Persister\Entity\ReadWriteCachedEntityPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| NONSTRICT_READ_WRITE | ``Doctrine\ORM\Cache\Persister\Entity\NonStrictReadWriteCachedEntityPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| READ_ONLY | ``Doctrine\ORM\Cache\Persister\Collection\ReadOnlyCachedCollectionPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| READ_WRITE | ``Doctrine\ORM\Cache\Persister\Collection\ReadWriteCachedCollectionPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
| NONSTRICT_READ_WRITE | ``Doctrine\ORM\Cache\Persister\Collection\NonStrictReadWriteCachedCollectionPersister`` |
|
||||
+-----------------------+------------------------------------------------------------------------------------------+
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
@@ -172,7 +166,7 @@ Enable Second Level Cache
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To enable the second-level-cache, you should provide a cache factory.
|
||||
``\Doctrine\ORM\Cache\DefaultCacheFactory`` is the default implementation.
|
||||
``Doctrine\ORM\Cache\DefaultCacheFactory`` is the default implementation.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
@@ -196,7 +190,7 @@ Cache Factory
|
||||
|
||||
Cache Factory is the main point of extension.
|
||||
|
||||
It allows you to provide a specific implementation of the following components :
|
||||
It allows you to provide a specific implementation of the following components:
|
||||
|
||||
``QueryCache``
|
||||
stores and retrieves query cache results.
|
||||
@@ -209,8 +203,6 @@ It allows you to provide a specific implementation of the following components :
|
||||
``CollectionHydrator``
|
||||
transforms collections into cache entries and cache entries into collections
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/DefaultCacheFactory.html>`_.
|
||||
|
||||
Region Lifetime
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -234,12 +226,12 @@ Cache Log
|
||||
~~~~~~~~~
|
||||
By providing a cache logger you should be able to get information about all cache operations such as hits, misses and puts.
|
||||
|
||||
``\Doctrine\ORM\Cache\Logging\StatisticsCacheLogger`` is a built-in implementation that provides basic statistics.
|
||||
``Doctrine\ORM\Cache\Logging\StatisticsCacheLogger`` is a built-in implementation that provides basic statistics.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/* @var $config \Doctrine\ORM\Configuration */
|
||||
/** @var \Doctrine\ORM\Configuration $config */
|
||||
$logger = new \Doctrine\ORM\Cache\Logging\StatisticsCacheLogger();
|
||||
|
||||
// Cache logger
|
||||
@@ -269,12 +261,9 @@ By providing a cache logger you should be able to get information about all cach
|
||||
$logger->getMissCount();
|
||||
|
||||
If you want to get more information you should implement
|
||||
``\Doctrine\ORM\Cache\Logging\CacheLogger`` and collect
|
||||
``Doctrine\ORM\Cache\Logging\CacheLogger`` and collect
|
||||
all the information you want.
|
||||
|
||||
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/Logging/CacheLogger.html>`_.
|
||||
|
||||
|
||||
Entity cache definition
|
||||
-----------------------
|
||||
* Entity cache configuration allows you to define the caching strategy and region for an entity.
|
||||
@@ -330,8 +319,8 @@ level cache region.
|
||||
Country:
|
||||
type: entity
|
||||
cache:
|
||||
usage : READ_ONLY
|
||||
region : my_entity_region
|
||||
usage: READ_ONLY
|
||||
region: my_entity_region
|
||||
id:
|
||||
id:
|
||||
type: integer
|
||||
@@ -401,7 +390,7 @@ It caches the primary keys of association and cache each element will be cached
|
||||
</id>
|
||||
|
||||
<field name="name" type="string" column="name"/>
|
||||
|
||||
|
||||
<many-to-one field="country" target-entity="Country">
|
||||
<cache usage="NONSTRICT_READ_WRITE" />
|
||||
|
||||
@@ -421,7 +410,7 @@ It caches the primary keys of association and cache each element will be cached
|
||||
State:
|
||||
type: entity
|
||||
cache:
|
||||
usage : NONSTRICT_READ_WRITE
|
||||
usage: NONSTRICT_READ_WRITE
|
||||
id:
|
||||
id:
|
||||
type: integer
|
||||
@@ -439,17 +428,18 @@ It caches the primary keys of association and cache each element will be cached
|
||||
country_id:
|
||||
referencedColumnName: id
|
||||
cache:
|
||||
usage : NONSTRICT_READ_WRITE
|
||||
usage: NONSTRICT_READ_WRITE
|
||||
|
||||
oneToMany:
|
||||
cities:
|
||||
targetEntity:City
|
||||
mappedBy: state
|
||||
cache:
|
||||
usage : NONSTRICT_READ_WRITE
|
||||
usage: NONSTRICT_READ_WRITE
|
||||
|
||||
.. note::
|
||||
|
||||
> Note: for this to work, the target entity must also be marked as cacheable.
|
||||
for this to work, the target entity must also be marked as cacheable.
|
||||
|
||||
Cache usage
|
||||
~~~~~~~~~~~
|
||||
@@ -466,8 +456,8 @@ Basic entity cache
|
||||
|
||||
$country1 = $em->find('Country', 1); // Retrieve item from cache
|
||||
|
||||
$country1->setName("New Name");
|
||||
|
||||
$country1->setName('New Name');
|
||||
|
||||
$em->flush(); // Hit database to update the row and update cache
|
||||
|
||||
$em->clear(); // Clear entity manager
|
||||
@@ -492,7 +482,7 @@ Association cache
|
||||
$state = $em->find('State', 1);
|
||||
|
||||
// Hit database to update the row and update cache entry
|
||||
$state->setName("New Name");
|
||||
$state->setName('New Name');
|
||||
$em->persist($state);
|
||||
$em->flush();
|
||||
|
||||
@@ -543,14 +533,14 @@ The query cache stores the results of the query but as identifiers, entity value
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/* @var $em \Doctrine\ORM\EntityManager */
|
||||
/** @var \Doctrine\ORM\EntityManager $em */
|
||||
|
||||
// Execute database query, store query cache and entity cache
|
||||
$result1 = $em->createQuery('SELECT c FROM Country c ORDER BY c.name')
|
||||
->setCacheable(true)
|
||||
->getResult();
|
||||
|
||||
$em->clear()
|
||||
$em->clear();
|
||||
|
||||
// Check if query result is valid and load entities from cache
|
||||
$result2 = $em->createQuery('SELECT c FROM Country c ORDER BY c.name')
|
||||
@@ -570,10 +560,10 @@ The Cache Mode controls how a particular query interacts with the second-level c
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/* @var $em \Doctrine\ORM\EntityManager */
|
||||
/** @var \Doctrine\ORM\EntityManager $em */
|
||||
// Will refresh the query cache and all entities the cache as it reads from the database.
|
||||
$result1 = $em->createQuery('SELECT c FROM Country c ORDER BY c.name')
|
||||
->setCacheMode(Cache::MODE_GET)
|
||||
->setCacheMode(\Doctrine\ORM\Cache::MODE_GET)
|
||||
->setCacheable(true)
|
||||
->getResult();
|
||||
|
||||
@@ -597,7 +587,7 @@ Execute the ``UPDATE`` and invalidate ``all cache entries`` using ``Query::HINT_
|
||||
<?php
|
||||
// Execute and invalidate
|
||||
$this->_em->createQuery("UPDATE Entity\Country u SET u.name = 'unknown' WHERE u.id = 1")
|
||||
->setHint(Query::HINT_CACHE_EVICT, true)
|
||||
->setHint(\Doctrine\ORM\Query::HINT_CACHE_EVICT, true)
|
||||
->execute();
|
||||
|
||||
|
||||
@@ -659,7 +649,7 @@ However, you can use the cache API to check / invalidate cache entries.
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/* @var $cache \Doctrine\ORM\Cache */
|
||||
/** @var \Doctrine\ORM\Cache $cache */
|
||||
$cache = $em->getCache();
|
||||
|
||||
$cache->containsEntity('Entity\State', 1) // Check if the cache exists
|
||||
@@ -704,19 +694,19 @@ For performance reasons the cache API does not extract from composite primary ke
|
||||
}
|
||||
|
||||
// Supported
|
||||
/* @var $article Article */
|
||||
/** @var Article $article */
|
||||
$article = $em->find('Article', 1);
|
||||
|
||||
// Supported
|
||||
/* @var $article Article */
|
||||
/** @var Article $article */
|
||||
$article = $em->find('Article', $article);
|
||||
|
||||
// Supported
|
||||
$id = array('source' => 1, 'target' => 2);
|
||||
$id = ['source' => 1, 'target' => 2];
|
||||
$reference = $em->find('Reference', $id);
|
||||
|
||||
// NOT Supported
|
||||
$id = array('source' => new Article(1), 'target' => new Article(2));
|
||||
$id = ['source' => new Article(1), 'target' => new Article(2)];
|
||||
$reference = $em->find('Reference', $id);
|
||||
|
||||
Distributed environments
|
||||
|
||||
@@ -40,7 +40,7 @@ easily using a combination of ``count`` and ``slice``.
|
||||
``removeElement`` directly issued DELETE queries to the database from
|
||||
version 2.4.0 to 2.7.0. This circumvents the flush operation and might run
|
||||
outside a transactional boundary if you don't create one yourself. We
|
||||
consider this a critical bug in the assumptio of how the ORM works and
|
||||
consider this a critical bug in the assumption of how the ORM works and
|
||||
reverted ``removeElement`` EXTRA_LAZY behavior in 2.7.1.
|
||||
|
||||
|
||||
|
||||
@@ -81,7 +81,8 @@ that directory with the following contents:
|
||||
|
||||
{
|
||||
"require": {
|
||||
"doctrine/orm": "^2.6.2",
|
||||
"doctrine/orm": "^2.10.2",
|
||||
"doctrine/dbal": "^3.1.1",
|
||||
"symfony/yaml": "2.*",
|
||||
"symfony/cache": "^5.3"
|
||||
},
|
||||
@@ -112,6 +113,14 @@ Add the following directories:
|
||||
.. note::
|
||||
The YAML driver is deprecated and will be removed in version 3.0.
|
||||
It is strongly recommended to switch to one of the other mappings.
|
||||
.. note::
|
||||
It is strongly recommended that you require ``doctrine/dbal`` in your
|
||||
``composer.json`` as well, because using the ORM means mapping objects
|
||||
and their fields to database tables and their columns, and that
|
||||
requires mentioning so-called types that are defined in ``doctrine/dbal``
|
||||
in your application. Having an explicit requirement means you control
|
||||
when the upgrade to the next major version happens, so that you can
|
||||
do the necessary changes in your application beforehand.
|
||||
|
||||
Obtaining the EntityManager
|
||||
---------------------------
|
||||
@@ -642,7 +651,7 @@ Let's continue by creating a script to display the name of a product based on it
|
||||
echo sprintf("-%s\n", $product->getName());
|
||||
|
||||
Next we'll update a product's name, given its id. This simple example will
|
||||
help demonstrate Doctrine's implementation of the UnitOfWork pattern. Doctrine
|
||||
help demonstrate Doctrine's implementation of the :ref:`UnitOfWork pattern <unit-of-work>`. Doctrine
|
||||
keeps track of all the entities that were retrieved from the Entity Manager,
|
||||
and can detect when any of those entities' properties have been modified.
|
||||
As a result, rather than needing to call ``persist($entity)`` for each individual
|
||||
@@ -1334,7 +1343,7 @@ call this script as follows:
|
||||
php create_bug.php 1 1 1
|
||||
|
||||
See how simple it is to relate a Bug, Reporter, Engineer and Products?
|
||||
Also recall that thanks to the UnitOfWork pattern, Doctrine will detect
|
||||
Also recall that thanks to the :ref:`UnitOfWork pattern <unit-of-work>`, Doctrine will detect
|
||||
these relations and update all of the modified entities in the database
|
||||
automatically when ``flush()`` is called.
|
||||
|
||||
|
||||
+85
-4
@@ -18,13 +18,17 @@
|
||||
<xs:element name="mapped-superclass" type="orm:mapped-superclass" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:element name="entity" type="orm:entity" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:element name="embeddable" type="orm:embeddable" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:complexType name="emptyType">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="cascade-type">
|
||||
@@ -35,7 +39,9 @@
|
||||
<xs:element name="cascade-remove" type="orm:emptyType" minOccurs="0"/>
|
||||
<xs:element name="cascade-refresh" type="orm:emptyType" minOccurs="0"/>
|
||||
<xs:element name="cascade-detach" type="orm:emptyType" minOccurs="0"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="lifecycle-callback-type">
|
||||
@@ -61,15 +67,19 @@
|
||||
|
||||
<xs:complexType name="lifecycle-callback">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="type" type="orm:lifecycle-callback-type" use="required" />
|
||||
<xs:attribute name="method" type="xs:NMTOKEN" use="required" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="lifecycle-callbacks">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="lifecycle-callback" type="orm:lifecycle-callback" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="named-query">
|
||||
@@ -88,6 +98,7 @@
|
||||
<xs:complexType name="named-native-query">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="query" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
<xs:attribute name="result-class" type="orm:fqcn" />
|
||||
@@ -97,12 +108,14 @@
|
||||
<xs:complexType name="named-native-queries">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="named-native-query" type="orm:named-native-query" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="entity-listener">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="lifecycle-callback" type="orm:lifecycle-callback" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="class" type="orm:fqcn"/>
|
||||
</xs:complexType>
|
||||
@@ -135,7 +148,9 @@
|
||||
<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>
|
||||
@@ -173,6 +188,7 @@
|
||||
<xs:element name="many-to-many" type="orm:many-to-many" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:element name="association-overrides" type="orm:association-overrides" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:element name="attribute-overrides" type="orm:attribute-overrides" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
<xs:attribute name="table" type="orm:tablename" />
|
||||
@@ -181,6 +197,7 @@
|
||||
<xs:attribute name="inheritance-type" type="orm:inheritance-type"/>
|
||||
<xs:attribute name="change-tracking-policy" type="orm:change-tracking-policy" />
|
||||
<xs:attribute name="read-only" type="xs:boolean" default="false" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="tablename" id="tablename">
|
||||
@@ -193,21 +210,27 @@
|
||||
<xs:complexType name="option" mixed="true">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="option" type="orm:option"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="options">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="option" type="orm:option" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="mapped-superclass" >
|
||||
<xs:complexContent>
|
||||
<xs:extension base="orm:entity">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
@@ -216,6 +239,7 @@
|
||||
<xs:complexContent>
|
||||
<xs:extension base="orm:entity">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
@@ -267,10 +291,11 @@
|
||||
<xs:complexType name="field">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="options" type="orm:options" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="type" type="xs:NMTOKEN" default="string" />
|
||||
<xs:attribute name="column" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="column" type="orm:columntoken" />
|
||||
<xs:attribute name="length" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="unique" type="xs:boolean" default="false" />
|
||||
<xs:attribute name="nullable" type="xs:boolean" default="false" />
|
||||
@@ -278,6 +303,7 @@
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:attribute name="precision" type="xs:integer" use="optional" />
|
||||
<xs:attribute name="scale" type="xs:integer" use="optional" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="embedded">
|
||||
@@ -292,62 +318,78 @@
|
||||
|
||||
<xs:complexType name="discriminator-column">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="type" type="xs:NMTOKEN"/>
|
||||
<xs:attribute name="field-name" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="length" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="unique-constraint">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="options" type="orm:options" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="optional"/>
|
||||
<xs:attribute name="columns" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="fields" type="xs:string" use="optional"/>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="unique-constraints">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="unique-constraint" type="orm:unique-constraint" minOccurs="1" maxOccurs="unbounded"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="index">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="options" type="orm:options" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="optional"/>
|
||||
<xs:attribute name="columns" type="xs:string" use="required"/>
|
||||
<xs:attribute name="columns" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="fields" type="xs:string" use="optional"/>
|
||||
<xs:attribute name="flags" type="xs:string" use="optional"/>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="indexes">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="index" type="orm:index" minOccurs="1" maxOccurs="unbounded"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="discriminator-mapping">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="value" type="xs:NMTOKEN" use="required"/>
|
||||
<xs:attribute name="class" type="orm:fqcn" use="required"/>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="discriminator-map">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="discriminator-mapping" type="orm:discriminator-mapping" minOccurs="1" maxOccurs="unbounded"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="generator">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="strategy" type="orm:generator-strategy" use="optional" default="AUTO" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="id">
|
||||
@@ -356,25 +398,30 @@
|
||||
<xs:element name="sequence-generator" type="orm:sequence-generator" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="custom-id-generator" type="orm:custom-id-generator" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="options" type="orm:options" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="type" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="column" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="column" type="orm:columntoken" />
|
||||
<xs:attribute name="length" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="association-key" type="xs:boolean" default="false" />
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="sequence-generator">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="sequence-name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="allocation-size" type="xs:integer" use="optional" default="1" />
|
||||
<xs:attribute name="initial-value" type="xs:integer" use="optional" default="1" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="custom-id-generator">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="class" type="orm:fqcn" use="required" />
|
||||
</xs:complexType>
|
||||
@@ -389,11 +436,14 @@
|
||||
<xs:complexType name="inverse-join-columns">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="join-column" type="orm:join-column" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="join-column">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="optional" />
|
||||
<xs:attribute name="referenced-column-name" type="xs:NMTOKEN" use="optional" default="id" />
|
||||
@@ -401,34 +451,43 @@
|
||||
<xs:attribute name="nullable" type="xs:boolean" default="true" />
|
||||
<xs:attribute name="on-delete" type="orm:fk-action" />
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="join-columns">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="join-column" type="orm:join-column" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="join-table">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="join-columns" type="orm:join-columns" />
|
||||
<xs:element name="inverse-join-columns" type="orm:join-columns" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="schema" type="xs:NMTOKEN" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="order-by">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="order-by-field" type="orm:order-by-field" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="order-by-field">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="direction" type="orm:order-by-direction" default="ASC" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="order-by-direction">
|
||||
@@ -438,12 +497,19 @@
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:simpleType name="columntoken" id="columntoken">
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:pattern value="[-._:A-Za-z0-9`]+" id="columntoken.pattern"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
|
||||
<xs:complexType name="many-to-many">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="cache" type="orm:cache" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
|
||||
<xs:element name="join-table" type="orm:join-table" minOccurs="0" />
|
||||
<xs:element name="order-by" type="orm:order-by" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="target-entity" type="xs:string" use="required" />
|
||||
@@ -452,6 +518,7 @@
|
||||
<xs:attribute name="index-by" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
|
||||
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="one-to-many">
|
||||
@@ -459,6 +526,7 @@
|
||||
<xs:element name="cache" type="orm:cache" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
|
||||
<xs:element name="order-by" type="orm:order-by" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="target-entity" type="xs:string" use="required" />
|
||||
@@ -466,6 +534,7 @@
|
||||
<xs:attribute name="index-by" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
|
||||
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="many-to-one">
|
||||
@@ -475,12 +544,15 @@
|
||||
<xs:choice minOccurs="0" maxOccurs="1">
|
||||
<xs:element name="join-column" type="orm:join-column"/>
|
||||
<xs:element name="join-columns" type="orm:join-columns"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="target-entity" type="xs:string" />
|
||||
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="one-to-one">
|
||||
@@ -490,7 +562,9 @@
|
||||
<xs:choice minOccurs="0" maxOccurs="1">
|
||||
<xs:element name="join-column" type="orm:join-column"/>
|
||||
<xs:element name="join-columns" type="orm:join-columns"/>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="target-entity" type="xs:string" />
|
||||
@@ -498,11 +572,13 @@
|
||||
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
|
||||
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="association-overrides">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="association-override" type="orm:association-override" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
@@ -511,6 +587,7 @@
|
||||
<xs:element name="join-table" type="orm:join-table" minOccurs="0" />
|
||||
<xs:element name="join-columns" type="orm:join-columns" minOccurs="0" />
|
||||
<xs:element name="inversed-by" type="orm:inversed-by-override" minOccurs="0" maxOccurs="1" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="fetch" type="orm:fetch-type" use="optional" />
|
||||
@@ -523,12 +600,14 @@
|
||||
<xs:complexType name="attribute-overrides">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="attribute-override" type="orm:attribute-override" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="attribute-override">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="field" type="orm:attribute-override-field" minOccurs="1" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
</xs:complexType>
|
||||
@@ -536,9 +615,10 @@
|
||||
<xs:complexType name="attribute-override-field">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="options" type="orm:options" minOccurs="0" />
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="type" type="xs:NMTOKEN" default="string" />
|
||||
<xs:attribute name="column" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="column" type="orm:columntoken" />
|
||||
<xs:attribute name="length" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="unique" type="xs:boolean" default="false" />
|
||||
<xs:attribute name="nullable" type="xs:boolean" default="false" />
|
||||
@@ -546,6 +626,7 @@
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:attribute name="precision" type="xs:integer" use="optional" />
|
||||
<xs:attribute name="scale" type="xs:integer" use="optional" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
</xs:complexType>
|
||||
|
||||
</xs:schema>
|
||||
|
||||
@@ -1253,7 +1253,8 @@ abstract class AbstractQuery
|
||||
* Will return the configured id if it exists otherwise a hash will be
|
||||
* automatically generated for you.
|
||||
*
|
||||
* @return array<string, string> ($key, $hash)
|
||||
* @return string[] ($key, $hash)
|
||||
* @psalm-return array{string, string} ($key, $hash)
|
||||
*/
|
||||
protected function getHydrationCacheId()
|
||||
{
|
||||
|
||||
@@ -357,9 +357,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
$cached = $queryCache->put($queryKey, $rsm, [$result]);
|
||||
|
||||
if ($this->cacheLogger) {
|
||||
if ($result) {
|
||||
$this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
|
||||
}
|
||||
$this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
|
||||
|
||||
if ($cached) {
|
||||
$this->cacheLogger->queryCachePut($this->regionName, $queryKey);
|
||||
|
||||
@@ -5,9 +5,7 @@ declare(strict_types=1);
|
||||
namespace Doctrine\ORM\Cache\Persister\Entity;
|
||||
|
||||
use Doctrine\Common\Util\ClassUtils;
|
||||
use Doctrine\ORM\Cache\CacheException;
|
||||
use Doctrine\ORM\Cache\Exception\CannotUpdateReadOnlyEntity;
|
||||
use Doctrine\ORM\Utility\StaticClassNameConverter;
|
||||
|
||||
/**
|
||||
* Specific read-only region entity persister
|
||||
|
||||
@@ -19,6 +19,7 @@ use Doctrine\Persistence\ObjectManager;
|
||||
* EntityManager interface
|
||||
*
|
||||
* @method Mapping\ClassMetadataFactory getMetadataFactory()
|
||||
* @method mixed wrapInTransaction(callable $func)
|
||||
*/
|
||||
interface EntityManagerInterface extends ObjectManager
|
||||
{
|
||||
@@ -329,11 +330,9 @@ interface EntityManagerInterface extends ObjectManager
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-param string|class-string<T> $className
|
||||
* @phpstan-param string $className
|
||||
*
|
||||
* @return Mapping\ClassMetadata
|
||||
* @psalm-return Mapping\ClassMetadata<T>
|
||||
* @phpstan-return Mapping\ClassMetadata<object>
|
||||
*
|
||||
* @psalm-template T of object
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\ORM\Id;
|
||||
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Serializable;
|
||||
|
||||
@@ -54,11 +55,14 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
|
||||
{
|
||||
if ($this->_maxValue === null || $this->_nextValue === $this->_maxValue) {
|
||||
// Allocate new values
|
||||
$conn = $em->getConnection();
|
||||
$sql = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName);
|
||||
$connection = $em->getConnection();
|
||||
$sql = $connection->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName);
|
||||
|
||||
// Using `query` to force usage of the master server in MasterSlaveConnection
|
||||
$this->_nextValue = (int) $conn->executeQuery($sql)->fetchOne();
|
||||
if ($connection instanceof PrimaryReadReplicaConnection) {
|
||||
$connection->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
$this->_nextValue = (int) $connection->executeQuery($sql)->fetchOne();
|
||||
$this->_maxValue = $this->_nextValue + $this->_allocationSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\ORM\Id;
|
||||
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
@@ -39,9 +40,13 @@ class UuidGenerator extends AbstractIdGenerator
|
||||
*/
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
$conn = $em->getConnection();
|
||||
$sql = 'SELECT ' . $conn->getDatabasePlatform()->getGuidExpression();
|
||||
$connection = $em->getConnection();
|
||||
$sql = 'SELECT ' . $connection->getDatabasePlatform()->getGuidExpression();
|
||||
|
||||
return $conn->executeQuery($sql)->fetchOne();
|
||||
if ($connection instanceof PrimaryReadReplicaConnection) {
|
||||
$connection->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
return $connection->executeQuery($sql)->fetchOne();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ abstract class AbstractHydrator
|
||||
* @param Result|ResultStatement $stmt
|
||||
* @psalm-param array<string, mixed> $hints
|
||||
*
|
||||
* @return Generator<int, mixed>
|
||||
* @return Generator<array-key, mixed>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
@@ -194,9 +194,12 @@ abstract class AbstractHydrator
|
||||
$this->hydrateRowData($row, $result);
|
||||
|
||||
$this->cleanupAfterRowIteration();
|
||||
|
||||
if (count($result) === 1) {
|
||||
yield end($result);
|
||||
if (count($resultSetMapping->indexByMap) === 0) {
|
||||
yield end($result);
|
||||
} else {
|
||||
yield from $result;
|
||||
}
|
||||
} else {
|
||||
yield $result;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,8 @@ class SimpleObjectHydrator extends AbstractHydrator
|
||||
|
||||
// We need to find the correct entity class name if we have inheritance in resultset
|
||||
if ($this->class->inheritanceType !== ClassMetadata::INHERITANCE_TYPE_NONE) {
|
||||
$discrColumnName = $this->getSQLResultCasing($this->_platform, $this->class->discriminatorColumn['name']);
|
||||
$discrColumn = $this->class->getDiscriminatorColumn();
|
||||
$discrColumnName = $this->getSQLResultCasing($this->_platform, $discrColumn['name']);
|
||||
|
||||
// Find mapped discriminator column from the result set.
|
||||
$metaMappingDiscrColumnName = array_search($discrColumnName, $this->resultSetMapping()->metaMappings, true);
|
||||
|
||||
@@ -184,9 +184,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
$class->setPrimaryTable($parent->table);
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
$this->addInheritedIndexes($class, $parent);
|
||||
}
|
||||
$this->addInheritedIndexes($class, $parent);
|
||||
|
||||
if ($parent->cache) {
|
||||
$class->cache = $parent->cache;
|
||||
@@ -276,7 +274,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
} else {
|
||||
assert($parent instanceof ClassMetadataInfo); // https://github.com/doctrine/orm/issues/8746
|
||||
if (
|
||||
(! $class->reflClass || ! $class->reflClass->isAbstract())
|
||||
! $class->reflClass->isAbstract()
|
||||
&& ! in_array($class->name, $class->discriminatorMap, true)
|
||||
) {
|
||||
throw MappingException::mappedClassNotPartOfDiscriminatorMap($class->name, $class->rootEntityName);
|
||||
|
||||
@@ -20,6 +20,7 @@ use Doctrine\ORM\Id\AbstractIdGenerator;
|
||||
use Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Persistence\Mapping\ReflectionService;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use ReflectionClass;
|
||||
use ReflectionNamedType;
|
||||
use ReflectionProperty;
|
||||
@@ -69,6 +70,26 @@ use const PHP_VERSION_ID;
|
||||
*
|
||||
* @template-covariant T of object
|
||||
* @template-implements ClassMetadata<T>
|
||||
* @psalm-type FieldMapping = array{
|
||||
* type: string,
|
||||
* fieldName: string,
|
||||
* columnName?: string,
|
||||
* length?: int,
|
||||
* id?: bool,
|
||||
* nullable?: bool,
|
||||
* columnDefinition?: string,
|
||||
* precision?: int,
|
||||
* scale?: int,
|
||||
* unique?: string,
|
||||
* inherited?: class-string,
|
||||
* originalClass?: class-string,
|
||||
* originalField?: string,
|
||||
* quoted?: bool,
|
||||
* requireSQLConversion?: bool,
|
||||
* declared?: class-string,
|
||||
* declaredField?: string,
|
||||
* options?: array<string, mixed>
|
||||
* }
|
||||
*/
|
||||
class ClassMetadataInfo implements ClassMetadata
|
||||
{
|
||||
@@ -426,25 +447,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* Whether a unique constraint should be generated for the column.
|
||||
*
|
||||
* @var mixed[]
|
||||
* @psalm-var array<string, array{
|
||||
* type: string,
|
||||
* fieldName: string,
|
||||
* columnName?: string,
|
||||
* length?: int,
|
||||
* id?: bool,
|
||||
* nullable?: bool,
|
||||
* columnDefinition?: string,
|
||||
* precision?: int,
|
||||
* scale?: int,
|
||||
* unique?: string,
|
||||
* inherited?: class-string,
|
||||
* originalClass?: class-string,
|
||||
* originalField?: string,
|
||||
* quoted?: bool,
|
||||
* requireSQLConversion?: bool,
|
||||
* declaredField?: string,
|
||||
* options: array<mixed>
|
||||
* }>
|
||||
* @psalm-var array<string, FieldMapping>
|
||||
*/
|
||||
public $fieldMappings = [];
|
||||
|
||||
@@ -495,7 +498,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* READ-ONLY: The definition of the discriminator column used in JOINED and SINGLE_TABLE
|
||||
* inheritance mappings.
|
||||
*
|
||||
* @psalm-var array<string, mixed>
|
||||
* @psalm-var array<string, mixed>|null
|
||||
*/
|
||||
public $discriminatorColumn;
|
||||
|
||||
@@ -509,7 +512,14 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* uniqueConstraints => array
|
||||
*
|
||||
* @var mixed[]
|
||||
* @psalm-var array{name: string, schema: string, indexes: array, uniqueConstraints: array}
|
||||
* @psalm-var array{
|
||||
* name: string,
|
||||
* schema: string,
|
||||
* indexes: array,
|
||||
* uniqueConstraints: array,
|
||||
* options: array<string, mixed>,
|
||||
* quoted?: bool
|
||||
* }
|
||||
*/
|
||||
public $table;
|
||||
|
||||
@@ -665,7 +675,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
/**
|
||||
* The ReflectionClass instance of the mapped class.
|
||||
*
|
||||
* @var ReflectionClass
|
||||
* @var ReflectionClass|null
|
||||
*/
|
||||
public $reflClass;
|
||||
|
||||
@@ -1276,18 +1286,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* @param string $fieldName The field name.
|
||||
*
|
||||
* @return mixed[] The field mapping.
|
||||
* @psalm-return array{
|
||||
* type: string,
|
||||
* fieldName: string,
|
||||
* columnName?: string,
|
||||
* inherited?: class-string,
|
||||
* nullable?: bool,
|
||||
* originalClass?: class-string,
|
||||
* originalField?: string,
|
||||
* scale?: int,
|
||||
* precision?: int,
|
||||
* length?: int
|
||||
* }
|
||||
* @psalm-return FieldMapping
|
||||
*
|
||||
* @throws MappingException
|
||||
*/
|
||||
@@ -3090,6 +3089,18 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
final public function getDiscriminatorColumn(): array
|
||||
{
|
||||
if ($this->discriminatorColumn === null) {
|
||||
throw new LogicException('The discriminator column was not set.');
|
||||
}
|
||||
|
||||
return $this->discriminatorColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the discriminator values used by this class.
|
||||
* Used for JOINED and SINGLE_TABLE inheritance mapping strategies.
|
||||
|
||||
@@ -15,26 +15,26 @@ use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor;
|
||||
#[Attribute(Attribute::TARGET_PROPERTY)]
|
||||
final class Column implements Annotation
|
||||
{
|
||||
/** @var string */
|
||||
/** @var string|null */
|
||||
public $name;
|
||||
|
||||
/** @var mixed */
|
||||
public $type;
|
||||
|
||||
/** @var int */
|
||||
/** @var int|null */
|
||||
public $length;
|
||||
|
||||
/**
|
||||
* The precision for a decimal (exact numeric) column (Applies only for decimal column).
|
||||
*
|
||||
* @var int
|
||||
* @var int|null
|
||||
*/
|
||||
public $precision = 0;
|
||||
|
||||
/**
|
||||
* The scale for a decimal (exact numeric) column (Applies only for decimal column).
|
||||
*
|
||||
* @var int
|
||||
* @var int|null
|
||||
*/
|
||||
public $scale = 0;
|
||||
|
||||
@@ -47,7 +47,7 @@ final class Column implements Annotation
|
||||
/** @var array<string,mixed> */
|
||||
public $options = [];
|
||||
|
||||
/** @var string */
|
||||
/** @var string|null */
|
||||
public $columnDefinition;
|
||||
|
||||
/**
|
||||
|
||||
@@ -249,7 +249,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
$field = $this->quoteStrategy->getColumnName($name, $targetClass, $this->platform);
|
||||
$whereClauses[] = sprintf('te.%s %s ?', $field, $operator);
|
||||
$params[] = $value;
|
||||
$paramTypes[] = PersisterHelper::getTypeOfColumn($field, $targetClass, $this->em);
|
||||
$paramTypes[] = PersisterHelper::getTypeOfField($name, $targetClass, $this->em)[0];
|
||||
}
|
||||
|
||||
$tableName = $this->quoteStrategy->getTableName($targetClass, $this->platform);
|
||||
|
||||
@@ -24,7 +24,7 @@ abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
|
||||
$data = parent::prepareInsertData($entity);
|
||||
|
||||
// Populate the discriminator column
|
||||
$discColumn = $this->class->discriminatorColumn;
|
||||
$discColumn = $this->class->getDiscriminatorColumn();
|
||||
$this->columnTypes[$discColumn['name']] = $discColumn['type'];
|
||||
$data[$this->getDiscriminatorColumnTableName()][$discColumn['name']] = $this->class->discriminatorValue;
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ use Doctrine\ORM\Utility\PersisterHelper;
|
||||
|
||||
use function array_combine;
|
||||
use function implode;
|
||||
use function is_array;
|
||||
|
||||
/**
|
||||
* The joined subclass persister maps a single entity instance to several tables in the
|
||||
@@ -412,14 +411,15 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
||||
}
|
||||
|
||||
$columnList = [];
|
||||
$discrColumn = $this->class->discriminatorColumn['name'];
|
||||
$discrColumnType = $this->class->discriminatorColumn['type'];
|
||||
$discrColumn = $this->class->getDiscriminatorColumn();
|
||||
$discrColumnName = $discrColumn['name'];
|
||||
$discrColumnType = $discrColumn['type'];
|
||||
$baseTableAlias = $this->getSQLTableAlias($this->class->name);
|
||||
$resultColumnName = $this->getSQLResultCasing($this->platform, $discrColumn);
|
||||
$resultColumnName = $this->getSQLResultCasing($this->platform, $discrColumnName);
|
||||
|
||||
$this->currentPersisterContext->rsm->addEntityResult($this->class->name, 'r');
|
||||
$this->currentPersisterContext->rsm->setDiscriminatorColumn('r', $resultColumnName);
|
||||
$this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumn, false, $discrColumnType);
|
||||
$this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumnName, false, $discrColumnType);
|
||||
|
||||
// Add regular columns
|
||||
foreach ($this->class->fieldMappings as $fieldName => $mapping) {
|
||||
@@ -457,7 +457,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
||||
? $baseTableAlias
|
||||
: $this->getSQLTableAlias($this->class->rootEntityName);
|
||||
|
||||
$columnList[] = $tableAlias . '.' . $discrColumn;
|
||||
$columnList[] = $tableAlias . '.' . $discrColumnName;
|
||||
|
||||
// sub tables
|
||||
foreach ($this->class->subClasses as $subClassName) {
|
||||
@@ -540,7 +540,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
||||
|
||||
// Add discriminator column if it is the topmost class.
|
||||
if ($this->class->name === $this->class->rootEntityName) {
|
||||
$columns[] = $this->class->discriminatorColumn['name'];
|
||||
$columns[] = $this->class->getDiscriminatorColumn()['name'];
|
||||
}
|
||||
|
||||
return $columns;
|
||||
|
||||
@@ -44,16 +44,17 @@ class SingleTablePersister extends AbstractEntityInheritancePersister
|
||||
$rootClass = $this->em->getClassMetadata($this->class->rootEntityName);
|
||||
$tableAlias = $this->getSQLTableAlias($rootClass->name);
|
||||
|
||||
// Append discriminator column
|
||||
$discrColumn = $this->class->discriminatorColumn['name'];
|
||||
$discrColumnType = $this->class->discriminatorColumn['type'];
|
||||
// Append discriminator column
|
||||
$discrColumn = $this->class->getDiscriminatorColumn();
|
||||
$discrColumnName = $discrColumn['name'];
|
||||
$discrColumnType = $discrColumn['type'];
|
||||
|
||||
$columnList[] = $tableAlias . '.' . $discrColumn;
|
||||
$columnList[] = $tableAlias . '.' . $discrColumnName;
|
||||
|
||||
$resultColumnName = $this->getSQLResultCasing($this->platform, $discrColumn);
|
||||
$resultColumnName = $this->getSQLResultCasing($this->platform, $discrColumnName);
|
||||
|
||||
$this->currentPersisterContext->rsm->setDiscriminatorColumn('r', $resultColumnName);
|
||||
$this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumn, false, $discrColumnType);
|
||||
$this->currentPersisterContext->rsm->addMetaResult('r', $resultColumnName, $discrColumnName, false, $discrColumnType);
|
||||
|
||||
// Append subclass columns
|
||||
foreach ($this->class->subClasses as $subClassName) {
|
||||
@@ -100,7 +101,7 @@ class SingleTablePersister extends AbstractEntityInheritancePersister
|
||||
$columns = parent::getInsertColumnList();
|
||||
|
||||
// Add discriminator column to the INSERT SQL
|
||||
$columns[] = $this->class->discriminatorColumn['name'];
|
||||
$columns[] = $this->class->getDiscriminatorColumn()['name'];
|
||||
|
||||
return $columns;
|
||||
}
|
||||
@@ -158,11 +159,12 @@ class SingleTablePersister extends AbstractEntityInheritancePersister
|
||||
$values[] = $this->conn->quote($discrValues[$subclassName]);
|
||||
}
|
||||
|
||||
$discColumnName = $this->class->getDiscriminatorColumn()['name'];
|
||||
|
||||
$values = implode(', ', $values);
|
||||
$discColumn = $this->class->discriminatorColumn['name'];
|
||||
$tableAlias = $this->getSQLTableAlias($this->class->name);
|
||||
|
||||
return $tableAlias . '.' . $discColumn . ' IN (' . $values . ')';
|
||||
return $tableAlias . '.' . $discColumnName . ' IN (' . $values . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Doctrine\ORM\Query\Exec;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\ORM\Query\AST;
|
||||
use Doctrine\ORM\Query\AST\DeleteStatement;
|
||||
@@ -49,6 +50,10 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
|
||||
$platform = $conn->getDatabasePlatform();
|
||||
$quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
|
||||
|
||||
if ($conn instanceof PrimaryReadReplicaConnection) {
|
||||
$conn->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
$primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName);
|
||||
$primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable;
|
||||
$rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Doctrine\ORM\Query\Exec;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\ORM\Query\AST;
|
||||
use Doctrine\ORM\Query\AST\UpdateStatement;
|
||||
@@ -55,6 +56,10 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
|
||||
$platform = $conn->getDatabasePlatform();
|
||||
$quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
|
||||
|
||||
if ($conn instanceof PrimaryReadReplicaConnection) {
|
||||
$conn->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
$updateClause = $AST->updateClause;
|
||||
$primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName);
|
||||
$rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Doctrine\ORM\Query\Exec;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\ORM\Query\AST;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
|
||||
@@ -37,6 +38,10 @@ class SingleTableDeleteUpdateExecutor extends AbstractSqlExecutor
|
||||
*/
|
||||
public function execute(Connection $conn, array $params, array $types)
|
||||
{
|
||||
if ($conn instanceof PrimaryReadReplicaConnection) {
|
||||
$conn->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
return $conn->executeStatement($this->_sqlStatements, $params, $types);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +195,7 @@ abstract class SQLFilter
|
||||
* Gets the SQL query part to add to a query.
|
||||
*
|
||||
* @param string $targetTableAlias
|
||||
* @psalm-param ClassMetadata<object> $targetEntity
|
||||
*
|
||||
* @return string The constraint SQL if there is available, empty string otherwise.
|
||||
*/
|
||||
|
||||
@@ -214,7 +214,7 @@ class Parser
|
||||
*/
|
||||
private $customOutputWalker;
|
||||
|
||||
/** @psalm-var list<AST\SelectExpression> */
|
||||
/** @psalm-var array<string, AST\SelectExpression> */
|
||||
private $identVariableExpressions = [];
|
||||
|
||||
/**
|
||||
|
||||
@@ -369,7 +369,7 @@ class ResultSetMappingBuilder extends ResultSetMapping
|
||||
{
|
||||
if (isset($entityMapping['discriminatorColumn']) && $entityMapping['discriminatorColumn']) {
|
||||
$discriminatorColumn = $entityMapping['discriminatorColumn'];
|
||||
$discriminatorType = $classMetadata->discriminatorColumn['type'];
|
||||
$discriminatorType = $classMetadata->getDiscriminatorColumn()['type'];
|
||||
|
||||
$this->setDiscriminatorColumn($alias, $discriminatorColumn);
|
||||
$this->addMetaResult($alias, $discriminatorColumn, $discriminatorColumn, false, $discriminatorType);
|
||||
|
||||
@@ -465,7 +465,7 @@ class SqlWalker implements TreeWalker
|
||||
? $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.'
|
||||
: '';
|
||||
|
||||
$sqlParts[] = $sqlTableAlias . $class->discriminatorColumn['name'] . ' IN (' . implode(', ', $values) . ')';
|
||||
$sqlParts[] = $sqlTableAlias . $class->getDiscriminatorColumn()['name'] . ' IN (' . implode(', ', $values) . ')';
|
||||
}
|
||||
|
||||
$sql = implode(' AND ', $sqlParts);
|
||||
@@ -739,7 +739,7 @@ class SqlWalker implements TreeWalker
|
||||
// Add discriminator columns to SQL
|
||||
$rootClass = $this->em->getClassMetadata($class->rootEntityName);
|
||||
$tblAlias = $this->getSQLTableAlias($rootClass->getTableName(), $dqlAlias);
|
||||
$discrColumn = $rootClass->discriminatorColumn;
|
||||
$discrColumn = $rootClass->getDiscriminatorColumn();
|
||||
$columnAlias = $this->getSQLColumnAlias($discrColumn['name']);
|
||||
|
||||
$sqlSelectExpressions[] = $tblAlias . '.' . $discrColumn['name'] . ' AS ' . $columnAlias;
|
||||
@@ -2091,7 +2091,7 @@ class SqlWalker implements TreeWalker
|
||||
$sql .= $this->getSQLTableAlias($discrClass->getTableName(), $dqlAlias) . '.';
|
||||
}
|
||||
|
||||
$sql .= $class->discriminatorColumn['name'] . ($instanceOfExpr->not ? ' NOT IN ' : ' IN ');
|
||||
$sql .= $class->getDiscriminatorColumn()['name'] . ($instanceOfExpr->not ? ' NOT IN ' : ' IN ');
|
||||
$sql .= $this->getChildDiscriminatorsFromClassMetadata($discrClass, $instanceOfExpr);
|
||||
|
||||
return $sql;
|
||||
|
||||
@@ -151,7 +151,7 @@ EOT
|
||||
if (empty($metadata)) {
|
||||
$ui->success('No Metadata Classes to process.');
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($metadata as $class) {
|
||||
|
||||
@@ -1140,7 +1140,11 @@ public function __construct(<params>)
|
||||
return '';
|
||||
}
|
||||
|
||||
$discrColumn = $metadata->discriminatorColumn;
|
||||
$discrColumn = $metadata->discriminatorColumn;
|
||||
if ($discrColumn === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$columnDefinition = 'name="' . $discrColumn['name']
|
||||
. '", type="' . $discrColumn['type']
|
||||
. '", length=' . $discrColumn['length'];
|
||||
|
||||
@@ -31,7 +31,7 @@ use const DIRECTORY_SEPARATOR;
|
||||
*/
|
||||
class EntityRepositoryGenerator
|
||||
{
|
||||
/** @psalm-var class-string */
|
||||
/** @psalm-var class-string|null */
|
||||
private $repositoryName;
|
||||
|
||||
/** @var string */
|
||||
|
||||
@@ -9,6 +9,7 @@ use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\Common\Proxy\Proxy;
|
||||
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
|
||||
use Doctrine\DBAL\LockMode;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use Doctrine\ORM\Cache\Persister\CachedPersister;
|
||||
@@ -338,6 +339,12 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*/
|
||||
public function commit($entity = null)
|
||||
{
|
||||
$connection = $this->em->getConnection();
|
||||
|
||||
if ($connection instanceof PrimaryReadReplicaConnection) {
|
||||
$connection->ensureConnectedToPrimary();
|
||||
}
|
||||
|
||||
// Raise preFlush
|
||||
if ($this->evm->hasListeners(Events::preFlush)) {
|
||||
$this->evm->dispatchEvent(Events::preFlush, new PreFlushEventArgs($this->em));
|
||||
|
||||
+189
-39
@@ -85,11 +85,6 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php
|
||||
|
||||
-
|
||||
message: "#^If condition is always true\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#3 \\$entry of method Doctrine\\\\ORM\\\\Cache\\\\EntityHydrator\\:\\:loadCacheEntry\\(\\) expects Doctrine\\\\ORM\\\\Cache\\\\EntityCacheEntry, Doctrine\\\\ORM\\\\Cache\\\\CacheEntry given\\.$#"
|
||||
count: 1
|
||||
@@ -105,6 +100,11 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php
|
||||
|
||||
-
|
||||
message: "#^PHPDoc type Doctrine\\\\Common\\\\Cache\\\\Cache\\|Doctrine\\\\Common\\\\Cache\\\\MultiGetCache of property Doctrine\\\\ORM\\\\Cache\\\\Region\\\\DefaultMultiGetRegion\\:\\:\\$cache is not covariant with PHPDoc type Doctrine\\\\Common\\\\Cache\\\\Cache of overridden property Doctrine\\\\ORM\\\\Cache\\\\Region\\\\DefaultRegion\\:\\:\\$cache\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Cache/Region/DefaultMultiGetRegion.php
|
||||
|
||||
-
|
||||
message: "#^Method Doctrine\\\\ORM\\\\Cache\\\\Region\\\\DefaultRegion\\:\\:getCache\\(\\) should return Doctrine\\\\Common\\\\Cache\\\\CacheProvider but returns Doctrine\\\\Common\\\\Cache\\\\Cache\\.$#"
|
||||
count: 1
|
||||
@@ -185,6 +185,11 @@ parameters:
|
||||
count: 2
|
||||
path: lib/Doctrine/ORM/EntityManager.php
|
||||
|
||||
-
|
||||
message: "#^Template type T of method Doctrine\\\\ORM\\\\EntityManagerInterface\\:\\:getClassMetadata\\(\\) is not referenced in a parameter\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/EntityManagerInterface.php
|
||||
|
||||
-
|
||||
message: "#^Method Doctrine\\\\ORM\\\\EntityRepository\\:\\:findOneBy\\(\\) should return T\\|null but returns object\\|null\\.$#"
|
||||
count: 1
|
||||
@@ -240,6 +245,16 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/LazyCriteriaCollection.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'indexes' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'uniqueConstraints' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$cache\\.$#"
|
||||
count: 2
|
||||
@@ -412,7 +427,7 @@ parameters:
|
||||
|
||||
-
|
||||
message: "#^If condition is always true\\.$#"
|
||||
count: 2
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
|
||||
|
||||
-
|
||||
@@ -422,7 +437,12 @@ parameters:
|
||||
|
||||
-
|
||||
message: "#^Negated boolean expression is always false\\.$#"
|
||||
count: 3
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'indexes'\\|'uniqueConstraints' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
|
||||
|
||||
-
|
||||
@@ -530,21 +550,6 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
|
||||
|
||||
-
|
||||
message: "#^Array \\(array\\('name' \\=\\> string, 'schema' \\=\\> string, 'indexes' \\=\\> array, 'uniqueConstraints' \\=\\> array\\)\\) does not accept key 'options'\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
message: "#^Array \\(array\\('name' \\=\\> string, 'schema' \\=\\> string, 'indexes' \\=\\> array, 'uniqueConstraints' \\=\\> array\\)\\) does not accept key 'quoted'\\.$#"
|
||||
count: 2
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
message: "#^Array \\(array\\<string, array\\|string\\>\\) does not accept true\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
message: "#^Call to an undefined method ReflectionProperty\\:\\:getType\\(\\)\\.$#"
|
||||
count: 3
|
||||
@@ -566,13 +571,13 @@ parameters:
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$type of static method Doctrine\\\\ORM\\\\Mapping\\\\MappingException\\:\\:invalidInheritanceType\\(\\) expects string, int given\\.$#"
|
||||
message: "#^Offset 'schema' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} on left side of \\?\\? always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
message: "#^Result of && is always false\\.$#"
|
||||
count: 2
|
||||
message: "#^Parameter \\#2 \\$type of static method Doctrine\\\\ORM\\\\Mapping\\\\MappingException\\:\\:invalidInheritanceType\\(\\) expects string, int given\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
@@ -770,6 +775,11 @@ parameters:
|
||||
count: 2
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php
|
||||
|
||||
-
|
||||
message: "#^PHPDoc type array\\<string, int\\> of property Doctrine\\\\ORM\\\\Mapping\\\\Driver\\\\AttributeDriver\\:\\:\\$entityAnnotationClasses is not covariant with PHPDoc type array\\<class\\-string, bool\\|int\\> of overridden property Doctrine\\\\Persistence\\\\Mapping\\\\Driver\\\\AnnotationDriver\\:\\:\\$entityAnnotationClasses\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$metadata of static method Doctrine\\\\ORM\\\\Mapping\\\\Builder\\\\EntityListenerBuilder\\:\\:bindEntityListener\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo&Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\<T of object\\> given\\.$#"
|
||||
count: 1
|
||||
@@ -965,6 +975,11 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'version' on \\*NEVER\\* in isset\\(\\) always exists and is always null\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$metadata of static method Doctrine\\\\ORM\\\\Mapping\\\\Builder\\\\EntityListenerBuilder\\:\\:bindEntityListener\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\<T of object\\> given\\.$#"
|
||||
count: 1
|
||||
@@ -1120,6 +1135,11 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'usage' on array\\{usage\\: string, region\\?\\: string\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$metadata of static method Doctrine\\\\ORM\\\\Mapping\\\\Builder\\\\EntityListenerBuilder\\:\\:bindEntityListener\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\<T of object\\> given\\.$#"
|
||||
count: 1
|
||||
@@ -1385,15 +1405,30 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php
|
||||
|
||||
-
|
||||
message: "#^PHPDoc type array\\<string\\> of property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Andx\\:\\:\\$allowedClasses is not covariant with PHPDoc type array\\<int, class\\-string\\> of overridden property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Base\\:\\:\\$allowedClasses\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/Expr/Andx.php
|
||||
|
||||
-
|
||||
message: "#^PHPDoc type array\\<string\\> of property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Orx\\:\\:\\$allowedClasses is not covariant with PHPDoc type array\\<int, class\\-string\\> of overridden property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Base\\:\\:\\$allowedClasses\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/Expr/Orx.php
|
||||
|
||||
-
|
||||
message: "#^PHPDoc type array\\<string\\> of property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Select\\:\\:\\$allowedClasses is not covariant with PHPDoc type array\\<int, class\\-string\\> of overridden property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Base\\:\\:\\$allowedClasses\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/Expr/Select.php
|
||||
|
||||
-
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Query\\\\FilterCollection\\:\\:\\$em \\(Doctrine\\\\ORM\\\\EntityManager\\) does not accept Doctrine\\\\ORM\\\\EntityManagerInterface\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/FilterCollection.php
|
||||
|
||||
-
|
||||
message: "#^Array \\(array\\<int, Doctrine\\\\ORM\\\\Query\\\\AST\\\\SelectExpression\\>\\) does not accept key non\\-empty\\-string\\.$#"
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Query\\\\FilterCollection\\:\\:\\$filterHash is never written, only read\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/Parser.php
|
||||
path: lib/Doctrine/ORM/Query/FilterCollection.php
|
||||
|
||||
-
|
||||
message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#"
|
||||
@@ -1427,14 +1462,19 @@ parameters:
|
||||
path: lib/Doctrine/ORM/Query/Parser.php
|
||||
|
||||
-
|
||||
message: "#^Result of && is always false\\.$#"
|
||||
count: 1
|
||||
message: "#^Unreachable statement \\- code above always terminates\\.$#"
|
||||
count: 3
|
||||
path: lib/Doctrine/ORM/Query/Parser.php
|
||||
|
||||
-
|
||||
message: "#^Unreachable statement \\- code above always terminates\\.$#"
|
||||
count: 4
|
||||
path: lib/Doctrine/ORM/Query/Parser.php
|
||||
message: "#^Offset 'columns' on array\\{name\\: string, entities\\: array, columns\\: array\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'entities' on array\\{name\\: string, entities\\: array, columns\\: array\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$class of static method Doctrine\\\\ORM\\\\Utility\\\\PersisterHelper\\:\\:getTypeOfColumn\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo given\\.$#"
|
||||
@@ -1481,6 +1521,16 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/SqlWalker.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'resultVariable' on array\\{metadata\\: Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, parent\\: string, relation\\: array, map\\: mixed, nestingLevel\\: int, token\\: array\\} in isset\\(\\) does not exist\\.$#"
|
||||
count: 3
|
||||
path: lib/Doctrine/ORM/Query/SqlWalker.php
|
||||
|
||||
-
|
||||
message: "#^Offset string on array\\<int, array\\{class\\: Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, dqlAlias\\: string, resultAlias\\: string\\}\\> in isset\\(\\) does not exist\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Query/SqlWalker.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$entity of static method Doctrine\\\\ORM\\\\OptimisticLockException\\:\\:lockFailed\\(\\) expects object, class\\-string\\<object\\> given\\.$#"
|
||||
count: 1
|
||||
@@ -1987,7 +2037,7 @@ parameters:
|
||||
path: lib/Doctrine/ORM/QueryBuilder.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$dqlPart of method Doctrine\\\\ORM\\\\QueryBuilder\\:\\:add\\(\\) expects array\\<'join'\\|int, array\\<int\\|string, object\\>\\|string\\>\\|object\\|string, array\\<string, Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Join\\>&nonEmpty given\\.$#"
|
||||
message: "#^Parameter \\#2 \\$dqlPart of method Doctrine\\\\ORM\\\\QueryBuilder\\:\\:add\\(\\) expects array\\<'join'\\|int, array\\<int\\|string, object\\>\\|string\\>\\|object\\|string, non\\-empty\\-array\\<string, Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Join\\> given\\.$#"
|
||||
count: 2
|
||||
path: lib/Doctrine/ORM/QueryBuilder.php
|
||||
|
||||
@@ -2026,11 +2076,6 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
|
||||
|
||||
-
|
||||
message: "#^Method Doctrine\\\\ORM\\\\Tools\\\\Console\\\\Command\\\\ConvertMappingCommand\\:\\:execute\\(\\) should return int but empty return statement found\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$metadata of method Doctrine\\\\ORM\\\\Tools\\\\Export\\\\Driver\\\\AbstractExporter\\:\\:setMetadata\\(\\) expects array\\<int, Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata\\>, array\\<Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\> given\\.$#"
|
||||
count: 1
|
||||
@@ -2067,7 +2112,47 @@ parameters:
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Result of && is always false\\.$#"
|
||||
message: "#^Offset 'allocationSize' on array\\{sequenceName\\: string, allocationSize\\: string, initialValue\\: string, quoted\\?\\: mixed\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'indexes' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'initialValue' on array\\{sequenceName\\: string, allocationSize\\: string, initialValue\\: string, quoted\\?\\: mixed\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'name' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'options' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'schema' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'sequenceName' on array\\{sequenceName\\: string, allocationSize\\: string, initialValue\\: string, quoted\\?\\: mixed\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'uniqueConstraints' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
-
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\<object\\>\\:\\:\\$lifecycleCallbacks \\(array\\<string, array\\<int, string\\>\\>\\) in isset\\(\\) is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/EntityGenerator.php
|
||||
|
||||
@@ -2101,6 +2186,36 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'indexes' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'name' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'options' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'schema' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'uniqueConstraints' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'version' on array\\{type\\: string, fieldName\\: string, columnName\\?\\: string, length\\?\\: int, id\\?\\: bool, nullable\\?\\: bool, columnDefinition\\?\\: string, precision\\?\\: int, \\.\\.\\.\\} in isset\\(\\) does not exist\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$policy of method Doctrine\\\\ORM\\\\Tools\\\\Export\\\\Driver\\\\AbstractExporter\\:\\:_getChangeTrackingPolicyString\\(\\) expects 1\\|2\\|3, int given\\.$#"
|
||||
count: 1
|
||||
@@ -2111,6 +2226,11 @@ parameters:
|
||||
count: 2
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\<object\\>\\:\\:\\$lifecycleCallbacks \\(array\\<string, array\\<int, string\\>\\>\\) in isset\\(\\) is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Right side of && is always true\\.$#"
|
||||
count: 2
|
||||
@@ -2121,6 +2241,16 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\<object\\>\\:\\:\\$lifecycleCallbacks \\(array\\<string, array\\<int, string\\>\\>\\) in isset\\(\\) is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\<object\\>\\:\\:\\$table \\(array\\<string, array\\|bool\\|string\\>\\) on left side of \\?\\? is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
|
||||
|
||||
-
|
||||
message: "#^Return type \\(void\\) of method Doctrine\\\\ORM\\\\Tools\\\\Pagination\\\\CountWalker\\:\\:walkSelectStatement\\(\\) should be compatible with return type \\(string\\) of method Doctrine\\\\ORM\\\\Query\\\\TreeWalker\\:\\:walkSelectStatement\\(\\)$#"
|
||||
count: 1
|
||||
@@ -2131,6 +2261,11 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'parent' on array\\{metadata\\: Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, parent\\: string, relation\\: array, map\\: mixed, nestingLevel\\: int, token\\: array\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php
|
||||
|
||||
-
|
||||
message: "#^Return type \\(void\\) of method Doctrine\\\\ORM\\\\Tools\\\\Pagination\\\\LimitSubqueryWalker\\:\\:walkSelectStatement\\(\\) should be compatible with return type \\(string\\) of method Doctrine\\\\ORM\\\\Query\\\\TreeWalker\\:\\:walkSelectStatement\\(\\)$#"
|
||||
count: 1
|
||||
@@ -2166,6 +2301,21 @@ parameters:
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/SchemaTool.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'indexes' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/SchemaTool.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'options' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/SchemaTool.php
|
||||
|
||||
-
|
||||
message: "#^Offset 'uniqueConstraints' on array\\{name\\: string, schema\\: string, indexes\\: array, uniqueConstraints\\: array, options\\: array\\<string, mixed\\>, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#"
|
||||
count: 1
|
||||
path: lib/Doctrine/ORM/Tools/SchemaTool.php
|
||||
|
||||
-
|
||||
message: "#^Binary operation \"&\" between string and 3 results in an error\\.$#"
|
||||
count: 1
|
||||
|
||||
+1
-10
@@ -21,7 +21,7 @@ parameters:
|
||||
message: '/^Call to an undefined method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getSQLResultCasing\(\)\.$/'
|
||||
path: lib/Doctrine/ORM/Internal/SQLResultCasing.php
|
||||
-
|
||||
message: '/^Parameter \$stmt of method .* has invalid typehint type Doctrine\\DBAL\\Driver\\ResultStatement\.$/'
|
||||
message: '/^Parameter \$stmt of method .* has invalid type Doctrine\\DBAL\\Driver\\ResultStatement\.$/'
|
||||
path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
|
||||
-
|
||||
message: '/^Class Doctrine\\DBAL\\Driver\\ResultStatement not found\.$/'
|
||||
@@ -30,15 +30,6 @@ parameters:
|
||||
message: '/^Call to static method ensure\(\) on an unknown class Doctrine\\DBAL\\ForwardCompatibility\\Result\.$/'
|
||||
path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
|
||||
|
||||
# Forward compatibility for DBAL 3.2
|
||||
- '/^Call to an undefined method Doctrine\\DBAL\\Cache\\QueryCacheProfile::[gs]etResultCache\(\)\.$/'
|
||||
-
|
||||
message: '/^Call to an undefined static method Doctrine\\DBAL\\Configuration::[gs]etResultCache\(\)\.$/'
|
||||
path: lib/Doctrine/ORM/Configuration.php
|
||||
-
|
||||
message: '/^Parameter #3 \$resultCache of class Doctrine\\DBAL\\Cache\\QueryCacheProfile constructor/'
|
||||
path: lib/Doctrine/ORM/AbstractQuery.php
|
||||
|
||||
# False positive
|
||||
-
|
||||
message: '/^Variable \$offset in isset\(\) always exists and is not nullable\.$/'
|
||||
|
||||
+122
-129
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<files psalm-version="4.10.0@916b098b008f6de4543892b1e0651c1c3b92cbfa">
|
||||
<files psalm-version="v4.15.0@a1b5e489e6fcebe40cb804793d964e99fc347820">
|
||||
<file src="lib/Doctrine/ORM/AbstractQuery.php">
|
||||
<DeprecatedClass occurrences="1">
|
||||
<code>IterableResult</code>
|
||||
@@ -7,9 +7,6 @@
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>iterate</code>
|
||||
</DeprecatedMethod>
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<code>$resultCacheDriver !== null && ! ($resultCacheDriver instanceof \Doctrine\Common\Cache\Cache)</code>
|
||||
</DocblockTypeContradiction>
|
||||
<FalsableReturnStatement occurrences="1">
|
||||
<code>! $filteredParameters->isEmpty() ? $filteredParameters->first() : null</code>
|
||||
</FalsableReturnStatement>
|
||||
@@ -273,8 +270,7 @@
|
||||
<code>getCacheFactory</code>
|
||||
<code>getTimestampRegion</code>
|
||||
</PossiblyNullReference>
|
||||
<RedundantConditionGivenDocblockType occurrences="2">
|
||||
<code>$result</code>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>assert($metadata instanceof ClassMetadata)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<UndefinedInterfaceMethod occurrences="9">
|
||||
@@ -503,10 +499,9 @@
|
||||
<code>$entityName</code>
|
||||
<code>$entityName</code>
|
||||
</ParamNameMismatch>
|
||||
<PossiblyNullArgument occurrences="3">
|
||||
<PossiblyNullArgument occurrences="2">
|
||||
<code>$config->getProxyDir()</code>
|
||||
<code>$config->getProxyNamespace()</code>
|
||||
<code>$entity</code>
|
||||
</PossiblyNullArgument>
|
||||
<PossiblyNullReference occurrences="2">
|
||||
<code>createCache</code>
|
||||
@@ -520,15 +515,16 @@
|
||||
<PropertyTypeCoercion occurrences="1">
|
||||
<code>new $metadataFactoryClassName()</code>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantCondition occurrences="1">
|
||||
<RedundantCondition occurrences="2">
|
||||
<code>is_object($connection)</code>
|
||||
<code>is_object($connection)</code>
|
||||
</RedundantCondition>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>$this->filterCollection !== null</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<TypeDoesNotContainType occurrences="2">
|
||||
<code>$connection instanceof Connection</code>
|
||||
<code>': "' . $connection . '"'</code>
|
||||
<code>gettype($connection)</code>
|
||||
</TypeDoesNotContainType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/EntityManagerInterface.php">
|
||||
@@ -606,9 +602,6 @@
|
||||
<PossiblyNullPropertyAssignmentValue occurrences="1">
|
||||
<code>$sequenceName</code>
|
||||
</PossiblyNullPropertyAssignmentValue>
|
||||
<RedundantCastGivenDocblockType occurrences="1">
|
||||
<code>(string) $em->getConnection()->lastInsertId($this->sequenceName)</code>
|
||||
</RedundantCastGivenDocblockType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Id/TableGenerator.php">
|
||||
<PossiblyFalseOperand occurrences="3">
|
||||
@@ -779,9 +772,7 @@
|
||||
</RedundantCastGivenDocblockType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Mapping/ClassMetadata.php">
|
||||
<PropertyNotSetInConstructor occurrences="8">
|
||||
<code>ClassMetadata</code>
|
||||
<code>ClassMetadata</code>
|
||||
<PropertyNotSetInConstructor occurrences="6">
|
||||
<code>ClassMetadata</code>
|
||||
<code>ClassMetadata</code>
|
||||
<code>ClassMetadata</code>
|
||||
@@ -823,13 +814,13 @@
|
||||
<DeprecatedConstant occurrences="1">
|
||||
<code>ClassMetadata::GENERATOR_TYPE_UUID</code>
|
||||
</DeprecatedConstant>
|
||||
<DeprecatedMethod occurrences="2">
|
||||
<DeprecatedMethod occurrences="3">
|
||||
<code>addNamedNativeQuery</code>
|
||||
<code>addNamedQuery</code>
|
||||
<code>getName</code>
|
||||
</DeprecatedMethod>
|
||||
<DocblockTypeContradiction occurrences="3">
|
||||
<code>! $class->reflClass</code>
|
||||
<code>$class->reflClass</code>
|
||||
<DocblockTypeContradiction occurrences="2">
|
||||
<code>! $definition</code>
|
||||
<code>$definition</code>
|
||||
</DocblockTypeContradiction>
|
||||
<InvalidArrayOffset occurrences="1">
|
||||
@@ -872,6 +863,9 @@
|
||||
<code>$parent->table</code>
|
||||
<code>$parent->versionField</code>
|
||||
</NoInterfaceProperties>
|
||||
<PossiblyInvalidArrayAssignment occurrences="1">
|
||||
<code>$subClass->table[$indexType][$indexName]</code>
|
||||
</PossiblyInvalidArrayAssignment>
|
||||
<PossiblyInvalidIterator occurrences="1">
|
||||
<code>$parentClass->table[$indexType]</code>
|
||||
</PossiblyInvalidIterator>
|
||||
@@ -894,7 +888,7 @@
|
||||
<code>$subClass->table</code>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantConditionGivenDocblockType occurrences="2">
|
||||
<code>$parent</code>
|
||||
<code>$parent->idGenerator</code>
|
||||
<code>$parent->idGenerator</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<UndefinedInterfaceMethod occurrences="17">
|
||||
@@ -925,13 +919,17 @@
|
||||
<DeprecatedConstant occurrences="1">
|
||||
<code>self::GENERATOR_TYPE_UUID</code>
|
||||
</DeprecatedConstant>
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>canEmulateSchemas</code>
|
||||
</DeprecatedMethod>
|
||||
<DeprecatedProperty occurrences="4">
|
||||
<code>$this->columnNames</code>
|
||||
<code>$this->columnNames</code>
|
||||
<code>$this->columnNames</code>
|
||||
<code>$this->columnNames</code>
|
||||
</DeprecatedProperty>
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<DocblockTypeContradiction occurrences="2">
|
||||
<code>! $this->table</code>
|
||||
<code>$this->table</code>
|
||||
</DocblockTypeContradiction>
|
||||
<InvalidDocblock occurrences="4">
|
||||
@@ -940,9 +938,10 @@
|
||||
<code>protected function _validateAndCompleteOneToOneMapping(array $mapping)</code>
|
||||
<code>public $inheritanceType = self::INHERITANCE_TYPE_NONE;</code>
|
||||
</InvalidDocblock>
|
||||
<InvalidNullableReturnType occurrences="2">
|
||||
<InvalidNullableReturnType occurrences="3">
|
||||
<code>ReflectionProperty</code>
|
||||
<code>ReflectionProperty</code>
|
||||
<code>getReflectionClass</code>
|
||||
</InvalidNullableReturnType>
|
||||
<InvalidPropertyAssignmentValue occurrences="1">
|
||||
<code>$definition</code>
|
||||
@@ -971,7 +970,8 @@
|
||||
<MoreSpecificReturnType occurrences="1">
|
||||
<code>array{usage: int, region: string|null}</code>
|
||||
</MoreSpecificReturnType>
|
||||
<NullableReturnStatement occurrences="2">
|
||||
<NullableReturnStatement occurrences="3">
|
||||
<code>$this->reflClass</code>
|
||||
<code>$this->reflFields[$name]</code>
|
||||
<code>$this->reflFields[$this->identifier[0]]</code>
|
||||
</NullableReturnStatement>
|
||||
@@ -991,12 +991,17 @@
|
||||
<code>$queryMapping['resultClass']</code>
|
||||
<code>$reflService->getAccessibleProperty($mapping['originalClass'], $mapping['originalField'])</code>
|
||||
</PossiblyNullArgument>
|
||||
<PossiblyNullPropertyAssignmentValue occurrences="3">
|
||||
<code>$reflService->getClass($this->name)</code>
|
||||
<code>$reflService->getClass($this->name)</code>
|
||||
<PossiblyNullPropertyAssignmentValue occurrences="1">
|
||||
<code>null</code>
|
||||
</PossiblyNullPropertyAssignmentValue>
|
||||
<PossiblyNullReference occurrences="6">
|
||||
<PossiblyNullPropertyFetch occurrences="2">
|
||||
<code>$embeddable->reflClass->name</code>
|
||||
<code>$this->reflClass->name</code>
|
||||
</PossiblyNullPropertyFetch>
|
||||
<PossiblyNullReference occurrences="9">
|
||||
<code>getProperty</code>
|
||||
<code>getProperty</code>
|
||||
<code>getProperty</code>
|
||||
<code>getValue</code>
|
||||
<code>getValue</code>
|
||||
<code>getValue</code>
|
||||
@@ -1017,12 +1022,10 @@
|
||||
<code>$this->fieldMappings[$idProperty]['columnName']</code>
|
||||
<code>$this->fieldMappings[$idProperty]['columnName']</code>
|
||||
</PossiblyUndefinedArrayOffset>
|
||||
<PropertyNotSetInConstructor occurrences="8">
|
||||
<code>$discriminatorColumn</code>
|
||||
<PropertyNotSetInConstructor occurrences="6">
|
||||
<code>$idGenerator</code>
|
||||
<code>$isVersioned</code>
|
||||
<code>$namespace</code>
|
||||
<code>$reflClass</code>
|
||||
<code>$sequenceGeneratorDefinition</code>
|
||||
<code>$table</code>
|
||||
<code>$tableGeneratorDefinition</code>
|
||||
@@ -1040,26 +1043,19 @@
|
||||
<code>$this->table</code>
|
||||
<code>$this->table</code>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantCast occurrences="1">
|
||||
<code>array_values</code>
|
||||
</RedundantCast>
|
||||
<RedundantConditionGivenDocblockType occurrences="3">
|
||||
<code>$className !== null</code>
|
||||
<code>$mapping !== false</code>
|
||||
<code>$mapping !== false</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<RedundantPropertyInitializationCheck occurrences="1"/>
|
||||
<TooManyArguments occurrences="2">
|
||||
<code>joinColumnName</code>
|
||||
<code>joinColumnName</code>
|
||||
</TooManyArguments>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Mapping/Column.php">
|
||||
<PossiblyNullPropertyAssignmentValue occurrences="5">
|
||||
<code>$columnDefinition</code>
|
||||
<code>$length</code>
|
||||
<code>$name</code>
|
||||
<code>$precision</code>
|
||||
<code>$scale</code>
|
||||
</PossiblyNullPropertyAssignmentValue>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Mapping/ColumnResult.php">
|
||||
<MissingConstructor occurrences="1">
|
||||
<code>$name</code>
|
||||
@@ -1088,6 +1084,10 @@
|
||||
</PossiblyFalseOperand>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Mapping/DefaultQuoteStrategy.php">
|
||||
<DeprecatedMethod occurrences="2">
|
||||
<code>canEmulateSchemas</code>
|
||||
<code>canEmulateSchemas</code>
|
||||
</DeprecatedMethod>
|
||||
<MissingClosureParamType occurrences="1">
|
||||
<code>$joinColumn</code>
|
||||
</MissingClosureParamType>
|
||||
@@ -1108,9 +1108,14 @@
|
||||
<ArgumentTypeCoercion occurrences="1">
|
||||
<code>$metadata</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<DocblockTypeContradiction occurrences="2">
|
||||
<code>! $class</code>
|
||||
<code>$class</code>
|
||||
</DocblockTypeContradiction>
|
||||
<LessSpecificReturnStatement occurrences="1">
|
||||
<code>$mapping</code>
|
||||
</LessSpecificReturnStatement>
|
||||
<MoreSpecificReturnType occurrences="1"/>
|
||||
<NoInterfaceProperties occurrences="5">
|
||||
<code>$metadata->inheritanceType</code>
|
||||
<code>$metadata->isEmbeddedClass</code>
|
||||
@@ -1125,10 +1130,6 @@
|
||||
<code>$primaryTable['indexes']</code>
|
||||
<code>$primaryTable['uniqueConstraints']</code>
|
||||
</PossiblyUndefinedArrayOffset>
|
||||
<RedundantConditionGivenDocblockType occurrences="2">
|
||||
<code>isset($column->columnDefinition)</code>
|
||||
<code>isset($column->name)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<UndefinedInterfaceMethod occurrences="32">
|
||||
<code>addEntityListener</code>
|
||||
<code>addLifecycleCallback</code>
|
||||
@@ -1177,6 +1178,10 @@
|
||||
<code>$value[1]</code>
|
||||
<code>$value[1]</code>
|
||||
</InvalidArrayAccess>
|
||||
<LessSpecificReturnStatement occurrences="1">
|
||||
<code>$mapping</code>
|
||||
</LessSpecificReturnStatement>
|
||||
<MoreSpecificReturnType occurrences="1"/>
|
||||
<NonInvariantDocblockPropertyType occurrences="1">
|
||||
<code>$entityAnnotationClasses</code>
|
||||
</NonInvariantDocblockPropertyType>
|
||||
@@ -1193,10 +1198,8 @@
|
||||
<code>assert($method instanceof ReflectionMethod)</code>
|
||||
<code>assert($property instanceof ReflectionProperty)</code>
|
||||
</RedundantCondition>
|
||||
<RedundantConditionGivenDocblockType occurrences="3">
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>assert($cacheAttribute instanceof Mapping\Cache)</code>
|
||||
<code>isset($column->columnDefinition)</code>
|
||||
<code>isset($column->name)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php">
|
||||
@@ -1291,11 +1294,7 @@
|
||||
<code>$indexXml->options</code>
|
||||
<code>$uniqueXml->options</code>
|
||||
</PossiblyInvalidPropertyFetch>
|
||||
<RedundantCast occurrences="1">
|
||||
<code>(string) $attributes->name</code>
|
||||
</RedundantCast>
|
||||
<RedundantCondition occurrences="20">
|
||||
<code>isset($attributes->name)</code>
|
||||
<RedundantCondition occurrences="19">
|
||||
<code>isset($xmlRoot->cache)</code>
|
||||
<code>isset($xmlRoot->embedded)</code>
|
||||
<code>isset($xmlRoot->field)</code>
|
||||
@@ -1587,16 +1586,7 @@
|
||||
<InvalidDocblock occurrences="1">
|
||||
<code>final class PersistentCollection extends AbstractLazyCollection implements Selectable</code>
|
||||
</InvalidDocblock>
|
||||
<InvalidReturnStatement occurrences="5">
|
||||
<code>$persister->slice($this, $offset, $length)</code>
|
||||
<code>$this->collection</code>
|
||||
<code>new ArrayCollection($persister->loadCriteria($this, $criteria))</code>
|
||||
<code>parent::slice($offset, $length)</code>
|
||||
</InvalidReturnStatement>
|
||||
<InvalidReturnType occurrences="2">
|
||||
<code>Collection<TKey, T></code>
|
||||
<code>array<TKey,T></code>
|
||||
</InvalidReturnType>
|
||||
<InvalidReturnStatement occurrences="1"/>
|
||||
<MissingParamType occurrences="2">
|
||||
<code>$key</code>
|
||||
<code>$offset</code>
|
||||
@@ -1631,7 +1621,9 @@
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$backRefFieldName</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<RedundantConditionGivenDocblockType occurrences="3">
|
||||
<RedundantConditionGivenDocblockType occurrences="5">
|
||||
<code>$this->em</code>
|
||||
<code>$this->em</code>
|
||||
<code>is_object($this->collection)</code>
|
||||
<code>is_object($value) && $this->em</code>
|
||||
<code>is_object($value) && $this->em</code>
|
||||
@@ -1857,9 +1849,6 @@
|
||||
<PropertyTypeCoercion occurrences="1">
|
||||
<code>$this->currentPersisterContext->sqlTableAliases</code>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantCondition occurrences="1">
|
||||
<code>($comparison === Comparison::EQ || $comparison === Comparison::IS) && $value === null</code>
|
||||
</RedundantCondition>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>$this->insertSql !== null</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
@@ -1900,11 +1889,6 @@
|
||||
<code>$columnList</code>
|
||||
</PossiblyUndefinedVariable>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Persisters/SqlValueVisitor.php">
|
||||
<RedundantCondition occurrences="1">
|
||||
<code>($operator === Comparison::EQ || $operator === Comparison::IS) && $value === null</code>
|
||||
</RedundantCondition>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Proxy/ProxyFactory.php">
|
||||
<ArgumentTypeCoercion occurrences="2">
|
||||
<code>$classMetadata</code>
|
||||
@@ -1973,9 +1957,6 @@
|
||||
<code>$queryCacheTTL</code>
|
||||
<code>Query</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<RedundantCastGivenDocblockType occurrences="1">
|
||||
<code>(int) $timeToLive</code>
|
||||
</RedundantCastGivenDocblockType>
|
||||
<RedundantConditionGivenDocblockType occurrences="4">
|
||||
<code>$dqlQuery !== null</code>
|
||||
<code>$rsm !== null</code>
|
||||
@@ -2203,6 +2184,9 @@
|
||||
<ArgumentTypeCoercion occurrences="1">
|
||||
<code>$this->stringPrimary</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>getLowerExpression</code>
|
||||
</DeprecatedMethod>
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$stringPrimary</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
@@ -2232,6 +2216,9 @@
|
||||
</PropertyNotSetInConstructor>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php">
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>getSqrtExpression</code>
|
||||
</DeprecatedMethod>
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$simpleArithmeticExpression</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
@@ -2270,6 +2257,9 @@
|
||||
<ArgumentTypeCoercion occurrences="1">
|
||||
<code>$this->stringPrimary</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DeprecatedMethod occurrences="1">
|
||||
<code>getUpperExpression</code>
|
||||
</DeprecatedMethod>
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$stringPrimary</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
@@ -2636,16 +2626,9 @@
|
||||
<code>call_user_func($functionClass, $functionName)</code>
|
||||
<code>call_user_func($functionClass, $functionName)</code>
|
||||
</DocblockTypeContradiction>
|
||||
<InvalidArrayOffset occurrences="2">
|
||||
<code>$this->identVariableExpressions[$dqlAlias]</code>
|
||||
<code>$this->queryComponents[$dqlAlias]</code>
|
||||
</InvalidArrayOffset>
|
||||
<InvalidNullableReturnType occurrences="1">
|
||||
<code>SelectStatement|UpdateStatement|DeleteStatement</code>
|
||||
</InvalidNullableReturnType>
|
||||
<InvalidPropertyAssignmentValue occurrences="1">
|
||||
<code>$this->identVariableExpressions</code>
|
||||
</InvalidPropertyAssignmentValue>
|
||||
<InvalidReturnStatement occurrences="9">
|
||||
<code>$primary</code>
|
||||
<code>$this->CollectionMemberExpression()</code>
|
||||
@@ -2850,27 +2833,36 @@
|
||||
<code>$renameMode</code>
|
||||
<code>$renameMode</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<PossiblyNullPropertyFetch occurrences="1">
|
||||
<code>$classMetadata->reflClass->name</code>
|
||||
</PossiblyNullPropertyFetch>
|
||||
<PossiblyNullReference occurrences="3">
|
||||
<code>getShortName</code>
|
||||
<code>getShortName</code>
|
||||
<code>getShortName</code>
|
||||
</PossiblyNullReference>
|
||||
<PossiblyUndefinedArrayOffset occurrences="1">
|
||||
<code>$class->fieldMappings[$this->fieldMappings[$columnName]]['columnName']</code>
|
||||
</PossiblyUndefinedArrayOffset>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Query/SqlWalker.php">
|
||||
<DocblockTypeContradiction occurrences="10">
|
||||
<code>! ($factor instanceof AST\ConditionalFactor)</code>
|
||||
<code>$condExpr instanceof AST\ConditionalExpression</code>
|
||||
<code>$condTerm instanceof AST\ConditionalTerm</code>
|
||||
<code>$simpleArithmeticExpr instanceof AST\SimpleArithmeticExpression</code>
|
||||
<DocblockTypeContradiction occurrences="8">
|
||||
<code>$likeExpr->stringPattern instanceof AST\Functions\FunctionNode</code>
|
||||
<code>$likeExpr->stringPattern instanceof AST\PathExpression</code>
|
||||
<code>$this->queryComponents[$dqlAlias]['relation'] === null</code>
|
||||
<code>''</code>
|
||||
<code>is_numeric($leftExpr) ? $leftExpr : $this->conn->quote($leftExpr)</code>
|
||||
<code>is_numeric($rightExpr) ? $rightExpr : $this->conn->quote($rightExpr)</code>
|
||||
<code>is_numeric($leftExpr)</code>
|
||||
<code>is_numeric($rightExpr)</code>
|
||||
<code>is_string($expression)</code>
|
||||
<code>is_string($stringExpr)</code>
|
||||
</DocblockTypeContradiction>
|
||||
<ImplicitToStringCast occurrences="1">
|
||||
<code>$expr</code>
|
||||
</ImplicitToStringCast>
|
||||
<InvalidArgument occurrences="1">
|
||||
<InvalidArgument occurrences="4">
|
||||
<code>$condExpr</code>
|
||||
<code>$condTerm</code>
|
||||
<code>$factor</code>
|
||||
<code>$selectedClass['class']->name</code>
|
||||
</InvalidArgument>
|
||||
<InvalidArrayOffset occurrences="1">
|
||||
@@ -2941,10 +2933,12 @@
|
||||
<code>$this->queryComponents</code>
|
||||
<code>$this->selectedClasses</code>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantConditionGivenDocblockType occurrences="5">
|
||||
<RedundantConditionGivenDocblockType occurrences="7">
|
||||
<code>$leftExpr instanceof AST\Node</code>
|
||||
<code>$likeExpr->stringPattern instanceof AST\InputParameter</code>
|
||||
<code>$rightExpr instanceof AST\Node</code>
|
||||
<code>$this->conn->quote($leftExpr)</code>
|
||||
<code>$this->conn->quote($rightExpr)</code>
|
||||
<code>$whereClause !== null</code>
|
||||
<code>($factor->not ? 'NOT ' : '') . $this->walkConditionalPrimary($factor->conditionalPrimary)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
@@ -3239,10 +3233,9 @@
|
||||
<NullableReturnStatement occurrences="1">
|
||||
<code>$this->cacheMode</code>
|
||||
</NullableReturnStatement>
|
||||
<PossiblyFalseArgument occurrences="3">
|
||||
<PossiblyFalseArgument occurrences="2">
|
||||
<code>$spacePos</code>
|
||||
<code>$spacePos</code>
|
||||
<code>strpos($join, '.')</code>
|
||||
</PossiblyFalseArgument>
|
||||
<PossiblyFalseOperand occurrences="2">
|
||||
<code>$spacePos</code>
|
||||
@@ -3258,13 +3251,6 @@
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$_dql</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<RedundantCastGivenDocblockType occurrences="5">
|
||||
<code>(bool) $cacheable</code>
|
||||
<code>(bool) $flag</code>
|
||||
<code>(int) $cacheMode</code>
|
||||
<code>(int) $lifetime</code>
|
||||
<code>(string) $cacheRegion</code>
|
||||
</RedundantCastGivenDocblockType>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>$this->_dql !== null</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
@@ -3315,13 +3301,9 @@
|
||||
<MissingReturnType occurrences="1">
|
||||
<code>configure</code>
|
||||
</MissingReturnType>
|
||||
<PossiblyNullArgument occurrences="2">
|
||||
<code>$cacheDriver</code>
|
||||
<PossiblyNullArgument occurrences="1">
|
||||
<code>$cacheDriver</code>
|
||||
</PossiblyNullArgument>
|
||||
<PossiblyNullReference occurrences="1">
|
||||
<code>deleteAll</code>
|
||||
</PossiblyNullReference>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php">
|
||||
<ArgumentTypeCoercion occurrences="1">
|
||||
@@ -3352,9 +3334,6 @@
|
||||
<code>new ClassMetadataExporter()</code>
|
||||
<code>new EntityGenerator()</code>
|
||||
</DeprecatedClass>
|
||||
<InvalidNullableReturnType occurrences="1">
|
||||
<code>int</code>
|
||||
</InvalidNullableReturnType>
|
||||
<MissingReturnType occurrences="1">
|
||||
<code>configure</code>
|
||||
</MissingReturnType>
|
||||
@@ -3494,10 +3473,8 @@
|
||||
<DeprecatedConstant occurrences="1">
|
||||
<code>ClassMetadataInfo::GENERATOR_TYPE_UUID</code>
|
||||
</DeprecatedConstant>
|
||||
<DocblockTypeContradiction occurrences="3">
|
||||
<code>$metadata->reflClass !== null</code>
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<code>class_exists($metadata->name)</code>
|
||||
<code>new ReflectionClass($metadata->name)</code>
|
||||
</DocblockTypeContradiction>
|
||||
<InvalidDocblock occurrences="1">
|
||||
<code>public function setFieldVisibility($visibility)</code>
|
||||
@@ -3523,12 +3500,13 @@
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$classToExtend</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<RedundantCastGivenDocblockType occurrences="1">
|
||||
<RedundantCastGivenDocblockType occurrences="2">
|
||||
<code>(array) $metadata->table['options']</code>
|
||||
<code>(bool) $embeddablesImmutable</code>
|
||||
</RedundantCastGivenDocblockType>
|
||||
<RedundantConditionGivenDocblockType occurrences="3">
|
||||
<code>$metadata->reflClass</code>
|
||||
<code>$metadata->reflClass !== null</code>
|
||||
<code>$metadata->sequenceGeneratorDefinition</code>
|
||||
<code>$metadata->sequenceGeneratorDefinition</code>
|
||||
<code>isset($metadata->lifecycleCallbacks)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
</file>
|
||||
@@ -3538,15 +3516,9 @@
|
||||
<code>$fullClassName</code>
|
||||
<code>$fullClassName</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<code>EntityRepository::class</code>
|
||||
</DocblockTypeContradiction>
|
||||
<PossiblyFalseOperand occurrences="1">
|
||||
<code>strrpos($fullClassName, '\\')</code>
|
||||
</PossiblyFalseOperand>
|
||||
<PropertyNotSetInConstructor occurrences="1">
|
||||
<code>$repositoryName</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<PropertyTypeCoercion occurrences="1">
|
||||
<code>$repositoryName</code>
|
||||
</PropertyTypeCoercion>
|
||||
@@ -3609,6 +3581,10 @@
|
||||
<NonInvariantDocblockPropertyType occurrences="1">
|
||||
<code>$_extension</code>
|
||||
</NonInvariantDocblockPropertyType>
|
||||
<RedundantConditionGivenDocblockType occurrences="2">
|
||||
<code>$metadata->table</code>
|
||||
<code>$metadata->table</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php">
|
||||
<ArgumentTypeCoercion occurrences="3">
|
||||
@@ -3635,10 +3611,12 @@
|
||||
<PossiblyNullReference occurrences="1">
|
||||
<code>addAttribute</code>
|
||||
</PossiblyNullReference>
|
||||
<RedundantCondition occurrences="1">
|
||||
<RedundantCondition occurrences="2">
|
||||
<code>$field['associationKey']</code>
|
||||
<code>isset($field['associationKey']) && $field['associationKey']</code>
|
||||
</RedundantCondition>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<RedundantConditionGivenDocblockType occurrences="2">
|
||||
<code>$sequenceDefinition</code>
|
||||
<code>isset($metadata->lifecycleCallbacks)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
</file>
|
||||
@@ -3675,6 +3653,10 @@
|
||||
</RedundantConditionGivenDocblockType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php">
|
||||
<DeprecatedMethod occurrences="2">
|
||||
<code>getCountExpression</code>
|
||||
<code>getCountExpression</code>
|
||||
</DeprecatedMethod>
|
||||
<MoreSpecificImplementedParamType occurrences="1">
|
||||
<code>$query</code>
|
||||
</MoreSpecificImplementedParamType>
|
||||
@@ -3728,7 +3710,8 @@
|
||||
</PropertyNotSetInConstructor>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php">
|
||||
<DocblockTypeContradiction occurrences="2">
|
||||
<DocblockTypeContradiction occurrences="3">
|
||||
<code>$AST->whereClause->conditionalExpression instanceof ConditionalFactor</code>
|
||||
<code>$AST->whereClause->conditionalExpression instanceof ConditionalPrimary</code>
|
||||
</DocblockTypeContradiction>
|
||||
<ImplementedReturnTypeMismatch occurrences="1">
|
||||
@@ -3740,12 +3723,16 @@
|
||||
<PossiblyInvalidPropertyAssignmentValue occurrences="1">
|
||||
<code>$AST->whereClause->conditionalExpression</code>
|
||||
</PossiblyInvalidPropertyAssignmentValue>
|
||||
<RedundantConditionGivenDocblockType occurrences="1">
|
||||
<code>$AST->whereClause->conditionalExpression instanceof ConditionalExpression</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<RedundantConditionGivenDocblockType occurrences="1"/>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/SchemaTool.php">
|
||||
<DocblockTypeContradiction occurrences="1">
|
||||
<DeprecatedMethod occurrences="3">
|
||||
<code>canEmulateSchemas</code>
|
||||
<code>compare</code>
|
||||
<code>setExplicitForeignKeyIndexes</code>
|
||||
</DeprecatedMethod>
|
||||
<DocblockTypeContradiction occurrences="2">
|
||||
<code>! $definingClass</code>
|
||||
<code>$definingClass</code>
|
||||
</DocblockTypeContradiction>
|
||||
<MissingClosureParamType occurrences="1">
|
||||
@@ -3773,6 +3760,11 @@
|
||||
<code>$indexName</code>
|
||||
</TypeDoesNotContainType>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/SchemaValidator.php">
|
||||
<PossiblyNullReference occurrences="1">
|
||||
<code>isAbstract</code>
|
||||
</PossiblyNullReference>
|
||||
</file>
|
||||
<file src="lib/Doctrine/ORM/Tools/Setup.php">
|
||||
<DeprecatedClass occurrences="3">
|
||||
<code>new ClassLoader('Doctrine', $directory)</code>
|
||||
@@ -3877,7 +3869,8 @@
|
||||
<code>setValue</code>
|
||||
<code>setValue</code>
|
||||
</PossiblyNullReference>
|
||||
<PossiblyUndefinedMethod occurrences="3">
|
||||
<PossiblyUndefinedMethod occurrences="4">
|
||||
<code>addPropertyChangedListener</code>
|
||||
<code>unwrap</code>
|
||||
<code>unwrap</code>
|
||||
<code>unwrap</code>
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
<!-- We're calling the deprecated method for BC here. -->
|
||||
<file name="lib/Doctrine/ORM/Internal/SQLResultCasing.php"/>
|
||||
<!-- We need to keep the calls for DBAL 2.13 compatibility. -->
|
||||
<referencedMethod name="Doctrine\DBAL\Cache\QueryCacheProfile::getResultCacheDriver"/>
|
||||
<referencedMethod name="Doctrine\DBAL\Cache\QueryCacheProfile::setResultCacheDriver"/>
|
||||
<referencedMethod name="Doctrine\DBAL\Configuration::getResultCacheImpl"/>
|
||||
<referencedMethod name="Doctrine\DBAL\Configuration::setResultCacheImpl"/>
|
||||
<referencedMethod name="Doctrine\DBAL\Connection::getSchemaManager"/>
|
||||
<referencedMethod name="Doctrine\DBAL\Platforms\AbstractPlatform::getGuidExpression"/>
|
||||
</errorLevel>
|
||||
@@ -83,6 +87,13 @@
|
||||
<file name="lib/Doctrine/ORM/QueryBuilder.php"/>
|
||||
</errorLevel>
|
||||
</RedundantCastGivenDocblockType>
|
||||
<!-- Workaround for https://github.com/vimeo/psalm/issues/7026 -->
|
||||
<ReservedWord>
|
||||
<errorLevel type="suppress">
|
||||
<directory name="lib"/>
|
||||
<directory name="tests"/>
|
||||
</errorLevel>
|
||||
</ReservedWord>
|
||||
<TypeDoesNotContainType>
|
||||
<errorLevel type="suppress">
|
||||
<file name="lib/Doctrine/ORM/Internal/SQLResultCasing.php"/>
|
||||
|
||||
@@ -17,16 +17,14 @@ abstract class GetMetadata
|
||||
{
|
||||
/**
|
||||
* @param string|object $class
|
||||
* @phpstan-param class-string|object $class
|
||||
* @psalm-param class-string|object $class
|
||||
*/
|
||||
abstract public function getEntityManager($class): EntityManagerInterface;
|
||||
|
||||
/**
|
||||
* @psalm-param class-string<TObject> $class
|
||||
* @phpstan-param class-string $class
|
||||
*
|
||||
* @psalm-return ClassMetadata<TObject>
|
||||
* @phpstan-return ClassMetadata<object>
|
||||
*
|
||||
* @psalm-template TObject of object
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Tests\IterableTester;
|
||||
use Doctrine\Tests\Models\CMS\CmsAddress;
|
||||
use Doctrine\Tests\Models\CMS\CmsArticle;
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
@@ -68,4 +69,48 @@ final class QueryIterableTest extends OrmFunctionalTestCase
|
||||
|
||||
IterableTester::assertResultsAreTheSame($query);
|
||||
}
|
||||
|
||||
public function testIndexByQueryWithOneResult(): void
|
||||
{
|
||||
$user = new CmsUser();
|
||||
$user->name = 'Antonio J.';
|
||||
$user->username = 'ajgarlag';
|
||||
$user->status = 'developer';
|
||||
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
$query = $this->_em->createQuery('SELECT u FROM ' . CmsUser::class . ' u INDEX BY u.username');
|
||||
IterableTester::assertResultsAreTheSame($query);
|
||||
}
|
||||
|
||||
public function testIndexByQueryWithMultipleResults(): void
|
||||
{
|
||||
$article1 = new CmsArticle();
|
||||
$article1->topic = 'Doctrine 2';
|
||||
$article1->text = 'This is an introduction to Doctrine 2.';
|
||||
|
||||
$article2 = new CmsArticle();
|
||||
$article2->topic = 'Symfony 2';
|
||||
$article2->text = 'This is an introduction to Symfony 2.';
|
||||
|
||||
$article3 = new CmsArticle();
|
||||
$article3->topic = 'Laminas';
|
||||
$article3->text = 'This is an introduction to Laminas.';
|
||||
|
||||
$article4 = new CmsArticle();
|
||||
$article4->topic = 'CodeIgniter';
|
||||
$article4->text = 'This is an introduction to CodeIgniter.';
|
||||
|
||||
$this->_em->persist($article1);
|
||||
$this->_em->persist($article2);
|
||||
$this->_em->persist($article3);
|
||||
$this->_em->persist($article4);
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$query = $this->_em->createQuery('select a from ' . CmsArticle::class . ' a INDEX BY a.topic');
|
||||
IterableTester::assertResultsAreTheSame($query);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,9 +239,7 @@ class SecondLevelCacheManyToOneTest extends SecondLevelCacheAbstractTest
|
||||
self::assertFalse($this->cache->containsEntity(Action::class, $action3->name));
|
||||
|
||||
$queryCount = $this->getCurrentQueryCount();
|
||||
/**
|
||||
* @var $entity Token
|
||||
*/
|
||||
|
||||
$entity = $this->_em->find(Token::class, $token->token);
|
||||
|
||||
self::assertInstanceOf(Token::class, $entity);
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\Mapping\Column;
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
use Doctrine\ORM\Mapping\GeneratedValue;
|
||||
use Doctrine\ORM\Mapping\Id;
|
||||
use Doctrine\ORM\Mapping\ManyToMany;
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
/**
|
||||
* @group GH-9109
|
||||
*/
|
||||
class GH9109Test extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema(
|
||||
[
|
||||
$this->_em->getClassMetadata(GH9109User::class),
|
||||
$this->_em->getClassMetadata(GH9109Product::class),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$this->_schemaTool->dropSchema(
|
||||
[
|
||||
$this->_em->getClassMetadata(GH9109User::class),
|
||||
$this->_em->getClassMetadata(GH9109Product::class),
|
||||
]
|
||||
);
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testIssue(): void
|
||||
{
|
||||
$userFirstName = 'GH9109Test';
|
||||
$userLastName = 'UserGH9109';
|
||||
$productTitle = 'Test product';
|
||||
|
||||
$userRepository = $this->_em->getRepository(GH9109User::class);
|
||||
|
||||
$user = new GH9109User();
|
||||
$user->setFirstName($userFirstName);
|
||||
$user->setLastName($userLastName);
|
||||
|
||||
$product = new GH9109Product();
|
||||
$product->setTitle($productTitle);
|
||||
|
||||
$this->_em->persist($user);
|
||||
$this->_em->persist($product);
|
||||
$this->_em->flush();
|
||||
|
||||
$product->addBuyer($user);
|
||||
|
||||
$this->_em->persist($product);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
$persistedProduct = $this->_em->find(GH9109Product::class, $product->getId());
|
||||
|
||||
// assert Product was persisted
|
||||
self::assertInstanceOf(GH9109Product::class, $persistedProduct);
|
||||
self::assertEquals($productTitle, $persistedProduct->getTitle());
|
||||
|
||||
// assert Product has a Buyer
|
||||
$count = $persistedProduct->getBuyers()->count();
|
||||
self::assertEquals(1, $count);
|
||||
|
||||
// assert NOT QUOTED will WORK with findOneBy
|
||||
$user = $userRepository->findOneBy(['lastName' => $userLastName]);
|
||||
self::assertInstanceOf(GH9109User::class, $user);
|
||||
self::assertEquals($userLastName, $user->getLastName());
|
||||
|
||||
// assert NOT QUOTED will WORK with Criteria
|
||||
$criteria = Criteria::create();
|
||||
$criteria->where($criteria->expr()->eq('lastName', $userLastName));
|
||||
$user = $persistedProduct->getBuyers()->matching($criteria)->first();
|
||||
self::assertInstanceOf(GH9109User::class, $user);
|
||||
self::assertEquals($userLastName, $user->getLastName());
|
||||
|
||||
// assert QUOTED will WORK with findOneBy
|
||||
$user = $userRepository->findOneBy(['firstName' => $userFirstName]);
|
||||
self::assertInstanceOf(GH9109User::class, $user);
|
||||
self::assertEquals($userFirstName, $user->getFirstName());
|
||||
|
||||
// assert QUOTED will WORK with Criteria
|
||||
$criteria = Criteria::create();
|
||||
$criteria->where($criteria->expr()->eq('firstName', $userFirstName));
|
||||
$user = $persistedProduct->getBuyers()->matching($criteria)->first();
|
||||
self::assertInstanceOf(GH9109User::class, $user);
|
||||
self::assertEquals($userFirstName, $user->getFirstName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class GH9109Product
|
||||
{
|
||||
/**
|
||||
* @var int $id
|
||||
* @Column(name="`id`", type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string $title
|
||||
* @Column(name="`title`", type="string", length=255)
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @var Collection|GH9109User[]
|
||||
* @psalm-var Collection<int, GH9109User>
|
||||
* @ManyToMany(targetEntity="GH9109User")
|
||||
*/
|
||||
private $buyers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->buyers = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setTitle(string $title): void
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-return Collection<int, GH9109User>
|
||||
*/
|
||||
public function getBuyers(): Collection
|
||||
{
|
||||
return $this->buyers;
|
||||
}
|
||||
|
||||
public function addBuyer(GH9109User $buyer): void
|
||||
{
|
||||
$this->buyers[] = $buyer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class GH9109User
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
* @Column(name="`id`", type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @Column(name="`first_name`", type="string")
|
||||
*/
|
||||
private $firstName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @Column(name="last_name", type="string")
|
||||
*/
|
||||
private $lastName;
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getFirstName(): string
|
||||
{
|
||||
return $this->firstName;
|
||||
}
|
||||
|
||||
public function setFirstName(string $firstName): void
|
||||
{
|
||||
$this->firstName = $firstName;
|
||||
}
|
||||
|
||||
public function getLastName(): string
|
||||
{
|
||||
return $this->lastName;
|
||||
}
|
||||
|
||||
public function setLastName(string $lastName): void
|
||||
{
|
||||
$this->lastName = $lastName;
|
||||
}
|
||||
}
|
||||
@@ -1119,6 +1119,13 @@ abstract class AbstractMappingDriverTest extends OrmTestCase
|
||||
$class = $this->createClassMetadata(SingleTableEntityIncompleteDiscriminatorColumnMapping::class);
|
||||
self::assertEquals('dtype', $class->discriminatorColumn['name']);
|
||||
}
|
||||
|
||||
public function testReservedWordInTableColumn(): void
|
||||
{
|
||||
$metadata = $this->createClassMetadata(ReservedWordInTableColumn::class);
|
||||
|
||||
self::assertSame('count', $metadata->getFieldMapping('count')['columnName']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1774,3 +1781,42 @@ class SingleTableEntityIncompleteDiscriminatorColumnMappingSub1 extends SingleTa
|
||||
class SingleTableEntityIncompleteDiscriminatorColumnMappingSub2 extends SingleTableEntityIncompleteDiscriminatorColumnMapping
|
||||
{
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
#[ORM\Entity]
|
||||
class ReservedWordInTableColumn
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
* @GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
#[ORM\Id, ORM\Column(type: 'integer'), ORM\GeneratedValue(strategy: 'NONE')]
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
* @Column(name="`count`", type="integer")
|
||||
*/
|
||||
#[ORM\Column(name: '`count`', type: 'integer')]
|
||||
public $count;
|
||||
|
||||
public static function loadMetadata(ClassMetadataInfo $metadata): void
|
||||
{
|
||||
$metadata->mapField(
|
||||
[
|
||||
'id' => true,
|
||||
'fieldName' => 'id',
|
||||
'type' => 'integer',
|
||||
]
|
||||
);
|
||||
$metadata->mapField(
|
||||
[
|
||||
'fieldName' => 'count',
|
||||
'type' => 'integer',
|
||||
'columnName' => '`count`',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$metadata->mapField(
|
||||
[
|
||||
'id' => true,
|
||||
'fieldName' => 'id',
|
||||
'type' => 'integer',
|
||||
]
|
||||
);
|
||||
$metadata->mapField(
|
||||
[
|
||||
'fieldName' => 'count',
|
||||
'type' => 'integer',
|
||||
'columnName' => '`count`',
|
||||
]
|
||||
);
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
|
||||
|
||||
<entity name="Doctrine\Tests\ORM\Mapping\ReservedWordInTableColumn">
|
||||
|
||||
<id name="id" type="integer" column="id">
|
||||
<generator strategy="NONE"/>
|
||||
</id>
|
||||
|
||||
<field name="count" column="`count`" type="integer"/>
|
||||
|
||||
</entity>
|
||||
|
||||
</doctrine-mapping>
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
Doctrine\Tests\ORM\Mapping\ReservedWordInTableColumn:
|
||||
type: entity
|
||||
id:
|
||||
id:
|
||||
generator:
|
||||
strategy: NONE
|
||||
fields:
|
||||
count:
|
||||
type: integer
|
||||
column: '`count`'
|
||||
@@ -76,7 +76,7 @@ class SelectSqlGenerationTest extends OrmTestCase
|
||||
parent::assertEquals(
|
||||
$sqlToBeConfirmed,
|
||||
$sqlGenerated,
|
||||
sprintf('"%s" is not equal of "%s"', $sqlGenerated, $sqlToBeConfirmed)
|
||||
sprintf('"%s" is not equal to "%s"', $sqlGenerated, $sqlToBeConfirmed)
|
||||
);
|
||||
|
||||
$query->free();
|
||||
@@ -2116,26 +2116,6 @@ class SelectSqlGenerationTest extends OrmTestCase
|
||||
'SELECT CONCAT(c0_.id, c0_.name, c0_.status) AS sclr_0 FROM cms_users c0_ WHERE c0_.id = ?'
|
||||
);
|
||||
|
||||
$connMock->setDatabasePlatform(new PostgreSQL94Platform());
|
||||
$this->assertSqlGeneration(
|
||||
"SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
|
||||
"SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE c0_.name || c0_.status || 's' = ?"
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
|
||||
'SELECT c0_.id || c0_.name || c0_.status AS sclr_0 FROM cms_users c0_ WHERE c0_.id = ?'
|
||||
);
|
||||
|
||||
$connMock->setDatabasePlatform(new SQLServer2012Platform());
|
||||
$this->assertSqlGeneration(
|
||||
"SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
|
||||
"SELECT c0_.id AS id_0 FROM cms_users c0_ WHERE (c0_.name + c0_.status + 's') = ?"
|
||||
);
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
|
||||
'SELECT (c0_.id + c0_.name + c0_.status) AS sclr_0 FROM cms_users c0_ WHERE c0_.id = ?'
|
||||
);
|
||||
|
||||
$connMock->setDatabasePlatform($orgPlatform);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,23 +58,12 @@ abstract class OrmTestCase extends DoctrineTestCase
|
||||
/** @var Cache|null */
|
||||
protected $secondLevelCacheDriverImpl = null;
|
||||
|
||||
/**
|
||||
* @param mixed $alias
|
||||
*/
|
||||
protected function createAnnotationDriver(array $paths = [], $alias = null): AnnotationDriver
|
||||
protected function createAnnotationDriver(array $paths = []): AnnotationDriver
|
||||
{
|
||||
// Register the ORM Annotations in the AnnotationRegistry
|
||||
$reader = new Annotations\AnnotationReader();
|
||||
|
||||
if (class_exists(Annotations\PsrCachedReader::class)) {
|
||||
$reader = new Annotations\PsrCachedReader($reader, new ArrayAdapter());
|
||||
} else {
|
||||
$reader = new Annotations\CachedReader($reader, DoctrineProvider::wrap(new ArrayAdapter()));
|
||||
}
|
||||
|
||||
Annotations\AnnotationRegistry::registerFile(__DIR__ . '/../../../lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php');
|
||||
|
||||
return new AnnotationDriver($reader, (array) $paths);
|
||||
return new AnnotationDriver(
|
||||
new Annotations\PsrCachedReader(new Annotations\AnnotationReader(), new ArrayAdapter()),
|
||||
$paths
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user