Compare commits

...

318 Commits

Author SHA1 Message Date
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
Benjamin Eberlei
fa2b52c974 [docs] Fix wording for attributes=>parameters. (#9265) 2021-12-18 11:16:35 +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
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
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
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
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
Thomas Landauer
8b6fe52f74 Update events.rst 2021-12-01 01:01:04 +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
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
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
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
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
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
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
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
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
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
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
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
Benjamin Eberlei
25135d429f Merge 2.9.x into 2.10.x 2021-08-11 20:21:39 +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
Michael Olšavský
5685dc05f6 Fix mapped superclass missing in discriminator map 2021-08-09 16:24:37 +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
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
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
edaa05a217 Remove calls to prefersSequences()
Signed-off-by: Alexander M. Turek <me@derrabus.de>
2021-08-07 23:47:55 +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
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
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
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
8bb1454d5d Merge pull request #8859 from greg0ire/backport-7110
Drop tools/sandbox
2021-08-02 19:13:22 +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
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
Michael Moravec
183f4a5211 Drop tools/sandbox 2021-07-24 10:31:50 +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
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
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
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
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
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
55971d2f05 Merge pull request #8799 from greg0ire/backport-6909-6910
Combine consecutive issets and unsets
2021-06-29 23:51:35 +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
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
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
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
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
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
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
Alexander M. Turek
7277afefb9 Fix usages of deprecated DBAL constants 2021-06-23 01:30:14 +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
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
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
1213 changed files with 18261 additions and 18820 deletions

View File

@@ -12,21 +12,27 @@
"upcoming": true
},
{
"name": "2.10",
"branchName": "2.10.x",
"slug": "2.10",
"name": "2.11",
"branchName": "2.11.x",
"slug": "2.11",
"upcoming": true
},
{
"name": "2.9",
"branchName": "2.9.x",
"slug": "2.9",
"name": "2.10",
"branchName": "2.10.x",
"slug": "2.10",
"current": true,
"aliases": [
"current",
"stable"
]
},
{
"name": "2.9",
"branchName": "2.9.x",
"slug": "2.9",
"maintained": false
},
{
"name": "2.8",
"branchName": "2.8.x",

View File

@@ -10,30 +10,6 @@ on:
jobs:
coding-standards:
name: "Coding Standards"
runs-on: "ubuntu-20.04"
strategy:
matrix:
php-version:
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
tools: "cs2pr"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
dependency-versions: "highest"
# https://github.com/doctrine/.github/issues/3
- name: "Run PHP_CodeSniffer"
run: "vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr"
uses: "doctrine/.github/.github/workflows/coding-standards.yml@1.1.1"
with:
php-version: "7.4"

View File

@@ -2,7 +2,11 @@ name: "Continuous Integration"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
env:
fail-fast: true
@@ -19,6 +23,14 @@ jobs:
- "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.2@dev"
steps:
- name: "Checkout"
@@ -34,6 +46,10 @@ jobs:
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"
@@ -50,7 +66,7 @@ jobs:
- name: "Upload coverage file"
uses: "actions/upload-artifact@v2"
with:
name: "phpunit-sqlite-${{ matrix.php-version }}-coverage"
name: "phpunit-sqlite-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage"
path: "coverage*.xml"
@@ -63,9 +79,15 @@ jobs:
matrix:
php-version:
- "7.4"
dbal-version:
- "default"
postgres-version:
- "9.6"
- "13"
include:
- php-version: "8.0"
dbal-version: "2.13"
postgres-version: "13"
services:
postgres:
@@ -92,6 +114,10 @@ jobs:
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"
@@ -101,7 +127,7 @@ jobs:
- name: "Upload coverage file"
uses: "actions/upload-artifact@v2"
with:
name: "${{ github.job }}-${{ matrix.postgres-version }}-${{ matrix.php-version }}-coverage"
name: "${{ github.job }}-${{ matrix.postgres-version }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage"
path: "coverage.xml"
@@ -114,11 +140,18 @@ jobs:
matrix:
php-version:
- "7.4"
dbal-version:
- "default"
mariadb-version:
- "10.5"
extension:
- "mysqli"
- "pdo_mysql"
include:
- php-version: "8.0"
dbal-version: "2.13"
mariadb-version: "10.5"
extension: "pdo_mysql"
services:
mariadb:
@@ -139,6 +172,10 @@ jobs:
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:
@@ -156,7 +193,7 @@ jobs:
- name: "Upload coverage file"
uses: "actions/upload-artifact@v2"
with:
name: "${{ github.job }}-${{ matrix.mariadb-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-coverage"
name: "${{ github.job }}-${{ matrix.mariadb-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage"
path: "coverage.xml"
@@ -169,12 +206,19 @@ jobs:
matrix:
php-version:
- "7.4"
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:
@@ -202,6 +246,10 @@ jobs:
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"
@@ -218,9 +266,10 @@ jobs:
- name: "Upload coverage files"
uses: "actions/upload-artifact@v2"
with:
name: "${{ github.job }}-${{ matrix.mysql-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-coverage"
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"
@@ -253,6 +302,7 @@ jobs:
- 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"

View File

@@ -7,40 +7,10 @@ on:
jobs:
release:
name: "Git tag, release & create merge-up PR"
runs-on: "ubuntu-20.04"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Release"
uses: "laminas/automatic-releases@v1"
with:
command-name: "laminas:automatic-releases:release"
env:
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
"SHELL_VERBOSITY": "3"
- name: "Create Merge-Up Pull Request"
uses: "laminas/automatic-releases@v1"
with:
command-name: "laminas:automatic-releases:create-merge-up-pull-request"
env:
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
- name: "Create new milestones"
uses: "laminas/automatic-releases@v1"
with:
command-name: "laminas:automatic-releases:create-milestones"
env:
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@1.1.1"
secrets:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}
ORGANIZATION_ADMIN_TOKEN: ${{ secrets.ORGANIZATION_ADMIN_TOKEN }}
SIGNING_SECRET_KEY: ${{ secrets.SIGNING_SECRET_KEY }}

View File

@@ -15,9 +15,13 @@ jobs:
runs-on: "ubuntu-20.04"
strategy:
fail-fast: false
matrix:
php-version:
- "8.0"
dbal-version:
- "default"
- "2.13"
steps:
- name: "Checkout code"
@@ -29,6 +33,10 @@ jobs:
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:
@@ -36,15 +44,24 @@ jobs:
- 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.0"
dbal-version:
- "default"
- "2.13"
steps:
- name: "Checkout code"
@@ -56,6 +73,10 @@ jobs:
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:

View File

@@ -1,7 +1,7 @@
| [3.0.x][3.0] | [2.9.x][2.9] | [2.8.x][2.8] |
| [3.0.x][3.0] | [2.11.x][2.11] | [2.10.x][2.10] |
|:----------------:|:----------------:|:----------:|
| [![Build status][3.0 image]][3.0] | [![Build status][2.9 image]][2.9] | [![Build status][2.8 image]][2.8] |
| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.9 coverage image]][2.9 coverage] | [![Coverage Status][2.8 coverage image]][2.8 coverage] |
| [![Build status][3.0 image]][3.0] | [![Build status][2.11 image]][2.11] | [![Build status][2.10 image]][2.10] |
| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.11 coverage image]][2.11 coverage] | [![Coverage Status][2.10 coverage image]][2.10 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
@@ -20,11 +20,11 @@ without requiring unnecessary code duplication.
[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.9 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.9.x
[2.9]: https://github.com/doctrine/orm/tree/2.9.x
[2.9 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.9.x/graph/badge.svg
[2.9 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.9.x
[2.8 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg
[2.8]: https://github.com/doctrine/orm/tree/2.8
[2.8 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.8.x/graph/badge.svg
[2.8 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.8.x
[2.10 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.10.x
[2.10]: https://github.com/doctrine/orm/tree/2.10.x
[2.10 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.10.x/graph/badge.svg
[2.10 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.10.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

@@ -1,3 +1,81 @@
# 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
@@ -33,10 +111,10 @@ now always cleared regardless of the cache adapter being used.
Method `Doctrine\ORM\UnitOfWork#commit()` can throw an OptimisticLockException when a commit silently fails and returns false
since `Doctrine\DBAL\Connection#commit()` signature changed from returning void to boolean
## Deprecated: `Doctrine\ORM\AbstractQuery#iterator()`
## Deprecated: `Doctrine\ORM\AbstractQuery#iterate()`
The method `Doctrine\ORM\AbstractQuery#iterator()` is deprecated in favor of `Doctrine\ORM\AbstractQuery#toIterable()`.
Note that `toIterable()` yields results of the query, unlike `iterator()` which yielded each result wrapped into an array.
The method `Doctrine\ORM\AbstractQuery#iterate()` is deprecated in favor of `Doctrine\ORM\AbstractQuery#toIterable()`.
Note that `toIterable()` yields results of the query, unlike `iterate()` which yielded each result wrapped into an array.
# Upgrade to 2.7
@@ -107,24 +185,16 @@ The `Doctrine\ORM\Version` class is now deprecated and will be removed in Doctri
please refrain from checking the ORM version at runtime or use
[ocramius/package-versions](https://github.com/Ocramius/PackageVersions/).
## 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,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,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

@@ -20,11 +20,10 @@
"ext-ctype": "*",
"ext-pdo": "*",
"composer/package-versions-deprecated": "^1.8",
"doctrine/annotations": "^1.13",
"doctrine/cache": "^1.12.1 || ^2.1.1",
"doctrine/collections": "^1.5",
"doctrine/common": "^3.0.3",
"doctrine/dbal": "^2.13.0",
"doctrine/dbal": "^2.13.1 || ^3.1.1",
"doctrine/deprecations": "^0.5.3",
"doctrine/event-manager": "^1.1",
"doctrine/inflector": "^1.4 || ^2.0",
@@ -32,17 +31,23 @@
"doctrine/lexer": "^1.0",
"doctrine/persistence": "^2.2",
"psr/cache": "^1 || ^2 || ^3",
"symfony/console": "^3.0 || ^4.0 || ^5.0 || ^6.0"
"symfony/console": "^3.0 || ^4.0 || ^5.0 || ^6.0",
"symfony/polyfill-php72": "^1.23",
"symfony/polyfill-php80": "^1.15"
},
"require-dev": {
"doctrine/annotations": "^1.13",
"doctrine/coding-standard": "^9.0",
"phpbench/phpbench": "^0.16.10 || ^1.0",
"phpstan/phpstan": "0.12.94",
"phpstan/phpstan": "1.2.0",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.4",
"squizlabs/php_codesniffer": "3.6.0",
"squizlabs/php_codesniffer": "3.6.2",
"symfony/cache": "^4.4 || ^5.2",
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0",
"vimeo/psalm": "4.7.0"
"vimeo/psalm": "4.15.0"
},
"conflict": {
"doctrine/annotations": "<1.13 || >= 2.0"
},
"suggest": {
"symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0",

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
@@ -196,7 +196,7 @@ The format of the string representation format is called
`Well-known text (WKT) <https://en.wikipedia.org/wiki/Well-known_text>`_.
The advantage of this format is, that it is both human readable and parsable by MySQL.
Internally, MySQL stores geometry values in a binary format that is not
Internally, MySQL stores geometry values in a binary format that is not
identical to the WKT format. So, we need to let MySQL transform the WKT
representation into its internal format.
@@ -210,13 +210,13 @@ which convert WKT strings to and from the internal format of MySQL.
.. note::
When using DQL queries, the ``convertToPHPValueSQL`` and
When using DQL queries, the ``convertToPHPValueSQL`` and
``convertToDatabaseValueSQL`` methods only apply to identification variables
and path expressions in SELECT clauses. Expressions in WHERE clauses are
and path expressions in SELECT clauses. Expressions in WHERE clauses are
**not** wrapped!
If you want to use Point values in WHERE clauses, you have to implement a
:doc:`user defined function <dql-user-defined-functions>` for
:doc:`user defined function <dql-user-defined-functions>` for
``PointFromText``.
Example usage
@@ -252,5 +252,5 @@ Example usage
$query = $em->createQuery("SELECT l FROM Geo\Entity\Location l WHERE l.address = '1600 Amphitheatre Parkway, Mountain View, CA'");
$location = $query->getSingleResult();
/* @var Geo\ValueObject\Point */
/** @var Geo\ValueObject\Point */
$point = $location->getPoint();

View File

@@ -33,8 +33,8 @@ the DQL parser:
is only ever one of them. We implemented the default SqlWalker
implementation for it.
- A tree walker. There can be many tree walkers, they cannot
generate the sql, however they can modify the AST before its
rendered to sql.
generate the SQL, however they can modify the AST before its
rendered to SQL.
Now this is all awfully technical, so let me come to some use-cases
fast to keep you motivated. Using walker implementation you can for
@@ -50,7 +50,7 @@ example:
- Modify the Output walker to pretty print the SQL for debugging
purposes.
In this cookbook-entry I will show examples on the first two
In this cookbook-entry I will show examples of the first two
points. There are probably much more use-cases.
Generic count query for pagination
@@ -64,7 +64,7 @@ like:
SELECT p, c, a FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ...
Now in this query the blog post is the root entity, meaning its the
Now in this query the blog post is the root entity, meaning it's the
one that is hydrated directly from the query and returned as an
array of blog posts. In contrast the comment and author are loaded
for deeper use in the object tree.
@@ -79,7 +79,7 @@ query for pagination would look like:
SELECT count(DISTINCT p.id) FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ...
Now you could go and write each of these queries by hand, or you
can use a tree walker to modify the AST for you. Lets see how the
can use a tree walker to modify the AST for you. Let's see how the
API would look for this use-case:
.. code-block:: php
@@ -88,7 +88,7 @@ API would look for this use-case:
$pageNum = 1;
$query = $em->createQuery($dql);
$query->setFirstResult( ($pageNum-1) * 20)->setMaxResults(20);
$totalResults = Paginate::count($query);
$results = $query->getResult();
@@ -101,12 +101,12 @@ The ``Paginate::count(Query $query)`` looks like:
{
static public function count(Query $query)
{
/* @var $countQuery Query */
/** @var Query $countQuery */
$countQuery = clone $query;
$countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('DoctrineExtensions\Paginate\CountSqlWalker'));
$countQuery->setFirstResult(null)->setMaxResults(null);
return $countQuery->getSingleScalarResult();
}
}
@@ -137,13 +137,13 @@ implementation is:
break;
}
}
$pathExpression = new PathExpression(
PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $parentName,
$parent['metadata']->getSingleIdentifierFieldName()
);
$pathExpression->type = PathExpression::TYPE_STATE_FIELD;
$AST->selectClause->selectExpressions = array(
new SelectExpression(
new AggregateExpression('count', $pathExpression, true), null
@@ -196,7 +196,7 @@ modify the generation of the SELECT clause, adding the
public function walkSelectClause($selectClause)
{
$sql = parent::walkSelectClause($selectClause);
if ($this->getQuery()->getHint('mysqlWalker.sqlNoCache') === true) {
if ($selectClause->isDistinct) {
$sql = str_replace('SELECT DISTINCT', 'SELECT DISTINCT SQL_NO_CACHE', $sql);
@@ -204,7 +204,7 @@ modify the generation of the SELECT clause, adding the
$sql = str_replace('SELECT', 'SELECT SQL_NO_CACHE', $sql);
}
}
return $sql;
}
}

View File

@@ -45,7 +45,7 @@ configuration:
$config->addCustomStringFunction($name, $class);
$config->addCustomNumericFunction($name, $class);
$config->addCustomDatetimeFunction($name, $class);
$em = EntityManager::create($dbParams, $config);
The ``$name`` is the name the function will be referred to in the
@@ -96,7 +96,7 @@ discuss it step by step:
// (1)
public $firstDateExpression = null;
public $secondDateExpression = null;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER); // (2)
@@ -106,7 +106,7 @@ discuss it step by step:
$this->secondDateExpression = $parser->ArithmeticPrimary(); // (6)
$parser->match(Lexer::T_CLOSE_PARENTHESIS); // (3)
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return 'DATEDIFF(' .
@@ -180,28 +180,28 @@ I'll skip the blah and show the code for this function:
public $firstDateExpression = null;
public $intervalExpression = null;
public $unit = null;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->firstDateExpression = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_COMMA);
$parser->match(Lexer::T_IDENTIFIER);
$this->intervalExpression = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_IDENTIFIER);
/* @var $lexer Lexer */
/** @var Lexer $lexer */
$lexer = $parser->getLexer();
$this->unit = $lexer->token['value'];
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return 'DATE_ADD(' .

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

View File

@@ -9,22 +9,27 @@ 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');
@@ -41,19 +46,22 @@ steps of configuration.
$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 <https://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
---------------------
@@ -137,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***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -168,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
@@ -181,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***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -269,10 +259,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

View File

@@ -1,6 +1,11 @@
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
@@ -13,12 +18,15 @@ 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 ORM docblock
annotations support namespaces and nested annotations among other
things. The Doctrine ORM 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::
@@ -455,7 +463,7 @@ Optional attributes:
- **strategy**: Set the name of the identifier generation strategy.
Valid values are ``AUTO``, ``SEQUENCE``, ``TABLE``, ``IDENTITY``, ``UUID``, ``CUSTOM`` and ``NONE``, explained
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.

View File

@@ -184,6 +184,8 @@ in well defined units of work. Work with your objects and modify
them as usual and when you're done call ``EntityManager#flush()``
to make your changes persistent.
.. _unit-of-work:
The Unit of Work
~~~~~~~~~~~~~~~~

View File

@@ -430,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")},

View File

@@ -59,12 +59,12 @@ inside the instance variables PHP DocBlock comment. Any value hold
inside this variable will be saved to and loaded from the database
as part of the lifecycle of the instance variables entity-class.
Required attributes:
Required parameters:
- **type**: Name of the DBAL Type which does the conversion between PHP
and Database representation.
Optional attributes:
Optional parameters:
- **name**: By default the property name is used for the database
column name also, however the ``name`` attribute allows you to
@@ -165,7 +165,7 @@ Examples:
~~~~~~~~
Add caching strategy to a root entity or a collection.
Optional attributes:
Optional parameters:
- **usage**: One of ``READ_ONLY``, ``READ_WRITE`` or ``NONSTRICT_READ_WRITE``, By default this is ``READ_ONLY``.
- **region**: An specific region name
@@ -210,7 +210,7 @@ Example:
This attribute allows you to specify a user-provided class to generate identifiers. This attribute only works when both :ref:`#[Id] <attrref_id>` and :ref:`#[GeneratedValue(strategy: "CUSTOM")] <attrref_generatedvalue>` are specified.
Required attributes:
Required parameters:
- **class**: name of the class which should extend Doctrine\ORM\Id\AbstractIdGenerator
@@ -244,13 +244,13 @@ actually instantiated as.
If this attribute is not specified, the discriminator column defaults
to a string column of length 255 called ``dtype``.
Required attributes:
Required parameters:
- **name**: The column name of the discriminator. This name is also
used during Array hydration as key to specify the class-name.
Optional attributes:
Optional parameters:
- **type**: By default this is string.
@@ -319,7 +319,7 @@ attribute to establish the relationship between the two classes.
The embedded attribute is required on an entity's member variable,
in order to specify that it is an embedded class.
Required attributes:
Required parameters:
- **class**: The embeddable class
@@ -331,7 +331,7 @@ Required attributes:
Required attribute to mark a PHP class as an entity. Doctrine manages
the persistence of all classes marked as entities.
Optional attributes:
Optional parameters:
- **repositoryClass**: Specifies the FQCN of a subclass of the
``EntityRepository``. Use of repositories for entities is encouraged to keep
@@ -368,11 +368,11 @@ conjunction with #[Id].
If this attribute is not specified with ``#[Id]`` the ``NONE`` strategy is
used as default.
Optional attributes:
Optional parameters:
- **strategy**: Set the name of the identifier generation strategy.
Valid values are ``AUTO``, ``SEQUENCE``, ``TABLE``, ``IDENTITY``,
``UUID``, ``CUSTOM`` and ``NONE``.
Valid values are ``AUTO``, ``SEQUENCE``, ``IDENTITY``, ``UUID``
(deprecated), ``CUSTOM`` and ``NONE``.
If not specified, the default value is ``AUTO``.
Example:
@@ -424,14 +424,14 @@ Attribute is used on the entity-class level. It provides a hint to the SchemaToo
generate a database index on the specified table columns. It only
has meaning in the ``SchemaTool`` schema generation context.
Required attributes:
Required parameters:
- **name**: Name of the Index
- **fields**: Array of fields. Exactly one of **fields, columns** is required.
- **columns**: Array of columns. Exactly one of **fields, columns** is required.
Optional attributes:
Optional parameters:
- **options**: Array of platform specific options:
@@ -548,7 +548,7 @@ The ``#[InverseJoinColumn]`` is the same as ``#[JoinColumn]`` and is used in the
of a ``#[ManyToMany]`` attribute declaration to specifiy the details of the join table's
column information used for the join to the inverse entity.
Optional attributes:
Optional parameters:
- **name**: Column name that holds the foreign key identifier for
this relation. In the context of ``#[JoinTable]`` it specifies the column
@@ -623,14 +623,14 @@ Example:
Defines that the annotated instance variable holds a reference that
describes a many-to-one relationship between two entities.
Required attributes:
Required parameters:
- **targetEntity**: FQCN of the referenced target entity. Can be the
unqualified class name if both classes are in the same namespace.
*IMPORTANT:* No leading backslash!
Optional attributes:
Optional parameters:
- **cascade**: Cascade Option
@@ -659,14 +659,14 @@ additional, optional attribute that has reasonable default
configuration values using the table and names of the two related
entities.
Required attributes:
Required parameters:
- **targetEntity**: FQCN of the referenced target entity. Can be the
unqualified class name if both classes are in the same namespace.
*IMPORTANT:* No leading backslash!
Optional attributes:
Optional parameters:
- **mappedBy**: This option specifies the property name on the
@@ -720,7 +720,7 @@ The ``#[MappedSuperclass]`` attribute cannot be used in conjunction with
``#[Entity]``. See the Inheritance Mapping section for
:doc:`more details on the restrictions of mapped superclasses <inheritance-mapping>`.
Optional attributes:
Optional parameters:
- **repositoryClass**: Specifies the FQCN of a subclass of the EntityRepository.
That will be inherited for all subclasses of that Mapped Superclass.
@@ -756,13 +756,13 @@ be specified. When no
:ref:`#[JoinColumn] <attrref_joincolumn>` is specified it defaults to using the target entity table and
primary key column names and the current naming strategy to determine a name for the join column.
Required attributes:
Required parameters:
- **targetEntity**: FQCN of the referenced target entity. Can be the
unqualified class name if both classes are in the same namespace.
*IMPORTANT:* No leading backslash!
Optional attributes:
Optional parameters:
- **cascade**: Cascade Option
- **fetch**: One of LAZY or EAGER
@@ -786,13 +786,13 @@ Example:
#[OneToMany]
~~~~~~~~~~~~
Required attributes:
Required parameters:
- **targetEntity**: FQCN of the referenced target entity. Can be the
unqualified class name if both classes are in the same namespace.
*IMPORTANT:* No leading backslash!
Optional attributes:
Optional parameters:
- **cascade**: Cascade Option
- **orphanRemoval**: Boolean that specifies if orphans, inverse
@@ -916,11 +916,11 @@ For use with ``#[GeneratedValue(strategy: "SEQUENCE")]`` this
attribute allows to specify details about the sequence, such as
the increment size and initial values of the sequence.
Required attributes:
Required parameters:
- **sequenceName**: Name of the sequence
Optional attributes:
Optional parameters:
- **allocationSize**: Increment the sequence by the allocation size
when its fetched. A value larger than 1 allows optimization for
@@ -954,11 +954,11 @@ placed on the entity-class level and is optional. If it is
not specified the table name will default to the entity's
unqualified classname.
Required attributes:
Required parameters:
- **name**: Name of the table
Optional attributes:
Optional parameters:
- **schema**: Name of the schema the table lies in.
@@ -985,12 +985,12 @@ generate a database unique constraint on the specified table
columns. It only has meaning in the SchemaTool schema generation
context.
Required attributes:
Required parameters:
- **name**: Name of the Index
- **columns**: Array of columns.
Optional attributes:
Optional parameters:
- **options**: Array of platform specific options:

View File

@@ -379,11 +379,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

View File

@@ -1,266 +1,14 @@
Caching
=======
Doctrine provides cache drivers in the ``doctrine/cache`` package for some
of the most popular caching implementations such as APCu, 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/2.8.x/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 <https://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 <https://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 <https://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,11 +24,9 @@ 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
~~~~~~~~~~~~
@@ -292,11 +38,13 @@ 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.
@@ -313,10 +61,12 @@ 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'
);
$query->setResultCacheDriver($cacheDriver);
$query->setResultCache($cache);
.. note::
@@ -368,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.
@@ -422,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

@@ -134,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.

View File

@@ -490,21 +490,21 @@ where you can generate an arbitrary join with the following syntax:
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 ``Blacklist``, it can look like this:
and ``Banlist``, it can look like this:
- User
- Blacklist
- Blacklist
- Banlist
- Banlist
- User
- Blacklist
- Banlist
- User
- Blacklist
- Blacklist
- Blacklist
- Banlist
- Banlist
- Banlist
In this form of join, the ``Blacklist`` 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 Blacklists is invoked on a User instance,
it loads all the related ``Blacklist`` objects corresponding to this ``User``. This change of behaviour needs to be considered
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::
@@ -1184,6 +1184,7 @@ The constants for the different hydration modes are:
- ``Query::HYDRATE_ARRAY``
- ``Query::HYDRATE_SCALAR``
- ``Query::HYDRATE_SINGLE_SCALAR``
- ``Query::HYDRATE_SCALAR_COLUMN``
Object Hydration
^^^^^^^^^^^^^^^^
@@ -1272,6 +1273,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
^^^^^^^^^^^^^^^^^^^^^^
@@ -1283,13 +1303,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);
}
}
@@ -1526,7 +1547,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, ...)

View File

@@ -121,6 +121,53 @@ Now you can test the ``$eventSubscriber`` instance to see if the
echo 'pre foo invoked!';
}
Registering Events
~~~~~~~~~~~~~~~~~~
There are two ways to register an event:
* *All events* can be registered by calling ``$eventManager->addEventListener()``
or ``eventManager->addEventSubscriber()``, see
:ref:`Listening and subscribing to Lifecycle Events<listening-and-subscribing-to-lifecycle-events>`
* *Lifecycle Callbacks* can also be registered in the entity mapping (annotation, attribute, etc.),
see :ref:`Lifecycle Callbacks<lifecycle-callbacks>`
Events Overview
---------------
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| Event | Dispatched by | Lifecycle | Passed |
| | | Callback | Argument |
+=================================================================+=======================+===========+=====================================+
| :ref:`preRemove<reference-events-pre-remove>` | ``$em->remove()`` | Yes | `_LifecycleEventArgs`_ |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| :ref:`postRemove<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes | `_LifecycleEventArgs`_ |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| :ref:`prePersist<reference-events-pre-persist>` | ``$em->persist()`` | Yes | `_LifecycleEventArgs`_ |
| | on *initial* persist | | |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| :ref:`postPersist<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes | `_LifecycleEventArgs`_ |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| :ref:`preUpdate<reference-events-pre-update>` | ``$em->flush()`` | Yes | `_PreUpdateEventArgs`_ |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| :ref:`postUpdate<reference-events-post-update-remove-persist>` | ``$em->flush()`` | Yes | `_LifecycleEventArgs`_ |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| :ref:`postLoad<reference-events-post-load>` | Loading from database | Yes | `_LifecycleEventArgs`_ |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| :ref:`loadClassMetadata<reference-events-load-class-metadata>` | Loading of mapping | No | `_LoadClassMetadataEventArgs` |
| | metadata | | |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| ``onClassMetadataNotFound`` | ``MappingException`` | No | `_OnClassMetadataNotFoundEventArgs` |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| :ref:`preFlush<reference-events-pre-flush>` | ``$em->flush()`` | Yes | `_PreFlushEventArgs`_ |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| :ref:`onFlush<reference-events-on-flush>` | ``$em->flush()`` | No | `_OnFlushEventArgs` |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| :ref:`postFlush<reference-events-post-flush>` | ``$em->flush()`` | No | `_PostFlushEventArgs` |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
| ``onClear`` | ``$em->clear()`` | No | `_OnClearEventArgs` |
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
Naming convention
~~~~~~~~~~~~~~~~~
@@ -208,15 +255,6 @@ events during the life-time of their registered entities.
cascade remove relations. In this case, you should load yourself the proxy in
the associated pre event.
You can access the Event constants from the ``Events`` class in the
ORM package.
.. code-block:: php
<?php
use Doctrine\ORM\Events;
echo Events::preUpdate;
These can be hooked into by two different types of event
listeners:
@@ -237,6 +275,7 @@ The ``EventArgs`` instance received by the listener gives access to the entity,
:ref:`reference-events-implementing-listeners` section very carefully
to understand which operations are allowed in which lifecycle event.
.. _lifecycle-callbacks:
Lifecycle Callbacks
-------------------
@@ -250,138 +289,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;
/**
* @Column(type="string", length=255)
* #[Entity]
* #[HasLifecycleCallbacks]
*/
public $value;
/** @Column(name="created_at", type="string", length=255) */
private $createdAt;
/** @PrePersist */
public function doStuffOnPrePersist()
{
$this->createdAt = date('Y-m-d H:i:s');
}
/** @PrePersist */
public function doOtherStuffOnPrePersist()
{
$this->value = 'changed from prePersist callback!';
}
/** @PostPersist */
public function doStuffOnPostPersist()
{
$this->value = 'changed from postPersist callback!';
}
/** @PostLoad */
public function doStuffOnPostLoad()
{
$this->value = 'changed from postLoad callback!';
}
/** @PreUpdate */
public function doStuffOnPreUpdate()
{
$this->value = 'changed from preUpdate callback!';
}
}
Note that the methods set as lifecycle callbacks need to be public and,
when using these annotations, you have to apply the
``@HasLifecycleCallbacks`` marker annotation on the entity class.
If you want to register lifecycle callbacks from YAML or XML you
can do it with the following.
.. code-block:: yaml
User:
type: entity
fields:
# ...
name:
type: string(50)
lifecycleCallbacks:
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersist ]
postPersist: [ doStuffOnPostPersist ]
In YAML the ``key`` of the lifecycleCallbacks entry is the event that you
are triggering on and the value is the method (or methods) to call. The allowed
event types are the ones listed in the previous Lifecycle Events section.
XML would look something like this:
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="User">
<lifecycle-callbacks>
<lifecycle-callback type="prePersist" method="doStuffOnPrePersist"/>
<lifecycle-callback type="postPersist" method="doStuffOnPostPersist"/>
</lifecycle-callbacks>
</entity>
</doctrine-mapping>
In XML the ``type`` of the lifecycle-callback entry is the event that you
are triggering on and the ``method`` is the method to call. The allowed event
types are the ones listed in the previous Lifecycle Events section.
When using YAML or XML you need to remember to create public methods to match the
callback names you defined. E.g. in these examples ``doStuffOnPrePersist()``,
``doOtherStuffOnPrePersist()`` and ``doStuffOnPostPersist()`` methods need to be
defined on your ``User`` model.
.. code-block:: php
<?php
// ...
class User
{
// ...
public function doStuffOnPrePersist()
class User
{
// ...
}
public function doOtherStuffOnPrePersist()
#[Column(type: Types::STRING, length: 255)]
public $value;
#[PrePersist]
public function doStuffOnPrePersist(LifecycleEventArgs $eventArgs)
{
$this->createdAt = date('Y-m-d H:i:s');
}
#[PrePersist]
public function doOtherStuffOnPrePersist()
{
$this->value = 'changed from prePersist callback!';
}
#[PreUpdate]
public function doStuffOnPreUpdate(PreUpdateEventArgs $eventArgs)
{
$this->value = 'changed from preUpdate callback!';
}
}
.. code-block:: annotation
<?php
use Doctrine\Persistence\Event\LifecycleEventArgs;
/**
* @Entity
* @HasLifecycleCallbacks
*/
class User
{
// ...
}
public function doStuffOnPostPersist()
{
// ...
}
}
/** @Column(type="string", length=255) */
public $value;
/** @PrePersist */
public function doStuffOnPrePersist(LifecycleEventArgs $eventArgs)
{
$this->createdAt = date('Y-m-d H:i:s');
}
/** @PrePersist */
public function doOtherStuffOnPrePersist()
{
$this->value = 'changed from prePersist callback!';
}
/** @PreUpdate */
public function doStuffOnPreUpdate(PreUpdateEventArgs $eventArgs)
{
$this->value = 'changed from preUpdate callback!';
}
}
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="User">
<!-- ... -->
<lifecycle-callbacks>
<lifecycle-callback type="prePersist" method="doStuffOnPrePersist"/>
<lifecycle-callback type="prePersist" method="doOtherStuffOnPrePersist"/>
<lifecycle-callback type="preUpdate" method="doStuffOnPreUpdate"/>
</lifecycle-callbacks>
</entity>
</doctrine-mapping>
.. code-block:: yaml
User:
type: entity
fields:
# ...
value:
type: string(255)
lifecycleCallbacks:
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersist ]
preUpdate: [ doStuffOnPreUpdate ]
Lifecycle Callbacks Event Argument
-----------------------------------
----------------------------------
The triggered event is also given to the lifecycle-callback.
@@ -403,6 +416,8 @@ With the additional argument you have access to the
}
}
.. _listening-and-subscribing-to-lifecycle-events:
Listening and subscribing to Lifecycle Events
---------------------------------------------
@@ -413,7 +428,7 @@ behaviors across different entity classes.
Note that they require much more detailed knowledge about the inner
workings of the ``EntityManager`` and ``UnitOfWork`` classes. Please
read the :ref:`reference-events-implementing-listeners` section
read the :ref:`Implementing Event Listeners<reference-events-implementing-listeners>` section
carefully if you are trying to write your own listener.
For event subscribers, there are no surprises. They declare the
@@ -482,8 +497,10 @@ EventManager that is passed to the EntityManager factory:
.. code-block:: php
<?php
use Doctrine\ORM\Events;
$eventManager = new EventManager();
$eventManager->addEventListener(array(Events::preUpdate), new MyEventListener());
$eventManager->addEventListener([Events::preUpdate], new MyEventListener());
$eventManager->addEventSubscriber(new MyEventSubscriber());
$entityManager = EntityManager::create($dbOpts, $config, $eventManager);
@@ -494,7 +511,9 @@ EntityManager was created:
.. code-block:: php
<?php
$entityManager->getEventManager()->addEventListener(array(Events::preUpdate), new MyEventListener());
use Doctrine\ORM\Events;
$entityManager->getEventManager()->addEventListener([Events::preUpdate], new MyEventListener());
$entityManager->getEventManager()->addEventSubscriber(new MyEventSubscriber());
.. _reference-events-implementing-listeners:
@@ -514,6 +533,8 @@ the restrictions apply as well, with the additional restriction
that (prior to version 2.4) you do not have access to the
``EntityManager`` or ``UnitOfWork`` APIs inside these events.
.. _reference-events-pre-persist:
prePersist
~~~~~~~~~~
@@ -539,6 +560,8 @@ The following restrictions apply to ``prePersist``:
- Doctrine will not recognize changes made to relations in a prePersist
event. This includes modifications to
collections such as additions, removals or replacement.
.. _reference-events-pre-remove:
preRemove
~~~~~~~~~
@@ -551,6 +574,8 @@ There are no restrictions to what methods can be called inside the
``preRemove`` event, except when the remove method itself was
called during a flush operation.
.. _reference-events-pre-flush:
preFlush
~~~~~~~~
@@ -573,6 +598,8 @@ result in infinite loop.
}
}
.. _reference-events-on-flush:
onFlush
~~~~~~~
@@ -636,6 +663,8 @@ The following restrictions apply to the onFlush event:
affected entity. This can be done by calling
``$unitOfWork->recomputeSingleEntityChangeSet($classMetadata, $entity)``.
.. _reference-events-post-flush:
postFlush
~~~~~~~~~
@@ -656,12 +685,13 @@ 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
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.
Changes to associations of the updated entity are never allowed in
@@ -741,6 +771,8 @@ Restrictions for this event:
API are strongly discouraged and don't work as expected outside the
flush operation.
.. _reference-events-post-update-remove-persist:
postUpdate, postRemove, postPersist
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -750,6 +782,8 @@ database, but you can use these events to alter non-persistable items,
like non-mapped fields, logging or even associated classes that are
not directly mapped by Doctrine.
.. _reference-events-post-load:
postLoad
~~~~~~~~
@@ -766,7 +800,19 @@ An entity listener is a lifecycle listener class used for an entity.
.. configuration-block::
.. code-block:: php
.. code-block:: attribute
<?php
namespace MyProject\Entity;
use App\EventListener\UserListener;
#[Entity]
#[EntityListeners([UserListener::class])]
class User
{
// ....
}
.. code-block:: annotation
<?php
namespace MyProject\Entity;
@@ -900,7 +946,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 +1008,23 @@ 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
in to a ``Doctrine\ORM\Mapping\ClassMetadata`` instance. You can hook in to this
process and manipulate the instance.
.. 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,3 +1038,64 @@ process and manipulate the instance.
}
}
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

@@ -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*
@@ -27,11 +27,13 @@ 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.
The preferred cache driver for metadata and query caches is ``PhpFileCache``.
This driver serializes cache items and writes them to a file.
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:`integrating-with-the-orm`
See :ref:`types-of-caches`
Alternative Query Result Formats
--------------------------------

View File

@@ -39,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

View File

@@ -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::

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
@@ -93,8 +93,6 @@ Cache region
``Doctrine\ORM\Cache\Region`` defines a contract for accessing a particular
cache region.
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/Region.html>`_.
Concurrent cache region
~~~~~~~~~~~~~~~~~~~~~~~
@@ -105,8 +103,6 @@ If you want to use an ``READ_WRITE`` cache, you should consider providing your o
``Doctrine\ORM\Cache\ConcurrentRegion`` defines a contract for concurrently managed data region.
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/ConcurrentRegion.html>`_.
Timestamp region
~~~~~~~~~~~~~~~~
@@ -114,8 +110,6 @@ Timestamp region
Tracks the timestamps of the most recent updates to particular entity.
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/TimestampRegion.html>`_.
.. _reference-second-level-cache-mode:
Caching mode
@@ -132,7 +126,7 @@ Caching mode
* Read Write Cache doesnt employ any locks but can do reads, inserts, updates and deletes.
* Good if the application needs to update data rarely.
* ``READ_WRITE``
@@ -147,21 +141,21 @@ Built-in cached persisters
Cached persisters are responsible to access cache regions.
+-----------------------+-------------------------------------------------------------------------------------------+
| Cache Usage | Persister |
+=======================+===========================================================================================+
| READ_ONLY | Doctrine\\ORM\\Cache\\Persister\\Entity\\ReadOnlyCachedEntityPersister |
+-----------------------+-------------------------------------------------------------------------------------------+
| READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Entity\\ReadWriteCachedEntityPersister |
+-----------------------+-------------------------------------------------------------------------------------------+
| NONSTRICT_READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Entity\\NonStrictReadWriteCachedEntityPersister |
+-----------------------+-------------------------------------------------------------------------------------------+
| READ_ONLY | Doctrine\\ORM\\Cache\\Persister\\Collection\\ReadOnlyCachedCollectionPersister |
+-----------------------+-------------------------------------------------------------------------------------------+
| READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Collection\\ReadWriteCachedCollectionPersister |
+-----------------------+-------------------------------------------------------------------------------------------+
| NONSTRICT_READ_WRITE | Doctrine\\ORM\\Cache\\Persister\\Collection\\NonStrictReadWriteCachedCollectionPersister |
+-----------------------+-------------------------------------------------------------------------------------------+
+-----------------------+------------------------------------------------------------------------------------------+
| Cache Usage | Persister |
+=======================+==========================================================================================+
| READ_ONLY | ``Doctrine\ORM\Cache\Persister\Entity\ReadOnlyCachedEntityPersister`` |
+-----------------------+------------------------------------------------------------------------------------------+
| READ_WRITE | ``Doctrine\ORM\Cache\Persister\Entity\ReadWriteCachedEntityPersister`` |
+-----------------------+------------------------------------------------------------------------------------------+
| NONSTRICT_READ_WRITE | ``Doctrine\ORM\Cache\Persister\Entity\NonStrictReadWriteCachedEntityPersister`` |
+-----------------------+------------------------------------------------------------------------------------------+
| READ_ONLY | ``Doctrine\ORM\Cache\Persister\Collection\ReadOnlyCachedCollectionPersister`` |
+-----------------------+------------------------------------------------------------------------------------------+
| READ_WRITE | ``Doctrine\ORM\Cache\Persister\Collection\ReadWriteCachedCollectionPersister`` |
+-----------------------+------------------------------------------------------------------------------------------+
| NONSTRICT_READ_WRITE | ``Doctrine\ORM\Cache\Persister\Collection\NonStrictReadWriteCachedCollectionPersister`` |
+-----------------------+------------------------------------------------------------------------------------------+
Configuration
-------------
@@ -172,7 +166,7 @@ Enable Second Level Cache
~~~~~~~~~~~~~~~~~~~~~~~~~
To enable the second-level-cache, you should provide a cache factory.
``\Doctrine\ORM\Cache\DefaultCacheFactory`` is the default implementation.
``Doctrine\ORM\Cache\DefaultCacheFactory`` is the default implementation.
.. code-block:: php
@@ -196,7 +190,7 @@ Cache Factory
Cache Factory is the main point of extension.
It allows you to provide a specific implementation of the following components :
It allows you to provide a specific implementation of the following components:
``QueryCache``
stores and retrieves query cache results.
@@ -209,8 +203,6 @@ It allows you to provide a specific implementation of the following components :
``CollectionHydrator``
transforms collections into cache entries and cache entries into collections
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/DefaultCacheFactory.html>`_.
Region Lifetime
~~~~~~~~~~~~~~~
@@ -234,12 +226,12 @@ Cache Log
~~~~~~~~~
By providing a cache logger you should be able to get information about all cache operations such as hits, misses and puts.
``\Doctrine\ORM\Cache\Logging\StatisticsCacheLogger`` is a built-in implementation that provides basic statistics.
``Doctrine\ORM\Cache\Logging\StatisticsCacheLogger`` is a built-in implementation that provides basic statistics.
.. code-block:: php
<?php
/* @var $config \Doctrine\ORM\Configuration */
/** @var \Doctrine\ORM\Configuration $config */
$logger = new \Doctrine\ORM\Cache\Logging\StatisticsCacheLogger();
// Cache logger
@@ -269,12 +261,9 @@ By providing a cache logger you should be able to get information about all cach
$logger->getMissCount();
If you want to get more information you should implement
``\Doctrine\ORM\Cache\Logging\CacheLogger`` and collect
``Doctrine\ORM\Cache\Logging\CacheLogger`` and collect
all the information you want.
`See API Doc <https://www.doctrine-project.org/api/orm/current/Doctrine/ORM/Cache/Logging/CacheLogger.html>`_.
Entity cache definition
-----------------------
* Entity cache configuration allows you to define the caching strategy and region for an entity.
@@ -330,8 +319,8 @@ level cache region.
Country:
type: entity
cache:
usage : READ_ONLY
region : my_entity_region
usage: READ_ONLY
region: my_entity_region
id:
id:
type: integer
@@ -401,7 +390,7 @@ It caches the primary keys of association and cache each element will be cached
</id>
<field name="name" type="string" column="name"/>
<many-to-one field="country" target-entity="Country">
<cache usage="NONSTRICT_READ_WRITE" />
@@ -421,7 +410,7 @@ It caches the primary keys of association and cache each element will be cached
State:
type: entity
cache:
usage : NONSTRICT_READ_WRITE
usage: NONSTRICT_READ_WRITE
id:
id:
type: integer
@@ -439,17 +428,18 @@ It caches the primary keys of association and cache each element will be cached
country_id:
referencedColumnName: id
cache:
usage : NONSTRICT_READ_WRITE
usage: NONSTRICT_READ_WRITE
oneToMany:
cities:
targetEntity:City
mappedBy: state
cache:
usage : NONSTRICT_READ_WRITE
usage: NONSTRICT_READ_WRITE
.. note::
> Note: for this to work, the target entity must also be marked as cacheable.
for this to work, the target entity must also be marked as cacheable.
Cache usage
~~~~~~~~~~~
@@ -466,8 +456,8 @@ Basic entity cache
$country1 = $em->find('Country', 1); // Retrieve item from cache
$country1->setName("New Name");
$country1->setName('New Name');
$em->flush(); // Hit database to update the row and update cache
$em->clear(); // Clear entity manager
@@ -492,7 +482,7 @@ Association cache
$state = $em->find('State', 1);
// Hit database to update the row and update cache entry
$state->setName("New Name");
$state->setName('New Name');
$em->persist($state);
$em->flush();
@@ -543,14 +533,14 @@ The query cache stores the results of the query but as identifiers, entity value
.. code-block:: php
<?php
/* @var $em \Doctrine\ORM\EntityManager */
/** @var \Doctrine\ORM\EntityManager $em */
// Execute database query, store query cache and entity cache
$result1 = $em->createQuery('SELECT c FROM Country c ORDER BY c.name')
->setCacheable(true)
->getResult();
$em->clear()
$em->clear();
// Check if query result is valid and load entities from cache
$result2 = $em->createQuery('SELECT c FROM Country c ORDER BY c.name')
@@ -570,16 +560,16 @@ 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
~~~~~~~~~~~~~~~~~~~~~~~
@@ -597,7 +587,7 @@ Execute the ``UPDATE`` and invalidate ``all cache entries`` using ``Query::HINT_
<?php
// Execute and invalidate
$this->_em->createQuery("UPDATE Entity\Country u SET u.name = 'unknown' WHERE u.id = 1")
->setHint(Query::HINT_CACHE_EVICT, true)
->setHint(\Doctrine\ORM\Query::HINT_CACHE_EVICT, true)
->execute();
@@ -659,7 +649,7 @@ However, you can use the cache API to check / invalidate cache entries.
.. code-block:: php
<?php
/* @var $cache \Doctrine\ORM\Cache */
/** @var \Doctrine\ORM\Cache $cache */
$cache = $em->getCache();
$cache->containsEntity('Entity\State', 1) // Check if the cache exists
@@ -704,19 +694,19 @@ For performance reasons the cache API does not extract from composite primary ke
}
// Supported
/* @var $article Article */
/** @var Article $article */
$article = $em->find('Article', 1);
// Supported
/* @var $article Article */
/** @var Article $article */
$article = $em->find('Article', $article);
// Supported
$id = array('source' => 1, 'target' => 2);
$id = ['source' => 1, 'target' => 2];
$reference = $em->find('Reference', $id);
// NOT Supported
$id = array('source' => new Article(1), 'target' => new Article(2));
$id = ['source' => new Article(1), 'target' => new Article(2)];
$reference = $em->find('Reference', $id);
Distributed environments

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,

View File

@@ -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.

View File

@@ -81,7 +81,8 @@ that directory with the following contents:
{
"require": {
"doctrine/orm": "^2.6.2",
"doctrine/orm": "^2.10.2",
"doctrine/dbal": "^3.1.1",
"symfony/yaml": "2.*",
"symfony/cache": "^5.3"
},
@@ -112,6 +113,14 @@ Add the following directories:
.. note::
The YAML driver is deprecated and will be removed in version 3.0.
It is strongly recommended to switch to one of the other mappings.
.. note::
It is strongly recommended that you require ``doctrine/dbal`` in your
``composer.json`` as well, because using the ORM means mapping objects
and their fields to database tables and their columns, and that
requires mentioning so-called types that are defined in ``doctrine/dbal``
in your application. Having an explicit requirement means you control
when the upgrade to the next major version happens, so that you can
do the necessary changes in your application beforehand.
Obtaining the EntityManager
---------------------------
@@ -642,7 +651,7 @@ Let's continue by creating a script to display the name of a product based on it
echo sprintf("-%s\n", $product->getName());
Next we'll update a product's name, given its id. This simple example will
help demonstrate Doctrine's implementation of the UnitOfWork pattern. Doctrine
help demonstrate Doctrine's implementation of the :ref:`UnitOfWork pattern <unit-of-work>`. Doctrine
keeps track of all the entities that were retrieved from the Entity Manager,
and can detect when any of those entities' properties have been modified.
As a result, rather than needing to call ``persist($entity)`` for each individual
@@ -1334,7 +1343,7 @@ call this script as follows:
php create_bug.php 1 1 1
See how simple it is to relate a Bug, Reporter, Engineer and Products?
Also recall that thanks to the UnitOfWork pattern, Doctrine will detect
Also recall that thanks to the :ref:`UnitOfWork pattern <unit-of-work>`, Doctrine will detect
these relations and update all of the modified entities in the database
automatically when ``flush()`` is called.

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"/>
@@ -290,13 +289,13 @@
</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" />
@@ -308,6 +307,9 @@
</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="optional" />
<xs:attribute name="column-prefix" type="xs:string" use="optional" />
@@ -315,9 +317,9 @@
</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,10 +329,10 @@
</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="optional"/>
<xs:attribute name="fields" type="xs:string" use="optional"/>
@@ -338,69 +340,69 @@
</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" />
@@ -408,9 +410,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" />
@@ -418,9 +420,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>
@@ -432,17 +434,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" />
@@ -453,36 +455,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"/>
@@ -495,14 +497,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" />
@@ -514,12 +522,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" />
@@ -530,7 +538,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">
@@ -539,7 +547,7 @@
<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" />
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
@@ -548,7 +556,7 @@
</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">
@@ -557,7 +565,7 @@
<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" />
<xs:attribute name="mapped-by" type="xs:NMTOKEN" />
@@ -568,19 +576,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>
@@ -590,27 +598,27 @@
</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" />

View File

@@ -1,31 +1,18 @@
<?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 Countable;
use Doctrine\Common\Cache\Psr6\CacheAdapter;
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Result;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\Cache\Exception\InvalidResultCacheDriver;
use Doctrine\ORM\Cache\Logging\CacheLogger;
use Doctrine\ORM\Cache\QueryCacheKey;
use Doctrine\ORM\Cache\TimestampCacheKey;
@@ -35,10 +22,12 @@ use Doctrine\ORM\Query\Parameter;
use Doctrine\ORM\Query\QueryException;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Persistence\Mapping\MappingException;
use Psr\Cache\CacheItemPoolInterface;
use Traversable;
use function array_map;
use function array_shift;
use function assert;
use function count;
use function is_array;
use function is_numeric;
@@ -47,6 +36,7 @@ use function is_scalar;
use function iterator_count;
use function iterator_to_array;
use function ksort;
use function method_exists;
use function reset;
use function serialize;
use function sha1;
@@ -85,6 +75,11 @@ abstract class AbstractQuery
*/
public const HYDRATE_SIMPLEOBJECT = 5;
/**
* Hydrates scalar column value.
*/
public const HYDRATE_SCALAR_COLUMN = 6;
/**
* The parameter map of this query.
*
@@ -131,7 +126,7 @@ abstract class AbstractQuery
*/
protected $_expireResultCache = false;
/** @var QueryCacheProfile */
/** @var QueryCacheProfile|null */
protected $_hydrationCacheProfile;
/**
@@ -186,7 +181,7 @@ abstract class AbstractQuery
*
* @param bool $cacheable
*
* @return static This query instance.
* @return $this
*/
public function setCacheable($cacheable)
{
@@ -206,7 +201,7 @@ abstract class AbstractQuery
/**
* @param string $cacheRegion
*
* @return static This query instance.
* @return $this
*/
public function setCacheRegion($cacheRegion)
{
@@ -246,7 +241,7 @@ abstract class AbstractQuery
*
* @param int $lifetime
*
* @return static This query instance.
* @return $this
*/
public function setLifetime($lifetime)
{
@@ -266,7 +261,7 @@ abstract class AbstractQuery
/**
* @param int $cacheMode
*
* @return static This query instance.
* @return $this
*/
public function setCacheMode($cacheMode)
{
@@ -347,7 +342,7 @@ abstract class AbstractQuery
* @param ArrayCollection|mixed[] $parameters
* @psalm-param ArrayCollection<int, Parameter>|mixed[] $parameters
*
* @return static This query instance.
* @return $this
*/
public function setParameters($parameters)
{
@@ -377,7 +372,7 @@ abstract class AbstractQuery
* the type conversion of this type. This is usually not needed for
* strings and numeric types.
*
* @return static This query instance.
* @return $this
*/
public function setParameter($key, $value, $type = null)
{
@@ -484,7 +479,7 @@ abstract class AbstractQuery
/**
* Sets the ResultSetMapping that should be used for hydration.
*
* @return static This query instance.
* @return $this
*/
public function setResultSetMapping(Query\ResultSetMapping $rsm)
{
@@ -529,7 +524,7 @@ abstract class AbstractQuery
* some form of caching with UnitOfWork registration you should use
* {@see AbstractQuery::setResultCacheProfile()}.
*
* @return static This query instance.
* @return $this
*
* @example
* $lifetime = 100;
@@ -539,9 +534,25 @@ abstract class AbstractQuery
*/
public function setHydrationCacheProfile(?QueryCacheProfile $profile = null)
{
if ($profile !== null && ! $profile->getResultCacheDriver()) {
$resultCacheDriver = $this->_em->getConfiguration()->getHydrationCacheImpl();
$profile = $profile->setResultCacheDriver($resultCacheDriver);
if ($profile === null) {
$this->_hydrationCacheProfile = null;
return $this;
}
// DBAL < 3.2
if (! method_exists(QueryCacheProfile::class, 'setResultCache')) {
if (! $profile->getResultCacheDriver()) {
$defaultHydrationCacheImpl = $this->_em->getConfiguration()->getHydrationCache();
if ($defaultHydrationCacheImpl) {
$profile = $profile->setResultCacheDriver(DoctrineProvider::wrap($defaultHydrationCacheImpl));
}
}
} elseif (! $profile->getResultCache()) {
$defaultHydrationCacheImpl = $this->_em->getConfiguration()->getHydrationCache();
if ($defaultHydrationCacheImpl) {
$profile = $profile->setResultCache($defaultHydrationCacheImpl);
}
}
$this->_hydrationCacheProfile = $profile;
@@ -550,7 +561,7 @@ abstract class AbstractQuery
}
/**
* @return QueryCacheProfile
* @return QueryCacheProfile|null
*/
public function getHydrationCacheProfile()
{
@@ -563,13 +574,29 @@ abstract class AbstractQuery
* If no result cache driver is set in the QueryCacheProfile, the default
* result cache driver is used from the configuration.
*
* @return static This query instance.
* @return $this
*/
public function setResultCacheProfile(?QueryCacheProfile $profile = null)
{
if ($profile !== null && ! $profile->getResultCacheDriver()) {
$resultCacheDriver = $this->_em->getConfiguration()->getResultCacheImpl();
$profile = $profile->setResultCacheDriver($resultCacheDriver);
if ($profile === null) {
$this->_queryCacheProfile = null;
return $this;
}
// DBAL < 3.2
if (! method_exists(QueryCacheProfile::class, 'setResultCache')) {
if (! $profile->getResultCacheDriver()) {
$defaultResultCacheDriver = $this->_em->getConfiguration()->getResultCache();
if ($defaultResultCacheDriver) {
$profile = $profile->setResultCacheDriver(DoctrineProvider::wrap($defaultResultCacheDriver));
}
}
} elseif (! $profile->getResultCache()) {
$defaultResultCache = $this->_em->getConfiguration()->getResultCache();
if ($defaultResultCache) {
$profile = $profile->setResultCache($defaultResultCache);
}
}
$this->_queryCacheProfile = $profile;
@@ -580,22 +607,53 @@ abstract class AbstractQuery
/**
* Defines a cache driver to be used for caching result sets and implicitly enables caching.
*
* @deprecated Use {@see setResultCache()} instead.
*
* @param \Doctrine\Common\Cache\Cache|null $resultCacheDriver Cache driver
*
* @return static This query instance.
* @return $this
*
* @throws ORMException
* @throws InvalidResultCacheDriver
*/
public function setResultCacheDriver($resultCacheDriver = null)
{
/** @phpstan-ignore-next-line */
if ($resultCacheDriver !== null && ! ($resultCacheDriver instanceof \Doctrine\Common\Cache\Cache)) {
throw ORMException::invalidResultCacheDriver();
throw InvalidResultCacheDriver::create();
}
return $this->setResultCache($resultCacheDriver ? CacheAdapter::wrap($resultCacheDriver) : null);
}
/**
* Defines a cache driver to be used for caching result sets and implicitly enables caching.
*
* @return $this
*/
public function setResultCache(?CacheItemPoolInterface $resultCache = null)
{
if ($resultCache === null) {
if ($this->_queryCacheProfile) {
$this->_queryCacheProfile = new QueryCacheProfile($this->_queryCacheProfile->getLifetime(), $this->_queryCacheProfile->getCacheKey());
}
return $this;
}
// DBAL < 3.2
if (! method_exists(QueryCacheProfile::class, 'setResultCache')) {
$resultCacheDriver = DoctrineProvider::wrap($resultCache);
$this->_queryCacheProfile = $this->_queryCacheProfile
? $this->_queryCacheProfile->setResultCacheDriver($resultCacheDriver)
: new QueryCacheProfile(0, null, $resultCacheDriver);
return $this;
}
$this->_queryCacheProfile = $this->_queryCacheProfile
? $this->_queryCacheProfile->setResultCacheDriver($resultCacheDriver)
: new QueryCacheProfile(0, null, $resultCacheDriver);
? $this->_queryCacheProfile->setResultCache($resultCache)
: new QueryCacheProfile(0, null, $resultCache);
return $this;
}
@@ -626,7 +684,7 @@ abstract class AbstractQuery
* @param int $lifetime How long the cache entry is valid, in seconds.
* @param string $resultCacheId ID to use for the cache entry.
*
* @return static This query instance.
* @return $this
*/
public function useResultCache($useCache, $lifetime = null, $resultCacheId = null)
{
@@ -642,7 +700,7 @@ abstract class AbstractQuery
* @param int|null $lifetime How long the cache entry is valid, in seconds.
* @param string|null $resultCacheId ID to use for the cache entry.
*
* @return static This query instance.
* @return $this
*/
public function enableResultCache(?int $lifetime = null, ?string $resultCacheId = null): self
{
@@ -655,7 +713,7 @@ abstract class AbstractQuery
/**
* Disables caching of the results of this query.
*
* @return static This query instance.
* @return $this
*/
public function disableResultCache(): self
{
@@ -669,15 +727,33 @@ abstract class AbstractQuery
*
* @param int|null $lifetime How long the cache entry is valid, in seconds.
*
* @return static This query instance.
* @return $this
*/
public function setResultCacheLifetime($lifetime)
{
$lifetime = $lifetime !== null ? (int) $lifetime : 0;
$lifetime = (int) $lifetime;
$this->_queryCacheProfile = $this->_queryCacheProfile
? $this->_queryCacheProfile->setLifetime($lifetime)
: new QueryCacheProfile($lifetime, null, $this->_em->getConfiguration()->getResultCacheImpl());
if ($this->_queryCacheProfile) {
$this->_queryCacheProfile = $this->_queryCacheProfile->setLifetime($lifetime);
return $this;
}
$this->_queryCacheProfile = new QueryCacheProfile($lifetime);
$cache = $this->_em->getConfiguration()->getResultCache();
if (! $cache) {
return $this;
}
// Compatibility for DBAL < 3.2
if (! method_exists($this->_queryCacheProfile, 'setResultCache')) {
$this->_queryCacheProfile = $this->_queryCacheProfile->setResultCacheDriver(DoctrineProvider::wrap($cache));
return $this;
}
$this->_queryCacheProfile = $this->_queryCacheProfile->setResultCache($cache);
return $this;
}
@@ -699,7 +775,7 @@ abstract class AbstractQuery
*
* @param bool $expire Whether or not to force resultset cache expiration.
*
* @return static This query instance.
* @return $this
*/
public function expireResultCache($expire = true)
{
@@ -735,7 +811,7 @@ abstract class AbstractQuery
* @param string $assocName
* @param int $fetchMode
*
* @return static This query instance.
* @return $this
*/
public function setFetchMode($class, $assocName, $fetchMode)
{
@@ -754,7 +830,7 @@ abstract class AbstractQuery
* @param string|int $hydrationMode Doctrine processing mode to be used during hydration process.
* One of the Query::HYDRATE_* constants.
*
* @return static This query instance.
* @return $this
*/
public function setHydrationMode($hydrationMode)
{
@@ -799,6 +875,18 @@ abstract class AbstractQuery
return $this->execute(null, self::HYDRATE_ARRAY);
}
/**
* Gets one-dimensional array of results for the query.
*
* Alias for execute(null, HYDRATE_SCALAR_COLUMN).
*
* @return mixed[]
*/
public function getSingleColumnResult()
{
return $this->execute(null, self::HYDRATE_SCALAR_COLUMN);
}
/**
* Gets the scalar results for the query.
*
@@ -886,7 +974,6 @@ abstract class AbstractQuery
*
* @throws NoResultException If the query returned no result.
* @throws NonUniqueResultException If the query result is not unique.
* @throws NoResultException If the query returned no result.
*/
public function getSingleScalarResult()
{
@@ -899,7 +986,7 @@ abstract class AbstractQuery
* @param string $name The name of the hint.
* @param mixed $value The value of the hint.
*
* @return static This query instance.
* @return $this
*/
public function setHint($name, $value)
{
@@ -1053,9 +1140,9 @@ abstract class AbstractQuery
if ($this->_hydrationCacheProfile !== null) {
[$cacheKey, $realCacheKey] = $this->getHydrationCacheId();
$queryCacheProfile = $this->getHydrationCacheProfile();
$cache = $queryCacheProfile->getResultCacheDriver();
$result = $cache->fetch($cacheKey);
$cache = $this->getHydrationCache();
$cacheItem = $cache->getItem($cacheKey);
$result = $cacheItem->isHit() ? $cacheItem->get() : [];
if (isset($result[$realCacheKey])) {
return $result[$realCacheKey];
@@ -1065,10 +1152,8 @@ abstract class AbstractQuery
$result = [];
}
$setCacheEntry = static function ($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile): void {
$result[$realCacheKey] = $data;
$cache->save($cacheKey, $result, $queryCacheProfile->getLifetime());
$setCacheEntry = static function ($data) use ($cache, $result, $cacheItem, $realCacheKey): void {
$cache->save($cacheItem->set($result + [$realCacheKey => $data]));
};
}
@@ -1088,6 +1173,24 @@ abstract class AbstractQuery
return $data;
}
private function getHydrationCache(): CacheItemPoolInterface
{
assert($this->_hydrationCacheProfile !== null);
// Support for DBAL < 3.2
if (! method_exists($this->_hydrationCacheProfile, 'getResultCache')) {
$cacheDriver = $this->_hydrationCacheProfile->getResultCacheDriver();
assert($cacheDriver !== null);
return CacheAdapter::wrap($cacheDriver);
}
$cache = $this->_hydrationCacheProfile->getResultCache();
assert($cache !== null);
return $cache;
}
/**
* Load from second level cache or executes the query and put into cache.
*
@@ -1150,7 +1253,8 @@ abstract class AbstractQuery
* Will return the configured id if it exists otherwise a hash will be
* automatically generated for you.
*
* @return array<string, string> ($key, $hash)
* @return string[] ($key, $hash)
* @psalm-return array{string, string} ($key, $hash)
*/
protected function getHydrationCacheId()
{
@@ -1166,6 +1270,7 @@ abstract class AbstractQuery
$hints['hydrationMode'] = $this->getHydrationMode();
ksort($hints);
assert($queryCacheProfile !== null);
return $queryCacheProfile->generateCacheKeys($sql, $parameters, $hints);
}
@@ -1175,15 +1280,17 @@ abstract class AbstractQuery
* If this is not explicitly set by the developer then a hash is automatically
* generated for you.
*
* @param string $id
* @param string|null $id
*
* @return static This query instance.
* @return $this
*/
public function setResultCacheId($id)
{
$this->_queryCacheProfile = $this->_queryCacheProfile
? $this->_queryCacheProfile->setCacheKey($id)
: new QueryCacheProfile(0, $id, $this->_em->getConfiguration()->getResultCacheImpl());
if (! $this->_queryCacheProfile) {
return $this->setResultCacheProfile(new QueryCacheProfile(0, $id));
}
$this->_queryCacheProfile = $this->_queryCacheProfile->setCacheKey($id);
return $this;
}
@@ -1193,7 +1300,7 @@ abstract class AbstractQuery
*
* @deprecated
*
* @return string
* @return string|null
*/
public function getResultCacheId()
{
@@ -1203,9 +1310,9 @@ abstract class AbstractQuery
/**
* Executes the query and returns a the resulting Statement object.
*
* @return ResultStatement|int The executed database statement that holds
* the results, or an integer indicating how
* many rows were affected.
* @return Result|int The executed database statement that holds
* the results, or an integer indicating how
* many rows were affected.
*/
abstract protected function _doExecute();

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;

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;

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;

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;

View File

@@ -1,26 +1,10 @@
<?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;

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;

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;

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;

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;

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;

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;

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;
@@ -275,10 +259,10 @@ class DefaultCache implements Cache
return $this->queryCaches[$regionName];
}
/**
* @param ClassMetadata $metadata The entity metadata.
* @param mixed $identifier The entity identifier.
*/
/**
* @param ClassMetadata $metadata The entity metadata.
* @param mixed $identifier The entity identifier.
*/
private function buildEntityCacheKey(ClassMetadata $metadata, $identifier): EntityCacheKey
{
if (! is_array($identifier)) {

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;

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;
@@ -86,12 +70,16 @@ class DefaultCollectionHydrator implements CollectionHydrator
}
foreach ($entityEntries as $index => $entityEntry) {
$list[$index] = $this->uow->createEntity($entityEntry->class, $entityEntry->resolveAssociationEntries($this->em), self::$hints);
}
$entity = $this->uow->createEntity(
$entityEntry->class,
$entityEntry->resolveAssociationEntries($this->em),
self::$hints
);
array_walk($list, static function ($entity, $index) use ($collection) {
$collection->hydrateSet($index, $entity);
});
$list[$index] = $entity;
}
$this->uow->hydrationComplete();

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;

View File

@@ -1,28 +1,14 @@
<?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\Common\Collections\ArrayCollection;
use Doctrine\Common\Proxy\Proxy;
use Doctrine\ORM\Cache;
use Doctrine\ORM\Cache\Exception\FeatureNotImplemented;
use Doctrine\ORM\Cache\Exception\NonCacheableEntity;
use Doctrine\ORM\Cache\Logging\CacheLogger;
use Doctrine\ORM\Cache\Persister\Entity\CachedEntityPersister;
use Doctrine\ORM\EntityManagerInterface;
@@ -47,7 +33,7 @@ use function reset;
*/
class DefaultQueryCache implements QueryCache
{
/** @var EntityManagerInterface */
/** @var EntityManagerInterface */
private $em;
/** @var UnitOfWork */
@@ -186,7 +172,7 @@ class DefaultQueryCache implements QueryCache
$assocEntries = $assocRegion->getMultiple($assocKeys);
foreach ($assoc['list'] as $assocIndex => $assocId) {
$assocEntry = is_array($assocEntries) && array_key_exists($assocIndex, $assocEntries) ? $assocEntries[$assocIndex] : null;
$assocEntry = is_array($assocEntries) ? ($assocEntries[$assocIndex] ?? null) : null;
if ($assocEntry === null) {
if ($this->cacheLogger !== null) {
@@ -245,19 +231,19 @@ class DefaultQueryCache implements QueryCache
public function put(QueryCacheKey $key, ResultSetMapping $rsm, $result, array $hints = [])
{
if ($rsm->scalarMappings) {
throw new CacheException('Second level cache does not support scalar results.');
throw FeatureNotImplemented::scalarResults();
}
if (count($rsm->entityMappings) > 1) {
throw new CacheException('Second level cache does not support multiple root entities.');
throw FeatureNotImplemented::multipleRootEntities();
}
if (! $rsm->isSelect) {
throw new CacheException('Second-level cache query supports only select statements.');
throw FeatureNotImplemented::nonSelectStatements();
}
if (($hints[Query\SqlWalker::HINT_PARTIAL] ?? false) === true || ($hints[Query::HINT_FORCE_PARTIAL_LOAD] ?? false) === true) {
throw new CacheException('Second level cache does not support partial entities.');
throw FeatureNotImplemented::partialEntities();
}
if (! ($key->cacheMode & Cache::MODE_PUT)) {
@@ -270,7 +256,7 @@ class DefaultQueryCache implements QueryCache
$persister = $this->uow->getEntityPersister($entityName);
if (! $persister instanceof CachedEntityPersister) {
throw CacheException::nonCacheableEntity($entityName);
throw NonCacheableEntity::fromEntity($entityName);
}
$region = $persister->getCacheRegion();

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;

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;

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;

View File

@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
use Doctrine\ORM\Cache\CacheException as BaseCacheException;
use function sprintf;
/**
* Exception for cache.
*/
class CacheException extends BaseCacheException
{
}

View File

@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
use LogicException;
use function sprintf;
class CannotUpdateReadOnlyCollection extends CacheException
{
public static function fromEntityAndField(string $sourceEntity, string $fieldName): self
{
return new self(sprintf(
'Cannot update a readonly collection "%s#%s"',
$sourceEntity,
$fieldName
));
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
use LogicException;
use function sprintf;
class CannotUpdateReadOnlyEntity extends CacheException
{
public static function fromEntity(string $entityName): self
{
return new self(sprintf('Cannot update a readonly entity "%s"', $entityName));
}
}

View File

@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
use LogicException;
class FeatureNotImplemented extends CacheException
{
public static function scalarResults(): self
{
return new self('Second level cache does not support scalar results.');
}
public static function multipleRootEntities(): self
{
return new self('Second level cache does not support multiple root entities.');
}
public static function nonSelectStatements(): self
{
return new self('Second-level cache query supports only select statements.');
}
public static function partialEntities(): self
{
return new self('Second level cache does not support partial entities.');
}
}

View File

@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
/**
* @deprecated
*/
final class InvalidResultCacheDriver extends CacheException
{
public static function create(): self
{
return new self(
'Invalid result cache driver; it must implement Doctrine\\Common\\Cache\\Cache.'
);
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
use LogicException;
final class MetadataCacheNotConfigured extends CacheException
{
public static function create(): self
{
return new self('Class Metadata Cache is not configured.');
}
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
use Doctrine\Common\Cache\Cache;
use LogicException;
use function get_class;
final class MetadataCacheUsesNonPersistentCache extends CacheException
{
public static function fromDriver(Cache $cache): self
{
return new self(
'Metadata Cache uses a non-persistent cache driver, ' . get_class($cache) . '.'
);
}
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
use LogicException;
use function sprintf;
class NonCacheableEntity extends CacheException
{
public static function fromEntity(string $entityName): self
{
return new self(sprintf(
'Entity "%s" not configured as part of the second-level cache.',
$entityName
));
}
}

View File

@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
use function sprintf;
class NonCacheableEntityAssociation extends CacheException
{
public static function fromEntityAndField(string $entityName, string $field): self
{
return new self(sprintf(
'Entity association field "%s#%s" not configured as part of the second-level cache.',
$entityName,
$field
));
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
use LogicException;
final class QueryCacheNotConfigured extends CacheException
{
public static function create(): self
{
return new self('Query Cache is not configured.');
}
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Doctrine\ORM\Cache\Exception;
use Doctrine\Common\Cache\Cache;
use LogicException;
use function get_class;
final class QueryCacheUsesNonPersistentCache extends CacheException
{
public static function fromDriver(Cache $cache): self
{
return new self(
'Query Cache uses a non-persistent cache driver, ' . get_class($cache) . '.'
);
}
}

View File

@@ -1,31 +1,12 @@
<?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 function time;
use function uniqid;
/**
* Cache Lock
*/
class Lock
{
/** @var string */
@@ -34,14 +15,10 @@ class Lock
/** @var int */
public $time;
/**
* @param string $value
* @param int $time
*/
public function __construct($value, $time = null)
public function __construct(string $value, ?int $time = null)
{
$this->value = $value;
$this->time = $time ? : time();
$this->time = $time ?: time();
}
/**
@@ -49,6 +26,6 @@ class Lock
*/
public static function createLockRead()
{
return new self(uniqid(time(), true));
return new self(uniqid((string) time(), true));
}
}

View File

@@ -1,25 +1,11 @@
<?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\Cache\Exception\CacheException;
/**
* Lock exception for cache.
*/

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\Logging;
@@ -53,12 +37,12 @@ interface CacheLogger
*/
public function entityCacheMiss($regionName, EntityCacheKey $key);
/**
* Log an entity put into second level cache.
*
* @param string $regionName The name of the cache region.
* @param CollectionCacheKey $key The cache key of the collection.
*/
/**
* Log an entity put into second level cache.
*
* @param string $regionName The name of the cache region.
* @param CollectionCacheKey $key The cache key of the collection.
*/
public function collectionCachePut($regionName, CollectionCacheKey $key);
/**

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\Logging;
@@ -24,9 +8,6 @@ use Doctrine\ORM\Cache\CollectionCacheKey;
use Doctrine\ORM\Cache\EntityCacheKey;
use Doctrine\ORM\Cache\QueryCacheKey;
/**
* Cache logger chain
*/
class CacheLoggerChain implements CacheLogger
{
/** @var array<CacheLogger> */

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\Logging;

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;

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\Persister;

View File

@@ -1,25 +1,10 @@
<?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\Persister\Collection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\ORM\Cache\CollectionCacheKey;
@@ -38,11 +23,10 @@ use Doctrine\ORM\UnitOfWork;
use function array_values;
use function assert;
use function count;
use function is_array;
abstract class AbstractCollectionPersister implements CachedCollectionPersister
{
/** @var UnitOfWork */
/** @var UnitOfWork */
protected $uow;
/** @var ClassMetadataFactory */
@@ -60,7 +44,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
/** @var mixed[] */
protected $association;
/** @var mixed[] */
/** @var mixed[] */
protected $queuedCache = [];
/** @var Region */
@@ -151,7 +135,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
// Only preserve ordering if association configured it
if (! (isset($associationMapping['indexBy']) && $associationMapping['indexBy'])) {
// Elements may be an array or a Collection
$elements = array_values(is_array($elements) ? $elements : $elements->getValues());
$elements = array_values($elements instanceof Collection ? $elements->getValues() : $elements);
}
$entry = $this->hydrator->buildCacheEntry($this->targetEntity, $key, $elements);

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\Persister\Collection;

View File

@@ -1,29 +1,13 @@
<?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\Persister\Collection;
use Doctrine\ORM\Cache\CollectionCacheKey;
use Doctrine\ORM\PersistentCollection;
use function spl_object_hash;
use function spl_object_id;
class NonStrictReadWriteCachedCollectionPersister extends AbstractCollectionPersister
{
@@ -65,7 +49,7 @@ class NonStrictReadWriteCachedCollectionPersister extends AbstractCollectionPers
$this->persister->delete($collection);
$this->queuedCache['delete'][spl_object_hash($collection)] = $key;
$this->queuedCache['delete'][spl_object_id($collection)] = $key;
}
/**
@@ -87,14 +71,14 @@ class NonStrictReadWriteCachedCollectionPersister extends AbstractCollectionPers
if ($isDirty && ! $isInitialized || isset($this->association['orderBy'])) {
$this->persister->update($collection);
$this->queuedCache['delete'][spl_object_hash($collection)] = $key;
$this->queuedCache['delete'][spl_object_id($collection)] = $key;
return;
}
$this->persister->update($collection);
$this->queuedCache['update'][spl_object_hash($collection)] = [
$this->queuedCache['update'][spl_object_id($collection)] = [
'key' => $key,
'list' => $collection,
];

View File

@@ -1,27 +1,12 @@
<?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\Persister\Collection;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\ORM\Cache\CacheException;
use Doctrine\ORM\Cache\Exception\CannotUpdateReadOnlyCollection;
use Doctrine\ORM\PersistentCollection;
class ReadOnlyCachedCollectionPersister extends NonStrictReadWriteCachedCollectionPersister
@@ -32,7 +17,10 @@ class ReadOnlyCachedCollectionPersister extends NonStrictReadWriteCachedCollecti
public function update(PersistentCollection $collection)
{
if ($collection->isDirty() && $collection->getSnapshot()) {
throw CacheException::updateReadOnlyCollection(ClassUtils::getClass($collection->getOwner()), $this->association['fieldName']);
throw CannotUpdateReadOnlyCollection::fromEntityAndField(
ClassUtils::getClass($collection->getOwner()),
$this->association['fieldName']
);
}
parent::update($collection);

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\Persister\Collection;
@@ -26,7 +10,7 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Persisters\Collection\CollectionPersister;
use function spl_object_hash;
use function spl_object_id;
class ReadWriteCachedCollectionPersister extends AbstractCollectionPersister
{
@@ -96,7 +80,7 @@ class ReadWriteCachedCollectionPersister extends AbstractCollectionPersister
return;
}
$this->queuedCache['delete'][spl_object_hash($collection)] = [
$this->queuedCache['delete'][spl_object_id($collection)] = [
'key' => $key,
'lock' => $lock,
];
@@ -124,7 +108,7 @@ class ReadWriteCachedCollectionPersister extends AbstractCollectionPersister
return;
}
$this->queuedCache['update'][spl_object_hash($collection)] = [
$this->queuedCache['update'][spl_object_id($collection)] = [
'key' => $key,
'lock' => $lock,
];

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\Persister\Entity;
@@ -57,7 +41,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
/** @var ClassMetadata */
protected $class;
/** @var mixed[] */
/** @var mixed[] */
protected $queuedCache = [];
/** @var Region */
@@ -373,9 +357,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
$cached = $queryCache->put($queryKey, $rsm, [$result]);
if ($this->cacheLogger) {
if ($result) {
$this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
}
$this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
if ($cached) {
$this->cacheLogger->queryCachePut($this->regionName, $queryKey);

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\Persister\Entity;

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\Persister\Entity;

View File

@@ -1,27 +1,11 @@
<?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\Persister\Entity;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\ORM\Cache\CacheException;
use Doctrine\ORM\Cache\Exception\CannotUpdateReadOnlyEntity;
/**
* Specific read-only region entity persister
@@ -33,6 +17,6 @@ class ReadOnlyCachedEntityPersister extends NonStrictReadWriteCachedEntityPersis
*/
public function update($entity)
{
throw CacheException::updateReadOnlyEntity(ClassUtils::getClass($entity));
throw CannotUpdateReadOnlyEntity::fromEntity(ClassUtils::getClass($entity));
}
}

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\Persister\Entity;

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;

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;

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;
@@ -48,18 +32,13 @@ class QueryCacheKey extends CacheKey
*/
public $timestampKey;
/**
* @param string $hash Result cache id
* @param int $lifetime Query lifetime
* @param int $cacheMode Query cache mode
*/
public function __construct(
$hash,
$lifetime = 0,
$cacheMode = Cache::MODE_NORMAL,
string $cacheId,
int $lifetime = 0,
int $cacheMode = Cache::MODE_NORMAL,
?TimestampCacheKey $timestampKey = null
) {
$this->hash = $hash;
$this->hash = $cacheId;
$this->lifetime = $lifetime;
$this->cacheMode = $cacheMode;
$this->timestampKey = $timestampKey;

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;

View File

@@ -1,25 +1,11 @@
<?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\Cache\Exception\CacheException;
/**
* Defines a contract for accessing a particular named region.
*/

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\Region;

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\Region;

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\Region;

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\Region;

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;

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;

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;

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;

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;

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;
@@ -31,6 +15,16 @@ use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\Common\Proxy\AbstractProxyFactory;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\Cache\CacheConfiguration;
use Doctrine\ORM\Cache\Exception\CacheException;
use Doctrine\ORM\Cache\Exception\MetadataCacheNotConfigured;
use Doctrine\ORM\Cache\Exception\MetadataCacheUsesNonPersistentCache;
use Doctrine\ORM\Cache\Exception\QueryCacheNotConfigured;
use Doctrine\ORM\Cache\Exception\QueryCacheUsesNonPersistentCache;
use Doctrine\ORM\Exception\InvalidEntityRepository;
use Doctrine\ORM\Exception\NamedNativeQueryNotFound;
use Doctrine\ORM\Exception\NamedQueryNotFound;
use Doctrine\ORM\Exception\ProxyClassesAlwaysRegenerating;
use Doctrine\ORM\Exception\UnknownEntityNamespace;
use Doctrine\ORM\Mapping\ClassMetadataFactory;
use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
@@ -48,6 +42,7 @@ use Psr\Cache\CacheItemPoolInterface;
use ReflectionClass;
use function class_exists;
use function method_exists;
use function strtolower;
use function trim;
@@ -59,6 +54,9 @@ use function trim;
*/
class Configuration extends \Doctrine\DBAL\Configuration
{
/** @var mixed[] */
protected $_attributes = [];
/**
* Sets the directory where Doctrine generates any necessary proxy class files.
*
@@ -203,12 +201,19 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @return string
*
* @throws ORMException
* @throws UnknownEntityNamespace
*/
public function getEntityNamespace($entityNamespaceAlias)
{
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/issues/8818',
'Entity short namespace aliases such as "%s" are deprecated, use ::class constant instead.',
$entityNamespaceAlias
);
if (! isset($this->_attributes['entityNamespaces'][$entityNamespaceAlias])) {
throw ORMException::unknownEntityNamespace($entityNamespaceAlias);
throw UnknownEntityNamespace::fromNamespaceAlias($entityNamespaceAlias);
}
return trim($this->_attributes['entityNamespaces'][$entityNamespaceAlias], '\\');
@@ -240,54 +245,148 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Gets the cache driver implementation that is used for the mapping metadata.
*
* @return MappingDriver|null
*
* @throws ORMException
*/
public function getMetadataDriverImpl()
{
return $this->_attributes['metadataDriverImpl'] ?? null;
}
/**
* Gets the cache driver implementation that is used for query result caching.
*/
public function getResultCache(): ?CacheItemPoolInterface
{
// Compatibility with DBAL < 3.2
if (! method_exists(parent::class, 'getResultCache')) {
$cacheImpl = $this->getResultCacheImpl();
return $cacheImpl ? CacheAdapter::wrap($cacheImpl) : null;
}
return parent::getResultCache();
}
/**
* Sets the cache driver implementation that is used for query result caching.
*/
public function setResultCache(CacheItemPoolInterface $cache): void
{
// Compatibility with DBAL < 3.2
if (! method_exists(parent::class, 'setResultCache')) {
$this->setResultCacheImpl(DoctrineProvider::wrap($cache));
return;
}
parent::setResultCache($cache);
}
/**
* Gets the cache driver implementation that is used for the query cache (SQL cache).
*
* @deprecated Call {@see getQueryCache()} instead.
*
* @return CacheDriver|null
*/
public function getQueryCacheImpl()
{
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9002',
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use getQueryCache() instead.',
__METHOD__
);
return $this->_attributes['queryCacheImpl'] ?? null;
}
/**
* Sets the cache driver implementation that is used for the query cache (SQL cache).
*
* @deprecated Call {@see setQueryCache()} instead.
*
* @return void
*/
public function setQueryCacheImpl(CacheDriver $cacheImpl)
{
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9002',
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use setQueryCache() instead.',
__METHOD__
);
$this->_attributes['queryCache'] = CacheAdapter::wrap($cacheImpl);
$this->_attributes['queryCacheImpl'] = $cacheImpl;
}
/**
* Gets the cache driver implementation that is used for the query cache (SQL cache).
*/
public function getQueryCache(): ?CacheItemPoolInterface
{
return $this->_attributes['queryCache'] ?? null;
}
/**
* Sets the cache driver implementation that is used for the query cache (SQL cache).
*/
public function setQueryCache(CacheItemPoolInterface $cache): void
{
$this->_attributes['queryCache'] = $cache;
$this->_attributes['queryCacheImpl'] = DoctrineProvider::wrap($cache);
}
/**
* Gets the cache driver implementation that is used for the hydration cache (SQL cache).
*
* @deprecated Call {@see getHydrationCache()} instead.
*
* @return CacheDriver|null
*/
public function getHydrationCacheImpl()
{
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9002',
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use getHydrationCache() instead.',
__METHOD__
);
return $this->_attributes['hydrationCacheImpl'] ?? null;
}
/**
* Sets the cache driver implementation that is used for the hydration cache (SQL cache).
*
* @deprecated Call {@see setHydrationCache()} instead.
*
* @return void
*/
public function setHydrationCacheImpl(CacheDriver $cacheImpl)
{
Deprecation::trigger(
'doctrine/orm',
'https://github.com/doctrine/orm/pull/9002',
'Method %s() is deprecated and will be removed in Doctrine ORM 3.0. Use setHydrationCache() instead.',
__METHOD__
);
$this->_attributes['hydrationCache'] = CacheAdapter::wrap($cacheImpl);
$this->_attributes['hydrationCacheImpl'] = $cacheImpl;
}
public function getHydrationCache(): ?CacheItemPoolInterface
{
return $this->_attributes['hydrationCache'] ?? null;
}
public function setHydrationCache(CacheItemPoolInterface $cache): void
{
$this->_attributes['hydrationCache'] = $cache;
$this->_attributes['hydrationCacheImpl'] = DoctrineProvider::wrap($cache);
}
/**
* Gets the cache driver implementation that is used for metadata caching.
*
@@ -362,12 +461,12 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @return string The DQL query.
*
* @throws ORMException
* @throws NamedQueryNotFound
*/
public function getNamedQuery($name)
{
if (! isset($this->_attributes['namedQueries'][$name])) {
throw ORMException::namedQueryNotFound($name);
throw NamedQueryNotFound::fromName($name);
}
return $this->_attributes['namedQueries'][$name];
@@ -396,12 +495,12 @@ class Configuration extends \Doctrine\DBAL\Configuration
* @psalm-return array{string, ResultSetMapping} A tuple with the first element being the SQL string and the second
* element being the ResultSetMapping.
*
* @throws ORMException
* @throws NamedNativeQueryNotFound
*/
public function getNamedNativeQuery($name)
{
if (! isset($this->_attributes['namedNativeQueries'][$name])) {
throw ORMException::namedNativeQueryNotFound($name);
throw NamedNativeQueryNotFound::fromName($name);
}
return $this->_attributes['namedNativeQueries'][$name];
@@ -413,33 +512,34 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @return void
*
* @throws ORMException If a configuration setting has a value that is not
* suitable for a production environment.
* @throws ProxyClassesAlwaysRegenerating
* @throws CacheException If a configuration setting has a value that is not
* suitable for a production environment.
*/
public function ensureProductionSettings()
{
$queryCacheImpl = $this->getQueryCacheImpl();
if (! $queryCacheImpl) {
throw ORMException::queryCacheNotConfigured();
throw QueryCacheNotConfigured::create();
}
if ($queryCacheImpl instanceof ArrayCache) {
throw ORMException::queryCacheUsesNonPersistentCache($queryCacheImpl);
throw QueryCacheUsesNonPersistentCache::fromDriver($queryCacheImpl);
}
if ($this->getAutoGenerateProxyClasses()) {
throw ORMException::proxyClassesAlwaysRegenerating();
throw ProxyClassesAlwaysRegenerating::create();
}
if (! $this->getMetadataCache()) {
throw ORMException::metadataCacheNotConfigured();
throw MetadataCacheNotConfigured::create();
}
$metadataCacheImpl = $this->getMetadataCacheImpl();
if ($metadataCacheImpl instanceof ArrayCache) {
throw ORMException::metadataCacheUsesNonPersistentCache($metadataCacheImpl);
throw MetadataCacheUsesNonPersistentCache::fromDriver($metadataCacheImpl);
}
}
@@ -703,14 +803,14 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @return void
*
* @throws ORMException If $classname is not an ObjectRepository.
* @throws InvalidEntityRepository If $classname is not an ObjectRepository.
*/
public function setDefaultRepositoryClassName($className)
{
$reflectionClass = new ReflectionClass($className);
if (! $reflectionClass->implementsInterface(ObjectRepository::class)) {
throw ORMException::invalidEntityRepository($className);
throw InvalidEntityRepository::fromClassName($className);
}
$this->_attributes['defaultRepositoryClassName'] = $className;

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\Decorator;
@@ -24,6 +8,13 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Persistence\ObjectManagerDecorator;
use function get_class;
use function method_exists;
use function sprintf;
use function trigger_error;
use const E_USER_NOTICE;
/**
* Base class for EntityManager decorators
*/
@@ -69,6 +60,23 @@ abstract class EntityManagerDecorator extends ObjectManagerDecorator implements
return $this->wrapped->transactional($func);
}
/**
* {@inheritdoc}
*/
public function wrapInTransaction(callable $func)
{
if (! method_exists($this->wrapped, 'wrapInTransaction')) {
trigger_error(
sprintf('Calling `transactional()` instead of `wrapInTransaction()` which is not implemented on %s', get_class($this->wrapped)),
E_USER_NOTICE
);
return $this->wrapped->transactional($func);
}
return $this->wrapped->wrapInTransaction($func);
}
/**
* {@inheritdoc}
*/

View File

@@ -1,34 +1,23 @@
<?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 BadMethodCallException;
use Doctrine\Common\Cache\Psr6\CacheAdapter;
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\Common\EventManager;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\LockMode;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\Exception\EntityManagerClosed;
use Doctrine\ORM\Exception\InvalidHydrationMode;
use Doctrine\ORM\Exception\MismatchedEventManager;
use Doctrine\ORM\Exception\MissingIdentifierField;
use Doctrine\ORM\Exception\MissingMappingDriverImplementation;
use Doctrine\ORM\Exception\UnrecognizedIdentifierFields;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataFactory;
use Doctrine\ORM\Proxy\ProxyFactory;
@@ -50,7 +39,6 @@ use function is_callable;
use function is_object;
use function is_string;
use function ltrim;
use function method_exists;
use function sprintf;
/**
@@ -258,6 +246,28 @@ use function sprintf;
}
}
/**
* {@inheritDoc}
*/
public function wrapInTransaction(callable $func)
{
$this->conn->beginTransaction();
try {
$return = $func($this);
$this->flush();
$this->conn->commit();
return $return;
} catch (Throwable $e) {
$this->close();
$this->conn->rollBack();
throw $e;
}
}
/**
* {@inheritDoc}
*/
@@ -430,7 +440,7 @@ use function sprintf;
foreach ($class->identifier as $identifier) {
if (! isset($id[$identifier])) {
throw ORMException::missingIdentifierField($class->name, $identifier);
throw MissingIdentifierField::fromFieldAndClass($identifier, $class->name);
}
$sortedId[$identifier] = $id[$identifier];
@@ -438,7 +448,7 @@ use function sprintf;
}
if ($id) {
throw ORMException::unrecognizedIdentifierFields($class->name, array_keys($id));
throw UnrecognizedIdentifierFields::fromClassAndFieldNames($class->name, array_keys($id));
}
$unitOfWork = $this->getUnitOfWork();
@@ -473,7 +483,9 @@ use function sprintf;
case $lockMode === LockMode::OPTIMISTIC:
$entity = $persister->load($sortedId);
$unitOfWork->lock($entity, $lockMode, $lockVersion);
if ($entity !== null) {
$unitOfWork->lock($entity, $lockMode, $lockVersion);
}
return $entity;
@@ -501,7 +513,7 @@ use function sprintf;
foreach ($class->identifier as $identifier) {
if (! isset($id[$identifier])) {
throw ORMException::missingIdentifierField($class->name, $identifier);
throw MissingIdentifierField::fromFieldAndClass($identifier, $class->name);
}
$sortedId[$identifier] = $id[$identifier];
@@ -509,7 +521,7 @@ use function sprintf;
}
if ($id) {
throw ORMException::unrecognizedIdentifierFields($class->name, array_keys($id));
throw UnrecognizedIdentifierFields::fromClassAndFieldNames($class->name, array_keys($id));
}
$entity = $this->unitOfWork->tryGetById($sortedId, $class->rootEntityName);
@@ -801,12 +813,12 @@ use function sprintf;
/**
* Throws an exception if the EntityManager is closed or currently not active.
*
* @throws ORMException If the EntityManager is closed.
* @throws EntityManagerClosed If the EntityManager is closed.
*/
private function errorIfClosed(): void
{
if ($this->closed) {
throw ORMException::entityManagerClosed();
throw EntityManagerClosed::create();
}
}
@@ -855,6 +867,9 @@ use function sprintf;
case Query::HYDRATE_SIMPLEOBJECT:
return new Internal\Hydration\SimpleObjectHydrator($this);
case Query::HYDRATE_SCALAR_COLUMN:
return new Internal\Hydration\ScalarColumnHydrator($this);
default:
$class = $this->config->getCustomHydrationMode($hydrationMode);
@@ -863,7 +878,7 @@ use function sprintf;
}
}
throw ORMException::invalidHydrationMode($hydrationMode);
throw InvalidHydrationMode::fromMode((string) $hydrationMode);
}
/**
@@ -898,7 +913,7 @@ use function sprintf;
public static function create($connection, Configuration $config, ?EventManager $eventManager = null)
{
if (! $config->getMetadataDriverImpl()) {
throw ORMException::missingMappingDriverImpl();
throw MissingMappingDriverImplementation::create();
}
$connection = static::createConnection($connection, $config, $eventManager);
@@ -936,7 +951,7 @@ use function sprintf;
}
if ($eventManager !== null && $connection->getEventManager() !== $eventManager) {
throw ORMException::mismatchedEventManager();
throw MismatchedEventManager::create();
}
return $connection;
@@ -1000,15 +1015,7 @@ use function sprintf;
return;
}
// We have a PSR-6 compatible metadata factory. Use cache directly
if (method_exists($this->metadataFactory, 'setCache')) {
$this->metadataFactory->setCache($metadataCache);
return;
}
// Wrap PSR-6 cache to provide doctrine/cache interface
$this->metadataFactory->setCacheDriver(DoctrineProvider::wrap($metadataCache));
$this->metadataFactory->setCache($metadataCache);
}
private function configureLegacyMetadataCache(): void
@@ -1018,13 +1025,6 @@ use function sprintf;
return;
}
// Metadata factory is not PSR-6 compatible. Use cache directly
if (! method_exists($this->metadataFactory, 'setCache')) {
$this->metadataFactory->setCacheDriver($metadataCache);
return;
}
// Wrap doctrine/cache to provide PSR-6 interface
$this->metadataFactory->setCache(CacheAdapter::wrap($metadataCache));
}

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;
@@ -35,6 +19,7 @@ use Doctrine\Persistence\ObjectManager;
* EntityManager interface
*
* @method Mapping\ClassMetadataFactory getMetadataFactory()
* @method mixed wrapInTransaction(callable $func)
*/
interface EntityManagerInterface extends ObjectManager
{
@@ -96,12 +81,32 @@ interface EntityManagerInterface extends ObjectManager
* If an exception occurs during execution of the function or flushing or transaction commit,
* the transaction is rolled back, the EntityManager closed and the exception re-thrown.
*
* @deprecated 2.10 Use {@link wrapInTransaction} instead.
*
* @param callable $func The function to execute transactionally.
*
* @return mixed The non-empty value returned from the closure or true instead.
*/
public function transactional($func);
/**
* Executes a function in a transaction.
*
* The function gets passed this EntityManager instance as an (optional) parameter.
*
* {@link flush} is invoked prior to transaction commit.
*
* If an exception occurs during execution of the function or flushing or transaction commit,
* the transaction is rolled back, the EntityManager closed and the exception re-thrown.
*
* @param callable(self): T $func The function to execute transactionally.
*
* @return T The value returned from the closure.
*
* @template T
*/
// public function wrapInTransaction(callable $func);
/**
* Commits a transaction on the underlying database connection.
*
@@ -169,7 +174,7 @@ interface EntityManagerInterface extends ObjectManager
* @psalm-param class-string<T> $entityName
*
* @return object|null The entity reference.
* @psalm-return ?T
* @psalm-return T|null
*
* @throws ORMException
*
@@ -194,8 +199,12 @@ interface EntityManagerInterface extends ObjectManager
*
* @param string $entityName The name of the entity type.
* @param mixed $identifier The entity identifier.
* @psalm-param class-string<T> $entityName
*
* @return object|null The (partial) entity reference.
* @return object|null The (partial) entity reference
* @psalm-return T|null
*
* @template T
*/
public function getPartialReference($entityName, $identifier);
@@ -321,11 +330,9 @@ interface EntityManagerInterface extends ObjectManager
* {@inheritDoc}
*
* @psalm-param string|class-string<T> $className
* @phpstan-param string $className
*
* @return Mapping\ClassMetadata
* @psalm-return Mapping\ClassMetadata<T>
* @phpstan-return Mapping\ClassMetadata<object>
*
* @psalm-template T of object
*/

View File

@@ -1,25 +1,11 @@
<?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\Exception\ORMException;
use function implode;
use function sprintf;

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