Compare commits

..

153 Commits

Author SHA1 Message Date
Benjamin Eberlei 445796af0e Travis: Use 7.4 instead of 7.4snapshot 2020-02-15 15:35:56 +01:00
Benjamin Eberlei ab93285284 Remove nightly builds from .travis.yml 2020-02-15 15:34:36 +01:00
Benjamin Eberlei a692670469 Merge pull request #8006 from doctrine/malarzm-patch-1
Make Embeddable not transient
2020-02-13 21:31:02 +01:00
Maciej Malarz 58677c29b4 Make Embeddable not transient 2020-02-13 21:05:52 +01:00
Benjamin Eberlei 9a0fcb5a86 Merge pull request #7940 from doctrine/GH-7864-ExtraLazyRemoveElement
[GH-7864] Bugfix in PersistentCollection::removeElement for EXTRA_LAZY.
2020-02-12 23:42:06 +01:00
Benjamin Eberlei 8104c65d6c Merge pull request #7987 from beberlei/GH-7982-NoSqlExecutor
[GH-7982] no sql executor leads to parse error
2020-02-12 23:37:39 +01:00
Benjamin Eberlei a64d254d07 [GH-7982] Bugfix: Passing string|null DQL to Lexer(string $input) leads to downstream notice. 2020-02-12 23:23:12 +01:00
Benjamin Eberlei fdad48278b Merge pull request #7991 from greg0ire/7.4-sa
Try running phpstan on php 7.4
2020-01-17 00:06:40 +01:00
Benjamin Eberlei fc94127d7f Make ocramius/package-versions 1.2 the lowest version for phpstan 2020-01-16 23:51:17 +01:00
Grégoire Paris dea3e5df44 Try running phpstan on php 7.4
It might be easier to find packages compatible with both our locked deps
and phpstan with that version of php.
2020-01-16 23:49:15 +01:00
Benjamin Eberlei 5d7d3e99a0 Downgrade ocramius/package-versions to lowest in composer.lock to support all PHP versions. 2020-01-16 23:18:00 +01:00
Benjamin Eberlei 3bc1096fd0 [GH-7982] Default Query state to dirty to fix execution of empty query. 2020-01-15 23:30:59 +01:00
Benjamin Eberlei a2f01f7ccc Allow everything from ocramius/package-versions ^1.0. 2020-01-15 22:56:08 +01:00
Benjamin Eberlei 401db453a2 Merge pull request #7974 from beberlei/gh-7505
[GH-7505] Bug in SimpleObjectHydrator when using inheritance with same field
2020-01-15 22:02:25 +01:00
Benjamin Eberlei 6e59ec8f16 [GH-7505] Fix cs 2020-01-15 21:52:11 +01:00
Benjamin Eberlei 87e491465a Add @group 2020-01-15 21:13:25 +01:00
Luís Cobucci 8b588eceb2 Merge pull request #7973 from DocFX/patch-1
Just a micro grammar update.
2020-01-14 11:26:21 +01:00
Benjamin Eberlei edce36598f Adjust tests back for 2.x. 2020-01-09 00:41:47 +01:00
Woody Gilk 20c46035d1 [Docs] Prefer PhpFileCache for caching and remove APC/XCache. 2020-01-08 19:36:08 +01:00
William Pinaud 324aacfb54 Just a micro grammar update. 2020-01-08 18:52:11 +01:00
Benjamin Eberlei 1edfcabead Merge pull request #7894 from TomckySan/convert-default-value-to-boolean
Fix boolean properties default value when generating entities.
2020-01-05 16:11:33 +01:00
Luís Cobucci 2785cde792 Merge pull request #7957 from lcobucci/fix-version-information
Fix version information
2019-12-17 19:19:05 +01:00
Luís Cobucci d67e3e8b1b Rely on ocramius/package-versions to render the version
Since `Doctrine\ORM\Version` is now deprecated it shall not be updated
on future releases.

This ensures that our CLI tool will present the correct version number.
2019-12-17 15:47:55 +01:00
Luís Cobucci d629c4e487 Remove build.xml and related files
We aren't using ant/phing to handle the releases any more.
2019-12-17 01:03:34 +01:00
Luís Cobucci 4a4226213f Merge pull request #7875 from nicolas-grekas/schema-tool
Whilelist existing assets we know about from metadata in SchemaTool::getUpdateSchemaSql()
2019-12-16 23:59:31 +01:00
Andreas Braun 0ce1440884 Add upgrade note about schema_filter change 2019-12-16 23:45:49 +01:00
Laurent VOULLEMIER 9aa28b4e33 Test asset whitelisting on SchemaTool#getUpdateSchemasSql() 2019-12-16 23:45:49 +01:00
Nicolas Grekas 5c2b6870bf Whitelist existing assets we know about from metadata in SchemaTool::getUpdateSchemaSql() 2019-12-16 23:22:50 +01:00
Luís Cobucci 4389b2c188 Merge pull request #7956 from lcobucci/fix-test-suite
Ignore Doctrine\Common\Persistence\ObjectManagerDecorator deprecation
2019-12-16 21:49:25 +01:00
Luís Cobucci e481d9880b Ignore Doctrine\Common\Persistence\ObjectManagerDecorator deprecation
Since applying the fixes requires bumping up the dependency, which isn't
done in a patch release.

This should be removed in v2.8.0.
2019-12-16 21:22:28 +01:00
Luís Cobucci 85528f28e2 Fix CS errors 2019-12-16 21:22:23 +01:00
Luís Cobucci 5873242fb5 Merge pull request #7937 from doctrine/GH-7930-SqliteForeignKeys
Revert SchemaTool change to check for foreign key support
2019-12-16 10:45:07 +01:00
Luís Cobucci c9e41d0aa7 Merge pull request #7934 from BenMorel/php74
Fix Trying to access array offset on value of type null
2019-12-09 21:32:58 +01:00
Benjamin Morel f37c12834d Fix Trying to access array offset on value of type null 2019-12-09 21:24:29 +01:00
Benjamin Eberlei 041404e8b3 [GH-7864] Revert removeElement EXTRA_LAZY support. 2019-12-07 00:03:09 +01:00
Benjamin Eberlei bfc68b3aba Add warning about removeElement on extra lazy 2019-12-03 20:34:44 +01:00
Benjamin Eberlei 1e628370c4 [GH-7864] Address review comments. 2019-12-03 19:35:49 +01:00
Benjamin Eberlei ae2b9b1921 Housekeeping: phpcbf to fix issues. 2019-12-01 21:11:09 +01:00
Benjamin Eberlei 419df77a09 [GH-7864] ExtraLazyCollectionTest is not cacahble and should not fail SLC suite. 2019-12-01 20:28:30 +01:00
Benjamin Eberlei d6f6b2e97c [GH-7864] Remove tests that checked invalid behavior. 2019-12-01 19:47:58 +01:00
Benjamin Eberlei 75d5adf599 [GH-7864] Bugfix in PersistentCollection::removeElement for EXTRA_LAZY. 2019-12-01 19:27:45 +01:00
Benjamin Eberlei cfd6fadf9c Revert "#7841 SchemaTool generates extra diff for platforms without FK support"
This reverts commit 3707c39124.
2019-12-01 11:23:45 +01:00
Tomoka Baba 2bf7916c52 Fix to pass code quality check. 2019-11-20 17:03:34 +09:00
Tomoka Baba 253fd10cc0 Modified test to use assertTrue. 2019-11-20 17:02:25 +09:00
Tomoka Baba 2c956d55f2 Fix to pass code quality check. 2019-11-20 17:02:25 +09:00
Tomoka Baba 3db992e953 Add test code. 2019-11-20 17:01:52 +09:00
Tomoka Baba 6fc9b3ab16 Fix to pass code quality check. 2019-11-20 17:01:52 +09:00
Tomoka Baba 2d833a5e86 Fix boolean properties default value when generating entities. 2019-11-20 17:01:19 +09:00
Luís Cobucci a416a9a8b2 Bump up version 2019-11-19 09:43:57 +01:00
Luís Cobucci 4d763ca4c9 Bump up version 2019-11-19 09:38:05 +01:00
Luís Cobucci 398d74deaa Merge pull request #7911 from lcobucci/be-more-explicit-on-deprecation-messages
Be explicit about which Doctrine package in message
2019-11-19 09:36:14 +01:00
Luís Cobucci 3314322929 Be explicit about which Doctrine package in message
Avoiding possible confusion while reading the deprecation messages.
2019-11-19 09:03:36 +01:00
Luís Cobucci ce93817bf7 Merge pull request #7909 from lcobucci/add-deprecation-messages
Add deprecation messages
2019-11-19 08:21:44 +01:00
Luís Cobucci 50992eafa2 Deprecated the usage of number unaware underscore naming strategy 2019-11-19 02:15:11 +01:00
Luís Cobucci 9ccb8837e7 Add deprecation message for EM#clear($entityName) 2019-11-19 01:34:50 +01:00
Luís Cobucci d959744c0a Merge pull request #7079 from mairo744/hotfix/sqlite-join-table-name
fix getJoinTableName for sqlite with schema attribute
2019-11-18 23:37:33 +01:00
mairo744 0264ba1759 Fix creation of join table names with schemas in SQLite
Join table name doesnt depending on the platform.
Table name was "schema.table" instead of "schema__table".

(cherry picked from commit 4878cd3f4ef30ffc6047c18e0f7b16aafeabc3b4)
2019-11-18 23:25:28 +01:00
Luís Cobucci 8332fa1855 Merge remote-tracking branch 'upstream/2.6' into 2.7 2019-11-18 23:06:28 +01:00
Luís Cobucci 4fae126459 Bump up version 2019-11-18 23:05:16 +01:00
Luís Cobucci 2d9b935183 Bump up version 2019-11-18 23:01:21 +01:00
Luís Cobucci 4804f602f8 Merge pull request #7908 from lcobucci/fix-bc-break-on-naming-strategy
Fix BC-break on underscore naming strategy
2019-11-18 22:57:27 +01:00
Luís Cobucci 3d17290eb5 Fix BC-break on underscore naming strategy
We broke our BC promises on the last patch release by changing how the
underscore naming strategy parses values with numbers.

This commit makes it possible to configure whether or not to make the
underscore naming strategy aware of numbers, keeping the old
configuration as default value.
2019-11-18 22:38:14 +01:00
Luís Cobucci 8420d24f90 Merge remote-tracking branch 'upstream/2.6' into 2.7 2019-11-18 19:59:58 +01:00
Luís Cobucci 52f2b37921 Bump up version 2019-11-18 12:17:41 +01:00
Luís Cobucci 16751d210f Bump up version 2019-11-18 12:06:51 +01:00
Luís Cobucci 686f508576 Merge pull request #7905 from lcobucci/7890-paginator-objecti
[Paginator] Fix type conversion during hydration of pagination limit subquery
2019-11-18 10:50:54 +01:00
Luís Cobucci 00ef1eba90 Add paginator query hint to force type conversion
We're keeping a BC layer in the hydrator, which prevents type conversion
in scalar results.

This makes bypasses such layer in order to always convert the identifier
types when limiting the result set during a pagination.

The main goal here is to keep the conversion DB->PHP inside of the
hydrator components.
2019-11-18 10:27:10 +01:00
Gabriel Ostrolucký 3843eee5cb [Paginator] Add test case for regression with custom id
Co-authored-by: Alexei Korolev <alexei.korolev@gmail.com>
2019-11-18 10:27:10 +01:00
Luís Cobucci f576e6c41f Merge pull request #7904 from greg0ire/validate-composer-json
Make sure composer files are valid
2019-11-16 11:47:02 +01:00
Grégoire Paris c79d2e0dc2 Make sure composer files are valid
The composer.lock is put under version control and it often happens to
be out of sync with the composer.json, which could lead to
hard-to-understand issues.
Using the --strict option here because we might as well aim for a
perfectly valid composer.json
2019-11-16 10:59:39 +01:00
Grégoire Paris 33b8d020a7 Synchronize lock file and json manifest 2019-11-16 10:59:39 +01:00
Luís Cobucci 1b2daac25d Merge pull request #7710 from rtek/pretty-tool-describe
Prettified arrays in tool command orm:mapping:describe
2019-11-16 02:15:31 +01:00
Luís Cobucci 977985f756 Merge pull request #7701 from someniatko/deprecate-use-result-cache
Split and deprecate AbstractQuery#useResultCache()
2019-11-16 02:12:29 +01:00
rtek 0c36f87935 Prettify arrays in orm:mapping:describe command
This will prevent excessive column width and wrapping in the output which uses Symfony\Component\Console\Style\SymfonyStyle::table().
2019-11-16 02:03:03 +01:00
someniatko e8f265d480 Make ResultCacheTest tests slightly more logical 2019-11-16 01:59:57 +01:00
Illia Somov 7bcbad076d Split and deprecate AbstractQuery#useResultCache() 2019-11-16 01:59:57 +01:00
Luís Cobucci 57496e32fd Add minor BC-break notes on output walkers in paginator
As explained in
https://github.com/doctrine/orm/pull/7863#issuecomment-554578313.
2019-11-16 01:48:37 +01:00
Luís Cobucci 797bfc53c4 Fix deprecation messages version 2019-11-16 01:32:15 +01:00
Luís Cobucci 8c47dcb6fc Merge pull request #7863 from Seb33300/skip-limit-subquery
Paginator: Skip limit subquery if not required
2019-11-16 01:21:43 +01:00
Sébastien ALFAIATE 6347190886 Skip limit subquery if not required 2019-11-16 01:03:22 +01:00
Luís Cobucci 9162f3519d Merge pull request #7900 from doctrine/2.6.x-merge-up-into-2.7
Merge up 2.6 to 2.7
2019-11-16 00:27:50 +01:00
Grégoire Paris fc9314d9f5 Merge remote-tracking branch 'origin/2.7' into 7900--2.6.x-merge-up-into-2.7 2019-11-15 23:50:05 +01:00
Luís Cobucci 26806d08eb Require more updated doctrine packages 2019-11-15 23:46:22 +01:00
Luís Cobucci 6a827d5b61 Merge pull request #7861 from ferrastas/bug_removing_collection
Delete statements will not be created using `clear`
2019-11-15 22:58:31 +01:00
Gabriel Ostrolucký 7d77984306 Restore ability to clear deferred explicit tracked collections
This was regression from #7862 which tried to respect tracking config
when clearing collections, but this logic can happen in UOW only,
PersistentCollection::clear is triggered too early to know what
is (going to be) persisted.

Fixes #7862
2019-11-15 22:49:06 +01:00
Ferran Vidal ec93014713 Delete statements will not be created using clear. 2019-11-15 22:43:53 +01:00
Luís Cobucci c83094bde0 Merge pull request #7684 from rharink/2.6
only replace '_id' at end of columnName
2019-11-15 16:50:16 +01:00
Robert den Harink 982d1519db only replace '_id' at end of columnName 2019-11-15 16:36:48 +01:00
Marco Pivetta f7c04ae537 Merge pull request #7901 from lcobucci/add-deprecation-notices
Add deprecation warnings for 2.7.x
2019-11-15 16:15:31 +01:00
Michael Moravec f9a4258ded Upgrading notes for 2.7 2019-11-15 14:43:33 +01:00
Michael Moravec eb9f11bf96 Added deprecation warnings for 2.x 2019-11-15 14:43:15 +01:00
Luís Cobucci 2b8cb9de79 Add basic tool to verify deprecation messages 2019-11-15 14:42:48 +01:00
Luís Cobucci 570abb5bad Fix PHP warnings in test suite 2019-11-15 14:42:47 +01:00
Luís Cobucci 855244fd10 Merge pull request #7865 from Ocramius/fix/#7837-paginate-with-custom-identifier-types-even-with-cached-dql-parsing
#7837 paginate with custom identifier types even with enabled DQL query cache
2019-11-15 11:08:22 +01:00
Guilherme Blanco c62977412c Merge pull request #7869 from BenMorel/patch-4
UnitOfWork::clear() misses $eagerLoadingEntities
2019-11-15 00:27:08 -05:00
Gabriel Ostrolucký 98e557b68e Improve assertion failure message for testWillFindSongsInPaginatorEvenWithCachedQueryParsing 2019-11-14 23:37:13 +01:00
Mickaël RAYBAUD-ROIG 3a32c00dcf Add a failing test for issue #7505 2019-11-14 23:28:42 +01:00
Gabriel Ostrolucký 1dde2c9e8e Add test case verifying eager loads are clear
Otherwise, getClassMetadata would be triggered more times
2019-11-14 22:17:06 +01:00
Marco Pivetta adfd010a78 Merge pull request #7889 from ajgarlag/hotfix/fix-tests-with-dbal-2.10
Use quoted collation declaration when available.
2019-11-05 15:52:18 +01:00
Antonio J. García Lagar 1bc4e1f594 Use quoted collation declaration when available. 2019-11-05 14:58:24 +01:00
Marco Pivetta 21680df9bd Merge pull request #7884 from rogeriolino/patch-1
[Documentation] Advanced field value... - missing entity alias
2019-11-05 01:23:52 +01:00
Rogério Alencar Lino Filho 19aa3c125c missing entity alias 2019-10-31 18:20:58 -03:00
Marco Pivetta e9e012a037 Merge pull request #7880 from kuraobi/update-doc-dql-qb
Update documentation to recommend DQL over QueryBuilder when possible
2019-10-29 19:04:03 +01:00
Mathieu Lemoine d1db0655ac Update documentation to recommend DQL over QueryBuilder when possible 2019-10-29 16:26:17 +01:00
Luís Cobucci 2d643e6b7b Merge pull request #7876 from nicolas-grekas/sf5-cmd
Fix compat of commands with Symfony 5
2019-10-23 16:12:18 +02:00
Nicolas Grekas 4d6b1f3e63 Fix compat of commands with Symfony 5 2019-10-23 16:00:19 +02:00
Jonathan H. Wage d9c30e34c4 Merge pull request #7723 from nicolas-grekas/sf5
Allow Symfony 5.0
2019-10-23 15:57:25 +02:00
Nicolas Grekas 90c1ee0bd0 Allow Symfony 5.0 2019-10-23 15:57:25 +02:00
Marco Pivetta cfcca3a63c Merge pull request #7600 from Majkl578/travis-php7.4-2.7
[2.7] CI: Test against PHP 7.4snapshot instead of nightly (8.0)
2019-10-23 15:57:24 +02:00
Michael Moravec af0949adab Merge pull request #7382 from Majkl578/homepage-2.7
Update homepage
2019-10-23 15:57:24 +02:00
Michael Moravec cdb652ad87 CI: Test against PHP 7.4snapshot instead of nightly (8.0) 2019-10-23 15:57:24 +02:00
Claudio Zizza 4fb1ebfc10 Create 2.7 upgrade headline for deprecation changes 2019-10-23 15:57:24 +02:00
Michael Moravec 46c1b57560 Update homepage 2019-10-23 15:57:24 +02:00
Claudio Zizza fdbbf7edd1 Add deprecation of EntityManagerInterface::copy() to upgrade information 2019-10-23 15:57:23 +02:00
Claudio Zizza 2fed8204c1 Set copy-method as deprecated 2019-10-23 15:57:23 +02:00
Michael Moravec 76f03b5db0 Bump version to 2.7-dev 2019-10-23 15:57:19 +02:00
Guilherme Blanco 9fef4e86e4 Merge pull request #7871 from BenMorel/2.6
AbstractQuery::getSingleScalarResult() throws exception when no result
2019-10-18 10:37:53 -04:00
Benjamin Morel 4781dc03e9 AbstractQuery::getSingleScalarResult() throws exception when no result 2019-10-16 20:41:00 +02:00
Benjamin Morel cc5f84ac22 UnitOfWork::clear() misses $eagerLoadingEntities 2019-10-16 10:11:55 +02:00
Marco Pivetta 023e94661a #7837 force expiry of query cache when WhereInWalker is being used
In order to figure out the paginated query identifier type, we would
have to parse the DQL query into an AST+SQL anyway, so we'd have
to re-parse it manually: instead of doing that, we can force the
`WhereInWalker` to be reached at all times by forcing the
`$whereInQuery` to use no query cache.

While it is a sad performance regression, it is also not a
noticeable one, since we'll be performing an `O(1)` operation
around an I/O one (query execution, in this case).
2019-10-10 18:23:31 +02:00
Marco Pivetta b59fc23f86 #7837 reproduced issue: DQL caching prevents WhereInWalker run
Since `WhereInWalker` does not run, query parameters are not translated
from their in-memory type to the expected SQL type when the paginator
is run again with the same DQL string. This is an architectural
issue, since (for the sake of simplicity) we moved parameter
translation into the SQL walker, we didn't consider that SQL
walkers only act when no cache is in place. The translatio
needs to be moved into the paginator logic again.
2019-10-10 17:30:43 +02:00
Luís Cobucci d71dd5d94f Bump up version 2019-10-08 20:04:50 +02:00
Luís Cobucci 63513e9a05 Merge pull request #7856 from lcobucci/fix/underscore-strategy-dont-work-with-numbers
Fix underscore naming strategy behaviour with numbers
2019-10-08 12:06:24 +02:00
Luís Cobucci c802bc46a5 Format NamingStrategyTest according to our CS 2019-10-08 11:56:11 +02:00
Luís Cobucci 506bf0ee12 Allow numbers in property names on underscore naming strategy 2019-10-08 11:56:11 +02:00
Luís Cobucci a36809db72 Merge pull request #7851 from peter-gribanov/reflFieldValue2.6
Remove not used variable $reflFieldValue in ObjectHydrator
2019-10-04 07:50:26 +02:00
Peter Gribanov 5b00d7ba5e remove not used variable $reflFieldValue in ObjectHydrator 2019-10-03 11:14:24 +03:00
Luís Cobucci b22604352d Merge pull request #7849 from axi/patch-1
Mention SQL logger impact on batch processing
2019-10-02 14:14:48 +02:00
axi 00c6b1bc60 Update batch-processing.rst
Clarify note
2019-10-02 14:00:06 +02:00
Luís Cobucci 4b0d86ee92 Merge pull request #7842 from vpArth-php/gh-7841
#7841 SchemaTool generates extra diff for platforms without FK support
2019-10-02 10:50:42 +02:00
Alexander Deider 3707c39124 #7841 SchemaTool generates extra diff for platforms without FK support 2019-10-02 15:35:59 +07:00
Luís Cobucci fe72b00df2 Merge pull request #7850 from nlx-lars/nlx-lars/bugfix/7836-dont-merge-criteria
Don't merge PersistentCollection orderBy with criteria in matching()
2019-10-02 10:02:38 +02:00
Lars Lauger 79a7ecc92f Don't merge PersistentCollection orderBy with criteria in matching()
If no orderings are given to PersistentCollection::matching(), the
orderBy annotation will be used if present. If the criteria contains
orderings, those will be used without merging them with the orderBy.

See #7836
2019-10-02 09:23:38 +02:00
Luís Cobucci 16df8bfe0d Merge pull request #7298 from dunglas/patch-2
Add a missing type in Query::getFirstResult PHPDoc
2019-10-02 04:27:19 +02:00
Kévin Dunglas b37ceaa9f7 Add a missing type in Query::getFirstResult and Query::getDQL 2019-10-02 04:13:42 +02:00
Luís Cobucci c41fdbce8a Merge pull request #7727 from madand/patch-1
[doc] Finish incomplete definition of class UTCDateTimeType
2019-10-02 04:11:20 +02:00
Luís Cobucci 7526adc80a Merge pull request #7443 from naitsirch/fix/issue6793
Added doc about exception in Query#getOneOrNullResult()
2019-10-02 04:07:25 +02:00
Andriy Kmit 766eb693fb Finish incomplete definition of class UTCDateTimeType 2019-10-02 03:57:06 +02:00
Luís Cobucci f9e2ae3488 Merge pull request #7667 from jschaedl/patch-1
Fixes example One-To-One, Self-referencing
2019-10-02 03:56:01 +02:00
Luís Cobucci 6bf2ff5d10 Merge pull request #7671 from jschaedl/patch-4
Added missing "the"
2019-10-02 03:45:50 +02:00
Jan Schädlich 27fcc01d81 Fixes example One-To-One, Self-referencing 2019-10-02 03:37:23 +02:00
Jan Schädlich 3ac1f8e680 Added missing "the" 2019-10-02 03:36:06 +02:00
Luís Cobucci b63db53552 Merge pull request #7764 from guillaume-a/7763
#7763 escape quotes in field comments
2019-10-02 02:56:05 +02:00
Guillaume Aveline bed8186573 Fix comment quoting in the EntityGenerator
Fixes: https://github.com/doctrine/orm/issues/7763
2019-10-02 02:42:09 +02:00
Luís Cobucci f08ff83d0a Merge pull request #7768 from mickaelandrieu/patch-1
EntityManagerHelper can't accept an array of paths
2019-10-01 22:51:13 +02:00
axi 7c8c0906be Update batch-processing.rst
Looking for a way to improve one of our bulk update treatment, I went back to this page then found elsewhere that setting logger to null was a really effective way to improve time and memory consumption. Might be a right place to state it ? Don't know if my edit style is ok
2019-10-01 17:46:09 +02:00
Grégoire Paris 167cb44ea1 Merge pull request #7742 from bocharsky-bw/patch-1
Start i var from 1 instead of 0
2019-09-28 18:54:56 +02:00
Mickaël Andrieu 5d74bdb240 Remove misleading documentation
EntityManagerHelper does not have a second argument, see
https://github.com/doctrine/orm/blob/ca38249f6c71bc1d1c355822040a1788e3eeebd6/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php#L49
2019-09-28 12:32:09 +02:00
Luís Cobucci ca38249f6c Merge pull request #7838 from samnela/fix/name-classmetadata
Fix the name of ClassMetadata in documentation
2019-09-27 22:31:49 +02:00
Samuel NELA 6a74f373b9 Fix the name of ClassMetadata in documentation 2019-09-27 21:59:32 +02:00
naitsirch 1c45e1b744 Fixed grammatical mistake in doc
Co-Authored-By: Grégoire Paris <postmaster@greg0ire.fr>
2019-06-24 22:07:56 +02:00
Victor Bocharsky 5612790307 Start i var from 1 instead of 0
Because (0 % $batchSize) === 0 but we don't want to execute flush() and clear() on the first iteration.
2019-06-11 13:19:56 +03:00
naitsirch 17bc627bf2 Added hint about exception in Query#getOneOrNullResult()
When calling `Query#getOneOrNullResult()` and there are more than one
objects in the result an `NonUniqueResultException` is thrown.
This information was missing in the documentation about the query result
formats.

This commit addresses #6793.
2018-10-29 21:26:02 +01:00
134 changed files with 2638 additions and 1515 deletions
+5 -6
View File
@@ -6,8 +6,7 @@ php:
- 7.1
- 7.2
- 7.3
- 7.4snapshot
- nightly
- 7.4
env:
- DB=sqlite
@@ -18,7 +17,7 @@ before_install:
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{,.disabled} || echo "xdebug not available"
- composer self-update
install: travis_retry composer update --prefer-dist
install: travis_retry composer validate --strict && composer update --prefer-dist
script:
- if [[ "$DB" == "mysql" || "$DB" == "mariadb" ]]; then mysql -e "CREATE SCHEMA doctrine_tests; GRANT ALL PRIVILEGES ON doctrine_tests.* to travis@'%'"; fi
@@ -55,7 +54,7 @@ jobs:
- stage: Test
dist: xenial
env: DB=mysql MYSQL_VERSION=5.7
php: nightly
php: 7.4
services:
- mysql
before_script:
@@ -87,6 +86,7 @@ jobs:
- stage: Code Quality
env: DB=none STATIC_ANALYSIS
php: 7.4
install: travis_retry composer install --prefer-dist
before_script:
- echo "extension=memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
@@ -102,7 +102,7 @@ jobs:
- stage: Code Quality
if: NOT type = pull_request
env: DB=none CODING_STANDARDS
php: 7.1
php: 7.4
install: travis_retry composer install --prefer-dist
script:
- ./vendor/bin/phpcs
@@ -123,7 +123,6 @@ jobs:
- php git-phpcs.phar origin/$TRAVIS_BRANCH...$TRAVIS_PULL_REQUEST_SHA
allow_failures:
- php: nightly
- stage: Code Quality
env: DB=none CODING_STANDARDS
+142
View File
@@ -1,3 +1,145 @@
# Upgrade to 2.7
## Added `Doctrine\ORM\AbstractQuery#enableResultCache()` and `Doctrine\ORM\AbstractQuery#disableResultCache()` methods
Method `Doctrine\ORM\AbstractQuery#useResultCache()` which could be used for both enabling and disabling the cache
(depending on passed flag) was split into two.
## Minor BC BREAK: paginator output walkers aren't be called anymore on sub-queries for queries without max results
To optimize DB interaction, `Doctrine\ORM\Tools\Pagination\Paginator` no longer fetches identifiers to be able to
perform the pagination with join collections when max results isn't set in the query.
## Minor BC BREAK: tables filtered with `schema_filter` are no longer created
When generating schema diffs, if a source table is filtered out by a `schema_filter` expression, then a `CREATE TABLE` was
always generated, even if the table already existed. This has been changed in this release and the table will no longer
be created.
## Deprecated number unaware `Doctrine\ORM\Mapping\UnderscoreNamingStrategy`
In the last patch of the `v2.6.x` series, we fixed a bug that was not converting names properly when they had numbers
(e.g.: `base64Encoded` was wrongly converted to `base64encoded` instead of `base64_encoded`).
In order to not break BC we've introduced a way to enable the fixed behavior using a boolean constructor argument. This
argument will be removed in 3.0 and the default behavior will be the fixed one.
## Deprecated: `Doctrine\ORM\AbstractQuery#useResultCache()`
Method `Doctrine\ORM\AbstractQuery#useResultCache()` is deprecated because it is split into `enableResultCache()`
and `disableResultCache()`. It will be removed in 3.0.
## Deprecated code generators and related console commands
These console commands have been deprecated:
* `orm:convert-mapping`
* `orm:generate:entities`
* `orm:generate-repositories`
These classes have been deprecated:
* `Doctrine\ORM\Tools\EntityGenerator`
* `Doctrine\ORM\Tools\EntityRepositoryGenerator`
Whole Doctrine\ORM\Tools\Export namespace with all its members have been deprecated as well.
## Deprecated `Doctrine\ORM\Proxy\Proxy` marker interface
Proxy objects in Doctrine ORM 3.0 will no longer implement `Doctrine\ORM\Proxy\Proxy` nor
`Doctrine\Common\Persistence\Proxy`: instead, they implement
`ProxyManager\Proxy\GhostObjectInterface`.
These related classes have been deprecated:
* `Doctrine\ORM\Proxy\ProxyFactory`
* `Doctrine\ORM\Proxy\Autoloader` - we suggest using the composer autoloader instead
These methods have been deprecated:
* `Doctrine\ORM\Configuration#getAutoGenerateProxyClasses()`
* `Doctrine\ORM\Configuration#getProxyDir()`
* `Doctrine\ORM\Configuration#getProxyNamespace()`
## Deprecated `Doctrine\ORM\Version`
The `Doctrine\ORM\Version` class is now deprecated and will be removed in Doctrine ORM 3.0:
please refrain from checking the ORM version at runtime or use
[ocramius/package-versions](https://github.com/Ocramius/PackageVersions/).
## Deprecated `EntityManager#merge()` and `EntityManager#detach()` methods
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
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
application. If your application relies heavily on CRUD-alike interactions and/or `PATCH`
restful operations, you should look at alternatives such as [JMSSerializer](https://github.com/schmittjoh/serializer).
## Extending `EntityManager` is deprecated
Final keyword will be added to the `EntityManager::class` in Doctrine ORM 3.0 in order to ensure that EntityManager
is not used as valid extension point. Valid extension point should be EntityManagerInterface.
## Deprecated `EntityManager#clear($entityName)`
If your code relies on clearing a single entity type via `EntityManager#clear($entityName)`,
the signature has been changed to `EntityManager#clear()`.
The main reason is that partial clears caused multiple issues with data integrity
in the managed entity graph, which was constantly spawning more edge-case bugs/scenarios.
## Deprecated `EntityManager#flush($entity)` and `EntityManager#flush($entities)`
If your code relies on single entity flushing optimisations via
`EntityManager#flush($entity)`, the signature has been changed to
`EntityManager#flush()`.
Said API was affected by multiple data integrity bugs due to the fact
that change tracking was being restricted upon a subset of the managed
entities. The ORM cannot support committing subsets of the managed
entities while also guaranteeing data integrity, therefore this
utility was removed.
The `flush()` semantics will remain the same, but the change tracking will be performed
on all entities managed by the unit of work, and not just on the provided
`$entity` or `$entities`, as the parameter is now completely ignored.
The same applies to `UnitOfWork#commit($entity)`, which will simply be
`UnitOfWork#commit()`.
If you would still like to perform batching operations over small `UnitOfWork`
instances, it is suggested to follow these paths instead:
* eagerly use `EntityManager#clear()` in conjunction with a specific second level
cache configuration (see http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/second-level-cache.html)
* use an explicit change tracking policy (see http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/change-tracking-policies.html)
## Deprecated `YAML` mapping drivers.
If your code relies on `YamlDriver` or `SimpleYamlDriver`, you **MUST** change to
annotation or XML drivers instead.
## Deprecated: `Doctrine\ORM\EntityManagerInterface#copy()`
Method `Doctrine\ORM\EntityManagerInterface#copy()` never got its implementation and is deprecated.
It will be removed in 3.0.
# Upgrade to 2.6
## Added `Doctrine\ORM\EntityRepository::count()` method
-3
View File
@@ -1,3 +0,0 @@
# Version class and file
project.version_class = Doctrine\\ORM\\Version
project.version_file = lib/Doctrine/ORM/Version.php
-16
View File
@@ -1,16 +0,0 @@
version=2.0.0BETA2
dependencies.common=2.0.0BETA4
dependencies.dbal=2.0.0BETA4
stability=beta
build.dir=build
dist.dir=dist
report.dir=reports
log.archive.dir=logs
project.pirum_dir=
project.download_dir=
project.xsd_dir=
test.phpunit_configuration_file=
test.phpunit_generate_coverage=0
test.pmd_reports=0
test.pdepend_exec=
test.phpmd_exec=
-101
View File
@@ -1,101 +0,0 @@
<?xml version="1.0"?>
<project name="DoctrineORM" default="build" basedir=".">
<property file="build.properties" />
<target name="php">
<exec executable="which" outputproperty="php_executable">
<arg value="php" />
</exec>
</target>
<target name="prepare">
<mkdir dir="build" />
</target>
<target name="build" depends="check-git-checkout-clean,prepare,php,composer">
<exec executable="${php_executable}">
<arg value="build/composer.phar" />
<arg value="archive" />
<arg value="--dir=build" />
</exec>
</target>
<target name="composer" depends="php,composer-check,composer-download">
<exec executable="${php_executable}">
<arg value="build/composer.phar" />
<arg value="install" />
</exec>
</target>
<target name="composer-check" depends="prepare">
<available file="build/composer.phar" property="composer.present"/>
</target>
<target name="composer-download" unless="composer.present">
<exec executable="wget">
<arg value="-Obuild/composer.phar" />
<arg value="http://getcomposer.org/composer.phar" />
</exec>
</target>
<target name="make-release" depends="check-git-checkout-clean,prepare,php">
<replace file="${project.version_file}" token="-DEV" value="" failOnNoReplacements="true" />
<exec executable="${php_executable}" outputproperty="doctrine.current_version" failonerror="true">
<arg value="-r" />
<arg value="require_once '${project.version_file}';echo ${project.version_class}::VERSION;" />
</exec>
<exec executable="${php_executable}" outputproperty="doctrine.next_version" failonerror="true">
<arg value="-r" />
<arg value="$parts = explode('.', str_ireplace(array('-DEV', '-ALPHA', '-BETA'), '', '${doctrine.current_version}'));
if (count($parts) != 3) {
throw new \InvalidArgumentException('Version is assumed in format x.y.z, ${doctrine.current_version} given');
}
$parts[2]++;
echo implode('.', $parts);
" />
</exec>
<git-commit file="${project.version_file}" message="Release ${doctrine.current_version}" />
<git-tag version="${doctrine.current_version}" />
<replace file="${project.version_file}" token="${doctrine.current_version}" value="${doctrine.next_version}-DEV" />
<git-commit file="${project.version_file}" message="Bump version to ${doctrine.next_version}" />
</target>
<target name="check-git-checkout-clean">
<exec executable="git" failonerror="true">
<arg value="diff-index" />
<arg value="--quiet" />
<arg value="HEAD" />
</exec>
</target>
<macrodef name="git-commit">
<attribute name="file" default="NOT SET"/>
<attribute name="message" default="NOT SET"/>
<sequential>
<exec executable="git">
<arg value="add" />
<arg value="@{file}" />
</exec>
<exec executable="git">
<arg value="commit" />
<arg value="-m" />
<arg value="@{message}" />
</exec>
</sequential>
</macrodef>
<macrodef name="git-tag">
<attribute name="version" default="NOT SET" />
<sequential>
<exec executable="git">
<arg value="tag" />
<arg value="-m" />
<arg value="v@{version}" />
<arg value="v@{version}" />
</exec>
</sequential>
</macrodef>
</project>
+13 -10
View File
@@ -3,7 +3,7 @@
"type": "library",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "http://www.doctrine-project.org",
"homepage": "https://www.doctrine-project.org/projects/orm.html",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
@@ -18,18 +18,21 @@
"require": {
"php": "^7.1",
"ext-pdo": "*",
"doctrine/annotations": "~1.5",
"doctrine/cache": "~1.6",
"doctrine/collections": "^1.4",
"doctrine/common": "^2.7.1",
"doctrine/dbal": "^2.6",
"doctrine/instantiator": "~1.1",
"symfony/console": "~3.0|~4.0"
"doctrine/annotations": "^1.8",
"doctrine/cache": "^1.9.1",
"doctrine/collections": "^1.5",
"doctrine/common": "^2.11",
"doctrine/dbal": "^2.9.3",
"doctrine/event-manager": "^1.1",
"doctrine/instantiator": "^1.3",
"doctrine/persistence": "^1.2",
"ocramius/package-versions": "^1.2",
"symfony/console": "^3.0|^4.0|^5.0"
},
"require-dev": {
"doctrine/coding-standard": "^5.0",
"phpunit/phpunit": "^7.5",
"symfony/yaml": "~3.4|~4.0"
"symfony/yaml": "^3.4|^4.0|^5.0"
},
"suggest": {
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
@@ -46,7 +49,7 @@
"bin": ["bin/doctrine"],
"extra": {
"branch-alias": {
"dev-master": "2.6.x-dev"
"dev-master": "2.7.x-dev"
}
},
"archive": {
Generated
+286 -297
View File
File diff suppressed because it is too large Load Diff
@@ -249,7 +249,7 @@ Example usage
$em->clear();
// Fetch the Location object
$query = $em->createQuery("SELECT l FROM Geo\Entity\Location WHERE l.address = '1600 Amphitheatre Parkway, Mountain View, CA'");
$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 */
+10 -2
View File
@@ -90,7 +90,10 @@ the UTC time at the time of the booking and the timezone the event happened in.
class UTCDateTimeType extends DateTimeType
{
static private $utc;
/**
* @var \DateTimeZone
*/
private static $utc;
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
@@ -110,7 +113,7 @@ the UTC time at the time of the booking and the timezone the event happened in.
$converted = \DateTime::createFromFormat(
$platform->getDateTimeFormatString(),
$value,
self::$utc ? self::$utc : self::$utc = new \DateTimeZone('UTC')
self::getUtc()
);
if (! $converted) {
@@ -123,6 +126,11 @@ the UTC time at the time of the booking and the timezone the event happened in.
return $converted;
}
private static function getUtc(): \DateTimeZone
{
return self::$utc ?: self::$utc = new \DateTimeZone('UTC');
}
}
This database type makes sure that every DateTime instance is always saved in UTC, relative
+1 -1
View File
@@ -99,7 +99,7 @@ Optional attributes:
- **length**: Used by the "string" type to determine its maximum
length in the database. Doctrine does not validate the length of a
string values for you.
string value for you.
- **precision**: The precision for a decimal (exact numeric) column
(applies only for decimal column), which is the maximum number of
+1 -1
View File
@@ -286,7 +286,7 @@ below.
// ...
/**
* One Student has One Student.
* One Student has One Mentor.
* @OneToOne(targetEntity="Student")
* @JoinColumn(name="mentor_id", referencedColumnName="id")
*/
+11 -2
View File
@@ -16,6 +16,15 @@ especially what the strategies presented here provide help with.
operations.
.. note::
Having an SQL logger enabled when processing batches can have a serious impact on performance and resource usage.
To avoid that you should disable it in the DBAL configuration:
.. code-block:: php
<?php
$em->getConnection()->getConfiguration()->setSQLLogger(null);
Bulk Inserts
------------
@@ -75,7 +84,7 @@ with the batching strategy that was already used for bulk inserts:
<?php
$batchSize = 20;
$i = 0;
$i = 1;
$q = $em->createQuery('select u from MyProject\Model\User u');
$iterableResult = $q->iterate();
foreach ($iterableResult as $row) {
@@ -136,7 +145,7 @@ The following example shows how to do this:
<?php
$batchSize = 20;
$i = 0;
$i = 1;
$q = $em->createQuery('select u from MyProject\Model\User u');
$iterableResult = $q->iterate();
while (($row = $iterableResult->next()) !== false) {
+40 -49
View File
@@ -45,41 +45,29 @@ This documentation does not cover every single cache driver included
with Doctrine. For an up-to-date-list, see the
`cache directory on GitHub <https://github.com/doctrine/cache/tree/master/lib/Doctrine/Common/Cache>`_.
APC
~~~
PhpFileCache
~~~~~~~~~~~~
In order to use the APC cache driver you must have it compiled and
enabled in your php.ini. You can read about APC
`in the PHP Documentation <http://us2.php.net/apc>`_. 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.
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.
Below is a simple example of how you could use the APC cache driver
by itself.
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\ApcCache();
$cacheDriver = new \Doctrine\Common\Cache\PhpFileCache(
'/path/to/writable/directory'
);
$cacheDriver->save('cache_id', 'my_data');
APCu
~~~~
In order to use the APCu cache driver you must have it compiled and
enabled in your php.ini. You can read about APCu
`in the PHP Documentation <http://us2.php.net/apcu>`_. 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 APCu cache driver
by itself.
.. code-block:: php
<?php
$cacheDriver = new \Doctrine\Common\Cache\ApcuCache();
$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
~~~~~~~~
@@ -128,24 +116,6 @@ driver by itself.
$cacheDriver->setMemcached($memcached);
$cacheDriver->save('cache_id', 'my_data');
Xcache
~~~~~~
In order to use the Xcache cache driver you must have it compiled
and enabled in your php.ini. You can read about Xcache
`here <http://xcache.lighttpd.net/>`_. 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 Xcache cache
driver by itself.
.. code-block:: php
<?php
$cacheDriver = new \Doctrine\Common\Cache\XcacheCache();
$cacheDriver->save('cache_id', 'my_data');
Redis
~~~~~
@@ -306,8 +276,11 @@ use on your ORM configuration.
.. code-block:: php
<?php
$cacheDriver = new \Doctrine\Common\Cache\PhpFileCache(
'/path/to/writable/directory'
);
$config = new \Doctrine\ORM\Configuration();
$config->setQueryCacheImpl(new \Doctrine\Common\Cache\ApcuCache());
$config->setQueryCacheImpl($cacheDriver);
Result Cache
~~~~~~~~~~~~
@@ -320,7 +293,11 @@ cache implementation.
.. code-block:: php
<?php
$config->setResultCacheImpl(new \Doctrine\Common\Cache\ApcuCache());
$cacheDriver = new \Doctrine\Common\Cache\PhpFileCache(
'/path/to/writable/directory'
);
$config = new \Doctrine\ORM\Configuration();
$config->setResultCacheImpl($cacheDriver);
Now when you're executing DQL queries you can configure them to use
the result cache.
@@ -337,7 +314,11 @@ result cache driver.
.. code-block:: php
<?php
$query->setResultCacheDriver(new \Doctrine\Common\Cache\ApcuCache());
$cacheDriver = new \Doctrine\Common\Cache\PhpFileCache(
'/path/to/writable/directory'
);
$config = new \Doctrine\ORM\Configuration();
$query->setResultCacheDriver($cacheDriver);
.. note::
@@ -389,7 +370,11 @@ first.
.. code-block:: php
<?php
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ApcuCache());
$cacheDriver = new \Doctrine\Common\Cache\PhpFileCache(
'/path/to/writable/directory'
);
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl($cacheDriver);
Now the metadata information will only be parsed once and stored in
the cache driver.
@@ -425,6 +410,12 @@ To clear the result cache use the ``orm:clear-cache:result`` task.
All these tasks accept a ``--flush`` option to flush the entire
contents of the cache instead of invalidating the entries.
.. note::
None of these tasks will work with APC, APCu, or XCache drivers
because the memory that the cache is stored in is only accessible
to the webserver.
Cache Chaining
--------------
@@ -996,8 +996,9 @@ the Query class. Here they are:
result contains more than one object, an ``NonUniqueResultException``
is thrown. If the result contains no objects, an ``NoResultException``
is thrown. The pure/mixed distinction does not apply.
- ``Query#getOneOrNullResult()``: Retrieve a single object. If no
object is found null will be returned.
- ``Query#getOneOrNullResult()``: Retrieve a single object. If the
result contains more than one object, a ``NonUniqueResultException``
is thrown. If no object is found null will be returned.
- ``Query#getArrayResult()``: Retrieves an array graph (a nested
array) that is largely interchangeable with the object graph
generated by ``Query#getResult()`` for read-only purposes.
+15
View File
@@ -198,6 +198,21 @@ No, it is not supported to sort by function in DQL. If you need this functionali
use a native-query or come up with another solution. As a side note: Sorting with ORDER BY RAND() is painfully slow
starting with 1000 rows.
Is it better to write DQL or to generate it with the query builder?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The purpose of the ``QueryBuilder`` is to generate DQL dynamically,
which is useful when you have optional filters, conditional joins, etc.
But the ``QueryBuilder`` is not an alternative to DQL, it actually generates DQL
queries at runtime, which are then interpreted by Doctrine. This means that
using the ``QueryBuilder`` to build and run a query is actually always slower
than only running the corresponding DQL query.
So if you only need to generate a query and bind parameters to it,
you should use plain DQL, as this is a simpler and much more readable solution.
You should only use the ``QueryBuilder`` when you can't achieve what you want to do with a DQL query.
A Query fails, how can I debug it?
----------------------------------
+1 -1
View File
@@ -39,7 +39,7 @@ proper quoting of parameters.
<?php
namespace Example;
use Doctrine\ORM\Mapping\ClassMetaData,
use Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\Query\Filter\SQLFilter;
class MyLocaleFilter extends SQLFilter
+10 -5
View File
@@ -9,6 +9,12 @@ programmatically build queries, and also provides a fluent API.
This means that you can change between one methodology to the other
as you want, or just pick a preferred one.
.. note::
The ``QueryBuilder`` is not an abstraction of DQL, but merely a tool to dynamically build it.
You should still use plain DQL when you can, as it is simpler and more readable.
More about this in the :doc:`FAQ <faq>`_.
Constructing a new QueryBuilder object
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -80,7 +86,7 @@ Working with QueryBuilder
High level API methods
^^^^^^^^^^^^^^^^^^^^^^
To simplify even more the way you build a query in Doctrine, you can take
The most straightforward way to build a dynamic query with the ``QueryBuilder`` is by taking
advantage of Helper methods. For all base code, there is a set of
useful methods to simplify a programmer's life. To illustrate how
to work with them, here is the same example 6 re-written using
@@ -97,10 +103,9 @@ to work with them, here is the same example 6 re-written using
->orderBy('u.name', 'ASC');
``QueryBuilder`` helper methods are considered the standard way to
build DQL queries. Although it is supported, using string-based
queries should be avoided. You are greatly encouraged to use
``$qb->expr()->*`` methods. Here is a converted example 8 to
suggested standard way to build queries:
use the ``QueryBuilder``. The ``$qb->expr()->*`` methods can help you
build conditional expressions dynamically. Here is a converted example 8 to
suggested way to build queries with dynamic conditions:
.. code-block:: php
-9
View File
@@ -252,15 +252,6 @@ will output the SQL for the ran operation.
Before using the orm:schema-tool commands, remember to configure
your cli-config.php properly.
.. note::
When using the Annotation Mapping Driver you have to either setup
your autoloader in the cli-config.php correctly to find all the
entities, or you can use the second argument of the
``EntityManagerHelper`` to specify all the paths of your entities
(or mapping files), i.e.
``new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em, $mappingPaths);``
Entity Generation
-----------------
+1 -1
View File
@@ -156,7 +156,7 @@ wishes to be hydrated. Default result-types include:
- SQL to simple scalar result arrays
- SQL to a single result variable
Hydration to entities and arrays is one of most complex parts of Doctrine
Hydration to entities and arrays is one of the most complex parts of Doctrine
algorithm-wise. It can build results with for example:
- Single table selects
+3 -1
View File
@@ -800,7 +800,9 @@ DQL and its syntax as well as the Doctrine class can be found in
:doc:`the dedicated chapter <dql-doctrine-query-language>`.
For programmatically building up queries based on conditions that
are only known at runtime, Doctrine provides the special
``Doctrine\ORM\QueryBuilder`` class. More information on
``Doctrine\ORM\QueryBuilder`` class. While this a powerful tool,
it also brings more complexity to your code compared to plain DQL,
so you should only use it when you need it. More information on
constructing queries with a QueryBuilder can be found
:doc:`in Query Builder chapter <query-builder>`.
@@ -35,6 +35,15 @@ With extra lazy collections you can now not only add entities to large collectio
easily using a combination of ``count`` and ``slice``.
.. warning::
``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
reverted ``removeElement`` EXTRA_LAZY behavior in 2.7.1.
Enabling Extra-Lazy Associations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+1 -2
View File
@@ -1210,8 +1210,7 @@ The console output of this script is then:
throw your ORM into the dumpster, because it doesn't support some
the more powerful SQL concepts.
Instead of handwriting DQL you can use the ``QueryBuilder`` retrieved
If you need to build your query dynamically, you can use the ``QueryBuilder`` retrieved
by calling ``$entityManager->createQueryBuilder()``. There are more
details about this in the relevant part of the documentation.
+35 -10
View File
@@ -583,21 +583,45 @@ abstract class AbstractQuery
* Set whether or not to cache the results of this query and if so, for
* how long and which ID to use for the cache entry.
*
* @param boolean $bool
* @param integer $lifetime
* @param string $resultCacheId
* @deprecated 2.7 Use {@see enableResultCache} and {@see disableResultCache} instead.
*
* @param bool $useCache
* @param int $lifetime
* @param string $resultCacheId
*
* @return static This query instance.
*/
public function useResultCache($bool, $lifetime = null, $resultCacheId = null)
public function useResultCache($useCache, $lifetime = null, $resultCacheId = null)
{
if ($bool) {
$this->setResultCacheLifetime($lifetime);
$this->setResultCacheId($resultCacheId);
return $useCache
? $this->enableResultCache($lifetime, $resultCacheId)
: $this->disableResultCache();
}
return $this;
}
/**
* Enables caching of the results of this query, for given or default amount of seconds
* and optionally specifies which ID to use for the cache entry.
*
* @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.
*/
public function enableResultCache(?int $lifetime = null, ?string $resultCacheId = null) : self
{
$this->setResultCacheLifetime($lifetime);
$this->setResultCacheId($resultCacheId);
return $this;
}
/**
* Disables caching of the results of this query.
*
* @return static This query instance.
*/
public function disableResultCache() : self
{
$this->_queryCacheProfile = null;
return $this;
@@ -822,8 +846,9 @@ abstract class AbstractQuery
*
* Alias for getSingleResult(HYDRATE_SINGLE_SCALAR).
*
* @return mixed The scalar result, or NULL if the query returned no result.
* @return mixed The scalar result.
*
* @throws NoResultException If the query returned no result.
* @throws NonUniqueResultException If the query result is not unique.
*/
public function getSingleScalarResult()
@@ -243,20 +243,6 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
return $this->persister->get($collection, $index);
}
/**
* {@inheritdoc}
*/
public function removeElement(PersistentCollection $collection, $element)
{
if ($persisterResult = $this->persister->removeElement($collection, $element)) {
$this->evictCollectionCache($collection);
$this->evictElementCache($this->sourceEntity->rootEntityName, $collection->getOwner());
$this->evictElementCache($this->targetEntity->rootEntityName, $element);
}
return $persisterResult;
}
/**
* {@inheritdoc}
*/
+9
View File
@@ -70,6 +70,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Gets the directory where Doctrine generates any necessary proxy class files.
*
* @return string|null
*
* @deprecated 2.7 We're switch to `ocramius/proxy-manager` and this method isn't applicable any longer
* @see https://github.com/Ocramius/ProxyManager
*/
public function getProxyDir()
{
@@ -82,6 +85,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Gets the strategy for automatically generating proxy classes.
*
* @return int Possible values are constants of Doctrine\Common\Proxy\AbstractProxyFactory.
*
* @deprecated 2.7 We're switch to `ocramius/proxy-manager` and this method isn't applicable any longer
* @see https://github.com/Ocramius/ProxyManager
*/
public function getAutoGenerateProxyClasses()
{
@@ -107,6 +113,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Gets the namespace where proxy classes reside.
*
* @return string|null
*
* @deprecated 2.7 We're switch to `ocramius/proxy-manager` and this method isn't applicable any longer
* @see https://github.com/Ocramius/ProxyManager
*/
public function getProxyNamespace()
{
+26 -3
View File
@@ -29,6 +29,8 @@ use Doctrine\ORM\Proxy\ProxyFactory;
use Doctrine\ORM\Query\FilterCollection;
use Doctrine\Common\Util\ClassUtils;
use Throwable;
use const E_USER_DEPRECATED;
use function trigger_error;
/**
* The EntityManager is the central access point to ORM functionality.
@@ -354,6 +356,13 @@ use Throwable;
*/
public function flush($entity = null)
{
if ($entity !== null) {
@trigger_error(
'Calling ' . __METHOD__ . '() with any arguments to flush specific entities is deprecated and will not be supported in Doctrine ORM 3.0.',
E_USER_DEPRECATED
);
}
$this->errorIfClosed();
$this->unitOfWork->commit($entity);
@@ -547,6 +556,13 @@ use Throwable;
throw ORMInvalidArgumentException::invalidEntityName($entityName);
}
if ($entityName !== null) {
@trigger_error(
'Calling ' . __METHOD__ . '() with any arguments to clear specific entities is deprecated and will not be supported in Doctrine ORM 3.0.',
E_USER_DEPRECATED
);
}
$this->unitOfWork->clear(
null === $entityName
? null
@@ -649,9 +665,13 @@ use Throwable;
* @return void
*
* @throws ORMInvalidArgumentException
*
* @deprecated 2.7 This method is being removed from the ORM and won't have any replacement
*/
public function detach($entity)
{
@trigger_error('Method ' . __METHOD__ . '() is deprecated and will be removed in Doctrine ORM 3.0.', E_USER_DEPRECATED);
if ( ! is_object($entity)) {
throw ORMInvalidArgumentException::invalidObject('EntityManager#detach()', $entity);
}
@@ -670,9 +690,13 @@ use Throwable;
*
* @throws ORMInvalidArgumentException
* @throws ORMException
*
* @deprecated 2.7 This method is being removed from the ORM and won't have any replacement
*/
public function merge($entity)
{
@trigger_error('Method ' . __METHOD__ . '() is deprecated and will be removed in Doctrine ORM 3.0.', E_USER_DEPRECATED);
if ( ! is_object($entity)) {
throw ORMInvalidArgumentException::invalidObject('EntityManager#merge()', $entity);
}
@@ -684,12 +708,11 @@ use Throwable;
/**
* {@inheritDoc}
*
* @todo Implementation need. This is necessary since $e2 = clone $e1; throws an E_FATAL when access anything on $e:
* Fatal error: Maximum function nesting level of '100' reached, aborting!
*/
public function copy($entity, $deep = false)
{
@trigger_error('Method ' . __METHOD__ . '() is deprecated and will be removed in Doctrine ORM 3.0.', E_USER_DEPRECATED);
throw new \BadMethodCallException("Not implemented.");
}
@@ -190,6 +190,8 @@ interface EntityManagerInterface extends ObjectManager
/**
* Creates a copy of the given entity. Can create a shallow or a deep copy.
*
* @deprecated 2.7 This method is being removed from the ORM and won't have any replacement
*
* @param object $entity The entity to copy.
* @param boolean $deep FALSE for a shallow copy, TRUE for a deep copy.
*
@@ -23,6 +23,7 @@ use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker;
use PDO;
use function array_map;
use function in_array;
@@ -351,13 +352,11 @@ abstract class AbstractHydrator
// WARNING: BC break! We know this is the desired behavior to type convert values, but this
// erroneous behavior exists since 2.0 and we're forced to keep compatibility.
if ( ! isset($cacheKeyInfo['isScalar'])) {
$dqlAlias = $cacheKeyInfo['dqlAlias'];
$type = $cacheKeyInfo['type'];
$fieldName = $dqlAlias . '_' . $fieldName;
$value = $type
? $type->convertToPHPValue($value, $this->_platform)
: $value;
if (! isset($cacheKeyInfo['isScalar'])) {
$type = $cacheKeyInfo['type'];
$value = $type ? $type->convertToPHPValue($value, $this->_platform) : $value;
$fieldName = $cacheKeyInfo['dqlAlias'] . '_' . $fieldName;
}
$rowData[$fieldName] = $value;
@@ -422,6 +421,12 @@ abstract class AbstractHydrator
'class' => new \ReflectionClass($mapping['className']),
];
case isset($this->_rsm->scalarMappings[$key], $this->_hints[LimitSubqueryWalker::FORCE_DBAL_TYPE_CONVERSION]):
return $this->_cache[$key] = [
'fieldName' => $this->_rsm->scalarMappings[$key],
'type' => Type::getType($this->_rsm->typeMappings[$key]),
'dqlAlias' => '',
];
case (isset($this->_rsm->scalarMappings[$key])):
return $this->_cache[$key] = [
'isScalar' => true,
@@ -422,7 +422,7 @@ class ObjectHydrator extends AbstractHydrator
$this->resultPointers[$dqlAlias] = $reflFieldValue[$index];
}
} else if ( ! $reflFieldValue) {
$reflFieldValue = $this->initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias);
$this->initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias);
} else if ($reflFieldValue instanceof PersistentCollection && $reflFieldValue->isInitialized() === false) {
$reflFieldValue->setInitialized(true);
}
@@ -22,6 +22,7 @@ namespace Doctrine\ORM\Internal\Hydration;
use PDO;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query;
use function in_array;
class SimpleObjectHydrator extends AbstractHydrator
{
@@ -78,8 +79,9 @@ class SimpleObjectHydrator extends AbstractHydrator
*/
protected function hydrateRowData(array $sqlResult, array &$result)
{
$entityName = $this->class->name;
$data = [];
$entityName = $this->class->name;
$data = [];
$discrColumnValue = null;
// We need to find the correct entity class name if we have inheritance in resultset
if ($this->class->inheritanceType !== ClassMetadata::INHERITANCE_TYPE_NONE) {
@@ -104,7 +106,8 @@ class SimpleObjectHydrator extends AbstractHydrator
throw HydrationException::invalidDiscriminatorValue($sqlResult[$discrColumnName], array_keys($discrMap));
}
$entityName = $discrMap[$sqlResult[$discrColumnName]];
$entityName = $discrMap[$sqlResult[$discrColumnName]];
$discrColumnValue = $sqlResult[$discrColumnName];
unset($sqlResult[$discrColumnName]);
}
@@ -134,6 +137,11 @@ class SimpleObjectHydrator extends AbstractHydrator
// Prevent overwrite in case of inherit classes using same property name (See AbstractHydrator)
if ( ! isset($data[$fieldName]) || ! $valueIsNull) {
// If we have inheritance in resultset, make sure the field belongs to the correct class
if (isset($cacheKeyInfo['discriminatorValues']) && ! in_array($discrColumnValue, $cacheKeyInfo['discriminatorValues'], true)) {
continue;
}
$data[$fieldName] = $value;
}
}
@@ -99,7 +99,8 @@ class DefaultQuoteStrategy implements QuoteStrategy
$schema = '';
if (isset($association['joinTable']['schema'])) {
$schema = $association['joinTable']['schema'] . '.';
$schema = $association['joinTable']['schema'];
$schema .= ! $platform->supportsSchemas() && $platform->canEmulateSchemas() ? '__' : '.';
}
$tableName = $association['joinTable']['name'];
@@ -44,6 +44,7 @@ class AnnotationDriver extends AbstractAnnotationDriver
protected $entityAnnotationClasses = [
Mapping\Entity::class => 1,
Mapping\MappedSuperclass::class => 2,
Mapping\Embeddable::class => 3,
];
/**
@@ -29,6 +29,7 @@ use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Mapping\MappingException;
use function preg_replace;
/**
* The DatabaseDriver reverse engineers the mapping metadata from a database.
@@ -548,7 +549,7 @@ class DatabaseDriver implements MappingDriver
// Replace _id if it is a foreignkey column
if ($fk) {
$columnName = str_replace('_id', '', $columnName);
$columnName = preg_replace('/_id$/', '', $columnName);
}
return Inflector::camelize($columnName);
@@ -25,6 +25,7 @@ use Doctrine\Common\Persistence\Mapping\Driver\FileDriver;
use Doctrine\ORM\Mapping\ClassMetadata as Metadata;
use Doctrine\ORM\Mapping\MappingException;
use Symfony\Component\Yaml\Yaml;
use function trigger_error;
/**
* The YamlDriver reads the mapping metadata from yaml schema files.
@@ -34,6 +35,8 @@ use Symfony\Component\Yaml\Yaml;
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class YamlDriver extends FileDriver
{
@@ -44,6 +47,11 @@ class YamlDriver extends FileDriver
*/
public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION)
{
@trigger_error(
'YAML mapping driver is deprecated and will be removed in Doctrine ORM 3.0, please migrate to annotation or XML driver.',
E_USER_DEPRECATED
);
parent::__construct($locator, $fileExtension);
}
@@ -20,30 +20,55 @@
namespace Doctrine\ORM\Mapping;
use const CASE_LOWER;
use const CASE_UPPER;
use const E_USER_DEPRECATED;
use function preg_replace;
use function strpos;
use function strrpos;
use function strtolower;
use function strtoupper;
use function substr;
use function trigger_error;
/**
* Naming strategy implementing the underscore naming convention.
* Converts 'MyEntity' to 'my_entity' or 'MY_ENTITY'.
*
*
*
* @link www.doctrine-project.org
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class UnderscoreNamingStrategy implements NamingStrategy
{
private const DEFAULT_PATTERN = '/(?<=[a-z])([A-Z])/';
private const NUMBER_AWARE_PATTERN = '/(?<=[a-z0-9])([A-Z])/';
/**
* @var integer
*/
private $case;
/** @var string */
private $pattern;
/**
* Underscore naming strategy construct.
*
* @param integer $case CASE_LOWER | CASE_UPPER
* @param int $case CASE_LOWER | CASE_UPPER
*/
public function __construct($case = CASE_LOWER)
public function __construct($case = CASE_LOWER, bool $numberAware = false)
{
$this->case = $case;
if (! $numberAware) {
@trigger_error(
'Creating ' . self::class . ' without making it number aware is deprecated and will be removed in Doctrine ORM 3.0.',
E_USER_DEPRECATED
);
}
$this->case = $case;
$this->pattern = $numberAware ? self::NUMBER_AWARE_PATTERN : self::DEFAULT_PATTERN;
}
/**
@@ -57,7 +82,7 @@ class UnderscoreNamingStrategy implements NamingStrategy
/**
* Sets string case CASE_LOWER | CASE_UPPER.
* Alphabetic characters converted to lowercase or uppercase.
*
*
* @param integer $case
*
* @return void
@@ -118,7 +143,7 @@ class UnderscoreNamingStrategy implements NamingStrategy
{
return $this->classToTableName($sourceEntity) . '_' . $this->classToTableName($targetEntity);
}
/**
* {@inheritdoc}
*/
@@ -127,15 +152,10 @@ class UnderscoreNamingStrategy implements NamingStrategy
return $this->classToTableName($entityName) . '_' .
($referencedColumnName ?: $this->referenceColumnName());
}
/**
* @param string $string
*
* @return string
*/
private function underscore($string)
private function underscore(string $string) : string
{
$string = preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $string);
$string = preg_replace($this->pattern, '_$1', $string);
if ($this->case === CASE_UPPER) {
return strtoupper($string);
+2 -15
View File
@@ -25,7 +25,6 @@ use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Selectable;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping\ClassMetadata;
use function array_merge;
use function get_class;
/**
@@ -368,16 +367,6 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
*/
public function removeElement($element)
{
if ( ! $this->initialized && $this->association['fetch'] === ClassMetadata::FETCH_EXTRA_LAZY) {
if ($this->collection->contains($element)) {
return $this->collection->removeElement($element);
}
$persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association);
return $persister->removeElement($this, $element);
}
$removed = parent::removeElement($element);
if ( ! $removed) {
@@ -567,9 +556,7 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
if ($this->association['isOwningSide'] && $this->owner) {
$this->changed();
if (! $this->em->getClassMetadata(get_class($this->owner))->isChangeTrackingDeferredExplicit()) {
$uow->scheduleCollectionDeletion($this);
}
$uow->scheduleCollectionDeletion($this);
$this->takeSnapshot();
}
@@ -672,7 +659,7 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
$criteria = clone $criteria;
$criteria->where($expression);
$criteria->orderBy(array_merge($this->association['orderBy'] ?? [], $criteria->getOrderings()));
$criteria->orderBy($criteria->getOrderings() ?: $this->association['orderBy'] ?? []);
$persister = $this->em->getUnitOfWork()->getEntityPersister($this->association['targetEntity']);
@@ -90,16 +90,6 @@ interface CollectionPersister
*/
public function containsKey(PersistentCollection $collection, $key);
/**
* Removes an element.
*
* @param \Doctrine\ORM\PersistentCollection $collection
* @param object $element
*
* @return mixed
*/
public function removeElement(PersistentCollection $collection, $element);
/**
* Gets an element by key.
*
@@ -211,22 +211,6 @@ class ManyToManyPersister extends AbstractCollectionPersister
return (bool) $this->conn->fetchColumn($sql, $params, 0, $types);
}
/**
* {@inheritDoc}
*/
public function removeElement(PersistentCollection $collection, $element)
{
if ( ! $this->isValidEntityState($element)) {
return false;
}
list($quotedJoinTable, $whereClauses, $params, $types) = $this->getJoinTableRestrictions($collection, $element, false);
$sql = 'DELETE FROM ' . $quotedJoinTable . ' WHERE ' . implode(' AND ', $whereClauses);
return (bool) $this->conn->executeUpdate($sql, $params, $types);
}
/**
* {@inheritDoc}
*/
@@ -166,28 +166,6 @@ class OneToManyPersister extends AbstractCollectionPersister
return $persister->exists($element, $criteria);
}
/**
* {@inheritdoc}
*/
public function removeElement(PersistentCollection $collection, $element)
{
$mapping = $collection->getMapping();
if ( ! $mapping['orphanRemoval']) {
// no-op: this is not the owning side, therefore no operations should be applied
return false;
}
if ( ! $this->isValidEntityState($element)) {
return false;
}
return $this
->uow
->getEntityPersister($mapping['targetEntity'])
->delete($element);
}
/**
* {@inheritdoc}
*/
+2
View File
@@ -26,6 +26,8 @@ use Doctrine\Common\Proxy\Proxy as BaseProxy;
*
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
*
* @deprecated 2.7 This interface is being removed from the ORM and won't have any replacement, proxies will no longer implement it.
*/
interface Proxy extends BaseProxy
{
+2
View File
@@ -37,6 +37,8 @@ use Doctrine\ORM\Utility\IdentifierFlattener;
* @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
* @author Marco Pivetta <ocramius@gmail.com>
* @since 2.0
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class ProxyFactory extends AbstractProxyFactory
{
+5 -5
View File
@@ -133,7 +133,7 @@ final class Query extends AbstractQuery
*
* @var integer
*/
private $_state = self::STATE_CLEAN;
private $_state = self::STATE_DIRTY;
/**
* A snapshot of the parameter types the query was parsed with.
@@ -145,7 +145,7 @@ final class Query extends AbstractQuery
/**
* Cached DQL query.
*
* @var string
* @var string|null
*/
private $_dql = null;
@@ -159,7 +159,7 @@ final class Query extends AbstractQuery
/**
* The first result to return (the "offset").
*
* @var integer
* @var int|null
*/
private $_firstResult = null;
@@ -587,7 +587,7 @@ final class Query extends AbstractQuery
/**
* Returns the DQL query that is represented by this query object.
*
* @return string DQL query.
* @return string|null
*/
public function getDQL()
{
@@ -640,7 +640,7 @@ final class Query extends AbstractQuery
* Gets the position of the first result the query object was set to retrieve (the "offset").
* Returns NULL if {@link setFirstResult} was not applied to this query.
*
* @return integer The position of the first result.
* @return int|null The position of the first result.
*/
public function getFirstResult()
{
+2 -2
View File
@@ -189,7 +189,7 @@ class Parser
{
$this->query = $query;
$this->em = $query->getEntityManager();
$this->lexer = new Lexer($query->getDQL());
$this->lexer = new Lexer((string) $query->getDQL());
$this->parserResult = new ParserResult();
}
@@ -302,7 +302,7 @@ class Parser
*/
public function match($token)
{
$lookaheadType = $this->lexer->lookahead['type'];
$lookaheadType = $this->lexer->lookahead['type'] ?? null;
// Short-circuit on first condition, usually types match
if ($lookaheadType === $token) {
@@ -116,7 +116,7 @@ EOT
)
);
return;
return 0;
}
if ($input->getOption('all')) {
@@ -124,7 +124,7 @@ EOT
$cache->evictEntityRegions();
return;
return 0;
}
if ($ownerId) {
@@ -138,10 +138,12 @@ EOT
);
$cache->evictCollection($ownerClass, $assoc, $ownerId);
return;
return 0;
}
$ui->comment(sprintf('Clearing second-level cache for collection <info>"%s#%s"</info>', $ownerClass, $assoc));
$cache->evictCollectionRegion($ownerClass, $assoc);
return 0;
}
}
@@ -108,7 +108,7 @@ EOT
$ui->comment(sprintf('Flushing cache provider configured for entity named <info>"%s"</info>', $entityClass));
return;
return 0;
}
if ($input->getOption('all')) {
@@ -116,7 +116,7 @@ EOT
$cache->evictEntityRegions();
return;
return 0;
}
if ($entityId) {
@@ -129,10 +129,12 @@ EOT
);
$cache->evictEntity($entityClass, $entityId);
return;
return 0;
}
$ui->comment(sprintf('Clearing second-level cache for entity <info>"%s"</info>', $entityClass));
$cache->evictEntityRegion($entityClass);
return 0;
}
}
@@ -112,7 +112,7 @@ EOT
)
);
return;
return 0;
}
if ($input->getOption('all')) {
@@ -120,10 +120,12 @@ EOT
$cache->evictQueryRegions();
return;
return 0;
}
$ui->comment(sprintf('Clearing second-level cache query region named <info>"%s"</info>', $name));
$cache->evictQueryRegion($name);
return 0;
}
}
@@ -27,6 +27,7 @@ use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* Command to convert a Doctrine 1 schema to a Doctrine 2 mapping file.
@@ -37,6 +38,8 @@ use Symfony\Component\Console\Output\OutputInterface;
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class ConvertDoctrine1SchemaCommand extends Command
{
@@ -116,6 +119,9 @@ class ConvertDoctrine1SchemaCommand extends Command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$ui = new SymfonyStyle($input, $output);
$ui->warning('Command ' . $this->getName() . ' is deprecated and will be removed in Doctrine ORM 3.0.');
// Process source directories
$fromPaths = array_merge([$input->getArgument('from-path')], $input->getOption('from'));
@@ -127,6 +133,8 @@ class ConvertDoctrine1SchemaCommand extends Command
$numSpaces = $input->getOption('num-spaces');
$this->convertDoctrine1Schema($fromPaths, $destPath, $toType, $numSpaces, $extend, $output);
return 0;
}
/**
@@ -167,6 +167,8 @@ EOT
$destPath
)
);
return 0;
}
/**
@@ -38,6 +38,8 @@ use Symfony\Component\Console\Style\SymfonyStyle;
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class GenerateEntitiesCommand extends Command
{
@@ -87,6 +89,7 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output)
{
$ui = new SymfonyStyle($input, $output);
$ui->warning('Command ' . $this->getName() . ' is deprecated and will be removed in Doctrine ORM 3.0.');
$em = $this->getHelper('em')->getEntityManager();
@@ -112,7 +115,7 @@ EOT
if (empty($metadatas)) {
$ui->success('No Metadata Classes to process.');
return;
return 0;
}
$entityGenerator = new EntityGenerator();
@@ -138,5 +141,7 @@ EOT
// Outputting information message
$ui->newLine();
$ui->success(sprintf('Entity classes generated to "%s"', $destPath));
return 0;
}
}
@@ -91,7 +91,7 @@ class GenerateProxiesCommand extends Command
if (empty($metadatas)) {
$ui->success('No Metadata Classes to process.');
return;
return 0;
}
foreach ($metadatas as $metadata) {
@@ -104,5 +104,7 @@ class GenerateProxiesCommand extends Command
// Outputting information message
$ui->newLine();
$ui->text(sprintf('Proxy classes generated to "<info>%s</info>"', $destPath));
return 0;
}
}
@@ -37,6 +37,8 @@ use Symfony\Component\Console\Style\SymfonyStyle;
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class GenerateRepositoriesCommand extends Command
{
@@ -59,6 +61,7 @@ class GenerateRepositoriesCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output)
{
$ui = new SymfonyStyle($input, $output);
$ui->warning('Command ' . $this->getName() . ' is deprecated and will be removed in Doctrine ORM 3.0.');
$em = $this->getHelper('em')->getEntityManager();
@@ -84,7 +87,7 @@ class GenerateRepositoriesCommand extends Command
if (empty($metadatas)) {
$ui->success('No Metadata Classes to process.');
return;
return 0;
}
$numRepositories = 0;
@@ -104,11 +107,13 @@ class GenerateRepositoriesCommand extends Command
if ($numRepositories === 0) {
$ui->text('No Repository classes were found to be processed.');
return;
return 0;
}
// Outputting information message
$ui->newLine();
$ui->text(sprintf('Repository classes generated to "<info>%s</info>"', $destPath));
return 0;
}
}
@@ -26,6 +26,10 @@ use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use const JSON_PRETTY_PRINT;
use const JSON_UNESCAPED_SLASHES;
use const JSON_UNESCAPED_UNICODE;
use function json_encode;
/**
* Show information about mapped entities.
@@ -213,7 +217,7 @@ EOT
}
if (is_array($value)) {
return json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
return json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
}
if (is_object($value)) {
@@ -104,11 +104,13 @@ class RunDqlCommand extends Command
if ($input->getOption('show-sql')) {
$ui->text($query->getSQL());
return;
return 0;
}
$resultSet = $query->execute([], constant($hydrationMode));
$ui->text(Debug::dump($resultSet, $input->getOption('depth'), true, false));
return 0;
}
}
@@ -22,7 +22,8 @@ namespace Doctrine\ORM\Tools\Console;
use Doctrine\DBAL\Tools\Console as DBALConsole;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
use Doctrine\ORM\Version;
use OutOfBoundsException;
use PackageVersions\Versions;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\HelperSet;
@@ -70,10 +71,11 @@ final class ConsoleRunner
* @param array $commands
*
* @return \Symfony\Component\Console\Application
* @throws OutOfBoundsException
*/
public static function createApplication(HelperSet $helperSet, array $commands = []) : Application
{
$cli = new Application('Doctrine Command Line Interface', Version::VERSION);
$cli = new Application('Doctrine Command Line Interface', Versions::getVersion('doctrine/orm'));
$cli->setCatchExceptions(true);
$cli->setHelperSet($helperSet);
self::addCommands($cli);
+19 -3
View File
@@ -23,6 +23,10 @@ use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Inflector\Inflector;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use const E_USER_DEPRECATED;
use function str_replace;
use function trigger_error;
use function var_export;
/**
* Generic class used to generate PHP5 entity classes from ClassMetadataInfo instances.
@@ -44,6 +48,8 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo;
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class EntityGenerator
{
@@ -334,6 +340,8 @@ public function __construct(<params>)
*/
public function __construct()
{
@trigger_error(self::class . ' is deprecated and will be removed in Doctrine ORM 3.0', E_USER_DEPRECATED);
if (version_compare(\Doctrine\Common\Version::VERSION, '2.2.0-DEV', '>=')) {
$this->annotationsPrefix = 'ORM\\';
}
@@ -1321,9 +1329,17 @@ public function __construct(<params>)
continue;
}
$defaultValue = '';
if (isset($fieldMapping['options']['default'])) {
if ($fieldMapping['type'] === 'boolean' && $fieldMapping['options']['default'] === '1') {
$defaultValue = ' = true';
} else {
$defaultValue = ' = ' . var_export($fieldMapping['options']['default'], true);
}
}
$lines[] = $this->generateFieldMappingPropertyDocBlock($fieldMapping, $metadata);
$lines[] = $this->spaces . $this->fieldVisibility . ' $' . $fieldMapping['fieldName']
. (isset($fieldMapping['options']['default']) ? ' = ' . var_export($fieldMapping['options']['default'], true) : null) . ";\n";
$lines[] = $this->spaces . $this->fieldVisibility . ' $' . $fieldMapping['fieldName'] . $defaultValue . ";\n";
}
return implode("\n", $lines);
@@ -1679,7 +1695,7 @@ public function __construct(<params>)
}
if (isset($fieldMapping['options']['comment']) && $fieldMapping['options']['comment']) {
$options[] = '"comment"="' . $fieldMapping['options']['comment'] .'"';
$options[] = '"comment"="' . str_replace('"', '""', $fieldMapping['options']['comment']) . '"';
}
if (isset($fieldMapping['options']['collation']) && $fieldMapping['options']['collation']) {
@@ -20,6 +20,8 @@
namespace Doctrine\ORM\Tools;
use Doctrine\ORM\EntityRepository;
use const E_USER_DEPRECATED;
use function trigger_error;
/**
* Class to generate entity repository classes
@@ -31,6 +33,8 @@ use Doctrine\ORM\EntityRepository;
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class EntityRepositoryGenerator
{
@@ -52,6 +56,11 @@ class <className> extends <repositoryName>
}
';
public function __construct()
{
@trigger_error(self::class . ' is deprecated and will be removed in Doctrine ORM 3.0', E_USER_DEPRECATED);
}
/**
* @param string $fullClassName
*
@@ -19,6 +19,9 @@
namespace Doctrine\ORM\Tools\Export;
use const E_USER_DEPRECATED;
use function trigger_error;
/**
* Class used for converting your mapping information between the
* supported formats: yaml, xml, and php/annotation.
@@ -26,6 +29,8 @@ namespace Doctrine\ORM\Tools\Export;
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class ClassMetadataExporter
{
@@ -40,6 +45,11 @@ class ClassMetadataExporter
'annotation' => Driver\AnnotationExporter::class
];
public function __construct()
{
@trigger_error(self::class . ' is deprecated and will be removed in Doctrine ORM 3.0', E_USER_DEPRECATED);
}
/**
* Registers a new exporter driver class under a specified name.
*
@@ -21,6 +21,8 @@ namespace Doctrine\ORM\Tools\Export\Driver;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Tools\Export\ExportException;
use const E_USER_DEPRECATED;
use function trigger_error;
/**
* Abstract base class which is to be used for the Exporter drivers
@@ -29,6 +31,8 @@ use Doctrine\ORM\Tools\Export\ExportException;
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
abstract class AbstractExporter
{
@@ -57,6 +61,8 @@ abstract class AbstractExporter
*/
public function __construct($dir = null)
{
@trigger_error(static::class . ' is deprecated and will be removed in Doctrine ORM 3.0', E_USER_DEPRECATED);
$this->_outputDir = $dir;
}
@@ -28,6 +28,8 @@ use Doctrine\ORM\Tools\EntityGenerator;
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class AnnotationExporter extends AbstractExporter
{
@@ -27,6 +27,8 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo;
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class PhpExporter extends AbstractExporter
{
@@ -28,6 +28,8 @@ use SimpleXMLElement;
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class XmlExporter extends AbstractExporter
{
@@ -28,6 +28,8 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo;
* @link www.doctrine-project.org
* @since 2.0
* @author Jonathan Wage <jonwage@gmail.com>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class YamlExporter extends AbstractExporter
{
@@ -21,6 +21,9 @@ namespace Doctrine\ORM\Tools\Export;
use Doctrine\ORM\ORMException;
/**
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class ExportException extends ORMException
{
/**
@@ -39,10 +39,9 @@ use Doctrine\ORM\Query\AST\SelectStatement;
*/
class LimitSubqueryWalker extends TreeWalkerAdapter
{
/**
* ID type hint.
*/
const IDENTIFIER_TYPE = 'doctrine_paginator.id.type';
public const IDENTIFIER_TYPE = 'doctrine_paginator.id.type';
public const FORCE_DBAL_TYPE_CONVERSION = 'doctrine_paginator.scalar_result.force_dbal_type_conversion';
/**
* Counter for generating unique order column aliases.
@@ -82,6 +81,8 @@ class LimitSubqueryWalker extends TreeWalkerAdapter
Type::getType($rootClass->fieldMappings[$identifier]['type'])
);
$this->_getQuery()->setHint(self::FORCE_DBAL_TYPE_CONVERSION, true);
$pathExpression = new PathExpression(
PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
$rootAlias,
@@ -139,7 +139,7 @@ class Paginator implements \Countable, \IteratorAggregate
$offset = $this->query->getFirstResult();
$length = $this->query->getMaxResults();
if ($this->fetchJoinCollection) {
if ($this->fetchJoinCollection && $length !== null) {
$subQuery = $this->cloneQuery($this->query);
if ($this->useOutputWalker($subQuery)) {
@@ -166,6 +166,7 @@ class Paginator implements \Countable, \IteratorAggregate
$whereInQuery->setFirstResult(null)->setMaxResults(null);
$whereInQuery->setParameter(WhereInWalker::PAGINATOR_ID_ALIAS, $ids);
$whereInQuery->setCacheable($this->query->isCacheable());
$whereInQuery->expireQueryCache();
$result = $whereInQuery->getResult($this->query->getHydrationMode());
} else {
+34 -4
View File
@@ -19,7 +19,7 @@
namespace Doctrine\ORM\Tools;
use Doctrine\ORM\ORMException;
use Doctrine\DBAL\Schema\AbstractAsset;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Schema;
@@ -28,6 +28,7 @@ use Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector;
use Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
@@ -891,10 +892,8 @@ class SchemaTool
*/
public function getUpdateSchemaSql(array $classes, $saveMode = false)
{
$sm = $this->em->getConnection()->getSchemaManager();
$fromSchema = $sm->createSchema();
$toSchema = $this->getSchemaFromMetadata($classes);
$fromSchema = $this->createSchemaForComparison($toSchema);
$comparator = new Comparator();
$schemaDiff = $comparator->compare($fromSchema, $toSchema);
@@ -905,4 +904,35 @@ class SchemaTool
return $schemaDiff->toSql($this->platform);
}
/**
* Creates the schema from the database, ensuring tables from the target schema are whitelisted for comparison.
*/
private function createSchemaForComparison(Schema $toSchema) : Schema
{
$connection = $this->em->getConnection();
$schemaManager = $connection->getSchemaManager();
// backup schema assets filter
$config = $connection->getConfiguration();
$previousFilter = $config->getSchemaAssetsFilter();
if ($previousFilter === null) {
return $schemaManager->createSchema();
}
// whitelist assets we already know about in $toSchema, use the existing filter otherwise
$config->setSchemaAssetsFilter(static function ($asset) use ($previousFilter, $toSchema) : bool {
$assetName = $asset instanceof AbstractAsset ? $asset->getName() : $asset;
return $toSchema->hasTable($assetName) || $toSchema->hasSequence($assetName) || $previousFilter($asset);
});
try {
return $schemaManager->createSchema();
} finally {
// restore schema assets filter
$config->setSchemaAssetsFilter($previousFilter);
}
}
}
+32 -17
View File
@@ -46,6 +46,7 @@ use Doctrine\ORM\Utility\IdentifierFlattener;
use InvalidArgumentException;
use Throwable;
use UnexpectedValueException;
use function get_class;
/**
* The UnitOfWork is responsible for tracking changes to objects during an
@@ -380,7 +381,18 @@ class UnitOfWork implements PropertyChangedListener
try {
// Collection deletions (deletions of complete collections)
foreach ($this->collectionDeletions as $collectionToDelete) {
$this->getCollectionPersister($collectionToDelete->getMapping())->delete($collectionToDelete);
if (! $collectionToDelete instanceof PersistentCollection) {
$this->getCollectionPersister($collectionToDelete->getMapping())->delete($collectionToDelete);
continue;
}
// Deferred explicit tracked collections can be removed only when owning relation was persisted
$owner = $collectionToDelete->getOwner();
if ($this->em->getClassMetadata(get_class($owner))->isChangeTrackingDeferredImplicit() || $this->isScheduledForDirtyCheck($owner)) {
$this->getCollectionPersister($collectionToDelete->getMapping())->delete($collectionToDelete);
}
}
if ($this->entityInsertions) {
@@ -1866,7 +1878,7 @@ class UnitOfWork implements PropertyChangedListener
* @throws OptimisticLockException If the entity uses optimistic locking through a version
* attribute and the version check against the managed copy fails.
*
* @todo Require active transaction!? OptimisticLockException may result in undefined state!?
* @deprecated 2.7 This method is being removed from the ORM and won't have any replacement
*/
public function merge($entity)
{
@@ -2056,6 +2068,8 @@ class UnitOfWork implements PropertyChangedListener
* @param object $entity The entity to detach.
*
* @return void
*
* @deprecated 2.7 This method is being removed from the ORM and won't have any replacement
*/
public function detach($entity)
{
@@ -2483,22 +2497,23 @@ class UnitOfWork implements PropertyChangedListener
public function clear($entityName = null)
{
if ($entityName === null) {
$this->identityMap =
$this->entityIdentifiers =
$this->originalEntityData =
$this->entityChangeSets =
$this->entityStates =
$this->scheduledForSynchronization =
$this->entityInsertions =
$this->entityUpdates =
$this->entityDeletions =
$this->identityMap =
$this->entityIdentifiers =
$this->originalEntityData =
$this->entityChangeSets =
$this->entityStates =
$this->scheduledForSynchronization =
$this->entityInsertions =
$this->entityUpdates =
$this->entityDeletions =
$this->nonCascadedNewDetectedEntities =
$this->collectionDeletions =
$this->collectionUpdates =
$this->extraUpdates =
$this->readOnlyObjects =
$this->visitedCollections =
$this->orphanRemovals = [];
$this->collectionDeletions =
$this->collectionUpdates =
$this->extraUpdates =
$this->readOnlyObjects =
$this->visitedCollections =
$this->eagerLoadingEntities =
$this->orphanRemovals = [];
} else {
$this->clearIdentityMapForEntityName($entityName);
$this->clearEntityInsertionsForEntityName($entityName);
+3 -1
View File
@@ -29,13 +29,15 @@ namespace Doctrine\ORM;
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*
* @deprecated 2.7 This class is being removed from the ORM and won't have any replacement
*/
class Version
{
/**
* Current Doctrine Version
*/
const VERSION = '2.6.4-DEV';
const VERSION = '2.7.1-DEV';
/**
* Compares a Doctrine version with the current one.
@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace Doctrine\Tests\Mapping;
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
use Doctrine\Tests\VerifyDeprecations;
use PHPUnit\Framework\TestCase;
use const CASE_LOWER;
final class UnderscoreNamingStrategyTest extends TestCase
{
use VerifyDeprecations;
/** @test */
public function checkDeprecationMessage() : void
{
$this->expectDeprecationMessage('Creating Doctrine\ORM\Mapping\UnderscoreNamingStrategy without making it number aware is deprecated and will be removed in Doctrine ORM 3.0.');
new UnderscoreNamingStrategy(CASE_LOWER, false);
}
}
@@ -227,23 +227,6 @@ abstract class AbstractCollectionPersisterTest extends OrmTestCase
$this->assertFalse($persister->containsKey($collection, 0));
}
public function testInvokeRemoveElement()
{
$entity = new State("Foo");
$element = new State("Bar");
$persister = $this->createPersisterDefault();
$collection = $this->createCollection($entity);
$this->em->getUnitOfWork()->registerManaged($entity, ['id'=>1], ['id'=>1, 'name'=>'Foo']);
$this->collectionPersister->expects($this->once())
->method('removeElement')
->with($this->equalTo($collection), $this->equalTo($element))
->will($this->returnValue(false));
$this->assertFalse($persister->removeElement($collection, $element));
}
public function testInvokeGet()
{
$entity = new State("Foo");
@@ -5,10 +5,14 @@ namespace Doctrine\Tests\ORM\Decorator;
use Doctrine\ORM\Decorator\EntityManagerDecorator;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Tests\VerifyDeprecations;
use PHPUnit\Framework\TestCase;
use function in_array;
class EntityManagerDecoratorTest extends TestCase
{
use VerifyDeprecations;
const VOID_METHODS = [
'persist',
'remove',
@@ -24,6 +28,12 @@ class EntityManagerDecoratorTest extends TestCase
*/
private $wrapped;
/** @before */
public function ignoreDeprecationMessagesFromDoctrinePersistence() : void
{
$this->ignoreDeprecationMessage('The Doctrine\Common\Persistence\ObjectManagerDecorator class is deprecated since doctrine/persistence 1.3 and will be removed in 2.0. Use \Doctrine\Persistence\ObjectManagerDecorator instead.');
}
public function setUp()
{
$this->wrapped = $this->createMock(EntityManagerInterface::class);
@@ -83,5 +93,12 @@ class EntityManagerDecoratorTest extends TestCase
};
$this->assertSame($return, $decorator->$method(...$parameters));
if (in_array($method, ['copy', 'merge', 'detach', 'getHydrator'], true)) {
$this->assertHasDeprecationMessages();
return;
}
$this->assertNotHasDeprecationMessages();
}
}
@@ -20,9 +20,12 @@ use Doctrine\ORM\UnitOfWork;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\GeoNames\Country;
use Doctrine\Tests\OrmTestCase;
use Doctrine\Tests\VerifyDeprecations;
class EntityManagerTest extends OrmTestCase
{
use VerifyDeprecations;
/**
* @var EntityManager
*/
@@ -305,4 +308,53 @@ class EntityManagerTest extends OrmTestCase
$this->assertFalse($this->_em->contains($entity));
}
public function testDeprecatedClearWithArguments() : void
{
$entity = new Country(456, 'United Kingdom');
$this->_em->persist($entity);
$this->expectDeprecationMessage('Calling Doctrine\ORM\EntityManager::clear() with any arguments to clear specific entities is deprecated and will not be supported in Doctrine ORM 3.0.');
$this->_em->clear(Country::class);
}
public function testDeprecatedFlushWithArguments() : void
{
$entity = new Country(456, 'United Kingdom');
$this->_em->persist($entity);
$this->expectDeprecationMessage('Calling Doctrine\ORM\EntityManager::flush() with any arguments to flush specific entities is deprecated and will not be supported in Doctrine ORM 3.0.');
$this->_em->flush($entity);
}
public function testDeprecatedMerge() : void
{
$entity = new Country(456, 'United Kingdom');
$this->_em->persist($entity);
$this->expectDeprecationMessage('Method Doctrine\ORM\EntityManager::merge() is deprecated and will be removed in Doctrine ORM 3.0.');
$this->_em->merge($entity);
}
public function testDeprecatedDetach() : void
{
$entity = new Country(456, 'United Kingdom');
$this->_em->persist($entity);
$this->expectDeprecationMessage('Method Doctrine\ORM\EntityManager::detach() is deprecated and will be removed in Doctrine ORM 3.0.');
$this->_em->detach($entity);
}
public function testDeprecatedCopy() : void
{
$entity = new Country(456, 'United Kingdom');
$this->_em->persist($entity);
try {
$this->expectDeprecationMessage('Method Doctrine\ORM\EntityManager::copy() is deprecated and will be removed in Doctrine ORM 3.0.');
$this->_em->copy($entity);
} catch (\BadMethodCallException $e) {
// do nothing
}
}
}
@@ -16,9 +16,12 @@ use Doctrine\Tests\Models\CMS\CmsComment;
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\OrmFunctionalTestCase;
use Doctrine\Tests\VerifyDeprecations;
class BasicFunctionalTest extends OrmFunctionalTestCase
{
use VerifyDeprecations;
protected function setUp()
{
$this->useModelSet('cms');
@@ -499,7 +502,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$this->_em->persist($address);
$this->_em->flush();
$this->_em->detach($address);
$this->_em->clear(CmsAddress::class);
$this->assertFalse($this->_em->contains($address));
$this->assertTrue($this->_em->contains($user));
@@ -894,6 +897,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$user2 = $this->_em->find(get_class($managedUser), $userId);
$this->assertInstanceOf(CmsUser::class, $user2);
$this->assertHasDeprecationMessages();
}
public function testMergeNonPersistedProperties()
@@ -921,6 +925,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$this->assertNull($user2->nonPersistedProperty);
$this->assertNull($user2->nonPersistedPropertyObject);
$this->assertEquals('active', $user2->status);
$this->assertHasDeprecationMessages();
}
public function testMergeThrowsExceptionIfEntityWithGeneratedIdentifierDoesNotExist()
@@ -933,6 +938,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$this->expectException(EntityNotFoundException::class);
$this->_em->merge($user);
$this->assertHasDeprecationMessages();
}
/**
@@ -962,6 +968,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$this->_em->clear();
$this->assertNull($this->_em->find(get_class($ph), $ph->phonenumber)->getUser());
$this->assertHasDeprecationMessages();
}
/**
@@ -1073,6 +1080,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$this->assertTrue($userB->id > 0, 'user b has an id');
$this->assertTrue($userC->id > 0, 'user c has an id');
$this->assertEquals('UserC', $userC->name, 'name has not changed because we did not flush it');
$this->assertHasDeprecationMessages();
}
/**
@@ -1094,6 +1102,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$user = $this->_em->find(get_class($user), $user->id);
$this->assertEquals('administrator', $user->status);
$this->assertHasDeprecationMessages();
}
/**
@@ -1137,6 +1146,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$this->assertTrue($this->_em->contains($otherUser), "Other user is contained in EntityManager");
$this->assertTrue($otherUser->id > 0, "other user has an id");
$this->assertHasDeprecationMessages();
}
/**
@@ -1164,6 +1174,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$this->assertTrue($this->_em->contains($address), "Other user is contained in EntityManager");
$this->assertTrue($address->id > 0, "other user has an id");
$this->assertHasDeprecationMessages();
}
/**
@@ -1213,6 +1224,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$this->_em->clear();
$this->assertNull($this->_em->find(get_class($user), $userId));
$this->assertHasDeprecationMessages();
}
/**
@@ -1241,6 +1253,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$this->assertTrue($this->_em->contains($otherUser), "Other user is contained in EntityManager");
$this->assertTrue($otherUser->id > 0, "other user has an id");
$this->assertHasDeprecationMessages();
}
/**
@@ -1270,6 +1283,7 @@ class BasicFunctionalTest extends OrmFunctionalTestCase
$user2 = $this->_em->find(get_class($user2), $user2->id);
$this->assertEquals('developer', $user2->status);
$this->assertHasDeprecationMessages();
}
/**
@@ -10,6 +10,7 @@ use Doctrine\Tests\Models\CMS\CmsPhonenumber;
use Doctrine\Tests\Models\CMS\CmsAddress;
use Doctrine\Tests\Models\CMS\CmsArticle;
use Doctrine\Tests\OrmFunctionalTestCase;
use Doctrine\Tests\VerifyDeprecations;
/**
* Description of DetachedEntityTest
@@ -18,6 +19,8 @@ use Doctrine\Tests\OrmFunctionalTestCase;
*/
class DetachedEntityTest extends OrmFunctionalTestCase
{
use VerifyDeprecations;
protected function setUp()
{
$this->useModelSet('cms');
@@ -44,6 +47,7 @@ class DetachedEntityTest extends OrmFunctionalTestCase
$this->assertFalse($user === $user2);
$this->assertTrue($this->_em->contains($user2));
$this->assertEquals('Roman B.', $user2->name);
$this->assertHasDeprecationMessages();
}
public function testSerializeUnserializeModifyMerge()
@@ -105,6 +109,7 @@ class DetachedEntityTest extends OrmFunctionalTestCase
$this->assertInstanceOf(CmsPhonenumber::class, $phonenumbers[0]);
$this->assertTrue($this->_em->getUnitOfWork()->isInIdentityMap($phonenumbers[0]));
$this->assertTrue($this->_em->contains($phonenumbers[0]), "Failed to assert that first phonenumber in collection is contained inside EntityManager persistence context.");
$this->assertHasDeprecationMessages();
}
/**
@@ -156,6 +161,7 @@ class DetachedEntityTest extends OrmFunctionalTestCase
$this->assertInstanceOf(Proxy::class, $managedAddress2->user);
$this->assertFalse($managedAddress2->user === $detachedAddress2->user);
$this->assertFalse($managedAddress2->user->__isInitialized__);
$this->assertHasDeprecationMessages();
}
/**
@@ -181,6 +187,7 @@ class DetachedEntityTest extends OrmFunctionalTestCase
$this->assertInstanceOf(CmsUser::class, $newUser);
$this->assertEquals('gblanco', $newUser->username);
$this->assertHasDeprecationMessages();
}
/**
@@ -200,6 +207,7 @@ class DetachedEntityTest extends OrmFunctionalTestCase
$this->assertFalse($this->_em->contains($user));
$this->assertFalse($this->_em->getUnitOfWork()->isInIdentityMap($user));
$this->assertHasDeprecationMessages();
}
/**
@@ -223,6 +231,7 @@ class DetachedEntityTest extends OrmFunctionalTestCase
$this->expectExceptionMessage('The optimistic lock failed, version 1 was expected, but is actually 2');
$this->_em->merge($article);
$this->assertHasDeprecationMessages();
}
}
@@ -20,12 +20,15 @@ use Doctrine\Tests\Models\DDC753\DDC753EntityWithCustomRepository;
use Doctrine\Tests\Models\DDC753\DDC753EntityWithDefaultCustomRepository;
use Doctrine\Tests\Models\DDC753\DDC753InvalidRepository;
use Doctrine\Tests\OrmFunctionalTestCase;
use Doctrine\Tests\VerifyDeprecations;
/**
* @author robo
*/
class EntityRepositoryTest extends OrmFunctionalTestCase
{
use VerifyDeprecations;
protected function setUp()
{
$this->useModelSet('cms');
@@ -969,6 +972,7 @@ class EntityRepositoryTest extends OrmFunctionalTestCase
$this->assertNull($usersIsNull[0]->getEmail());
$this->assertNull($usersEqNull[0]->getEmail());
$this->assertHasDeprecationMessages();
}
/**
File diff suppressed because it is too large Load Diff
@@ -5,9 +5,12 @@ namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Tests\Models\MixedToOneIdentity\CompositeToOneKeyState;
use Doctrine\Tests\Models\MixedToOneIdentity\Country;
use Doctrine\Tests\OrmFunctionalTestCase;
use Doctrine\Tests\VerifyDeprecations;
class MergeCompositeToOneKeyTest extends OrmFunctionalTestCase
{
use VerifyDeprecations;
/**
* {@inheritDoc}
*/
@@ -43,5 +46,6 @@ class MergeCompositeToOneKeyTest extends OrmFunctionalTestCase
$this->assertNotSame($state, $merged);
$this->assertInstanceOf(Country::class, $merged->country);
$this->assertNotSame($country, $merged->country);
$this->assertHasDeprecationMessages();
}
}
@@ -11,9 +11,12 @@ use Doctrine\ORM\Proxy\Proxy;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\Tests\Models\Generic\DateTimeModel;
use Doctrine\Tests\OrmFunctionalTestCase;
use Doctrine\Tests\VerifyDeprecations;
class MergeProxiesTest extends OrmFunctionalTestCase
{
use VerifyDeprecations;
/**
* {@inheritDoc}
*/
@@ -24,6 +27,12 @@ class MergeProxiesTest extends OrmFunctionalTestCase
parent::setUp();
}
/** @after */
public function ensureTestGeneratedDeprecationMessages() : void
{
$this->assertHasDeprecationMessages();
}
/**
* @group DDC-1392
* @group DDC-1734
@@ -4,9 +4,12 @@ namespace Doctrine\Tests\ORM\Functional;
use Doctrine\ORM\Tools\ToolsException;
use Doctrine\Tests\OrmFunctionalTestCase;
use Doctrine\Tests\VerifyDeprecations;
class MergeSharedEntitiesTest extends OrmFunctionalTestCase
{
use VerifyDeprecations;
/**
* {@inheritDoc}
*/
@@ -25,6 +28,12 @@ class MergeSharedEntitiesTest extends OrmFunctionalTestCase
}
}
/** @after */
public function ensureTestGeneratedDeprecationMessages() : void
{
$this->assertHasDeprecationMessages();
}
public function testMergeSharedNewEntities()
{
$file = new MSEFile;
@@ -5,12 +5,15 @@ namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Tests\Models\VersionedManyToOne\Article;
use Doctrine\Tests\Models\VersionedManyToOne\Category;
use Doctrine\Tests\OrmFunctionalTestCase;
use Doctrine\Tests\VerifyDeprecations;
/**
* @group MergeVersionedOneToMany
*/
class MergeVersionedManyToOneTest extends OrmFunctionalTestCase
{
use VerifyDeprecations;
protected function setUp()
{
$this->useModelSet('versioned_many_to_one');
@@ -40,5 +43,6 @@ class MergeVersionedManyToOneTest extends OrmFunctionalTestCase
$this->_em->flush();
$this->assertEquals(2, $articleMerged->version);
$this->assertHasDeprecationMessages();
}
}
@@ -2,19 +2,24 @@
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\ORM\Query;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Doctrine\Tests\DbalTypes\CustomIdObject;
use Doctrine\Tests\DbalTypes\CustomIdObjectType;
use Doctrine\Tests\Models\CMS\CmsArticle;
use Doctrine\Tests\Models\CMS\CmsEmail;
use Doctrine\Tests\Models\CMS\CmsGroup;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\Company\CompanyManager;
use Doctrine\Tests\Models\CustomType\CustomIdObjectTypeParent;
use Doctrine\Tests\Models\Pagination\Company;
use Doctrine\Tests\Models\Pagination\Department;
use Doctrine\Tests\Models\Pagination\Logo;
use Doctrine\Tests\Models\Pagination\User1;
use Doctrine\Tests\OrmFunctionalTestCase;
use ReflectionMethod;
use function iterator_to_array;
/**
* @group DDC-1613
@@ -26,6 +31,14 @@ class PaginationTest extends OrmFunctionalTestCase
$this->useModelSet('cms');
$this->useModelSet('pagination');
$this->useModelSet('company');
$this->useModelSet('custom_id_object_type');
if (DBALType::hasType(CustomIdObjectType::NAME)) {
DBALType::overrideType(CustomIdObjectType::NAME, CustomIdObjectType::class);
} else {
DBALType::addType(CustomIdObjectType::NAME, CustomIdObjectType::class);
}
parent::setUp();
$this->populate();
}
@@ -641,6 +654,27 @@ class PaginationTest extends OrmFunctionalTestCase
$this->assertEquals(1, $paginator->count());
}
/**
* @group GH-7890
*/
public function testCustomIdTypeWithoutOutputWalker()
{
$this->_em->persist(new CustomIdObjectTypeParent(new CustomIdObject('foo')));
$this->_em->flush();
$dql = 'SELECT p FROM Doctrine\Tests\Models\CustomType\CustomIdObjectTypeParent p';
$query = $this->_em->createQuery($dql);
$paginator = new Paginator($query, true);
$paginator->setUseOutputWalkers(false);
$matchedItems = iterator_to_array($paginator->getIterator());
self::assertCount(1, $matchedItems);
self::assertInstanceOf(CustomIdObjectTypeParent::class, $matchedItems[0]);
self::assertSame('foo', (string) $matchedItems[0]->id);
}
public function testCountQueryStripsParametersInSelect()
{
$query = $this->_em->createQuery(
@@ -83,7 +83,7 @@ class ProxiesLikeEntitiesTest extends OrmFunctionalTestCase
$this->assertInstanceOf(CmsUserProxy::class, $uninitializedProxy);
$this->_em->persist($uninitializedProxy);
$this->_em->flush($uninitializedProxy);
$this->_em->flush();
$this->assertFalse($uninitializedProxy->__isInitialized(), 'Proxy didn\'t get initialized during flush operations');
$this->assertEquals($userId, $uninitializedProxy->getId());
$this->_em->remove($uninitializedProxy);
@@ -8,6 +8,7 @@ use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\CMS\CmsArticle;
use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Tests\OrmFunctionalTestCase;
use function count;
/**
* ResultCacheTest
@@ -89,7 +90,7 @@ class ResultCacheTest extends OrmFunctionalTestCase
$this->assertTrue($cache->contains('testing_result_cache_id'));
}
public function testUseResultCache()
public function testUseResultCacheTrue()
{
$cache = new ArrayCache();
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
@@ -104,6 +105,22 @@ class ResultCacheTest extends OrmFunctionalTestCase
$this->_em->getConfiguration()->setResultCacheImpl(new ArrayCache());
}
public function testUseResultCacheFalse()
{
$cache = new ArrayCache();
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
$query->setResultCacheDriver($cache);
$query->setResultCacheId('testing_result_cache_id');
$query->useResultCache(false);
$query->getResult();
$this->assertFalse($cache->contains('testing_result_cache_id'));
$this->_em->getConfiguration()->setResultCacheImpl(new ArrayCache());
}
/**
* @group DDC-1026
*/
@@ -113,24 +130,99 @@ class ResultCacheTest extends OrmFunctionalTestCase
$sqlCount = count($this->_sqlLoggerStack->queries);
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux WHERE ux.id = ?1');
$query->setParameter(1, 1);
$query->setResultCacheDriver($cache);
$query->useResultCache(true);
$query->getResult();
$query->setParameter(1, 2);
$query->getResult();
$this->assertEquals($sqlCount + 2, count($this->_sqlLoggerStack->queries), "Two non-cached queries.");
// these queries should result in cache miss:
$query->setParameter(1, 1);
$query->useResultCache(true);
$query->getResult();
$query->setParameter(1, 2);
$query->getResult();
$this->assertEquals($sqlCount + 2, count($this->_sqlLoggerStack->queries), "The next two sql should have been cached, but were not.");
$this->assertCount(
$sqlCount + 2,
$this->_sqlLoggerStack->queries,
'Two non-cached queries.'
);
// these two queries should actually be cached, as they repeat previous ones:
$query->setParameter(1, 1);
$query->getResult();
$query->setParameter(1, 2);
$query->getResult();
$this->assertCount(
$sqlCount + 2,
$this->_sqlLoggerStack->queries,
'The next two sql queries should have been cached, but were not.'
);
}
public function testEnableResultCache() : void
{
$cache = new ArrayCache();
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
$query->enableResultCache();
$query->setResultCacheDriver($cache);
$query->setResultCacheId('testing_result_cache_id');
$query->getResult();
$this->assertTrue($cache->contains('testing_result_cache_id'));
$this->_em->getConfiguration()->setResultCacheImpl(new ArrayCache());
}
/**
* @group DDC-1026
*/
public function testEnableResultCacheParams() : void
{
$cache = new ArrayCache();
$sqlCount = count($this->_sqlLoggerStack->queries);
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux WHERE ux.id = ?1');
$query->setResultCacheDriver($cache);
$query->enableResultCache();
// these queries should result in cache miss:
$query->setParameter(1, 1);
$query->getResult();
$query->setParameter(1, 2);
$query->getResult();
$this->assertCount(
$sqlCount + 2,
$this->_sqlLoggerStack->queries,
'Two non-cached queries.'
);
// these two queries should actually be cached, as they repeat previous ones:
$query->setParameter(1, 1);
$query->getResult();
$query->setParameter(1, 2);
$query->getResult();
$this->assertCount(
$sqlCount + 2,
$this->_sqlLoggerStack->queries,
'The next two sql queries should have been cached, but were not.'
);
}
public function testDisableResultCache() : void
{
$cache = new ArrayCache();
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
$query->setResultCacheDriver($cache);
$query->setResultCacheId('testing_result_cache_id');
$query->disableResultCache();
$query->getResult();
$this->assertFalse($cache->contains('testing_result_cache_id'));
$this->_em->getConfiguration()->setResultCacheImpl(new ArrayCache());
}
public function testNativeQueryResultCaching()
@@ -143,7 +235,7 @@ class ResultCacheTest extends OrmFunctionalTestCase
$query = $this->_em->createNativeQuery('select u.id FROM cms_users u WHERE u.id = ?', $rsm);
$query->setParameter(1, 10);
$query->setResultCacheDriver($cache)->useResultCache(true);
$query->setResultCacheDriver($cache)->enableResultCache();
$this->assertEquals(0, $this->getCacheSize($cache));
@@ -229,7 +321,7 @@ class ResultCacheTest extends OrmFunctionalTestCase
$cache = new ArrayCache();
$query->setResultCacheDriver($cache)->useResultCache(true);
$query->setResultCacheDriver($cache)->enableResultCache();
$articles = $query->getResult();
@@ -241,7 +333,7 @@ class ResultCacheTest extends OrmFunctionalTestCase
$query2 = $this->_em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.user = ?1');
$query2->setParameter(1, $user1);
$query2->setResultCacheDriver($cache)->useResultCache(true);
$query2->setResultCacheDriver($cache)->enableResultCache();
$articles = $query2->getResult();
@@ -251,7 +343,7 @@ class ResultCacheTest extends OrmFunctionalTestCase
$query3 = $this->_em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.user = ?1');
$query3->setParameter(1, $user2);
$query3->setResultCacheDriver($cache)->useResultCache(true);
$query3->setResultCacheDriver($cache)->enableResultCache();
$articles = $query3->getResult();
@@ -5,6 +5,8 @@ namespace Doctrine\Tests\ORM\Functional\SchemaTool;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\Tests\OrmFunctionalTestCase;
use Doctrine\Tests\Models;
use function method_exists;
use function sprintf;
class MySqlSchemaToolTest extends OrmFunctionalTestCase
{
@@ -28,15 +30,16 @@ class MySqlSchemaToolTest extends OrmFunctionalTestCase
$tool = new SchemaTool($this->_em);
$sql = $tool->getCreateSchemaSql($classes);
$collation = $this->getColumnCollationDeclarationSQL('utf8_unicode_ci');
$this->assertEquals("CREATE TABLE cms_groups (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
$this->assertEquals("CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[1]);
$this->assertEquals("CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, INDEX IDX_7EA9409AA76ED395 (user_id), INDEX IDX_7EA9409AFE54D947 (group_id), PRIMARY KEY(user_id, group_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[2]);
$this->assertEquals("CREATE TABLE cms_users_tags (user_id INT NOT NULL, tag_id INT NOT NULL, INDEX IDX_93F5A1ADA76ED395 (user_id), INDEX IDX_93F5A1ADBAD26311 (tag_id), PRIMARY KEY(user_id, tag_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[3]);
$this->assertEquals("CREATE TABLE cms_tags (id INT AUTO_INCREMENT NOT NULL, tag_name VARCHAR(50) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[4]);
$this->assertEquals("CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, UNIQUE INDEX UNIQ_ACAC157BA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[5]);
$this->assertEquals("CREATE TABLE cms_emails (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(250) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[6]);
$this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, INDEX IDX_F21F790FA76ED395 (user_id), PRIMARY KEY(phonenumber)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[7]);
$this->assertEquals('CREATE TABLE cms_groups (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[0]);
$this->assertEquals('CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[1]);
$this->assertEquals('CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, INDEX IDX_7EA9409AA76ED395 (user_id), INDEX IDX_7EA9409AFE54D947 (group_id), PRIMARY KEY(user_id, group_id)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[2]);
$this->assertEquals('CREATE TABLE cms_users_tags (user_id INT NOT NULL, tag_id INT NOT NULL, INDEX IDX_93F5A1ADA76ED395 (user_id), INDEX IDX_93F5A1ADBAD26311 (tag_id), PRIMARY KEY(user_id, tag_id)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[3]);
$this->assertEquals('CREATE TABLE cms_tags (id INT AUTO_INCREMENT NOT NULL, tag_name VARCHAR(50) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[4]);
$this->assertEquals('CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, UNIQUE INDEX UNIQ_ACAC157BA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[5]);
$this->assertEquals('CREATE TABLE cms_emails (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(250) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[6]);
$this->assertEquals('CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, INDEX IDX_F21F790FA76ED395 (user_id), PRIMARY KEY(phonenumber)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[7]);
$this->assertEquals("ALTER TABLE cms_users ADD CONSTRAINT FK_3AF03EC5A832C1C9 FOREIGN KEY (email_id) REFERENCES cms_emails (id)", $sql[8]);
$this->assertEquals("ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id)", $sql[9]);
$this->assertEquals("ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AFE54D947 FOREIGN KEY (group_id) REFERENCES cms_groups (id)", $sql[10]);
@@ -48,6 +51,15 @@ class MySqlSchemaToolTest extends OrmFunctionalTestCase
$this->assertEquals(15, count($sql));
}
private function getColumnCollationDeclarationSQL(string $collation) : string
{
if (method_exists($this->_em->getConnection()->getDatabasePlatform(), 'getColumnCollationDeclarationSQL')) {
return $this->_em->getConnection()->getDatabasePlatform()->getColumnCollationDeclarationSQL($collation);
}
return sprintf('COLLATE %s', $collation);
}
public function testGetCreateSchemaSql2()
{
$classes = [
@@ -56,9 +68,10 @@ class MySqlSchemaToolTest extends OrmFunctionalTestCase
$tool = new SchemaTool($this->_em);
$sql = $tool->getCreateSchemaSql($classes);
$collation = $this->getColumnCollationDeclarationSQL('utf8_unicode_ci');
$this->assertEquals(1, count($sql));
$this->assertEquals("CREATE TABLE decimal_model (id INT AUTO_INCREMENT NOT NULL, `decimal` NUMERIC(5, 2) NOT NULL, `high_scale` NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
$this->assertEquals('CREATE TABLE decimal_model (id INT AUTO_INCREMENT NOT NULL, `decimal` NUMERIC(5, 2) NOT NULL, `high_scale` NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[0]);
}
public function testGetCreateSchemaSql3()
@@ -69,9 +82,10 @@ class MySqlSchemaToolTest extends OrmFunctionalTestCase
$tool = new SchemaTool($this->_em);
$sql = $tool->getCreateSchemaSql($classes);
$collation = $this->getColumnCollationDeclarationSQL('utf8_unicode_ci');
$this->assertEquals(1, count($sql));
$this->assertEquals("CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
$this->assertEquals('CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[0]);
}
/**
@@ -9,12 +9,15 @@ use Doctrine\Tests\Models\DDC117\DDC117Translation;
use Doctrine\Tests\Models\DDC117\DDC117ApproveChanges;
use Doctrine\Tests\Models\DDC117\DDC117Editor;
use Doctrine\Tests\Models\DDC117\DDC117Link;
use Doctrine\Tests\VerifyDeprecations;
/**
* @group DDC-117
*/
class DDC117Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
use VerifyDeprecations;
private $article1;
private $article2;
private $reference;
@@ -435,11 +438,12 @@ class DDC117Test extends \Doctrine\Tests\OrmFunctionalTestCase
$refRep = $this->_em->find(DDC117Reference::class, $idCriteria);
$this->_em->detach($refRep);
$this->_em->clear(DDC117Reference::class);
$refRep = $this->_em->merge($refRep);
$this->assertEquals($this->article1->id(), $refRep->source()->id());
$this->assertEquals($this->article2->id(), $refRep->target()->id());
$this->assertHasDeprecationMessages();
}
/**
@@ -4,12 +4,15 @@ namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\CMS\CmsGroup;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\VerifyDeprecations;
/**
* @group DDC-1276
*/
class DDC1276Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
use VerifyDeprecations;
public function setUp()
{
$this->useModelSet('cms');
@@ -43,5 +46,6 @@ class DDC1276Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(2, count($user->groups));
$this->_em->flush();
$this->assertHasDeprecationMessages();
}
}
@@ -2,11 +2,15 @@
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\VerifyDeprecations;
/**
* @group DDC-1383
*/
class DDC1383Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
use VerifyDeprecations;
protected function setUp()
{
parent::setUp();
@@ -47,6 +51,7 @@ class DDC1383Test extends \Doctrine\Tests\OrmFunctionalTestCase
// Parent is NOT instance of entity
self::assertTrue($parent instanceof DDC1383Entity,
"Entity class is " . get_class($parent) . ', "DDC1383Entity" was expected');
$this->assertHasDeprecationMessages();
}
}
@@ -3,12 +3,15 @@
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\ORM\UnitOfWork;
use Doctrine\Tests\VerifyDeprecations;
/**
* @group DDC-1392
*/
class DDC1392Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
use VerifyDeprecations;
protected function setUp()
{
parent::setUp();
@@ -61,6 +64,7 @@ class DDC1392Test extends \Doctrine\Tests\OrmFunctionalTestCase
$result = $q->getSingleScalarResult();
self::assertEquals(1, $result);
$this->assertHasDeprecationMessages();
}
}
@@ -2,11 +2,14 @@
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\VerifyDeprecations;
/**
* @group DDC-1509
*/
class DDC1509Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
use VerifyDeprecations;
protected function setUp()
{
@@ -48,6 +51,7 @@ class DDC1509Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertNotNull($pic->getThumbnail());
$this->assertNotNull($pic->getFile());
$this->assertHasDeprecationMessages();
}
}
@@ -3,12 +3,15 @@
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\VerifyDeprecations;
/**
* @group DDC-1594
*/
class DDC1594Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
use VerifyDeprecations;
public function setUp()
{
$this->useModelSet('cms');
@@ -37,5 +40,6 @@ class DDC1594Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertNotSame($mergedUser, $detachedUser);
$this->assertEquals('bar', $detachedUser->getName());
$this->assertEquals('bar', $mergedUser->getName());
$this->assertHasDeprecationMessages();
}
}
@@ -29,6 +29,7 @@ class DDC1685Test extends \Doctrine\Tests\OrmFunctionalTestCase
$dql = "SELECT ad FROM Doctrine\Tests\Models\DDC117\DDC117ArticleDetails ad";
$query = $this->_em->createQuery($dql);
$query->setMaxResults(1);
$this->paginator = new Paginator($query);
}
@@ -4,9 +4,12 @@ namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\ORM\Proxy\Proxy;
use Doctrine\Tests\Models\CMS\CmsGroup;
use Doctrine\Tests\VerifyDeprecations;
class DDC1734Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
use VerifyDeprecations;
/**
* {@inheritDoc}
*/
@@ -16,6 +19,12 @@ class DDC1734Test extends \Doctrine\Tests\OrmFunctionalTestCase
parent::setUp();
}
/** @after */
public function ensureTestGeneratedDeprecationMessages() : void
{
$this->assertHasDeprecationMessages();
}
/**
* This test is DDC-1734 minus the serialization, i.e. it works
*
@@ -26,7 +26,7 @@ class DDC2106Test extends \Doctrine\Tests\OrmFunctionalTestCase
$entity = new DDC2106Entity();
$this->_em->persist($entity);
$this->_em->flush();
$this->_em->detach($entity);
$this->_em->clear(DDC2106Entity::class);
$entity = $this->_em->getRepository(DDC2106Entity::class)->findOneBy([]);
// ... and a managed entity without id
@@ -2,6 +2,9 @@
namespace Doctrine\Tests\ORM\Functional\Ticket;
use function method_exists;
use function sprintf;
class DDC2182Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function testPassColumnOptionsToJoinColumns()
@@ -16,11 +19,21 @@ class DDC2182Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->getClassMetadata(DDC2182OptionChild::class),
]
);
$collation = $this->getColumnCollationDeclarationSQL('utf8_unicode_ci');
$this->assertEquals("CREATE TABLE DDC2182OptionParent (id INT UNSIGNED NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
$this->assertEquals("CREATE TABLE DDC2182OptionChild (id VARCHAR(255) NOT NULL, parent_id INT UNSIGNED DEFAULT NULL, INDEX IDX_B314D4AD727ACA70 (parent_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[1]);
$this->assertEquals('CREATE TABLE DDC2182OptionParent (id INT UNSIGNED NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[0]);
$this->assertEquals('CREATE TABLE DDC2182OptionChild (id VARCHAR(255) NOT NULL, parent_id INT UNSIGNED DEFAULT NULL, INDEX IDX_B314D4AD727ACA70 (parent_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 ' . $collation . ' ENGINE = InnoDB', $sql[1]);
$this->assertEquals("ALTER TABLE DDC2182OptionChild ADD CONSTRAINT FK_B314D4AD727ACA70 FOREIGN KEY (parent_id) REFERENCES DDC2182OptionParent (id)", $sql[2]);
}
private function getColumnCollationDeclarationSQL(string $collation) : string
{
if (method_exists($this->_em->getConnection()->getDatabasePlatform(), 'getColumnCollationDeclarationSQL')) {
return $this->_em->getConnection()->getDatabasePlatform()->getColumnCollationDeclarationSQL($collation);
}
return sprintf('COLLATE %s', $collation);
}
}
/**
@@ -7,12 +7,15 @@ use Doctrine\Common\PropertyChangedListener;
use Doctrine\Common\Proxy\Proxy;
use Doctrine\ORM\Tools\ToolsException;
use Doctrine\Tests\OrmFunctionalTestCase;
use Doctrine\Tests\VerifyDeprecations;
/**
* @group DDC-2230
*/
class DDC2230Test extends OrmFunctionalTestCase
{
use VerifyDeprecations;
protected function setUp()
{
parent::setUp();
@@ -48,6 +51,7 @@ class DDC2230Test extends OrmFunctionalTestCase
$this->assertInstanceOf(Proxy::class, $address);
$this->assertFalse($address->__isInitialized());
$this->assertHasDeprecationMessages();
}
public function testNotifyTrackingCalledOnProxyInitialization()
@@ -67,6 +71,7 @@ class DDC2230Test extends OrmFunctionalTestCase
$addressProxy->__load();
$this->assertSame($this->_em->getUnitOfWork(), $addressProxy->listener);
$this->assertNotHasDeprecationMessages();
}
}
@@ -5,12 +5,15 @@ namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\ORM\UnitOfWork;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\CMS\CmsArticle;
use Doctrine\Tests\VerifyDeprecations;
/**
* @group DDC-2409
*/
class DDC2409Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
use VerifyDeprecations;
public function setUp()
{
$this->useModelSet('cms');
@@ -53,8 +56,8 @@ class DDC2409Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(UnitOfWork::STATE_MANAGED, $uow->getEntityState($article));
$this->assertEquals(UnitOfWork::STATE_NEW, $uow->getEntityState($user));
$em->detach($user);
$em->detach($article);
$em->clear(CmsUser::class);
$em->clear(CmsArticle::class);
$userMerged = $em->merge($user);
$articleMerged = $em->merge($article);
@@ -68,5 +71,6 @@ class DDC2409Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertNotSame($article, $articleMerged);
$this->assertNotSame($userMerged, $articleMerged->user);
$this->assertSame($user, $articleMerged->user);
$this->assertHasDeprecationMessages();
}
}
@@ -2,11 +2,15 @@
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\VerifyDeprecations;
/**
* @group DDC-2645
*/
class DDC2645Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
use VerifyDeprecations;
public function testIssue()
{
$bar = new DDC2645Bar;
@@ -22,6 +26,7 @@ class DDC2645Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertSame($foo, $foo3);
$this->assertEquals('Bar', $foo->name);
$this->assertHasDeprecationMessages();
}
}
@@ -45,7 +45,7 @@ class DDC2790Test extends \Doctrine\Tests\OrmFunctionalTestCase
// (and consequently also triggers preUpdate/postUpdate for the entity in question)
$entity->name = 'Robin';
$this->_em->flush($entity);
$this->_em->flush();
$qb = $this->_em->createQueryBuilder();
$qb->from(get_class($entity), 'c');
@@ -40,7 +40,7 @@ class DDC2984Test extends \Doctrine\Tests\OrmFunctionalTestCase
$user->applyName('Alex');
$this->_em->persist($user);
$this->_em->flush($user);
$this->_em->flush();
$repository = $this->_em->getRepository(__NAMESPACE__ . "\DDC2984User");
@@ -3,12 +3,15 @@
use Doctrine\Tests\Models\DDC3699\DDC3699RelationOne;
use Doctrine\Tests\Models\DDC3699\DDC3699RelationMany;
use Doctrine\Tests\Models\DDC3699\DDC3699Child;
use Doctrine\Tests\VerifyDeprecations;
/**
* @group DDC-3699
*/
class DDC3597Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
use VerifyDeprecations;
protected function setUp()
{
$this->useModelSet('ddc3699');
@@ -16,6 +19,12 @@ class DDC3597Test extends \Doctrine\Tests\OrmFunctionalTestCase
parent::setUp();
}
/** @after */
public function ensureTestGeneratedDeprecationMessages() : void
{
$this->assertHasDeprecationMessages();
}
/**
* @group DDC-3699
*/

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