Compare commits

...

992 Commits

Author SHA1 Message Date
flack
9c351e0444 Make sure MemcachedAdapter is supported before tring to use it (#9574) 2022-03-09 16:23:58 +01:00
Thomas Landauer
5ed5383338 Fixing :doc: link (#9569) 2022-03-08 22:31:56 +01:00
Thomas Landauer
eb1d54871b Adding PHP attributes (#9555)
Co-authored-by: Alexander M. Turek <me@derrabus.de>
Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
2022-03-08 01:40:01 +01:00
Grégoire Paris
e148c838b0 Merge pull request #9563 from greg0ire/address-sqllogger-deprecation
Remove reference to removed class
2022-03-03 22:27:51 +01:00
Grégoire Paris
c73df2a7b4 Remove reference to removed class
EchoSQLLogger is deprecated in DBAL 2, and removed in DBAL 3.
2022-03-03 22:12:04 +01:00
Jan Barášek
38682e93db Parser: SimpleArithmeticExpression should return ArithmeticTerm (#9557) 2022-03-03 00:25:27 +01:00
Alexander M. Turek
84df37de97 Update baselines for Lexer 1.2.3 (#9546) 2022-02-28 14:06:31 +01:00
Grégoire Paris
856c3143f8 Merge pull request #9537 from kiler129/fix-bug-9536
Make error message suggestion accurate
2022-02-22 20:08:49 +01:00
kiler129
79f73a23f3 Fix bug-#9536
Wrong validation message is displayed when an incorrect bidirectional
bi-directional mapping is set up. When the owning side is configured
correctly and the target side is missing the back reference, the ORM
suggests adding inverseBy instead of mappedBy, with the field name
missing. This commit fixes this problem.
2022-02-22 12:05:35 -06:00
Grégoire Paris
4af912f712 Merge pull request #9539 from greg0ire/use-stable-dbal
Drop minor version number
2022-02-22 18:01:26 +01:00
Grégoire Paris
65f48e0ecd Drop minor version number
We should make it explicit that we mean to test with whatever is the
latest 3.x
2022-02-22 17:25:21 +01:00
Matthias Pigulla
193c3abf0e Bring FilterCollection to a "clean" state after hash computation (#9523)
Co-authored-by: Alexander M. Turek <me@derrabus.de>
2022-02-20 13:09:05 +00:00
Grégoire Paris
5b8263e8fb Merge pull request #9526 from greg0ire/better-model-setup
Make creating test models more straightforward and revert to swallowing exceptions
2022-02-20 09:35:21 +01:00
Grégoire Paris
26e85b8c88 Make creating test models more straightforward
In https://github.com/doctrine/orm/pull/8962, I established that
swallowing exceptions while creating model was bad because it could hide
other helpful exceptions.
As it turns out however, swallowing exceptions is really the way to go
here, because of the performance implication of calling dropSchema(). It
is possible to catch a more precise exception as well, which should
preserve the benefits of not swallowing them.

It looks like I based my grep on the comment inside the catch and today,
I found many other occurrences of this pattern, without the easy to grep
comment.

I decided to fix them as well, but in a lazier way: one no longer has to
remember to call dropSchema in tearDown() now, it is automated.
2022-02-20 09:26:57 +01:00
Grégoire Paris
152c04c03d Merge pull request #9519 from lcobucci/fix-pagination-test
Trigger the desired code path
2022-02-16 09:24:32 +01:00
Luís Cobucci
12ab6fa43f Trigger the desired code path
Since v2.7.0 the ORM avoids using extra queries via the paginator
component when maximum results isn't set on the original query. With
that change, this test was not executing the code path that it was
expected to run.

This makes sure we trigger the forcing of custom DBAL types when
hydrating the identifiers, making sure we don't introduce bugs.

More info:
- Forcing DBAL type conversion: https://github.com/doctrine/orm/pull/7905
- Issue on optimisation: https://github.com/doctrine/orm/issues/7829
- PR on optimisation: https://github.com/doctrine/orm/pull/7863
- Minor BC-break docs: https://github.com/doctrine/orm/blob/2.11.x/UPGRADE.md#minor-bc-break-paginator-output-walkers-arent-be-called-anymore-on-sub-queries-for-queries-without-max-results
2022-02-15 22:59:09 +01:00
Yann Rabiller
e8e61cbbd5 Fix syntax typo in attributes reference (#9513)
Curly brackets are the annotation way of declaring array. Probably a
mistake while copy pasting some examples from annotations.
2022-02-15 14:32:33 +00:00
Tony Lemke
8f847cb5aa Constructor-Argument "options" has the same type as the associated property. (#9501) 2022-02-13 21:42:15 +01:00
David Maicher
599832cb81 Fix AbstractQuery::setParameter phpdoc (#9504)
* Fix AbstractQuery::setParameter phpdoc

* Fix AbstractQuery::setParameter phpdoc
2022-02-12 21:49:30 +01:00
Dmytro Hordinskyi
530f515556 Added "false" value to $columnPrefix type declaration. (#9493) 2022-02-09 09:40:16 +01:00
Alexander M. Turek
1c55025b12 PHPStan 1.4.6, Psalm 4.20.0 (#9491) 2022-02-09 00:42:34 +01:00
Steve
0900d4bc97 Fix #[DiscriminatorMap] params (#9487)
Fix `#[DiscriminatorMap]` params
2022-02-08 08:35:46 +00:00
Alexander M. Turek
be2518d784 Run tests with stricter error handling (#9482) 2022-02-07 22:08:34 +00:00
Alexander M. Turek
bdd8883d12 Run Postgres 14 and MariaDB 10.6 in CI (#9470) 2022-02-05 19:28:13 +01:00
Alexander M. Turek
536b65f02b PDO is not a required extension (#9457) 2022-02-01 14:13:50 +01:00
Alexander M. Turek
103c42cdb7 Check requirements for metadata drivers (#9452) 2022-02-01 13:48:03 +01:00
Grégoire Paris
cdaf7b5308 Remove trailing underscore (#9446)
It looks like there was confusion between the syntax for external links
and the syntax for internal links, which does not mention underscores.
See https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-doc
versus https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#external-links
2022-01-30 23:01:35 +00:00
Claudio Zizza
4b88ce787d Introduce __unserialize behaviour in docs (#9390)
* Introduce __unserialize behaviour in docs

* Mention deprecation of Serializable interface

* Add link to __unserialize method
2022-01-30 22:47:06 +01:00
Grégoire Paris
f9c3470a8d Adapt test logic to PHP and SQLite II (#9442)
In a88242ee6c, testDateSub() was modified
in order to satisfy different opinions to the question "What is now
minus one month", that has different answers for different pieces of
software on March 30th.

Today, we are January 30th, we need to do the same for testDateAdd().
Hopefully this is the last time we hear about this.
2022-01-30 17:48:10 +01:00
Grégoire Paris
c1b131b67e Merge pull request #9440 from sir-kain/php-8.1-ci
Added php 8.1 to CI
2022-01-30 09:55:04 +01:00
Grégoire Paris
16b82ea061 Use the identify generator strategy
It is a better default, and should fix tests for PostgreSQL
2022-01-29 11:33:13 +01:00
Waly
f8f370ace6 Added php 8.1 to CI 2022-01-28 22:55:25 +00:00
Alexander M. Turek
d5c69fb73f Psalm 4.19.0, PHPStan 1.4.3 (#9438) 2022-01-28 21:54:10 +00:00
Alexander M. Turek
93f9eb7af2 Ignore PHPUnit result cache everywhere (#9425) 2022-01-24 12:35:44 +01:00
HypeMC
6d5da83c68 Add support for PHP 8.1 enums in embedded classes (#9419) 2022-01-23 23:56:36 +01:00
jworman
5f01dd8d09 Added class-string typehint on $targetEntity (#9415) 2022-01-23 20:09:41 +01:00
Benjamin Cremer
b596e6a665 Allow DiscriminatorColumn with length=0 (#9410) 2022-01-21 10:27:29 +01:00
Alexander M. Turek
79d3cf5880 Move UnderscoreNamingStrategyTest to correct namespace (#9414) 2022-01-20 20:49:11 +01:00
Alexander M. Turek
d7b7c28ae5 Fix type on loadCacheEntry (#9398) 2022-01-18 22:49:52 +01:00
Alexander M. Turek
d6fd510c49 Update baselines for DBAL 3.3 (#9393) 2022-01-18 09:13:14 +01:00
olsavmic
a2a7d5bb01 Accessing private properties and methods from the same class is forbidden (#9311)
Resolves issue https://github.com/doctrine/common/issues/934

Update docs/en/cookbook/accessing-private-properties-of-the-same-class-from-different-instance.rst

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>

Update docs/en/cookbook/accessing-private-properties-of-the-same-class-from-different-instance.rst

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>

Fix review issues
2022-01-17 23:15:31 +01:00
Vadim Borodavko
223b2650c4 Expose enumType to DBAL to make native DB Enum possible (#9382) 2022-01-17 10:39:16 +01:00
Vadim Borodavko
01c1644d9c Allow using Enum from different namespace than Entity (#9384) 2022-01-16 13:08:30 +01:00
Sukhdev Mohan
3eff2d4b3f Corrected ORM version and added missing dependency (#9386)
* Corrected ORM version and added missing dependency

Noticed that the version wasn't updated, pointing to 2.11.0 instead of 2.10.2. 
Also when following this tutotial ran into missing dependency for "doctrine/annotation" so added that too.

* Tutorial: Bump DBAL, YAML and Cache

Co-authored-by: Alexander M. Turek <me@derrabus.de>
2022-01-16 02:28:30 +01:00
Alexander M. Turek
9ddf8b96f8 PHPStan 1.4.0 (#9385) 2022-01-16 01:22:41 +01:00
Benjamin Eberlei
3d00fa817a [GH-9380] Bugfix: Delegate ReflectionEnumProperty::getAttributes(). (#9381)
* [GH-9380] Bugfix: Delegate ReflectionEnumProperty::getAttributes().

* [GH-9380] Add test for retrieving attributes via enum property.

* [GH-9380] Add test for retrieving attributes via enum property.

* [GH-9380] Call parent ReflectionProperty ctor for best behavior.

* Update tests/Doctrine/Tests/ORM/Functional/EnumTest.php

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2022-01-16 00:06:59 +01:00
Andrii Dembitskyi
c0a1404e4c Add detach as of list cascade-all operations (#9357) 2022-01-12 22:33:11 +01:00
Alexander M. Turek
bfed8cb6ed Update branch metadata for 2.11 (#9364) 2022-01-12 14:20:33 +01:00
Alexander M. Turek
09a2648f7e Fix doc blocks on ID generators (#9368) 2022-01-12 12:10:23 +01:00
Alexander M. Turek
ee591195cf Use EntityManagerInterface in type declarations (#9325) 2022-01-12 11:00:07 +01:00
Alexander M. Turek
e974313523 Merge branch '2.10.x' into 2.11.x
* 2.10.x:
  Add errors caused by the lexer update to the baselines (#9360)
2022-01-12 10:11:19 +01:00
Alexander M. Turek
1e972b6e0e Add errors caused by the lexer update to the baselines (#9360) 2022-01-12 10:06:40 +01:00
Christian Mehldau
e369cb6e73 Generated/Virtual Columns: Insertable / Updateable (#9118)
* Generated/Virtual Columns: Insertable / Updateable

Defines whether a column is included in an SQL INSERT and/or UPDATE statement.
Throws an exception for UPDATE statements attempting to update this field/column.

Closes #5728

* Apply suggestions from code review

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>

* Add example for virtual column usage in attributes to docs.

Co-authored-by: Benjamin Eberlei <kontakt@beberlei.de>
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2022-01-12 08:06:11 +01:00
Grégoire Paris
ec391be4f2 Merge pull request #9356 from derrabus/remove/package-versions
Remove the `composer/package-versions-deprecated` package
2022-01-11 21:03:59 +01:00
Alexander M. Turek
697e23422f Remove the composer/package-versions-deprecated package 2022-01-11 10:42:42 +01:00
Alexander M. Turek
e487b6fe2b Relax assertion to include null as possible outcome (#9355) 2022-01-10 23:09:02 +01:00
Alexander M. Turek
656f881756 Merge branch '2.10.x' into 2.11.x
* 2.10.x:
  Fix WhereInWalker description to better describe the behaviour of this class (#9268)
2022-01-09 23:48:22 +01:00
Alexander M. Turek
cd2aa487a5 Leverage generic ObjectManagerDecorator (#9312) 2022-01-09 23:10:05 +01:00
LuigiCardamone
b7d822972e Fix WhereInWalker description to better describe the behaviour of this class (#9268)
* Fix WhereInWalker description:
- change the verb "replace" with "append" to better describe the behaviour of this class

* Rephrase comment in WhereInWalker as suggested from reviewer

Co-authored-by: Alexander M. Turek <me@derrabus.de>

* Rephrase comment in WhereInWalker as suggested from reviewer

Co-authored-by: Alexander M. Turek <me@derrabus.de>

Co-authored-by: Alexander M. Turek <me@derrabus.de>
2022-01-09 23:09:28 +01:00
Alexander M. Turek
ec63f5d32a Regenerate Psalm baseline 2022-01-09 22:35:05 +01:00
Alexander M. Turek
952ccc5fc8 Merge branch '2.10.x' into 2.11.x
* 2.10.x:
  Update Psalm baseline for Persistence 2.3 (#9349)
2022-01-09 22:33:24 +01:00
Alexander M. Turek
9a2f1f380d Update Psalm baseline for Persistence 2.3 (#9349) 2022-01-09 20:11:12 +00:00
Alexander M. Turek
580b9196e6 Support readonly properties for read operations (#9316)
* Provide failing test for readonly properties

* Skip writing readonly properties if the value did not change
2022-01-09 20:15:56 +01:00
Grégoire Paris
0d911b9381 Merge pull request #9322 from derrabus/feature/psr-region-cache
PSR-6 second level cache
2022-01-09 16:23:04 +01:00
Grégoire Paris
c6d8aecc0f Merge pull request #9326 from kimhemsoe/rsm-custom-type
Add support for custom types with requireSQLConversion and ResultSetMappingBuilder::generateSelectClause()
2022-01-09 16:17:31 +01:00
Grégoire Paris
fdd3d112b0 Merge remote-tracking branch 'origin/2.10.x' into 2.11.x 2022-01-09 15:50:52 +01:00
Grégoire Paris
2fecb3cb1a Merge pull request #9341 from derrabus/bump/phpstan-psalm
PHPStan 1.3.3, Psalm 4.18.1
2022-01-09 15:48:49 +01:00
Alexander M. Turek
f3630ea16b PHPStan 1.3.3, Psalm 4.18.1 2022-01-09 15:39:44 +01:00
Grégoire Paris
fd19444761 Merge pull request #9344 from greg0ire/remove-dbal2-psalm-job
Remove Psalm job for analyzing DBAL 2
2022-01-09 15:38:56 +01:00
Grégoire Paris
4b1afb41b3 Remove Psalm job for analyzing DBAL 2
As of now, we cannot have specific config files for each DBAL version
and avoid repetition. We already have PHPStan performing checks with
DBAL 2, which could be considered enough.
2022-01-09 13:57:00 +01:00
Alexander M. Turek
f9f453f4d7 Use the readonly annotation (#9340) 2022-01-09 12:25:04 +01:00
Kim Hemsø Rasmussen
f508a4bb71 Add support for custom types with requireSQLConversion and ResultSetMappingBuilder::generateSelectClause() 2022-01-09 10:02:30 +01:00
Alexander M. Turek
5d0fbc47d0 PSR-6 second level cache 2022-01-09 02:02:50 +01:00
Alexander M. Turek
1e977426eb Fix type errors in AbstractQuery and QueryBuilder (#9275) 2022-01-09 00:26:58 +01:00
Grégoire Paris
2640f88f8a Merge pull request #9339 from greg0ire/fix-field-mapping-typing
Fix field mapping typing
2022-01-08 23:57:48 +01:00
Grégoire Paris
fa731b10ec Mark columnName as always set
This is enforced before writing to the property that holds FieldMapping
arrays.
As shown by the static analysis baselines reduction, this existence is
relied on throughout the codebase.
2022-01-08 14:12:04 +01:00
Grégoire Paris
4117ca349f Merge pull request #9304 from beberlei/EnumSupport
Add support for PHP 8.1 enums.
2022-01-08 11:49:08 +01:00
Benjamin Eberlei
2d475c9bb3 Add support for PHP 8.1 enums. 2022-01-08 09:53:11 +01:00
Grégoire Paris
6f54011e7b Merge remote-tracking branch 'origin/2.10.x' into 2.11.x 2022-01-07 20:28:54 +01:00
Grégoire Paris
760397c429 Remove ignore rules for issues fixed upstream (#9336)
The rules still should apply when using DBAL v2
2022-01-07 20:25:00 +01:00
Benjamin Eberlei
7190ac5127 [GH-9277] deprecate php driver (#9309)
* [GH-9277] Deprecate PHPDriver

* Update UPGRADE.md, fix wrong parameter

* Copy docblock to appease confused Psalm

* Talk about alternatives more
2022-01-06 10:19:42 +01:00
Alexander M. Turek
ceaefcb18d Merge 2.10.x into 2.11.x (#9331)
* Enable some previously disabled PHPCS rules (#9324)

* Fix broken type declaration (#9330)
2022-01-05 10:03:45 +01:00
Alexander M. Turek
844ce77cae Added runtime deprecation to UnitOfWork::commit() and clear() (#9327) 2022-01-05 08:14:46 +01:00
Alexander M. Turek
cf3a185b62 Document return type of getEntityState() (#9328) 2022-01-05 07:58:21 +01:00
Alexander M. Turek
efc982a48d Fix broken type declaration (#9330) 2022-01-05 07:55:33 +01:00
Alexander M. Turek
96bc214acd Enable some previously disabled PHPCS rules (#9324) 2022-01-03 23:25:34 +01:00
Alexander M. Turek
15999758a7 Merge branch '2.10.x' into 2.11.x
* 2.10.x:
  Run static analysis with language level PHP 8.1 (#9314)
  Document PHPUnit mocks with intersection types (#9318)
2022-01-02 19:36:10 +01:00
Alexander M. Turek
44aa8c2c5b Run static analysis with language level PHP 8.1 (#9314) 2022-01-02 18:01:31 +01:00
Alexander M. Turek
8c6fc5ae52 Document LockMode enums (#9319) 2022-01-02 18:01:00 +01:00
Alexander M. Turek
c4561571aa Document PHPUnit mocks with intersection types (#9318) 2022-01-02 18:00:17 +01:00
Alexander M. Turek
40a203843d Merge branch '2.10.x' into 2.11.x
* 2.10.x:
  Run PHP CodeSniffer on PHP 8.1 (#9317)
  Psalm 4.17.0 (#9315)
2022-01-02 14:16:56 +01:00
Alexander M. Turek
8b5ee54c6a Run PHP CodeSniffer on PHP 8.1 (#9317) 2022-01-02 14:15:30 +01:00
Alexander M. Turek
03fa495fbc Psalm 4.17.0 (#9315) 2022-01-01 23:41:05 +01:00
Alexander M. Turek
5901848944 Merge 2.10.x into 2.11.x (#9313) 2022-01-01 23:40:19 +01:00
Grégoire Paris
d40f9e57ff Run static analysis on PHP 8.1 (#9310)
This will make it easier to add code that leverages features only
defined since that version of PHP.
2022-01-01 20:28:17 +01:00
Alexander M. Turek
133cc95f33 Merge branch '2.10.x' into 2.11.x
* 2.10.x:
  Bump PHPStan & Psalm (#9303)
  Removing list "Lifecycle Events" (#9243)
  Drop unneeded backslashes
  Fix Hidden fields triggering error when using getSingleScalarResult() (#8340)
  Findby joined lookup (#8285)
2021-12-31 02:59:55 +01:00
Alexander M. Turek
d30e748e64 Bump PHPStan & Psalm (#9303) 2021-12-31 02:21:15 +01:00
Alexander M. Turek
98d77043d8 Fix type errors in AnnotationDriver (#9274) 2021-12-29 16:03:10 +01:00
Grégoire Paris
40d1e7bbfc Merge pull request #9214 from doctrine/2.7
Merge 2.7 into 2.10.x
2021-12-28 23:41:38 +01:00
Thomas Landauer
e8275f6e4d Removing list "Lifecycle Events" (#9243)
As announced in https://github.com/doctrine/orm/pull/9184#issuecomment-965837780
2021-12-28 14:04:58 +01:00
Alexander M. Turek
70dcffa025 Leverage get_debug_type() (#9297) 2021-12-28 08:02:16 +01:00
Alexander M. Turek
c94a9b1d8b Merge 2.10.x into 2.11.x (#9298)
* Bump reusable workflows

* Fix union type on QueryExpressionVisitorTest::testWalkComparison() (#9294)

* Synchronize Psalm baseline (#9296)

* Fix return type (#9295)

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-12-28 01:25:01 +01:00
Alexander M. Turek
6a9393e8ed Fix return type (#9295) 2021-12-28 00:49:50 +01:00
Alexander M. Turek
ab98d0ffc6 Synchronize Psalm baseline (#9296) 2021-12-28 00:49:32 +01:00
Alexander M. Turek
2ddeb79431 Fix union type on QueryExpressionVisitorTest::testWalkComparison() (#9294) 2021-12-27 23:43:09 +01:00
David ALLIX
92ff9c9108 Allow arithmetic expressions within IN operator (#9242)
* allow arithmetic expressions within IN operator

Co-authored-by: Artem Stepin <stepin.artem@gmail.com>
2021-12-27 19:03:47 +01:00
Grégoire Paris
7c58dc89c3 Merge pull request #9289 from derrabus/bump/workflows
Bump reusable workflows
2021-12-27 18:36:35 +01:00
Alexander M. Turek
b513f7c935 Bump reusable workflows 2021-12-27 13:05:20 +01:00
Alexander M. Turek
f1483f848c Merge 2.10.x into 2.11.x (#9287)
* Better explain limitations of DQL "DELETE" (#9281)

We think the current documentation does not stress these details enough, so that they are easily overlooked.

Co-authored-by: Malte Wunsch <mw@webfactory.de>

Co-authored-by: Malte Wunsch <mw@webfactory.de>

* Put actual value instead of index inside $originalEntityData. (#9244)

This fixes a bug with redundant UPDATE queries, that are executed when some entity uses foreign index of other entity as a primary key. This happens when after inserting related entities with $em->flush() call, you do the second $em->flush() without changing any data inside entities.
Fixes GH8217.

Co-authored-by: ivan <ivan.strygin@managinglife.com>

* Allow symfony/cache 6 (#9283)

* Fix XML export for `change-tracking-policy` (#9285)

* Whitelist composer plugins used by this repository (#9286)

Co-authored-by: Matthias Pigulla <mp@webfactory.de>
Co-authored-by: Malte Wunsch <mw@webfactory.de>
Co-authored-by: Ivan Strygin <feolius@gmail.com>
Co-authored-by: ivan <ivan.strygin@managinglife.com>
Co-authored-by: Fedir Zinchuk <getthesite@gmail.com>
2021-12-26 01:06:54 +01:00
Alexander M. Turek
ea4c9b21b7 Enable UnusedUse sniff again (#9267) 2021-12-25 23:06:50 +01:00
Alexander M. Turek
72edfbc270 Whitelist composer plugins used by this repository (#9286) 2021-12-25 13:04:42 +01:00
Fedir Zinchuk
5ccf2eac40 Fix XML export for change-tracking-policy (#9285) 2021-12-24 00:22:42 +01:00
Alexander M. Turek
6696b0dfbf Allow symfony/cache 6 (#9283) 2021-12-24 00:12:11 +01:00
Ivan Strygin
aead77d597 Put actual value instead of index inside $originalEntityData. (#9244)
This fixes a bug with redundant UPDATE queries, that are executed when some entity uses foreign index of other entity as a primary key. This happens when after inserting related entities with $em->flush() call, you do the second $em->flush() without changing any data inside entities.
Fixes GH8217.

Co-authored-by: ivan <ivan.strygin@managinglife.com>
2021-12-24 00:10:42 +01:00
Alexander M. Turek
130c27c1da Fix return types of cache interfaces (#9271) 2021-12-22 01:04:07 +01:00
Matthias Pigulla
f6e1dd44f0 Better explain limitations of DQL "DELETE" (#9281)
We think the current documentation does not stress these details enough, so that they are easily overlooked.

Co-authored-by: Malte Wunsch <mw@webfactory.de>

Co-authored-by: Malte Wunsch <mw@webfactory.de>
2021-12-22 00:44:25 +01:00
Alexander M. Turek
1e9973a0c0 Merge release 2.10.4 into 2.11.x (#9280) 2021-12-21 11:01:59 +01:00
Alexander M. Turek
91761738fd Fix docblocks on nullable EM properties (#9273) 2021-12-20 22:31:57 +01:00
Andrii Dembitskyi
cccb2e2fdf Docs: use canonical order for phpdoc tags, add missed semicolon (#9190) 2021-12-20 22:23:47 +01:00
Benjamin Eberlei
18138d895e Make PrimaryReadReplicaConnection enforcement explicit (#9239)
* Move primary replica connection logic into ORM explicitly.

* Housekeeping: Use full named variables

* Housekeeping: phpcs
2021-12-20 13:50:25 +01:00
Alexander M. Turek
95d434d003 Merge 2.10.x into 2.11.x (#9276)
* Docs: consistency for FQCN, spacing, etc (#9232)

* Docs: consistent spacing, consistent array-style, consistent FQCN, avoid double escaped slashes, avoid double quotes if not necessary

* Docs: use special note block instead of markdown-based style

* Docs: Quote FQCN in table with backticks to be compatible with all render engines

* Drop all mentions API doc - it is not available anymore

* Add missed FQCN for code snippets

* Revert "Fix SchemaValidator with abstract child class in discriminator map (#9096)" (#9262)

This reverts commit bbb68d0072.

* [docs] Fix wording for attributes=>parameters. (#9265)

Co-authored-by: Andrii Dembitskyi <andrew.dembitskiy@gmail.com>
Co-authored-by: olsavmic <molsavsky1@gmail.com>
Co-authored-by: Benjamin Eberlei <kontakt@beberlei.de>
2021-12-20 04:11:33 +01:00
Alexander M. Turek
70c651ebb7 Regenerate Psalm baseline (#9272) 2021-12-19 17:06:20 +01:00
Sergei Morozov
8cb62a616a Improve compatibility with Doctrine DBAL 4 (#9266)
* Improve compatibility with AbstractPlatform::getLocateExpression() in DBAL 4

* Improve compatibility with AbstractPlatform::getTrimExpression() in DBAL 4

* Improve compatibility with Connection::quote() in DBAL 4
2021-12-19 13:19:30 +01:00
Benjamin Eberlei
fa2b52c974 [docs] Fix wording for attributes=>parameters. (#9265) 2021-12-18 11:16:35 +01:00
Benjamin Eberlei
6d306c1946 Support for nesting attributes with PHP 8.1 (#9241)
* [GH-9240] Refactor Association/AttributeOverrides to use @NamedConstructorArguments with AnnotationDriver.

* [GH-9240] Add support for PHP 8.1 nested attributes.

Supported/new attributes are #[AttributeOverrides], #[AssociationOverrides], #[JoinTable] with nested joinColumns, inverseJoinColumns.

* [GH-9240] Add support for nesting Index, UniqueCosntraint into #[Table] on PHP 8.1

* Apply review comments by gregooire.

* Add documentation for new attributes.

* Add docs for new nested #[JoinTable] support of join columns

* Add docs for new nested #[Table] support of index, uniqueConstraints

* Rename "Required/Optional atttributes" to "Required/Optional parameters"

* Remove nesting for JoinTable#joinColumns and Table#indexes/uniqueConstraints again.

* Hosuekeeping: phpcs/psalm

* housekeeping

* Remove unused function imports.
2021-12-18 11:03:12 +01:00
olsavmic
5bf814032f Revert "Fix SchemaValidator with abstract child class in discriminator map (#9096)" (#9262)
This reverts commit bbb68d0072.
2021-12-18 11:01:30 +01:00
Sergei Morozov
bea5e7166c Address more DBAL 3.2 deprecations (#9256)
* Instantiate comparator via the schema manager, if possible

* Do not use AbstractPlatform::getName()
2021-12-16 23:18:18 +01:00
Alexander M. Turek
003090b70c Deprecate Setup::registerAutoloadDirectory() (#9249) 2021-12-13 23:36:10 +01:00
Andrii Dembitskyi
02a4e4099d Docs: consistency for FQCN, spacing, etc (#9232)
* Docs: consistent spacing, consistent array-style, consistent FQCN, avoid double escaped slashes, avoid double quotes if not necessary

* Docs: use special note block instead of markdown-based style

* Docs: Quote FQCN in table with backticks to be compatible with all render engines

* Drop all mentions API doc - it is not available anymore

* Add missed FQCN for code snippets
2021-12-13 23:10:01 +01:00
Alexander M. Turek
56e0ac02af Merge 2.10.x into 2.11.x (#9248) 2021-12-13 22:21:00 +01:00
Alexander M. Turek
12a70bbefb PHPCS 3.6.2, Psalm 4.15.0 (#9247) 2021-12-13 21:28:56 +01:00
Grégoire Paris
5a4ddb2870 Merge pull request #9184 from ThomasLandauer/patch-1
[Documentation] Events Overview Table: Adding "Passed Argument" column
2021-12-12 16:21:13 +01:00
Simon Podlipsky
42195060e6 Add SchemaIgnoreClasses property for #8195. (#9202)
Co-authored-by: Simon Podlipsky <simon@podlipsky.net>

Co-authored-by: Iab Foulds <ianfoulds@x-act.co.uk>
2021-12-12 13:42:07 +01:00
Alexander M. Turek
68fa55f310 Remove fallbacks for old doctrine/annotations version (#9235) 2021-12-11 17:11:34 +01:00
Thomas Landauer
0b0c3e7e58 Update docs/en/reference/events.rst
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-12-09 12:00:30 +01:00
Kevin van Sonsbeek
92434f91c7 Added psalm param to abstract addFilterConstraint (#9229) 2021-12-08 22:31:52 +00:00
Alexander Schranz
6414ad4cbb Merge pull request #9210 from alexander-schranz/patch-2
Fix making columns  optional in indexes xml schema as they can be defined via fields now
2021-12-06 00:55:01 +01:00
Alexander M. Turek
ac5aea1c81 Merge release 2.10.3 into 2.11.x (#9224) 2021-12-03 22:40:00 +01:00
Alexander M. Turek
a75605b8c3 Merge pull request #9211 from derrabus/deprecate/convert-mapping
Add deprecation hints to `orm:convert-mapping` command
2021-12-03 15:50:09 +01:00
Grégoire Paris
7b24275346 Merge pull request #9218 from Florian-Varrin/patch-1
Fix typo assumptio--> assumption
2021-12-03 13:27:05 +01:00
Florian Varrin
ed1a576305 Fix typo assumptio--> assumption 2021-12-03 11:39:59 +01:00
Grégoire Paris
66c95a65c5 Drop unneeded backslashes 2021-12-01 21:53:36 +01:00
Bruce
62a0d7359b Fix Hidden fields triggering error when using getSingleScalarResult() (#8340)
* Fix Hidden fields triggering error when using getSingleScalarResult()

Fixes #4257
HIDDEN fields was causing the "unicity" check to fail (NonUniqueResultException), because we was counting raw data instead of gathered row data.

* Fix Coding Standards (7.4)

* Fix Coding Standards (7.4) #2

* Fix Coding Standards (7.4) - Fix whitespaces

* Fix Coding Standards (7.4) - Fix whitespaces in tests

* Fix Coding Standards (7.4) - Fix more things

* Refactor tests into separate methods

* Fix Coding Standards (7.4) - Equals sign not aligned with surrounding assignments
2021-12-01 21:52:31 +01:00
Benjamin Eberlei
2c7d7ebb48 Findby joined lookup (#8285)
* [GH-7512] Bugfix: Load metadata on object-typed  value in EntityPersisters

* [GH-7512] Refactor double check for object/entity and flatten code.

Co-authored-by: Joe Mizzi <themizzi@me.com>
2021-12-01 21:52:29 +01:00
Thomas Landauer
8b6fe52f74 Update events.rst 2021-12-01 01:01:04 +01:00
Alexander M. Turek
eabb7f84e9 Add deprecation hints to orm:convert-mapping command 2021-11-30 23:04:44 +01:00
Alexander M. Turek
f0a20dbc9c Merge 2.10.x into 2.11.x (#9213) 2021-11-30 22:37:08 +01:00
Alexander M. Turek
15ec77fa79 Suppress Psalm's ReservedWord errors (#9212) 2021-11-30 20:20:27 +01:00
Thomas Landauer
32cd2106d0 Completing links to EventArgs classes in overview table
Questions:
1. Is https://github.com/doctrine/persistence/blob/master/lib/Doctrine/Persistence/Event/LifecycleEventArgs.php correct at all? Shouldn't this be https://github.com/doctrine/orm/blob/2.10.x/lib/Doctrine/ORM/Event/LifecycleEventArgs.php, like all the others?

2. Which one is correct for `preUpdate`? https://www.doctrine-project.org/projects/doctrine-orm/en/2.10/reference/events.html#entity-listeners-class says `PreUpdateEventArgs`, but https://www.doctrine-project.org/projects/doctrine-orm/en/2.10/reference/events.html#listening-and-subscribing-to-lifecycle-events says `LifecycleEventArgs`

For the two links to `doctrine/persistence`, I'm linking to `/master/` now, which is being forwarded to `/2.2.x/`.
2021-11-30 15:51:20 +01:00
Alexander M. Turek
6857a2e8d4 Add missing deprecations for YAML metadata mapping (#9206) 2021-11-29 16:46:05 +01:00
Alexander M. Turek
5e8b34ae30 Merge pull request #9203 from derrabus/bump/dbal-3.2
Drop support for DBAL 3.1
2021-11-29 16:45:30 +01:00
Alexander M. Turek
a9b682b7c0 Drop support for DBAL 3.1 2021-11-29 10:37:05 +01:00
Alexander M. Turek
0aadc456dc Merge 2.10.x into 2.11.x (#9205)
* Adding Attributes code block (#9161)

Just that there is some real-world example somewhere ;-) see https://github.com/doctrine/orm/issues/9020#issuecomment-955582801

* Use `equal to` instead of `equal of` in `assertSqlGeneration()` (#9195)

* Add a psalm type for field mapping

Field mapping have different definitions
in property definition and method return.
As suggested in issue and to avoid further desynchronization,
a psalm type has been created.
Fixes #9193

* Psalm 4.13.1, PHPStan 1.2.0 (#9204)

Co-authored-by: Thomas Landauer <thomas@landauer.at>
Co-authored-by: Simon Podlipsky <simon@podlipsky.net>
Co-authored-by: Julien LARY <47776596+laryjulien@users.noreply.github.com>
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-11-28 01:08:49 +01:00
Alexander M. Turek
cac2acae07 Psalm 4.13.1, PHPStan 1.2.0 (#9204) 2021-11-28 00:50:56 +01:00
Grégoire Paris
146b465ec1 Merge pull request #9198 from laryjulien/fix-fieldmapping-definition
Add a psalm type for field mapping
2021-11-23 21:10:18 +01:00
Julien LARY
5aba762a33 Add a psalm type for field mapping
Field mapping have different definitions
in property definition and method return.
As suggested in issue and to avoid further desynchronization,
a psalm type has been created.
Fixes #9193
2021-11-23 18:05:47 +01:00
Thomas Landauer
77b7107d05 Using const for type 2021-11-23 01:41:01 +01:00
Simon Podlipsky
a663dda869 Use equal to instead of equal of in assertSqlGeneration() (#9195) 2021-11-20 21:27:46 +01:00
Thomas Landauer
db14f0fa89 Adding Attributes code block (#9161)
Just that there is some real-world example somewhere ;-) see https://github.com/doctrine/orm/issues/9020#issuecomment-955582801
2021-11-20 18:14:49 +01:00
Grégoire Paris
2488b4c50c Merge pull request #9196 from greg0ire/2.11.x
Merge 2.10.x up into 2.11.x
2021-11-20 15:38:36 +01:00
Grégoire Paris
ed642c72c9 Merge remote-tracking branch 'origin/2.10.x' into 2.11.x 2021-11-20 15:28:20 +01:00
Vincent Langlet
9a74ae6280 Fix discriminatorColumn phpdoc (#9168) 2021-11-11 23:01:34 +01:00
Grégoire Paris
32eb38ebd9 Merge pull request #9181 from greg0ire/fix-broken-build
Remove similar assertions for other platforms
2021-11-11 16:20:53 +01:00
Thomas Landauer
2dde65c4ba [Documentation] Events Overview Table: Adding "Passed Argument" column
As announced in https://github.com/doctrine/orm/pull/9160#issuecomment-954304588 I'm adding the passed "EventArgs" class to the overview table. Once this is complete, my further plan is to remove the entire paragraph https://www.doctrine-project.org/projects/doctrine-orm/en/2.10/reference/events.html#lifecycle-callbacks-event-argument, and probably also the second code block at https://www.doctrine-project.org/projects/doctrine-orm/en/2.10/reference/events.html#entity-listeners-class

Is there a better way to link to the source code of `LifecycleEventArgs` than https://github.com/doctrine/persistence/blob/2.2.x/lib/Doctrine/Persistence/Event/LifecycleEventArgs.php ?

Also, I changed `postLoad` to `preUpdate` in the code block, to have an example that does not receive `LifecycleEventArgs` ;-)
2021-11-11 00:22:25 +01:00
Thomas Landauer
176fbedc69 Fine-tuning codeblock (#9176)
* Deleting "Not needed for XML and YAML mapping" - this was stupid of me, since *all* annotations are obviously not needed in XML&YAML ;-)
* Shortening the @Column annotation, for consistency with the following event handlers
* Removing some blank lines from XML, for consistency with YAML
* Adding PHP Attributes
2021-11-10 22:43:09 +01:00
Grégoire Paris
1b15af44b6 Remove similar assertions for other platforms
Testing with several platforms should not increase code coverage here,
since the DBAL is responsible for providing the concat expression for
each platform.

Moreover, whenever that concat expression changes for one of the tested
platforms, this test will break.

In doctrine/dbal 3.2, that is the case for SQLServer2012Platform, which
means this test no longer passes.
2021-11-08 21:21:41 +01:00
Grégoire Paris
8336420a26 Merge pull request #9153 from armenio/2.10.x
Infer type from field instead of column
2021-11-08 07:45:07 +01:00
Thomas Landauer
1e971d85c4 Merging two ~identical lists on event types (#9160)
* Merging two ~identical lists on event types

Just noticed that what I added in https://github.com/doctrine/orm/pull/9128 was (in other words) already there ;-)

* Update docs/en/reference/events.rst

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
2021-11-06 21:32:46 +01:00
Thomas Landauer
a6b7569d7a Fixing more links (#9154)
* Fixing more links

The first two I missed in https://github.com/doctrine/orm/pull/9151
The third is probably older.
Shouldn't the chapter name be displayed as link text by default?? Are you sure that everything is set up correctly with the parser?

* Update architecture.rst

* Update getting-started.rst

* Update events.rst
2021-11-06 20:49:54 +01:00
Rafael Armenio
9e37c788ef Infer type from field instead of column
getTypeOfColumn() relies on getTypeOfField(), and does not suffer from
mismatching issues caused by quoting, because you cannot quote a field.
Since a field can be composite, that method returns an array, hence why we
need to select the first element.
2021-11-05 13:58:53 -03:00
Grégoire Paris
ca0a6bbf71 Merge pull request #9167 from derrabus/bump/phpstan
PHPStan 1.0.1
2021-11-03 21:15:19 +01:00
Grégoire Paris
a3da3d78d4 Merge pull request #9159 from ThomasLandauer/patch-10
Merging Lifecycle Callbacks code samples for PHP + XML + YAML
2021-11-03 21:13:53 +01:00
Alexander M. Turek
e1c2d2e65d PHPStan 1.0.1
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-11-02 20:41:48 +01:00
Alexander Schranz
6f194eeabf Remove reverted bc break (#9166) 2021-11-01 13:56:12 +01:00
Grégoire Paris
16cbc16998 Document BC break (#9143)
Closes #9141
2021-10-30 19:10:25 +02:00
Thomas Landauer
5e6608b48e Update events.rst 2021-10-30 13:48:03 +02:00
Grégoire Paris
94bc137526 Merge pull request #9123 from phansys/quotes_in_column_names
Add XSD "orm:columntoken" type in order to support reserved words in column names
2021-10-29 18:19:35 +02:00
Thomas Landauer
276a0f55ee Removing paragraph on consts (#9158)
IMO, this is better shown by example, so I added it there.
2021-10-29 14:21:37 +02:00
Thomas Landauer
dbaf99f3d9 Update events.rst 2021-10-29 01:17:32 +02:00
Thomas Landauer
97411f5567 Merging Lifecycle Callbacks code samples for PHP + XML + YAML
IMO, the text I deleted just repeated things that are obvious in the example anyway.
2021-10-29 01:12:02 +02:00
Chase Noel
641330baa6 Add doctrine/dbal to project composer.json (#9152)
As discussed in https://github.com/doctrine/orm/issues/9078 when entities utilize data mappings which are provided by the dbal lib it is expected behavior that users will explicitly define their dependency on the package.

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-10-28 23:42:05 +02:00
Grégoire Paris
2074fc3ff9 Merge pull request #9133 from judahnator/2.10.x
Adding a setup helper for attribute metadata config
2021-10-28 22:23:25 +02:00
Thomas Landauer
35e680cd3f Fixing links in overview table (#9151)
I got them wrong in https://github.com/doctrine/orm/pull/9131 ;-)
2021-10-28 21:29:47 +02:00
Javier Spagnoletti
705d88eaba Add XSD "orm:columntoken" type in order to support reserved words in column names 2021-10-28 14:00:39 -03:00
Judah Wright
8fef44333b Adding a setup helper for attribute metadata config 2021-10-27 15:05:38 -07:00
Paul Waring
3271d8f6e2 Fix markup for variable names (#9150)
Three references to `$isDevMode` were marked up with a single backtick, however two backticks are required in order for the variable name to be highlighted correctly (c.f. `ArrayCache`).
2021-10-26 10:59:31 +00:00
Thomas Landauer
3622381f8c Overview table for events: Jump links (#9131)
* Overview table for events: Jump links

* Update events.rst
2021-10-25 22:34:36 +02:00
wickedOne
f2729b0610 Return 0 when there's no metadata to process (#9147) 2021-10-23 09:43:40 +00:00
chapterjason
cd44547573 Remove old use statements (#9146) 2021-10-23 11:32:44 +02:00
Grégoire Paris
3361691d0a Merge pull request #9140 from doctrine/2.10.x-merge-up-into-2.11.x_JJHD4HD8
Merge release 2.10.2 into 2.11.x
2021-10-21 20:49:48 +02:00
Grégoire Paris
81d472f6f9 Merge pull request #9139 from greg0ire/upgrade-workflows
Upgrade workflows to 1.1.1
2021-10-21 19:57:02 +02:00
Grégoire Paris
d458968cee Upgrade workflows to 1.1.1
That version fixes a bug with the release workflow. Releasing is not
possible unless we do that upgrade.
2021-10-21 19:55:57 +02:00
Alexander M. Turek
b6a2257758 Merge 2.10.x into 2.11.x (#9137) 2021-10-21 19:50:56 +02:00
Christophe Coevoet
5eb01da0a0 Fix the upgrade guide for 2.8 changes (#9138) 2021-10-21 16:44:42 +02:00
Grégoire Paris
5aaf361139 Merge pull request #9136 from greg0ire/revert-bc-break
Revert "Removing all the occurence of any"
2021-10-21 08:49:18 +02:00
Alexander M. Turek
6a8dcbc392 Regenerate Psalm baseline (#9135) 2021-10-20 23:30:57 +02:00
Grégoire Paris
12babcc1c2 Revert "Removing all the occurence of any"
This reverts commit 84afd6c937, because it
is a BC-break that seems to affect more people than we originally
thought it would.
2021-10-20 23:12:01 +02:00
Thomas Landauer
416aa1d2d7 Explaining the two major ways to register an event v2 (#9128)
Co-authored-by: Javier Spagnoletti <phansys@gmail.com>
2021-10-16 11:45:10 +02:00
Alexander M. Turek
06d9c584a3 Merge 2.10.x into 2.11.x (#9127) 2021-10-15 18:41:04 +02:00
Grégoire Paris
8e16bb4ddc Merge pull request #9126 from greg0ire/explicitly-pass-secrets
Explicitly pass secrets
2021-10-14 23:45:30 +02:00
Grégoire Paris
e1dee439bb Explicitly pass secrets
Secrets are sensitive and not passed implicitly.
2021-10-14 23:35:29 +02:00
Thomas Landauer
e313d012ae Overview table for events (#9039)
* Overview table for events

Better late than never - finally delivering what I announced at https://github.com/doctrine/orm/pull/8435#issuecomment-769940427 :-)

* Update events.rst

* Update events.rst

* Adding "Lifecycle Callback" column

* Update events.rst
2021-10-14 10:58:07 +02:00
Javier Spagnoletti
dede619b9e Add "@method" annotation for wrapInTransaction() method at EntityManagerInterface (#9091) 2021-10-13 20:18:50 +02:00
Grégoire Paris
142cfb39fc Merge pull request #9114 from greg0ire/try-out-reusable-workflows
Directly reference upstream CS workflow
2021-10-11 21:00:41 +02:00
Alexander M. Turek
53d41a456a PHP CodeSniffer 3.6.1 (#9115) 2021-10-11 12:05:46 +02:00
Grégoire Paris
95b34ca940 Directly reference some upstream workflows 2021-10-10 21:08:57 +02:00
Paul Capron
3eaf76eebd Fix typo & minor issues in dql-custom-walkers.rst (#9113) 2021-10-09 23:29:38 +02:00
Grégoire Paris
5c12d36be3 Merge pull request #9107 from BackEndTea/patch-1
Remove the twitter #doctrine2 hashtag refference
2021-10-07 22:35:44 +02:00
Grégoire Paris
1ee68eb318 Merge pull request #9098 from ajgarlag/bugfix-indexed-iterable
Honor INDEX BY construct in Query::toIterable
2021-10-07 22:34:54 +02:00
orklah
705c7f0a4b [Psalm] always true/false conditions (#9108) 2021-10-07 20:21:58 +02:00
Gert de Pagter
8c5e49efc0 Remove the twitter #doctrine2 hashtag refference
Looking at twitter, the hashtag its hardly used. There was 1 question posted in the last year, and it went unanswered.

The `2` part has mostly been dropped everywhere, and orm is now just refered to doctrine orm instead of doctrine2
2021-10-07 16:12:06 +02:00
Antonio J. García Lagar
483e09cf1c Fix Query::toIterable to honor INDEX BY construct 2021-10-07 13:02:22 +02:00
Benjamin Morel
bbb68d0072 Fix SchemaValidator with abstract child class in discriminator map (#9096) 2021-10-06 22:35:51 +02:00
Alexander M. Turek
b0381b3705 Merge release 2.10.1 into 2.11.x (#9092) 2021-10-05 15:12:04 +02:00
Knallcharge
f346379c7b Add integer cast in setFirstResult methods of Query and QueryBuilder (#9090) 2021-10-05 15:04:30 +02:00
Michael Telgmann
b1c31e1aac Add integer cast in setMaxResults methods of Query and QueryBuilder (#9079) 2021-10-04 23:00:38 +02:00
Grégoire Paris
02b6f9c335 Merge pull request #9084 from annechko/patch-1
Update phpdoc comment - association-mapping.rst
2021-10-04 21:59:30 +02:00
Anna Borzenko
d14d9919c7 Update phpdoc comment 2021-10-04 21:50:03 +02:00
Alexander M. Turek
3984f74eb4 Deprecate ensureProductionSettings() (#9074) 2021-10-04 10:00:34 +02:00
Alexander M. Turek
ebdced6175 Deprecate AbstractHydrator::hydrateRow() (#9072) 2021-10-03 21:46:30 +00:00
Grégoire Paris
1a702075ba Merge pull request #9071 from doctrine/2.10.x
Merge up
2021-10-03 22:49:21 +02:00
Grégoire Paris
bd79e3d383 Merge pull request #9068 from greg0ire/update-branch-metadata
Reflect latest minor release in metadata
2021-10-03 22:48:37 +02:00
Grégoire Paris
10f72417c9 Reflect latest minor release in metadata 2021-10-03 21:12:59 +02:00
Grégoire Paris
87ad869a8a Merge pull request #9067 from greg0ire/use-latest-laminas-release
Use latest laminas release
2021-10-03 21:08:55 +02:00
Grégoire Paris
bc4659b73c Revert "Pin laminas/automatic-releases to 1.11.1"
This reverts commit e800f90d7c.
2021-10-03 20:56:35 +02:00
Grégoire Paris
4eab6536c3 Revert "Try using docker image directly"
This reverts commit ddcea63d0f.
2021-10-03 20:56:27 +02:00
Grégoire Paris
1571c8a781 Revert "Explicitly disallow workflows for tags"
This reverts commit bbe4022566.
2021-10-03 20:56:12 +02:00
Grégoire Paris
20a65cbe32 Revert "Use org admin token"
This reverts commit e8a221d227.
2021-10-03 20:55:17 +02:00
Grégoire Paris
07e15a0038 Merge pull request #9065 from greg0ire/2.10.x
Merge up
2021-10-03 17:14:07 +02:00
Grégoire Paris
5918cfaa20 Merge remote-tracking branch 'origin/2.9.x' into 2.10.x 2021-10-03 17:13:24 +02:00
Grégoire Paris
73fa465c26 Merge pull request #9064 from greg0ire/use-org-token
Use org admin token
2021-10-03 17:09:48 +02:00
Grégoire Paris
e8a221d227 Use org admin token
My previous attempts to disallow running a workflow when pushing a tag
failed, so let's ensure we can run said workflow. Maybe we will be able
to understand why it happened after it happens.
2021-10-03 17:08:50 +02:00
Grégoire Paris
b734a7d155 Merge pull request #9063 from greg0ire/explicitly-disallow-workflows-for-tags
Explicitly disallow workflows for tags
2021-10-03 17:02:04 +02:00
Grégoire Paris
bbe4022566 Explicitly disallow workflows for tags
Despite what is described in the docs, it seems that there is still an
attempt to run a workflow for tags.
2021-10-03 17:01:08 +02:00
Grégoire Paris
63f3abfbe8 Avoid triggering workflows for tags
To avoid recursive workflows, Github will prevent the release bot from
pushing tags because that would result in a new workflow being triggered.
2021-10-03 16:41:29 +02:00
Grégoire Paris
22added5fa Merge pull request #9062 from greg0ire/dont-run-workflows-for-tags
Avoid triggering workflows for tags
2021-10-03 16:39:43 +02:00
Grégoire Paris
3a3b53e11d Avoid triggering workflows for tags
To avoid recursive workflows, Github will prevent the release bot from
pushing tags because that would result in a new workflow being triggered.
2021-10-03 16:36:46 +02:00
Grégoire Paris
ddcea63d0f Try using docker image directly 2021-10-03 16:23:22 +02:00
Grégoire Paris
e800f90d7c Pin laminas/automatic-releases to 1.11.1
1.12.0 and up comes with a migration to azjezz/psl that makes it
impossible to troubleshoot issues with external commands such as git push
2021-10-03 15:09:18 +02:00
Grégoire Paris
6d16147d60 Merge pull request #9061 from greg0ire/revert-to-older-automatic-releases
Revert to older automatic releases
2021-10-03 15:06:41 +02:00
Grégoire Paris
9ed1fe59f2 Pin laminas/automatic-releases to 1.11.1
1.12.0 and up comes with a migration to azjezz/psl that makes it
impossible to troubleshoot issues with external commands such as git push
2021-10-03 14:49:00 +02:00
Alexander M. Turek
f805526336 Deprecate isIdGeneratorTable and isIdentifierUuid (#9046) 2021-10-03 12:18:53 +02:00
Alexander M. Turek
2e86134c0b Merge branch '2.9.x' into 2.10.x
* 2.9.x:
  Run PHP 8.1 CI with stable dependencies (#9058)
  Duplicate testTwoIterateHydrations (#9048)
  Add PHP 8.1 to CI (#9006)
  Fix locking non-existing entity (#9053)

Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-10-02 21:22:45 +02:00
Alexander M. Turek
5f768742a0 Run PHP 8.1 CI with stable dependencies (#9058) 2021-10-02 19:37:08 +02:00
Alexander M. Turek
7a8c086d44 Add PHP 8.1 to CI (#9057) 2021-10-02 18:01:18 +02:00
Alexander M. Turek
1d4e12bc6b Duplicate testTwoIterateHydrations (#9048) 2021-10-02 17:45:29 +02:00
Alexander M. Turek
70b0f50d13 Add PHP 8.1 to CI (#9006)
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-10-02 17:20:20 +02:00
Grégoire Paris
149c4308bb Merge pull request #9056 from derrabus/improvement/foreign-key-get-columns
Remove calls to `ForeignKeyConstraint::getColumns()`
2021-10-02 17:14:03 +02:00
Alexander M. Turek
9d4fac088c Remove calls to ForeignKeyConstraint::getColumns()
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-10-02 17:05:16 +02:00
Alexander M. Turek
eb27acaa65 Update documentation regarding caching (#9043) 2021-09-30 23:30:49 +02:00
Csupity Laszlo
2362aa1a7a Fix locking non-existing entity (#9053) 2021-09-30 23:29:34 +02:00
Kévin Dunglas
f414e57d82 fix: prevent TypeError in QueryBuilder joins (#9050) 2021-09-30 06:03:33 +00:00
Alexander M. Turek
13543df649 Merge pull request #9049 from derrabus/merge/2.9.x
Merge 2.9.x into 2.10.x
2021-09-29 23:15:15 +02:00
Alexander M. Turek
1d7fdde81d Merge branch '2.9.x' into merge/2.9.x
* 2.9.x:
  Minor rewording (#8435)
  Don't presume one-to-one lookup returned an entity  (#9028)
  Minor change about double The (#9038)
  Remove duplicate comment (#9036)
  Fix docblock types for some nullable properties (#9024)
  Explicitly allow to use `Comparison` and `Composite` in JOIN conditions (#9022)
  Fix some typehints in QueryBuilder
  Bump PHPStan (#9014)
  Add tests for advanced types in collection matching
  Use types in collection persister

Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-09-29 20:33:01 +02:00
Thomas Landauer
5326736571 Minor rewording (#8435)
Emphasizing the (counter-intuitive) fact that preUpdate is called inside **flush** - cause this was causing me some confusion, see https://github.com/symfony/symfony/issues/39894
2021-09-28 09:41:16 +02:00
Greg Tyler
78d07b0bd2 Don't presume one-to-one lookup returned an entity (#9028)
If `$this->em->find()` returns null, don't treat it like an object. Instead, just set the field to null and back out of the switch statement.

Fixes #9027
2021-09-27 12:43:35 +02:00
Loenix
51ff4713b3 Minor change about double The (#9038) 2021-09-27 08:50:16 +00:00
Jérémy
c0f70204d1 Remove duplicate comment (#9036) 2021-09-23 12:47:01 +00:00
Javier Spagnoletti
2575aa5120 Fix docblock types for some nullable properties (#9024) 2021-09-22 23:48:49 +02:00
Javier Spagnoletti
1f6401ee0a Explicitly allow to use Comparison and Composite in JOIN conditions (#9022) 2021-09-20 06:09:05 +02:00
Grégoire Paris
248ff82f83 Merge pull request #9017 from norkunas/fix-typehints
Fix some typehints in QueryBuilder
2021-09-16 16:44:29 +01:00
Tomas
f1db7d7fa2 Fix some typehints in QueryBuilder 2021-09-16 15:26:18 +03:00
Alexander M. Turek
0bcc3ee4e9 Bump PHPStan (#9014) 2021-09-15 15:46:59 +02:00
Grégoire Paris
0bd651abda Merge pull request #9010 from sztyup/2.9.x
Fix ignoring custom types for PersistentCollection matching()
2021-09-15 08:02:57 +01:00
Alexander M. Turek
334ca18171 Document fluent interfaces (#9009) 2021-09-13 21:25:33 +02:00
Laszlo_Csupity
ff978ce4d8 Add tests for advanced types in collection matching 2021-09-13 13:56:13 +02:00
Laszlo_Csupity
128ebe630b Use types in collection persister 2021-09-13 13:55:41 +02:00
Alexander M. Turek
6371081593 Use PSR-6 for accessing the query cache (#9004) 2021-09-13 12:39:32 +02:00
Alexander M. Turek
31d8bd7a5e Merge pull request #9008 from greg0ire/2.10.x
Merge 2.9.x up into 2.10.x
2021-09-13 12:16:40 +02:00
Grégoire Paris
dee58cfefd Merge remote-tracking branch 'origin/2.9.x' into 2.10.x 2021-09-13 12:07:43 +02:00
Grégoire Paris
71f1fdb668 Merge pull request #9007 from derrabus/test/query-get-cache
Add tests for Query::getQueryCacheDriver()
2021-09-13 11:06:04 +01:00
Alexander M. Turek
85488d69e2 Add tests for Query::getQueryCacheDriver()
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-09-13 10:08:58 +02:00
Alexander M. Turek
5c7e6689fc Switch cache configuration to PSR-6 (#9002) 2021-09-11 23:16:31 +02:00
Grégoire Paris
5b3fb6ac56 Merge pull request #8999 from derrabus/merge/2.9.x
Merge 2.9.x into 2.10.x
2021-09-11 16:36:44 +01:00
Alexander M. Turek
65839235ce Merge branch '2.9.x' into merge/2.9.x
* 2.9.x:
  Remove Proxy from EntityManagerInterface contract
  Add extension point for the "embedded" XML node (#8992)
  Fix return type at `EntityManagerInterface::get(Partial)Reference()` (#8922)
  Fix class casing and avoid name collisions
  Remove unused performance base test class
  Drop unused test base classes
  Fix mapped superclass missing in discriminator map
2021-09-11 16:53:52 +02:00
Grégoire Paris
d1cd8047fa Merge pull request #9001 from derrabus/sa/em-get-reference
Remove Proxy from EntityManagerInterface contract
2021-09-11 15:33:26 +01:00
Alexander M. Turek
90ed9f5387 Remove Proxy from EntityManagerInterface contract
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-09-11 15:23:14 +02:00
Javier Spagnoletti
04d28a9362 Add extension point for the "embedded" XML node (#8992) 2021-09-11 14:17:37 +02:00
Grégoire Paris
fb89129fb2 Merge pull request #9000 from derrabus/bugfix/missing-imports
Fix class casing and avoid name collisions
2021-09-11 12:55:07 +01:00
Simon Podlipsky
399b69a309 Fix return type at EntityManagerInterface::get(Partial)Reference() (#8922) 2021-09-11 13:53:20 +02:00
Grégoire Paris
01ab70d204 Merge pull request #8996 from derrabus/improvement/psr6-result-cache
Support for PSR-6 result caches
2021-09-11 12:53:09 +01:00
Alexander M. Turek
45553556d5 Fix class casing and avoid name collisions 2021-09-11 13:41:46 +02:00
Alexander M. Turek
996fa777bd Support for PSR-6 result caches
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-09-11 13:20:37 +02:00
Grégoire Paris
dc1336dbc2 Include the DBAL version in coverage filenames (#8998)
Currently, files from different jobs probably overwrite each other.
2021-09-11 13:03:55 +02:00
Alexander M. Turek
b1f89a5cb8 Merge pull request #8997 from greg0ire/drop-unused-classes 2021-09-10 22:15:58 +02:00
Grégoire Paris
48f7abf697 Remove unused performance base test class
It is unused since b960170fe1
2021-09-10 21:13:32 +02:00
Grégoire Paris
2159fbee56 Drop unused test base classes
They are no longer needed since e4c7fa961e
2021-09-10 21:13:24 +02:00
Grégoire Paris
7fcab3d52e Merge pull request #8903 from olsavmic/fix-schema-validator-for-mapped-superclass-inheritance
SchemaValidator: Fix mapped superclass missing in discriminator map
2021-09-08 17:25:23 +01:00
Grégoire Paris
2d42d7835d Merge pull request #8919 from bhushan/feat/add-get-flat-array-results-by-key-for-query
feat(ScalarColumnHydrator): added ScalarColumnHydrator to get flat array results from query for single column
2021-09-08 17:02:58 +01:00
Bhushan
ed83825223 feat(ScalarColumnHydrator): get one dimensional array values for single column 2021-09-08 17:32:35 +02:00
Alexander M. Turek
beee34055a Merge pull request #8991 from derrabus/merge/2.9.x
Merge 2.9.x into 2.10.x
2021-09-08 09:07:18 +02:00
Alexander M. Turek
7abd106c8a Merge branch '2.9.x' into merge/2.9.x
* 2.9.x:
  Restore functional cache tests (#8981)
  Fix English in `note`. (#8987)
  Remove detach deprecation entry in UPGRADE.md (#8978)
  Bump to PHPStan 0.12.98 and Psalm 4.10.0 (#8979)

Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-09-08 08:57:00 +02:00
Alexander M. Turek
be2208f208 Remove unnecessary method_exists() checks (#8984) 2021-09-07 22:45:44 +02:00
Alexander M. Turek
316ba5f75e Restore functional cache tests (#8981) 2021-09-07 22:45:12 +02:00
ash-m
a08b6306d3 Fix English in note. (#8987)
Improper agreement; either:
 - Doctrine does not EVER touch ...
 - Doctrine NEVER touches ...
2021-09-07 22:44:43 +02:00
Simon Berger
21e71af13f Remove detach deprecation entry in UPGRADE.md (#8978) 2021-09-06 19:46:48 +02:00
Alexander M. Turek
f352b2a7ed Bump to PHPStan 0.12.98 and Psalm 4.10.0 (#8979) 2021-09-06 15:14:20 +02:00
Grégoire Paris
7bf1ad1a5a Merge pull request #8964 from derrabus/feature/dbal-3
DBAL 3
2021-08-31 22:42:46 +02:00
Alexander M. Turek
9de601f377 Merge pull request #8966 from doctrine/2.9.x
Merge 2.9.x into 2.10.x
2021-08-30 00:34:08 +02:00
carnage
df5086196f Added clarification of using change tracking policy on entities with embeddables (#7495)
* Added clarification of using change tracking policy on entities with embeddables

* Apply suggestions from code review

Co-Authored-By: carnage <carnage@users.noreply.github.com>

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-08-29 23:44:14 +02:00
Grégoire Paris
a427d7d852 Merge pull request #8961 from greg0ire/drop-table
Deprecate / remove TABLE id generator strategy
2021-08-29 23:43:09 +02:00
Grégoire Paris
efbcca3cb6 Get dbname from connection params first
Getting the database name from a connection object results in a PDO
object being created, which might in turn result in an error message if
the database does not exist. For instance it does with PostgreSQL.
In some other situations, like when using sqlite, there is no database
name though, so we still have to fallback on the previous behavior.
2021-08-29 21:08:17 +02:00
Alexander M. Turek
c65cc91f5b Support for DBAL 3 2021-08-29 21:08:17 +02:00
Grégoire Paris
d5f65ba62e Merge pull request #8962 from greg0ire/dont-swallow-exceptions
Stop swallowing exceptions
2021-08-29 20:54:57 +02:00
Grégoire Paris
ef9c984bcd Merge pull request #8946 from derrabus/bugfix/dbal-3-platforms
Support for DBAL 3's platform classes
2021-08-29 16:07:49 +02:00
Grégoire Paris
3074a4b02d Merge pull request #8932 from greg0ire/drop-support-for-generating-json-array-fields
Drop support for generating json array fields
2021-08-29 15:48:17 +02:00
Alexander M. Turek
fdbc6b6c13 Support for DBAL 3's platform classes
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-29 15:27:28 +02:00
Grégoire Paris
ea584992d5 Drop support for generating JSON_ARRAY fields
JSON_ARRAY has been deprecated in favor of JSON for a while, we should
not encourage people to generate new entities with it, since it will
introduce technical debt for them.
Support for JSON is added instead.
2021-08-29 14:40:29 +02:00
Grégoire Paris
96b4c763e4 Stop swallowing exceptions
This was probably done in order to get rid of exceptions about tables
already existing, but may and does swallow other exceptions as well, for
instance exceptions about sequences failing to be created on Oracle
because the identifier is too long. This makes it unnecessarily hard to
understand what is going on.
2021-08-28 18:02:41 +02:00
Grégoire Paris
0b55275418 Deprecate / remove TABLE id generator strategy
This strategy has been marked as TODO for more than 14 years. It should
be OK to remove some things related to it since they lead to an
exception being thrown.
2021-08-28 11:02:06 +02:00
Grégoire Paris
1963733311 Merge pull request #8959 from norkunas/fix-typehint
Fix `getEntityChangeSet` return typehint
2021-08-27 08:27:04 +02:00
Grégoire Paris
a06bbafd6a Merge pull request #8957 from derrabus/remove/connection-helper
Only wire ConnectionHelper if it's available
2021-08-25 19:33:54 +02:00
Grégoire Paris
250f7acc98 Merge pull request #8960 from inarli/2.9.x
Fix typo
2021-08-25 19:32:36 +02:00
İlkay Narlı
82f8a7c56a Fix typo 2021-08-25 17:54:14 +03:00
Alexander M. Turek
b345488272 Remove calls to fixSchemaElementName() (#8941) 2021-08-25 15:06:06 +02:00
Tomas
1de4020dc9 Fix getEntityChangeSet return typehint 2021-08-25 12:38:44 +03:00
Alexander M. Turek
dc6ed8716d Only wire ConnectionHelper if it's available
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-24 16:34:00 +02:00
Grégoire Paris
a8a9b2ae75 Merge pull request #8953 from derrabus/improvement/create-schema-manager
Don't call deprecated `getSchemaManager()`
2021-08-24 08:21:25 +02:00
Grégoire Paris
e03a30bd85 Merge pull request #8954 from derrabus/bugfix/dbal-exception
Fix references to deprecated `DBALException`
2021-08-24 08:19:26 +02:00
Alexander M. Turek
16357c5666 Fix references to deprecated DBALException
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-24 04:59:12 +02:00
Alexander M. Turek
131cc17384 Don't call deprecated getSchemaManager()
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-24 04:41:36 +02:00
Grégoire Paris
c18b474bbf Merge pull request #8934 from derrabus/remove/sql-result-casing
Remove calls to `AbstractPlatform::getSQLResultCasing()`
2021-08-23 20:46:40 +02:00
Grégoire Paris
e3b1ad5591 Merge pull request #8935 from derrabus/improvement/deprecated-calls
Remove calls to deprecated Connection methods
2021-08-23 18:32:14 +02:00
Alexander M. Turek
e6f1bb7dad Remove calls to AbstractPlatform::getSQLResultCasing() 2021-08-23 16:55:33 +02:00
Alexander M. Turek
730143e39b Remove calls to deprecated Connection methods 2021-08-23 16:54:59 +02:00
Alexander M. Turek
5cd00a50b2 Remove UUID generator strategy from fixtures (#8947) 2021-08-23 16:47:19 +02:00
Alexander M. Turek
3b8b3f9034 Remove ImportCommand from console (#8948) 2021-08-23 16:41:25 +02:00
Alexander M. Turek
bbe0b17b93 Don't pass false as lock mode to appendLockHint() (#8937) 2021-08-23 16:25:49 +02:00
Alexander M. Turek
7446569cf4 Remove remaining call to prefersSequences() (#8942) 2021-08-23 16:24:35 +02:00
Alexander M. Turek
930c2e093c Remove calls to EchoSQLLogger (#8940) 2021-08-23 16:23:34 +02:00
Alexander M. Turek
2154b513af Make mock layer compatible with DBAL 3 (#8949) 2021-08-23 16:22:43 +02:00
Grégoire Paris
93508438fa Merge pull request #8945 from greg0ire/document-possible-null-variable 2021-08-23 14:22:41 +02:00
Grégoire Paris
1490b2c3bb Merge pull request #8952 from greg0ire/ditch-simple-annotation-reader-2 2021-08-23 14:20:40 +02:00
Grégoire Paris
760abfc316 Drop more usages of SimpleAnnotationReader 2021-08-23 14:05:52 +02:00
Grégoire Paris
a1c15778ae Merge pull request #8951 from doctrine/2.9.x-merge-up-into-2.10.x_Ryg07QLG 2021-08-23 13:05:04 +02:00
Grégoire Paris
4f9c104ec9 Merge tag '2.9.5' into 2.9.x-merge-up-into-2.10.x_Ryg07QLG
2.9.x bugfix release (patch)

- Total issues resolved: **0**
- Total pull requests resolved: **2**
- Total contributors: **2**

 - [8930: Introduce 2.10 to readme](https://github.com/doctrine/orm/pull/8930) thanks to @SenseException

 - [8895: Implement &#95;&#95;serialize() and &#95;&#95;unserialize()](https://github.com/doctrine/orm/pull/8895) thanks to @derrabus
2021-08-23 12:35:37 +02:00
Grégoire Paris
77cc86ed88 Merge pull request #8916 from greg0ire/failing-test-8914
Check current class' discriminator map
2021-08-23 12:20:22 +02:00
Grégoire Paris
627113dc60 Merge pull request #8950 from derrabus/bump/phpstan
PHPStan 0.12.96
2021-08-23 00:02:24 +02:00
Alexander M. Turek
234829644c PHPStan 0.12.96
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-22 23:45:59 +02:00
Grégoire Paris
af4ecbadab Document possibly-null member variables
Many of the variables in AbstractHydrator are not initialized in the
constructor, and should be documented as possibly null because of that.
Introducing accessors that perform null checks allows to to have to do
these null checks when using the accessors.
Making the member variables private would be a backwards-compatibility
break and could be considered for the next major version.

This makes Psalm's and PHPStan's baselines smaller, and should make
implementing new hydrators easier.
2021-08-22 22:12:00 +02:00
Grégoire Paris
b20743b352 Merge pull request #8943 from simPod/wrap-types
Add missing EntityManagerInterface argument to callable that is being passed to `EM::wrapInTransaction()`
2021-08-22 18:17:41 +02:00
Grégoire Paris
e546cdef51 Merge pull request #8944 from derrabus/bugfix/datetime-constant
Remove references to `Type::DATETIME`
2021-08-22 18:10:22 +02:00
Alexander M. Turek
5f3e17152b Remove references to Type::DATETIME
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-22 17:43:07 +02:00
Simon Podlipsky
0d6ff230da Add missing EntityManagerInterface argument to callable that is being passed to EM::wrapInTransaction() 2021-08-22 17:26:57 +02:00
Grégoire Paris
14da92cf6b Merge pull request #8939 from derrabus/remove/driver-get-name
Remove calls to `Driver::getName()`
2021-08-22 16:27:48 +02:00
Grégoire Paris
563f3bdd85 Merge pull request #8938 from derrabus/bump-psalm
Bump Psalm to 4.9.3
2021-08-22 16:26:56 +02:00
Marcin Czarnecki
8bed63090b Throw exception NotSupported Exception for UuidGenerator with doctrine/dbal:3.x. (#8898)
Generating `getGuidExpression` has been removed in doctrine/dbal:3.x.

Partially fixes #8884
2021-08-22 16:05:22 +02:00
Alexander M. Turek
4f28ad6ccc Remove calls to Driver::getName()
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-22 15:56:18 +02:00
Alexander M. Turek
3f98633704 Bump Psalm to 4.9.3
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-22 15:43:55 +02:00
Grégoire Paris
e7758866c9 Merge pull request #8936 from derrabus/bugfix/reset-baseline
Reset Psalm baseline
2021-08-22 14:51:30 +02:00
Alexander M. Turek
1b1d1a246f Reset Psalm baseline
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-22 14:18:08 +02:00
Grégoire Paris
db175020e0 Merge pull request #8928 from simPod/wrap-types
Add types to `EM::wrapInTransaction()`
2021-08-21 16:06:49 +02:00
Grégoire Paris
1de28c2cab Merge pull request #8930 from doctrine/2.10-readme
Introduce 2.10 to readme
2021-08-21 16:05:17 +02:00
Claudio Zizza
565987f583 Introduce 2.10 to readme 2021-08-20 21:14:25 +02:00
Simon Podlipsky
44bea09b10 Add types to EM::wrapInTransaction() 2021-08-19 16:35:22 +02:00
Grégoire Paris
ae10af0259 Check current class' discriminator map
A class can be in its own discriminator map, as described in the
documentation example at
https://www.doctrine-project.org/projects/doctrine-orm/en/2.9/reference/inheritance-mapping.html#single-table-inheritance
Checking only the current class' discriminator map should be enough,
since it is set to a copy of its parent's discriminator map earlier.

Fixes #8914
2021-08-15 11:59:11 +02:00
Grégoire Paris
d636d79686 Merge pull request #8895 from derrabus/bugfix/serializable
Implement __serialize() and __unserialize()
2021-08-15 11:56:49 +02:00
Grégoire Paris
aee197f027 Merge pull request #8904 from carnage/refactoring-tests-backport
Refactoring more tests
2021-08-14 21:22:49 +02:00
Carnage
38c0f2b205 Change assertion order to ensure query count is tested correctly 2021-08-14 14:14:11 +01:00
Carnage
3dfbce1f40 Tidy up CS errors 2021-08-14 13:57:39 +01:00
Carnage
ad2cbd6afe Fix PHP Unit deprecations and removed methods 2021-08-14 13:31:55 +01:00
Gabriel Caruso
f34215d56a Refactoring more tests 2021-08-14 11:46:47 +01:00
Grégoire Paris
163aef158b Merge pull request #8915 from basseta/address-type-deprecation
Address Type deprecation messages
2021-08-12 23:13:56 +02:00
Antoine BASSET
40f613199a Address Type deprecation messages
This makes us more compatible with DBAL v3.
We didn't address Type::JSON_ARRAY because it has been removed
2021-08-12 17:11:41 +02:00
Grégoire Paris
ed230264fb Merge pull request #8913 from doctrine/2.9.x-merge-up-into-2.10.x_GK8LNgB8
Merge release 2.9.4 into 2.10.x
2021-08-11 23:32:36 +02:00
Vincent Langlet
b19a13f4ed Override getAssociationTargetClass phpdoc (#8907)
The upstream interface now allows null to be returned, but this
implementation never returns null, and consumers are expecting it not
to.
2021-08-11 22:53:03 +02:00
Grégoire Paris
03948f891e Merge pull request #8911 from greg0ire/2.10.x
Merge 2.9.x up into 2.10.x
2021-08-11 22:23:44 +02:00
Grégoire Paris
7dfa140542 Remove uneeded assertion 2021-08-11 22:14:33 +02:00
Grégoire Paris
01e7e45744 Merge remote-tracking branch 'origin/2.9.x' into 2.10.x 2021-08-11 22:11:32 +02:00
Grégoire Paris
1e2c0ce72d Merge pull request #8909 from greg0ire/fix-build
Fix build
2021-08-11 22:08:05 +02:00
Grégoire Paris
6a6bcc1e2b Ignore error caused by upstream package
See https://github.com/doctrine/collections/pull/282
2021-08-11 21:48:09 +02:00
Grégoire Paris
e2f54f6fa6 Remove phpstan-specific annotation
This is a direct consequence of https://github.com/doctrine/collections/pull/274
2021-08-11 21:48:09 +02:00
Grégoire Paris
e16a768916 Adapt baseline to new error message
The signature has become more precise, and so has the error message.
2021-08-11 21:48:03 +02:00
Benjamin Eberlei
25135d429f Merge 2.9.x into 2.10.x 2021-08-11 20:21:39 +02:00
Grégoire Paris
3b9e04e971 Merge pull request #8905 from nicolas-grekas/ret-types
Add explicit `@return` type next to `#[ReturnTypeWillChange]`
2021-08-11 00:13:16 +02:00
Grégoire Paris
7c1593742c Merge pull request #8870 from derrabus/improvement/prefers-sequences
Remove calls to prefersSequences()
2021-08-10 23:24:26 +02:00
Nicolas Grekas
fca1f5240d Add explicit @return type next to #[ReturnTypeWillChange] 2021-08-10 18:51:46 +02:00
Michael Olšavský
5685dc05f6 Fix mapped superclass missing in discriminator map 2021-08-09 16:24:37 +02:00
Grégoire Paris
4fa2f6baa4 Merge pull request #8896 from derrabus/bugfix/dont-pass-null
Don't pass null as parameter
2021-08-09 08:19:12 +02:00
Grégoire Paris
245563e1cf Merge pull request #8894 from derrabus/bugfix/return-type-will-change
Fix return types for PHP 8.1
2021-08-09 08:18:46 +02:00
Grégoire Paris
f980682829 Merge pull request #8897 from scyzoryck/dbal-3-fix-connection-params
Redeclare `$_attributes` property in `Configuration` class.
2021-08-09 08:18:10 +02:00
Grégoire Paris
b600c01bca Merge pull request #8419 from simPod/more-tests
Introduce `EntityManagerInterface#wrapInTransaction()`
2021-08-08 22:45:14 +02:00
Grégoire Paris
ad43cc04ff Merge pull request #8900 from simPod/psalm-10
Regenerate psalm baseline
2021-08-08 18:01:39 +02:00
Simon Podlipsky
c45402c1eb Regenerate psalm baseline 2021-08-08 17:48:07 +02:00
Grégoire Paris
a35ce43a61 Merge pull request #8902 from greg0ire/2.10.x
Merge 2.9.x into 2.10.x
2021-08-08 17:47:08 +02:00
Grégoire Paris
ed32b4c812 Merge remote-tracking branch 'origin/2.9.x' into 2.10.x 2021-08-08 17:38:45 +02:00
Grégoire Paris
a5436be939 Merge pull request #8899 from simPod/psalm
Regenerate psalm baseline
2021-08-08 17:13:19 +02:00
Simon Podlipsky
1246b3b5c3 Regenerate psalm baseline 2021-08-08 16:24:49 +02:00
Simon Podlipsky
4ad5d3edbd Introduce Doctrine\ORM\EntityManagerInterface#wrapInTransaction() 2021-08-08 16:22:53 +02:00
scyzoryck
355a4a126b Redeclare $_attributes property in Configuration class that has been removed in doctrine/dbal:3.x
To keep backward compatibility we need to redeclare this property to keep using it.
Partially fixes #8884
2021-08-08 12:22:16 +02:00
Alexander M. Turek
3464591763 Don't pass null as parameter
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-08 01:39:43 +02:00
Alexander M. Turek
ae4bcd61ee Implement __serialize() and __unserialize()
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-08 01:24:06 +02:00
Alexander M. Turek
dc960d7d96 Fix return types for PHP 8.1
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-08 01:10:58 +02:00
Grégoire Paris
7736429e9b Merge pull request #8892 from derrabus/bump/phpstan
Bump PHPStan to 0.12.94
2021-08-08 00:08:21 +02:00
Alexander M. Turek
edaa05a217 Remove calls to prefersSequences()
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-07 23:47:55 +02:00
Alexander M. Turek
7c6bea1307 Bump PHPStan to 0.12.94
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-07 22:12:21 +02:00
Grégoire Paris
c4456a2863 Merge pull request #8889 from scyzoryck/dbal-3-fix-possibly-null-argument
doctrine/dbal v3 - Make sure that values passed to are not null
2021-08-05 23:58:20 +02:00
scyzoryck
2bf0f64295 Make sure that passed values (offset and lock mode) will not be a null to meet changes in doctrine/dbal v3.
Fix psalm issues with type: `PossiblyNullArgument`, found after updating doctrine/dbal to v3. Override `null` passed as offset with `0` in calls to `Doctrine\DBAL\Platforms\AbstractPlatform::modifyLimitQuery`. Override `null` passed as lockMode with `LockMode::NONE` in calls to `Doctrine\DBAL\Platforms\AbstractPlatform::appendLockHint`.
Partialy fixes #8884
2021-08-05 22:30:58 +02:00
Grégoire Paris
12705b5c3e Merge pull request #8820 from beberlei/GH-8818-EntityNamespaceAliasDeprecation
[GH-8818] Deprecate entity namespace short aliases.
2021-08-05 19:49:39 +02:00
Benjamin Eberlei
913700b116 Remove alias in docs 2021-08-05 00:48:28 +02:00
Grégoire Paris
106ed8009a Merge pull request #8883 from dopeh/patch-1
Fix getting-started example by including cache
2021-08-05 00:20:07 +02:00
Pep
b2e00f6086 Fix getting-started example by including cache
The getting started example does not work without a valid cache library, this adds symfony/cache.
2021-08-04 23:04:46 +02:00
Benjamin Eberlei
0540485b14 Update UPGRADE.md 2021-08-04 22:29:12 +02:00
Benjamin Eberlei
e5228ba66f [GH-8818] Deprecate entity namespace short aliases. 2021-08-04 22:17:09 +02:00
Grégoire Paris
e09f126abf Merge pull request #8852 from greg0ire/backport-6943
Remove possibility to extend the doctrine mapping xml schema with anything
2021-08-04 07:43:13 +02:00
Grégoire Paris
055b646d9a Merge pull request #8769 from greg0ire/remove-unhelpful-template
Make templating Psalm-specific
2021-08-04 07:42:29 +02:00
Grégoire Paris
acdbbdacab Merge pull request #8874 from greg0ire/build-with-dbal-3
Build with DBAL 3
2021-08-03 23:52:55 +02:00
Grégoire Paris
6a267f588c Build with DBAL 3
Making these jobs green will not result in a comprehensive result of the
features, but it is a good start, and having them should give a good
overview of what is left to do.
2021-08-03 19:47:30 +02:00
Grégoire Paris
c1c3c89836 Merge pull request #8855 from piowin/GH8443-failing-test
Failing test for GH8443
2021-08-03 07:53:38 +02:00
Grégoire Paris
692277e72c Merge pull request #8862 from carnage/this-to-self
Change $this->assert* to self::assert* in unit tests
2021-08-03 07:53:00 +02:00
Grégoire Paris
47267b0da5 Merge pull request #8875 from doctrine/2.9.x
Merge 2.9.x up into 2.10.x
2021-08-02 23:57:34 +02:00
Grégoire Paris
6fc0176f87 Merge pull request #8872 from simPod/fix-build
Fix CI SA failures
2021-08-02 23:48:02 +02:00
Grégoire Paris
8bb1454d5d Merge pull request #8859 from greg0ire/backport-7110
Drop tools/sandbox
2021-08-02 19:13:22 +02:00
Simon Podlipsky
42126dc1bd Fix CI SA failures 2021-08-02 18:30:31 +02:00
Grégoire Paris
5861b0575d Merge pull request #8861 from carnage/dbal-compat
Fix compatibility with DBAL develop
2021-07-25 20:12:15 +02:00
Carnage
afe0d1c810 Change ->assert* to self::assert* 2021-07-24 19:10:38 +01:00
Grégoire Paris
bc9e0b3d2c Merge pull request #8860 from t-richard/patch-1
Fix typo in "Working with Objects"
2021-07-24 14:55:58 +02:00
Michael Moravec
0b6ab2d1a7 Fix compatibility with DBAL develop
* ResultStatement signature BC break
* PDO::FETCH_* -> FetchMode::*
* PDO::PARAM_* -> ParameterType::*
* AbstractPlatform::DATE_INTERVAL_UNIT_* -> DateIntervalUnit::*
* AbstractPlatform::TRIM_* -> TrimMode::*
2021-07-24 13:24:39 +01:00
Thibault RICHARD
aa9d0148d5 Fix typo in "Working with Objects" 2021-07-24 14:13:29 +02:00
Michael Moravec
183f4a5211 Drop tools/sandbox 2021-07-24 10:31:50 +02:00
21skills
86703cbc73 Extra brackets if no cti joins fix
Continuation of a problem from
https://github.com/doctrine/orm/pull/6812
The same problem appears if you add WITH condition to the joined entity with discriminator
2021-07-23 21:27:05 +02:00
piowin
0504c535f1 Failing test for GH8443 2021-07-23 21:27:05 +02:00
mike
84afd6c937 Removing all the occurence of any
If someone wants to override the doctrine mapping that person should
write their own mapping file.
2021-07-21 19:48:11 +02:00
mike
7065070838 replacing all the sequence by choice
The order is never important in the declaration
2021-07-21 19:45:36 +02:00
Grégoire Paris
3e18990e90 Merge pull request #8851 from greg0ire/backport-7008
Remove unused exceptions
2021-07-21 07:45:28 +02:00
Grégoire Paris
6b481be074 Remove unused exceptions 2021-07-20 23:28:50 +02:00
Grégoire Paris
52f5528d3a Merge pull request #8838 from carnage/remove-expensive-array-ops
Remove expensive array ops
2021-07-20 23:23:13 +02:00
Grégoire Paris
0db4a3936f Merge pull request #8841 from greg0ire/strict_types
Enable strict mode
2021-07-20 23:19:35 +02:00
Grégoire Paris
ccc2993610 Merge pull request #8837 from greg0ire/backport-6878
Replace spl_object_hash() with spl_object_id()
2021-07-20 23:19:18 +02:00
Grégoire Paris
b7c0e97e71 Assert child property is not null
It is then passed to a class whose constructor cannot work with null.
2021-07-20 21:56:31 +02:00
Grégoire Paris
6c7e854797 Enable strict mode 2021-07-20 21:56:29 +02:00
Grégoire Paris
efb74f3ba3 Document possible return type 2021-07-20 21:56:11 +02:00
Grégoire Paris
270e7a4234 Pass strings to SimpleXMLELement::addAttribute() 2021-07-20 21:56:10 +02:00
Grégoire Paris
decbd93af4 Cast mode to string
It might be an integer, in fact it probably is, but the phpdoc says it
might be a string too.
2021-07-20 21:55:49 +02:00
Grégoire Paris
4770008cb7 Cast string value to float
round() becomes stricter with PHP 8 and no longer accepts strings.
2021-07-20 21:55:49 +02:00
Grégoire Paris
1413111099 Ensure walkLiteral returns a string
By contract, it is supposed to.
2021-07-20 21:55:45 +02:00
Grégoire Paris
60cf2c785f Merge pull request #8846 from greg0ire/backport-6974
Use $strict param in functions that have it
2021-07-19 20:14:10 +02:00
Grégoire Paris
ee7ddac7a2 Merge pull request #8848 from greg0ire/2.10.x
Merge 2.9.x into 2.10.x
2021-07-18 12:39:24 +02:00
Grégoire Paris
e7de028d2d Merge remote-tracking branch 'origin/2.9.x' into 2.10.x 2021-07-18 12:05:37 +02:00
Grégoire Paris
3c4009df38 Merge pull request #8847 from greg0ire/adapt-tests-to-new-wrapping
Adapt tests to new way of wrapping
2021-07-18 12:04:40 +02:00
Grégoire Paris
0a1be2cc21 Adapt tests to new way of wrapping
Namespacing is configured here, which means instead of just one layer,
we have a PSR cache wrapped in a doctrine cache with namespacing, itself
wrapped again with a PSR cache.
2021-07-18 11:00:46 +02:00
Grégoire Paris
e39a9ba199 Regenerate Psalm baseline
It looks like using --update-baseline can make number of occurences
drop, but will not result in a removal of some code elements.
2021-07-17 10:37:07 +02:00
Grégoire Paris
65a55cea7e Use $strict param in functions that have it 2021-07-15 23:18:27 +02:00
Grégoire Paris
9e6bc35944 Merge pull request #8845 from greg0ire/backport-6929
[CS] Clean elses
2021-07-15 22:51:47 +02:00
Grégoire Paris
c289b79fb2 Merge pull request #8844 from greg0ire/backport-6549
Ditch SimpleAnnotationReader
2021-07-15 22:32:22 +02:00
Grégoire Paris
03a728dfc8 Ditch SimpleAnnotationReader
We want to get rid of it, because it is not really usable in context
when you use annotations from more than one namespace. This implies
importing classes for all annotations in use.
2021-07-15 22:23:40 +02:00
Grégoire Paris
558ebcdc83 Merge pull request #8842 from greg0ire/backport-6963
Add documentation for ToolEvents
2021-07-15 08:06:59 +02:00
Gabriel Caruso
4b06fb2424 [CS] Clean elses 2021-07-14 22:08:46 +02:00
Claudio Zizza
474218395a Add root namespace to full classname 2021-07-14 11:06:35 +02:00
Claudio Zizza
70092b9800 Update loadClassMetadata example and add namespaces 2021-07-14 11:04:41 +02:00
Claudio Zizza
cd13addcfc Add ToolEvents of SchemaTool 2021-07-14 11:03:08 +02:00
Grégoire Paris
5b6a1d7a40 Merge pull request #8836 from greg0ire/explicit-type-casts
Make implicit type casts explicit
2021-07-13 23:53:35 +02:00
Marco Pivetta
74ffc25b50 Removing useless post-array-population association hydration via array_walk() 2021-07-11 14:40:22 +02:00
Marco Pivetta
91de49e6a6 Removing is_array check on a type that can only have two possible states - using instanceof instead 2021-07-11 14:40:21 +02:00
Marco Pivetta
102484dea8 Removing useless array_key_exists() calls, using ?? operator instead 2021-07-11 14:34:21 +02:00
Marco Pivetta
f9b9a14275 Removing useless variable 2021-07-11 14:34:17 +02:00
Marco Pivetta
8b3d5848a2 Removing useless checking for never-used parameter, inlining merge operation 2021-07-11 14:33:49 +02:00
Marco Pivetta
9c5d676111 Replacing possible O(n^2) operation from PersistentCollection diffing operations 2021-07-11 14:33:43 +02:00
Michael Moravec
84ad007de3 Replace spl_object_hash() with spl_object_id()
It is more efficient, and can be provided to 7.1 users thanks to
symfony/polyfill-php72.
2021-07-10 11:55:13 +02:00
Grégoire Paris
e88d261dca Make implicit type casts explicit 2021-07-10 10:41:25 +02:00
Benjamin Eberlei
95408cd8e4 [docs] Fix sentence about how nullable types affecting column definitions. (#8835) 2021-07-08 22:22:34 +02:00
Thomas Landauer
182bdaac6b Adding fields to Index (#8830)
* Adding `fields` to Index

I guess this was just forgotten here.
Wording is taken from https://www.doctrine-project.org/projects/doctrine-orm/en/2.9/reference/annotations-reference.html#index

* Update attributes-reference.rst
2021-07-08 22:06:57 +02:00
Grégoire Paris
3c805b22b4 Merge pull request #8825 from greg0ire/github-templates
Backport Github issue and PR templates
2021-07-06 08:34:55 +02:00
Grégoire Paris
7a56ca13f8 Merge pull request #8824 from greg0ire/remove-license-header
Drop license header
2021-07-06 08:30:55 +02:00
Grégoire Paris
6a41ab56ce Backport Github issue and PR templates 2021-07-05 23:14:47 +02:00
fridde
802dd54f07 Referenced new support for PHP8 attributes (#8823) 2021-07-05 22:06:04 +02:00
Grégoire Paris
be2d99e5f6 Drop license header 2021-07-05 21:26:41 +02:00
Grégoire Paris
0a663da5b6 Merge pull request #8822 from greg0ire/2.10.x 2021-07-05 10:36:24 +02:00
Grégoire Paris
0b3fc57458 Merge remote-tracking branch 'origin/2.9.x' into 2.10.x 2021-07-05 10:14:57 +02:00
Grégoire Paris
836c0d3803 Merge pull request #8814 from greg0ire/backport-7158
Proposed corrected typo in demo code.
2021-07-05 10:11:50 +02:00
Grégoire Paris
aa3ed91dd2 Merge pull request #8821 from greg0ire/fix-phpstan 2021-07-05 10:01:59 +02:00
Grégoire Paris
f542dde131 Pin PHPStan to current version
We want to control upgrades to avoid suddenly failing builds.
2021-07-05 09:22:54 +02:00
Grégoire Paris
a165d4af7c Adapt ignore rules to new PHPStan version 2021-07-05 09:13:37 +02:00
Cathy Guilbaud
ff13059ba2 Proposed corrected typo in demo code.
changed $payed to $paid.
2021-07-04 17:34:22 +02:00
Grégoire Paris
c3953435dd Merge pull request #8806 from greg0ire/resurrect-phpbench
Resurrect phpbench
2021-07-03 23:21:21 +02:00
Grégoire Paris
37f60be836 Merge pull request #8813 from greg0ire/deprecate-uuid-generator
Deprecate all things related to DB-generated UUIDs
2021-07-03 22:38:44 +02:00
Grégoire Paris
9f5b38f539 Deprecate all things related to DB-generated UUIDs
DB-generated UUIDs have been deprecated in the DBAL.
2021-07-03 21:52:26 +02:00
Grégoire Paris
665e5c49ea Merge pull request #8812 from greg0ire/update-baseline
Update baseline
2021-07-03 21:31:33 +02:00
Grégoire Paris
3a10e07dfc Update baseline
Many deprecations have been addressed, particularly DBAL ones.
2021-07-03 21:21:24 +02:00
Grégoire Paris
909de45c5c Merge pull request #8811 from greg0ire/2.10.x
Merge 2.9.x into 2.10.x
2021-07-03 21:17:46 +02:00
Grégoire Paris
5aa7f75f77 Merge remote-tracking branch 'origin/2.9.x' into 2.10.x 2021-07-03 21:02:03 +02:00
Grégoire Paris
8f2aef5fa3 Merge pull request #8810 from greg0ire/update-baseline
Update Psalm baseline
2021-07-03 21:00:26 +02:00
Grégoire Paris
05be0e8bbd Update Psalm baseline
It seems some deprecations have been addressed recently.
2021-07-03 20:46:37 +02:00
Grégoire Paris
64cf6edea6 Use consistent style for the OR operator 2021-07-03 12:07:43 +02:00
Grégoire Paris
7608a40463 Run phpbench in the CI 2021-07-03 12:05:45 +02:00
Grégoire Paris
b1f6f9bfc3 Make phpbench runnable again
There seems to have been a new major version.
2021-07-03 11:57:32 +02:00
Grégoire Paris
71af666c38 Merge pull request #8796 from derrabus/improvement/hydrators-dbal-3
Migrate hydrators and queries to DBAL's new Result interface
2021-06-30 23:39:19 +02:00
Grégoire Paris
3fe980de96 Merge pull request #8801 from derrabus/bugfix/ignore-return-type-will-change
Ignore errors about missing ReturnTypeWillChange class
2021-06-30 23:02:01 +02:00
Grégoire Paris
f5d988de4e Merge pull request #8784 from greg0ire/undeprecate-passing-null
Undeprecate targetEntity omission for some types
2021-06-30 21:42:13 +02:00
Grégoire Paris
e840aef630 Merge pull request #8798 from greg0ire/backport-7776
Remove hack to access class scope inside closures
2021-06-30 08:20:29 +02:00
Gabriel Caruso
2936bac7ec Remove hack to access class scope inside closures
This is possible since 5.4.
2021-06-29 23:56:37 +02:00
Grégoire Paris
55971d2f05 Merge pull request #8799 from greg0ire/backport-6909-6910
Combine consecutive issets and unsets
2021-06-29 23:51:35 +02:00
Grégoire Paris
1f6bfe1754 Merge pull request #8800 from jderusse/fix-exception
Fix exception not thrown by "getEntityIdentifier"
2021-06-29 23:50:41 +02:00
Alexander M. Turek
0723e664e1 Migrate hydrators and queries to DBAL's new Result interface
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-06-29 23:04:15 +02:00
Alexander M. Turek
b0c7993dd6 Ignore errors about missing ReturnTypeWillChange class
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-06-29 22:50:16 +02:00
Jérémy Derussé
796af72650 Fix exception not thrown by "getEntityIdentifier" 2021-06-29 22:32:29 +02:00
Gabriel Caruso
02174fb68f Combine consecutives issets 2021-06-28 23:33:33 +02:00
Gabriel Caruso
92c51de734 Combine consecutive unsets 2021-06-28 23:32:02 +02:00
Claudio Zizza
233d9b0276 Update session examples in docs (#8795)
The session examples contained approaches that aren't favorable for an application
and needed an overhaul using either scalar values or an DTO instead of the whole
entity with detach() and merge().
2021-06-28 23:23:40 +02:00
Grégoire Paris
b6d7826dc7 Merge pull request #8789 from greg0ire/backport-7292
Use a more concrete, less confusing example
2021-06-28 23:09:24 +02:00
Grégoire Paris
ce8de6df7f Merge pull request #8794 from derrabus/improvement/dbal-depecations
Fix deprecated DBAL calls
2021-06-28 10:58:20 +02:00
Grégoire Paris
b3ee7141eb Use a more concrete, less confusing example
I picked a toothbrush because you usually do not share it with other
persons, feel free to propose something else.
2021-06-28 00:03:29 +02:00
Grégoire Paris
73aa6e8352 Merge pull request #8791 from greg0ire/backport-docs-batch-2
Backport docs batch 2
2021-06-28 00:00:10 +02:00
Grégoire Paris
d1e5c59af9 Merge pull request #8792 from greg0ire/backport-malukenho
Backport malukenho's work
2021-06-27 23:59:19 +02:00
Grégoire Paris
e792777187 Merge pull request #8793 from greg0ire/backport-slamdunk
Backport slamdunk's work
2021-06-27 23:58:46 +02:00
Alexander M. Turek
afa837a361 Fix deprecated DBAL calls 2021-06-27 18:26:37 +02:00
Filippo Tessarotto
5a9bd0904b Apply ternary_operator_spaces 2021-06-27 12:18:14 +02:00
Filippo Tessarotto
b50d06ae58 Apply align_multiline_comment 2021-06-27 12:15:37 +02:00
Filippo Tessarotto
220201cf14 Apply escape_implicit_backslashes,heredoc_to_nowdoc 2021-06-27 12:06:02 +02:00
Filippo Tessarotto
5fa3a92ecb Apply bare heredoc_to_nowdoc 2021-06-27 12:05:50 +02:00
Jefersson Nathan
fef46263b5 Remove unused return statement
Signed-off-by: Jefersson Nathan <admin@phpse.net>
2021-06-27 11:09:23 +02:00
Jefersson Nathan
e6d9f99ac0 Remove redundant php-docs
Signed-off-by: Jefersson Nathan <admin@phpse.net>
2021-06-27 11:09:21 +02:00
Igor Pellegrini
f3e87d2c2f Fix bullet list not rendering correctly on Github
As *rst*, if reading the tutorial on the Github repository, the items
are not seen as elements of a bullet list, hence they are not rendered
and they are collapsed in a single line of text.

Fix won't affect how it renders on
[doctrine-project.org](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html).
2021-06-27 10:42:17 +02:00
Grégoire Paris
244e7c7c29 Merge pull request #8787 from greg0ire/optional-doctrine-annotations
Make doctrine/annotations an optional dependency
2021-06-27 10:15:00 +02:00
Catalin Ciobanu
53ba6b9732 Updated docblock 2021-06-26 23:04:56 +02:00
Jachim Coudenys
b3f580bf5e Fix the link to the 'Change Tracking Policies' documentation 2021-06-26 23:04:12 +02:00
Alex Rock Ancelet
774b5cbdd4 document using DTOs and entities as Value Objects 2021-06-26 22:51:22 +02:00
Gabriel Caruso
7fa3e6ec7c Use HTTPS instead of HTTP 2021-06-26 22:43:16 +02:00
Grégoire Paris
e743981f8d Merge pull request #8790 from greg0ire/backport-docs-batch
Backport docs batch
2021-06-26 22:18:30 +02:00
Haralan Dobrev
a469514ef0 Remove obsolete backslashes from underscores
These backslashes were not correctly migrated when updating the website
and it prevents search for some important terms like the query hints.
2021-06-26 18:57:58 +02:00
Jachim Coudenys
9fb13dbe28 Fix the result cache documentation (it caches raw data, not hydrated entities) 2021-06-26 17:12:28 +02:00
Adrian Föder
fc97041e49 [TASK] Streamline code block type hints for readability
This corrects a mistake with a given type hint in
the PHP code blocks as well as adds further for
consistency and brevity.
2021-06-26 16:14:05 +02:00
Claudio Zizza
f8f3b196a1 Extend documentation of arbitrary joins 2021-06-26 16:13:56 +02:00
Claudio Zizza
c01961840e Fix of variable typo in cache usage example 2021-06-26 16:13:47 +02:00
Andreas Möller
6ef1367cde Fix: Consistently format inversedBy and mappedBy attributes 2021-06-26 16:13:39 +02:00
Adrian Föder
3572b49e6a [FEATURE] Mention and link identifier generation strategies 2021-06-26 16:13:30 +02:00
Maciej Malarz
587c5f5ad6 Fix Criteria's orderBy example 2021-06-26 16:13:23 +02:00
someniatko
4f0a04e0eb Better PHPDoc for AbstractQuery cache methods
Updated useResultCache() and setResultCacheLifetime() docs to clearly state $lifetime is measured in seconds;
Added description to useResultCache()'s params. Renamed $bool => $useCache.
2021-06-26 16:13:19 +02:00
Andreas Möller
4451019dc0 Fix: Attributes vs. annotations 2021-06-26 15:56:33 +02:00
Gabriel Ostrolucký
c021426613 Fix #2935 [DDC-2236] Add note that Paginator might screw aggreg. queries 2021-06-26 15:56:09 +02:00
Gabriel Ostrolucký
243c8bff1f Fix EBNF of InExpression (StateFieldPath -> Arithmetic) 2021-06-26 15:55:18 +02:00
Gert de Pagter
5bbad8c403 Require ctype extension 2021-06-26 15:53:07 +02:00
Thomas Landauer
6c6b919788 Added UNIQUE INDEX to generated SQL schema
When I tried the example code, I got this unique index too.

Plus my `ALTER TABLE` statement was a little different from the one in the docs:
> ALTER TABLE cart ADD CONSTRAINT FK_BA388B79395C3F3 FOREIGN KEY (customer_id) REFERENCES customer (id)
Should I change that too?
2021-06-26 15:51:51 +02:00
Thomas Bisignani
b37c433080 [Documentation] Fixed comments syntax 2021-06-26 15:50:34 +02:00
Claudio Zizza
173f31a14a Add readOnly attribute to annotation example 2021-06-26 15:48:33 +02:00
Guido Sangiovanni
319acb1076 typo in class description
fixed typo in class description
2021-06-26 15:46:45 +02:00
Arman
242d2c1c41 Remove year from license 2021-06-26 15:46:14 +02:00
Jérôme Vasseur
5c95ce5c21 Fix EntityRepository constructor phpdoc
Remove redundant phpdoc from EntityRepository constructor
2021-06-26 15:45:02 +02:00
Grégoire Paris
fa583f6533 Make doctrine/annotations an optional dependency
First, there are other drivers than the annotations-based one, and
second, one of them is base on attributes, which are basically
annotations native to PHP.

Closes #8785
2021-06-26 09:51:42 +02:00
Grégoire Paris
7a78fd2900 Undeprecate targetEntity omission for some types
Some relationship types are attached to properties that can be typed
since php 7.4.
To avoid repeating the property type in targetEntity, an autodetection
feature has been developed that allows building the mapping from that
type information and annotations.
Omitting the targetEntity stays deprecated for ManyToMany as there is no
auto-detection for that yet (although one could be built by analyzing
phpdoc annotations).
2021-06-24 23:41:05 +02:00
Grégoire Paris
67fc57b5e1 Merge pull request #8780 from derrabus/improvement/deprecated-constants
Fix usages of deprecated DBAL constants
2021-06-23 09:13:32 +02:00
Grégoire Paris
b4547888d9 Merge pull request #8782 from doctrine/2.9.x
Merge 2.9.x up into 2.10.x
2021-06-23 08:28:06 +02:00
Grégoire Paris
f233e4cf6b Merge pull request #8781 from derrabus/bugfix/static-analysis
Fix Psalm/PHPStan errors
2021-06-23 08:20:28 +02:00
Alexander M. Turek
7277afefb9 Fix usages of deprecated DBAL constants 2021-06-23 01:30:14 +02:00
Alexander M. Turek
b9f7e09401 Fix Psalm/PHPStan errors 2021-06-23 01:12:54 +02:00
Julio Montoya
5e91eea726 Link to correct section (#8778) 2021-06-22 13:12:54 +02:00
Julio Montoya
10922a5329 Spell "entity" properly (#8777) 2021-06-22 13:09:57 +02:00
Grégoire Paris
fbf793af0e Merge pull request #8543 from simonberger/add_missing_param_and_return_attributes
Add missing @param and @return PHPDoc attributes
2021-06-20 21:51:38 +02:00
Simon Berger
a26ae0648f Add missing @param and @Result PHPDoc attributes 2021-06-20 21:42:50 +02:00
Grégoire Paris
8bb564d5fe Limit template annotations to Psalm
Phpstan requires that the template can be resolved in all cases, while
Psalm seems to tolerate this ambiguous situation.
See https://github.com/phpstan/phpstan/issues/5175#issuecomment-861437050
2021-06-16 08:13:57 +02:00
Grégoire Paris
08149ea0b9 Merge pull request #8692 from greg0ire/split_orm_exception
Split the ORMException class
2021-06-15 23:43:16 +02:00
Grégoire Paris
06844484dd Split the ORMException class 2021-06-15 23:34:35 +02:00
Matthias Pigulla
7827869191 Make ResolveTargetEntityListener deal with the DiscriminatorMap as well (#8402) 2021-06-15 08:08:15 +02:00
Grégoire Paris
23602784f8 Merge pull request #8765 from doctrine/2.9.x-merge-up-into-2.10.x_osteH8Wj
Merge release 2.9.3 into 2.10.x
2021-06-14 18:40:15 +02:00
Philipp Fritsche
82e77cf508 Bugfix: handle repeatable attributes (#8756)
* fix: handle repeatable attributes

* Restore interface compatibility

A reader is supposed to only ever return objects. By introducing
RepeatableAttributeCollection, we fulfill the interface and improve
clarity.

* refactor: accurate type declarations and returns

* refactor: remove unused use

* Ignore AttributeReader in phpstan and psalm to pass on CI running PHP 7.4.

* test: isTransient

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
Co-authored-by: Benjamin Eberlei <kontakt@beberlei.de>
2021-06-13 12:29:22 +02:00
Grégoire Paris
1518b40dd2 Merge pull request #8758 from greg0ire/restore-bc-for-annotations
Restore bc for annotations
2021-06-10 19:12:13 +02:00
Grégoire Paris
10e41ec8bc Deprecate required of mandatory arguments 2021-06-09 23:04:16 +02:00
Grégoire Paris
303e346390 Restore backwards-compatibility
There used to be no constructor in this class, adding one with mandatory
arguments was technically a BC-break.

Fixes #8753
2021-06-09 23:04:16 +02:00
Grégoire Paris
fc7db8f59e Merge pull request #8747 from greg0ire/fix-attributes-syntax
Use correct named argument syntax in docs
2021-06-07 22:41:13 +02:00
Grégoire Paris
ae7f04ea53 Use correct named argument syntax in docs 2021-06-07 21:06:44 +02:00
Grégoire Paris
b8808099ea Merge pull request #8742 from derrabus/bugfix/return-type-will-change
Add ReturnTypeWillChange to ReflectionEmbeddedProperty
2021-06-05 23:52:49 +02:00
Alexander M. Turek
6432a3eeb2 Add ReturnTypeWillChange to ReflectionEmbeddedProperty 2021-06-05 22:51:55 +02:00
Grégoire Paris
3a0f60d6c6 Merge pull request #8734 from VincentLanglet/fixMetadata
Fix metadata constructor inference by phpstan
2021-06-05 21:48:17 +02:00
Grégoire Paris
ee19cf5cfd Merge pull request #8740 from VincentLanglet/fixMetada2
Make ClassMetadata covariant
2021-06-03 10:21:39 +02:00
Vincent Langlet
66daafd597 Make ClassMetadata covariant 2021-06-03 09:04:46 +02:00
Vincent Langlet
249c4fe61b Remove currentWorkingDirectory 2021-06-01 09:28:45 +02:00
Vincent Langlet
89673c60bf Fix metadata constructor inference by phpstan 2021-05-31 23:53:58 +02:00
github-actions[bot]
f8bcd2d200 Merge release 2.9.2 into 2.10.x (#8733)
* Mark 2.8.x as unmaintained, and 2.9.x as current

* Fix ClassMetadataInfo template inference

* Fix metadata cache compatibility layer

* Bump doctrine/cache patch dependency to fix build with lowest deps

* Add generics to parameters

* Add note about performance and inheritance mapping (#8704)

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>

* Adapt flush($argument) in documentation as it's deprecated. (#8728)

* [GH-8723] Remove use of nullability to automatically detect nullable status (#8732)

* [GH-8723] Remove use of nullability to automatically detect nullable status.

* [GH-8723] Make Column::$nullable default to false again, fix tests.

* Add automatic type detection for Embedded. (#8724)

* Add automatic type detection for Embedded.

* Inline statement.

Co-authored-by: Benjamin Eberlei <kontakt@beberlei.de>

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
Co-authored-by: Vincent Langlet <VincentLanglet@users.noreply.github.com>
Co-authored-by: Andreas Braun <git@alcaeus.org>
Co-authored-by: Fran Moreno <franmomu@gmail.com>
Co-authored-by: Juan Iglesias <juan.manuel.iglesias93@gmail.com>
Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
Co-authored-by: Yup <warxcell@gmail.com>
Co-authored-by: Benjamin Eberlei <kontakt@beberlei.de>
2021-05-31 17:45:06 +02:00
Yup
75b4b88c5b Add automatic type detection for Embedded. (#8724)
* Add automatic type detection for Embedded.

* Inline statement.

Co-authored-by: Benjamin Eberlei <kontakt@beberlei.de>
2021-05-31 11:53:14 +02:00
Benjamin Eberlei
d9e59d6862 [GH-8723] Remove use of nullability to automatically detect nullable status (#8732)
* [GH-8723] Remove use of nullability to automatically detect nullable status.

* [GH-8723] Make Column::$nullable default to false again, fix tests.
2021-05-31 10:19:16 +02:00
Yup
5fa94969de Adapt flush($argument) in documentation as it's deprecated. (#8728) 2021-05-29 22:22:19 +02:00
Juan Iglesias
f2c3ddac97 Add note about performance and inheritance mapping (#8704)
Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
2021-05-27 08:27:55 +02:00
Grégoire Paris
46f0da9ffa Merge pull request #8710 from franmomu/recompute
Handle generic parameters in UnitOfWork
2021-05-25 13:29:21 +02:00
Fran Moreno
1e832a6782 Add generics to parameters 2021-05-25 13:01:47 +02:00
Grégoire Paris
56bdb44efd Merge pull request #8722 from alcaeus/fix-metadata-cache-clear 2021-05-25 12:55:00 +02:00
Andreas Braun
fffac44991 Bump doctrine/cache patch dependency to fix build with lowest deps 2021-05-25 11:58:11 +02:00
Andreas Braun
e42b3d6584 Fix metadata cache compatibility layer 2021-05-25 10:38:00 +02:00
Grégoire Paris
7ab2c3abbd Merge pull request #8708 from VincentLanglet/patch-2
Fix ClassMetadaInfo template inference
2021-05-25 08:49:50 +02:00
Grégoire Paris
498c816b65 Merge pull request #8717 from greg0ire/update-branch-metadata
Mark 2.8.x as unmaintained, and 2.9.x as current
2021-05-25 00:01:21 +02:00
Vincent Langlet
eec740079d Fix ClassMetadataInfo template inference 2021-05-24 21:52:40 +02:00
Grégoire Paris
c359715a97 Mark 2.8.x as unmaintained, and 2.9.x as current 2021-05-24 21:32:26 +02:00
Benjamin Eberlei
f3e55fae9f Update .doctrine-project.json to include 2.9 stable and 2.10 upcoming 2021-05-24 17:54:12 +02:00
Michael Babker
91c3bd4121 Fix links to attribute sections (#8714) 2021-05-24 17:52:30 +02:00
Peter Gribanov
e6cf12c66f remove usage Webmozart (#8713) 2021-05-24 17:50:15 +02:00
Grégoire Paris
99d67cb77d Merge pull request #8705 from greg0ire/2.9.x
Merge 2.8.x into 2.9.x
2021-05-21 09:15:28 +02:00
Grégoire Paris
43f66d5808 Merge remote-tracking branch 'origin/2.8.x' into 2.9.x 2021-05-21 09:04:27 +02:00
Grégoire Paris
a6577b89a2 Merge pull request #8701 from jderusse/symfony6
Allow Symfony 6.0
2021-05-20 07:58:49 +02:00
Jérémy Derussé
0ca87566a9 Allow Symfony 6.0 2021-05-20 07:48:21 +02:00
Grégoire Paris
5d01f94a36 Merge pull request #8699 from greg0ire/fix-psalm
Fix some static analysis issues
2021-05-20 07:43:12 +02:00
Grégoire Paris
3d02b02636 Update static analysis baseline files
These issues were not introduced with new code, but with upgrades.
2021-05-20 00:03:39 +02:00
Grégoire Paris
6de321cb09 Address Psalm issues introduced by persistence 2021-05-20 00:03:39 +02:00
Grégoire Paris
535bc92dc8 Merge pull request #8700 from deguif/fix-undefined-offset
Fix undefined index
2021-05-18 12:20:38 +02:00
François-Xavier de Guillebon
ebb5d03f7a Fix undefined offset 2021-05-18 10:00:19 +02:00
Grégoire Paris
8e13369621 Merge pull request #8698 from deguif/cache-deprecation
Fix cache deprecation
2021-05-17 22:15:13 +02:00
François-Xavier de Guillebon
8eff4b775a Fix cache deprecation 2021-05-17 21:33:52 +02:00
Grégoire Paris
b85403d0a2 Merge pull request #8691 from alcaeus/check-deprecations
Check for use of deprecated API with Psalm
2021-05-15 18:50:30 +02:00
Andreas Braun
22ce3adfce Move to psalm level 2
This converts more issues to errors, most notably around deprecations. This can be used to later remove deprecated API.
2021-05-15 17:01:43 +02:00
tweet9ra
3a194ad699 SimpleObjectHydrator: skip unsuit custom type before converting it (#8566)
When using inheritance, it is possible to map the same column to properties of
different child classes. This can result in the same column being selecting several
times with different aliases in one SQL query, and only one aliased field needs
to be hydrated per row.
We now check that such an aliased value is mapped to the class we are hydrated
before attempting to convert it as it might result in an error when using a custom
type that does not get the expected data to initialize php value.

Co-authored-by: Sergey Naumov <s.naumov@lamoda.ru>
2021-05-15 09:37:16 +02:00
Andreas Braun
d52dab54dd Merge pull request #8672 from alcaeus/allow-cache-2.0 2021-05-14 20:21:56 +02:00
Andreas Braun
b5ac7714bc Remove ignored phpstan errors related to doctrine/cache 2.0 2021-05-13 20:38:21 +02:00
Andreas Braun
590551d5c3 Fix setup tool tests 2021-05-13 20:16:52 +02:00
Andreas Braun
c9fb9fdb40 Improve BC layer for getMetadataCacheImpl 2021-05-13 20:16:52 +02:00
Andreas Braun
965926dcc8 Update phpstan baseline to account for doctrine/cache deprecation 2021-05-13 20:16:52 +02:00
Andreas Braun
a6e30c5f4c Fix checkstyle violations 2021-05-13 20:16:52 +02:00
Andreas Braun
30ab6f4cea Add upgrade note for cache changes 2021-05-13 20:16:52 +02:00
Andreas Braun
5e5a44dce2 Suggest using symfony/cache in setup tool 2021-05-13 20:16:52 +02:00
Andreas Braun
d7bf30b291 Fix setup tool tests 2021-05-13 20:16:51 +02:00
Andreas Braun
ce8da6623f Stop using doctrine/cache 2021-05-13 20:16:51 +02:00
Andreas Braun
2ecec0c5d6 Remove reliance on doctrine/cache implementations in tests 2021-05-13 20:16:51 +02:00
Andreas Braun
6f128e4515 Allow installing doctrine/cache 2.0 2021-05-13 20:11:14 +02:00
Benjamin Eberlei
e24b0f0be7 [GH-8589] A new approach to non-nullable typed associations for BC (#8678)
* [GH-8589] A new approach to non-nullable typed associations for BC

* Address review comment about keeping the target entity type detection.
2021-05-10 19:08:16 +02:00
Benjamin Eberlei
6753b26f73 [GH-8676] Allow nested annotations to work without parents as attributes (#8677)
* [GH-8676] Allow nested annotations to work without parents as attributes.

* Housekeeping
2021-05-09 19:58:44 +02:00
Grégoire Paris
4ccc4e19fc Merge pull request #8600 from VincentLanglet/computeChangeset
Remove internal tag from computeChangeSet
2021-05-05 19:27:39 +02:00
Simon Podlipsky
4e2009433b Reflect that default EntityManager is not always named default (#8671)
Follows up #8646
2021-05-05 18:53:34 +02:00
Grégoire Paris
c25b822217 Merge pull request #8673 from Seldaek/patch-1
Add hint for ->iterate() deprecation
2021-05-05 13:31:30 +02:00
Jordi Boggiano
c3dcc5af91 Add hint for ->iterate() deprecation 2021-05-05 10:31:33 +02:00
Grégoire Paris
b2f404b25f Merge pull request #8651 from alcaeus/deprecate-doctrine-metadata-cache
Introduce PSR-6 for metadata caching
2021-05-01 14:53:46 +02:00
Alexandr Li
d141f27875 ConvertDoctrine1Schema: Fix Doctrine 1 notnull field import (#8649)
* ConvertDoctrine1Schema: Fix Doctrine 1 `notnull` field import

* cs fix

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-05-01 13:56:41 +02:00
Andreas Braun
4691839201 Extend DoctrineTestCase to fix missing methods 2021-04-29 12:54:23 +02:00
Andreas Braun
91387382b7 Allow symfony/cache 4.4 to provide PHP 7.1 support 2021-04-29 09:48:27 +02:00
Andreas Braun
f634c64b7a Use stubs over mocks in tests
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-04-29 09:42:18 +02:00
Andreas Braun
7ba9c980b5 Introduce PSR-6 for metadata caching 2021-04-29 09:42:18 +02:00
Grégoire Paris
dacdcf2c7b Merge pull request #8662 from greg0ire/2.9.x
Merge 2.8.x into 2.9.x
2021-04-29 09:27:40 +02:00
Grégoire Paris
f296fee9e4 Merge remote-tracking branch 'origin/2.8.x' into 2.9.x 2021-04-29 09:20:26 +02:00
Grégoire Paris
8555fc1d34 Merge pull request #8659 from greg0ire/make-tests-independent
Make tests independent
2021-04-29 09:07:26 +02:00
Grégoire Paris
b0826fd746 Merge pull request #8201 from oojacoboo/2.8.x
Throw Exception when unable to locate identifier
2021-04-28 15:57:50 +02:00
Jacob Thomason
fe93c2e9d5 Throw Exception that includes name of entity when unable to locate identifier 2021-04-28 15:33:03 +02:00
Grégoire Paris
850d57827f Make tests independent
It seems like IdentityMapTest cannot be run on its own when the second
level cache is enabled (with ENABLE_SECOND_LEVEL_CACHE=1).
It does work when running the whole test suite because
ExtraLazyCollectionTest disables part of that cache in its setUp()
method.
In this patch, we restore the class metadata as it was before running
setUp() and put the test in IdentityMapTest inside the group that is
excluded when running with ENABLE_SECOND_LEVEL_CACHE=1 on the CI.
2021-04-28 14:12:31 +02:00
Benjamin Eberlei
e1388fa986 [GH-8327] Make EntityManagerProvider compatible with expected DoctrineBundle usage (#8646)
* [GH-8327] Make EntityManagerProvider compatible with expected DoctrineBundle usage.

* phpcs

* [Gh-8327] Delegate to EntityManagerProvider::getDefaultManager in ConnectionFromManagerProvider
2021-04-25 19:44:12 +02:00
Grégoire Paris
9a48450481 Merge pull request #7608 from mavroprovato/patch-1
Avoid unnecessary flush after processing first row
2021-04-24 14:23:09 +02:00
Kostas Kokkoros
cff8b96dd6 Avoid unnecessary flush after processing first row
The code as is needlessly flushes after just one row is updated or
removed. It makes more sense to update after ``$batchSize`` elements are
updated or removed, just as it is in the insert case.
2021-04-24 13:01:33 +02:00
Grégoire Paris
996c1c74b3 Merge pull request #8644 from greg0ire/more-accurate-return-type
Describe return types more accurately
2021-04-22 22:31:05 +02:00
Grégoire Paris
48612e6dc6 Merge pull request #8641 from Jean85/remove-deprecated-proxy-usage
Replace deprecated Proxy usages with parent interface to reduce baseline
2021-04-19 23:37:22 +02:00
Benjamin Eberlei
ddfee26f80 Support for Array parameters in SQL filters (#8375)
* #1168 Add support for array parameters on the SQLFilter

* DDC-1168 Add support for array parameters on the SQLFilter

* [GH-2624] Rework array support to use new getParameterList()

* [DDC-1952] Change at() mocking to using returnCallback()

* [DDC-1952] Make arrays of values explicit with new setParameterList

* Adjust tests to use country as list and locale as single value.

* [DDC-1952] Add tests for new exxeption conditions.

* Apply suggestions from code review

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>

Co-authored-by: Manuel Nogales <nogales.manuel@gmail.com>
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-04-19 19:46:22 +02:00
Grégoire Paris
eb860a704e Change incorrect DBAL return types 2021-04-19 19:27:00 +02:00
Grégoire Paris
51ffcb4891 Describe return types more accurately
This fixes an SA regression introduced when using stricter types in
SchemaTool.

Fixes #8642
2021-04-19 19:09:10 +02:00
Grégoire Paris
72f500318a Merge pull request #8544 from greg0ire/bc-type-declarations
Add type declarations where backwards-compatible
2021-04-19 14:02:17 +02:00
Grégoire Paris
55f030f66b Add type declarations where backwards-compatible
This includes:
- private methods
- return type declarations of final protected methods
- return type declarations of public and protected methods of final classes

Parameter type declarations are a more delicate matter and should
probably be handled separately to make it easier to catch issues during
code review.

Type declarations can be more trusted than simple phpdoc when it
comes to static analysis, having them means we can infer the phpdoc of
calling methods with confidence.

Note that it seems that some of the phpdoc I initially inferred these
declarations from were apparently wrong, in particular some mentioning
Doctrine\Dbal\Statement when was is really passed around is
Doctrine\Dbal\Driver\Statement.
2021-04-19 13:51:00 +02:00
orklah
95af30eb72 FileLockRegion::__construct 3rd param is meant to be an int (#8640) 2021-04-19 13:29:43 +02:00
Alessandro Lai
9ea0769d78 Replace deprecated Proxy usages with parent interface to reduce baseline 2021-04-19 10:43:49 +02:00
Benjamin Eberlei
22413453da Reintroduce PHP 7.1 support (#8613)
* Reintroduce PHP 7.1 support

* phpcs

* Another object typehint

* More compatibility

* phpcs

* Reduce doctrine/inflector versions again since 1.4.4 is released.

* Housekeeping: phpcbf

* Simplify PHPUnit Polyfill abstraction.

* Missing assertDoesNotMatchRegularExpression

* phpcs

* Add 7.1 on Github actions, since dependencies now supported.

* Simplify code to work with renamed phpunit assertions and document when to remove.

* phpcs

* Downgrade target phpstan version to 7.1.0

* Run --prefer-lowest with PHP 7.1 not 7.3
2021-04-18 21:24:51 +02:00
Grégoire Paris
06fadcdd8c Merge pull request #8630 from Jean85/reduce-baseline
Reduce baseline
2021-04-18 18:50:59 +02:00
Alessandro Lai
7c56aa2141 Reduce baseline with a nullable return where needed 2021-04-18 18:39:20 +02:00
Alessandro Lai
4cdcb5f760 Reduce baseline for AbstractCollectionPersister 2021-04-18 18:39:20 +02:00
Alessandro Lai
b542b36e45 Remove baseline for DefaultCacheFactory 2021-04-18 18:39:20 +02:00
Alessandro Lai
e5a7a13e1e Remove single baseline rule from DefaultCache 2021-04-18 18:39:20 +02:00
Alessandro Lai
8336dd3779 Remove baseline for AbstractQuery 2021-04-18 18:39:14 +02:00
Grégoire Paris
b04d7a62ae Merge pull request #8548 from orklah/test2
Adding details to types in PHPDoc
2021-04-18 18:09:28 +02:00
Grégoire Paris
a959a474fd Merge pull request #8636 from greg0ire/update-gitattributes
Update ignore rules to reflect current situation
2021-04-18 17:56:47 +02:00
Benjamin Eberlei
ce128e742b [GH-5202] Implement Query::HINT_READ_ONLY flag (#7936)
* Rebase QueryHintReadOnly on 2.9.x

* Housekeeping: phpcs

* [GH-5202] Dont mark known entities as read only.

* [GH-5202] Not mark objects read only when proxy before.

* phpcs
2021-04-18 16:45:25 +02:00
Benjamin Eberlei
dac87dae06 [GH-8327] Deprecate EntityManagerHelper for a provider abstraction. (#8524)
* cli config

* [GH-8327] Deprecate EntityManager HelperSet for a provider abstraction.

* Housekeeping: phpcs

* [GH-8327] Refactor tests towards use of SingleManagerProvider instead of HelperSet.

* [GH-8327] Refactor tests towards use of SingleManagerProvider instead of HelperSet.

* [GH-8327] Refactor tests towards use of SingleManagerProvider instead of HelperSet.

* Housekeeping: cs

* Update tests/Doctrine/Tests/ORM/Tools/Console/ConsoleRunnerTest.php

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>

* [GH-8327] Change option from entity-manager to em for consistency with DoctrineBundle.

* Add final to new methods and classes

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>

* [GH-8327] Bugfix: phpstan detected stricter type checks needed.

* phpcs

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-04-18 14:32:42 +02:00
Jakub Caban
a2230485b2 Fix typed properties for default metadata (#7939) (#8589)
* Make Column::$type, Column::$nullable and JoinColumn::$nullable nullable by default

* Add tests for mapped typed properties (type and nullable)

* Fix Yaml driver tests and remove driver exceptions thrown too early

* Fix PHP driver tests

* Fix static PHP driver tests

* Fix XML driver tests

* Coding Standards

* Deprecate unused MappingException method

* Add manyToOne test and check nullable at the right place

* Coding Standards

* Bugfix: Temporarily change association join columns in CascadeRemoveOrderTest to circumvent new CommitOrderCalculator bug.

* phpcs

Co-authored-by: Benjamin Eberlei <kontakt@beberlei.de>
2021-04-18 14:26:41 +02:00
Benjamin Eberlei
a68aa580c5 [GH-8345] Fields for unique constraints (#8629)
* Add possibility to use fields instead of column for unique constraint and indexes (#8345)

* Document changes in annotation reference

* phpcs

* Ensure exactly one of fields/columns is set for index/uniqueConstraint

* Adapt docs to fields/columns changes

* phpcs

* Implement fields in Attribute driver and fix mapping classes constructors.

* Coding Standard

* Apply suggestions from code review

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>

* phpcs

Co-authored-by: Jakub Caban <kuba.iluvatar@gmail.com>
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-04-18 14:06:30 +02:00
Grégoire Paris
5ee71c54d4 Update ignore rules to reflect current situation
We no longer use Travis, we do not use git submodules as far as I know,
and we now use baseline files as well as project metadata.
2021-04-18 10:49:48 +02:00
orklah
dc37c2cd2f psalm fixes 2021-04-17 17:11:04 +02:00
Grégoire Paris
261a405970 Merge pull request #8635 from greg0ire/2.9.x
Manually merge 2.8.x into 2.9.x
2021-04-17 16:42:07 +02:00
Grégoire Paris
1ea51d88c4 Merge remote-tracking branch 'origin/2.8.x' into 2.9.x 2021-04-17 16:31:14 +02:00
Grégoire Paris
da3a9fa361 Merge pull request #8634 from orklah/static-upgrade
upgrade static tools
2021-04-17 15:41:51 +02:00
orklah
4fd81d26ff upgrade static tools 2021-04-17 13:12:35 +02:00
Benjamin Eberlei
f8e06ad31e [GH-6396] Allow custom hydrators access to meta columns via Query::HINT_INCLUDE_META_COLUMNS hint. (#8382) 2021-04-16 21:27:29 +02:00
Grégoire Paris
559c1ba806 Merge pull request #8628 from greg0ire/2.9.x
Merge 2.8.x up into 2.9.x
2021-04-16 20:08:51 +02:00
Grégoire Paris
4665758c44 Merge remote-tracking branch 'origin/2.8.x' into 2.9.x 2021-04-16 19:59:27 +02:00
Grégoire Paris
e2e9f8fa97 Merge pull request #8627 from greg0ire/add-baselines
Add baseline files for static analyzers
2021-04-16 19:04:04 +02:00
Grégoire Paris
f7249ec709 Declare return type
This helps SA tools figure out that it is fine to call count on the
return value of that method.
As a side-effect, using $metadata->name is not really an option since it
is not part of the ClassMetadata interface.
2021-04-16 13:14:54 +02:00
Grégoire Paris
87dbcca454 Add baseline files for static analyzers
There are many CS and SA-related changes in the ORM as we pursue better
code quality, and easier contributions. These often involve huge
changes, which can be hard to review and inevitably lead to some
regressions. I know some of those could have been avoided if we were
using stricter levels for PHPStan and Psalm.

By adding baselines, we ensure new code is at level 5 for both tools,
which should allow us to catch the most interesting issues.
2021-04-16 09:23:11 +02:00
Grégoire Paris
ceeea8ccd1 Merge pull request #8620 from greg0ire/2.9.x
Manually merge 2.8.x into 2.9.x
2021-04-13 19:23:10 +02:00
Grégoire Paris
6e16ef8c31 Merge remote-tracking branch 'origin/2.8.x' into 2.9.x 2021-04-13 18:51:39 +02:00
Grégoire Paris
305e0d6664 Merge pull request #8617 from greg0ire/cs9
Upgrade to doctrine/coding-standard 9
2021-04-13 18:48:12 +02:00
Grégoire Paris
199be94e6d Upgrade to doctrine/coding-standard 9 2021-04-13 09:00:33 +02:00
Benjamin Eberlei
09a7d9f18a [GH-6578] Add validation that inherited entity class is mapped in discriminator. (#8378) 2021-04-10 18:13:31 +02:00
Grégoire Paris
f57f33b67f Merge pull request #8606 from greg0ire/2.9.x 2021-04-09 13:33:34 +02:00
Grégoire Paris
e86cddb360 Merge remote-tracking branch 'origin/2.8.x' into 2.9.x 2021-04-09 13:21:30 +02:00
Grégoire Paris
fa588af3b1 Merge pull request #8604 from janatjak/2.8.x
Fix psalm param typehint for OneToManyAssociationBuilder::setOrderBy method
2021-04-09 12:57:12 +02:00
Grégoire Paris
d4741720fa Merge pull request #8605 from greg0ire/fix-phpdoc-lsp-violations 2021-04-09 11:59:28 +02:00
Grégoire Paris
343385d060 Pin squizlabs/php_codesniffer
We are referencing rules in phpcs.xml.dist, and may experience
unexpected BC-breaks because of that when they get renamed.
2021-04-09 09:27:44 +02:00
Grégoire Paris
6d04dced03 Address sniff rename
This sniff seems to have been renamed or split in the latest version of
phpcs.
2021-04-09 09:19:10 +02:00
Grégoire Paris
22fa3a8556 Document actual return types
Some executors may return integers, for instance executors that only
execute update or delete statements.
Also, in case an integer is not returned, what's actually returned is a
Doctrine\DBAL\Driver\ResultStatement, and not a Doctrine\DBAL\Driver\Statement
2021-04-09 08:52:56 +02:00
Jakub Janata
eb05756dc3 Fix psalm param typehint for OneToManyAssociationBuilder::setOrderBy method 2021-04-08 22:52:50 +02:00
Grégoire Paris
5bb7e20708 Merge pull request #8602 from NicoHaase/fix-8599
Adjusted return type annotation for getOriginalEntityData
2021-04-07 23:22:19 +02:00
Nico Haase
a9076313c7 Adjusted return type 2021-04-07 21:06:58 +02:00
Grégoire Paris
2a87821b28 Merge pull request #8552 from acoulton/maint-phpunit-upgrade 2021-04-07 15:33:06 +02:00
acoulton
da5877d60c Only polyfill older phpunit methods when required 2021-04-07 12:08:55 +01:00
Andrew Coulton
67dfe8e1af Simplify mock building calls
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-04-07 11:07:35 +01:00
Vincent Langlet
2dfe51b396 Remove internal tag 2021-04-07 11:41:34 +02:00
Grégoire Paris
5ac036de02 Merge pull request #8594 from greg0ire/make-sure-test-is-run 2021-04-06 17:47:17 +02:00
Grégoire Paris
fda0d7b440 Merge pull request #8596 from doctrine/2.8.x-merge-up-into-2.9.x_606c485ba431f2.86881997 2021-04-06 15:06:02 +02:00
Grégoire Paris
23e1fd8ad6 Drop assertion about not being an instance of proxy
We do not want to enforce it as it is an internal details that seems to
vary from environment to environment.
2021-04-06 14:55:25 +02:00
Benjamin Eberlei
f8fa0fe069 [GH-8592] Deprecated Named (Native) Queries in Metadata/EntityRepository (#8593)
* [GH-8592] Deprecated Named (Native) Queries in Metadata and EntityRepository.

* [GH-8592] Add deprecation notice for named queries in docs [ci-skip]
2021-04-05 21:59:08 +02:00
Grégoire Paris
a588555ecd Merge pull request #8586 from KartaviK/patch-3
Additional psalm param typehint for orderBy argument in findBy method
2021-04-05 20:38:36 +02:00
Grégoire Paris
501057da83 Ensure test is suffixed with Test 2021-04-05 14:42:17 +02:00
Grégoire Paris
7de84537f6 Merge pull request #8591 from DmitriiBezborodnikov/case_insensive_parenthesis
Return case insensitive check
2021-04-05 14:40:51 +02:00
Grégoire Paris
97f8325dad Make sure tests are suffixed with Test
They will not be taken into account when running vendor/bin/phpunit
otherwise.
2021-04-05 14:32:40 +02:00
Grégoire Paris
0ebd7052d7 Drop create table at shutdown
It makes tests more isolated from each other: another test relying on
some tables including some of the ones created here may fail creating
the tables it needs because they already exist.
2021-04-05 14:03:49 +02:00
Dmitrii Bezborodnikov
5d73378b92 Return case insensitive check 2021-04-05 14:03:49 +02:00
Grégoire Paris
10572ec441 Merge pull request #8590 from VincentLanglet/patch-2
Fix phpdoc of ClassMetadataInfo::getIdentifierValues
2021-04-04 23:47:09 +02:00
Vincent Langlet
76278d801d Fix phpdoc 2021-04-04 21:19:54 +02:00
Roman Varkuta
ca80830b26 Describe $orderBy parameter as a hash
A list of string is incorrect, it actually looks like this:
['someField' => 'DESC', 'someOtherField' => 'ASC'…]`
2021-04-03 12:45:24 +02:00
Grégoire Paris
1ed89c756a Merge pull request #8582 from doctrine/2.8.x-merge-up-into-2.9.x_6066399d9875f8.96494390
Merge release 2.8.3 into 2.9.x
2021-04-02 09:12:58 +02:00
Grégoire Paris
bb078b5cb7 Merge remote-tracking branch 'origin/2.8.x' into 2.8.x-merge-up-into-2.9.x_6066399d9875f8.96494390 2021-04-02 09:00:35 +02:00
Grégoire Paris
bcb4889a2c Merge pull request #8583 from greg0ire/sync-static-analysis-workflows
Synchronize static analysis jobs with upstream
2021-04-02 08:58:50 +02:00
Grégoire Paris
961da8b0cc Synchronize static analysis jobs with upstream 2021-04-01 23:32:04 +02:00
Benjamin Eberlei
657a30f8ce [GH-6394] Bugfix: IdentifierFlattener support for association non-object values. (#8384)
* [GH-6394] Bugfix: IdentifierFlattener support for association non-object values

* [GH-6394] Bugfix: BasicEntityPersister::update used wrong identifiers for version assignment.

* Exclude MissingNativeTypeHint phpcs rule as 7.4 is not lowest version.
2021-04-01 23:16:53 +02:00
Benjamin Eberlei
c3f8996af5 Bump requirement to DBAL 2.13 (#8577) 2021-04-01 21:26:25 +02:00
Grégoire Paris
0655083e50 Merge remote-tracking branch 'origin/2.8.x' into 2.9.x 2021-04-01 09:02:08 +02:00
Grégoire Paris
0b25d4d8b0 Merge pull request #8573 from greg0ire/fix-build
Fix build issues
2021-04-01 07:49:27 +02:00
Grégoire Paris
a88242ee6c Adapt test logic to PHP and SQLite
There seems to be at least 2 camps in the software world when it comes
to the question "What's today minus one month", today being at the end
of march.

While PHP and SQLite agree that that would be the 2nd of March, other
RDBMS than SQLite and humans will tell you that it's the last day of
February.

This patch ensures that we check one logic for SQLite, and the other
logic for other platforms.
2021-03-30 21:08:29 +02:00
Grégoire Paris
fe4964008d Accommodate 2 behaviors of symfony/console in test
Decorated text used to be wrapped too early in SymfonyStyle->block()
See https://github.com/symfony/symfony/pull/40348
The fix was not contributed to version 3, which means we have to rewrite
the test so that it passes for both the correct and the buggy version.
2021-03-30 08:41:10 +02:00
Grégoire Paris
3f3de70c3e Merge pull request #8564 from cybercitizen7/featureIncludeDirectory
Adding DIR to include statement to fix issue with pathing
2021-03-26 19:46:40 +01:00
darkw1z
eb4e317144 Adding DIR to include statement to fix issue with pathing 2021-03-26 14:04:46 +01:00
Grégoire Paris
c8f2f61ea1 Merge pull request #8556 from VincentLanglet/patch-2
Fix fieldMapping phpdoc
2021-03-26 08:26:40 +01:00
Vincent Langlet
c9502d3d0b Fix fieldMapping phpdoc 2021-03-24 15:07:08 +01:00
Benjamin Eberlei
b6b3c97436 [GH-8265] Attribute Metadata Driver (#8266)
* [GH-8265] Prototype for Attribute Metadata Driver

* [GH-8265] Skip AttributeDriverTest on PHP 7.

* [GH-8265] Fill more test entities with Attribute declarations to pass tests.

* [GH-8265] More test entity attributes for passing AttributeDriverTest.

* [GH-8265] Final changes to get AttributeDriverTest passing with test entities.

* [GH-8265] automatically update cs for new code when possible.

* [GH-8265] exclude sniffs that break because of phpcs not knowing attributes.

* [GH-8265] Fix AttributeReader styles.

* [GH-8265] Fix AttributeReader styles.

* [GH-8265] Missing changes to AttributeDriver

* [GH-8265] Fix InverseJoinColumn attribute cs violations.

* [GH-8265] Fix AbstractMappingDriverTest::_loadDriver and other CS

* [GH-8265] Coding styles

* [GH-8265] Coding styles

* [GH-8265] Coding styles

* [GH-8265] Coding styles

* [GH-8265] Convert Cache, ChangeTrackingPolicy, Column to named annotations.

* [GH-8265] Convert all annotations to named constructor for attribute support.

* [GH-8265] Style after attribute changes.

* [GH-8265] more styles

* [GH-8265] Remove workaround code for attributes.

* More cs

* More cs

* More cs

* More cs

* Add Attribute Metadata driver reference.

* Housekeeping: phpcs

* More merge conflict resolutions

* phpcs

* fix broken merge

* Change NamedArgumentConstructorAnnotation interface to use NamedArgumentConstructor annotation instead.

* phpcs

* Housekeeping: cs

* Housekeeping: cs

* Update docs with review comments

* Improve attribute docs

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>

* Rename AttributesDriver to AttributeDriver

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-03-23 13:30:57 +01:00
Benjamin Eberlei
8f6d146bc4 Bump doctrine/deprecations to at least v0.5.3 (#8553) 2021-03-22 23:23:03 +01:00
Grégoire Paris
3358ccde39 Merge pull request #8547 from greg0ire/psalm-lv6-phpdoc
Make phpdoc types correct
2021-03-21 22:11:51 +01:00
acoulton
1f4e6ebeeb Add a forward-compatibility wrapper for phpunit8 assertions
While doctrine still supports php7.2 the test cases need to run
under phpunit8 as well. However some assertion methods produce
deprecation warnings in the test output with phpunit >= 9.

This commit adds a thin forward compatiblity wrapper for the
new assertion method names so that they can be used with both
supported phpunit versions.
2021-03-18 11:25:18 +00:00
acoulton
a94db4f5c0 Fix remaining warnings from the phpunit9 upgrade
Some tests were still using deprecated assertion and mocking methods,
resulting in a long list of warnings in the phpunit output.

This commit resolves all the warnings:

* Fixes a couple of test names in `@depends` tags (presumably these
  tests were renamed at some point for coding standards).

* Changes how mocks are configured when asserting the same method
  is called multiple times with a sequence of arguments / sequence
  of return values. The old `->at` expectation is deprecated because
  it can be brittle and give unreliable results. Some of this
  mocking could probably still be refactored further, but my focus
  was on solving the deprecation with the existing setup.

* Removes one use of prophecy for mocking, in favour of using
  phpunit mock objects. Prophecy now requires an extra composer
  dependency and a trait which seems overkill given it was only
  used in one place.

* Updates to the new names for assertFileExists and assertRegExp
  (and their `not` versions) - these are functionally equivalent.

* Replaces the last few references to old PHPUnit_Framework_XXX
  classes with their namespaced equivalent. These were mostly in
  comments, or in native php `assert()` statements that were sanity
  checking mocked object types. These asserts are probably redundant
  (and are clearly not running in CI since the classes they referenced
  no longer exist).
2021-03-18 10:51:43 +00:00
Grégoire Paris
47475f3a67 Merge pull request #8532 from acoulton/bug-fix-ci-db-connection
All CI runs are using the sqlite fallback connection instead of the expected driver
2021-03-17 19:49:56 +01:00
acoulton
61c4a5da0a Rename tmpdb_ to privileged_db in test config and TestUtil
To avoid confusion, the `tmpdb_` test config values are now named
`privileged_db_` and better documented in the phpunit.xml.dist.

The TestUtil class has been refactored to more closely mirror the
structure and method / variable naming of the equivalent in
doctrine/dbal. This does not introduce any significant functional
changes. The only real difference is that the test output now prints
the selected database driver the first time it is referenced,
rather than repeating this through the test run.
2021-03-17 10:31:22 +00:00
acoulton
dd34bca4eb Upgrade previously-skipped tests to phpunit 9
These tests had not been running in CI so missed the previous
phpunit upgrade.

Note that assertions in decimal/floaty values in GH7941Test have
been changed to compare numerically with a reasonable level of
precision, instead of using regex. This is because the types
returned by the different drivers are inconsistent, and phpunit
now only allows regex comparisons on strings.
2021-03-17 10:31:22 +00:00
acoulton
3e21c50f61 Fix unit test and CI database driver / credential configuration
Builds using the github actions phpunit.xml files were not properly
recognising driver-specific configuration values, so were all
falling back to use the in-memory sqlite database instead of the
expected driver. This also meant a number of tests were skipped
as they rely on functionality not available in sqlite.

This commit addresses that by:

* REMOVING the automatic fallback to the sqlite memory database -
  phpunit.xml must now always specify explicit parameters for the
  desired connection.

* Displaying the active driver in the build output for visibility
  and debugging.

* Changing the way TestUtil loads the database config in line
  with the equivalent logic in doctrine/dbal, and to support the
  way that the config is/was specified in the phpunit.xml files
  for CI.

Note that this means a couple of the expected config variable names
have changed. Developers that are using customised phpunit.xml files
locally will need to update them to provide:

* Database config variables if they want to use the sqlite/memory
  driver - see phpunit.xml.dist for details.
* `db_driver` instead of `db_type`
* `db_user` instead of `db_username`
* `db_dbname` instead of `db_name`
* And, if in use, the equivalent changes to the `tmpdb_` values

The other change is that now if you provide any value for
`db_driver` we will attempt to create that connection type and
that will throw if other details (username / password / etc as
required by the driver) are not provided. Previously providing
partial configuration would cause TestUtil to silently fall back
to the in-memory sqlite driver.
2021-03-17 10:31:22 +00:00
Grégoire Paris
bc3592bcc8 Make phpdoc type correct 2021-03-16 19:20:11 +01:00
Grégoire Paris
4fccec1322 Merge pull request #8545 from orklah/psalm-plugins-2
remove some empty() use when safe
2021-03-15 23:51:09 +01:00
orklah
0177133385 remove unwanted check with 0 2021-03-15 23:28:20 +01:00
orklah
8df5cb84fa remove some empty() use when safe 2021-03-15 23:28:19 +01:00
Grégoire Paris
3b7275e183 Merge remote-tracking branch 'origin/2.8.x' into 2.9.x 2021-03-14 18:57:41 +01:00
Grégoire Paris
5247c56fce Merge pull request #8539 from greg0ire/cs-20210311
🎉 Final CS batch 🎉
2021-03-14 18:47:03 +01:00
Grégoire Paris
cc37c490c2 Synchronize coding standard workflow with upstream
Now that there no longer are cs issues, we can thank diff-sniffer and
kiss it goodbye!
2021-03-13 09:55:38 +01:00
Grégoire Paris
95824efd61 Manually fix cs 2021-03-13 09:46:38 +01:00
Grégoire Paris
44d4712e64 Ignore rule about annotation phpdoc
These phpdoc is parsed by doctrine/annotations, and that package does
not understand things like array<string, mixed> yet.
2021-03-13 09:46:38 +01:00
Grégoire Paris
930f44c02f Ignore rule for externally-defined property 2021-03-13 00:08:03 +01:00
Grégoire Paris
6e3c011e65 Ignore rule about superflous comment
We can fix it with a breaking change.
2021-03-13 00:08:03 +01:00
Grégoire Paris
a82de0d422 Ignore rule about unused method
It cannot work when you call the private method like a callable.
2021-03-13 00:08:03 +01:00
Grégoire Paris
9917488179 Ignore rule about empty statements
This should be implemented in a separate pull request.
2021-03-12 08:20:46 +01:00
Grégoire Paris
93f31d2c33 Merge pull request #8533 from acoulton/test-string-lock-version
Add test coverage for passing optimistic lock version as string
2021-03-11 21:41:32 +01:00
acoulton
77356b954f Add test coverage for passing optimistic lock version as string
As discussed in #8527, when using optimistic locking with integer
version columns, Doctrine has always supported passing the lock
version as a string. For example when passing in a version
received in POST / GET.

Technically speaking this does not comply with the docs and phdoc
(which show the app explicitly casting to int before passing).

Nonetheless the maintainers decided it should continue to be valid
for now and reinstated the old soft-equals logic with #8531.

This modified test just avoids accidental changes in future.
2021-03-11 13:24:53 +00:00
Grégoire Paris
92f764206e Ignore broken rule 2021-03-11 09:11:24 +01:00
Grégoire Paris
141539673e Merge pull request #8530 from doctrine/cs-20210310
CS-batch 25/26 🤩
2021-03-11 00:05:31 +01:00
Grégoire Paris
23dc804c9b Merge pull request #8531 from beberlei/GH-8527-RevertLockEquals
[GH-8527] Revert cs fixes for entity version compares in lock+merge
2021-03-10 23:30:25 +01:00
Benjamin Eberlei
9e3baa7baa [GH-8527] Revert cs fixes for entity version compares in lock+merge 2021-03-10 22:46:07 +01:00
Grégoire Paris
322ea51ecf Manually fix cs 2021-03-10 22:17:31 +01:00
Grégoire Paris
21b046452b Merge pull request #8529 from greg0ire/cs-20210308
CS batch 24/26 🤞
2021-03-10 19:53:52 +01:00
Grégoire Paris
c57b81ada4 Manually fix cs 2021-03-09 21:15:33 +01:00
Grégoire Paris
4fa7c9c6de Merge pull request #8521 from greg0ire/cs-20210228
CS batch 23/an estimated 26
2021-03-08 19:57:18 +01:00
Benjamin Eberlei
2685b65c2b [GH-6855] Trigger deprecation for unsupported lifecycle callback mapping on embedded classes.(#8381) 2021-03-04 22:08:11 +01:00
Benjamin Eberlei
3902a4eb6e [GH-8458] Properly deprecate ConvertDoctrine1Schema (#8517) 2021-03-02 09:38:09 +01:00
Jakub Caban
b3ed525d4d Use typed properties for default metadata for #7939 (#8439)
[GH-7939] Detect column and association types from typed properties.

* Use typed properties for default metadata for #7939

* Coding Standards

* Remove $name from CmsUserTypes and adapt tests

* Factor out conditions required for typed property

* Factor out typed validation and completion methods

* Move Typed tests model to separate namespace

* Don't pass by reference, return array

* Document changes to default mapping for typed properties

* Better wording in annotation reference

* Add missing targetEntity assertion on typed association

* Try to comply with CS

* USe constants instead of strings

* Use one-line comments for single line content

* phpcs

* phpcs

Co-authored-by: Benjamin Eberlei <kontakt@beberlei.de>
2021-03-01 22:13:58 +01:00
Grégoire Paris
3580517aac Manually fix cs 2021-03-01 21:49:10 +01:00
Benjamin Eberlei
4cdc6b1a71 [GH-7128] Improve OneToManyRequiresMappedBy Exception message (#8380) 2021-03-01 21:42:57 +01:00
plfort
38ccbd8638 DDC-2076 - MEMBER OF - Remove useless join over target table of ManyToMany relationship (#8438)
Co-authored-by: Pierre-Louis FORT <pierre-louis.fort@theia.fr>
2021-02-28 23:37:40 +01:00
Grégoire Paris
f9e7c3c2d8 Merge pull request #8516 from greg0ire/cs-20210227
CS batch 22/an estimated 26
2021-02-28 21:27:52 +01:00
Grégoire Paris
3600c0fbca Manually fix cs 2021-02-28 18:31:38 +01:00
Grégoire Paris
f779513042 Remove unused properties
They should have been removed as part of a6b43b93ac
2021-02-28 18:31:38 +01:00
Benjamin Eberlei
b4e6530d2d [GH-8471] Deprecate Partial DQL syntax and forcing partial loads. (#8472)
* [GH-8471] Deprecate Partial DQL syntax and forcing partial loads.
2021-02-28 18:17:12 +01:00
Diego Rin Martín
07d426edf5 Changed lock function to compare timestamps instead of DateTimeInterface objects directly. (#8508)
When using optimistic lock with DateTimeInterface based version field a bug appears due to the use of the === operator for comparing the lock version and the entity version. This comparison always resolves to false because the === operator when comparing objects is only true when both sides are the exact same instance of the object.

To fix the issue I have decided to compare timestamps instead the DateTimeInterface based objects directly, calling getTimestamp() method and doing a strict comparison.

Modified OptimisticLockException to use DateTimeInterface instead of DateTime class.

Added test suite to cover case.

Fixes #8499
2021-02-27 18:40:48 +01:00
Grégoire Paris
4afd4069be Merge pull request #8515 from greg0ire/cs-20210226
CS batch 21/an estimated 26
2021-02-27 14:30:25 +01:00
Grégoire Paris
239215c2e5 Merge pull request #8502 from greg0ire/rework-contributing-md
Rework CONTRIBUTING.md
2021-02-27 13:03:20 +01:00
Grégoire Paris
e6f11652d2 Add section for 2.9.x branch 2021-02-27 12:16:49 +01:00
Grégoire Paris
2910a73927 Rework badges urls
Some .x were missing, and ugly urlencoding can be avoided.
2021-02-27 12:10:47 +01:00
Grégoire Paris
3959b2743c Remove references to Travis 2021-02-27 12:03:35 +01:00
Grégoire Paris
658e54027e Remove trailing whitespace 2021-02-27 12:01:06 +01:00
Grégoire Paris
ba882451b0 Refer to our actual coding/standard
We do much more than just PSR 1 and 2
2021-02-27 12:01:05 +01:00
Grégoire Paris
1ed9840123 Refer to global workflow policy
We are doing things differently now, and the how is already documented.
2021-02-27 12:01:05 +01:00
Grégoire Paris
71044894a1 Manually fix cs 2021-02-26 21:30:49 +01:00
Grégoire Paris
1a41d6b87c Fix configuration mix up 2021-02-26 08:25:44 +01:00
Grégoire Paris
5dfcb08999 Merge pull request #8512 from greg0ire/cs-20210225
CS batch 20/an estimated 26
2021-02-25 23:23:24 +01:00
Grégoire Paris
284bd6fd03 Manually fix cs 2021-02-25 21:22:50 +01:00
Grégoire Paris
e40ac3e1d0 Merge pull request #8510 from greg0ire/cs-20210224
CS batch 19/an estimated 26
2021-02-24 22:41:28 +01:00
Grégoire Paris
0bce2472f2 Manually fix cs 2021-02-24 18:51:02 +01:00
Grégoire Paris
89f57de884 Merge pull request #8504 from greg0ire/cs-20210223
CS batch 18/an estimated 26
2021-02-23 23:18:42 +01:00
Grégoire Paris
ae19f40958 Merge pull request #8495 from Warxcell/fix_to_iterable_with_cache
Fix bug when using Result Cache with Query::toIterable
2021-02-23 20:16:39 +01:00
Grégoire Paris
c2d69a3c48 Merge pull request #8507 from greg0ire/address-move-away-from-master
Address move away from master
2021-02-23 18:19:47 +01:00
Grégoire Paris
6ce91dd37b Address move away from master 2021-02-23 09:24:40 +01:00
Grégoire Paris
57e6ba25c9 Merge pull request #8505 from dbu/patch-1
fix typo in changelog
2021-02-23 08:56:31 +01:00
David Buchmann
9d2e67bbb4 fix typo in changelog 2021-02-23 08:17:31 +01:00
Grégoire Paris
2dce5b20ad Manually fix cs 2021-02-22 23:50:09 +01:00
Warxcell
930859f803 Fix bug when using ResultCache with Query::toIterable.
Signed-off-by: Warxcell <warxcell@gmail.com>
2021-02-22 23:35:22 +02:00
Yup
a70c73ae3a Use RegEx to match if queryPart contains OR/AND (#8453)
This allows fixes cases of queries that contain line feeds or tabs but
do not benefit from automatic wrapping of parenthesis.
2021-02-22 20:58:06 +01:00
David Buchmann
074346b8d5 Note deprecation of AbstractQuery::iterator (#8497) 2021-02-22 20:30:05 +01:00
Grégoire Paris
9ed4a8c043 Merge pull request #8498 from greg0ire/cs-20210222
CS batch 17/an estimated 26
2021-02-22 20:25:06 +01:00
Grégoire Paris
9c917811e5 Manually fix cs 2021-02-22 09:12:04 +01:00
Grégoire Paris
f883820257 Ignore rule about wrong comment style 2021-02-22 08:48:46 +01:00
Grégoire Paris
a32045dd51 Ignore rule violated by external package 2021-02-22 07:52:57 +01:00
Grégoire Paris
672b04a55d Merge pull request #8483 from olsavmic/fix-single-scalar-hydrator-memory-leak-on-exception
Fix single scalar hydrator memory leak on exception
2021-02-21 21:12:50 +01:00
Grégoire Paris
261334aca2 Merge pull request #8494 from greg0ire/cs-20210221
CS batch 16/an estimated 26
2021-02-21 20:29:47 +01:00
Warxcell
7f6ed094cd Add test to verify that using ResultCache with Query::toIterable is failing. 2021-02-21 21:12:52 +02:00
Grégoire Paris
a792655813 Manually fix cs 2021-02-21 12:20:19 +01:00
Grégoire Paris
fb71204910 Relax assertion (#8493)
EntityManager is too restrictive, any implementation can actually be
returned here.

Closes #8488
2021-02-21 07:43:56 +01:00
Grégoire Paris
b918661cf1 Merge pull request #8492 from greg0ire/cs-20210220
CS batch 15/an estimated 26
2021-02-20 20:49:25 +01:00
Michael Olšavský
7971a53164 Method hydrateAll() does not take into account possible exception
from hydrateAllData() which in turn does not call cleanup()
2021-02-20 18:58:50 +01:00
Grégoire Paris
a175f96ae8 Manually fix cs 2021-02-20 15:37:15 +01:00
Grégoire Paris
7c1cde6471 Ignore rule that triggers on external property 2021-02-20 15:32:26 +01:00
Grégoire Paris
1ffc0cacf4 Merge pull request #8491 from greg0ire/cs-20210219
CS batch 14/an estimated 26
2021-02-20 11:10:27 +01:00
Grégoire Paris
e979d0d50f Manually fix cs 2021-02-20 00:01:41 +01:00
Grégoire Paris
553ea03079 Ignore rule about case mismatch
@group does not have to do with the Group entity at all.
2021-02-19 23:33:25 +01:00
Grégoire Paris
149014879d Ignore rule about property defined externally 2021-02-19 23:11:43 +01:00
Grégoire Paris
b991c58988 Merge pull request #8490 from greg0ire/cs-20210218
CS batch 13/an estimated 26
2021-02-19 23:08:25 +01:00
Aleksandr Frolov
ee9627b82e Update QueryBuilder::setParameters docs (#8487)
Use `ArrayCollection` instead of plain array (which is supported only for bc)
2021-02-19 01:45:14 +01:00
Grégoire Paris
e3f03414f9 Manually fix cs 2021-02-18 23:17:03 +01:00
Grégoire Paris
1f406fd3df Merge pull request #8484 from greg0ire/cs-20210217
CS batch 12/an estimated 26
2021-02-18 21:54:43 +01:00
Grégoire Paris
0ae53a6703 Merge pull request #8485 from doctrine/2.8.x-merge-up-into-2.9.x_602d59a0aa86b9.63081052
Merge release 2.8.2 into 2.9.x
2021-02-17 20:50:44 +01:00
Grégoire Paris
49864a7f57 Merge remote-tracking branch 'origin/2.8.x' into 2.8.x-merge-up-into-2.9.x_602d59a0aa86b9.63081052 2021-02-17 20:39:28 +01:00
Grégoire Paris
b747bf15ff Manually fix cs 2021-02-17 16:32:39 +01:00
Grégoire Paris
5fe85bfc03 Ignore rule about underscore in method name
We inherit from a class defined in another package.
2021-02-17 15:55:21 +01:00
Grégoire Paris
0dccf05ca8 Automatically fix cs 2021-02-17 15:55:21 +01:00
Grégoire Paris
ebae57eb96 Merge pull request #8480 from greg0ire/cs-20210216
CS batch 11/an estimated 26
2021-02-16 23:10:18 +01:00
Benjamin Eberlei
30a7c2aa67 [GH-8410] Fix memory leak in new toIterable and state bug. (#8467)
* [GH-8410] Fix memory leak in new toIterable and state bug.

The new AbstractQuery::toIterable() had a memory leak that
AbstractQuery::iterable() did not have. This leak is now fixed.

After fixing the leak, one test failed where the identity map in
ObjectHydrator triggered and lead to a notice. Introduced a new
AbstractHydrator::cleanupAfterRowIteration() that the ObjectHydrator
uses to cleanup the state.

* [GH-8413] Bugfix: Iterating with multiple, mixed results

When multiple entity results are part of a row, the result handling
must be different. In addition mixed results with scalars are broken
and now throw an exception as illegal operation.

* Housekeeping: phpcs

* [GH-8413] Add assertions for entity alias iteration.

* [GH-8387] Missing @deprecated on Query::iterate
2021-02-16 17:52:20 +01:00
Benjamin Eberlei
3a9b8fde9b Housekeeping: Fix cs 2021-02-16 16:24:19 +01:00
Yosh
4f864bc178 Identifier type is not set when many2many relations are deleted (#8401)
* Ensure identifier type is set on deleteJoinTableRecords

* Housekeeping: phpcs

* Housekeeping: phpcs

Co-authored-by: Benjamin Eberlei <kontakt@beberlei.de>
2021-02-16 16:12:39 +01:00
Grégoire Paris
d76cbd755f Manually fix cs 2021-02-16 09:07:26 +01:00
Grégoire Paris
4aece04ae7 Automatically fix cs 2021-02-16 08:48:48 +01:00
Grégoire Paris
f31dbf8d4e Merge pull request #8479 from greg0ire/cs-20210215
CS batch 10/an estimated 27
2021-02-15 23:44:27 +01:00
Grégoire Paris
416f35dba9 Manually fix cs 2021-02-14 21:00:58 +01:00
Grégoire Paris
c29370e061 Automatically fix cs 2021-02-14 14:39:35 +01:00
Grégoire Paris
4e0f6837d0 Merge pull request #8478 from beberlei/CsFixes2
CS Fixes 2 string interpolation to sprintf
2021-02-14 14:39:00 +01:00
Benjamin Eberlei
e45d212f02 Housekeeping: CS fixes Doctrine\ORM\Mapping\MappingException 2021-02-14 14:28:42 +01:00
Benjamin Eberlei
8f62bd39b5 Housekeeping: CS fixes Doctrine\ORM\ORMException 2021-02-14 09:53:19 +01:00
Benjamin Eberlei
5e11afcdf1 Housekeeping: CS fixes Doctrine\ORM\Mapping\MappingException 2021-02-14 09:49:39 +01:00
Benjamin Eberlei
f833222017 Cs fixes1 (#8475)
* Housekeeping: CS Query, AbstractQuery, NativeQuery.

* Housekeeping: phpcs TreeWalker

* Housekeeping: CS Doctrine\ORM\EntityManager

* Housekeeping: CS Doctrine\ORM\Cache

* Upgrade git-phpcs

* Drop unused method parameter

* Describe types more precisely

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-02-14 09:23:15 +01:00
Grégoire Paris
c7f39ebbde Merge pull request #8477 from greg0ire/cs-20210214
CS batch 9/an estimated 28
2021-02-14 09:20:11 +01:00
Grégoire Paris
15f08ed006 Manually fix cs 2021-02-14 00:04:18 +01:00
Grégoire Paris
b6fd4b5ef3 Automatically fix cs 2021-02-14 00:04:11 +01:00
Benjamin Eberlei
e2e59e94f5 [GH-8383] deprecate notify change tracking policy (#8473)
* [GH-8383] Deprecate notify change tracking policy.

* [GH-8383] Add warning to documentation about notify change tracking policy deprecation.
2021-02-13 23:14:28 +01:00
Grégoire Paris
5e4dae88f3 Merge pull request #8476 from greg0ire/cs-20210213
CS batch 8/an estimated 30
2021-02-13 17:26:58 +01:00
Grégoire Paris
7312ddeda7 Manually fix cs 2021-02-13 13:46:01 +01:00
Grégoire Paris
9a67b6f699 Merge pull request #8474 from greg0ire/cs-20210212
CS batch 7/an estimated 30
2021-02-12 23:03:28 +01:00
Grégoire Paris
f59a0c349b Manually fix cs 2021-02-12 20:43:17 +01:00
Grégoire Paris
4c8831f716 Remove unused helper method 2021-02-12 20:04:56 +01:00
Benjamin Eberlei
6fe388a705 Introduce doctrine/deprecations (#8466)
* Introduce doctrine/deprecations, empty out VerifyDeprecations trait for now.

* Replace more usages of VerifyDeprecations (akwardkly for now)

* Update doctrine/deprecations to v0.2.0

* Remove ORM VerifyDeprecations trait and its use.

* Use doctrine/deprecatios VerifyDeprecations trait where useful

* Housekeeping: phpcs

* Fix reference link for toIterable/iterate deprecation
2021-02-12 18:14:34 +01:00
Vincent Langlet
172a8d9414 Restrict EntityManagerInterface::getRepository (#8417) 2021-02-12 17:44:22 +01:00
Grégoire Paris
01ca442be7 Ignore error about no assignment
These files must be require'd
2021-02-12 08:45:07 +01:00
Grégoire Paris
01374ca2ab Ignore rule about lone comment
That comment is mistaken for a method comment because it precedes one.
The issue was reported but will most likely not be fixed.
2021-02-12 07:39:56 +01:00
Grégoire Paris
94e8b1d43c Merge pull request #8470 from greg0ire/cs-20210211
CS batch 6/an estimated 30
2021-02-12 07:25:43 +01:00
Grégoire Paris
61d0f96c17 Manually fix cs 2021-02-11 21:02:10 +01:00
Grégoire Paris
41729be80a Spell "first" properly 2021-02-11 18:24:56 +01:00
Grégoire Paris
6dbaa39016 Merge pull request #8469 from greg0ire/cs-20210209
CS batch 5/an estimated 30
2021-02-10 21:11:11 +01:00
Grégoire Paris
58c95a92d1 Manually fix cs 2021-02-09 22:58:05 +01:00
Grégoire Paris
4958180b02 Merge pull request #8468 from greg0ire/cs-20210208
CS batch 4/an estimated 30
2021-02-09 22:22:41 +01:00
Grégoire Paris
d00dbf7e2d Merge pull request #8357 from snapshotpl/add-psalm-annotation
Add psalm annotation to ArrayCollection of Parameters
2021-02-08 21:25:58 +01:00
Grégoire Paris
8312ff0cb5 Merge pull request #8353 from fezfez/patch-1
Add docs to export-ignore
2021-02-08 21:23:35 +01:00
Witold Wasiczko
17012f1fea Improve psalm types 2021-02-08 21:16:56 +01:00
Witold Wasiczko
324ac3972f Add psalm annotation for parameters 2021-02-08 21:16:25 +01:00
Grégoire Paris
fb9b9b276e Manually fix cs 2021-02-08 13:53:04 +01:00
Benjamin Eberlei
323469cdb7 Add /*.phpunit.xml to .gitignore 2021-02-07 19:38:52 +01:00
Grégoire Paris
792a9a9149 Merge pull request #8464 from greg0ire/cs-20210207
CS batch 3/many
2021-02-07 14:21:09 +01:00
Grégoire Paris
0f655f9fb6 Manually fix cs 2021-02-07 12:21:40 +01:00
Grégoire Paris
2d7acbd07f Merge pull request #8457 from greg0ire/cs-20210206
CS Batch 2/many
2021-02-06 12:22:10 +01:00
andrews05
835030297a Add support for INDEX BY an associated entity (2.9.x) (#7918)
* Add support for INDEX BY an associated entity

This allows specifying an association in the INDEX BY clause of a query
which will index by the association's join column.

Related to #7661.

* Reintroduce IndexBy#simpleStateFieldPathExpression as deprecated property.

* Housekeeping: phpcs

* Housekeeping: phpcs

Co-authored-by: Benjamin Eberlei <kontakt@beberlei.de>
2021-02-06 11:46:18 +01:00
Grégoire Paris
b06679cc14 Manually fix cs 2021-02-06 11:44:32 +01:00
Julian Ullrich
2693a93aed fixed entity generation for numeric values (#8434)
* fixed entity generation for numeric values

* fixed entity generation for numeric values

Co-authored-by: julian <julian@ullrichmail.net>
2021-02-06 00:35:45 +01:00
Benjamin Eberlei
8724589c6e Housekeeping: Fix wrong typehint - Closes #8421 2021-02-06 00:23:45 +01:00
Grégoire Paris
4cc78d9478 Merge remote-tracking branch 'origin/2.8.x' into 2.9.x 2021-02-05 23:40:59 +01:00
Grégoire Paris
424305ef38 Merge pull request #8455 from greg0ire/cs
Cs
2021-02-05 23:40:01 +01:00
Grégoire Paris
9d01f6a45c Run phpcbf after running git-phpcs
git-phpcs can publish comments to Github, that will be helpful.
phpcbf will still be helpful to ensure no one upgrades the coding
standard without also fixing issues that can be autofixed.
2021-02-05 21:39:13 +01:00
Grégoire Paris
7ed487b534 Manually fix CS 2021-02-05 21:38:33 +01:00
Grégoire Paris
68d24288ce Merge remote-tracking branch 'origin/2.8.x' into 2.9.x 2021-02-05 20:06:04 +01:00
Grégoire Paris
40f3925589 Merge pull request #8144 from greg0ire/cs
Automated fixes with phpcbf + manual fixes
2021-02-05 08:44:58 +01:00
Alexander Schranz
f92c3dba32 Fix --complete flag in orm:ensure-production-settings command (#8426) 2021-02-01 22:08:04 +01:00
Grégoire Paris
5abad7c0af Merge remote-tracking branch 'origin/2.8.x' into 2.9.x 2021-01-31 00:01:45 +01:00
Grégoire Paris
bcbd4401b8 Ignore export directory 2021-01-30 23:50:15 +01:00
Grégoire Paris
d6aca8e146 Fix proxy file exclude pattern
__CG__ is a file prefix, not a directory
2021-01-30 23:45:46 +01:00
Grégoire Paris
8f1911a4fe Fix cs by hand 2021-01-30 23:29:40 +01:00
Grégoire Paris
7f30cd3102 Require doctrine/common ^3.0.3
That release comes with a fix for a bug that affects us since we are
using return type declarations for wakeUp() in proxyfied classes in on
of our tests.
2021-01-30 18:55:32 +01:00
Grégoire Paris
f01fe3e050 Fix or remove wrong assertions 2021-01-30 18:55:32 +01:00
Grégoire Paris
210c2ee6a4 Remove strict types 2021-01-30 18:55:32 +01:00
Grégoire Paris
497dfd1a84 Avoid covariant return types
It's not supported by PHP 7.2/7.3
2021-01-30 18:55:31 +01:00
Grégoire Paris
d9f0e2a27f Add exclude rules for tricky cases 2021-01-30 18:55:31 +01:00
Grégoire Paris
9a40ac6e2a Restore weird phpdoc
Tests do not pass when I format that phpdoc nicely.
2021-01-30 18:55:31 +01:00
Grégoire Paris
1687d9c479 Restore version annotation, but capitalized
@version is commonly used for svn ids and is forbidden
2021-01-30 18:55:31 +01:00
Gabriel Ostrolucký
1a46ed8901 Relax contract of EntityListenerResolver so it doesn't require class name (#8448)
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2021-01-30 13:37:26 +01:00
Grégoire Paris
36d0352c01 Add missing use statements 2021-01-30 11:21:44 +01:00
Grégoire Paris
15eacd787b Remove weird extra argument 2021-01-30 11:21:44 +01:00
Grégoire Paris
5b3f9bdd7b Fix type declarations 2021-01-30 11:21:44 +01:00
Grégoire Paris
e00dba94f4 Remove strict types 2021-01-30 11:21:44 +01:00
Grégoire Paris
ab0e4007a5 Use interface instead of concretion 2021-01-30 11:17:40 +01:00
Grégoire Paris
32266c54f9 Fix compatibility with parent signature 2021-01-30 11:17:39 +01:00
Grégoire Paris
dd2120cd41 Make default value compatible with phpdoc 2021-01-30 11:17:39 +01:00
Grégoire Paris
8991df0785 Add missing return types 2021-01-30 11:17:39 +01:00
Grégoire Paris
ca31923a39 Run phpcbf in the CI
There are still many CS issues to fix, but with this, we now know people
can run vendor/bin/phpcbf to fix their issues and only their issues.
2021-01-30 11:17:39 +01:00
Grégoire Paris
68bc00b6c6 Automatically fix CS 2021-01-30 10:58:42 +01:00
Grégoire Paris
5b55b8c6cf Disable rules that would result in BC-breaks 2021-01-29 23:21:12 +01:00
Grégoire Paris
10f381bc95 Restrict fixes to be compatible with PHP 7.2 2021-01-29 21:16:18 +01:00
Nikolay Gagarinov
40aa8fe5db update getting-started fix type, improve doc (#8440)
* update getting-started fix type, improve doc

* Update getting-started.rst
2021-01-26 21:40:41 +01:00
Simon Podlipsky
5801474ba3 Catch doctrine/persistence MappingException (#8264)
When driver chain is used doctrine/persistence MappingException is thrown instead of doctrine/orm MappingException
2021-01-11 09:07:06 +01:00
Claudio Zizza
9dbd960631 Update website config to current repository branches (#8420) 2021-01-11 09:06:06 +01:00
Grégoire Paris
544df89055 Use proper workflow name (#8418)
This must have been a copy/paste/adapt mistake.
2021-01-11 09:05:18 +01:00
orklah
f0ad5f72b2 bump psalm and fix some issues on level 6 (#8409) 2021-01-08 20:30:15 +01:00
azjezz
378944dd27 remove T from class metadata (#8398) 2020-12-19 20:48:16 +01:00
Benjamin Eberlei
8b749642cd [GH-8231] Bugfix: Missed dirty check synchronization check. (#8392)
When an entity with change tracking policy "deferred explicit" gets
removed, then persisted again, it is not schedulded for a dirty check
synchronization. This is not the case for entities that are persisted
and are already in the managed state.
2020-12-14 11:00:07 +01:00
Nic Wortel
277b53a970 Use the ramsey/composer-install action to install dependencies (#8388)
Follow-up of https://github.com/doctrine/.github/pull/16.
2020-12-10 20:03:47 +01:00
Benjamin Morel
2febb4509a Fix Psalm param (#8386) 2020-12-09 11:03:01 +01:00
Benjamin Eberlei
cbc252f3b7 Add Doctrine\ORM\Query\Expr::mod() (#8377)
* Add Doctrine\ORM\Query\Expr::mod()

Co-authored-by: Menno Holtkamp <menno.holtkamp@shopforce.nl>

* [GH-6739] Add entry to documentation

Co-authored-by: Menno Holtkamp <menno.holtkamp@shopforce.nl>
2020-12-06 23:09:20 +01:00
Benjamin Eberlei
21d2c88013 [GH-7486] Bugfix: failing the command when clearing empty cache is wrong semantics. (#8376) 2020-12-06 22:00:00 +01:00
Vašek Henzl
e7d33eb1a9 Infer datetime_immutable DBAL type for \DateTimeImmutable instance parameters (#8328)
The support for passing \DateTimeImmutable instance as a query parameter has
been added to ORM in #1333 (the year 2015), a long time before immutable date
types (datetime_immutable etc) were introduced to DBAL in doctrine/dbal#2450
(2017).

Back then, it made sense to treat \DateTimeImmutable (or any
\DateTimeInterface) in the same way as \DateTime and infer parameter type as
datetime. However, when immutable date types were later added to DBAL, it
wasn't reflected anyhow in type inference in ORM and \DateTimeImmmutable
instances are still inferred as datetime DBAL type.

This PR fixes this IMO incorrect behaviour of
ParameterTypeInferer::inferType(): for a \DateTimeImmmutable parameter, it now
returns datetime_immutable DBAL type; for \DateTime or any other types
implementing \DateTimeInterface, it returns datetime DBAL type as it did
before.

This behaviour is in line with DateTimeImmutableType handling only
\DateTimeImmutable and DateTimeType handling any \DateTimeInterface.

Why? In most cases, it doesn't matter and datetime works for \DateTimeImmutable
parameters just fine. But it does matter if using custom implementation of
datetime_immutable type like UTCDateTimeImmutableType from
simpod/doctrine-utcdatetime. Then the broken type inference is revealed.

This is partially related to #6443, however, this PR isn't about custom DBAL
types but about correct type inference for build-in types.
2020-12-05 23:36:33 +01:00
Michel Hunziker
cab7a4558d Fix invalid psalm annotation (#8374) 2020-12-05 14:47:49 +01:00
Benjamin Eberlei
242cf1a33d Fix ambiguous case where an entity is also a Traversable (#8371)
* Fix ambiguous case where an entity is also a Traversable

* Address phpcs violations.

* Address phpcs violations.

* Address phpcs violations.

Co-authored-by: Laurent VOULLEMIER <laurent.voullemier@gmail.com>
2020-12-04 20:53:07 +01:00
Grégoire Paris
da225a0db8 Drop step that switches the release branch (#8372)
ORM is a repository where we use the stable branch as the default
branch, that step is not appropriate here.
2020-12-04 20:46:09 +01:00
Benjamin Eberlei
3ef5a30102 [GH-8366] Catch additional Persistence MappingException (#8370) 2020-12-04 20:16:50 +01:00
Grégoire Paris
418587bc25 Merge remote-tracking branch 'origin/2.7' into 2.8.x 2020-12-03 20:18:13 +01:00
Grégoire Paris
01187c9260 Remove trailing whitespaces (#8360)
Stylistically, it's not great to have them, but more importantly, the
latest symfony/yaml version has issues with trailing whitespaces.
2020-12-03 09:52:14 +01:00
Stéphane
35cf4810c1 Add docs to export-ignore 2020-11-27 18:50:57 +01:00
Benjamin Eberlei
404edd418b [GH-8229] Prevent Illegal Inheritance Override (#8348)
* [GH-8229] Prevent AttributeOverride on fields from entities, only allowed for MappedSuperclass

* [GH-8229] Prevent AssociationOverride on fields from entities, only allowed for MappedSuperclass

* Revert "Fix SQL alias generation regression for simple inheritance (#8329)"

This reverts commit f4ebded63c.

* [GH-8229] Finalize checks for illegal attribute/assocation overrides.

* [GH-8229] Revert ccae8f7176 PR #8234

* [GH-8229] Update documentation to clarify only mapped superclass or trait works with overrides

* [GH-8229] Fix style violations introduced by revert

* [GH-8229] Fix style violations introduced by revert

* [GH-8229] Temporarily disable the exception until 2.8.

* Make phpcs happy
2020-11-25 23:04:56 +01:00
Claudio Zizza
011d3c21eb Update functionality of code examples (#8336) 2020-11-24 22:39:42 +01:00
Benjamin Eberlei
3d46e07887 PHP8 Support (#8303)
* Update doctrine/dbal to 2.12 for PHP 8 support.

* Change Query\Parser::match to Query\Parser::matchToken including DQL functions.

* Fix phpunit constraint to 9.4, adjust @group usage to workaround PHPUnit bug.

* Fix PHPUnit API related changes.

* Add PHP 8 support for EntityGenerator namespace detection.

* Use new assertEqualsWithDetla for QueryDqlFunctionTest with date comparisons

* Replace ReflectionParameter::getClass usage with non-deprecated ::getType instead.

* Revert "Change Query\Parser::match to Query\Parser::matchToken including DQL functions."

This reverts commit 279070491d50deaa4d41e17b28bb5a68f5a22796.

* More matchToken => match reverts

* Housekeeping: phpcs

* Housekeeping: phpcs

* Housekeeping: phpcs

* Housekeeping: phpcs

* Add PHP 8 testrunner, update composer.json and small fix in OrmFunctionalTestCase for new PHPUnit behvaior

* Update doctrine/coding-standard to 8.x

* Update rule names for doctrine/coding-standard v8.0

* Update to Psalm 4.

* Not failOnWarning anymore.

* Fix phpcs

* fix phpcs

* remove 7.2 for now until we can support in DBAL.

* Relax doctrine/dbal requirement and add 7.2 CI support again.
2020-11-15 13:24:31 +01:00
Roma
b1ac293a50 Add missing backtick in rst markup (#8335) 2020-11-10 20:37:36 +01:00
Romain Grégoire
f4ebded63c Fix SQL alias generation regression for simple inheritance (#8329)
This fixes a regression from 099c5b42e1.
Without the fix, "where part" in SQL is generated with incorrect aliases.
See https://github.com/doctrine/orm/issues/8229#issuecomment-722942180.
2020-11-10 10:53:01 +01:00
Benjamin Eberlei
51bc596502 Update to Psalm 4. (#8332) 2020-11-08 10:38:21 +01:00
Grégoire Paris
95f1b48422 Merge remote-tracking branch 'origin/2.7' into 2.8.x 2020-11-07 20:19:45 +01:00
Grégoire Paris
385b5a2f80 Phpunit 8 (#8330)
* Revert to whitelist

coverage requires PHPunit 9, and we don't have that yet.

* Upgrade to PHPUnit 8

This unlocks PCOV usage for coverage

* Upload coverage files to Codecov
2020-11-07 19:41:15 +01:00
Benjamin Eberlei
f7d8b155db Merge branch '2.7' into 2.8.x 2020-11-07 18:37:53 +01:00
Benjamin Eberlei
fa6fe09647 Ignore composer.lock 2020-11-07 18:37:46 +01:00
Benjamin Eberlei
539ffea390 Merge 2.7 into 2.8.x 2020-11-07 18:30:32 +01:00
Benjamin Eberlei
c270eba678 Start moving travis phpunit runs to Github actions. (#8317)
* Move PHPUnit runs from Travis to Github Actions

This removes all artifacts used for TravisCI testing and replaces them
with the existing infrastructure for Github Actions from DBAL component.

In addition some test changes were needed and triggered larger Coding
Style cleanups in 3 test files.

* Remove composer.lock and improve naming in CI workflow.
2020-11-07 18:11:42 +01:00
Michael Käfer
2f0eb95c90 Patch 1 (#8325)
* Update outdated doc parts

- The cache implementation moved from `Common` to `doctrine/cache`
- APCu is mor appropiate nowadays I guess
- AbstractQuery::useResultCache() is deprecated since 2.7

* Fix wrong argument

* Fix wrong arguments and remove useless line
2020-10-31 12:13:48 +01:00
Grégoire Paris
b13b2e8bab Upgrade doctrine/coding-standard (#8321)
* Use a classname that exists

Doctrine\ORM\Mapping\TableGenerator does not exist, only
Doctrine\ORM\Id\TableGenerator does.

* Upgrade doctrine/coding-standard

That library has a dependency on another library that requires composer
plugin API v1. Updating both libs allow to use Composer v2.

* Account for doctrine/reflection deprecation
2020-10-28 11:14:10 +01:00
Simon Podlipsky
4bfc84f035 Rename getIterable() to toIterable() (part 2) (#8293) 2020-10-17 23:55:39 +02:00
Michael Voříšek
ca27cc3f72 Fix EOL of text files (#8310) 2020-10-17 19:04:42 +02:00
Mateusz Sip
53dc5b2ac3 Detect associations inside embeddables (#8291) 2020-10-17 18:49:16 +02:00
orklah
f1219f1418 Add psalm template support to several types (#8289) 2020-10-17 12:01:52 +02:00
Grégoire Paris
072066f746 Merge remote-tracking branch 'origin/2.7' into 2.8.x 2020-10-17 11:07:05 +02:00
Laurent VOULLEMIER
5fde5801c1 Fix many typos (#8299)
- Some uppercase letters were used in the middle of sentence
- Some dots were missing
- There was two sentences with wrong or missing words
2020-10-13 21:52:04 +02:00
Thomas Landauer
18d96fcc02 Update working-with-indexed-associations.rst (#8298)
* Update working-with-indexed-associations.rst

Fixing broken link

* Update docs/en/tutorials/working-with-indexed-associations.rst

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
2020-10-12 21:27:18 +02:00
Benjamin Eberlei
4d2908a065 Change <phpunit verbose="true" /> to false for better readability of test output. 2020-10-11 19:14:47 +02:00
Benjamin Eberlei
8d250f5921 Use SHELL_VERBOSITY=3 instead of LOG_LEVEL=DEBUG 2020-10-11 12:03:57 +02:00
Benjamin Eberlei
59fd9b5ea7 Change LOG_LEVEL to debug should expose more info from laminas/automatic-releases. 2020-10-11 00:17:52 +02:00
Benjamin Eberlei
8fcc70cfbe Change LOG_LEVEL to debug should expose more info from laminas/automatic-releases. 2020-10-11 00:14:35 +02:00
Grégoire Paris
7d84a49980 Setup automated release workflow (#8301) 2020-10-10 19:11:26 +02:00
Claudio Zizza
bb64fc953d Move website config to default branch (#8287)
Adds the website config to be compatible with the doctrine/doctrine-website#356 changes
2020-10-02 20:31:00 +02:00
orklah
e0eb82a3b1 psalm fixes (#8286) 2020-09-30 22:00:38 +02:00
orklah
79cdcde9ec rename parameters to match parents (#8284) 2020-09-26 20:24:11 +02:00
orklah
f4524a8bb0 Fix psalm errors and upgrade strictness (#8209)
* Fixes and improvements

* fix param type
2020-09-25 20:44:07 +02:00
Simon Podlipsky
f1365b78d5 Rename getIterable to toIterable (#8268) 2020-09-25 20:42:09 +02:00
Grégoire Paris
d810ea4111 Use inline literals over escaping (#8279)
Escaping underscores does not work as expected.
See https://www.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/dql-custom-walkers.html#modify-the-output-walker-to-generate-vendor-specific-sql
2020-09-22 20:10:05 +02:00
Michael Voříšek
107ba93d79 Convert CRLF to LF in test file (#8276)
* Convert CRLF to LF in test file
* fix cs
2020-09-21 22:51:49 +02:00
Guillaume Simon
706670215d Fix OrderByItem parser to proceed with SimpleArithmetic expression before function (#8277)
There is parser bug for OrderByItem(), where a function is detected
before a SimpleArithmeticExpression while it should be the reverse:
simple arithmetic expressions can start with a function too, and thus
they should be matched first if present.

This fix enables the use of expressions in sorting and with window
functions.
2020-09-20 18:56:57 +02:00
Yohann Durand
ab2b4987b3 Improve formatting (#8028) 2020-09-08 20:56:51 +02:00
Thomas Landauer
717ef9106c Update events.rst (#8257)
* Update events.rst

Improved code formatting

* Update docs/en/reference/events.rst

I was wondering myself what the `#` was about ;-)

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>

* Update events.rst

See https://github.com/doctrine/orm/pull/8257#discussion_r482305774

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
2020-09-03 22:44:28 +02:00
Christoph Ziegenberg
ccae8f7176 Fix for bug #8229 (id column from parent class renamed in child class) (#8234)
This fixes problems with id columns defined in the parent class but renamed in the child class using an attribute override. Before this change always the child column name was used (which was not present in the parent class), now the correct column names are used for the parent table when creating inserts, joins and deletions for it.

Co-authored-by: Crossjoin <crossjoin@users.noreply.github.com>
2020-08-29 13:25:18 +02:00
Grégoire Paris
da18985aca Stop using the DBAL extension of PHPBench (#8252)
It has been removed, and the default XML storage driver is supposed to
be fine for our purposes.
2020-08-29 12:28:40 +02:00
Simon Podlipsky
60cd524443 Introduce getIterable() on AbstractQuery (#7885) 2020-08-14 11:12:40 +02:00
Simon Podlipsky
045d1f3bf2 Bump Doctrine CS to v6 (#8241) 2020-08-13 09:10:43 +02:00
Grégoire Paris
1ae6f18fe9 Merge remote-tracking branch 'origin/2.7' into 2.8.x 2020-08-12 22:26:19 +02:00
Simon Podlipsky
1e2ed07731 Use consistent formatting in command line (#8238) 2020-08-12 08:38:00 +02:00
Grégoire Paris
424241f29c Use more accurate terminology (#8236)
I think this was a mistake when writing this documentation, and that the
original author meant to use attribute here, columns do not have
columns, they have attributes.
2020-08-09 22:48:52 +02:00
Grégoire Paris
8230afcde9 Fetch deeper
This is needed to preserve parent information and be able to find the
merge base with the head branch. The assumption here is that the common
ancestor can be found among the 10 parent commits.
2020-08-07 22:11:21 +02:00
Kirill Matasov
7cffba8743 Fix annotation in Expr 2020-08-07 22:11:21 +02:00
Zacharias Luiten
91b9dd90f4 Add DQL support for ORDER BY CASE (#8188) 2020-08-05 22:49:51 +02:00
Benjamin Cremer
7e5fe79349 Change preferred cache driver for metadata and query caches (#8223)
See: https://twitter.com/lcobucci/status/1289087725694484481
2020-08-03 21:40:52 +02:00
njutn95
efd25484f4 Update aggregate-fields.rst (#8215)
Minor typo fix
2020-07-20 21:19:16 +02:00
Andreas Möller
271f3480c8 Fix: Typo (#8213) 2020-07-15 22:46:25 +02:00
orklah
aab589b596 add/fix more types (checked by psalm) (#8199)
* add/fix more psalm types

* remove inexistant SimpleEntityExpression

* Declare template implements for TreeWalkerChainIterator
2020-07-10 22:08:13 +02:00
orklah
190218b267 Change list() syntax to array destructuring (short list syntax) (#8204) 2020-07-07 22:02:34 +02:00
Benjamin Eberlei
181114f2c7 [GH-8106] Move test into existing QueryTest testcase to reduce surface. 2020-07-05 21:51:35 +02:00
tom93
3689b76a86 Fix QueryBuilder::getParameter() on parameter names with colons (#8107)
* Fix type errors

(partially cherry picked from commit 17e7c2a42e)

* Fix QueryBuilder::getParameter() on parameter names with colons

Fixes #8106.

Co-authored-by: Michael Moravec <mail@majkl578.cz>
2020-07-05 21:46:48 +02:00
Igor Pellegrini
75fe18ea5f Add alert to "avoid persisting detached entities" (#8109)
The alert is hidden into the code of ``EntityManager``,
while it's useful to be mentioned in the documentation.
2020-07-05 20:24:08 +02:00
Grégoire Paris
6c73a6b720 Infer return type information with Psalter (#8150)
These changes are a subset of changes done with vendor/bin/psalm --alter
--issues=LessSpecificReturnType
--allow-backwards-incompatible-changes=false
2020-07-05 20:15:39 +02:00
Benjamin Eberlei
775d91c2a3 [GH-8122] Move test from AbstractMappingDriverTest to ClassMetadataFactoryTest case 2020-07-05 20:11:01 +02:00
Gildas Quéméner
64c3f68734 Prohibits class typo in the discriminator map (#8122)
* Prevents incorrect table aliases to be generated

When a defined subclass has a case typo, the query builder will be lost
and will generate exotic table alias. This commit fixes the issue at the
root by prohibiting case typo in discriminator map.

See https://github.com/doctrine/orm/pull/8112 for the consequence of
such typo.

* Controls growing rate of the abstract test class

* Fixes incorrect test case

The Cube class must be autoloaded with the correct case, otherwise
composer autoloader will complain.

* Removes non architecture compliant code

See https://github.com/doctrine/orm/pull/8122/files#r423952247

* Ensures discriminator map is case sensitive
2020-07-05 19:48:38 +02:00
Mohamed Ettaki Talbi
2a2a0b2980 Remove unwanted period (#8198) 2020-07-02 08:36:18 +02:00
Grégoire Paris
505d658e3d Merge remote-tracking branch 'origin/2.7' into 2.8.x 2020-06-21 13:50:48 +02:00
vladyslavstartsev
a438e90046 add dev files to .gitattribute (#8190)
those files probably are not used by end user of the lib
2020-06-19 13:48:45 +02:00
Nicolas Grekas
6a670d7d6d Allow using on PHP 7.1 with Composer 2 (#8184) 2020-06-18 23:05:13 +02:00
Grégoire Paris
765521d257 Use CodeCov instead of Scrutinizer (#8187)
* Document current branch status in the README

* Use CodeCov instead of Scrutinizer
2020-06-17 22:47:25 +02:00
Grégoire Paris
5ced62bf83 Run benchmark on PHP 7.4 (#8186)
phpbench recently dropped compatibilty with PHP 7.1
When this job was introduced, 7.1 was the latest version of PHP we
supported, so it makes sense to bump to 7.4 now.
See https://github.com/phpbench/phpbench/releases/tag/0.17.0
See e07c90df44
2020-06-17 22:06:42 +02:00
Grégoire Paris
bee8decd18 Require persistence 2 and common 3 (#8166)
This allows us to drop the autoload-calls-based BC layer.
2020-06-17 14:56:17 +02:00
Alexander Berl
93867f8d77 TASK: Replace "Blacklist" example with "Banlist" (#8174) 2020-06-08 23:06:53 +02:00
Laurent VOULLEMIER
6bce7e9cab Add iterable support for IN criterias (#8162) 2020-06-03 18:40:53 +02:00
Grégoire Paris
4d8418fe6f Merge remote-tracking branch 'origin/2.7' into drop-persistence-bc-layer 2020-06-02 18:40:48 +02:00
Benjamin Eberlei
850d57e791 [GH-8137] Update doctrine/inflector dependency to 1.4|2.0 (#8147)
* [GH-8137] Update doctrine/inflector dependency to 1.4|2.0 and resolve deprecations.

* [GH-8137] Address review comments

* Address phpcs issues.

* More CS

* Codingstyle
2020-05-17 19:58:02 +02:00
Grégoire Paris
c3dd71704b Merge remote-tracking branch 'origin/2.7' into 2.8.x 2020-05-16 15:14:51 +02:00
Philippe Le Van (@plv)
0b305e5bd3 Add possibility to use sql comments in the DQL syntax (#8140) 2020-05-15 08:04:58 +02:00
Gabriel Birke
061207861b Improve CLI config documentation (#8130)
Change code examples for `cli-config.php` to use
`ConsoleRunner::createHelperSet` instead of constructing the helper set
array yourself.
Remove DBAL-specific documentation

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
2020-05-11 21:43:26 +02:00
Grégoire Paris
3c91792dd8 Address deprecation about PHPUnit annotations (#8070)
These changes have been done using Rector, this might not result in the
best placement for method calls, but it is not worse than the current
situation.

I used the configuration documented at
b398e8740c/docs/HowItWorks.md (221-order-of-rectors)

Fixes #8069
2020-03-16 08:56:59 +01:00
Claudio Zizza
431d0a3c5e Remove ORM 2.0 version constraints from docs (#8002) 2020-03-06 21:47:40 +01:00
Soliman
1da002ca2f Throw OptimisticLockException when connection::commit() returns… (#7946)
* Throw OptimisticLockException when connection::commit() returns false

* Update unit tests

* Fix doctrine persistence version to avoid deprecations changes

* Apply changes from 2.8.x

* Update from 2.8.x
2020-02-29 23:06:47 +01:00
Benjamin Eberlei
ef639d4de6 Remove nightly builds from .travis.yml 2020-02-15 15:34:05 +01:00
Benjamin Eberlei
31f4dd671a Merge remote-tracking branch 'origin/2.7' into 2.8.x 2020-02-13 21:31:29 +01:00
Benjamin Eberlei
60c4867ed3 Merge branch 2.7 into 2.8.x 2020-02-12 23:42:36 +01:00
Benjamin Eberlei
0ee1716b26 Merge branch 2.7 into 2.8.x 2020-02-12 23:38:27 +01:00
Claudio Zizza
a236a83fa8 Merge pull request #7993 from SenseException/readme2-8
Update version and links in readme
2020-01-20 11:14:33 +01:00
Claudio Zizza
37f1bd7606 Update version and links in readme 2020-01-17 21:42:59 +01:00
Grégoire Paris
af4cb282ba Merge pull request #7978 from alexeyshockov/patch-2
Stable PHP 7.4 in Travis
2020-01-17 07:49:48 +01:00
Benjamin Eberlei
ce4914ba0e Merge 2.7 to 2.8.x 2020-01-17 00:08:23 +01:00
Alexey Shokov
bdfd6c1677 Stable PHP 7.4 in Travis 2020-01-16 23:27:20 +01:00
Benjamin Eberlei
8e0157d97d Merge branch '2.7' into 2.8.x 2020-01-15 22:57:06 +01:00
Benjamin Eberlei
1767f4b8e7 Merge branch '2.7' into 2.8.x 2020-01-15 22:02:55 +01:00
Benjamin Eberlei
ca95b0ee13 Merge branch '2.7' into 2.8.x 2020-01-08 19:39:17 +01:00
Luís Cobucci
4aa09861dd Merge pull request #7941 from Grafikart/feat-typed-functions
Allow DQL functions to specify return type
2019-12-12 19:50:23 +01:00
Grafikart
24e9a7caaf Allow defining return types for DQL functions 2019-12-12 14:19:09 +01:00
Luís Cobucci
d90df59118 Merge pull request #7948 from beberlei/TravisSmokeTesting
Add stage that runs before Test to allow fast failures on Sqlite/phpcs
2019-12-12 11:54:41 +01:00
Benjamin Eberlei
f9103a7b41 Add another stage that runs before Test to allow fast failures on Sqlite, Quality + PHPCS-differ 2019-12-12 11:43:24 +01:00
Luís Cobucci
9891477094 Merge pull request #7928 from kokspflanze/2.7-patch-deprecated
Deprecate EntityRepository#clear()
2019-12-09 21:56:41 +01:00
kokspflanze
59e3a55110 Deprecate EntityRepository#clear() 2019-12-09 21:42:11 +01:00
1483 changed files with 67311 additions and 51833 deletions

73
.doctrine-project.json Normal file
View File

@@ -0,0 +1,73 @@
{
"active": true,
"name": "Object Relational Mapper",
"shortName": "ORM",
"slug": "orm",
"docsSlug": "doctrine-orm",
"versions": [
{
"name": "3.0",
"branchName": "3.0.x",
"slug": "latest",
"upcoming": true
},
{
"name": "2.12",
"branchName": "2.12.x",
"slug": "2.12",
"upcoming": true
},
{
"name": "2.11",
"branchName": "2.11.x",
"slug": "2.11",
"current": true,
"aliases": [
"current",
"stable"
]
},
{
"name": "2.10",
"branchName": "2.10.x",
"slug": "2.10",
"maintained": false
},
{
"name": "2.9",
"branchName": "2.9.x",
"slug": "2.9",
"maintained": false
},
{
"name": "2.8",
"branchName": "2.8.x",
"slug": "2.8",
"maintained": false
},
{
"name": "2.7",
"branchName": "2.7",
"slug": "2.7",
"maintained": false
},
{
"name": "2.6",
"branchName": "2.6",
"slug": "2.6",
"maintained": false
},
{
"name": "2.5",
"branchName": "2.5",
"slug": "2.5",
"maintained": false
},
{
"name": "2.4",
"branchName": "2.4",
"slug": "2.4",
"maintained": false
}
]
}

10
.gitattributes vendored
View File

@@ -1,9 +1,10 @@
/tests export-ignore
/tools export-ignore
/docs export-ignore
/.github export-ignore
.doctrine-project.json export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.gitmodules export-ignore
.travis.yml export-ignore
build.properties export-ignore
build.properties.dev export-ignore
build.xml export-ignore
@@ -11,3 +12,8 @@ CONTRIBUTING.md export-ignore
phpunit.xml.dist export-ignore
run-all.sh export-ignore
phpcs.xml.dist export-ignore
phpbench.json export-ignore
phpstan.neon export-ignore
phpstan-baseline.neon export-ignore
psalm.xml export-ignore
psalm-baseline.xml export-ignore

37
.github/ISSUE_TEMPLATE/BC_Break.md vendored Normal file
View File

@@ -0,0 +1,37 @@
---
name: 💥 BC Break
about: Have you encountered an issue during upgrade? 💣
---
<!--
Before reporting a BC break, please consult the upgrading document to make sure it's not an expected change: https://github.com/doctrine/orm/blob/2.9.x/UPGRADE.md
-->
### BC Break Report
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A
|------------ | ------
| BC Break | yes
| Version | x.y.z
#### Summary
<!-- Provide a summary describing the problem you are experiencing. -->
#### Previous behavior
<!-- What was the previous (working) behavior? -->
#### Current behavior
<!-- What is the current (broken) behavior? -->
#### How to reproduce
<!--
Provide steps to reproduce the BC break.
If possible, also add a code snippet with relevant configuration, entity mappings, DQL etc.
Adding a failing Unit or Functional Test would help us a lot - you can submit it in a Pull Request separately, referencing this bug report.
-->

34
.github/ISSUE_TEMPLATE/Bug.md vendored Normal file
View File

@@ -0,0 +1,34 @@
---
name: 🐞 Bug Report
about: Something is broken? 🔨
---
### Bug Report
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A
|------------ | ------
| BC Break | yes/no
| Version | x.y.z
#### Summary
<!-- Provide a summary describing the problem you are experiencing. -->
#### Current behavior
<!-- What is the current (buggy) behavior? -->
#### How to reproduce
<!--
Provide steps to reproduce the bug.
If possible, also add a code snippet with relevant configuration, entity mappings, DQL etc.
Adding a failing Unit or Functional Test would help us a lot - you can submit one in a Pull Request separately, referencing this bug report.
-->
#### Expected behavior
<!-- What was the expected (correct) behavior? -->

View File

@@ -0,0 +1,18 @@
---
name: 🎉 Feature Request
about: You have a neat idea that should be implemented? 🎩
---
### Feature Request
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A
|------------ | ------
| New Feature | yes
| RFC | yes/no
| BC Break | yes/no
#### Summary
<!-- Provide a summary of the feature you would like to see implemented. -->

View File

@@ -0,0 +1,6 @@
---
name: ❓ Support Question
about: Have a problem that you can't figure out? 🤔
---
Please use https://github.com/doctrine/orm/discussions instead.

View File

@@ -0,0 +1,19 @@
---
name: 🐞 Failing Test
about: You found a bug and have a failing Unit or Functional test? 🔨
---
### Failing Test
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A
|------------ | ------
| BC Break | yes/no
| Version | x.y.z
#### Summary
<!-- Provide a summary of the failing scenario. -->

View File

@@ -0,0 +1,18 @@
---
name: ⚙ Improvement
about: You have some improvement to make Doctrine better? 🎁
---
### Improvement
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A
|------------ | ------
| New Feature | yes
| RFC | yes/no
| BC Break | yes/no
#### Summary
<!-- Provide a summary of the improvement you are submitting. -->

View File

@@ -0,0 +1,26 @@
---
name: 🎉 New Feature
about: You have implemented some neat idea that you want to make part of Doctrine? 🎩
---
<!--
Thank you for submitting new feature!
Pick the target branch based according to these criteria:
* submitting a bugfix: target the lowest active stable branch: 2.9.x
* submitting a new feature: target the next minor branch: 2.10.x
* submitting a BC-breaking change: target the next major branch: 3.0.x
-->
### New Feature
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A
|------------ | ------
| New Feature | yes
| RFC | yes/no
| BC Break | yes/no
#### Summary
<!-- Provide a summary of the feature you have implemented. -->

View File

@@ -1,109 +0,0 @@
name: CI
on:
pull_request:
jobs:
static-analysis-phpstan:
name: "Static Analysis with PHPStan"
runs-on: "ubuntu-latest"
strategy:
matrix:
php-version:
- "7.4"
steps:
- name: "Checkout code"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
tools: cs2pr
- name: "Cache dependencies installed with composer"
uses: "actions/cache@v1"
with:
path: "~/.composer/cache"
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
- name: "Install dependencies with composer"
run: "composer install --no-progress --no-suggest --no-interaction --prefer-dist"
- name: "Run a static analysis with phpstan/phpstan"
run: "php vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr"
static-analysis-psalm:
name: "Static Analysis with Psalm"
runs-on: "ubuntu-latest"
strategy:
matrix:
php-version:
- "7.4"
steps:
- name: "Checkout code"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
- name: "Cache dependencies installed with composer"
uses: "actions/cache@v1"
with:
path: "~/.composer/cache"
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
- name: "Install dependencies with composer"
run: "composer install --no-interaction --no-progress --no-suggest"
- name: "Run a static analysis with vimeo/psalm"
run: "vendor/bin/psalm --show-info=false --stats --output-format=github --threads=$(nproc)"
coding-standards:
name: "Coding Standards"
runs-on: "ubuntu-latest"
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: "Cache dependencies installed with composer"
uses: "actions/cache@v1"
with:
path: "~/.composer/cache"
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
- name: "Install dependencies with composer"
run: "composer install --no-interaction --no-progress --no-suggest"
- name: "Install git-phpcs"
run: "wget https://github.com/diff-sniffer/git/releases/download/0.3.2/git-phpcs.phar"
- name: "Fetch head branch"
run: "git remote set-branches --add origin $GITHUB_BASE_REF && git fetch origin $GITHUB_BASE_REF"
- name: "Run git-phpcs"
run: "php git-phpcs.phar origin/$GITHUB_BASE_REF...$GITHUB_SHA --report=checkstyle|cs2pr"

15
.github/workflows/coding-standard.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
name: "Coding Standards"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
jobs:
coding-standards:
uses: "doctrine/.github/.github/workflows/coding-standards.yml@1.4.1"
with:
php-version: "8.1"

View File

@@ -0,0 +1,329 @@
name: "Continuous Integration"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
env:
fail-fast: true
jobs:
phpunit-smoke-check:
name: "PHPUnit with SQLite"
runs-on: "ubuntu-20.04"
strategy:
matrix:
php-version:
- "7.2"
- "7.3"
- "7.4"
- "8.0"
- "8.1"
dbal-version:
- "default"
include:
- php-version: "8.0"
dbal-version: "2.13"
- php-version: "8.1"
dbal-version: "3@dev"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
extensions: "pdo, pdo_sqlite"
coverage: "pcov"
ini-values: "zend.assertions=1"
- name: "Require specific DBAL version"
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
if: "${{ matrix.dbal-version != 'default' }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit -c ci/github/phpunit/sqlite.xml --coverage-clover=coverage-no-cache.xml"
env:
ENABLE_SECOND_LEVEL_CACHE: 0
- name: "Run PHPUnit with Second Level Cache"
run: "vendor/bin/phpunit -c ci/github/phpunit/sqlite.xml --exclude-group performance,non-cacheable,locking_functional --coverage-clover=coverage-cache.xml"
env:
ENABLE_SECOND_LEVEL_CACHE: 1
- name: "Upload coverage file"
uses: "actions/upload-artifact@v2"
with:
name: "phpunit-sqlite-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage"
path: "coverage*.xml"
phpunit-postgres:
name: "PHPUnit with PostgreSQL"
runs-on: "ubuntu-20.04"
needs: "phpunit-smoke-check"
strategy:
matrix:
php-version:
- "8.1"
dbal-version:
- "default"
postgres-version:
- "9.6"
- "14"
include:
- php-version: "8.0"
dbal-version: "2.13"
postgres-version: "14"
services:
postgres:
image: "postgres:${{ matrix.postgres-version }}"
env:
POSTGRES_PASSWORD: "postgres"
options: >-
--health-cmd "pg_isready"
ports:
- "5432:5432"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
ini-values: "zend.assertions=1"
- name: "Require specific DBAL version"
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
if: "${{ matrix.dbal-version != 'default' }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit -c ci/github/phpunit/pdo_pgsql.xml --coverage-clover=coverage.xml"
- name: "Upload coverage file"
uses: "actions/upload-artifact@v2"
with:
name: "${{ github.job }}-${{ matrix.postgres-version }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage"
path: "coverage.xml"
phpunit-mariadb:
name: "PHPUnit with MariaDB"
runs-on: "ubuntu-20.04"
needs: "phpunit-smoke-check"
strategy:
matrix:
php-version:
- "8.1"
dbal-version:
- "default"
mariadb-version:
- "10.6"
extension:
- "mysqli"
- "pdo_mysql"
include:
- php-version: "8.0"
dbal-version: "2.13"
mariadb-version: "10.6"
extension: "pdo_mysql"
services:
mariadb:
image: "mariadb:${{ matrix.mariadb-version }}"
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: "doctrine_tests"
options: >-
--health-cmd "mysqladmin ping --silent"
ports:
- "3306:3306"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Require specific DBAL version"
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
if: "${{ matrix.dbal-version != 'default' }}"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
ini-values: "zend.assertions=1"
extensions: "${{ matrix.extension }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage.xml"
- name: "Upload coverage file"
uses: "actions/upload-artifact@v2"
with:
name: "${{ github.job }}-${{ matrix.mariadb-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage"
path: "coverage.xml"
phpunit-mysql:
name: "PHPUnit with MySQL"
runs-on: "ubuntu-20.04"
needs: "phpunit-smoke-check"
strategy:
matrix:
php-version:
- "8.1"
dbal-version:
- "default"
mysql-version:
- "5.7"
- "8.0"
extension:
- "mysqli"
- "pdo_mysql"
include:
- php-version: "8.0"
dbal-version: "2.13"
mysql-version: "8.0"
extension: "pdo_mysql"
services:
mysql:
image: "mysql:${{ matrix.mysql-version }}"
options: >-
--health-cmd "mysqladmin ping --silent"
-e MYSQL_ALLOW_EMPTY_PASSWORD=yes
-e MYSQL_DATABASE=doctrine_tests
ports:
- "3306:3306"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
ini-values: "zend.assertions=1"
extensions: "${{ matrix.extension }}"
- name: "Require specific DBAL version"
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
if: "${{ matrix.dbal-version != 'default' }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage-no-cache.xml"
env:
ENABLE_SECOND_LEVEL_CACHE: 0
- name: "Run PHPUnit with Second Level Cache"
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --exclude-group performance,non-cacheable,locking_functional --coverage-clover=coverage-no-cache.xml"
env:
ENABLE_SECOND_LEVEL_CACHE: 1
- name: "Upload coverage files"
uses: "actions/upload-artifact@v2"
with:
name: "${{ github.job }}-${{ matrix.mysql-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage"
path: "coverage*.xml"
phpunit-lower-php-versions:
name: "PHPUnit with SQLite"
runs-on: "ubuntu-20.04"
strategy:
matrix:
php-version:
- "7.1"
deps:
- "highest"
- "lowest"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
ini-values: "zend.assertions=1"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
dependency-versions: "${{ matrix.deps }}"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit -c ci/github/phpunit/sqlite.xml"
upload_coverage:
name: "Upload coverage to Codecov"
runs-on: "ubuntu-20.04"
needs:
- "phpunit-smoke-check"
- "phpunit-postgres"
- "phpunit-mariadb"
- "phpunit-mysql"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Download coverage files"
uses: "actions/download-artifact@v2"
with:
path: "reports"
- name: "Upload to Codecov"
uses: "codecov/codecov-action@v1"
with:
directory: reports

49
.github/workflows/phpbench.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: "Performance benchmark"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
env:
fail-fast: true
jobs:
phpbench:
name: "PHPBench"
runs-on: "ubuntu-20.04"
strategy:
matrix:
php-version:
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
ini-values: "zend.assertions=1"
- name: "Cache dependencies installed with composer"
uses: "actions/cache@v2"
with:
path: "~/.composer/cache"
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
- name: "Install dependencies with composer"
run: "composer update --no-interaction --no-progress"
- name: "Run PHPBench"
run: "vendor/bin/phpbench run --report=default"

View File

@@ -0,0 +1,15 @@
name: "Automatic Releases"
on:
milestone:
types:
- "closed"
jobs:
release:
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@1.4.1"
secrets:
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 }}

79
.github/workflows/static-analysis.yml vendored Normal file
View File

@@ -0,0 +1,79 @@
name: "Static Analysis"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
jobs:
static-analysis-phpstan:
name: "Static Analysis with PHPStan"
runs-on: "ubuntu-20.04"
strategy:
fail-fast: false
matrix:
php-version:
- "8.1"
dbal-version:
- "default"
- "2.13"
steps:
- name: "Checkout code"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
- name: "Require specific DBAL version"
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
if: "${{ matrix.dbal-version != 'default' }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
dependency-versions: "highest"
- name: "Run a static analysis with phpstan/phpstan"
run: "vendor/bin/phpstan analyse"
if: "${{ matrix.dbal-version == 'default' }}"
- name: "Run a static analysis with phpstan/phpstan"
run: "vendor/bin/phpstan analyse -c phpstan-dbal2.neon"
if: "${{ matrix.dbal-version == '2.13' }}"
static-analysis-psalm:
name: "Static Analysis with Psalm"
runs-on: "ubuntu-20.04"
strategy:
fail-fast: false
matrix:
php-version:
- "8.1"
steps:
- name: "Checkout code"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
dependency-versions: "highest"
- name: "Run a static analysis with vimeo/psalm"
run: "vendor/bin/psalm --show-info=false --stats --output-format=github --threads=$(nproc)"

3
.gitignore vendored
View File

@@ -14,3 +14,6 @@ lib/Doctrine/DBAL
vendor/
/tests/Doctrine/Performance/history.db
/.phpcs-cache
composer.lock
.phpunit.result.cache
/*.phpunit.xml

View File

@@ -1,34 +0,0 @@
build:
nodes:
analysis:
environment:
php:
version: 7.1
cache:
disabled: false
directories:
- ~/.composer/cache
project_setup:
override: true
tests:
override:
- php-scrutinizer-run
before_commands:
- "composer install --no-dev --prefer-source"
tools:
external_code_coverage:
timeout: 3600
filter:
excluded_paths:
- docs
- tools
build_failure_conditions:
- 'elements.rating(<= C).new.exists' # No new classes/methods with a rating of C or worse allowed
- 'issues.severity(>= MAJOR).new.exists' # New issues of major or higher severity
- 'project.metric_change("scrutinizer.test_coverage", < 0)' # Code Coverage decreased from previous inspection
- 'patches.label("Unused Use Statements").new.exists' # No new unused imports patches allowed

View File

@@ -1,106 +0,0 @@
dist: trusty
sudo: false
language: php
php:
- 7.1
- 7.2
- 7.3
- 7.4
env:
- DB=sqlite
- DB=mysql
- DB=pgsql
before_install:
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{,.disabled} || echo "xdebug not available"
- composer self-update
install: travis_retry composer validate --strict && composer update --prefer-dist
script:
- if [[ "$DB" == "mysql" || "$DB" == "mariadb" ]]; then mysql -e "CREATE SCHEMA doctrine_tests; GRANT ALL PRIVILEGES ON doctrine_tests.* to travis@'%'"; fi
- ENABLE_SECOND_LEVEL_CACHE=0 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml
- ENABLE_SECOND_LEVEL_CACHE=1 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml --exclude-group performance,non-cacheable,locking_functional
jobs:
include:
- stage: Test
env: DB=mariadb
addons:
mariadb: 10.1
- stage: Test
dist: xenial
env: DB=mysql MYSQL_VERSION=5.7
php: 7.1
services:
- mysql
before_script:
- ./tests/travis/install-mysql-$MYSQL_VERSION.sh
sudo: required
- stage: Test
dist: xenial
env: DB=mysql MYSQL_VERSION=5.7
php: 7.2
services:
- mysql
before_script:
- ./tests/travis/install-mysql-$MYSQL_VERSION.sh
sudo: required
- stage: Test
dist: xenial
env: DB=mysql MYSQL_VERSION=5.7
php: 7.4
services:
- mysql
before_script:
- ./tests/travis/install-mysql-$MYSQL_VERSION.sh
sudo: required
- stage: Test
env: DB=sqlite DEPENDENCIES=low
install: travis_retry composer update --prefer-dist --prefer-lowest
- stage: Test
if: type = cron
php: 7.3
env: DB=sqlite DEV_DEPENDENCIES
install:
- composer config minimum-stability dev
- travis_retry composer update --prefer-dist
- stage: Test
env: DB=sqlite COVERAGE
before_script:
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{.disabled,}
- if [[ ! $(php -m | grep -si xdebug) ]]; then echo "xdebug required for coverage"; exit 1; fi
script:
- ENABLE_SECOND_LEVEL_CACHE=0 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml --coverage-clover ./build/logs/clover.xml
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml
- stage: Code Quality
env: DB=none BENCHMARK
before_script: wget https://phpbench.github.io/phpbench/phpbench.phar https://phpbench.github.io/phpbench/phpbench.phar.pubkey
script: php phpbench.phar run -l dots --report=default
- stage: Code Quality
if: NOT type = pull_request
env: DB=none CODING_STANDARDS
php: 7.4
install: travis_retry composer install --prefer-dist
script:
- ./vendor/bin/phpcs
allow_failures:
- stage: Code Quality
env: DB=none CODING_STANDARDS
cache:
directories:
- $HOME/.composer/cache

View File

@@ -6,30 +6,17 @@ Before we can merge your Pull-Request here are some guidelines that you need to
These guidelines exist not to annoy you, but to keep the code base clean,
unified and future proof.
## We only accept PRs to "master"
Doctrine has [general contributing guidelines][contributor workflow], make
sure you follow them.
Our branching strategy is "everything to master first", even
bugfixes and we then merge them into the stable branches. You should only
open pull requests against the master branch. Otherwise we cannot accept the PR.
There is one exception to the rule, when we merged a bug into some stable branches
we do occasionally accept pull requests that merge the same bug fix into earlier
branches.
[contributor workflow]: https://www.doctrine-project.org/contribute/index.html
## Coding Standard
We use PSR-1 and PSR-2:
This project follows [`doctrine/coding-standard`][coding standard homepage].
You may fix many some of the issues with `vendor/bin/phpcbf`.
* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md
* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
with some exceptions/differences:
* Keep the nesting of control structures per method as small as possible
* Align equals (=) signs
* Add spaces between assignment, control and return statements
* Prefer early exit over nesting conditions
* Add spaces around a negation if condition ``if ( ! $cond)``
[coding standard homepage]: https://github.com/doctrine/coding-standard
## Unit-Tests
@@ -56,25 +43,19 @@ curl -sS https://getcomposer.org/installer | php --
To run the testsuite against another database, copy the ``phpunit.xml.dist``
to for example ``mysql.phpunit.xml`` and edit the parameters. You can
take a look at the ``tests/travis`` folder for some examples. Then run:
take a look at the ``ci/github/phpunit`` directory for some examples. Then run:
vendor/bin/phpunit -c mysql.phpunit.xml
If you do not provide these parameters, the test suite will use an in-memory
sqlite database.
Tips for creating unit tests:
1. If you put a test into the `Ticket` namespace as described above, put the testcase and all entities into the same class.
See `https://github.com/doctrine/orm/tree/master/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2306Test.php` for an
See `https://github.com/doctrine/orm/tree/2.8.x/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2306Test.php` for an
example.
## Travis
We automatically run your pull request through [Travis CI](http://www.travis-ci.org)
against SQLite, MySQL and PostgreSQL. If you break the tests, we cannot merge your code,
so please make sure that your code is working before opening up a Pull-Request.
## Getting merged
Please allow us time to review your pull requests. We will give our best to review

View File

@@ -1,4 +1,4 @@
Copyright (c) 2006-2015 Doctrine Project
Copyright (c) Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

View File

@@ -1,7 +1,7 @@
| [Master][Master] | [2.5][2.5] |
|:----------------:|:----------:|
| [![Build status][Master image]][Master] | [![Build status][2.5 image]][2.5] |
| [![Coverage Status][Master coverage image]][Master coverage] | [![Coverage Status][2.5 coverage image]][2.5 coverage] |
| [3.0.x][3.0] | [2.12.x][2.12] | [2.11.x][2.11] |
|:----------------:|:----------------:|:----------:|
| [![Build status][3.0 image]][3.0] | [![Build status][2.12 image]][2.12] | [![Build status][2.11 image]][2.11] |
| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.12 coverage image]][2.12 coverage] | [![Coverage Status][2.11 coverage image]][2.11 coverage] |
Doctrine 2 is an object-relational mapper (ORM) for PHP 7.1+ that provides transparent persistence
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
@@ -13,14 +13,18 @@ without requiring unnecessary code duplication.
## More resources:
* [Website](http://www.doctrine-project.org)
* [Documentation](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/index.html)
* [Documentation](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/index.html)
[Master image]: https://img.shields.io/travis/doctrine/orm/master.svg?style=flat-square
[Master]: https://travis-ci.org/doctrine/orm
[Master coverage image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/orm/master.svg?style=flat-square
[Master coverage]: https://scrutinizer-ci.com/g/doctrine/orm/?branch=master
[2.5 image]: https://img.shields.io/travis/doctrine/orm/2.5.svg?style=flat-square
[2.5]: https://github.com/doctrine/orm/tree/2.5
[2.5 coverage image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/orm/2.5.svg?style=flat-square
[2.5 coverage]: https://scrutinizer-ci.com/g/doctrine/orm/?branch=2.5
[3.0 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.0.x
[3.0]: https://github.com/doctrine/orm/tree/3.0.x
[3.0 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.0.x/graph/badge.svg
[3.0 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.0.x
[2.12 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.12.x
[2.12]: https://github.com/doctrine/orm/tree/2.12.x
[2.12 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.12.x/graph/badge.svg
[2.12 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.12.x
[2.11 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.11.x
[2.11]: https://github.com/doctrine/orm/tree/2.11.x
[2.11 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.11.x/graph/badge.svg
[2.11 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.11.x

View File

@@ -10,8 +10,8 @@ we cannot protect you from SQL injection.
Please read the documentation chapter on Security in Doctrine DBAL and ORM to
understand the assumptions we make.
- [DBAL Security Page](https://github.com/doctrine/dbal/blob/master/docs/en/reference/security.rst)
- [ORM Security Page](https://github.com/doctrine/orm/blob/master/docs/en/reference/security.rst)
- [DBAL Security Page](https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/security.html)
- [ORM Security Page](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/security.html)
If you find a Security bug in Doctrine, please report it on Jira and change the
Security Level to "Security Issues". It will be visible to Doctrine Core

View File

@@ -1,3 +1,174 @@
# Upgrade to 2.11
## Rename `AbstractIdGenerator::generate()` to `generateId()`
Implementations of `AbstractIdGenerator` have to override the method
`generateId()` without calling the parent implementation. Not doing so is
deprecated. Calling `generate()` on any `AbstractIdGenerator` implementation
is deprecated.
## PSR-6-based second level cache
The second level cache has been reworked to consume a PSR-6 cache. Using a
Doctrine Cache instance is deprecated.
* `DefaultCacheFactory`: The constructor expects a PSR-6 cache item pool as
second argument now.
* `DefaultMultiGetRegion`: This class is deprecated in favor of `DefaultRegion`.
* `DefaultRegion`:
* The constructor expects a PSR-6 cache item pool as second argument now.
* The protected `$cache` property is deprecated.
* The properties `$name` and `$lifetime` as well as the constant
`REGION_KEY_SEPARATOR` and the method `getCacheEntryKey()` are flagged as
`@internal` now. They all will become `private` in 3.0.
* The method `getCache()` is deprecated without replacement.
## Deprecated: `Doctrine\ORM\Mapping\Driver\PHPDriver`
Use `StaticPHPDriver` instead when you want to programmatically configure
entity metadata.
You can convert mappings with the `orm:convert-mapping` command or more simply
in this case, `include` the metadata file from the `loadMetadata` static method
used by the `StaticPHPDriver`.
## Deprecated: `Setup::registerAutoloadDirectory()`
Use Composer's autoloader instead.
## Deprecated: `AbstractHydrator::hydrateRow()`
Following the deprecation of the method `AbstractHydrator::iterate()`, the
method `hydrateRow()` has been deprecated as well.
## Deprecate cache settings inspection
Doctrine does not provide its own cache implementation anymore and relies on
the PSR-6 standard instead. As a consequence, we cannot determine anymore
whether a given cache adapter is suitable for a production environment.
Because of that, functionality that aims to do so has been deprecated:
* `Configuration::ensureProductionSettings()`
* the `orm:ensure-production-settings` console command
# 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.
It is now deprecated to rely on:
- `Doctrine\ORM\Id\TableGenerator`;
- `Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_TABLE`;
- `Doctrine\ORM\Mapping\ClassMetadata::$tableGeneratorDefinition`;
- or `Doctrine\ORM\Mapping\ClassMetadata::isIdGeneratorTable()`.
## 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_.
Because of BC policy, the method does not exist on the interface yet. This is the example of safe usage:
```php
function foo(EntityManagerInterface $entityManager, callable $func) {
if (method_exists($entityManager, 'wrapInTransaction')) {
return $entityManager->wrapInTransaction($func);
}
return $entityManager->transactional($func);
}
```
`Doctrine\ORM\EntityManagerInterface#transactional()` has been deprecated.
## Minor BC BREAK: some exception methods have been removed
The following methods were not in use and are very unlikely to be used by
downstream packages or applications, and were consequently removed:
- `ORMException::entityMissingForeignAssignedId`
- `ORMException::entityMissingAssignedIdForField`
- `ORMException::invalidFlushMode`
## Deprecated: database-side UUID generation
[DB-generated UUIDs are deprecated as of `doctrine/dbal` 2.8][DBAL deprecation].
As a consequence, using the `UUID` strategy for generating identifiers is deprecated as well.
Furthermore, relying on the following classes and methods is deprecated:
- `Doctrine\ORM\Id\UuidGenerator`
- `Doctrine\ORM\Mapping\ClassMetadataInfo::isIdentifierUuid()`
[DBAL deprecation]: https://github.com/doctrine/dbal/pull/3212
## Minor BC BREAK: Custom hydrators and `toIterable()`
The type declaration of the `$stmt` parameter of `AbstractHydrator::toIterable()` has been removed. This change might
break custom hydrator implementations that override this very method.
Overriding this method is not recommended, which is why the method is documented as `@final` now.
```diff
- public function toIterable(ResultStatement $stmt, ResultSetMapping $resultSetMapping, array $hints = []): iterable
+ public function toIterable($stmt, ResultSetMapping $resultSetMapping, array $hints = []): iterable
```
## Deprecated: Entity Namespace Aliases
Entity namespace aliases are deprecated, use the magic ::class constant to abbreviate full class names
in EntityManager, EntityRepository and DQL.
```diff
- $entityManager->find('MyBundle:User', $id);
+ $entityManager->find(User::class, $id);
```
# Upgrade to 2.9
## Minor BC BREAK: Setup tool needs cache implementation
With the deprecation of doctrine/cache, the setup tool might no longer work as expected without a different cache
implementation. To work around this:
* Install symfony/cache: `composer require symfony/cache`. This will keep previous behaviour without any changes
* Instantiate caches yourself: to use a different cache implementation, pass a cache instance when calling any
configuration factory in the setup tool:
```diff
- $config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode, $proxyDir);
+ $cache = \Doctrine\Common\Cache\Psr6\DoctrineProvider::wrap($anyPsr6Implementation);
+ $config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode, $proxyDir, $cache);
```
* As a quick workaround, you can lock the doctrine/cache dependency to work around this: `composer require doctrine/cache ^1.11`.
Note that this is only recommended as a bandaid fix, as future versions of ORM will no longer work with doctrine/cache
1.11.
## Deprecated: doctrine/cache for metadata caching
The `Doctrine\ORM\Configuration#setMetadataCacheImpl()` method is deprecated and should no longer be used. Please use
`Doctrine\ORM\Configuration#setMetadataCache()` with any PSR-6 cache adapter instead.
## Removed: flushing metadata cache
To support PSR-6 caches, the `--flush` option for the `orm:clear-cache:metadata` command is ignored. Metadata cache is
now always cleared regardless of the cache adapter being used.
# Upgrade to 2.8
## Minor BC BREAK: Failed commit now throw OptimisticLockException
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#iterate()`
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
## Added `Doctrine\ORM\AbstractQuery#enableResultCache()` and `Doctrine\ORM\AbstractQuery#disableResultCache()` methods
@@ -30,7 +201,7 @@ Method `Doctrine\ORM\AbstractQuery#useResultCache()` is deprecated because it is
and `disableResultCache()`. It will be removed in 3.0.
## Deprecated code generators and related console commands
These console commands have been deprecated:
* `orm:convert-mapping`
@@ -64,27 +235,18 @@ These methods have been deprecated:
## Deprecated `Doctrine\ORM\Version`
The `Doctrine\ORM\Version` class is now deprecated and will be removed in Doctrine ORM 3.0:
please refrain from checking the ORM version at runtime or use
[ocramius/package-versions](https://github.com/Ocramius/PackageVersions/).
please refrain from checking the ORM version at runtime or use Composer's [runtime API](https://getcomposer.org/doc/07-runtime.md#knowing-whether-package-x-is-installed-in-version-y).
## Deprecated `EntityManager#merge()` and `EntityManager#detach()` methods
## Deprecated `EntityManager#merge()` method
Merge and detach semantics were a poor fit for the PHP "share-nothing" architecture.
In addition to that, merging/detaching caused multiple issues with data integrity
Merge semantics was a poor fit for the PHP "share-nothing" architecture.
In addition to that, merging caused multiple issues with data integrity
in the managed entity graph, which was constantly spawning more edge-case bugs/scenarios.
The following API methods were therefore deprecated:
* `EntityManager#merge()`
* `EntityManager#detach()`
* `UnitOfWork#merge()`
* `UnitOfWork#detach()`
Users are encouraged to migrate `EntityManager#detach()` calls to `EntityManager#clear()`.
In order to maintain performance on batch processing jobs, it is endorsed to enable
the second level cache (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/second-level-cache.html)
on entities that are frequently reused across multiple `EntityManager#clear()` calls.
An alternative to `EntityManager#merge()` will not be provided by ORM 3.0, since the merging
semantics should be part of the business domain rather than the persistence domain of an

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env php
<?php
include('doctrine.php');
include(__DIR__ . '/doctrine.php');

View File

@@ -1,21 +1,4 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
require_once 'Doctrine/Common/ClassLoader.php';

View File

@@ -1,9 +1,9 @@
@echo off
if "%PHPBIN%" == "" set PHPBIN=@php_bin@
if not exist "%PHPBIN%" if "%PHP_PEAR_PHP_BIN%" neq "" goto USE_PEAR_PATH
GOTO RUN
:USE_PEAR_PATH
set PHPBIN=%PHP_PEAR_PHP_BIN%
:RUN
"%PHPBIN%" "@bin_dir@\doctrine" %*
@echo off
if "%PHPBIN%" == "" set PHPBIN=@php_bin@
if not exist "%PHPBIN%" if "%PHP_PEAR_PHP_BIN%" neq "" goto USE_PEAR_PATH
GOTO RUN
:USE_PEAR_PATH
set PHPBIN=%PHP_PEAR_PHP_BIN%
:RUN
"%PHPBIN%" "@bin_dir@\doctrine" %*

View File

@@ -1,21 +1,4 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
use Symfony\Component\Console\Helper\HelperSet;
use Doctrine\ORM\Tools\Console\ConsoleRunner;

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
failOnRisky="true"
convertDeprecationsToExceptions="true"
>
<php>
<ini name="error_reporting" value="-1" />
<var name="db_driver" value="mysqli"/>
<var name="db_host" value="127.0.0.1" />
<var name="db_port" value="3306"/>
<var name="db_user" value="root" />
<var name="db_dbname" value="doctrine_tests" />
<!-- necessary change for some CLI/console output test assertions -->
<env name="COLUMNS" value="120"/>
</php>
<testsuites>
<testsuite name="Doctrine DBAL Test Suite">
<directory>../../../tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">../../../lib/Doctrine</directory>
</whitelist>
</filter>
<groups>
<exclude>
<group>performance</group>
<group>locking_functional</group>
</exclude>
</groups>
</phpunit>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
failOnRisky="true"
convertDeprecationsToExceptions="true"
>
<php>
<ini name="error_reporting" value="-1" />
<var name="db_driver" value="pdo_mysql"/>
<var name="db_host" value="127.0.0.1" />
<var name="db_port" value="3306"/>
<var name="db_user" value="root" />
<var name="db_dbname" value="doctrine_tests" />
<!-- necessary change for some CLI/console output test assertions -->
<env name="COLUMNS" value="120"/>
</php>
<testsuites>
<testsuite name="Doctrine DBAL Test Suite">
<directory>../../../tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">../../../lib/Doctrine</directory>
</whitelist>
</filter>
<groups>
<exclude>
<group>performance</group>
<group>locking_functional</group>
</exclude>
</groups>
</phpunit>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
failOnRisky="true"
convertDeprecationsToExceptions="true"
>
<php>
<ini name="error_reporting" value="-1" />
<var name="db_driver" value="pdo_pgsql"/>
<var name="db_host" value="localhost" />
<var name="db_user" value="postgres" />
<var name="db_password" value="postgres" />
<var name="db_dbname" value="doctrine_tests" />
<!-- necessary change for some CLI/console output test assertions -->
<env name="COLUMNS" value="120"/>
</php>
<testsuites>
<testsuite name="Doctrine DBAL Test Suite">
<directory>../../../tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">../../../lib/Doctrine</directory>
</whitelist>
</filter>
<groups>
<exclude>
<group>performance</group>
<group>locking_functional</group>
</exclude>
</groups>
</phpunit>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
failOnRisky="true"
convertDeprecationsToExceptions="true"
>
<php>
<ini name="error_reporting" value="-1" />
<!-- use an in-memory sqlite database -->
<var name="db_driver" value="pdo_sqlite"/>
<var name="db_memory" value="true"/>
<!-- necessary change for some CLI/console output test assertions -->
<env name="COLUMNS" value="120"/>
</php>
<testsuites>
<testsuite name="Doctrine DBAL Test Suite">
<directory>../../../tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">../../../lib/Doctrine</directory>
</whitelist>
</filter>
<groups>
<exclude>
<group>performance</group>
<group>locking_functional</group>
</exclude>
</groups>
</phpunit>

View File

@@ -13,35 +13,47 @@
{"name": "Marco Pivetta", "email": "ocramius@gmail.com"}
],
"config": {
"platform": {
"php": "7.1.3"
"allow-plugins": {
"composer/package-versions-deprecated": true,
"dealerdirect/phpcodesniffer-composer-installer": true
},
"sort-packages": true
},
"require": {
"php": "^7.1",
"ext-pdo": "*",
"doctrine/annotations": "^1.8",
"doctrine/cache": "^1.9.1",
"php": "^7.1 || ^8.0",
"composer-runtime-api": "^2",
"ext-ctype": "*",
"doctrine/cache": "^1.12.1 || ^2.1.1",
"doctrine/collections": "^1.5",
"doctrine/common": "^2.11 || ^3.0",
"doctrine/dbal": "^2.9.3",
"doctrine/common": "^3.0.3",
"doctrine/dbal": "^2.13.1 || ^3.2",
"doctrine/deprecations": "^0.5.3",
"doctrine/event-manager": "^1.1",
"doctrine/inflector": "^1.0",
"doctrine/inflector": "^1.4 || ^2.0",
"doctrine/instantiator": "^1.3",
"doctrine/lexer": "^1.0",
"doctrine/persistence": "^1.3.3 || ^2.0",
"ocramius/package-versions": "^1.2",
"symfony/console": "^3.0|^4.0|^5.0"
"doctrine/persistence": "^2.2",
"psr/cache": "^1 || ^2 || ^3",
"symfony/console": "^3.0 || ^4.0 || ^5.0 || ^6.0",
"symfony/polyfill-php72": "^1.23",
"symfony/polyfill-php80": "^1.15"
},
"require-dev": {
"doctrine/coding-standard": "^5.0",
"phpstan/phpstan": "^0.12.18",
"phpunit/phpunit": "^7.5",
"symfony/yaml": "^3.4|^4.0|^5.0",
"vimeo/psalm": "^3.11"
"doctrine/annotations": "^1.13",
"doctrine/coding-standard": "^9.0",
"phpbench/phpbench": "^0.16.10 || ^1.0",
"phpstan/phpstan": "1.4.6",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.4",
"squizlabs/php_codesniffer": "3.6.2",
"symfony/cache": "^4.4 || ^5.4 || ^6.0",
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0",
"vimeo/psalm": "4.22.0"
},
"conflict": {
"doctrine/annotations": "<1.13 || >= 2.0"
},
"suggest": {
"symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0",
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
},
"autoload": {
@@ -50,16 +62,12 @@
"autoload-dev": {
"psr-4": {
"Doctrine\\Tests\\": "tests/Doctrine/Tests",
"Doctrine\\StaticAnalysis\\": "tests/Doctrine/StaticAnalysis",
"Doctrine\\Performance\\": "tests/Doctrine/Performance"
}
},
"bin": ["bin/doctrine"],
"extra": {
"branch-alias": {
"dev-master": "2.7.x-dev"
}
},
"archive": {
"exclude": ["!vendor", "tests", "*phpunit.xml", ".travis.yml", "build.xml", "build.properties", "composer.phar", "vendor/satooshi", "lib/vendor", "*.swp"]
"exclude": ["!vendor", "tests", "*phpunit.xml", "build.xml", "build.properties", "composer.phar", "vendor/satooshi", "lib/vendor", "*.swp"]
}
}

3618
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
The Doctrine2 documentation is licensed under [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US)
The Doctrine ORM documentation is licensed under [CC BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US)
Creative Commons Legal Code
@@ -359,5 +359,4 @@ Creative Commons Notice
available upon request from time to time. For the avoidance of doubt,
this trademark restriction does not form part of this License.
Creative Commons may be contacted at http://creativecommons.org/.
Creative Commons may be contacted at https://creativecommons.org/.

View File

@@ -7,4 +7,4 @@ rm build -Rf
sphinx-build en build
sphinx-build -b latex en build/pdf
rubber --into build/pdf --pdf build/pdf/Doctrine2ORM.tex
rubber --into build/pdf --pdf build/pdf/Doctrine2ORM.tex

View File

@@ -1,2 +1,2 @@
#!/bin/bash
sudo apt-get update && sudo apt-get install -y python2.7 python-sphinx python-pygments
sudo apt-get update && sudo apt-get install -y python2.7 python-sphinx python-pygments

View File

@@ -0,0 +1,74 @@
Accessing private/protected properties/methods of the same class from different instance
========================================================================================
.. sectionauthor:: Michael Olsavsky (olsavmic)
As explained in the :doc:`restrictions for entity classes in the manual <../reference/architecture>`,
it is dangerous to access private/protected properties of different entity instance of the same class because of lazy loading.
The proxy instance that's injected instead of the real entity may not be initialized yet
and therefore not contain expected data which may result in unexpected behavior.
That's a limitation of current proxy implementation - only public methods automatically initialize proxies.
It is usually preferable to use a public interface to manipulate the object from outside the `$this`
context but it may not be convenient in some cases. The following example shows how to do it safely.
Safely accessing private properties from different instance of the same class
-----------------------------------------------------------------------------
To safely access private property of different instance of the same class, make sure to initialise
the proxy before use manually as follows:
.. code-block:: php
<?php
use Doctrine\Common\Proxy\Proxy;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Entity
{
// ...
/**
* @ORM\ManyToOne(targetEntity="Entity")
* @ORM\JoinColumn(nullable=false)
*/
private self $parent;
/**
* @ORM\Column(type="string", nullable=false)
*/
private string $name;
// ...
public function doSomethingWithParent()
{
// Always initializing the proxy before use
if ($this->parent instanceof Proxy) {
$this->parent->__load();
}
// Accessing the `$this->parent->name` property without loading the proxy first
// may throw error in case the Proxy has not been initialized yet.
$this->parent->name;
}
public function doSomethingWithAnotherInstance(self $instance)
{
// Always initializing the proxy before use
if ($instance instanceof Proxy) {
$instance->__load();
}
// Accessing the `$instance->name` property without loading the proxy first
// may throw error in case the Proxy has not been initialized yet.
$instance->name;
}
// ...
}

View File

@@ -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
@@ -193,10 +193,10 @@ object into a string representation before saving to the database (in the
value from the database (in the ``convertToPHPValue`` method).
The format of the string representation format is called
`Well-known text (WKT) <http://en.wikipedia.org/wiki/Well-known_text>`_.
`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();

View File

@@ -6,7 +6,7 @@ Aggregate Fields
You will often come across the requirement to display aggregate
values of data that can be computed by using the MIN, MAX, COUNT or
SUM SQL functions. For any ORM this is a tricky issue
traditionally. Doctrine 2 offers several ways to get access to
traditionally. Doctrine ORM offers several ways to get access to
these values and this article will describe all of them from
different perspectives.
@@ -22,7 +22,7 @@ into the account can either be of positive or negative money
values. Each account has a credit limit and the account is never
allowed to have a balance below that value.
For simplicity we live in a world were money is composed of
For simplicity we live in a world where money is composed of
integers only. Also we omit the receiver/sender name, stated reason
for transfer and the execution date. These all would have to be
added on the ``Entry`` object.
@@ -32,30 +32,39 @@ Our entities look like:
.. code-block:: php
<?php
namespace Bank\Entities;
use Doctrine\ORM\Mapping as ORM;
/**
* @Entity
* @ORM\Entity
*/
class Account
{
/** @Id @GeneratedValue @Column(type="integer") */
private $id;
/** @Column(type="string", unique=true) */
private $no;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private ?int $id;
/**
* @OneToMany(targetEntity="Entry", mappedBy="account", cascade={"persist"})
* @ORM\Column(type="string", unique=true)
*/
private $entries;
private string $no;
/**
* @Column(type="integer")
* @ORM\OneToMany(targetEntity="Entry", mappedBy="account", cascade={"persist"})
*/
private $maxCredit = 0;
private array $entries;
public function __construct($no, $maxCredit = 0)
/**
* @ORM\Column(type="integer")
*/
private int $maxCredit = 0;
public function __construct(string $no, int $maxCredit = 0)
{
$this->no = $no;
$this->maxCredit = $maxCredit;
@@ -64,31 +73,35 @@ Our entities look like:
}
/**
* @Entity
* @ORM\Entity
*/
class Entry
{
/** @Id @GeneratedValue @Column(type="integer") */
private $id;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private ?int $id;
/**
* @ManyToOne(targetEntity="Account", inversedBy="entries")
* @ORM\ManyToOne(targetEntity="Account", inversedBy="entries")
*/
private $account;
private Account $account;
/**
* @Column(type="integer")
* @ORM\Column(type="integer")
*/
private $amount;
private int $amount;
public function __construct($account, $amount)
public function __construct(Account $account, int $amount)
{
$this->account = $account;
$this->amount = $amount;
// more stuff here, from/to whom, stated reason, execution date and such
}
public function getAmount()
public function getAmount(): Amount
{
return $this->amount;
}
@@ -146,12 +159,14 @@ collection, which means we can compute this value at runtime:
class Account
{
// .. previous code
public function getBalance()
public function getBalance(): int
{
$balance = 0;
foreach ($this->entries as $entry) {
$balance += $entry->getAmount();
}
return $balance;
}
}
@@ -175,13 +190,12 @@ relation with this method:
<?php
class Account
{
public function addEntry($amount)
public function addEntry(int $amount): void
{
$this->assertAcceptEntryAllowed($amount);
$e = new Entry($this, $amount);
$this->entries[] = $e;
return $e;
}
}
@@ -190,7 +204,10 @@ Now look at the following test-code for our entities:
.. code-block:: php
<?php
class AccountTest extends \PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;
class AccountTest extends TestCase
{
public function testAddEntry()
{
@@ -208,7 +225,7 @@ Now look at the following test-code for our entities:
{
$account = new Account("123456", $maxCredit = 200);
$this->setExpectedException("Exception");
$this->expectException(Exception::class);
$account->addEntry(-1000);
}
}
@@ -219,9 +236,12 @@ To enforce our rule we can now implement the assertion in
.. code-block:: php
<?php
class Account
{
private function assertAcceptEntryAllowed($amount)
// .. previous code
private function assertAcceptEntryAllowed(int $amount): void
{
$futureBalance = $this->getBalance() + $amount;
$allowedMinimalBalance = ($this->maxCredit * -1);
@@ -266,23 +286,22 @@ entries collection) we want to add an aggregate field called
class Account
{
/**
* @Column(type="integer")
* @ORM\Column(type="integer")
*/
private $balance = 0;
private int $balance = 0;
public function getBalance()
public function getBalance(): int
{
return $this->balance;
}
public function addEntry($amount)
public function addEntry(int $amount): void
{
$this->assertAcceptEntryAllowed($amount);
$e = new Entry($this, $amount);
$this->entries[] = $e;
$this->balance += $amount;
return $e;
}
}
@@ -306,12 +325,15 @@ potentially lead to inconsistent state. See this example:
.. code-block:: php
<?php
use Bank\Entities\Account;
// The Account $accId has a balance of 0 and a max credit limit of 200:
// request 1 account
$account1 = $em->find('Bank\Entities\Account', $accId);
$account1 = $em->find(Account::class, $accId);
// request 2 account
$account2 = $em->find('Bank\Entities\Account', $accId);
$account2 = $em->find(Account::class, $accId);
$account1->addEntry(-200);
$account2->addEntry(-200);
@@ -332,10 +354,14 @@ Optimistic locking is as easy as adding a version column:
.. code-block:: php
<?php
class Account
{
/** @Column(type="integer") @Version */
private $version;
/**
* @ORM\Column(type="integer")
* @ORM\Version
*/
private int $version;
}
The previous example would then throw an exception in the face of
@@ -349,9 +375,11 @@ the database using a FOR UPDATE.
.. code-block:: php
<?php
use Bank\Entities\Account;
use Doctrine\DBAL\LockMode;
$account = $em->find('Bank\Entities\Account', $accId, LockMode::PESSIMISTIC_READ);
$account = $em->find(Account::class, $accId, LockMode::PESSIMISTIC_READ);
Keeping Updates and Deletes in Sync
-----------------------------------
@@ -372,5 +400,3 @@ field that offers serious performance benefits over iterating all
the related objects that make up an aggregate value. Finally I
showed how you can ensure that your aggregate fields do not get out
of sync due to race-conditions and concurrent access.

View File

@@ -3,45 +3,45 @@ Persisting the Decorator Pattern
.. sectionauthor:: Chris Woodford <chris.woodford@gmail.com>
This recipe will show you a simple example of how you can use
Doctrine 2 to persist an implementation of the
`Decorator Pattern <http://en.wikipedia.org/wiki/Decorator_pattern>`_
This recipe will show you a simple example of how you can use
Doctrine ORM to persist an implementation of the
`Decorator Pattern <https://en.wikipedia.org/wiki/Decorator_pattern>`_
Component
---------
The ``Component`` class needs to be persisted, so it's going to
be an ``Entity``. As the top of the inheritance hierarchy, it's going
to have to define the persistent inheritance. For this example, we
will use Single Table Inheritance, but Class Table Inheritance
would work as well. In the discriminator map, we will define two
concrete subclasses, ``ConcreteComponent`` and ``ConcreteDecorator``.
The ``Component`` class needs to be persisted, so it's going to
be an ``Entity``. As the top of the inheritance hierarchy, it's going
to have to define the persistent inheritance. For this example, we
will use Single Table Inheritance, but Class Table Inheritance
would work as well. In the discriminator map, we will define two
concrete subclasses, ``ConcreteComponent`` and ``ConcreteDecorator``.
.. code-block:: php
<?php
namespace Test;
/**
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"cc" = "Test\Component\ConcreteComponent",
* @DiscriminatorMap({"cc" = "Test\Component\ConcreteComponent",
"cd" = "Test\Decorator\ConcreteDecorator"})
*/
abstract class Component
{
/**
* @Id @Column(type="integer")
* @GeneratedValue(strategy="AUTO")
*/
protected $id;
/** @Column(type="string", nullable=true) */
protected $name;
/**
* Get id
* @return integer $id
@@ -50,7 +50,7 @@ concrete subclasses, ``ConcreteComponent`` and ``ConcreteDecorator``.
{
return $this->id;
}
/**
* Set name
* @param string $name
@@ -59,7 +59,7 @@ concrete subclasses, ``ConcreteComponent`` and ``ConcreteDecorator``.
{
$this->name = $name;
}
/**
* Get name
* @return string $name
@@ -68,33 +68,33 @@ concrete subclasses, ``ConcreteComponent`` and ``ConcreteDecorator``.
{
return $this->name;
}
}
ConcreteComponent
-----------------
The ``ConcreteComponent`` class is pretty simple and doesn't do much
more than extend the abstract ``Component`` class (only for the
The ``ConcreteComponent`` class is pretty simple and doesn't do much
more than extend the abstract ``Component`` class (only for the
purpose of keeping this example simple).
.. code-block:: php
<?php
namespace Test\Component;
use Test\Component;
/** @Entity */
class ConcreteComponent extends Component
{}
Decorator
---------
The ``Decorator`` class doesn't need to be persisted, but it does
need to define an association with a persisted ``Entity``. We can
The ``Decorator`` class doesn't need to be persisted, but it does
need to define an association with a persisted ``Entity``. We can
use a ``MappedSuperclass`` for this.
.. code-block:: php
@@ -102,17 +102,17 @@ use a ``MappedSuperclass`` for this.
<?php
namespace Test;
/** @MappedSuperclass */
abstract class Decorator extends Component
{
/**
* @OneToOne(targetEntity="Test\Component", cascade={"all"})
* @JoinColumn(name="decorates", referencedColumnName="id")
*/
protected $decorates;
/**
* initialize the decorator
* @param Component $c
@@ -121,7 +121,7 @@ use a ``MappedSuperclass`` for this.
{
$this->setDecorates($c);
}
/**
* (non-PHPdoc)
* @see Test.Component::getName()
@@ -130,7 +130,7 @@ use a ``MappedSuperclass`` for this.
{
return 'Decorated ' . $this->getDecorates()->getName();
}
/**
* the component being decorated
* @return Component
@@ -139,7 +139,7 @@ use a ``MappedSuperclass`` for this.
{
return $this->decorates;
}
/**
* sets the component being decorated
* @param Component $c
@@ -148,52 +148,52 @@ use a ``MappedSuperclass`` for this.
{
$this->decorates = $c;
}
}
All operations on the ``Decorator`` (i.e. persist, remove, etc) will
cascade from the ``Decorator`` to the ``Component``. This means that
when we persist a ``Decorator``, Doctrine will take care of
persisting the chain of decorated objects for us. A ``Decorator`` can
be treated exactly as a ``Component`` when it comes time to
All operations on the ``Decorator`` (i.e. persist, remove, etc) will
cascade from the ``Decorator`` to the ``Component``. This means that
when we persist a ``Decorator``, Doctrine will take care of
persisting the chain of decorated objects for us. A ``Decorator`` can
be treated exactly as a ``Component`` when it comes time to
persisting it.
The ``Decorator's`` constructor accepts an instance of a
``Component``, as defined by the ``Decorator`` pattern. The
setDecorates/getDecorates methods have been defined as protected to
hide the fact that a ``Decorator`` is decorating a ``Component`` and
keeps the ``Component`` interface and the ``Decorator`` interface
The ``Decorator's`` constructor accepts an instance of a
``Component``, as defined by the ``Decorator`` pattern. The
setDecorates/getDecorates methods have been defined as protected to
hide the fact that a ``Decorator`` is decorating a ``Component`` and
keeps the ``Component`` interface and the ``Decorator`` interface
identical.
To illustrate the intended result of the ``Decorator`` pattern, the
getName() method has been overridden to append a string to the
To illustrate the intended result of the ``Decorator`` pattern, the
getName() method has been overridden to append a string to the
``Component's`` getName() method.
ConcreteDecorator
-----------------
The final class required to complete a simple implementation of the
Decorator pattern is the ``ConcreteDecorator``. In order to further
illustrate how the ``Decorator`` can alter data as it moves through
the chain of decoration, a new field, "special", has been added to
this class. The getName() has been overridden and appends the value
of the getSpecial() method to its return value.
The final class required to complete a simple implementation of the
Decorator pattern is the ``ConcreteDecorator``. In order to further
illustrate how the ``Decorator`` can alter data as it moves through
the chain of decoration, a new field, "special", has been added to
this class. The getName() has been overridden and appends the value
of the getSpecial() method to its return value.
.. code-block:: php
<?php
namespace Test\Decorator;
use Test\Decorator;
/** @Entity */
class ConcreteDecorator extends Decorator
{
/** @Column(type="string", nullable=true) */
protected $special;
/**
* Set special
* @param string $special
@@ -202,7 +202,7 @@ of the getSpecial() method to its return value.
{
$this->special = $special;
}
/**
* Get special
* @return string $special
@@ -211,7 +211,7 @@ of the getSpecial() method to its return value.
{
return $this->special;
}
/**
* (non-PHPdoc)
* @see Test.Component::getName()
@@ -219,55 +219,55 @@ of the getSpecial() method to its return value.
public function getName()
{
return '[' . $this->getSpecial()
. '] ' . parent::getName();
. '] ' . parent::getName();
}
}
Examples
--------
Here is an example of how to persist and retrieve your decorated
Here is an example of how to persist and retrieve your decorated
objects
.. code-block:: php
<?php
use Test\Component\ConcreteComponent,
Test\Decorator\ConcreteDecorator;
// assumes Doctrine 2 is configured and an instance of
// assumes Doctrine ORM is configured and an instance of
// an EntityManager is available as $em
// create a new concrete component
$c = new ConcreteComponent();
$c->setName('Test Component 1');
$em->persist($c); // assigned unique ID = 1
// create a new concrete decorator
$c = new ConcreteComponent();
$c->setName('Test Component 2');
$d = new ConcreteDecorator($c);
$d->setSpecial('Really');
$em->persist($d);
$em->persist($d);
// assigns c as unique ID = 2, and d as unique ID = 3
$em->flush();
$c = $em->find('Test\Component', 1);
$d = $em->find('Test\Component', 3);
echo get_class($c);
// prints: Test\Component\ConcreteComponent
echo $c->getName();
// prints: Test Component 1
echo get_class($d)
// prints: Test Component 1
echo get_class($d)
// prints: Test\Component\ConcreteDecorator
echo $d->getName();
// prints: [Really] Decorated Test Component 2

View File

@@ -1,4 +1,4 @@
Extending DQL in Doctrine 2: Custom AST Walkers
Extending DQL in Doctrine ORM: Custom AST Walkers
===============================================
.. sectionauthor:: Benjamin Eberlei <kontakt@beberlei.de>
@@ -12,9 +12,9 @@ the Doctrine ORM.
In Doctrine 1 the DQL language was not implemented using a real
parser. This made modifications of the DQL by the user impossible.
Doctrine 2 in contrast has a real parser for the DQL language,
Doctrine ORM in contrast has a real parser for the DQL language,
which transforms the DQL statement into an
`Abstract Syntax Tree <http://en.wikipedia.org/wiki/Abstract_syntax_tree>`_
`Abstract Syntax Tree <https://en.wikipedia.org/wiki/Abstract_syntax_tree>`_
and generates the appropriate SQL statement for it. Since this
process is deterministic Doctrine heavily caches the SQL that is
generated from any given DQL query, which reduces the performance
@@ -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
@@ -167,7 +167,7 @@ can be set via ``Query::setHint($name, $value)`` as shown in the
previous example with the ``HINT_CUSTOM_TREE_WALKERS`` query hint.
We will implement a custom Output Walker that allows to specify the
SQL\_NO\_CACHE query hint.
``SQL_NO_CACHE`` query hint.
.. code-block:: php
@@ -180,7 +180,7 @@ SQL\_NO\_CACHE query hint.
Our ``MysqlWalker`` will extend the default ``SqlWalker``. We will
modify the generation of the SELECT clause, adding the
SQL\_NO\_CACHE on those queries that need it:
``SQL_NO_CACHE`` on those queries that need it:
.. code-block:: php
@@ -196,7 +196,7 @@ SQL\_NO\_CACHE on those queries that need it:
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 @@ SQL\_NO\_CACHE on those queries that need it:
$sql = str_replace('SELECT', 'SELECT SQL_NO_CACHE', $sql);
}
}
return $sql;
}
}

View File

@@ -10,7 +10,7 @@ change it during the life of your project. This decision for a
specific vendor potentially allows you to make use of powerful SQL
features that are unique to the vendor.
It is worth to mention that Doctrine 2 also allows you to handwrite
It is worth to mention that Doctrine ORM also allows you to handwrite
your SQL instead of extending the DQL parser. Extending DQL is sort of an
advanced extension point. You can map arbitrary SQL to your objects
and gain access to vendor specific functionalities using the
@@ -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(' .
@@ -132,7 +132,7 @@ dql statement.
The ``ArithmeticPrimary`` method call is the most common
denominator of valid EBNF tokens taken from the
`DQL EBNF grammar <http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#ebnf>`_
`DQL EBNF grammar <https://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#ebnf>`_
that matches our requirements for valid input into the DateDiff Dql
function. Picking the right tokens for your methods is a tricky
business, but the EBNF grammar is pretty helpful finding it, as is
@@ -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(' .
@@ -240,12 +240,12 @@ functionalities in DQL, we would be excited to see user extensions
that add vendor specific function packages, for example more math
functions, XML + GIS Support, Hashing functions and so on.
For 2.0 we will come with the current set of functions, however for
For ORM we will come with the current set of functions, however for
a future version we will re-evaluate if we can abstract even more
vendor sql functions and extend the DQL languages scope.
Code for this Extension to DQL and other Doctrine Extensions can be
found
`in the GitHub DoctrineExtensions repository <http://github.com/beberlei/DoctrineExtensions>`_.
`in the GitHub DoctrineExtensions repository <https://github.com/beberlei/DoctrineExtensions>`_.

View File

@@ -3,42 +3,69 @@ Entities in the Session
There are several use-cases to save entities in the session, for example:
1. User object
1. User data
2. Multi-step forms
To achieve this with Doctrine you have to pay attention to some details to get
this working.
Merging entity into an EntityManager
------------------------------------
Updating an entity
------------------
In Doctrine an entity objects has to be "managed" by an EntityManager to be
updateable. Entities saved into the session are not managed in the next request
anymore. This means that you have to register these entities with an
EntityManager again if you want to change them or use them as part of
references between other entities. You can achieve this by calling
``EntityManager#merge()``.
updatable. Entities saved into the session are not managed in the next request
anymore. This means that you have to update the entities with the stored session
data after you fetch the entities from the EntityManager again.
For a representative User object the code to get turn an instance from
the session into a managed Doctrine object looks like this:
For a representative User object the code to get data from the session into a
managed Doctrine object can look like these examples:
Working with scalars
~~~~~~~~~~~~~~~~~~~~
In simpler applications there is no need to work with objects in sessions and you can use
separate session elements.
.. code-block:: php
<?php
require_once 'bootstrap.php';
$em = GetEntityManager(); // creates an EntityManager
session_start();
if (isset($_SESSION['user']) && $_SESSION['user'] instanceof User) {
$user = $_SESSION['user'];
$user = $em->merge($user);
if (isset($_SESSION['userId']) && is_int($_SESSION['userId'])) {
$userId = $_SESSION['userId'];
$em = GetEntityManager(); // creates an EntityManager
$user = $em->find(User::class, $userId);
$user->setValue($_SESSION['storedValue']);
$em->flush();
}
.. note::
Working with custom data transfer objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A frequent mistake is not to get the merged user object from the return
value of ``EntityManager#merge()``. The entity object passed to merge is
not necessarily the same object that is returned from the method.
If objects are needed, we discourage the storage of entity objects in the session. It's
preferable to use a `DTO (data transfer object) <https://en.wikipedia.org/wiki/Data_transfer_object>`_
instead and merge the DTO data later with the entity.
.. code-block:: php
<?php
require_once 'bootstrap.php';
session_start();
if (isset($_SESSION['user']) && $_SESSION['user'] instanceof UserDto) {
$userDto = $_SESSION['user'];
$em = GetEntityManager(); // creates an EntityManager
$userEntity = $em->find(User::class, $userDto->getId());
$userEntity->populateFromDto($userDto);
$em->flush();
}
Serializing entity into the session
-----------------------------------
@@ -47,22 +74,20 @@ Entities that are serialized into the session normally contain references to
other entities as well. Think of the user entity has a reference to their
articles, groups, photos or many other different entities. If you serialize
this object into the session then you don't want to serialize the related
entities as well. This is why you should call ``EntityManager#detach()`` on this
object or implement the __sleep() magic method on your entity.
entities as well. This is why you shouldn't serialize an entity and use
only the needed values of it. This can happen with the help of a DTO.
.. code-block:: php
<?php
require_once 'bootstrap.php';
$em = GetEntityManager(); // creates an EntityManager
$user = $em->find("User", 1);
$em->detach($user);
$_SESSION['user'] = $user;
$userDto = new UserDto($user->getId(), $user->getFirstName(), $user->getLastName());
// or "UserDto::createFrom($user);", but don't store an entity in a property. Only its values without relations.
.. note::
$_SESSION['user'] = $userDto;
When you called detach on your objects they get "unmanaged" with that
entity manager. This means you cannot use them as part of write operations
during ``EntityManager#flush()`` anymore in this request.

View File

@@ -6,7 +6,7 @@ Implementing ArrayAccess for Domain Objects
This recipe will show you how to implement ArrayAccess for your
domain objects in order to allow more uniform access, for example
in templates. In these examples we will implement ArrayAccess on a
`Layer Supertype <http://martinfowler.com/eaaCatalog/layerSupertype.html>`_
`Layer Supertype <https://martinfowler.com/eaaCatalog/layerSupertype.html>`_
for all our domain objects.
Option 1

View File

@@ -7,9 +7,14 @@ The NOTIFY change-tracking policy is the most effective
change-tracking policy provided by Doctrine but it requires some
boilerplate code. This recipe will show you how this boilerplate
code should look like. We will implement it on a
`Layer Supertype <http://martinfowler.com/eaaCatalog/layerSupertype.html>`_
`Layer Supertype <https://martinfowler.com/eaaCatalog/layerSupertype.html>`_
for all our domain objects.
.. note::
The notify change tracking policy is deprecated and will be removed in ORM 3.0.
(`Details <https://github.com/doctrine/orm/issues/8383>`_)
Implementing NotifyPropertyChanged
----------------------------------

View File

@@ -4,7 +4,7 @@ Implementing Wakeup or Clone
.. sectionauthor:: Roman Borschel (roman@code-factory.org)
As explained in the
`restrictions for entity classes in the manual <http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/architecture.html#entities>`_,
`restrictions for entity classes in the manual <https://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/architecture.html#entities>`_,
it is usually not allowed for an entity to implement ``__wakeup``
or ``__clone``, because Doctrine makes special use of them.
However, it is quite easy to make use of these methods in a safe
@@ -23,7 +23,7 @@ implementation code in an identity check as follows:
class MyEntity
{
private $id; // This is the identifier of the entity.
//...
// ...
public function __wakeup()
{
@@ -34,7 +34,7 @@ implementation code in an identity check as follows:
// otherwise do nothing, do NOT throw an exception!
}
//...
// ...
}
Safely implementing __clone
@@ -48,7 +48,7 @@ Safely implementing ``__clone`` is pretty much the same:
class MyEntity
{
private $id; // This is the identifier of the entity.
//...
// ...
public function __clone()
{
@@ -59,7 +59,7 @@ Safely implementing ``__clone`` is pretty much the same:
// otherwise do nothing, do NOT throw an exception!
}
//...
// ...
}
Summary

View File

@@ -1,12 +1,12 @@
Mysql Enums
===========
The type system of Doctrine 2 consists of flyweights, which means there is only
The type system of Doctrine ORM consists of flyweights, which means there is only
one instance of any given type. Additionally types do not contain state. Both
assumptions make it rather complicated to work with the Enum Type of MySQL that
is used quite a lot by developers.
When using Enums with a non-tweaked Doctrine 2 application you will get
When using Enums with a non-tweaked Doctrine ORM application you will get
errors from the Schema-Tool commands due to the unknown database type "enum".
By default Doctrine does not map the MySQL enum type to a Doctrine type.
This is because Enums contain state (their allowed values) and Doctrine

View File

@@ -1,13 +1,11 @@
Keeping your Modules independent
=================================
.. versionadded:: 2.2
One of the goals of using modules is to create discrete units of functionality
that do not have many (if any) dependencies, allowing you to use that
functionality in other applications without including unnecessary items.
Doctrine 2.2 includes a new utility called the ``ResolveTargetEntityListener``,
Doctrine ORM includes a new utility called the ``ResolveTargetEntityListener``,
that functions by intercepting certain calls inside Doctrine and rewrite
targetEntity parameters in your metadata mapping at runtime. It means that
in your bundle you are able to use an interface or abstract class in your

View File

@@ -30,7 +30,7 @@ highly uncomfortable because of the following:
every panel-type? This wouldn't be flexible. You might be tempted
to add an AbstractPanelEntity and an AbstractBlockEntity that use
class inheritance. Your page could then only confer to the
AbstractPanelType and Doctrine 2 would do the rest for you, i.e.
AbstractPanelType and Doctrine ORM would do the rest for you, i.e.
load the right entities. But - you'll for sure have lots of panels
and blocks, and even worse, you'd have to edit the discriminator
map *manually* every time you or another developer implements a new
@@ -152,7 +152,7 @@ As you can see, we have a method "setBlockEntity" which ties a potential strateg
/**
* This var contains the classname of the strategy
* that is used for this blockitem. (This string (!) value will be persisted by Doctrine 2)
* that is used for this blockitem. (This string (!) value will be persisted by Doctrine ORM)
*
* This is a doctrine field, so make sure that you use an @column annotation or setup your
* yaml or xml files correctly
@@ -161,7 +161,7 @@ As you can see, we have a method "setBlockEntity" which ties a potential strateg
protected $strategyClassName;
/**
* This var contains an instance of $this->blockStrategy. Will not be persisted by Doctrine 2.
* This var contains an instance of $this->blockStrategy. Will not be persisted by Doctrine ORM.
*
* @var BlockStrategyInterface
*/
@@ -199,7 +199,7 @@ As you can see, we have a method "setBlockEntity" which ties a potential strateg
$strategy->setBlockEntity($this);
}
Now, the important point is that $strategyClassName is a Doctrine 2
Now, the important point is that $strategyClassName is a Doctrine ORM
field, i.e. Doctrine will persist this value. This is only the
class name of your strategy and not an instance!

View File

@@ -3,7 +3,7 @@ Validation of Entities
.. sectionauthor:: Benjamin Eberlei <kontakt@beberlei.de>
Doctrine 2 does not ship with any internal validators, the reason
Doctrine ORM does not ship with any internal validators, the reason
being that we think all the frameworks out there already ship with
quite decent ones that can be integrated into your Domain easily.
What we offer are hooks to execute any kind of validation.

View File

@@ -3,7 +3,7 @@ Working with DateTime Instances
There are many nitty gritty details when working with PHPs DateTime instances. You have to know their inner
workings pretty well not to make mistakes with date handling. This cookbook entry holds several
interesting pieces of information on how to work with PHP DateTime instances in Doctrine 2.
interesting pieces of information on how to work with PHP DateTime instances in ORM.
DateTime changes are detected by Reference
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -58,16 +58,16 @@ Handling different Timezones with the DateTime Type
If you first come across the requirement to save different timezones you may be still optimistic about how
to manage this mess,
however let me crush your expectations fast. There is not a single database out there (supported by Doctrine 2)
however let me crush your expectations fast. There is not a single database out there (supported by Doctrine ORM)
that supports timezones correctly. Correctly here means that you can cover all the use-cases that
can come up with timezones. If you don't believe me you should read up on `Storing DateTime
in Databases <http://derickrethans.nl/storing-date-time-in-database.html>`_.
in Databases <https://derickrethans.nl/storing-date-time-in-database.html>`_.
The problem is simple. Not a single database vendor saves the timezone, only the differences to UTC.
However with frequent daylight saving and political timezone changes you can have a UTC offset that moves
in different offset directions depending on the real location.
The solution for this dilemma is simple. Don't use timezones with DateTime and Doctrine 2. However there is a workaround
The solution for this dilemma is simple. Don't use timezones with DateTime and Doctrine ORM. However there is a workaround
that even allows correct date-time handling with timezones:
1. Always convert any DateTime instance to UTC.

View File

@@ -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
@@ -41,6 +40,7 @@ Mapping Objects onto a Database
* **Drivers**:
:doc:`Docblock Annotations <reference/annotations-reference>` |
:doc:`Attributes <reference/attributes-reference>` |
:doc:`XML <reference/xml-mapping>` |
:doc:`YAML <reference/yaml-mapping>` |
:doc:`PHP <reference/php-mapping>`

View File

@@ -1,113 +1,113 @@
@ECHO OFF
REM Command file for Sphinx documentation
set SPHINXBUILD=sphinx-build
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Doctrine2ORM.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Doctrine2ORM.ghc
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end
@ECHO OFF
REM Command file for Sphinx documentation
set SPHINXBUILD=sphinx-build
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Doctrine2ORM.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Doctrine2ORM.ghc
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end

View File

@@ -9,51 +9,59 @@ steps of configuration.
.. code-block:: php
<?php
use Doctrine\ORM\EntityManager,
Doctrine\ORM\Configuration;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
// ...
if ($applicationMode == "development") {
$cache = new \Doctrine\Common\Cache\ArrayCache;
$queryCache = new ArrayAdapter();
$metadataCache = new ArrayAdapter();
} else {
$cache = new \Doctrine\Common\Cache\ApcCache;
$queryCache = new PhpFilesAdapter('doctrine_queries');
$metadataCache = new PhpFilesAdapter('doctrine_metadata');
}
$config = new Configuration;
$config->setMetadataCacheImpl($cache);
$config->setMetadataCache($metadataCache);
$driverImpl = $config->newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities');
$config->setMetadataDriverImpl($driverImpl);
$config->setQueryCacheImpl($cache);
$config->setQueryCache($queryCache);
$config->setProxyDir('/path/to/myproject/lib/MyProject/Proxies');
$config->setProxyNamespace('MyProject\Proxies');
if ($applicationMode == "development") {
$config->setAutoGenerateProxyClasses(true);
} else {
$config->setAutoGenerateProxyClasses(false);
}
$connectionOptions = array(
'driver' => 'pdo_sqlite',
'path' => 'database.sqlite'
);
$em = EntityManager::create($connectionOptions, $config);
Doctrine and Caching
--------------------
Doctrine is optimized for working with caches. The main parts in Doctrine
that are optimized for caching are the metadata mapping information with
the metadata cache and the DQL to SQL conversions with the query cache.
These 2 caches require only an absolute minimum of memory yet they heavily
improve the runtime performance of Doctrine.
Doctrine does not bundle its own cache implementation anymore. Instead,
the PSR-6 standard interfaces are used to access the cache. In the examples
in this documentation, Symfony Cache is used as a reference implementation.
.. note::
Do not use Doctrine without a metadata and query cache!
Doctrine is optimized for working with caches. The main
parts in Doctrine that are optimized for caching are the metadata
mapping information with the metadata cache and the DQL to SQL
conversions with the query cache. These 2 caches require only an
absolute minimum of memory yet they heavily improve the runtime
performance of Doctrine. The recommended cache driver to use with
Doctrine is `APC <http://www.php.net/apc>`_. APC provides you with
an opcode-cache (which is highly recommended anyway) and a very
fast in-memory cache storage that you can use for the metadata and
query caches as seen in the previous code snippet.
Configuration Options
---------------------
@@ -101,10 +109,11 @@ Gets or sets the metadata driver implementation that is used by
Doctrine to acquire the object-relational metadata for your
classes.
There are currently 4 available implementations:
There are currently 5 available implementations:
- ``Doctrine\ORM\Mapping\Driver\AnnotationDriver``
- ``Doctrine\ORM\Mapping\Driver\AttributeDriver``
- ``Doctrine\ORM\Mapping\Driver\XmlDriver``
- ``Doctrine\ORM\Mapping\Driver\YamlDriver``
- ``Doctrine\ORM\Mapping\Driver\DriverChain``
@@ -136,30 +145,21 @@ Metadata Cache (***RECOMMENDED***)
.. code-block:: php
<?php
$config->setMetadataCacheImpl($cache);
$config->getMetadataCacheImpl();
$config->setMetadataCache($cache);
$config->getMetadataCache();
Gets or sets the cache implementation to use for caching metadata
Gets or sets the cache adapter to use for caching metadata
information, that is, all the information you supply via
annotations, xml or yaml, so that they do not need to be parsed and
loaded from scratch on every single request which is a waste of
resources. The cache implementation must implement the
``Doctrine\Common\Cache\Cache`` interface.
resources. The cache implementation must implement the PSR-6
``Psr\Cache\CacheItemPoolInterface`` interface.
Usage of a metadata cache is highly recommended.
The recommended implementations for production are:
- ``Doctrine\Common\Cache\ApcCache``
- ``Doctrine\Common\Cache\ApcuCache``
- ``Doctrine\Common\Cache\MemcacheCache``
- ``Doctrine\Common\Cache\XcacheCache``
- ``Doctrine\Common\Cache\RedisCache``
For development you should use the
``Doctrine\Common\Cache\ArrayCache`` which only caches data on a
per-request basis.
For development you should use an array cache like
``Symfony\Component\Cache\Adapter\ArrayAdapter``
which only caches data on a per-request basis.
Query Cache (***RECOMMENDED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -167,8 +167,8 @@ Query Cache (***RECOMMENDED***)
.. code-block:: php
<?php
$config->setQueryCacheImpl($cache);
$config->getQueryCacheImpl();
$config->setQueryCache($cache);
$config->getQueryCache();
Gets or sets the cache implementation to use for caching DQL
queries, that is, the result of a DQL parsing process that includes
@@ -180,18 +180,9 @@ minimal memory usage in your cache).
Usage of a query cache is highly recommended.
The recommended implementations for production are:
- ``Doctrine\Common\Cache\ApcCache``
- ``Doctrine\Common\Cache\ApcuCache``
- ``Doctrine\Common\Cache\MemcacheCache``
- ``Doctrine\Common\Cache\XcacheCache``
- ``Doctrine\Common\Cache\RedisCache``
For development you should use the
``Doctrine\Common\Cache\ArrayCache`` which only caches data on a
per-request basis.
For development you should use an array cache like
``Symfony\Component\Cache\Adapter\ArrayAdapter``
which only caches data on a per-request basis.
SQL Logger (***Optional***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -204,10 +195,7 @@ SQL Logger (***Optional***)
Gets or sets the logger to use for logging all SQL statements
executed by Doctrine. The logger class must implement the
``Doctrine\DBAL\Logging\SQLLogger`` interface. A simple default
implementation that logs to the standard output using ``echo`` and
``var_dump`` can be found at
``Doctrine\DBAL\Logging\EchoSQLLogger``.
deprecated ``Doctrine\DBAL\Logging\SQLLogger`` interface.
Auto-generating Proxy Classes (***OPTIONAL***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -259,7 +247,7 @@ In a production environment, it is highly recommended to use
AUTOGENERATE_NEVER to allow for optimal performances. The other
options are interesting in development environment.
Before v2.4, ``setAutoGenerateProxyClasses`` would accept a boolean
``setAutoGenerateProxyClasses`` can accept a boolean
value. This is still possible, ``FALSE`` being equivalent to
AUTOGENERATE_NEVER and ``TRUE`` to AUTOGENERATE_ALWAYS.
@@ -268,10 +256,10 @@ Development vs Production Configuration
You should code your Doctrine2 bootstrapping with two different
runtime models in mind. There are some serious benefits of using
APC or Memcache in production. In development however this will
APCu or Memcache in production. In development however this will
frequently give you fatal errors, when you change your entities and
the cache still keeps the outdated metadata. That is why we
recommend the ``ArrayCache`` for development.
recommend an array cache for development.
Furthermore you should have the Auto-generating Proxy Classes
option to true in development and to false in production. If this
@@ -299,7 +287,7 @@ Proxy Objects
A proxy object is an object that is put in place or used instead of
the "real" object. A proxy object can add behavior to the object
being proxied without that object being aware of it. In Doctrine 2,
being proxied without that object being aware of it. In ORM,
proxy objects are used to realize several features but mainly for
transparent lazy-loading.
@@ -309,7 +297,7 @@ of the objects. This is an essential property as without it there
would always be fragile partial objects at the outer edges of your
object graph.
Doctrine 2 implements a variant of the proxy pattern where it
Doctrine ORM implements a variant of the proxy pattern where it
generates classes that extend your entity classes and adds
lazy-loading capabilities to them. Doctrine can then give you an
instance of such a proxy class whenever you request an object of
@@ -411,7 +399,7 @@ be found.
Multiple Metadata Sources
-------------------------
When using different components using Doctrine 2 you may end up
When using different components using Doctrine ORM you may end up
with them using two different metadata drivers, for example XML and
YAML. You can use the DriverChain Metadata implementations to
aggregate these drivers based on namespaces:
@@ -449,6 +437,19 @@ That will be available for all entities without a custom repository class.
The default value is ``Doctrine\ORM\EntityRepository``.
Any repository class must be a subclass of EntityRepository otherwise you got an ORMException
Ignoring entities (***OPTIONAL***)
-----------------------------------
Specifies the Entity FQCNs to ignore.
SchemaTool will then skip these (e.g. when comparing schemas).
.. code-block:: php
<?php
$config->setSchemaIgnoreClasses([$fqcn]);
$config->getSchemaIgnoreClasses();
Setting up the Console
----------------------

View File

@@ -1,33 +1,41 @@
Annotations Reference
=====================
.. note::
To be able to use annotations, you will have to install an extra
package called ``doctrine/annotations``.
You've probably used docblock annotations in some form already,
most likely to provide documentation metadata for a tool like
``PHPDocumentor`` (@author, @link, ...). Docblock annotations are a
tool to embed metadata inside the documentation section which can
then be processed by some tool. Doctrine 2 generalizes the concept
then be processed by some tool. Doctrine ORM generalizes the concept
of docblock annotations so that they can be used for any kind of
metadata and so that it is easy to define new docblock annotations.
In order to allow more involved annotation values and to reduce the
chances of clashes with other docblock annotations, the Doctrine 2
chances of clashes with other docblock annotations, the Doctrine ORM
docblock annotations feature an alternative syntax that is heavily
inspired by the Annotation syntax introduced in Java 5.
The implementation of these enhanced docblock annotations is
located in the ``Doctrine\Common\Annotations`` namespace and
therefore part of the Common package. Doctrine 2 docblock
annotations support namespaces and nested annotations among other
things. The Doctrine 2 ORM defines its own set of docblock
annotations for supplying object-relational mapping metadata.
The implementation of these enhanced docblock annotations is located in
the ``doctrine/annotations`` package, but in the
``Doctrine\Common\Annotations`` namespace for backwards compatibility
reasons. Note that ``doctrine/annotations`` is not required by Doctrine
ORM, and you will need to require that package if you want to use
annotations. Doctrine ORM docblock annotations support namespaces and
nested annotations among other things. The Doctrine ORM defines its
own set of docblock annotations for supplying object-relational mapping
metadata.
.. note::
If you're not comfortable with the concept of docblock
annotations, don't worry, as mentioned earlier Doctrine 2 provides
annotations, don't worry, as mentioned earlier Doctrine ORM provides
XML and YAML alternatives and you could easily implement your own
favourite mechanism for defining ORM metadata.
In this chapter a reference of every Doctrine 2 Annotation is given
In this chapter a reference of every Doctrine ORM Annotation is given
with short explanations on their context and usage.
Index
@@ -89,7 +97,7 @@ as part of the lifecycle of the instance variables entity-class.
Required attributes:
- **type**: Name of the Doctrine Type which is converted between PHP
and Database representation.
and Database representation. Default to ``string`` or :ref:`Type from PHP property type <reference-php-mapping-types>`
Optional attributes:
@@ -115,6 +123,18 @@ Optional attributes:
- **nullable**: Determines if NULL values allowed for this column. If not specified, default value is false.
- **insertable**: Boolean value to determine if the column should be
included when inserting a new row into the underlying entities table.
If not specified, default value is true.
- **updatable**: Boolean value to determine if the column should be
included when updating the row of the underlying entities table.
If not specified, default value is true.
- **generated**: An enum with the possible values ALWAYS, INSERT, NEVER. Is
used after an INSERT or UPDATE statement to determine if the database
generated this value and it needs to be fetched using a SELECT statement.
- **options**: Array of additional options:
- ``default``: The default value to set for the column if no value
@@ -185,6 +205,13 @@ Examples:
*/
protected $loginCount;
/**
* Generated column
* @Column(type="string", name="user_fullname", insertable=false, updatable=false)
* MySQL example: full_name char(41) GENERATED ALWAYS AS (concat(firstname,' ',lastname)),
*/
protected $fullname;
.. _annref_column_result:
@ColumnResult
@@ -213,7 +240,7 @@ Optional attributes:
~~~~~~~~~~~~~~~~~~~~~
The Change Tracking Policy annotation allows to specify how the
Doctrine 2 UnitOfWork should detect changes in properties of
Doctrine ORM UnitOfWork should detect changes in properties of
entities during flush. By default each entity is checked according
to a deferred implicit strategy, which means upon flush UnitOfWork
compares all the properties of an entity to a previously stored
@@ -254,7 +281,7 @@ Example:
<?php
/**
* @Id
* @Id
* @Column(type="integer")
* @GeneratedValue(strategy="CUSTOM")
* @CustomIdGenerator(class="My\Namespace\MyIdGenerator")
@@ -350,7 +377,7 @@ in order to specify that it is an embedded class.
Required attributes:
- **class**: The embeddable class
- **class**: The embeddable class. You can omit this value if you use a PHP property type instead.
.. code-block:: php
@@ -388,7 +415,7 @@ Optional attributes:
EntityRepository. Use of repositories for entities is encouraged to keep
specialized DQL and SQL operations separated from the Model/Domain
Layer.
- **readOnly**: (>= 2.1) Specifies that this entity is marked as read only and not
- **readOnly**: Specifies that this entity is marked as read only and not
considered for change-tracking. Entities of this type can be persisted
and removed though.
@@ -398,11 +425,11 @@ Example:
<?php
/**
* @Entity(repositoryClass="MyProject\UserRepository")
* @Entity(repositoryClass="MyProject\UserRepository", readOnly=true)
*/
class User
{
//...
// ...
}
.. _annref_entity_result:
@@ -455,7 +482,8 @@ Optional attributes:
- **strategy**: Set the name of the identifier generation strategy.
Valid values are AUTO, SEQUENCE, TABLE, IDENTITY, UUID, CUSTOM and NONE.
Valid values are ``AUTO``, ``SEQUENCE``, ``IDENTITY``, ``UUID`` (deprecated), ``CUSTOM`` and ``NONE``, explained
in the :ref:`Identifier Generation Strategies <identifier-generation-strategies>` section.
If not specified, default value is AUTO.
Example:
@@ -513,7 +541,8 @@ Required attributes:
- **name**: Name of the Index
- **columns**: Array of columns.
- **fields**: Array of fields. Exactly one of **fields**, **columns** is required.
- **columns**: Array of columns. Exactly one of **fields**, **columns** is required.
Optional attributes:
@@ -535,6 +564,19 @@ Basic example:
{
}
Basic example using fields:
.. code-block:: php
<?php
/**
* @Entity
* @Table(name="ecommerce_products",indexes={@Index(name="search_idx", fields={"name", "email"})})
*/
class ECommerceProduct
{
}
Example with partial indexes:
.. code-block:: php
@@ -715,6 +757,7 @@ Required attributes:
- **targetEntity**: FQCN of the referenced target entity. Can be the
unqualified class name if both classes are in the same namespace.
You can omit this value if you use a PHP property type instead.
*IMPORTANT:* No leading backslash!
Optional attributes:
@@ -812,7 +855,7 @@ The @MappedSuperclass annotation cannot be used in conjunction with
Optional attributes:
- **repositoryClass**: (>= 2.2) Specifies the FQCN of a subclass of the EntityRepository.
- **repositoryClass**: Specifies the FQCN of a subclass of the EntityRepository.
That will be inherited for all subclasses of that Mapped Superclass.
Example:
@@ -840,6 +883,11 @@ Example:
@NamedNativeQuery
~~~~~~~~~~~~~~~~~
.. note::
Named Native Queries are deprecated as of version 2.9 and will be removed in ORM 3.0
Is used to specify a native SQL named query.
The NamedNativeQuery annotation can be applied to an entity or mapped superclass.
@@ -923,6 +971,7 @@ Required attributes:
- **targetEntity**: FQCN of the referenced target entity. Can be the
unqualified class name if both classes are in the same namespace.
When typed properties are used it is inherited from PHP type.
*IMPORTANT:* No leading backslash!
Optional attributes:
@@ -1231,7 +1280,7 @@ Optional attributes:
- **indexes**: Array of @Index annotations
- **uniqueConstraints**: Array of @UniqueConstraint annotations.
- **schema**: (>= 2.5) Name of the schema the table lies in.
- **schema**: Name of the schema the table lies in.
Example:
@@ -1263,7 +1312,8 @@ Required attributes:
- **name**: Name of the Index
- **columns**: Array of columns.
- **fields**: Array of fields. Exactly one of **fields**, **columns** is required.
- **columns**: Array of columns. Exactly one of **fields**, **columns** is required.
Optional attributes:
@@ -1285,6 +1335,19 @@ Basic example:
{
}
Basic example using fields:
.. code-block:: php
<?php
/**
* @Entity
* @Table(name="ecommerce_products",uniqueConstraints={@UniqueConstraint(name="search_idx", fields={"name", "email"})})
*/
class ECommerceProduct
{
}
Example with partial indexes:
.. code-block:: php

View File

@@ -2,29 +2,29 @@ Architecture
============
This chapter gives an overview of the overall architecture,
terminology and constraints of Doctrine 2. It is recommended to
terminology and constraints of Doctrine ORM. It is recommended to
read this chapter carefully.
Using an Object-Relational Mapper
---------------------------------
As the term ORM already hints at, Doctrine 2 aims to simplify the
As the term ORM already hints at, Doctrine ORM aims to simplify the
translation between database rows and the PHP object model. The
primary use case for Doctrine are therefore applications that
utilize the Object-Oriented Programming Paradigm. For applications
that do not primarily work with objects Doctrine 2 is not suited very
that do not primarily work with objects Doctrine ORM is not suited very
well.
Requirements
------------
Doctrine 2 requires a minimum of PHP 7.1. For greatly improved
Doctrine ORM requires a minimum of PHP 7.1. For greatly improved
performance it is also recommended that you use APC with PHP.
Doctrine 2 Packages
Doctrine ORM Packages
-------------------
Doctrine 2 is divided into three main packages.
Doctrine ORM is divided into three main packages.
- Common
- DBAL (includes Common)
@@ -82,9 +82,13 @@ be any regular PHP class observing the following restrictions:
:doc:`do so safely <../cookbook/implementing-wakeup-or-clone>`.
- An entity class must not implement ``__wakeup`` or
:doc:`do so safely <../cookbook/implementing-wakeup-or-clone>`.
Also consider implementing
`Serializable <http://php.net/manual/en/class.serializable.php>`_
instead.
You can also consider implementing
`Serializable <https://php.net/manual/en/class.serializable.php>`_,
but be aware that it is deprecated since PHP 8.1. We do not recommend its usage.
- PHP 7.4 introduces :doc:`the new magic method <https://php.net/manual/en/language.oop5.magic.php#object.unserialize>`
``__unserialize``, which changes the execution priority between
``__wakeup`` and itself when used. This can cause unexpected behaviour in
an Entity.
- Any two entity classes in a class hierarchy that inherit
directly or indirectly from one another must not have a mapped
property with the same name. That is, if B inherits from A then B
@@ -93,6 +97,7 @@ be any regular PHP class observing the following restrictions:
- An entity cannot make use of func_get_args() to implement variable parameters.
Generated proxies do not support this for performance reasons and your code might
actually fail to work when violating this restriction.
- Entity cannot access private/protected properties/methods of another entity of the same class or :doc:`do so safely <../cookbook/accessing-private-properties-of-the-same-class-from-different-instance>`.
Entities support inheritance, polymorphic associations, and
polymorphic queries. Both abstract and concrete classes can be
@@ -161,13 +166,14 @@ possible for ``__sleep`` to return names of private properties in
parent classes. On the other hand it is not a solution for proxy
objects to implement ``Serializable`` because Serializable does not
work well with any potential cyclic object references (at least we
did not find a way yet, if you did, please contact us).
did not find a way yet, if you did, please contact us). The
``Serializable`` interface is also deprecated beginning with PHP 8.1.
The EntityManager
~~~~~~~~~~~~~~~~~
The ``EntityManager`` class is a central access point to the ORM
functionality provided by Doctrine 2. The ``EntityManager`` API is
The ``EntityManager`` class is a central access point to the
functionality provided by Doctrine ORM. The ``EntityManager`` API is
used to manage the persistence of your objects and to query for
persistent objects.
@@ -184,12 +190,14 @@ 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
~~~~~~~~~~~~~~~~
Internally an ``EntityManager`` uses a ``UnitOfWork``, which is a
typical implementation of the
`Unit of Work pattern <http://martinfowler.com/eaaCatalog/unitOfWork.html>`_,
`Unit of Work pattern <https://martinfowler.com/eaaCatalog/unitOfWork.html>`_,
to keep track of all the things that need to be done the next time
``flush`` is invoked. You usually do not directly interact with a
``UnitOfWork`` but with the ``EntityManager`` instead.

View File

@@ -18,13 +18,13 @@ This chapter is split into three different sections.
One tip for working with relations is to read the relation from left to right, where the left word refers to the current Entity. For example:
- OneToMany - One instance of the current Entity has Many instances (references) to the refered Entity.
- ManyToOne - Many instances of the current Entity refer to One instance of the refered Entity.
- OneToOne - One instance of the current Entity refers to One instance of the refered Entity.
- OneToMany - One instance of the current Entity has Many instances (references) to the referred Entity.
- ManyToOne - Many instances of the current Entity refer to One instance of the referred Entity.
- OneToOne - One instance of the current Entity refers to One instance of the referred Entity.
See below for all the possible relations.
See below for all the possible relations.
An association is considered to be unidirectional if only one side of the association has
An association is considered to be unidirectional if only one side of the association has
a property referring to the other side.
To gain a full understanding of associations you should also read about :doc:`owning and
@@ -182,7 +182,7 @@ Here is a one-to-one relationship between a ``Customer`` and a
``Cart``. The ``Cart`` has a reference back to the ``Customer`` so
it is bidirectional.
Here we see the ``mappedBy`` and ``inversedBy`` annotations for the first time.
Here we see the ``mappedBy`` and ``inversedBy`` attributes for the first time.
They are used to tell Doctrine which property on the other side refers to the
object.
@@ -259,6 +259,7 @@ Generated MySQL Schema:
CREATE TABLE Cart (
id INT AUTO_INCREMENT NOT NULL,
customer_id INT DEFAULT NULL,
UNIQUE INDEX UNIQ_BA388B79395C3F3 (customer_id),
PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE Customer (
@@ -429,7 +430,7 @@ The following example sets up such a unidirectional one-to-many association:
// ...
/**
* Many User have Many Phonenumbers.
* Many Users have Many Phonenumbers.
* @ManyToMany(targetEntity="Phonenumber")
* @JoinTable(name="users_phonenumbers",
* joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
@@ -977,10 +978,10 @@ similar defaults. As an example, consider this mapping:
<?php
class User
{
//...
// ...
/** @ManyToMany(targetEntity="Group") */
private $groups;
//...
// ...
}
.. code-block:: xml
@@ -1008,7 +1009,7 @@ This is essentially the same as the following, more verbose, mapping:
<?php
class User
{
//...
// ...
/**
* Many Users have Many Groups.
* @ManyToMany(targetEntity="Group")
@@ -1018,7 +1019,7 @@ This is essentially the same as the following, more verbose, mapping:
* )
*/
private $groups;
//...
// ...
}
.. code-block:: xml
@@ -1061,6 +1062,70 @@ join columns default to the simple, unqualified class name of the
targeted class followed by "\_id". The referencedColumnName always
defaults to "id", just as in one-to-one or many-to-one mappings.
Additionally, when using typed properties with Doctrine 2.9 or newer
you can skip ``targetEntity`` in ``ManyToOne`` and ``OneToOne``
associations as they will be set based on type. Also ``nullable``
attribute on ``JoinColumn`` will be inherited from PHP type. So that:
.. configuration-block::
.. code-block:: php
<?php
/** @OneToOne */
private Shipment $shipment;
.. code-block:: xml
<doctrine-mapping>
<entity class="Product">
<one-to-one field="shipment" />
</entity>
</doctrine-mapping>
.. code-block:: yaml
Product:
type: entity
oneToOne:
shipment: ~
Is essentially the same as following:
.. configuration-block::
.. code-block:: php
<?php
/**
* One Product has One Shipment.
* @OneToOne(targetEntity="Shipment")
* @JoinColumn(name="shipment_id", referencedColumnName="id", nullable=false)
*/
private Shipment $shipment;
.. code-block:: xml
<doctrine-mapping>
<entity class="Product">
<one-to-one field="shipment" target-entity="Shipment">
<join-column name="shipment_id" referenced-column-name="id" nulable=false />
</one-to-one>
</entity>
</doctrine-mapping>
.. code-block:: yaml
Product:
type: entity
oneToOne:
shipment:
targetEntity: Shipment
joinColumn:
name: shipment_id
referencedColumnName: id
nullable: false
If you accept these defaults, you can reduce the mapping code to a
minimum.

File diff suppressed because it is too large Load Diff

View File

@@ -14,17 +14,11 @@ After working through this guide you should know:
Mapping of associations will be covered in the next chapter on
:doc:`Association Mapping <association-mapping>`.
Guide Assumptions
-----------------
You should have already :doc:`installed and configure <configuration>`
Doctrine.
Creating Classes for the Database
---------------------------------
Every PHP object that you want to save in the database using Doctrine
is called an "Entity". The term "Entity" describes objects
is called an *Entity*. The term "Entity" describes objects
that have an identity over many independent requests. This identity is
usually achieved by assigning a unique identifier to an entity.
In this tutorial the following ``Message`` PHP class will serve as the
@@ -50,10 +44,11 @@ that describes your entity.
Doctrine provides several different ways to specify object-relational
mapping metadata:
- :doc:`Attributes <attributes-reference>`
- :doc:`Docblock Annotations <annotations-reference>`
- :doc:`XML <xml-mapping>`
- :doc:`YAML <yaml-mapping>`
- :doc:`PHP code <php-mapping>`
- :doc:`YAML <yaml-mapping>` (deprecated and will be removed in ``doctrine/orm`` 3.0.)
This manual will usually show mapping metadata via docblock annotations, though
many examples also show the equivalent configuration in YAML and XML.
@@ -61,8 +56,8 @@ many examples also show the equivalent configuration in YAML and XML.
.. note::
All metadata drivers perform equally. Once the metadata of a class has been
read from the source (annotations, xml or yaml) it is stored in an instance
of the ``Doctrine\ORM\Mapping\ClassMetadata`` class and these instances are
read from the source (attributes, annotations, XML, etc.) it is stored in an instance
of the ``Doctrine\ORM\Mapping\ClassMetadata`` class which are
stored in the metadata cache. If you're not using a metadata cache (not
recommended!) then the XML driver is the fastest.
@@ -70,13 +65,26 @@ Marking our ``Message`` class as an entity for Doctrine is straightforward:
.. configuration-block::
.. code-block:: php
.. code-block:: attribute
<?php
use Doctrine\ORM\Mapping\Entity;
#[Entity]
class Message
{
// ...
}
.. code-block:: annotation
<?php
use Doctrine\ORM\Mapping\Entity;
/** @Entity */
class Message
{
//...
// ...
}
.. code-block:: xml
@@ -99,16 +107,32 @@ You can change this by configuring information about the table:
.. configuration-block::
.. code-block:: php
.. code-block:: attribute
<?php
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
#[Entity]
#[Table(name: 'message')]
class Message
{
// ...
}
.. code-block:: annotation
<?php
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
/**
* @Entity
* @Table(name="message")
*/
class Message
{
//...
// ...
}
.. code-block:: xml
@@ -131,19 +155,38 @@ Now the class ``Message`` will be saved and fetched from the table ``message``.
Property Mapping
----------------
The next step after marking a PHP class as an entity is mapping its properties
to columns in a table.
The next step is mapping its properties to columns in the table.
To configure a property use the ``@Column`` docblock annotation. The ``type``
To configure a property use the ``Column`` docblock annotation. The ``type``
attribute specifies the :ref:`Doctrine Mapping Type <reference-mapping-types>`
to use for the field. If the type is not specified, ``string`` is used as the
default.
.. configuration-block::
.. code-block:: php
.. code-block:: attribute
<?php
use Doctrine\ORM\Mapping\Column;
use Doctrine\DBAL\Types\Types;
#[Entity]
class Message
{
#[Column(type: Types::INTEGER)]
private $id;
#[Column(length: 140)]
private $text;
#[Column(name: 'posted_at', type: Types::DATETIME)]
private $postedAt;
}
.. code-block:: annotation
<?php
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Column;
/** @Entity */
class Message
{
@@ -179,38 +222,71 @@ default.
column: posted_at
When we don't explicitly specify a column name via the ``name`` option, Doctrine
assumes the field name is also the column name. This means that:
assumes the field name is also the column name. So in this example:
* the ``id`` property will map to the column ``id`` using the type ``integer``;
* the ``text`` property will map to the column ``text`` with the default mapping type ``string``;
* the ``postedAt`` property will map to the ``posted_at`` column with the ``datetime`` type.
The Column annotation has some more attributes. Here is a complete
list:
Here is a complete list of ``Column``s attributes (all optional):
- ``type``: (optional, defaults to 'string') The mapping type to
use for the column.
- ``name``: (optional, defaults to field name) The name of the
column in the database.
- ``length``: (optional, default 255) The length of the column in
the database. (Applies only if a string-valued column is used).
- ``unique``: (optional, default FALSE) Whether the column is a
unique key.
- ``nullable``: (optional, default FALSE) Whether the database
column is nullable.
- ``precision``: (optional, default 0) The precision for a decimal
(exact numeric) column (applies only for decimal column),
- ``type`` (default: 'string'): The mapping type to use for the column.
- ``name`` (default: name of property): The name of the column in the database.
- ``length`` (default: 255): The length of the column in the database.
Applies only if a string-valued column is used.
- ``unique`` (default: ``false``): Whether the column is a unique key.
- ``nullable`` (default: ``false``): Whether the column is nullable.
- ``insertable`` (default: ``true``): Whether the column should be inserted.
- ``updatable`` (default: ``true``): Whether the column should be updated.
- ``enumType`` (requires PHP 8.1 and ``doctrine/orm`` 2.11): The PHP enum class name to convert the database value into.
- ``precision`` (default: 0): The precision for a decimal (exact numeric) column
(applies only for decimal column),
which is the maximum number of digits that are stored for the values.
- ``scale``: (optional, default 0) The scale for a decimal (exact
- ``scale`` (default: 0): The scale for a decimal (exact
numeric) column (applies only for decimal column), which represents
the number of digits to the right of the decimal point and must
not be greater than *precision*.
- ``columnDefinition``: (optional) Allows to define a custom
not be greater than ``precision``.
- ``columnDefinition``: Allows to define a custom
DDL snippet that is used to create the column. Warning: This normally
confuses the SchemaTool to always detect the column as changed.
- ``options``: (optional) Key-value pairs of options that get passed
confuses the :doc:`SchemaTool <tools>` to always detect the column as changed.
- ``options``: Key-value pairs of options that get passed
to the underlying database platform when generating DDL statements.
.. _reference-php-mapping-types:
PHP Types Mapping
_________________
.. versionadded:: 2.9
The column types can be inferred automatically from PHP's property types.
However, when the property type is nullable this has no effect on the ``nullable`` Column attribute.
These are the "automatic" mapping rules:
+-----------------------+-------------------------------+
| PHP property type | Doctrine column type |
+=======================+===============================+
| ``DateInterval`` | ``Types::DATEINTERVAL`` |
+-----------------------+-------------------------------+
| ``DateTime`` | ``Types::DATETIME_MUTABLE`` |
+-----------------------+-------------------------------+
| ``DateTimeImmutable`` | ``Types::DATETIME_IMMUTABLE`` |
+-----------------------+-------------------------------+
| ``array`` | ``Types::JSON`` |
+-----------------------+-------------------------------+
| ``bool`` | ``Types::BOOLEAN`` |
+-----------------------+-------------------------------+
| ``float`` | ``Types::FLOAT`` |
+-----------------------+-------------------------------+
| ``int`` | ``Types::INTEGER`` |
+-----------------------+-------------------------------+
| Any other type | ``Types::STRING`` |
+-----------------------+-------------------------------+
As of version 2.11 Doctrine can also automatically map typed properties using a
PHP 8.1 enum to set the right ``type`` and ``enumType``.
.. _reference-mapping-types:
Doctrine Mapping Types
@@ -270,7 +346,7 @@ A cookbook article shows how to define :doc:`your own custom mapping types
.. warning::
All Date types assume that you are exclusively using the default timezone
set by `date_default_timezone_set() <http://php.net/manual/en/function.date-default-timezone-set.php>`_
set by `date_default_timezone_set() <https://php.net/manual/en/function.date-default-timezone-set.php>`_
or by the php.ini configuration ``date.timezone``. Working with
different timezones will cause troubles and unexpected behavior.
@@ -300,7 +376,7 @@ annotation.
* @GeneratedValue
*/
private $id;
//...
// ...
}
.. code-block:: xml
@@ -328,9 +404,11 @@ annotation.
In most cases using the automatic generator strategy (``@GeneratedValue``) is
what you want. It defaults to the identifier generation mechanism your current
database vendor prefers: AUTO_INCREMENT with MySQL, sequences with PostgreSQL
database vendor prefers: AUTO_INCREMENT with MySQL, sequences with PostgreSQL
and Oracle and so on.
.. _identifier-generation-strategies:
Identifier Generation Strategies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -355,11 +433,8 @@ Here is the list of possible generation strategies:
strategy does currently not provide full portability and is
supported by the following platforms: MySQL/SQLite/SQL Anywhere
(AUTO\_INCREMENT), MSSQL (IDENTITY) and PostgreSQL (SERIAL).
- ``UUID``: Tells Doctrine to use the built-in Universally Unique Identifier
generator. This strategy provides full portability.
- ``TABLE``: Tells Doctrine to use a separate table for ID
generation. This strategy provides full portability.
***This strategy is not yet implemented!***
- ``UUID`` (deprecated): Tells Doctrine to use the built-in Universally
Unique Identifier generator. This strategy provides full portability.
- ``NONE``: Tells Doctrine that the identifiers are assigned (and
thus generated) by your code. The assignment must take place before
a new entity is passed to ``EntityManager#persist``. NONE is the
@@ -387,7 +462,7 @@ besides specifying the sequence's name:
* @SequenceGenerator(sequenceName="message_seq", initialValue=1, allocationSize=100)
*/
protected $id = null;
//...
// ...
}
.. code-block:: xml
@@ -423,7 +498,7 @@ performance of Doctrine. The allocationSize specifies by how much
values the sequence is incremented whenever the next value is
retrieved. If this is larger than 1 (one) Doctrine can generate
identifier values for the allocationSizes amount of entities. In
the above example with ``allocationSize=100`` Doctrine 2 would only
the above example with ``allocationSize=100`` Doctrine ORM would only
need to access the sequence once to generate the identifiers for
100 new entities.
@@ -451,7 +526,7 @@ need to access the sequence once to generate the identifiers for
Composite Keys
~~~~~~~~~~~~~~
With Doctrine 2 you can use composite primary keys, using ``@Id`` on more then
With Doctrine ORM you can use composite primary keys, using ``@Id`` on more then
one column. Some restrictions exist opposed to using a single identifier in
this case: The use of the ``@GeneratedValue`` annotation is not supported,
which means you can only use composite keys if you generate the primary key
@@ -484,15 +559,11 @@ according to the used database platform.
.. _reference-basic-mapping-custom-mapping-types:
.. versionadded: 2.3
For more control over column quoting the ``Doctrine\ORM\Mapping\QuoteStrategy`` interface
was introduced in 2.3. It is invoked for every column, table, alias and other
was introduced in ORM. It is invoked for every column, table, alias and other
SQL names. You can implement the QuoteStrategy and set it by calling
``Doctrine\ORM\Configuration#setQuoteStrategy()``.
.. versionadded: 2.4
The ANSI Quote Strategy was added, which assumes quoting is not necessary for any SQL name.
You can use it with the following code:

View File

@@ -51,7 +51,7 @@ internally but also mean more work during ``flush``.
$em->clear(); // Detaches all objects from Doctrine!
}
}
$em->flush(); //Persist objects that did not make up an entire batch
$em->flush(); // Persist objects that did not make up an entire batch
$em->clear();
Bulk Updates
@@ -75,7 +75,7 @@ Iterating results
~~~~~~~~~~~~~~~~~
An alternative solution for bulk updates is to use the
``Query#iterate()`` facility to iterate over the query results step
``Query#toIterable()`` facility to iterate over the query results step
by step instead of loading the whole result into memory at once.
The following example shows how to do this, combining the iteration
with the batching strategy that was already used for bulk inserts:
@@ -86,16 +86,14 @@ with the batching strategy that was already used for bulk inserts:
$batchSize = 20;
$i = 1;
$q = $em->createQuery('select u from MyProject\Model\User u');
$iterableResult = $q->iterate();
foreach ($iterableResult as $row) {
$user = $row[0];
foreach ($q->toIterable() as $user) {
$user->increaseCredit();
$user->calculateNewBonuses();
++$i;
if (($i % $batchSize) === 0) {
$em->flush(); // Executes all updates.
$em->clear(); // Detaches all objects from Doctrine!
}
++$i;
}
$em->flush();
@@ -137,7 +135,7 @@ Iterating results
~~~~~~~~~~~~~~~~~
An alternative solution for bulk deletes is to use the
``Query#iterate()`` facility to iterate over the query results step
``Query#toIterable()`` facility to iterate over the query results step
by step instead of loading the whole result into memory at once.
The following example shows how to do this:
@@ -147,14 +145,13 @@ The following example shows how to do this:
$batchSize = 20;
$i = 1;
$q = $em->createQuery('select u from MyProject\Model\User u');
$iterableResult = $q->iterate();
while (($row = $iterableResult->next()) !== false) {
$em->remove($row[0]);
foreach($q->toIterable() as $row) {
$em->remove($row);
++$i;
if (($i % $batchSize) === 0) {
$em->flush(); // Executes all deletions.
$em->clear(); // Detaches all objects from Doctrine!
}
++$i;
}
$em->flush();
@@ -168,20 +165,18 @@ The following example shows how to do this:
Iterating Large Results for Data-Processing
-------------------------------------------
You can use the ``iterate()`` method just to iterate over a large
result and no UPDATE or DELETE intention. The ``IterableResult``
instance returned from ``$query->iterate()`` implements the
Iterator interface so you can process a large result without memory
You can use the ``toIterable()`` method just to iterate over a large
result and no UPDATE or DELETE intention. ``$query->toIterable()`` returns ``iterable``
so you can process a large result without memory
problems using the following approach:
.. code-block:: php
<?php
$q = $this->_em->createQuery('select u from MyProject\Model\User u');
$iterableResult = $q->iterate();
foreach ($iterableResult as $row) {
// do stuff with the data in the row, $row[0] is always the object
foreach ($q->toIterable() as $row) {
// do stuff with the data in the row
// detach from Doctrine, so that it can be Garbage-Collected immediately
$this->_em->detach($row[0]);
}

View File

@@ -1,266 +1,14 @@
Caching
=======
Doctrine provides cache drivers in the ``Common`` package for some
of the most popular caching implementations such as APC, Memcache
and Xcache. We also provide an ``ArrayCache`` driver which stores
the data in a PHP array. Obviously, when using ``ArrayCache``, the
cache does not persist between requests, but this is useful for
testing in a development environment.
The Doctrine ORM package can leverage cache adapters implementing the PSR-6
standard to allow you to improve the performance of various aspects of
Doctrine by simply making some additional configurations and method calls.
Cache Drivers
-------------
.. _types-of-caches:
The cache drivers follow a simple interface that is defined in
``Doctrine\Common\Cache\Cache``. All the cache drivers extend a
base class ``Doctrine\Common\Cache\CacheProvider`` which implements
this interface.
The interface defines the following public methods for you to implement:
- fetch($id) - Fetches an entry from the cache
- contains($id) - Test if an entry exists in the cache
- save($id, $data, $lifeTime = false) - Puts data into the cache for x seconds. 0 = infinite time
- delete($id) - Deletes a cache entry
Each driver extends the ``CacheProvider`` class which defines a few
abstract protected methods that each of the drivers must
implement:
- doFetch($id)
- doContains($id)
- doSave($id, $data, $lifeTime = false)
- doDelete($id)
The public methods ``fetch()``, ``contains()`` etc. use the
above protected methods which are implemented by the drivers. The
code is organized this way so that the protected methods in the
drivers do the raw interaction with the cache implementation and
the ``CacheProvider`` can build custom functionality on top of
these methods.
This documentation does not cover every single cache driver included
with Doctrine. For an up-to-date-list, see the
`cache directory on GitHub <https://github.com/doctrine/cache/tree/master/lib/Doctrine/Common/Cache>`_.
PhpFileCache
~~~~~~~~~~~~
The preferred cache driver for metadata and query caches is ``PhpFileCache``.
This driver serializes cache items and writes them to a file. This allows for
opcode caching to be used and provides high performance in most scenarios.
In order to use the ``PhpFileCache`` driver it must be able to write to
a directory.
Below is an example of how to use the ``PhpFileCache`` driver by itself.
.. code-block:: php
<?php
$cacheDriver = new \Doctrine\Common\Cache\PhpFileCache(
'/path/to/writable/directory'
);
$cacheDriver->save('cache_id', 'my_data');
The PhpFileCache is not distributed across multiple machines if you are running
your application in a distributed setup. This is ok for the metadata and query
cache but is not a good approach for the result cache.
Memcache
~~~~~~~~
In order to use the Memcache cache driver you must have it compiled
and enabled in your php.ini. You can read about Memcache
`on the PHP website <http://php.net/memcache>`_. It will
give you a little background information about what it is and how
you can use it as well as how to install it.
Below is a simple example of how you could use the Memcache cache
driver by itself.
.. code-block:: php
<?php
$memcache = new Memcache();
$memcache->connect('memcache_host', 11211);
$cacheDriver = new \Doctrine\Common\Cache\MemcacheCache();
$cacheDriver->setMemcache($memcache);
$cacheDriver->save('cache_id', 'my_data');
Memcached
~~~~~~~~~
Memcached is a more recent and complete alternative extension to
Memcache.
In order to use the Memcached cache driver you must have it compiled
and enabled in your php.ini. You can read about Memcached
`on the PHP website <http://php.net/memcached>`_. It will
give you a little background information about what it is and how
you can use it as well as how to install it.
Below is a simple example of how you could use the Memcached cache
driver by itself.
.. code-block:: php
<?php
$memcached = new Memcached();
$memcached->addServer('memcache_host', 11211);
$cacheDriver = new \Doctrine\Common\Cache\MemcachedCache();
$cacheDriver->setMemcached($memcached);
$cacheDriver->save('cache_id', 'my_data');
Redis
~~~~~
In order to use the Redis cache driver you must have it compiled
and enabled in your php.ini. You can read about what Redis is
`from here <http://redis.io/>`_. Also check
`A PHP extension for Redis <https://github.com/nicolasff/phpredis/>`_ for how you can use
and install the Redis PHP extension.
Below is a simple example of how you could use the Redis cache
driver by itself.
.. code-block:: php
<?php
$redis = new Redis();
$redis->connect('redis_host', 6379);
$cacheDriver = new \Doctrine\Common\Cache\RedisCache();
$cacheDriver->setRedis($redis);
$cacheDriver->save('cache_id', 'my_data');
Using Cache Drivers
-------------------
In this section we'll describe how you can fully utilize the API of
the cache drivers to save data to a cache, check if some cached data
exists, fetch the cached data and delete the cached data. We'll use the
``ArrayCache`` implementation as our example here.
.. code-block:: php
<?php
$cacheDriver = new \Doctrine\Common\Cache\ArrayCache();
Saving
~~~~~~
Saving some data to the cache driver is as simple as using the
``save()`` method.
.. code-block:: php
<?php
$cacheDriver->save('cache_id', 'my_data');
The ``save()`` method accepts three arguments which are described
below:
- ``$id`` - The cache id
- ``$data`` - The cache entry/data.
- ``$lifeTime`` - The lifetime. If != false, sets a specific
lifetime for this cache entry (null => infinite lifeTime).
You can save any type of data whether it be a string, array,
object, etc.
.. code-block:: php
<?php
$array = array(
'key1' => 'value1',
'key2' => 'value2'
);
$cacheDriver->save('my_array', $array);
Checking
~~~~~~~~
Checking whether cached data exists is very simple: just use the
``contains()`` method. It accepts a single argument which is the ID
of the cache entry.
.. code-block:: php
<?php
if ($cacheDriver->contains('cache_id')) {
echo 'cache exists';
} else {
echo 'cache does not exist';
}
Fetching
~~~~~~~~
Now if you want to retrieve some cache entry you can use the
``fetch()`` method. It also accepts a single argument just like
``contains()`` which is again the ID of the cache entry.
.. code-block:: php
<?php
$array = $cacheDriver->fetch('my_array');
Deleting
~~~~~~~~
As you might guess, deleting is just as easy as saving, checking
and fetching. You can delete by an individual ID, or you can
delete all entries.
By Cache ID
^^^^^^^^^^^
.. code-block:: php
<?php
$cacheDriver->delete('my_array');
All
^^^
If you simply want to delete all cache entries you can do so with
the ``deleteAll()`` method.
.. code-block:: php
<?php
$deleted = $cacheDriver->deleteAll();
Namespaces
~~~~~~~~~~
If you heavily use caching in your application and use it in
multiple parts of your application, or use it in different
applications on the same server you may have issues with cache
naming collisions. This can be worked around by using namespaces.
You can set the namespace a cache driver should use by using the
``setNamespace()`` method.
.. code-block:: php
<?php
$cacheDriver->setNamespace('my_namespace_');
.. _integrating-with-the-orm:
Integrating with the ORM
------------------------
The Doctrine ORM package is tightly integrated with the cache
drivers to allow you to improve the performance of various aspects of
Doctrine by simply making some additional configurations and
method calls.
Types of Caches
---------------
Query Cache
~~~~~~~~~~~
@@ -276,28 +24,27 @@ use on your ORM configuration.
.. code-block:: php
<?php
$cacheDriver = new \Doctrine\Common\Cache\PhpFileCache(
'/path/to/writable/directory'
);
$cache = new \Symfony\Component\Cache\Adapter\PhpFilesAdapter('doctrine_queries');
$config = new \Doctrine\ORM\Configuration();
$config->setQueryCacheImpl($cacheDriver);
$config->setQueryCache($cache);
Result Cache
~~~~~~~~~~~~
The result cache can be used to cache the results of your queries
so that we don't have to query the database or hydrate the data
again after the first time. You just need to configure the result
cache implementation.
so that we don't have to query the database again after the first time.
You just need to configure the result cache implementation.
.. code-block:: php
<?php
$cacheDriver = new \Doctrine\Common\Cache\PhpFileCache(
$cache = new \Symfony\Component\Cache\Adapter\PhpFilesAdapter(
'doctrine_results',
0,
'/path/to/writable/directory'
);
$config = new \Doctrine\ORM\Configuration();
$config->setResultCacheImpl($cacheDriver);
$config->setResultCache($cache);
Now when you're executing DQL queries you can configure them to use
the result cache.
@@ -306,7 +53,7 @@ the result cache.
<?php
$query = $em->createQuery('select u from \Entities\User u');
$query->useResultCache(true);
$query->enableResultCache();
You can also configure an individual query to use a different
result cache driver.
@@ -314,22 +61,23 @@ result cache driver.
.. code-block:: php
<?php
$cacheDriver = new \Doctrine\Common\Cache\PhpFileCache(
$cache = new \Symfony\Component\Cache\Adapter\PhpFilesAdapter(
'doctrine_results',
0,
'/path/to/writable/directory'
);
$config = new \Doctrine\ORM\Configuration();
$query->setResultCacheDriver($cacheDriver);
$query->setResultCache($cache);
.. note::
Setting the result cache driver on the query will
automatically enable the result cache for the query. If you want to
disable it pass false to ``useResultCache()``.
disable it use ``disableResultCache()``.
::
<?php
$query->useResultCache(false);
$query->disableResultCache();
If you want to set the time the cache has to live you can use the
@@ -350,12 +98,12 @@ yourself with the ``setResultCacheId()`` method.
$query->setResultCacheId('my_custom_id');
You can also set the lifetime and cache ID by passing the values as
the second and third argument to ``useResultCache()``.
the first and second argument to ``enableResultCache()``.
.. code-block:: php
<?php
$query->useResultCache(true, 3600, 'my_custom_id');
$query->enableResultCache(3600, 'my_custom_id');
Metadata Cache
~~~~~~~~~~~~~~
@@ -370,11 +118,13 @@ first.
.. code-block:: php
<?php
$cacheDriver = new \Doctrine\Common\Cache\PhpFileCache(
$cache = \Symfony\Component\Cache\Adapter\PhpFilesAdapter(
'doctrine_metadata',
0,
'/path/to/writable/directory'
);
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl($cacheDriver);
$config->setMetadataCache($cache);
Now the metadata information will only be parsed once and stored in
the cache driver.
@@ -424,30 +174,15 @@ requested many times in a single PHP request. Even though this data
may be stored in a fast memory cache, often that cache is over a
network link leading to sizable network traffic.
The ChainCache class allows multiple caches to be registered at once.
For example, a per-request ArrayCache can be used first, followed by
a (relatively) slower MemcacheCache if the ArrayCache misses.
ChainCache automatically handles pushing data up to faster caches in
A chain cache class allows multiple caches to be registered at once.
For example, a per-request array cache can be used first, followed by
a (relatively) slower Memcached cache if the array cache misses.
The chain cache automatically handles pushing data up to faster caches in
the chain and clearing data in the entire stack when it is deleted.
A ChainCache takes a simple array of CacheProviders in the order that
they should be used.
.. code-block:: php
$arrayCache = new \Doctrine\Common\Cache\ArrayCache();
$memcache = new Memcache();
$memcache->connect('memcache_host', 11211);
$chainCache = new \Doctrine\Common\Cache\ChainCache([
$arrayCache,
$memcache,
]);
ChainCache itself extends the CacheProvider interface, so it is
possible to create chains of chains. While this may seem like an easy
way to build a simple high-availability cache, ChainCache does not
implement any exception handling so using it as a high-availability
mechanism is not recommended.
Symfony Cache provides such a chain cache. To find out how to use it,
please have a look at the
`Symfony Documentation <https://symfony.com/doc/current/components/cache/adapters/chain_adapter.html>`_.
Cache Slams
-----------

View File

@@ -30,7 +30,7 @@ Deferred Explicit
The deferred explicit policy is similar to the deferred implicit
policy in that it detects changes through a property-by-property
comparison at commit time. The difference is that Doctrine 2 only
comparison at commit time. The difference is that Doctrine ORM only
considers entities that have been explicitly marked for change detection
through a call to EntityManager#persist(entity) or through a save
cascade. All other entities are skipped. This policy therefore
@@ -61,6 +61,11 @@ This policy can be configured as follows:
Notify
~~~~~~
.. note::
The notify change tracking policy is deprecated and will be removed in ORM 3.0.
(`Details <https://github.com/doctrine/orm/issues/8383>`_)
This policy is based on the assumption that the entities notify
interested listeners of changes to their properties. For that
purpose, a class that wants to use this policy needs to implement
@@ -129,6 +134,32 @@ The check whether the new value is different from the old one is
not mandatory but recommended. That way you also have full control
over when you consider a property changed.
If your entity contains an embeddable, you will need to notify
separately for each property in the embeddable when it changes
for example:
.. code-block:: php
<?php
// ...
class MyEntity implements NotifyPropertyChanged
{
public function setEmbeddable(MyValueObject $embeddable)
{
if (!$embeddable->equals($this->embeddable)) {
// notice the entityField.embeddableField notation for referencing the property
$this->_onPropertyChanged('embeddable.prop1', $this->embeddable->getProp1(), $embeddable->getProp1());
$this->_onPropertyChanged('embeddable.prop2', $this->embeddable->getProp2(), $embeddable->getProp2());
$this->embeddable = $embeddable;
}
}
}
This would update all the fields of the embeddable, you may wish to
implement a diff method on your embedded object which returns only
the changed fields.
The negative point of this policy is obvious: You need implement an
interface and write some plumbing code. But also note that we tried
hard to keep this notification functionality abstract. Strictly

View File

@@ -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.
@@ -95,7 +95,7 @@ If you want to configure Doctrine in more detail, take a look at the :doc:`Advan
.. note::
You can learn more about the database connection configuration in the
`Doctrine DBAL connection configuration reference <http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html>`_.
`Doctrine DBAL connection configuration reference <https://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html>`_.
Setting up the Commandline Tool
-------------------------------
@@ -112,8 +112,6 @@ You need to register your applications EntityManager to the console tool
to make use of the tasks by creating a ``cli-config.php`` file with the
following content:
On Doctrine 2.4 and above:
.. code-block:: php
<?php
@@ -126,19 +124,3 @@ On Doctrine 2.4 and above:
$entityManager = GetEntityManager();
return ConsoleRunner::createHelperSet($entityManager);
On Doctrine 2.3 and below:
.. code-block:: php
<?php
// cli-config.php
require_once 'my_bootstrap.php';
// Any way to access the EntityManager from your application
$em = GetMyEntityManager();
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));

View File

@@ -1,5 +1,5 @@
Doctrine Query Language
===========================
=======================
DQL stands for Doctrine Query Language and is an Object
Query Language derivative that is very similar to the Hibernate
@@ -458,8 +458,6 @@ Get all users that have no phonenumber
Get all instances of a specific type, for use with inheritance
hierarchies:
.. versionadded:: 2.1
.. code-block:: php
<?php
@@ -469,29 +467,45 @@ hierarchies:
Get all users visible on a given website that have chosen certain gender:
.. versionadded:: 2.2
.. code-block:: php
<?php
$query = $em->createQuery('SELECT u FROM User u WHERE u.gender IN (SELECT IDENTITY(agl.gender) FROM Site s JOIN s.activeGenderList agl WHERE s.id = ?1)');
.. versionadded:: 2.4
Starting with 2.4, the IDENTITY() DQL function also works for composite primary keys:
The IDENTITY() DQL function also works for composite primary keys
.. code-block:: php
<?php
$query = $em->createQuery("SELECT IDENTITY(c.location, 'latitude') AS latitude, IDENTITY(c.location, 'longitude') AS longitude FROM Checkpoint c WHERE c.user = ?1");
Joins between entities without associations were not possible until version
2.4, where you can generate an arbitrary join with the following syntax:
Joins between entities without associations are available,
where you can generate an arbitrary join with the following syntax:
.. code-block:: php
<?php
$query = $em->createQuery('SELECT u FROM User u JOIN Blacklist b WITH u.email = b.email');
$query = $em->createQuery('SELECT u FROM User u JOIN Banlist b WITH u.email = b.email');
With an arbitrary join the result differs from the joins using a mapped property.
The result of an arbitrary join is an one dimensional array with a mix of the entity from the ``SELECT``
and the joined entity fitting to the filtering of the query. In case of the example with ``User``
and ``Banlist``, it can look like this:
- User
- Banlist
- Banlist
- User
- Banlist
- User
- Banlist
- Banlist
- Banlist
In this form of join, the ``Banlist`` entities found by the filtering in the ``WITH`` part are not fetched by an accessor
method on ``User``, but are already part of the result. In case the accessor method for Banlists is invoked on a User instance,
it loads all the related ``Banlist`` objects corresponding to this ``User``. This change of behaviour needs to be considered
when the DQL is switched to an arbitrary join.
.. note::
The differences between WHERE, WITH and HAVING clauses may be
@@ -534,8 +548,6 @@ You use the partial syntax when joining as well:
"NEW" Operator Syntax
^^^^^^^^^^^^^^^^^^^^^
.. versionadded:: 2.4
Using the ``NEW`` operator you can construct Data Transfer Objects (DTOs) directly from DQL queries.
- When using ``SELECT NEW`` you don't need to specify a mapped entity.
@@ -611,6 +623,13 @@ then phonenumber-id:
...
'nameUpper' => string 'JWAGE' (length=5)
You can also index by a to-one association, which will use the id of
the associated entity (the join column) as the key in the result set:
.. code-block:: sql
SELECT p, u FROM Participant INDEX BY p.user JOIN p.user u WHERE p.event = 3
UPDATE queries
--------------
@@ -651,12 +670,34 @@ The same restrictions apply for the reference of related entities.
.. warning::
DQL DELETE statements are ported directly into a
Database DELETE statement and therefore bypass any events and checks for the
version column if they are not explicitly added to the WHERE clause
of the query. Additionally Deletes of specified entities are *NOT*
cascaded to related entities even if specified in the metadata.
DQL DELETE statements are ported directly into an SQL DELETE statement.
Therefore, some limitations apply:
- Lifecycle events for the affected entities are not executed.
- A cascading ``remove`` operation (as indicated e. g. by ``cascade={"remove"}``
or ``cascade={"all"}`` in the mapping configuration) is not being performed
for associated entities. You can rely on database level cascade operations by
configuring each join column with the ``onDelete`` option.
- Checks for the version column are bypassed if they are not explicitly added
to the WHERE clause of the query.
When you rely on one of these features, one option is to use the
``EntityManager#remove($entity)`` method. This, however, is costly performance-wise:
It means collections and related entities are fetched into memory
(even if they are marked as lazy). Pulling object graphs into memory on cascade
can cause considerable performance overhead, especially when the cascaded collections
are large. Make sure to weigh the benefits and downsides.
Comments in queries
-------------------
We can use comments with the SQL syntax of comments.
.. code-block:: sql
SELECT u FROM MyProject\Model\User u
-- my comment
WHERE u.age > 20 -- comment at the end of a line
Functions, Operators, Aggregates
--------------------------------
@@ -671,29 +712,35 @@ The following functions are supported in SELECT, WHERE and HAVING
clauses:
- IDENTITY(single\_association\_path\_expression [, fieldMapping]) - Retrieve the foreign key column of association of the owning side
- ABS(arithmetic\_expression)
- CONCAT(str1, str2)
- CURRENT\_DATE() - Return the current date
- CURRENT\_TIME() - Returns the current time
- CURRENT\_TIMESTAMP() - Returns a timestamp of the current date
- ``IDENTITY(single_association_path_expression [, fieldMapping])`` -
Retrieve the foreign key column of association of the owning side
- ``ABS(arithmetic_expression)``
- ``CONCAT(str1, str2)``
- ``CURRENT_DATE()`` - Return the current date
- ``CURRENT_TIME()`` - Returns the current time
- ``CURRENT_TIMESTAMP()`` - Returns a timestamp of the current date
and time.
- LENGTH(str) - Returns the length of the given string
- LOCATE(needle, haystack [, offset]) - Locate the first
- ``LENGTH(str)`` - Returns the length of the given string
- ``LOCATE(needle, haystack [, offset])`` - Locate the first
occurrence of the substring in the string.
- LOWER(str) - returns the string lowercased.
- MOD(a, b) - Return a MOD b.
- SIZE(collection) - Return the number of elements in the
- ``LOWER(str)`` - returns the string lowercased.
- ``MOD(a, b)`` - Return a MOD b.
- ``SIZE(collection)`` - Return the number of elements in the
specified collection
- SQRT(q) - Return the square-root of q.
- SUBSTRING(str, start [, length]) - Return substring of given
- ``SQRT(q)`` - Return the square-root of q.
- ``SUBSTRING(str, start [, length])`` - Return substring of given
string.
- TRIM([LEADING \| TRAILING \| BOTH] ['trchar' FROM] str) - Trim
- ``TRIM([LEADING | TRAILING | BOTH] ['trchar' FROM] str)`` - Trim
the string by the given trim char, defaults to whitespaces.
- UPPER(str) - Return the upper-case of the given string.
- DATE_ADD(date, value, unit) - Add the given time to a given date. (Supported units are SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, YEAR)
- DATE_SUB(date, value, unit) - Subtract the given time from a given date. (Supported units are SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, YEAR)
- DATE_DIFF(date1, date2) - Calculate the difference in days between date1-date2.
- ``UPPER(str)`` - Return the upper-case of the given string.
- ``DATE_ADD(date, value, unit)`` - Add the given time to a given date.
(Supported units are ``SECOND``, ``MINUTE``, ``HOUR``, ``DAY``,
``WEEK``, ``MONTH``, ``YEAR``)
- ``DATE_SUB(date, value, unit)`` - Subtract the given time from a
given date. (Supported units are ``SECOND``, ``MINUTE``, ``HOUR``,
``DAY``, ``WEEK``, ``MONTH``, ``YEAR``)
- ``DATE_DIFF(date1, date2)`` - Calculate the difference in days
between date1-date2.
Arithmetic operators
~~~~~~~~~~~~~~~~~~~~
@@ -803,7 +850,7 @@ what type of results to expect.
Single Table
~~~~~~~~~~~~
`Single Table Inheritance <http://martinfowler.com/eaaCatalog/singleTableInheritance.html>`_
`Single Table Inheritance <https://martinfowler.com/eaaCatalog/singleTableInheritance.html>`_
is an inheritance mapping strategy where all classes of a hierarchy
are mapped to a single database table. In order to distinguish
which row represents which type in the hierarchy a so-called
@@ -896,11 +943,11 @@ entities:
Class Table Inheritance
~~~~~~~~~~~~~~~~~~~~~~~
`Class Table Inheritance <http://martinfowler.com/eaaCatalog/classTableInheritance.html>`_
`Class Table Inheritance <https://martinfowler.com/eaaCatalog/classTableInheritance.html>`_
is an inheritance mapping strategy where each class in a hierarchy
is mapped to several tables: its own table and the tables of all
parent classes. The table of a child class is linked to the table
of a parent class through a foreign key constraint. Doctrine 2
of a parent class through a foreign key constraint. Doctrine ORM
implements this strategy through the use of a discriminator column
in the topmost table of the hierarchy because this is the easiest
way to achieve polymorphic queries with Class Table Inheritance.
@@ -1145,10 +1192,11 @@ make best use of the different result formats:
The constants for the different hydration modes are:
- Query::HYDRATE\_OBJECT
- Query::HYDRATE\_ARRAY
- Query::HYDRATE\_SCALAR
- Query::HYDRATE\_SINGLE\_SCALAR
- ``Query::HYDRATE_OBJECT``
- ``Query::HYDRATE_ARRAY``
- ``Query::HYDRATE_SCALAR``
- ``Query::HYDRATE_SINGLE_SCALAR``
- ``Query::HYDRATE_SCALAR_COLUMN``
Object Hydration
^^^^^^^^^^^^^^^^
@@ -1214,7 +1262,7 @@ Scalar Hydration:
1. Fields from classes are prefixed by the DQL alias in the result.
A query of the kind 'SELECT u.name ..' returns a key 'u\_name' in
A query of the kind 'SELECT u.name ..' returns a key 'u_name' in
the result rows.
Single Scalar Hydration
@@ -1237,6 +1285,25 @@ You can use the ``getSingleScalarResult()`` shortcut as well:
<?php
$numArticles = $query->getSingleScalarResult();
Scalar Column Hydration
^^^^^^^^^^^^^^^^^^^^^^^
If you have a query which returns a one-dimensional array of scalar values
you can use scalar column hydration:
.. code-block:: php
<?php
$query = $em->createQuery('SELECT a.id FROM CmsUser u');
$ids = $query->getResult(Query::HYDRATE_SCALAR_COLUMN);
You can use the ``getSingleColumnResult()`` shortcut as well:
.. code-block:: php
<?php
$ids = $query->getSingleColumnResult();
Custom Hydration Modes
^^^^^^^^^^^^^^^^^^^^^^
@@ -1248,13 +1315,14 @@ creating a class which extends ``AbstractHydrator``:
<?php
namespace MyProject\Hydrators;
use Doctrine\DBAL\FetchMode;
use Doctrine\ORM\Internal\Hydration\AbstractHydrator;
class CustomHydrator extends AbstractHydrator
{
protected function _hydrateAll()
{
return $this->_stmt->fetchAll(PDO::FETCH_ASSOC);
return $this->_stmt->fetchAll(FetchMode::FETCH_ASSOC);
}
}
@@ -1362,21 +1430,22 @@ userland. However the following few hints are to be used in
userland:
- Query::HINT\_FORCE\_PARTIAL\_LOAD - Allows to hydrate objects
- ``Query::HINT_FORCE_PARTIAL_LOAD`` - Allows to hydrate objects
although not all their columns are fetched. This query hint can be
used to handle memory consumption problems with large result-sets
that contain char or binary data. Doctrine has no way of implicitly
reloading this data. Partially loaded objects have to be passed to
``EntityManager::refresh()`` if they are to be reloaded fully from
the database.
- Query::HINT\_REFRESH - This query is used internally by
the database. This query hint is deprecated and will be removed
in the future (`Details <https://github.com/doctrine/orm/issues/8471>`_)
- ``Query::HINT_REFRESH`` - This query is used internally by
``EntityManager::refresh()`` and can be used in userland as well.
If you specify this hint and a query returns the data for an entity
that is already managed by the UnitOfWork, the fields of the
existing entity will be refreshed. In normal operation a result-set
that loads data of an already existing entity is discarded in favor
of the already existing entity.
- Query::HINT\_CUSTOM\_TREE\_WALKERS - An array of additional
- ``Query::HINT_CUSTOM_TREE_WALKERS`` - An array of additional
``Doctrine\ORM\Query\TreeWalker`` instances that are attached to
the DQL query parsing process.
@@ -1490,7 +1559,6 @@ Terminals
- identifier (name, email, ...) must match ``[a-z_][a-z0-9_]*``
- fully_qualified_name (Doctrine\Tests\Models\CMS\CmsUser) matches PHP's fully qualified class names
- aliased_name (CMS:CmsUser) uses two identifiers, one for the namespace alias and one for the class inside it
- string ('foo', 'bar''s house', '%ninja%', ...)
- char ('/', '\\', ' ', ...)
- integer (-1, 0, 1, 34, ...)
@@ -1613,7 +1681,7 @@ From, Join and Index by
RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable
JoinAssociationDeclaration ::= JoinAssociationPathExpression ["AS"] AliasIdentificationVariable [IndexBy]
Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" (JoinAssociationDeclaration | RangeVariableDeclaration) ["WITH" ConditionalExpression]
IndexBy ::= "INDEX" "BY" StateFieldPathExpression
IndexBy ::= "INDEX" "BY" SingleValuedPathExpression
Select Expressions
~~~~~~~~~~~~~~~~~~
@@ -1656,7 +1724,7 @@ Literal Values
.. code-block:: php
Literal ::= string | char | integer | float | boolean
InParameter ::= Literal | InputParameter
InParameter ::= ArithmeticExpression | InputParameter
Input Parameter
~~~~~~~~~~~~~~~
@@ -1731,7 +1799,7 @@ QUANTIFIED/BETWEEN/COMPARISON/LIKE/NULL/EXISTS
QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")"
BetweenExpression ::= ArithmeticExpression ["NOT"] "BETWEEN" ArithmeticExpression "AND" ArithmeticExpression
ComparisonExpression ::= ArithmeticExpression ComparisonOperator ( QuantifiedExpression | ArithmeticExpression )
InExpression ::= SingleValuedPathExpression ["NOT"] "IN" "(" (InParameter {"," InParameter}* | Subselect) ")"
InExpression ::= ArithmeticExpression ["NOT"] "IN" "(" (InParameter {"," InParameter}* | Subselect) ")"
InstanceOfExpression ::= IdentificationVariable ["NOT"] "INSTANCE" ["OF"] (InstanceOfParameter | "(" InstanceOfParameter {"," InstanceOfParameter}* ")")
InstanceOfParameter ::= AbstractSchemaName | InputParameter
LikeExpression ::= StringExpression ["NOT"] "LIKE" StringPrimary ["ESCAPE" char]

View File

@@ -1,7 +1,7 @@
Events
======
Doctrine 2 features a lightweight event system that is part of the
Doctrine ORM features a lightweight event system that is part of the
Common package. Doctrine uses it to dispatch system events, mainly
:ref:`lifecycle events <reference-events-lifecycle-events>`.
You can also use it for your own custom events.
@@ -70,7 +70,7 @@ method.
<?php
$evm->removeEventListener(array(self::preFoo, self::postFoo), $this);
The Doctrine 2 event system also has a simple concept of event
The Doctrine ORM event system also has a simple concept of event
subscribers. We can define a simple ``TestEventSubscriber`` class
which implements the ``\Doctrine\Common\EventSubscriber`` interface
and implements a ``getSubscribedEvents()`` method which returns an
@@ -121,10 +121,60 @@ Now you can test the ``$eventSubscriber`` instance to see if the
echo 'pre foo invoked!';
}
Registering Event Handlers
~~~~~~~~~~~~~~~~~~~~~~~~~~
There are two ways to set up an event handler:
* For *all events* you can create a Lifecycle Event Listener or Subscriber class and register
it by calling ``$eventManager->addEventListener()`` or ``eventManager->addEventSubscriber()``,
see
:ref:`Listening and subscribing to Lifecycle Events<listening-and-subscribing-to-lifecycle-events>`
* For *some events* (see table below), you can create a *Lifecycle Callback* method in the
entity, see :ref:`Lifecycle Callbacks<lifecycle-callbacks>`.
.. _reference-events-lifecycle-events:
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` |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| :ref:`onClear<reference-events-on-clear>` | ``$em->clear()`` | No | `_OnClearEventArgs` |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
Naming convention
~~~~~~~~~~~~~~~~~
Events being used with the Doctrine 2 EventManager are best named
Events being used with the Doctrine ORM EventManager are best named
with camelcase and the value of the corresponding constant should
be the name of the constant itself, even with spelling. This has
several reasons:
@@ -140,99 +190,7 @@ several reasons:
An example for a correct notation can be found in the example
``TestEvent`` above.
.. _reference-events-lifecycle-events:
Lifecycle Events
----------------
The EntityManager and UnitOfWork trigger a bunch of events during
the life-time of their registered entities.
- preRemove - The preRemove event occurs for a given entity before
the respective EntityManager remove operation for that entity is
executed. It is not called for a DQL DELETE statement.
- postRemove - The postRemove event occurs for an entity after the
entity has been deleted. It will be invoked after the database
delete operations. It is not called for a DQL DELETE statement.
- prePersist - The prePersist event occurs for a given entity
before the respective EntityManager persist operation for that
entity is executed. It should be noted that this event is only triggered on
*initial* persist of an entity (i.e. it does not trigger on future updates).
- postPersist - The postPersist event occurs for an entity after
the entity has been made persistent. It will be invoked after the
database insert operations. Generated primary key values are
available in the postPersist event.
- preUpdate - The preUpdate event occurs before the database
update operations to entity data. It is not called for a DQL UPDATE statement
nor when the computed changeset is empty.
- postUpdate - The postUpdate event occurs after the database
update operations to entity data. It is not called for a DQL UPDATE statement.
- postLoad - The postLoad event occurs for an entity after the
entity has been loaded into the current EntityManager from the
database or after the refresh operation has been applied to it.
- loadClassMetadata - The loadClassMetadata event occurs after the
mapping metadata for a class has been loaded from a mapping source
(annotations/xml/yaml). This event is not a lifecycle callback.
- onClassMetadataNotFound - Loading class metadata for a particular
requested class name failed. Manipulating the given event args instance
allows providing fallback metadata even when no actual metadata exists
or could be found. This event is not a lifecycle callback.
- preFlush - The preFlush event occurs at the very beginning of a flush
operation.
- onFlush - The onFlush event occurs after the change-sets of all
managed entities are computed. This event is not a lifecycle
callback.
- postFlush - The postFlush event occurs at the end of a flush operation. This
event is not a lifecycle callback.
- onClear - The onClear event occurs when the EntityManager#clear() operation is
invoked, after all references to entities have been removed from the unit of
work. This event is not a lifecycle callback.
.. warning::
Note that, when using ``Doctrine\ORM\AbstractQuery#iterate()``, ``postLoad``
events will be executed immediately after objects are being hydrated, and therefore
associations are not guaranteed to be initialized. It is not safe to combine
usage of ``Doctrine\ORM\AbstractQuery#iterate()`` and ``postLoad`` event
handlers.
.. warning::
Note that the postRemove event or any events triggered after an entity removal
can receive an uninitializable proxy in case you have configured an entity to
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:
- Lifecycle Callbacks are methods on the entity classes that are
called when the event is triggered. As of v2.4 they receive some kind
of ``EventArgs`` instance.
- Lifecycle Event Listeners and Subscribers are classes with specific callback
methods that receives some kind of ``EventArgs`` instance.
The EventArgs instance received by the listener gives access to the entity,
EntityManager and other relevant data.
.. note::
All Lifecycle events that happen during the ``flush()`` of
an EntityManager have very specific constraints on the allowed
operations that can be executed. Please read the
:ref:`reference-events-implementing-listeners` section very carefully
to understand which operations are allowed in which lifecycle event.
.. _lifecycle-callbacks:
Lifecycle Callbacks
-------------------
@@ -246,142 +204,112 @@ 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;
#[Entity]
#[HasLifecycleCallbacks]
class User
{
// ...
#[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;
/**
* @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="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="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="string", length=255) */
public $value;
public function doStuffOnPostPersist()
{
// ...
}
}
/** @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
-----------------------------------
----------------------------------
.. versionadded:: 2.4
Since 2.4 the triggered event is given to the lifecycle-callback.
The triggered event is also given to the lifecycle-callback.
With the additional argument you have access to the
``EntityManager`` and ``UnitOfWork`` APIs inside these callback methods.
@@ -401,6 +329,8 @@ With the additional argument you have access to the
}
}
.. _listening-and-subscribing-to-lifecycle-events:
Listening and subscribing to Lifecycle Events
---------------------------------------------
@@ -410,9 +340,9 @@ sit at a level above the entities and allow you to implement re-usable
behaviors across different entity classes.
Note that they require much more detailed knowledge about the inner
workings of the EntityManager and UnitOfWork. Please read the
:ref:`reference-events-implementing-listeners` section carefully if you
are trying to write your own listener.
workings of the ``EntityManager`` and ``UnitOfWork`` classes. Please
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
lifecycle events in their ``getSubscribedEvents`` method and provide
@@ -480,8 +410,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);
@@ -492,7 +424,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:
@@ -501,35 +435,39 @@ Implementing Event Listeners
----------------------------
This section explains what is and what is not allowed during
specific lifecycle events of the UnitOfWork. Although you get
passed the EntityManager in all of these events, you have to follow
these restrictions very carefully since operations in the wrong
event may produce lots of different errors, such as inconsistent
specific lifecycle events of the ``UnitOfWork`` class. Although you get
passed the ``EntityManager`` instance in all of these events, you have
to follow these restrictions very carefully since operations in the
wrong event may produce lots of different errors, such as inconsistent
data and lost updates/persists/removes.
For the described events that are also lifecycle callback events
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.
``EntityManager`` or ``UnitOfWork`` APIs inside these events.
.. _reference-events-pre-persist:
prePersist
~~~~~~~~~~
There are two ways for the ``prePersist`` event to be triggered.
One is obviously when you call ``EntityManager#persist()``. The
event is also called for all cascaded associations.
There are two ways for the ``prePersist`` event to be triggered:
There is another way for ``prePersist`` to be called, inside the
- One is obviously when you call ``EntityManager::persist()``. The
event is also called for all :ref:`cascaded associations<transitive-persistence>`.
- The other is inside the
``flush()`` method when changes to associations are computed and
this association is marked as cascade persist. Any new entity found
this association is marked as :ref:`cascade: persist<transitive-persistence>`. Any new entity found
during this operation is also persisted and ``prePersist`` called
on it. This is called "persistence by reachability".
on it. This is called :ref:`persistence by reachability<persistence-by-reachability>`.
In both cases you get passed a ``LifecycleEventArgs`` instance
which has access to the entity and the entity manager.
The following restrictions apply to ``prePersist``:
This event is only triggered on *initial* persist of an entity
(i.e. it does not trigger on future updates).
The following restrictions apply to ``prePersist``:
- If you are using a PrePersist Identity Generator such as
sequences the ID value will *NOT* be available within any
@@ -538,24 +476,30 @@ The following restrictions apply to ``prePersist``:
event. This includes modifications to
collections such as additions, removals or replacement.
.. _reference-events-pre-remove:
preRemove
~~~~~~~~~
The ``preRemove`` event is called on every entity when its passed
to the ``EntityManager#remove()`` method. It is cascaded for all
associations that are marked as cascade delete.
The ``preRemove`` event is called on every entity immediately when it is passed
to the ``EntityManager::remove()`` method. It is cascaded for all
associations that are marked as :ref:`cascade: remove<transitive-persistence>`
It is not called for a DQL ``DELETE`` statement.
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
~~~~~~~~
``preFlush`` is called at ``EntityManager#flush()`` before
anything else. ``EntityManager#flush()`` should not be called inside
its listeners, since `preFlush` event is dispatched in it, which would
result in infinite loop.
``preFlush`` is called inside ``EntityManager::flush()`` before
anything else. ``EntityManager::flush()`` must not be called inside
its listeners, since it would fire the ``preFlush`` event again, which would
result in an infinite loop.
.. code-block:: php
@@ -571,23 +515,24 @@ result in infinite loop.
}
}
.. _reference-events-on-flush:
onFlush
~~~~~~~
OnFlush is a very powerful event. It is called inside
``EntityManager#flush()`` after the changes to all the managed
``onFlush`` is a very powerful event. It is called inside
``EntityManager::flush()`` after the changes to all the managed
entities and their associations have been computed. This means, the
``onFlush`` event has access to the sets of:
- Entities scheduled for insert
- Entities scheduled for update
- Entities scheduled for removal
- Collections scheduled for update
- Collections scheduled for removal
To make use of the onFlush event you have to be familiar with the
internal UnitOfWork API, which grants you access to the previously
To make use of the ``onFlush`` event you have to be familiar with the
internal :ref:`UnitOfWork<unit-of-work>` API, which grants you access to the previously
mentioned sets. See this example:
.. code-block:: php
@@ -622,11 +567,10 @@ mentioned sets. See this example:
}
}
The following restrictions apply to the onFlush event:
The following restrictions apply to the ``onFlush`` event:
- If you create and persist a new entity in ``onFlush``, then
calling ``EntityManager#persist()`` is not enough.
calling ``EntityManager::persist()`` is not enough.
You have to execute an additional call to
``$unitOfWork->computeChangeSet($classMetadata, $entity)``.
- Changing primitive fields or associations requires you to
@@ -634,11 +578,14 @@ 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
~~~~~~~~~
``postFlush`` is called at the end of ``EntityManager#flush()``.
``EntityManager#flush()`` can **NOT** be called safely inside its listeners.
``postFlush`` is called at the end of ``EntityManager::flush()``.
``EntityManager::flush()`` can **NOT** be called safely inside its listeners.
This event is not a lifecycle callback.
.. code-block:: php
@@ -654,26 +601,27 @@ postFlush
}
}
.. _reference-events-pre-update:
preUpdate
~~~~~~~~~
PreUpdate is the most restrictive to use event, since it is called
right before an update statement is called for an entity inside the
``EntityManager#flush()`` method. Note that this event is not
triggered when the computed changeset is empty.
PreUpdate is called inside the ``EntityManager::flush()`` method,
right before an SQL ``UPDATE`` statement. This event is not
triggered when the computed changeset is empty, nor for a DQL
``UPDATE`` statement.
Changes to associations of the updated entity are never allowed in
this event, since Doctrine cannot guarantee to correctly handle
referential integrity at this point of the flush operation. This
event has a powerful feature however, it is executed with a
``PreUpdateEventArgs`` instance, which contains a reference to the
`_PreUpdateEventArgs`_ instance, which contains a reference to the
computed change-set of this entity.
This means you have access to all the fields that have changed for
this entity with their old and new value. The following methods are
available on the ``PreUpdateEventArgs``:
- ``getEntity()`` to get access to the actual entity.
- ``getEntityChangeSet()`` to get a copy of the changeset array.
Changes to this returned array do not affect updating.
@@ -727,38 +675,74 @@ lifecycle callback when there are expensive validations to call:
Restrictions for this event:
- Changes to associations of the passed entities are not
recognized by the flush operation anymore.
- Changes to fields of the passed entities are not recognized by
the flush operation anymore, use the computed change-set passed to
the event to modify primitive field values, e.g. use
``$eventArgs->setNewValue($field, $value);`` as in the Alice to Bob example above.
- Any calls to ``EntityManager#persist()`` or
``EntityManager#remove()``, even in combination with the UnitOfWork
- Any calls to ``EntityManager::persist()`` or
``EntityManager::remove()``, even in combination with the ``UnitOfWork``
API are strongly discouraged and don't work as expected outside the
flush operation.
.. _reference-events-post-update-remove-persist:
postUpdate, postRemove, postPersist
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The three post events are called inside ``EntityManager#flush()``.
These three post* events are called inside ``EntityManager::flush()``.
Changes in here are not relevant to the persistence in the
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.
- The ``postUpdate`` event occurs after the database
update operations to entity data. It is not called for a DQL
``UPDATE`` statement.
- The ``postPersist`` event occurs for an entity after
the entity has been made persistent. It will be invoked after the
database insert operations. Generated primary key values are
available in the postPersist event.
- The ``postRemove`` event occurs for an entity after the
entity has been deleted. It will be invoked after the database
delete operations. It is not called for a DQL ``DELETE`` statement.
.. warning::
The ``postRemove`` event or any events triggered after an entity removal
can receive an uninitializable proxy in case you have configured an entity to
cascade remove relations. In this case, you should load yourself the proxy in
the associated ``pre*`` event.
.. _reference-events-post-load:
postLoad
~~~~~~~~
This event is called after an entity is constructed by the
EntityManager.
The postLoad event occurs after the entity has been loaded into the current
``EntityManager`` from the database or after ``refresh()`` has been applied to it.
.. warning::
When using ``Doctrine\ORM\AbstractQuery::toIterable()``, ``postLoad``
events will be executed immediately after objects are being hydrated, and therefore
associations are not guaranteed to be initialized. It is not safe to combine
usage of ``Doctrine\ORM\AbstractQuery::toIterable()`` and ``postLoad`` event
handlers.
.. _reference-events-on-clear:
onClear
~~~~~~~~
The ``onClear`` event occurs when the ``EntityManager::clear()`` operation is invoked,
after all references to entities have been removed from the unit of work.
This event is not a lifecycle callback.
Entity listeners
----------------
.. versionadded:: 2.4
An entity listener is a lifecycle listener class used for an entity.
- The entity listener's mapping may be applied to an entity class or mapped superclass.
@@ -766,7 +750,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;
@@ -900,7 +896,7 @@ you need to map the listener method using the event type mapping:
Entity listeners resolver
~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~
Doctrine invokes the listener resolver to get the listener instance.
- A resolver allows you register a specific entity listener instance.
@@ -962,22 +958,25 @@ Implementing your own resolver :
$configurations->setEntityListenerResolver(new MyEntityListenerResolver);
EntityManager::create(.., $configurations, ..);
.. _reference-events-load-class-metadata:
Load ClassMetadata Event
------------------------
When the mapping information for an entity is read, it is populated
in to a ``ClassMetadataInfo`` instance. You can hook in to this
process and manipulate the instance.
``loadClassMetadata`` - The ``loadClassMetadata`` event occurs after the
mapping metadata for a class has been loaded from a mapping source
(annotations/xml/yaml) in to a ``Doctrine\ORM\Mapping\ClassMetadata`` instance.
You can hook in to this process and manipulate the instance.
This event is not a lifecycle callback.
.. code-block:: php
<?php
$test = new TestEvent();
$metadataFactory = $em->getMetadataFactory();
$test = new TestEventListener();
$evm = $em->getEventManager();
$evm->addEventListener(Events::loadClassMetadata, $test);
$evm->addEventListener(Doctrine\ORM\Events::loadClassMetadata, $test);
class TestEvent
class TestEventListener
{
public function loadClassMetadata(\Doctrine\ORM\Event\LoadClassMetadataEventArgs $eventArgs)
{
@@ -991,4 +990,69 @@ process and manipulate the instance.
}
}
If not class metadata can be found, an ``onClassMetadataNotFound`` event is dispatched.
Manipulating the given event args instance
allows providing fallback metadata even when no actual metadata exists
or could be found. This event is not a lifecycle callback.
SchemaTool Events
-----------------
It is possible to access the schema metadata during schema changes that are happening in ``Doctrine\ORM\Tools\SchemaTool``.
There are two different events where you can hook in.
postGenerateSchemaTable
~~~~~~~~~~~~~~~~~~~~~~~
This event is fired for each ``Doctrine\DBAL\Schema\Table`` instance, after one was created and built up with the current class metadata
of an entity. It is possible to access to the current state of ``Doctrine\DBAL\Schema\Schema``, the current table schema
instance and class metadata.
.. code-block:: php
<?php
$test = new TestEventListener();
$evm = $em->getEventManager();
$evm->addEventListener(\Doctrine\ORM\Tools\ToolEvents::postGenerateSchemaTable, $test);
class TestEventListener
{
public function postGenerateSchemaTable(\Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs $eventArgs)
{
$classMetadata = $eventArgs->getClassMetadata();
$schema = $eventArgs->getSchema();
$table = $eventArgs->getClassTable();
}
}
postGenerateSchema
~~~~~~~~~~~~~~~~~~
This event is fired after the schema instance was successfully built and before SQL queries are generated from the
schema information of ``Doctrine\DBAL\Schema\Schema``. It allows to access the full object representation of the database schema
and the EntityManager.
.. code-block:: php
<?php
$test = new TestEventListener();
$evm = $em->getEventManager();
$evm->addEventListener(\Doctrine\ORM\Tools\ToolEvents::postGenerateSchema, $test);
class TestEventListener
{
public function postGenerateSchema(\Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs $eventArgs)
{
$schema = $eventArgs->getSchema();
$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

View File

@@ -52,7 +52,7 @@ or adding entities to a collection twice. You have to check for both conditions
in the code before calling ``$em->flush()`` if you know that unique constraint failures
can occur.
In `Symfony2 <http://www.symfony.com>`_ for example there is a Unique Entity Validator
In `Symfony2 <https://www.symfony.com>`_ for example there is a Unique Entity Validator
to achieve this task.
For collections you can check with ``$collection->contains($entity)`` if an entity is already
@@ -80,7 +80,7 @@ You can solve this exception by:
How can I filter an association?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Natively you can't filter associations in 2.0 and 2.1. You should use DQL queries to query for the filtered set of entities.
You should use DQL queries to query for the filtered set of entities.
I call clear() on a One-To-Many collection but the entities are not deleted
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -98,7 +98,7 @@ How can I add columns to a many-to-many table?
The many-to-many association is only supporting foreign keys in the table definition
To work with many-to-many tables containing extra columns you have to use the
foreign keys as primary keys feature of Doctrine introduced in version 2.1.
foreign keys as primary keys feature of Doctrine ORM.
See :doc:`the tutorial on composite primary keys for more information<../tutorials/composite-primary-keys>`.
@@ -112,8 +112,8 @@ over this collection using a LIMIT statement (or vendor equivalent).
Doctrine does not offer a solution for this out of the box but there are several extensions
that do:
* `DoctrineExtensions <http://github.com/beberlei/DoctrineExtensions>`_
* `Pagerfanta <http://github.com/whiteoctober/pagerfanta>`_
* `DoctrineExtensions <https://github.com/beberlei/DoctrineExtensions>`_
* `Pagerfanta <https://github.com/whiteoctober/pagerfanta>`_
Why does pagination not work correctly with fetch joins?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -128,10 +128,10 @@ See the previous question for a solution to this task.
Inheritance
-----------
Can I use Inheritance with Doctrine 2?
Can I use Inheritance with Doctrine ORM?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Yes, you can use Single- or Joined-Table Inheritance in Doctrine 2.
Yes, you can use Single- or Joined-Table Inheritance in ORM.
See the documentation chapter on :doc:`inheritance mapping <inheritance-mapping>` for
the details.

View File

@@ -1,9 +1,7 @@
Filters
=======
.. versionadded:: 2.2
Doctrine 2.2 features a filter system that allows the developer to add SQL to
Doctrine ORM features a filter system that allows the developer to add SQL to
the conditional clauses of queries, regardless the place where the SQL is
generated (e.g. from a DQL query, or by loading associated entities).
@@ -55,6 +53,9 @@ proper quoting of parameters.
}
}
If the parameter is an array and should be quoted as a list of values for an IN query
this is possible with the alternative ``SQLFilter#setParameterList()`` and
``SQLFilter#getParameterList()`` functions.
Configuration
-------------

View File

@@ -11,7 +11,7 @@ request and can greatly improve performance.
"If you care about performance and don't use a bytecode
cache then you don't really care about performance. Please get one
and start using it."
*Stas Malyshev, Core Contributor to PHP and Zend Employee*
@@ -20,13 +20,20 @@ Metadata and Query caches
As already mentioned earlier in the chapter about configuring
Doctrine, it is strongly discouraged to use Doctrine without a
Metadata and Query cache (preferably with APC or Memcache as the
cache driver). Operating Doctrine without these caches means
Metadata and Query cache.
Operating Doctrine without these caches means
Doctrine will need to load your mapping information on every single
request and has to parse each DQL query on every single request.
This is a waste of resources.
See :ref:`integrating-with-the-orm`
The preferred cache adapter for metadata and query caches is a PHP file
cache like Symfony's
`PHP files adapter <https://symfony.com/doc/current/components/cache/adapters/php_files_adapter.html>`_.
This kind of cache serializes cache items and writes them to a file.
This allows for opcode caching to be used and provides high performance in most scenarios.
See :ref:`types-of-caches`
Alternative Query Result Formats
--------------------------------
@@ -38,14 +45,36 @@ in scenarios where data is loaded for read-only purposes.
Read-Only Entities
------------------
Starting with Doctrine 2.1 you can mark entities as read only (See metadata mapping
references for details). This means that the entity marked as read only is never considered
for updates, which means when you call flush on the EntityManager these entities are skipped
even if properties changed. Read-Only allows to persist new entities of a kind and remove existing
ones, they are just not considered for updates.
You can mark entities as read only (See metadata mapping
references for details).
This means that the entity marked as read only is never considered for updates.
During flush on the EntityManager these entities are skipped even if properties
changed.
Read-Only allows to persist new entities of a kind and remove existing ones,
they are just not considered for updates.
See :ref:`annref_entity`
You can also explicitly mark individual entities read only directly on the
UnitOfWork via a call to ``markReadOnly()``:
.. code-block:: php
$user = $entityManager->find(User::class, $id);
$entityManager->getUnitOfWork()->markReadOnly($user);
Or you can set all objects that are the result of a query hydration to be
marked as read only with the following query hint:
.. code-block:: php
$query = $entityManager->createQuery('SELECT u FROM App\\Entity\\User u');
$query->setHint(Query::HINT_READ_ONLY, true);
$users = $query->getResult();
Extra-Lazy Collections
----------------------
@@ -70,4 +99,4 @@ See :doc:`Best Practices <reference/best-practices>`
Change Tracking policies
------------------------
See: :doc:`Change Tracking Policies <reference/change-tracking-policies>`
See: :doc:`Change Tracking Policies <change-tracking-policies>`

View File

@@ -31,24 +31,31 @@ Example:
.. code-block:: php
<?php
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\OneToOne;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\MappedSuperclass;
use Doctrine\ORM\Mapping\Entity;
/** @MappedSuperclass */
class MappedSuperclassBase
class Person
{
/** @Column(type="integer") */
protected $mapped1;
/** @Column(type="string") */
protected $mapped2;
/**
* @OneToOne(targetEntity="MappedSuperclassRelated1")
* @JoinColumn(name="related1_id", referencedColumnName="id")
* @OneToOne(targetEntity="Toothbrush")
* @JoinColumn(name="toothbrush_id", referencedColumnName="id")
*/
protected $mappedRelated1;
protected $toothbrush;
// ... more fields and methods
}
/** @Entity */
class EntitySubClass extends MappedSuperclassBase
class Employee extends Person
{
/** @Id @Column(type="integer") */
private $id;
@@ -58,6 +65,15 @@ Example:
// ... more fields and methods
}
/** @Entity */
class Toothbrush
{
/** @Id @Column(type="integer") */
private $id;
// ... more fields and methods
}
The DDL for the corresponding database schema would look something
like this (this is for SQLite):
@@ -73,7 +89,7 @@ defined on that class directly.
Single Table Inheritance
------------------------
`Single Table Inheritance <http://martinfowler.com/eaaCatalog/singleTableInheritance.html>`_
`Single Table Inheritance <https://martinfowler.com/eaaCatalog/singleTableInheritance.html>`_
is an inheritance mapping strategy where all classes of a hierarchy
are mapped to a single database table. In order to distinguish
which row represents which type in the hierarchy a so-called
@@ -181,11 +197,11 @@ the root entity of the single-table inheritance hierarchy.
Class Table Inheritance
-----------------------
`Class Table Inheritance <http://martinfowler.com/eaaCatalog/classTableInheritance.html>`_
`Class Table Inheritance <https://martinfowler.com/eaaCatalog/classTableInheritance.html>`_
is an inheritance mapping strategy where each class in a hierarchy
is mapped to several tables: its own table and the tables of all
parent classes. The table of a child class is linked to the table
of a parent class through a foreign key constraint. Doctrine 2
of a parent class through a foreign key constraint. Doctrine ORM
implements this strategy through the use of a discriminator column
in the topmost table of the hierarchy because this is the easiest
way to achieve polymorphic queries with Class Table Inheritance.
@@ -274,6 +290,9 @@ be a leaf entity in the inheritance hierarchy, (ie. have no subclasses).
Otherwise Doctrine *CANNOT* create proxy instances
of this entity and will *ALWAYS* load the entity eagerly.
There is also another important performance consideration that it is *NOT POSSIBLE*
to query for the base entity without any LEFT JOINs to the sub-types.
SQL Schema considerations
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -289,9 +308,15 @@ column and cascading on delete.
Overrides
---------
Used to override a mapping for an entity field or relationship.
May be applied to an entity that extends a mapped superclass
to override a relationship or field mapping defined by the mapped superclass.
Used to override a mapping for an entity field or relationship. Can only be
applied to an entity that extends a mapped superclass or uses a trait to
override a relationship or field mapping defined by the mapped superclass or
trait.
It is not possible to override attributes or associations in entity to entity
inheritance scenarios, because this can cause unforseen edge case behavior and
increases complexity in ORM internal classes.
Association Override
@@ -315,7 +340,7 @@ Example:
*/
class User
{
//other fields mapping
// other fields mapping
/**
* @ManyToMany(targetEntity="Group", inversedBy="users")
@@ -454,7 +479,7 @@ Things to note:
- This feature is available for all kind of associations. (OneToOne, OneToMany, ManyToOne, ManyToMany)
- The association type *CANNOT* be changed.
- The override could redefine the joinTables or joinColumns depending on the association type.
- The override could redefine inversedBy to reference more than one extended entity.
- The override could redefine ``inversedBy`` to reference more than one extended entity.
- The override could redefine fetch to modify the fetch strategy of the extended entity.
Attribute Override
@@ -584,7 +609,7 @@ Things to note:
- The "attribute override" specifies the overrides base on the property name.
- The column type *CANNOT* be changed. If the column type is not equal you get a ``MappingException``
- The override can redefine all the columns except the type.
- The override can redefine all the attributes except the type.
Query the Type
--------------

View File

@@ -6,7 +6,7 @@ Therefore we think it is very important to be honest about the
current limitations to our users. Much like every other piece of
software Doctrine2 is not perfect and far from feature complete.
This section should give you an overview of current limitations of
Doctrine 2 as well as critical known issues that you should know
Doctrine ORM as well as critical known issues that you should know
about.
Current Limitations
@@ -107,17 +107,17 @@ to the same entity.
Behaviors
~~~~~~~~~
Doctrine 2 will **never** include a behavior system like Doctrine 1
Doctrine ORM will **never** include a behavior system like Doctrine 1
in the core library. We don't think behaviors add more value than
they cost pain and debugging hell. Please see the many different
blog posts we have written on this topics:
- `Doctrine2 "Behaviors" in a Nutshell <http://www.doctrine-project.org/2010/02/17/doctrine2-behaviours-nutshell.html>`_
- `A re-usable Versionable behavior for Doctrine2 <http://www.doctrine-project.org/2010/02/24/doctrine2-versionable.html>`_
- `Write your own ORM on top of Doctrine2 <http://www.doctrine-project.org/2010/07/19/your-own-orm-doctrine2.html>`_
- `Doctrine 2 Behavioral Extensions <http://www.doctrine-project.org/2010/11/18/doctrine2-behavioral-extensions.html>`_
- `Doctrine2 "Behaviors" in a Nutshell <https://www.doctrine-project.org/2010/02/17/doctrine2-behaviours-nutshell.html>`_
- `A re-usable Versionable behavior for Doctrine2 <https://www.doctrine-project.org/2010/02/24/doctrine2-versionable.html>`_
- `Write your own ORM on top of Doctrine2 <https://www.doctrine-project.org/2010/07/19/your-own-orm-doctrine2.html>`_
- `Doctrine ORM Behavioral Extensions <https://www.doctrine-project.org/2010/11/18/doctrine2-behavioral-extensions.html>`_
Doctrine 2 has enough hooks and extension points so that **you** can
Doctrine ORM has enough hooks and extension points so that **you** can
add whatever you want on top of it. None of this will ever become
core functionality of Doctrine2 however, you will have to rely on
third party extensions for magical behaviors.
@@ -126,13 +126,13 @@ Nested Set
~~~~~~~~~~
NestedSet was offered as a behavior in Doctrine 1 and will not be
included in the core of Doctrine 2. However there are already two
included in the core of Doctrine ORM. However there are already two
extensions out there that offer support for Nested Set with
Doctrine 2:
ORM:
- `Doctrine2 Hierarchical-Structural Behavior <http://github.com/guilhermeblanco/Doctrine2-Hierarchical-Structural-Behavior>`_
- `Doctrine2 NestedSet <http://github.com/blt04/doctrine2-nestedset>`_
- `Doctrine2 Hierarchical-Structural Behavior <https://github.com/guilhermeblanco/Doctrine2-Hierarchical-Structural-Behavior>`_
- `Doctrine2 NestedSet <https://github.com/blt04/doctrine2-nestedset>`_
Known Issues
------------
@@ -149,9 +149,9 @@ Identifier Quoting and Legacy Databases
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For compatibility reasons between all the supported vendors and
edge case problems Doctrine 2 does **NOT** do automatic identifier
edge case problems Doctrine ORM does **NOT** do automatic identifier
quoting. This can lead to problems when trying to get
legacy-databases to work with Doctrine 2.
legacy-databases to work with Doctrine ORM.
- You can quote column-names as described in the

View File

@@ -14,6 +14,7 @@ metadata:
- **XML files** (XmlDriver)
- **Class DocBlock Annotations** (AnnotationDriver)
- **Attributes** (AttributeDriver)
- **YAML files** (YamlDriver)
- **PHP Code in files or static functions** (PhpDriver)
@@ -38,8 +39,9 @@ an entity.
$em->getConfiguration()->setMetadataCacheImpl(new ApcuCache());
If you want to use one of the included core metadata drivers you
just need to configure it. All the drivers are in the
If you want to use one of the included core metadata drivers you need to
configure it. If you pick the annotation driver, you will additionally
need to install ``doctrine/annotations``. All the drivers are in the
``Doctrine\ORM\Mapping\Driver`` namespace:
.. code-block:: php
@@ -147,7 +149,7 @@ ClassMetadata
-------------
The last piece you need to know and understand about metadata in
Doctrine 2 is the API of the ``ClassMetadata`` classes. You need to
Doctrine ORM is the API of the ``ClassMetadata`` classes. You need to
be familiar with them in order to implement your own drivers but
more importantly to retrieve mapping information for a certain
entity when needed.

View File

@@ -1,8 +1,6 @@
Implementing a NamingStrategy
==============================
.. versionadded:: 2.3
Using a naming strategy you can provide rules for generating database identifiers,
column or table names. This feature helps
reduce the verbosity of the mapping document, eliminating repetitive noise (eg: ``TABLE_``).

View File

@@ -71,7 +71,7 @@ with inheritance hierarchies.
use Doctrine\ORM\Query\ResultSetMappingBuilder;
$sql = "SELECT u.id, u.name, a.id AS address_id, a.street, a.city " .
$sql = "SELECT u.id, u.name, a.id AS address_id, a.street, a.city " .
"FROM users u INNER JOIN address a ON u.address_id = a.id";
$rsm = new ResultSetMappingBuilder($entityManager);
@@ -80,9 +80,7 @@ with inheritance hierarchies.
The builder extends the ``ResultSetMapping`` class and as such has all the functionality of it as well.
.. versionadded:: 2.4
Starting with Doctrine ORM 2.4 you can generate the ``SELECT`` clause
The ``SELECT`` clause can be generated
from a ``ResultSetMappingBuilder``. You can either cast the builder
object to ``(string)`` and the DQL aliases are used as SQL table aliases
or use the ``generateSelectClause($tableAliases)`` method and pass
@@ -267,7 +265,7 @@ detail:
<?php
/**
* Adds a meta column (foreign key or discriminator column) to the result set.
*
*
* @param string $alias
* @param string $columnAlias
* @param string $columnName
@@ -322,10 +320,10 @@ entity.
$rsm->addEntityResult('User', 'u');
$rsm->addFieldResult('u', 'id', 'id');
$rsm->addFieldResult('u', 'name', 'name');
$query = $this->_em->createNativeQuery('SELECT id, name FROM users WHERE name = ?', $rsm);
$query->setParameter(1, 'romanb');
$users = $query->getResult();
The result would look like this:
@@ -358,10 +356,10 @@ thus owns the foreign key.
$rsm->addFieldResult('u', 'id', 'id');
$rsm->addFieldResult('u', 'name', 'name');
$rsm->addMetaResult('u', 'address_id', 'address_id');
$query = $this->_em->createNativeQuery('SELECT id, name, address_id FROM users WHERE name = ?', $rsm);
$query->setParameter(1, 'romanb');
$users = $query->getResult();
Foreign keys are used by Doctrine for lazy-loading purposes when
@@ -387,12 +385,12 @@ associations that are lazy.
$rsm->addFieldResult('a', 'address_id', 'id');
$rsm->addFieldResult('a', 'street', 'street');
$rsm->addFieldResult('a', 'city', 'city');
$sql = 'SELECT u.id, u.name, a.id AS address_id, a.street, a.city FROM users u ' .
'INNER JOIN address a ON u.address_id = a.id WHERE u.name = ?';
$query = $this->_em->createNativeQuery($sql, $rsm);
$query->setParameter(1, 'romanb');
$users = $query->getResult();
In this case the nested entity ``Address`` is registered with the
@@ -422,10 +420,10 @@ to map the hierarchy (both use a discriminator column).
$rsm->addFieldResult('u', 'name', 'name');
$rsm->addMetaResult('u', 'discr', 'discr'); // discriminator column
$rsm->setDiscriminatorColumn('u', 'discr');
$query = $this->_em->createNativeQuery('SELECT id, name, discr FROM users WHERE name = ?', $rsm);
$query->setParameter(1, 'romanb');
$users = $query->getResult();
Note that in the case of Class Table Inheritance, an example as
@@ -437,6 +435,10 @@ strategy but with native SQL it is your responsibility.
Named Native Query
------------------
.. note::
Named Native Queries are deprecated as of version 2.9 and will be removed in ORM 3.0
You can also map a native query using a named native query mapping.
To achieve that, you must describe the SQL resultset structure
@@ -791,7 +793,7 @@ followed by a dot ("."), followed by the name or the field or property of the pr
6:
name: address.country
column: a_country
If you retrieve a single entity and if you use the default mapping,

View File

@@ -1,6 +1,14 @@
Partial Objects
===============
.. note::
Creating Partial Objects through DQL is deprecated and
will be removed in the future, use data transfer object
support in DQL instead. (`Details
<https://github.com/doctrine/orm/issues/8471>`_)
A partial object is an object whose state is not fully initialized
after being reconstituted from the database and that is
disconnected from the rest of its data. The following section will

View File

@@ -1,7 +1,7 @@
PHP Mapping
===========
Doctrine 2 also allows you to provide the ORM metadata in the form
Doctrine ORM also allows you to provide the ORM metadata in the form
of plain PHP code using the ``ClassMetadata`` API. You can write
the code in PHP files or inside of a static function named
``loadMetadata($class)`` on the entity class itself.
@@ -9,6 +9,11 @@ the code in PHP files or inside of a static function named
PHP Files
---------
.. note::
PHPDriver is deprecated and will be removed in 3.0, use StaticPHPDriver
instead.
If you wish to write your mapping information inside PHP files that
are named after the entity and included to populate the metadata
for an entity you can do so by using the ``PHPDriver``:

View File

@@ -13,7 +13,7 @@ as you want, or just pick a preferred one.
The ``QueryBuilder`` is not an abstraction of DQL, but merely a tool to dynamically build it.
You should still use plain DQL when you can, as it is simpler and more readable.
More about this in the :doc:`FAQ <faq>`_.
More about this in the :doc:`FAQ <faq>`.
Constructing a new QueryBuilder object
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -252,8 +252,8 @@ while the named placeholders start with a : followed by a string.
Calling ``setParameter()`` automatically infers which type you are setting as
value. This works for integers, arrays of strings/integers, DateTime instances
and for managed entities. If you want to set a type explicitly you can call
the third argument to ``setParameter()`` explicitly. It accepts either a PDO
type or a DBAL Type name for conversion.
the third argument to ``setParameter()`` explicitly. It accepts either a DBAL
Doctrine\DBAL\ParameterType::* or a DBAL Type name for conversion.
.. note::
@@ -277,10 +277,17 @@ following syntax:
.. code-block:: php
<?php
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Query\Parameter;
// $qb instanceof QueryBuilder
// Query here...
$qb->setParameters(array(1 => 'value for ?1', 2 => 'value for ?2'));
$qb->setParameters(new ArrayCollection([
new Parameter('1', 'value for ?1'),
new Parameter('2', 'value for ?2')
]));
Getting already bound parameters is easy - simply use the above
mentioned syntax with "getParameter()" or "getParameters()":
@@ -354,6 +361,7 @@ a querybuilder instance into a Query object:
// Execute Query
$result = $query->getResult();
$iterableResult = $query->toIterable();
$single = $query->getSingleResult();
$array = $query->getArrayResult();
$scalar = $query->getScalarResult();
@@ -512,6 +520,9 @@ complete list of supported helper methods available:
// Example - $qb->expr()->sqrt('u.currentBalance')
public function sqrt($x); // Returns Expr\Func
// Example - $qb->expr()->mod('u.currentBalance', '10')
public function mod($x); // Returns Expr\Func
// Example - $qb->expr()->count('u.firstname')
public function count($x); // Returns Expr\Func
@@ -532,7 +543,7 @@ using ``addCriteria``:
// ...
$criteria = Criteria::create()
->orderBy(['firstName', 'ASC']);
->orderBy(['firstName' => Criteria::ASC]);
// $qb instanceof QueryBuilder
$qb->addCriteria($criteria);

View File

@@ -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
@@ -77,11 +77,10 @@ A query region might be something like :
Cache Regions
-------------
``Doctrine\ORM\Cache\Region\DefaultRegion`` It's the default implementation.
``Doctrine\ORM\Cache\Region\DefaultRegion`` is the default implementation.
A simplest cache region compatible with all doctrine-cache drivers but does not support locking.
``Doctrine\ORM\Cache\Region`` and ``Doctrine\ORM\Cache\ConcurrentRegion``
Defines contracts that should be implemented by a cache provider.
define contracts that should be implemented by a cache provider.
It allows you to provide your own cache implementation that might take advantage of specific cache driver.
@@ -91,13 +90,8 @@ If you want to support locking for ``READ_WRITE`` strategies you should implemen
Cache region
~~~~~~~~~~~~
Defines a contract for accessing a particular 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>`_.
``Doctrine\ORM\Cache\Region`` defines a contract for accessing a particular
cache region.
Concurrent cache region
~~~~~~~~~~~~~~~~~~~~~~~
@@ -107,11 +101,7 @@ By default, Doctrine provides a very simple implementation based on file locks `
If you want to use an ``READ_WRITE`` cache, you should consider providing your own cache region.
``Doctrine\ORM\Cache\ConcurrentRegion``
Defines contract for concurrently managed data region.
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/ConcurrentRegion.html>`_.
``Doctrine\ORM\Cache\ConcurrentRegion`` defines a contract for concurrently managed data region.
Timestamp region
~~~~~~~~~~~~~~~~
@@ -120,8 +110,6 @@ Timestamp region
Tracks the timestamps of the most recent updates to particular entity.
`See API Doc <http://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/TimestampRegion.html>`_.
.. _reference-second-level-cache-mode:
Caching mode
@@ -138,7 +126,7 @@ Caching mode
* Read Write Cache doesnt employ any locks but can do reads, inserts, updates and deletes.
* Good if the application needs to update data rarely.
* ``READ_WRITE``
@@ -153,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
-------------
@@ -177,16 +165,17 @@ Doctrine allows you to specify configurations and some points of extension for t
Enable Second Level Cache
~~~~~~~~~~~~~~~~~~~~~~~~~
To enable the second-level-cache, you should provide a cache factory
``\Doctrine\ORM\Cache\DefaultCacheFactory`` is the default implementation.
To enable the second-level-cache, you should provide a cache factory.
``Doctrine\ORM\Cache\DefaultCacheFactory`` is the default implementation.
.. code-block:: php
<?php
/* @var $config \Doctrine\ORM\Cache\RegionsConfiguration */
/* @var $cache \Doctrine\Common\Cache\Cache */
/** @var \Doctrine\ORM\Cache\RegionsConfiguration $cacheConfig */
/** @var \Psr\Cache\CacheItemPoolInterface $cache */
/** @var \Doctrine\ORM\Configuration $config */
$factory = new \Doctrine\ORM\Cache\DefaultCacheFactory($config, $cache);
$factory = new \Doctrine\ORM\Cache\DefaultCacheFactory($cacheConfig, $cache);
// Enable second-level-cache
$config->setSecondLevelCacheEnabled();
@@ -201,15 +190,18 @@ 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`` Store and retrieve query cache results.
* ``CachedEntityPersister`` Store and retrieve entity results.
* ``CachedCollectionPersister`` Store and retrieve query results.
* ``EntityHydrator`` Transform an entity into a cache entry and cache entry into entities
* ``CollectionHydrator`` Transform a collection into a cache entry and cache entry into collection
`See API Doc <http://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/DefaultCacheFactory.html>`_.
``QueryCache``
stores and retrieves query cache results.
``CachedEntityPersister``
stores and retrieves entity results.
``CachedCollectionPersister``
stores and retrieves query results.
``EntityHydrator``
transforms entities into a cache entries and cache entries into entities
``CollectionHydrator``
transforms collections into cache entries and cache entries into collections
Region Lifetime
~~~~~~~~~~~~~~~
@@ -219,26 +211,27 @@ To specify a default lifetime for all regions or specify a different lifetime fo
.. code-block:: php
<?php
/* @var $config \Doctrine\ORM\Configuration */
/* @var $cacheConfig \Doctrine\ORM\Cache\CacheConfiguration */
/** @var \Doctrine\ORM\Configuration $config */
/** @var \Doctrine\ORM\Cache\CacheConfiguration $cacheConfig */
/** @var \Doctrine\ORM\Cache\RegionsConfiguration $regionConfig */
$cacheConfig = $config->getSecondLevelCacheConfiguration();
$regionConfig = $cacheConfig->getRegionsConfiguration();
// Cache Region lifetime
$regionConfig->setLifetime('my_entity_region', 3600); // Time to live for a specific region; In seconds
$regionConfig->setDefaultLifetime(7200); // Default time to live; In seconds
$regionConfig->setLifetime('my_entity_region', 3600); // Time to live for a specific region (in seconds)
$regionConfig->setDefaultLifetime(7200); // Default time to live (in seconds)
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
@@ -267,18 +260,19 @@ By providing a cache logger you should be able to get information about all cach
// Get the total number of cached entries *not* found in all regions.
$logger->getMissCount();
If you want to get more information you should implement ``\Doctrine\ORM\Cache\Logging\CacheLogger``.
and collect all information you want.
`See API Doc <http://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/Logging/CacheLogger.html>`_.
If you want to get more information you should implement
``Doctrine\ORM\Cache\Logging\CacheLogger`` and collect
all the information you want.
Entity cache definition
-----------------------
* Entity cache configuration allows you to define the caching strategy and region for an entity.
* ``usage`` Specifies the caching strategy: ``READ_ONLY``, ``NONSTRICT_READ_WRITE``, ``READ_WRITE``. see :ref:`reference-second-level-cache-mode`
* ``region`` Optional value that specifies the name of the second level cache region.
* ``usage`` specifies the caching strategy: ``READ_ONLY``,
``NONSTRICT_READ_WRITE``, ``READ_WRITE``.
See :ref:`reference-second-level-cache-mode`.
* ``region`` is an optional value that specifies the name of the second
level cache region.
.. configuration-block::
@@ -310,7 +304,7 @@ Entity cache definition
.. code-block:: xml
<?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">
<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="Country">
<cache usage="READ_ONLY" region="my_entity_region" />
<id name="id" type="integer" column="id">
@@ -325,8 +319,8 @@ Entity cache definition
Country:
type: entity
cache:
usage : READ_ONLY
region : my_entity_region
usage: READ_ONLY
region: my_entity_region
id:
id:
type: integer
@@ -386,7 +380,7 @@ It caches the primary keys of association and cache each element will be cached
.. code-block:: xml
<?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">
<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="State">
<cache usage="NONSTRICT_READ_WRITE" />
@@ -396,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" />
@@ -416,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
@@ -434,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
~~~~~~~~~~~
@@ -461,8 +456,8 @@ Basic entity cache
$country1 = $em->find('Country', 1); // Retrieve item from cache
$country->setName("New Name");
$em->persist($country);
$country1->setName('New Name');
$em->flush(); // Hit database to update the row and update cache
$em->clear(); // Clear entity manager
@@ -487,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();
@@ -538,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')
@@ -565,21 +560,22 @@ 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();
.. note::
The the default query cache mode is ```Cache::MODE_NORMAL```
The default query cache mode is ```Cache::MODE_NORMAL```
DELETE / UPDATE queries
~~~~~~~~~~~~~~~~~~~~~~~
DQL UPDATE / DELETE statements are ported directly into a database and bypass the second-level cache,
DQL UPDATE / DELETE statements are ported directly into a database and bypass
the second-level cache.
Entities that are already cached will NOT be invalidated.
However the cached data could be evicted using the cache API or an special query hint.
@@ -591,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();
@@ -622,7 +618,7 @@ Using the repository query cache
--------------------------------
As well as ``Query Cache`` all persister queries store only identifier values for an individual query.
All persister use a single timestamps cache region keeps track of the last update for each persister,
All persisters use a single timestamp cache region to keep track of the last update for each persister,
When a query is loaded from cache, the timestamp region is checked for the last update for that persister.
Using the last update timestamps as part of the query key invalidate the cache key when an update occurs.
@@ -641,7 +637,7 @@ Using the last update timestamps as part of the query key invalidate the cache k
$em->clear();
// Reload from database.
// At this point the query cache key if not logger valid, the select goes straight
// At this point the query cache key is no longer valid, the select goes straight to the database
$entities = $em->getRepository('Entity\Country')->findAll();
Cache API
@@ -653,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
@@ -698,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
@@ -728,4 +724,5 @@ Paginator
~~~~~~~~~
Count queries generated by ``Doctrine\ORM\Tools\Pagination\Paginator`` are not cached by second-level cache.
Although entities and query result are cached count queries will hit the database every time.
Although entities and query result are cached, count queries will hit the
database every time.

View File

@@ -10,7 +10,7 @@ we cannot protect you from SQL injection.
Please also read the documentation chapter on Security in Doctrine DBAL. This
page only handles Security issues in the ORM.
- `DBAL Security Page <http://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/security.html>`
- `DBAL Security Page <https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/security.html>`
If you find a Security bug in Doctrine, please report it on Jira and change the
Security Level to "Security Issues". It will be visible to Doctrine Core

View File

@@ -5,7 +5,7 @@ Doctrine Console
----------------
The Doctrine Console is a Command Line Interface tool for simplifying common
administration tasks during the development of a project that uses Doctrine 2.
administration tasks during the development of a project that uses ORM.
Take a look at the :doc:`Installation and Configuration <configuration>`
chapter for more information how to setup the console command.
@@ -27,64 +27,34 @@ Configuration
~~~~~~~~~~~~~
Whenever the ``doctrine`` command line tool is invoked, it can
access all Commands that were registered by developer. There is no
access all Commands that were registered by a developer. There is no
auto-detection mechanism at work. The Doctrine binary
already registers all the commands that currently ship with
Doctrine DBAL and ORM. If you want to use additional commands you
have to register them yourself.
All the commands of the Doctrine Console require access to the ``EntityManager``
or ``DBAL`` Connection. You have to inject them into the console application
using so called Helper-Sets. This requires either the ``db``
or the ``em`` helpers to be defined in order to work correctly.
All the commands of the Doctrine Console require access to the
``EntityManager``. You have to inject it into the console application with
``ConsoleRunner::createHelperSet``. Whenever you invoke the Doctrine
binary, it searches the current directory for the file ``cli-config.php``.
This file contains the project-specific configuration.
Whenever you invoke the Doctrine binary the current folder is searched for a
``cli-config.php`` file. This file contains the project specific configuration:
Here is an example of a the project-specific ``cli-config.php``:
.. code-block:: php
<?php
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($conn)
));
$cli->setHelperSet($helperSet);
use Doctrine\ORM\Tools\Console\ConsoleRunner;
When dealing with the ORM package, the EntityManagerHelper is
required:
// replace this with the path to your own project bootstrap file.
require_once 'bootstrap.php';
.. code-block:: php
// replace with mechanism to retrieve EntityManager in your app
$entityManager = GetEntityManager();
<?php
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));
$cli->setHelperSet($helperSet);
return ConsoleRunner::createHelperSet($entityManager);
The HelperSet instance has to be generated in a separate file (i.e.
``cli-config.php``) that contains typical Doctrine bootstrap code
and predefines the needed HelperSet attributes mentioned above. A
sample ``cli-config.php`` file looks as follows:
.. code-block:: php
<?php
// cli-config.php
require_once 'my_bootstrap.php';
// Any way to access the EntityManager from your application
$em = GetMyEntityManager();
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));
It is important to define a correct HelperSet that Doctrine binary
script will ultimately use. The Doctrine Binary will automatically
find the first instance of HelperSet in the global variable
namespace and use this.
.. note::
.. note::
You have to adjust this snippet for your specific application or framework
and use their facilities to access the Doctrine EntityManager and
@@ -375,7 +345,7 @@ First you need to retrieve the metadata instances with the
$em->getConnection()->getSchemaManager()
)
);
$cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);
$metadata = $cmf->getAllMetadata();
@@ -412,7 +382,7 @@ You can also reverse engineer a database using the
Runtime vs Development Mapping Validation
-----------------------------------------
For performance reasons Doctrine 2 has to skip some of the
For performance reasons Doctrine ORM has to skip some of the
necessary validation of metadata mappings. You have to execute
this validation in your development workflow to verify the
associations are correctly defined.
@@ -517,4 +487,3 @@ HelperSet, like it is described in the configuration section.
// Runs console application
$cli->run();

View File

@@ -16,13 +16,13 @@ transaction. Without any explicit transaction demarcation from your
side, this quickly results in poor performance because transactions
are not cheap.
For the most part, Doctrine 2 already takes care of proper
For the most part, Doctrine ORM already takes care of proper
transaction demarcation for you: All the write operations
(INSERT/UPDATE/DELETE) are queued until ``EntityManager#flush()``
is invoked which wraps all of these changes in a single
transaction.
However, Doctrine 2 also allows (and encourages) you to take over
However, Doctrine ORM also allows (and encourages) you to take over
and control transaction demarcation yourself.
These are two ways to deal with transactions when using the
@@ -68,7 +68,7 @@ looks like this:
// $em instanceof EntityManager
$em->getConnection()->beginTransaction(); // suspend auto-commit
try {
//... do some work
// ... do some work
$user = new User;
$user->setName('George');
$em->persist($user);
@@ -98,7 +98,7 @@ functionally equivalent to the previously shown code looks as follows:
<?php
// $em instanceof EntityManager
$em->transactional(function($em) {
//... do some work
// ... do some work
$user = new User;
$user->setName('George');
$em->persist($user);
@@ -154,7 +154,7 @@ occurred you should do that with a new ``EntityManager``.
Locking Support
---------------
Doctrine 2 offers support for Pessimistic- and Optimistic-locking
Doctrine ORM offers support for Pessimistic- and Optimistic-locking
strategies natively. This allows to take very fine-grained control
over what kind of locking is required for your Entities in your
application.
@@ -367,7 +367,7 @@ And the change headline action (POST Request):
Pessimistic Locking
~~~~~~~~~~~~~~~~~~~
Doctrine 2 supports Pessimistic Locking at the database level. No
Doctrine ORM supports Pessimistic Locking at the database level. No
attempt is being made to implement pessimistic locking inside
Doctrine, rather vendor-specific and ANSI-SQL commands are used to
acquire row-level locks. Every Entity can be part of a pessimistic
@@ -376,11 +376,11 @@ lock, there is no special metadata required to use this feature.
However for Pessimistic Locking to work you have to disable the
Auto-Commit Mode of your Database and start a transaction around
your pessimistic lock use-case using the "Approach 2: Explicit
Transaction Demarcation" described above. Doctrine 2 will throw an
Transaction Demarcation" described above. Doctrine ORM will throw an
Exception if you attempt to acquire an pessimistic lock and no
transaction is running.
Doctrine 2 currently supports two pessimistic lock modes:
Doctrine ORM currently supports two pessimistic lock modes:
- Pessimistic Write

View File

@@ -16,11 +16,11 @@ Bidirectional Associations
The following rules apply to **bidirectional** associations:
- The inverse side has to have the ``mappedBy`` attribute of the OneToOne,
OneToMany, or ManyToMany mapping declaration. The mappedBy
OneToMany, or ManyToMany mapping declaration. The ``mappedBy``
attribute contains the name of the association-field on the owning side.
- The owning side has to have the ``inversedBy`` attribute of the
OneToOne, ManyToOne, or ManyToMany mapping declaration.
The inversedBy attribute contains the name of the association-field
OneToOne, ManyToOne, or ManyToMany mapping declaration.
The ``inversedBy`` attribute contains the name of the association-field
on the inverse-side.
- ManyToOne is always the owning side of a bidirectional association.
- OneToMany is always the inverse side of a bidirectional association.

View File

@@ -134,6 +134,10 @@ optimize the performance of the Flush Operation:
explicit strategies of notifying the UnitOfWork what objects/properties
changed.
.. note::
Flush only a single entity with ``$entityManager->flush($entity)`` is deprecated and will be removed in ORM 3.0.
(`Details <https://github.com/doctrine/orm/issues/8459>`_)
Query Internals
---------------

View File

@@ -291,7 +291,7 @@ example that encapsulate much of the association management code:
<?php
class User
{
//...
// ...
public function markCommentRead(Comment $comment) {
// Collections implement ArrayAccess
$this->commentsRead[] = $comment;
@@ -407,7 +407,7 @@ There are two approaches to handle this problem in your code:
Transitive persistence / Cascade Operations
-------------------------------------------
Doctrine 2 provides a mechanism for transitive persistence through cascading of certain operations.
Doctrine ORM provides a mechanism for transitive persistence through cascading of certain operations.
Each association to another entity or a collection of
entities can be configured to automatically cascade the following operations to the associated entities:
``persist``, ``remove``, ``merge``, ``detach``, ``refresh`` or ``all``.
@@ -463,14 +463,14 @@ If you then set up the cascading to the ``User#commentsAuthored`` property...
<?php
class User
{
//...
// ...
/**
* Bidirectional - One-To-Many (INVERSE SIDE)
*
* @OneToMany(targetEntity="Comment", mappedBy="author", cascade={"persist", "remove"})
*/
private $commentsAuthored;
//...
// ...
}
...you can now create a user and an associated comment like this:
@@ -521,6 +521,8 @@ For each cascade operation that gets activated, Doctrine also
applies that operation to the association, be it single or
collection valued.
.. _persistence-by-reachability:
Persistence by Reachability: Cascade Persist
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -27,7 +27,7 @@ Work that have not yet been persisted are lost.
.. note::
Doctrine does NEVER touch the public API of methods in your entity
Doctrine NEVER touches the public API of methods in your entity
classes (like getters and setters) nor the constructor method.
Instead, it uses reflection to get/set data from/to your entity objects.
When Doctrine fetches data from DB and saves it back,
@@ -48,12 +48,12 @@ headline "Hello World" with the ID 1234:
<?php
$article = $entityManager->find('CMS\Article', 1234);
$article->setHeadline('Hello World dude!');
$article2 = $entityManager->find('CMS\Article', 1234);
echo $article2->getHeadline();
In this case the Article is accessed from the entity manager twice,
but modified in between. Doctrine 2 realizes this and will only
but modified in between. Doctrine ORM realizes this and will only
ever give you access to one instance of the Article with ID 1234,
no matter how often do you retrieve it from the EntityManager and
even no matter what kind of Query method you are using (find,
@@ -100,25 +100,25 @@ from newly opened EntityManager.
{
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
/** @Column(type="string") */
private $headline;
/** @ManyToOne(targetEntity="User") */
private $author;
/** @OneToMany(targetEntity="Comment", mappedBy="article") */
private $comments;
public function __construct()
{
$this->comments = new ArrayCollection();
}
public function getAuthor() { return $this->author; }
public function getComments() { return $this->comments; }
}
$article = $em->find('Article', 1);
This code only retrieves the ``Article`` instance with id 1 executing
@@ -139,22 +139,22 @@ your code. See the following code:
<?php
$article = $em->find('Article', 1);
// accessing a method of the user instance triggers the lazy-load
echo "Author: " . $article->getAuthor()->getName() . "\n";
// Lazy Loading Proxies pass instanceof tests:
if ($article->getAuthor() instanceof User) {
// a User Proxy is a generated "UserProxy" class
}
// accessing the comments as an iterator triggers the lazy-load
// retrieving ALL the comments of this article from the database
// using a single SELECT statement
foreach ($article->getComments() as $comment) {
echo $comment->getText() . "\n\n";
}
// Article::$comments passes instanceof tests for the Collection interface
// But it will NOT pass for the ArrayCollection interface
if ($article->getComments() instanceof \Doctrine\Common\Collections\Collection) {
@@ -174,7 +174,7 @@ methods along the lines of the ``getName()`` method shown below:
{
// lazy loading code
}
public function getName()
{
$this->_load();
@@ -250,6 +250,12 @@ as follows:
- If X is a detached entity, an exception will be thrown on
flush.
.. caution::
Do not pass detached entities to the persist operation. The persist operation always
considers entities that are not yet known to the ``EntityManager`` as new entities
(refer to the ``STATE_NEW`` constant inside the ``UnitOfWork``).
Removing entities
-----------------
@@ -269,7 +275,7 @@ which means that its persistent state will be deleted once
for and appear in query and collection results. See
the section on :ref:`Database and UnitOfWork Out-Of-Sync <workingobjects_database_uow_outofsync>`
for more information.
Example:
@@ -312,7 +318,7 @@ Deleting an object with all its associated objects can be achieved
in multiple ways with very different performance impacts.
1. If an association is marked as ``CASCADE=REMOVE`` Doctrine 2
1. If an association is marked as ``CASCADE=REMOVE`` Doctrine ORM
will fetch this association. If its a Single association it will
pass this entity to
``EntityManager#remove()``. If the association is a collection, Doctrine will loop over all its elements and pass them to``EntityManager#remove()``.
@@ -332,7 +338,7 @@ in multiple ways with very different performance impacts.
.. note::
Calling ``remove`` on an entity will remove the object from the identiy
Calling ``remove`` on an entity will remove the object from the identity
map and therefore detach it. Querying the same entity again, for example
via a lazy loaded relation, will return a new object.
@@ -382,8 +388,7 @@ automatically without invoking the ``detach`` method:
currently managed by the EntityManager instance become detached.
- When serializing an entity. The entity retrieved upon subsequent
unserialization will be detached (This is the case for all entities
that are serialized and stored in some cache, i.e. when using the
Query Result Cache).
that are serialized and stored in some cache).
The ``detach`` operation is usually not as frequently needed and
used as ``persist`` and ``remove``.
@@ -647,7 +652,7 @@ just created via the "new" operator).
Querying
--------
Doctrine 2 provides the following ways, in increasing level of
Doctrine ORM provides the following ways, in increasing level of
power and flexibility, to query for persistent objects. You should
always start with the simplest one that suits your needs.
@@ -694,13 +699,13 @@ methods on a repository as follows:
<?php
// $em instanceof EntityManager
// All users that are 20 years old
$users = $em->getRepository('MyProject\Domain\User')->findBy(array('age' => 20));
// All users that are 20 years old and have a surname of 'Miller'
$users = $em->getRepository('MyProject\Domain\User')->findBy(array('age' => 20, 'surname' => 'Miller'));
// A single user by its nickname
$user = $em->getRepository('MyProject\Domain\User')->findOneBy(array('nickname' => 'romanb'));
@@ -736,7 +741,7 @@ examples are equivalent:
<?php
// A single user by its nickname
$user = $em->getRepository('MyProject\Domain\User')->findOneBy(array('nickname' => 'romanb'));
// A single user by its nickname (__call magic)
$user = $em->getRepository('MyProject\Domain\User')->findOneByNickname('romanb');
@@ -751,8 +756,6 @@ Additionally, you can just count the result of the provided conditions when you
By Criteria
~~~~~~~~~~~
.. versionadded:: 2.3
The Repository implement the ``Doctrine\Common\Collections\Selectable``
interface. That means you can build ``Doctrine\Common\Collections\Criteria``
and pass them to the ``matching($criteria)`` method.
@@ -794,7 +797,7 @@ A DQL query is represented by an instance of the
<?php
// $em instanceof EntityManager
// All users with an age between 20 and 30 (inclusive).
$q = $em->createQuery("select u from MyDomain\Model\User u where u.age >= 20 and u.age <= 30");
$users = $q->getResult();
@@ -839,18 +842,18 @@ in a central location.
<?php
namespace MyDomain\Model;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="MyDomain\Model\UserRepository")
*/
class User
{
}
class UserRepository extends EntityRepository
{
public function getAllAdminUsers()
@@ -866,7 +869,7 @@ You can access your repository now by calling:
<?php
// $em instanceof EntityManager
$admins = $em->getRepository('MyDomain\Model\User')->getAllAdminUsers();

View File

@@ -8,9 +8,7 @@ The XML driver is backed by an XML Schema document that describes
the structure of a mapping document. The most recent version of the
XML Schema document is available online at
`https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd <https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd>`_.
In order to point to the latest version of the document of a
particular stable release branch, just append the release number,
i.e.: doctrine-mapping-2.0.xsd The most convenient way to work with
The most convenient way to work with
XML mapping files is to use an IDE/editor that can provide
code-completion based on such an XML Schema document. The following
is an outline of a XML mapping document with the proper xmlns/xsi
@@ -18,9 +16,9 @@ setup for the latest code in trunk.
.. code-block:: xml
<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
<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">
...
@@ -104,9 +102,9 @@ of several common elements:
// Doctrine.Tests.ORM.Mapping.User.dcm.xml
<?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
<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="Doctrine\Tests\ORM\Mapping\User" table="cms_users">
@@ -208,10 +206,10 @@ Optional attributes:
- **inheritance-type** - The type of inheritance, defaults to none. A
more detailed description follows in the
*Defining Inheritance Mappings* section.
- **read-only** - (>= 2.1) Specifies that this entity is marked as read only and not
- **read-only** - Specifies that this entity is marked as read only and not
considered for change-tracking. Entities of this type can be persisted
and removed though.
- **schema** - (>= 2.5) The schema the table lies in, for platforms that support schemas
- **schema** - The schema the table lies in, for platforms that support schemas
Defining Fields
~~~~~~~~~~~~~~~
@@ -258,6 +256,11 @@ Optional attributes:
table? Defaults to false.
- nullable - Should this field allow NULL as a value? Defaults to
false.
- insertable - Should this field be inserted? Defaults to true.
- updatable - Should this field be updated? Defaults to true.
- generated - Enum of the values ALWAYS, INSERT, NEVER that determines if
generated value must be fetched from database after INSERT or UPDATE.
Defaults to "NEVER".
- version - Should this field be used for optimistic locking? Only
works on fields with type integer or datetime.
- scale - Scale of a decimal type.
@@ -293,7 +296,7 @@ Defining Identity and Generator Strategies
An entity has to have at least one ``<id />`` element. For
composite keys you can specify more than one id-element, however
surrogate keys are recommended for use with Doctrine 2. The Id
surrogate keys are recommended for use with Doctrine ORM. The Id
field allows to define properties of the identifier and allows a
subset of the ``<field />`` element attributes:
@@ -691,6 +694,7 @@ specified by their respective tags:
- ``<cascade-merge />``
- ``<cascade-remove />``
- ``<cascade-refresh />``
- ``<cascade-detach />``
Join Column Element
~~~~~~~~~~~~~~~~~~~
@@ -765,9 +769,9 @@ entity relationship. You can define this in XML with the "association-key" attri
.. code-block:: xml
<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
<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="Application\Model\ArticleAttribute">

View File

@@ -41,9 +41,10 @@
reference/native-sql
reference/change-tracking-policies
reference/partial-objects
reference/annotations-reference
reference/attributes-reference
reference/xml-mapping
reference/yaml-mapping
reference/annotations-reference
reference/php-mapping
reference/caching
reference/improving-performance

View File

@@ -43,9 +43,10 @@ Reference Guide
reference/native-sql
reference/change-tracking-policies
reference/partial-objects
reference/annotations-reference
reference/attributes-reference
reference/xml-mapping
reference/yaml-mapping
reference/annotations-reference
reference/php-mapping
reference/caching
reference/improving-performance

View File

@@ -1,11 +1,9 @@
Composite and Foreign Keys as Primary Key
=========================================
.. versionadded:: 2.1
Doctrine 2 supports composite primary keys natively. Composite keys are a very powerful relational database concept
and we took good care to make sure Doctrine 2 supports as many of the composite primary key use-cases.
For Doctrine 2.0 composite keys of primitive data-types are supported, for Doctrine 2.1 even foreign keys as
Doctrine ORM supports composite primary keys natively. Composite keys are a very powerful relational database concept
and we took good care to make sure Doctrine ORM supports as many of the composite primary key use-cases.
For Doctrine ORM composite keys of primitive data-types are supported, even foreign keys as
primary keys are supported.
This tutorial shows how the semantics of composite primary keys work and how they map to the database.
@@ -19,7 +17,7 @@ the ID fields have to have their values set before you call ``EntityManager#pers
Primitive Types only
~~~~~~~~~~~~~~~~~~~~
Even in version 2.0 you can have composite keys as long as they only consist of the primitive types
You can have composite keys as long as they only consist of the primitive types
``integer`` and ``string``. Suppose you want to create a database of cars and use the model-name
and year of production as primary keys:
@@ -60,9 +58,9 @@ and year of production as primary keys:
.. code-block:: xml
<?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
<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="VehicleCatalogue\Model\Car">
@@ -120,10 +118,6 @@ and to ``year`` to the related entities.
Identity through foreign Entities
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. note::
Identity through foreign entities is only supported with Doctrine 2.1
There are tons of use-cases where the identity of an Entity should be determined by the entity
of one or many parent entities.
@@ -200,9 +194,9 @@ We keep up the example of an Article with arbitrary attributes, the mapping look
.. code-block:: xml
<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
<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="Application\Model\ArticleAttribute">
@@ -308,7 +302,7 @@ of products purchased and maybe even the current price.
private $items;
/** @Column(type="boolean") */
private $payed = false;
private $paid = false;
/** @Column(type="boolean") */
private $shipped = false;
/** @Column(type="datetime") */

View File

@@ -5,19 +5,19 @@ Extra Lazy Associations
In many cases associations between entities can get pretty large. Even in a simple scenario like a blog.
where posts can be commented, you always have to assume that a post draws hundreds of comments.
In Doctrine 2.0 if you accessed an association it would always get loaded completely into memory. This
In Doctrine ORM if you accessed an association it would always get loaded completely into memory. This
can lead to pretty serious performance problems, if your associations contain several hundreds or thousands
of entities.
With Doctrine 2.1 a feature called **Extra Lazy** is introduced for associations. Associations
Doctrine ORM includes a feature called **Extra Lazy** for associations. Associations
are marked as **Lazy** by default, which means the whole collection object for an association is populated
the first time its accessed. If you mark an association as extra lazy the following methods on collections
can be called without triggering a full load of the collection:
- ``Collection#contains($entity)``
- ``Collection#containsKey($key)`` (available with Doctrine 2.5)
- ``Collection#containsKey($key)``
- ``Collection#count()``
- ``Collection#get($key)`` (available with Doctrine 2.4)
- ``Collection#get($key)``
- ``Collection#slice($offset, $length = null)``
For each of the above methods the following semantics apply:
@@ -25,7 +25,7 @@ For each of the above methods the following semantics apply:
- For each call, if the Collection is not yet loaded, issue a straight SELECT statement against the database.
- For each call, if the collection is already loaded, fallback to the default functionality for lazy collections. No additional SELECT statements are executed.
Additionally even with Doctrine 2.0 the following methods do not trigger the collection load:
Additionally even with Doctrine ORM the following methods do not trigger the collection load:
- ``Collection#add($entity)``
- ``Collection#offsetSet($key, $entity)`` - ArrayAccess with no specific key ``$coll[] = $entity``, it does
@@ -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.
@@ -71,9 +71,9 @@ switch to extra lazy as shown in these examples:
.. code-block:: xml
<?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
<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="Doctrine\Tests\Models\CMS\CmsGroup">

View File

@@ -20,8 +20,7 @@ development is said to use the *Database First* approach to Doctrine.
In this workflow you would modify the database schema first and then
regenerate the PHP code to use with this schema. You need a flexible
code-generator for this task and up to Doctrine 2.2, the code generator hasn't
been flexible enough to achieve this.
code-generator for this task.
We spinned off a subproject, Doctrine CodeGenerator, that will fill this gap and
allow you to do *Database First* development.

View File

@@ -23,15 +23,10 @@ installed:
The code of this tutorial is `available on Github <https://github.com/doctrine/doctrine2-orm-tutorial>`_.
.. note::
This tutorial assumes you work with **Doctrine 2.6** and above.
Some of the code will not work with lower versions.
What is Doctrine?
-----------------
Doctrine 2 is an `object-relational mapper (ORM) <https://en.wikipedia.org/wiki/Object-relational_mapping>`_
Doctrine ORM is an `object-relational mapper (ORM) <https://en.wikipedia.org/wiki/Object-relational_mapping>`_
for PHP 7.1+ that provides transparent persistence for PHP objects. It uses the Data Mapper
pattern at the heart, aiming for a complete separation of your domain/business
logic from the persistence in a relational database management system.
@@ -86,8 +81,11 @@ that directory with the following contents:
{
"require": {
"doctrine/orm": "^2.6.2",
"symfony/yaml": "2.*"
"doctrine/orm": "^2.11.0",
"doctrine/dbal": "^3.2",
"doctrine/annotations": "1.13.2",
"symfony/yaml": "^5.4",
"symfony/cache": "^5.4"
},
"autoload": {
"psr-0": {"": "src/"}
@@ -116,6 +114,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
---------------------------
@@ -123,7 +129,7 @@ Obtaining the EntityManager
Doctrine's public interface is through the ``EntityManager``. This class
provides access points to the complete lifecycle management for your entities,
and transforms entities from and back to persistence. You have to
configure and create it to use your entities with Doctrine 2. I
configure and create it to use your entities with Doctrine ORM. I
will show the configuration steps and then discuss them step by
step:
@@ -133,9 +139,9 @@ step:
// bootstrap.php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
require_once "vendor/autoload.php";
// Create a simple "default" Doctrine ORM configuration for Annotations
$isDevMode = true;
$proxyDir = null;
@@ -143,15 +149,15 @@ step:
$useSimpleAnnotationReader = false;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode, $proxyDir, $cache, $useSimpleAnnotationReader);
// or if you prefer yaml or XML
//$config = Setup::createXMLMetadataConfiguration(array(__DIR__."/config/xml"), $isDevMode);
//$config = Setup::createYAMLMetadataConfiguration(array(__DIR__."/config/yaml"), $isDevMode);
// $config = Setup::createXMLMetadataConfiguration(array(__DIR__."/config/xml"), $isDevMode);
// $config = Setup::createYAMLMetadataConfiguration(array(__DIR__."/config/yaml"), $isDevMode);
// database configuration parameters
$conn = array(
'driver' => 'pdo_sqlite',
'path' => __DIR__ . '/db.sqlite',
);
// obtaining the entity manager
$entityManager = EntityManager::create($conn, $config);
@@ -193,7 +199,7 @@ defined entity classes and their metadata. For this tool to work, a
<?php
// cli-config.php
require_once "bootstrap.php";
return \Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet($entityManager);
Now call the Doctrine command-line tool:
@@ -240,44 +246,246 @@ entity definition:
/**
* @var int
*/
protected $id;
private $id;
/**
* @var string
*/
protected $name;
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
private $name;
}
When creating entity classes, all of the fields should be ``protected`` or ``private``
(not ``public``), with getter and setter methods for each one (except ``$id``).
The use of mutators allows Doctrine to hook into calls which
manipulate the entities in ways that it could not if you just
directly set the values with ``entity#field = foo;``
When creating entity classes, all of the fields should be ``private``.
Use ``protected`` when strictly needed and very rarely if not ever ``public``.
Adding behavior to Entities
~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are two options to define methods in entities:
**getters/setters**, or **mutators and DTOs**,
respectively for **anemic entities** or **rich entities**.
**Anemic entities: Getters and setters**
The most popular method is to create two kinds of methods to
**read** (getter) and **update** (setter) the object's properties.
The id field has no setter since, generally speaking, your code
should not set this value since it represents a database id value.
(Note that Doctrine itself can still set the value using the
Reflection API instead of a defined setter function.)
The next step for persistence with Doctrine is to describe the
structure of the ``Product`` entity to Doctrine using a metadata
language. The metadata language describes how entities, their
properties and references should be persisted and what constraints
should be applied to them.
.. note::
Doctrine ORM does not use any of the methods you defined: it uses
reflection to read and write values to your objects, and will never
call methods, not even ``__construct``.
This approach is mostly used when you want to focus on behavior-less
entities, and when you want to have all your business logic in your
services rather than in the objects themselves.
Getters and setters are a common convention which makes it possible to
expose each field of your entity to the external world, while allowing
you to keep some type safety in place.
Such an approach is a good choice for RAD (rapid application development),
but may lead to problems later down the road, because providing such an
easy way to modify any field in your entity means that the entity itself
cannot guarantee validity of its internal state. Having any object in
invalid state is dangerous:
- An invalid state can bring bugs in your business logic.
- The state can be implicitly saved in the database: any forgotten ``flush``
can persist the broken state.
- If persisted, the corrupted data will be retrieved later in your application
when the data is loaded again, thereby leading to bugs in your business logic.
- When bugs occur after corrupted data is persisted, troubleshooting will
become much harder, and you might be aware of the bug too late to fix it in a
proper manner.
implicitly saved in database, thereby leading to corrupted or inconsistent
data in your storage, and later in your application when the data is loaded again.
.. note::
This method, although very common, is inappropriate for Domain Driven
Design (`DDD <https://en.wikipedia.org/wiki/Domain-driven_design>`)
where methods should represent real business operations and not simple
property change, And business invariants should be maintained both in the
application state (entities in this case) and in the database, with no
space for data corruption.
Here is an example of a simple **anemic entity**:
.. configuration-block::
.. code-block:: php
<?php
class User
{
private $username;
private $passwordHash;
private $bans;
public function getUsername(): string
{
return $this->username;
}
public function setUsername(string $username): void
{
$this->username = $username;
}
public function getPasswordHash(): string
{
return $this->passwordHash;
}
public function setPasswordHash(string $passwordHash): void
{
$this->passwordHash = $passwordHash;
}
public function getBans(): array
{
return $this->bans;
}
public function addBan(Ban $ban): void
{
$this->bans[] = $ban;
}
}
In the example above, we avoid all possible logic in the entity and only care
about putting and retrieving data into it without validation (except the one
provided by type-hints) nor consideration about the object's state.
As Doctrine ORM is a persistence tool for your domain, the state of an object is
really important. This is why we strongly recommend using rich entities.
**Rich entities: Mutators and DTOs**
We recommend using a rich entity design and rely on more complex mutators,
and if needed based on DTOs.
In this design, you should **not** use getters nor setters, and instead,
implement methods that represent the **behavior** of your domain.
For example, when having a ``User`` entity, we could foresee
the following kind of optimization.
Example of a rich entity with proper accessors and mutators:
.. configuration-block::
.. code-block:: php
<?php
class User
{
private $banned;
private $username;
private $passwordHash;
private $bans;
public function toNickname(): string
{
return $this->username;
}
public function authenticate(string $password, callable $checkHash): bool
{
return $checkHash($password, $this->passwordHash) && ! $this->hasActiveBans();
}
public function changePassword(string $password, callable $hash): void
{
$this->passwordHash = $hash($password);
}
public function ban(\DateInterval $duration): void
{
assert($duration->invert !== 1);
$this->bans[] = new Ban($this);
}
}
.. note::
Please note that this example is only a stub. When going further in the
documentation, we will update this object with more behavior and maybe
update some methods.
The entities should only mutate state after checking that all business logic
invariants are being respected.
Additionally, our entities should never see their state change without
validation. For example, creating a ``new Product()`` object without any data
makes it an **invalid object**.
Rich entities should represent **behavior**, not **data**, therefore
they should be valid even after a ``__construct()`` call.
To help creating such objects, we can rely on ``DTOs``, and/or make
our entities always up-to-date. This can be performed with static constructors,
or rich mutators that accept ``DTOs`` as parameters.
The role of the ``DTO`` is to maintain the entity's state and to help us rely
upon objects that correctly represent the data that is used to mutate the
entity.
.. note::
A `DTO <https://en.wikipedia.org/wiki/Data_transfer_object>` is an object
that only carries data without any logic. Its only goal is to be transferred
from one service to another.
A ``DTO`` often represents data sent by a client and that has to be validated,
but can also be used as simple data carrier for other cases.
By using ``DTOs``, if we take our previous ``User`` example, we could create
a ``ProfileEditingForm`` DTO that will be a plain model, totally unrelated to
our database, that will be populated via a form and validated.
Then we can add a new mutator to our ``User``:
.. configuration-block::
.. code-block:: php
<?php
class User
{
public function updateFromProfile(ProfileEditingDTO $profileFormDTO): void
{
// ...
}
public static function createFromRegistration(UserRegistrationDTO $registrationDTO): self
{
// ...
}
}
There are several advantages to using such a model:
* **Entity state is always valid.** Since no setters exist, this means that we
only update portions of the entity that should already be valid.
* Instead of having plain getters and setters, our entity now has
**real behavior**: it is much easier to determine the logic in the domain.
* DTOs can be reused in other components, for example deserializing mixed
content, using forms...
* Classic and static constructors can be used to manage different ways to
create our objects, and they can also use DTOs.
* Anemic entities tend to isolate the entity from logic, whereas rich
entities allow putting the logic in the object itself, including data
validation.
The next step for persistence with Doctrine is to describe the structure of
the ``Product`` entity to Doctrine using a metadata language. The metadata
language describes how entities, their properties and references should be
persisted and what constraints should be applied to them.
Metadata for an Entity can be configured using DocBlock annotations directly
in the Entity class itself, or in an external XML or YAML file. This Getting
@@ -299,16 +507,16 @@ but you only need to choose one.
*/
class Product
{
/**
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\Column(type="string")
private $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
private $name;
// .. (other code)
}
@@ -316,9 +524,9 @@ but you only need to choose one.
.. code-block:: xml
<!-- config/xml/Product.dcm.xml -->
<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
<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="Product" table="products">
@@ -444,7 +652,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
@@ -488,6 +696,7 @@ classes. We'll store them in ``src/Bug.php`` and ``src/User.php``, respectively.
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="bugs")
*/
class Bug
@@ -498,25 +707,25 @@ classes. We'll store them in ``src/Bug.php`` and ``src/User.php``, respectively.
* @ORM\GeneratedValue
* @var int
*/
protected $id;
private $id;
/**
* @ORM\Column(type="string")
* @var string
*/
protected $description;
private $description;
/**
* @ORM\Column(type="datetime")
* @var DateTime
*/
protected $created;
private $created;
/**
* @ORM\Column(type="string")
* @var string
*/
protected $status;
private $status;
public function getId()
{
@@ -562,7 +771,7 @@ classes. We'll store them in ``src/Bug.php`` and ``src/User.php``, respectively.
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Entity
* @ORM\Table(name="users")
*/
class User
@@ -573,13 +782,13 @@ classes. We'll store them in ``src/Bug.php`` and ``src/User.php``, respectively.
* @ORM\Column(type="integer")
* @var int
*/
protected $id;
private $id;
/**
* @ORM\Column(type="string")
* @var string
*/
protected $name;
private $name;
public function getId()
{
@@ -610,7 +819,7 @@ foreign keys through their own identities.
For every foreign key you either have a Doctrine ManyToOne or OneToOne
association. On the inverse sides of these foreign keys you can have
OneToMany associations. Obviously you can have ManyToMany associations
that connect two tables with each other through a join table with
that connect two tables with each other through a join table with
two foreign keys.
Now that you know the basics about references in Doctrine, we can extend the
@@ -626,7 +835,7 @@ domain model to match the requirements:
{
// ... (previous code)
protected $products;
private $products;
public function __construct()
{
@@ -644,8 +853,8 @@ domain model to match the requirements:
{
// ... (previous code)
protected $reportedBugs;
protected $assignedBugs;
private $reportedBugs;
private $assignedBugs;
public function __construct()
{
@@ -666,12 +875,12 @@ domain model to match the requirements:
Lazy load proxies always contain an instance of
Doctrine's EntityManager and all its dependencies. Therefore a
var\_dump() will possibly dump a very large recursive structure
``var_dump()`` will possibly dump a very large recursive structure
which is impossible to render and read. You have to use
``Doctrine\Common\Util\Debug::dump()`` to restrict the dumping to a
human readable level. Additionally you should be aware that dumping
the EntityManager to a Browser may take several minutes, and the
Debug::dump() method just ignores any occurrences of it in Proxy
``Debug::dump()`` method just ignores any occurrences of it in Proxy
instances.
Because we only work with collections for the references we must be
@@ -679,8 +888,8 @@ careful to implement a bidirectional reference in the domain model.
The concept of owning or inverse side of a relation is central to
this notion and should always be kept in mind. The following
assumptions are made about relations and have to be followed to be
able to work with Doctrine 2. These assumptions are not unique to
Doctrine 2 but are best practices in handling database relations
able to work with Doctrine ORM. These assumptions are not unique to
Doctrine ORM but are best practices in handling database relations
and Object-Relational Mapping.
- In a one-to-one relation, the entity holding the foreign key of
@@ -720,8 +929,8 @@ the bi-directional reference:
{
// ... (previous code)
protected $engineer;
protected $reporter;
private $engineer;
private $reporter;
public function setEngineer(User $engineer)
{
@@ -754,8 +963,8 @@ the bi-directional reference:
{
// ... (previous code)
protected $reportedBugs;
protected $assignedBugs;
private $reportedBugs;
private $assignedBugs;
public function addReportedBug(Bug $bug)
{
@@ -806,7 +1015,7 @@ the database that points from Bugs to Products.
{
// ... (previous code)
protected $products;
private $products;
public function assignToProduct(Product $product)
{
@@ -832,47 +1041,47 @@ the ``Product`` before:
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Entity
* @ORM\Table(name="bugs")
*/
class Bug
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;
private $id;
/**
* @ORM\Column(type="string")
*/
protected $description;
private $description;
/**
* @ORM\Column(type="datetime")
*/
protected $created;
private $created;
/**
* @ORM\Column(type="string")
*/
protected $status;
private $status;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="assignedBugs")
*/
protected $engineer;
private $engineer;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="reportedBugs")
*/
protected $reporter;
private $reporter;
/**
* @ORM\ManyToMany(targetEntity="Product")
*/
protected $products;
private $products;
// ... (other code)
}
@@ -880,9 +1089,9 @@ the ``Product`` before:
.. code-block:: xml
<!-- config/xml/Bug.dcm.xml -->
<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
<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="Bug" table="bugs">
@@ -936,8 +1145,8 @@ the ``Product`` before:
Here we have the entity, id and primitive type definitions.
For the "created" field we have used the ``datetime`` type,
which translates the YYYY-mm-dd HH:mm:ss database format
For the "created" field we have used the ``datetime`` type,
which translates the YYYY-mm-dd HH:mm:ss database format
into a PHP DateTime instance and back.
After the field definitions, the two qualified references to the
@@ -975,30 +1184,30 @@ Finally, we'll add metadata mappings for the ``User`` entity.
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @var int
*/
protected $id;
private $id;
/**
* @ORM\Column(type="string")
* @var string
*/
protected $name;
private $name;
/**
* @ORM\OneToMany(targetEntity="Bug", mappedBy="reporter")
* @var Bug[] An ArrayCollection of Bug objects.
*/
protected $reportedBugs;
private $reportedBugs;
/**
* @ORM\OneToMany(targetEntity="Bug", mappedBy="engineer")
* @var Bug[] An ArrayCollection of Bug objects.
*/
protected $assignedBugs;
private $assignedBugs;
// .. (other code)
}
@@ -1006,9 +1215,9 @@ Finally, we'll add metadata mappings for the ``User`` entity.
.. code-block:: xml
<!-- config/xml/User.dcm.xml -->
<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
<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" table="users">
@@ -1135,7 +1344,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.
@@ -1192,9 +1401,9 @@ The console output of this script is then:
use-case. Don't we use an ORM to get rid of all the endless
hand-writing of SQL? Doctrine introduces DQL which is best
described as **object-query-language** and is a dialect of
`OQL <http://en.wikipedia.org/wiki/Object_Query_Language>`_ and
`OQL <https://en.wikipedia.org/wiki/Object_Query_Language>`_ and
similar to `HQL <http://www.hibernate.org>`_ or
`JPQL <http://en.wikipedia.org/wiki/Java_Persistence_Query_Language>`_.
`JPQL <https://en.wikipedia.org/wiki/Java_Persistence_Query_Language>`_.
It does not know the concept of columns and tables, but only those
of Entity-Class and property. Using the Metadata we defined before
it allows for very short distinctive and powerful queries.
@@ -1215,10 +1424,10 @@ The console output of this script is then:
As a last resort you can still use Native SQL and a description of the
result set to retrieve entities from the database. DQL boils down to a
Native SQL statement and a ``ResultSetMapping`` instance itself. Using
Native SQL you could even use stored procedures for data retrieval, or
make use of advanced non-portable database queries like PostgreSql's
result set to retrieve entities from the database. DQL boils down to a
Native SQL statement and a ``ResultSetMapping`` instance itself. Using
Native SQL you could even use stored procedures for data retrieval, or
make use of advanced non-portable database queries like PostgreSql's
recursive queries.
@@ -1231,7 +1440,7 @@ objects only from Doctrine however. For a simple list view like the
previous one we only need read access to our entities and can
switch the hydration from objects to simple PHP arrays instead.
Hydration can be an expensive process so only retrieving what you need can
Hydration can be an expensive process so only retrieving what you need can
yield considerable performance benefits for read-only requests.
Implementing the same list view as before using array hydration we
@@ -1448,7 +1657,7 @@ Entity Repositories
For now we have not discussed how to separate the Doctrine query logic from your model.
In Doctrine 1 there was the concept of ``Doctrine_Table`` instances for this
separation. The similar concept in Doctrine2 is called Entity Repositories, integrating
the `repository pattern <http://martinfowler.com/eaaCatalog/repository.html>`_ at the heart of Doctrine.
the `repository pattern <https://martinfowler.com/eaaCatalog/repository.html>`_ at the heart of Doctrine.
Every Entity uses a default repository by default and offers a bunch of convenience
methods that you can use to query for instances of that Entity. Take for example
@@ -1544,14 +1753,14 @@ we have to adjust the metadata slightly.
**/
class Bug
{
//...
// ...
}
.. code-block:: xml
<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
<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="Bug" table="bugs" repository-class="BugRepository">

View File

@@ -1,9 +1,7 @@
Pagination
==========
.. versionadded:: 2.2
Starting with version 2.2 Doctrine ships with a Paginator for DQL queries. It
Doctrine ORM ships with a Paginator for DQL queries. It
has a very simple API and implements the SPL interfaces ``Countable`` and
``IteratorAggregate``.
@@ -41,3 +39,7 @@ collection. You can disable this behavior by setting the
``$fetchJoinCollection`` flag to ``false``; in that case only 2 instead of the 3 queries
described are executed. We hope to automate the detection for this in
the future.
.. note::
``$fetchJoinCollection`` flag set to ``true`` might affect results if you use aggregations in your query.

View File

@@ -1,13 +1,9 @@
Working with Indexed Associations
=================================
.. note::
This feature is available from version 2.1 of Doctrine.
Doctrine 2 collections are modelled after PHPs native arrays. PHP arrays are an ordered hashmap, but in
Doctrine ORM collections are modelled after PHPs native arrays. PHP arrays are an ordered hashmap, but in
the first version of Doctrine keys retrieved from the database were always numerical unless ``INDEX BY``
was used. Starting with Doctrine 2.1 you can index your collections by a value in the related entity.
was used. You can index your collections by a value in the related entity.
This is a first step towards full ordered hashmap support through the Doctrine ORM.
The feature works like an implicit ``INDEX BY`` for the selected association but has several
downsides also:
@@ -104,9 +100,9 @@ The code and mappings for the Market entity looks like this:
.. code-block:: xml
<?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
<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="Doctrine\Tests\Models\StockExchange\Market">
@@ -190,9 +186,9 @@ here are the code and mappings for it:
.. code-block:: xml
<?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
<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="Doctrine\Tests\Models\StockExchange\Stock">
@@ -291,6 +287,5 @@ Outlook into the Future
~~~~~~~~~~~~~~~~~~~~~~~
For the inverse side of a many-to-many associations there will be a way to persist the keys and the order
as a third and fourth parameter into the join table. This feature is discussed in `DDC-213 <http://www.doctrine-project.org/jira/browse/DDC-213>`_
as a third and fourth parameter into the join table. This feature is discussed in `#2817 <https://github.com/doctrine/orm/issues/2817>`_
This feature cannot be implemented for one-to-many associations, because they are never the owning side.

View File

@@ -14,25 +14,25 @@
<xs:element name="doctrine-mapping">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<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:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
</xs:element>
<xs:complexType name="emptyType">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="cascade-type">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="cascade-all" type="orm:emptyType" minOccurs="0"/>
<xs:element name="cascade-persist" type="orm:emptyType" minOccurs="0"/>
<xs:element name="cascade-merge" type="orm:emptyType" minOccurs="0"/>
@@ -40,7 +40,7 @@
<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:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
@@ -66,19 +66,19 @@
</xs:simpleType>
<xs:complexType name="lifecycle-callback">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</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:sequence>
<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:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
@@ -96,34 +96,34 @@
</xs:complexType>
<xs:complexType name="named-native-query">
<xs:sequence>
<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:sequence>
</xs:choice>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="result-class" type="orm:fqcn" />
<xs:attribute name="result-set-mapping" type="xs:string" />
</xs:complexType>
<xs:complexType name="named-native-queries">
<xs:sequence>
<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:sequence>
</xs:choice>
</xs:complexType>
<xs:complexType name="entity-listener">
<xs:sequence>
<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:sequence>
</xs:choice>
<xs:attribute name="class" type="orm:fqcn"/>
</xs:complexType>
<xs:complexType name="entity-listeners">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="entity-listener" type="orm:entity-listener" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:choice>
</xs:complexType>
<xs:complexType name="column-result">
@@ -136,29 +136,29 @@
</xs:complexType>
<xs:complexType name="entity-result">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="field-result" type="orm:field-result" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:choice>
<xs:attribute name="entity-class" type="orm:fqcn" use="required" />
<xs:attribute name="discriminator-column" type="xs:string" use="optional" />
</xs:complexType>
<xs:complexType name="sql-result-set-mapping">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="entity-result" type="orm:entity-result"/>
<xs:element name="column-result" type="orm:column-result"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:choice>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:choice>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="sql-result-set-mappings">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="sql-result-set-mapping" type="orm:sql-result-set-mapping" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:choice>
</xs:complexType>
<xs:complexType name="cache">
@@ -208,28 +208,28 @@
</xs:simpleType>
<xs:complexType name="option" mixed="true">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="option" type="orm:option"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:choice>
<xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="options">
<xs:sequence>
<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:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="mapped-superclass" >
<xs:complexContent>
<xs:extension base="orm:entity">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:extension>
</xs:complexContent>
@@ -238,9 +238,9 @@
<xs:complexType name="embeddable">
<xs:complexContent>
<xs:extension base="orm:entity">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:choice>
</xs:extension>
</xs:complexContent>
</xs:complexType>
@@ -264,7 +264,6 @@
<xs:simpleType name="generator-strategy">
<xs:restriction base="xs:token">
<xs:enumeration value="NONE"/>
<xs:enumeration value="TABLE"/>
<xs:enumeration value="SEQUENCE"/>
<xs:enumeration value="IDENTITY"/>
<xs:enumeration value="AUTO"/>
@@ -289,17 +288,29 @@
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="generated-type">
<xs:restriction base="xs:token">
<xs:enumeration value="NEVER"/>
<xs:enumeration value="INSERT"/>
<xs:enumeration value="ALWAYS"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="field">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="options" type="orm:options" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</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" />
<xs:attribute name="insertable" type="xs:boolean" default="true" />
<xs:attribute name="updatable" type="xs:boolean" default="true" />
<xs:attribute name="generated" type="orm:generated-type" default="NEVER" />
<xs:attribute name="enum-type" type="xs:string" />
<xs:attribute name="version" type="xs:boolean" />
<xs:attribute name="column-definition" type="xs:string" />
<xs:attribute name="precision" type="xs:integer" use="optional" />
@@ -308,16 +319,19 @@
</xs:complexType>
<xs:complexType name="embedded">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="class" type="orm:fqcn" use="required" />
<xs:attribute name="class" type="orm:fqcn" use="optional" />
<xs:attribute name="column-prefix" type="xs:string" use="optional" />
<xs:attribute name="use-column-prefix" type="xs:boolean" default="true" use="optional" />
</xs:complexType>
<xs:complexType name="discriminator-column">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</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" />
@@ -327,78 +341,80 @@
</xs:complexType>
<xs:complexType name="unique-constraint">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="options" type="orm:options" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</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:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="unique-constraints">
<xs:sequence>
<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:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="index">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="options" type="orm:options" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</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:sequence>
<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:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="discriminator-mapping">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</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:sequence>
<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:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="generator">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:choice>
<xs:attribute name="strategy" type="orm:generator-strategy" use="optional" default="AUTO" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="id">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="generator" type="orm:generator" minOccurs="0" />
<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:sequence>
</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" />
@@ -406,9 +422,9 @@
</xs:complexType>
<xs:complexType name="sequence-generator">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</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" />
@@ -416,9 +432,9 @@
</xs:complexType>
<xs:complexType name="custom-id-generator">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:choice>
<xs:attribute name="class" type="orm:fqcn" use="required" />
</xs:complexType>
@@ -430,17 +446,17 @@
</xs:simpleType>
<xs:complexType name="inverse-join-columns">
<xs:sequence>
<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:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="join-column">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:choice>
<xs:attribute name="name" type="xs:NMTOKEN" use="optional" />
<xs:attribute name="referenced-column-name" type="xs:NMTOKEN" use="optional" default="id" />
<xs:attribute name="unique" type="xs:boolean" default="false" />
@@ -451,36 +467,36 @@
</xs:complexType>
<xs:complexType name="join-columns">
<xs:sequence>
<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:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="join-table">
<xs:sequence>
<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:sequence>
</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:sequence>
<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:sequence>
</xs:choice>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="order-by-field">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</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"/>
@@ -493,14 +509,20 @@
</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:sequence>
<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:sequence>
</xs:choice>
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="target-entity" type="xs:string" use="required" />
<xs:attribute name="mapped-by" type="xs:NMTOKEN" />
@@ -512,12 +534,12 @@
</xs:complexType>
<xs:complexType name="one-to-many">
<xs:sequence>
<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="order-by" type="orm:order-by" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:choice>
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="target-entity" type="xs:string" use="required" />
<xs:attribute name="mapped-by" type="xs:NMTOKEN" use="required" />
@@ -528,7 +550,7 @@
</xs:complexType>
<xs:complexType name="many-to-one">
<xs:sequence>
<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:choice minOccurs="0" maxOccurs="1">
@@ -537,16 +559,16 @@
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:choice>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:choice>
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="target-entity" type="xs:string" 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">
<xs:sequence>
<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:choice minOccurs="0" maxOccurs="1">
@@ -555,9 +577,9 @@
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:choice>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:choice>
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="target-entity" type="xs:string" use="required" />
<xs:attribute name="target-entity" type="xs:string" />
<xs:attribute name="mapped-by" type="xs:NMTOKEN" />
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
@@ -566,19 +588,19 @@
</xs:complexType>
<xs:complexType name="association-overrides">
<xs:sequence>
<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:sequence>
</xs:choice>
</xs:complexType>
<xs:complexType name="association-override">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<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:sequence>
</xs:choice>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="fetch" type="orm:fetch-type" use="optional" />
</xs:complexType>
@@ -588,30 +610,32 @@
</xs:complexType>
<xs:complexType name="attribute-overrides">
<xs:sequence>
<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:sequence>
</xs:choice>
</xs:complexType>
<xs:complexType name="attribute-override">
<xs:sequence>
<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:sequence>
</xs:choice>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
</xs:complexType>
<xs:complexType name="attribute-override-field">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="options" type="orm:options" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</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" />
<xs:attribute name="insertable" type="xs:boolean" default="true" />
<xs:attribute name="updateable" type="xs:boolean" default="true" />
<xs:attribute name="version" type="xs:boolean" />
<xs:attribute name="column-definition" type="xs:string" />
<xs:attribute name="precision" type="xs:integer" use="optional" />

File diff suppressed because it is too large Load Diff

View File

@@ -1,63 +1,47 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
declare(strict_types=1);
namespace Doctrine\ORM;
use Doctrine\ORM\Cache\QueryCache;
use Doctrine\ORM\Cache\Region;
/**
* Provides an API for querying/managing the second level cache regions.
*
* @since 2.5
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
interface Cache
{
const DEFAULT_QUERY_REGION_NAME = 'query_cache_region';
public const DEFAULT_QUERY_REGION_NAME = 'query_cache_region';
const DEFAULT_TIMESTAMP_REGION_NAME = 'timestamp_cache_region';
public const DEFAULT_TIMESTAMP_REGION_NAME = 'timestamp_cache_region';
/**
* May read items from the cache, but will not add items.
*/
const MODE_GET = 1;
public const MODE_GET = 1;
/**
* Will never read items from the cache,
* but will add items to the cache as it reads them from the database.
*/
const MODE_PUT = 2;
public const MODE_PUT = 2;
/**
* May read items from the cache, and add items to the cache.
*/
const MODE_NORMAL = 3;
public const MODE_NORMAL = 3;
/**
* The query will never read items from the cache,
* but will refresh items to the cache as it reads them from the database.
*/
const MODE_REFRESH = 4;
public const MODE_REFRESH = 4;
/**
* @param string $className The entity class.
*
* @return \Doctrine\ORM\Cache\Region|null
* @return Region|null
*/
public function getEntityCacheRegion($className);
@@ -65,7 +49,7 @@ interface Cache
* @param string $className The entity class.
* @param string $association The field name that represents the association.
*
* @return \Doctrine\ORM\Cache\Region|null
* @return Region|null
*/
public function getCollectionCacheRegion($className, $association);
@@ -75,7 +59,7 @@ interface Cache
* @param string $className The entity class.
* @param mixed $identifier The entity identifier
*
* @return boolean true if the underlying cache contains corresponding data; false otherwise.
* @return bool true if the underlying cache contains corresponding data; false otherwise.
*/
public function containsEntity($className, $identifier);
@@ -112,7 +96,7 @@ interface Cache
* @param string $association The field name that represents the association.
* @param mixed $ownerIdentifier The identifier of the owning entity.
*
* @return boolean true if the underlying cache contains corresponding data; false otherwise.
* @return bool true if the underlying cache contains corresponding data; false otherwise.
*/
public function containsCollection($className, $association, $ownerIdentifier);
@@ -149,7 +133,7 @@ interface Cache
*
* @param string $regionName The cache name given to the query.
*
* @return boolean true if the underlying cache contains corresponding data; false otherwise.
* @return bool true if the underlying cache contains corresponding data; false otherwise.
*/
public function containsQuery($regionName);
@@ -172,7 +156,7 @@ interface Cache
*
* @param string|null $regionName Query cache region name, or default query cache if the region name is NULL.
*
* @return \Doctrine\ORM\Cache\QueryCache The Query Cache associated with the region name.
* @return QueryCache The Query Cache associated with the region name.
*/
public function getQueryCache($regionName = null);
}

View File

@@ -1,55 +1,34 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
declare(strict_types=1);
namespace Doctrine\ORM\Cache;
/**
* Association cache entry
*
* @since 2.5
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class AssociationCacheEntry implements CacheEntry
{
/**
* READ-ONLY: Public only for performance reasons, it should be considered immutable.
*
* @var array The entity identifier
* @readonly Public only for performance reasons, it should be considered immutable.
* @var array<string, mixed> The entity identifier
*/
public $identifier;
/**
* READ-ONLY: Public only for performance reasons, it should be considered immutable.
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var string The entity class name
*/
public $class;
/**
* @param string $class The entity class.
* @param array $identifier The entity identifier.
* @param string $class The entity class.
* @param array<string, mixed> $identifier The entity identifier.
*/
public function __construct($class, array $identifier)
{
$this->class = $class;
$this->identifier = $identifier;
$this->class = $class;
$this->identifier = $identifier;
}
/**
@@ -57,7 +36,7 @@ class AssociationCacheEntry implements CacheEntry
*
* This method allow Doctrine\Common\Cache\PhpFileCache compatibility
*
* @param array $values array containing property values
* @param array<string, mixed> $values array containing property values
*
* @return AssociationCacheEntry
*/

View File

@@ -1,22 +1,6 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
declare(strict_types=1);
namespace Doctrine\ORM\Cache;
@@ -24,34 +8,23 @@ use Doctrine\ORM\Cache\Logging\CacheLogger;
/**
* Configuration container for second-level cache.
*
* @since 2.5
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class CacheConfiguration
{
/**
* @var \Doctrine\ORM\Cache\CacheFactory|null
*/
/** @var CacheFactory|null */
private $cacheFactory;
/**
* @var \Doctrine\ORM\Cache\RegionsConfiguration|null
*/
/** @var RegionsConfiguration|null */
private $regionsConfig;
/**
* @var \Doctrine\ORM\Cache\Logging\CacheLogger|null
*/
/** @var CacheLogger|null */
private $cacheLogger;
/**
* @var \Doctrine\ORM\Cache\QueryCacheValidator|null
*/
/** @var QueryCacheValidator|null */
private $queryValidator;
/**
* @return \Doctrine\ORM\Cache\CacheFactory|null
* @return CacheFactory|null
*/
public function getCacheFactory()
{
@@ -59,8 +32,6 @@ class CacheConfiguration
}
/**
* @param \Doctrine\ORM\Cache\CacheFactory $factory
*
* @return void
*/
public function setCacheFactory(CacheFactory $factory)
@@ -69,7 +40,7 @@ class CacheConfiguration
}
/**
* @return \Doctrine\ORM\Cache\Logging\CacheLogger|null
* @return CacheLogger|null
*/
public function getCacheLogger()
{
@@ -77,7 +48,7 @@ class CacheConfiguration
}
/**
* @param \Doctrine\ORM\Cache\Logging\CacheLogger $logger
* @return void
*/
public function setCacheLogger(CacheLogger $logger)
{
@@ -85,7 +56,7 @@ class CacheConfiguration
}
/**
* @return \Doctrine\ORM\Cache\RegionsConfiguration
* @return RegionsConfiguration
*/
public function getRegionsConfiguration()
{
@@ -97,7 +68,7 @@ class CacheConfiguration
}
/**
* @param \Doctrine\ORM\Cache\RegionsConfiguration $regionsConfig
* @return void
*/
public function setRegionsConfiguration(RegionsConfiguration $regionsConfig)
{
@@ -105,7 +76,7 @@ class CacheConfiguration
}
/**
* @return \Doctrine\ORM\Cache\QueryCacheValidator
* @return QueryCacheValidator
*/
public function getQueryValidator()
{
@@ -119,7 +90,7 @@ class CacheConfiguration
}
/**
* @param \Doctrine\ORM\Cache\QueryCacheValidator $validator
* @return void
*/
public function setQueryValidator(QueryCacheValidator $validator)
{

View File

@@ -1,22 +1,6 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
declare(strict_types=1);
namespace Doctrine\ORM\Cache;
@@ -26,11 +10,7 @@ namespace Doctrine\ORM\Cache;
* <b>IMPORTANT NOTE:</b>
*
* Fields of classes that implement CacheEntry are public for performance reason.
*
* @since 2.5
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
interface CacheEntry
{
}

View File

@@ -1,31 +1,15 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
declare(strict_types=1);
namespace Doctrine\ORM\Cache;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\Exception\ORMException;
use function sprintf;
/**
* Exception for cache.
*
* @since 2.5
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class CacheException extends ORMException
{
@@ -33,7 +17,7 @@ class CacheException extends ORMException
* @param string $sourceEntity
* @param string $fieldName
*
* @return \Doctrine\ORM\Cache\CacheException
* @return CacheException
*/
public static function updateReadOnlyCollection($sourceEntity, $fieldName)
{
@@ -43,7 +27,7 @@ class CacheException extends ORMException
/**
* @param string $entityName
*
* @return \Doctrine\ORM\Cache\CacheException
* @return CacheException
*/
public static function updateReadOnlyEntity($entityName)
{
@@ -53,7 +37,7 @@ class CacheException extends ORMException
/**
* @param string $entityName
*
* @return \Doctrine\ORM\Cache\CacheException
* @return CacheException
*/
public static function nonCacheableEntity($entityName)
{

Some files were not shown because too many files have changed in this diff Show More