Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/3rdparty.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Wurst <ChristophWurst@users.noreply.github.com>2021-10-21 19:17:21 +0300
committerGitHub <noreply@github.com>2021-10-21 19:17:21 +0300
commit217764f87ec6bbd359c76e57f0f48897d7c47646 (patch)
tree5b2c8c22b4a63c0a0295315bdd12dc642f759156
parent95a491127bf36e55b22ce4508e9c9d7c628fac37 (diff)
parent51285f0a85f53a534201ea9a189669c2822ce9b8 (diff)
Merge pull request #837 from nextcloud/dependabot/composer/doctrine/dbal-3.1.3v23.0.0rc2v23.0.0rc1v23.0.0beta3v23.0.0beta2
Bump doctrine/dbal from 3.0.0 to 3.1.3
-rw-r--r--.gitignore1
-rw-r--r--composer.json2
-rw-r--r--composer.lock122
-rw-r--r--composer/autoload_classmap.php31
-rw-r--r--composer/autoload_psr4.php1
-rw-r--r--composer/autoload_static.php36
-rw-r--r--composer/installed.json129
-rw-r--r--composer/installed.php31
-rw-r--r--composer/package-versions-deprecated/README.md2
-rw-r--r--composer/package-versions-deprecated/phpcs.xml.dist21
-rw-r--r--composer/package-versions-deprecated/src/PackageVersions/Installer.php25
-rw-r--r--composer/package-versions-deprecated/src/PackageVersions/Versions.php34
-rw-r--r--doctrine/cache/UPGRADE-1.11.md15
-rw-r--r--doctrine/cache/UPGRADE-1.4.md (renamed from doctrine/cache/UPGRADE.md)0
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php105
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php106
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php113
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/Cache.php2
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php20
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php195
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php197
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php105
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php198
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php281
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php102
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php25
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php175
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php104
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php170
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php112
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php6
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php118
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php143
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php340
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php118
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php125
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php13
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php99
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php181
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php206
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/Version.php8
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php59
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php106
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php104
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php69
-rw-r--r--doctrine/dbal/README.md52
-rw-r--r--doctrine/dbal/composer.json29
-rw-r--r--doctrine/dbal/src/Cache/ArrayResult.php4
-rw-r--r--doctrine/dbal/src/Cache/QueryCacheProfile.php2
-rw-r--r--doctrine/dbal/src/Connection.php152
-rw-r--r--doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php15
-rw-r--r--doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php4
-rw-r--r--doctrine/dbal/src/Driver/IBMDB2/Statement.php2
-rw-r--r--doctrine/dbal/src/Driver/Mysqli/Connection.php2
-rw-r--r--doctrine/dbal/src/Driver/Mysqli/Result.php5
-rw-r--r--doctrine/dbal/src/Driver/Mysqli/Statement.php2
-rw-r--r--doctrine/dbal/src/Driver/OCI8/Connection.php2
-rw-r--r--doctrine/dbal/src/Driver/OCI8/Result.php16
-rw-r--r--doctrine/dbal/src/Driver/OCI8/Statement.php2
-rw-r--r--doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php17
-rw-r--r--doctrine/dbal/src/Driver/PDO/Statement.php12
-rw-r--r--doctrine/dbal/src/Driver/SQLSrv/Connection.php8
-rw-r--r--doctrine/dbal/src/Driver/SQLSrv/LastInsertId.php32
-rw-r--r--doctrine/dbal/src/Driver/SQLSrv/Result.php8
-rw-r--r--doctrine/dbal/src/Driver/SQLSrv/Statement.php21
-rw-r--r--doctrine/dbal/src/DriverManager.php134
-rw-r--r--doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php10
-rw-r--r--doctrine/dbal/src/Logging/LoggerChain.php2
-rw-r--r--doctrine/dbal/src/Platforms/AbstractPlatform.php69
-rw-r--r--doctrine/dbal/src/Platforms/DB2Platform.php19
-rw-r--r--doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php2
-rw-r--r--doctrine/dbal/src/Platforms/MariaDb1027Platform.php11
-rw-r--r--doctrine/dbal/src/Platforms/MySQL57Platform.php10
-rw-r--r--doctrine/dbal/src/Platforms/MySQL80Platform.php11
-rw-r--r--doctrine/dbal/src/Platforms/MySQLPlatform.php12
-rw-r--r--doctrine/dbal/src/Platforms/OraclePlatform.php22
-rw-r--r--doctrine/dbal/src/Platforms/PostgreSQL100Platform.php11
-rw-r--r--doctrine/dbal/src/Platforms/PostgreSQL94Platform.php43
-rw-r--r--doctrine/dbal/src/Platforms/SQLServer2012Platform.php111
-rw-r--r--doctrine/dbal/src/Platforms/SqlitePlatform.php56
-rw-r--r--doctrine/dbal/src/Portability/Converter.php115
-rw-r--r--doctrine/dbal/src/Query/Expression/CompositeExpression.php21
-rw-r--r--doctrine/dbal/src/Query/Expression/ExpressionBuilder.php31
-rw-r--r--doctrine/dbal/src/Query/QueryBuilder.php185
-rw-r--r--doctrine/dbal/src/Schema/AbstractAsset.php4
-rw-r--r--doctrine/dbal/src/Schema/AbstractSchemaManager.php70
-rw-r--r--doctrine/dbal/src/Schema/DB2SchemaManager.php11
-rw-r--r--doctrine/dbal/src/Schema/Index.php2
-rw-r--r--doctrine/dbal/src/Schema/MySQLSchemaManager.php5
-rw-r--r--doctrine/dbal/src/Schema/OracleSchemaManager.php26
-rw-r--r--doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php49
-rw-r--r--doctrine/dbal/src/Schema/SQLServerSchemaManager.php33
-rw-r--r--doctrine/dbal/src/Schema/SchemaConfig.php4
-rw-r--r--doctrine/dbal/src/Schema/Sequence.php4
-rw-r--r--doctrine/dbal/src/Schema/SqliteSchemaManager.php53
-rw-r--r--doctrine/dbal/src/Schema/Table.php12
-rw-r--r--doctrine/dbal/src/Schema/UniqueConstraint.php2
-rw-r--r--doctrine/dbal/src/Schema/Visitor/DropSchemaSqlCollector.php13
-rw-r--r--doctrine/dbal/src/Schema/Visitor/RemoveNamespacedAssets.php14
-rw-r--r--doctrine/dbal/src/Statement.php48
-rw-r--r--doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php65
-rw-r--r--doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php2
-rw-r--r--doctrine/dbal/src/Tools/Console/ConsoleRunner.php4
-rw-r--r--doctrine/dbal/src/Tools/Dumper.php3
-rw-r--r--doctrine/dbal/src/Types/DecimalType.php10
-rw-r--r--doctrine/dbal/src/Types/Type.php3
-rw-r--r--doctrine/dbal/src/Types/TypeRegistry.php2
-rw-r--r--doctrine/dbal/static-analysis/driver-manager-retrieves-correct-connection-type.php19
-rw-r--r--doctrine/deprecations/.gitignore3
-rw-r--r--doctrine/deprecations/README.md147
-rw-r--r--doctrine/deprecations/composer.json27
-rw-r--r--doctrine/deprecations/lib/Doctrine/Deprecations/Deprecation.php266
-rw-r--r--doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php66
-rw-r--r--doctrine/deprecations/phpcs.xml20
-rw-r--r--doctrine/deprecations/phpunit.xml.dist8
-rw-r--r--doctrine/deprecations/test_fixtures/src/Foo.php22
-rw-r--r--doctrine/deprecations/test_fixtures/src/RootDeprecation.php20
117 files changed, 2853 insertions, 3601 deletions
diff --git a/.gitignore b/.gitignore
index 8b4c2e30..825d88c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,6 +41,7 @@ doctrine/collections/composer.json
doctrine/common/tests
doctrine/common/.travis.yml
doctrine/common/composer.json
+doctrine/deprecations/tests
doctrine/dbal/tests
doctrine/dbal/docs
doctrine/dbal/psalm.xml
diff --git a/composer.json b/composer.json
index 32e85c07..f553b88f 100644
--- a/composer.json
+++ b/composer.json
@@ -20,7 +20,7 @@
"cweagans/composer-patches": "^1.7",
"deepdiver/zipstreamer": "2.0.0",
"deepdiver1975/tarstreamer": "v2.0.0",
- "doctrine/dbal": "3.0.0",
+ "doctrine/dbal": "3.1.3",
"egulias/email-validator": "3.1.1",
"giggsey/libphonenumber-for-php": "^8.12",
"guzzlehttp/guzzle": "^7.2",
diff --git a/composer.lock b/composer.lock
index 43942b5a..61867a16 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "4d00ce69041cf4588a8790825888e5db",
+ "content-hash": "7a2c615cf730c6a5dc98776c2ee9b53a",
"packages": [
{
"name": "aws/aws-sdk-php",
@@ -291,16 +291,16 @@
},
{
"name": "composer/package-versions-deprecated",
- "version": "1.11.99.1",
+ "version": "1.11.99.4",
"source": {
"type": "git",
"url": "https://github.com/composer/package-versions-deprecated.git",
- "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6"
+ "reference": "b174585d1fe49ceed21928a945138948cb394600"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/7413f0b55a051e89485c5cb9f765fe24bb02a7b6",
- "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6",
+ "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600",
+ "reference": "b174585d1fe49ceed21928a945138948cb394600",
"shasum": ""
},
"require": {
@@ -344,7 +344,7 @@
"description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
"support": {
"issues": "https://github.com/composer/package-versions-deprecated/issues",
- "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.1"
+ "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.4"
},
"funding": [
{
@@ -360,7 +360,7 @@
"type": "tidelift"
}
],
- "time": "2020-11-11T10:22:58+00:00"
+ "time": "2021-09-13T08:41:34+00:00"
},
{
"name": "cweagans/composer-patches",
@@ -523,16 +523,16 @@
},
{
"name": "doctrine/cache",
- "version": "1.10.2",
+ "version": "2.1.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
- "reference": "13e3381b25847283a91948d04640543941309727"
+ "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/cache/zipball/13e3381b25847283a91948d04640543941309727",
- "reference": "13e3381b25847283a91948d04640543941309727",
+ "url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce",
+ "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce",
"shasum": ""
},
"require": {
@@ -543,20 +543,19 @@
},
"require-dev": {
"alcaeus/mongo-php-adapter": "^1.1",
- "doctrine/coding-standard": "^6.0",
+ "cache/integration-tests": "dev-master",
+ "doctrine/coding-standard": "^8.0",
"mongodb/mongodb": "^1.1",
- "phpunit/phpunit": "^7.0",
- "predis/predis": "~1.0"
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
+ "predis/predis": "~1.0",
+ "psr/cache": "^1.0 || ^2.0 || ^3.0",
+ "symfony/cache": "^4.4 || ^5.2 || ^6.0@dev",
+ "symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev"
},
"suggest": {
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.9.x-dev"
- }
- },
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
@@ -603,7 +602,7 @@
],
"support": {
"issues": "https://github.com/doctrine/cache/issues",
- "source": "https://github.com/doctrine/cache/tree/1.10.x"
+ "source": "https://github.com/doctrine/cache/tree/2.1.1"
},
"funding": [
{
@@ -619,37 +618,40 @@
"type": "tidelift"
}
],
- "time": "2020-07-07T18:54:01+00:00"
+ "time": "2021-07-17T14:49:29+00:00"
},
{
"name": "doctrine/dbal",
- "version": "3.0.0",
+ "version": "3.1.3",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
- "reference": "ee6d1260d5cc20ec506455a585945d7bdb98662c"
+ "reference": "96b0053775a544b4a6ab47654dac0621be8b4cf8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/dbal/zipball/ee6d1260d5cc20ec506455a585945d7bdb98662c",
- "reference": "ee6d1260d5cc20ec506455a585945d7bdb98662c",
+ "url": "https://api.github.com/repos/doctrine/dbal/zipball/96b0053775a544b4a6ab47654dac0621be8b4cf8",
+ "reference": "96b0053775a544b4a6ab47654dac0621be8b4cf8",
"shasum": ""
},
"require": {
"composer/package-versions-deprecated": "^1.11.99",
- "doctrine/cache": "^1.0",
+ "doctrine/cache": "^1.0|^2.0",
+ "doctrine/deprecations": "^0.5.3",
"doctrine/event-manager": "^1.0",
"php": "^7.3 || ^8.0"
},
"require-dev": {
- "doctrine/coding-standard": "^8.1",
- "jetbrains/phpstorm-stubs": "^2019.1",
- "phpstan/phpstan": "^0.12.40",
- "phpstan/phpstan-strict-rules": "^0.12.2",
- "phpunit/phpunit": "^9.4",
- "psalm/plugin-phpunit": "^0.10.0",
- "symfony/console": "^2.0.5|^3.0|^4.0|^5.0",
- "vimeo/psalm": "^3.17.2"
+ "doctrine/coding-standard": "9.0.0",
+ "jetbrains/phpstorm-stubs": "2021.1",
+ "phpstan/phpstan": "0.12.99",
+ "phpstan/phpstan-strict-rules": "^0.12.11",
+ "phpunit/phpunit": "9.5.10",
+ "psalm/plugin-phpunit": "0.16.1",
+ "squizlabs/php_codesniffer": "3.6.0",
+ "symfony/cache": "^5.2|^6.0",
+ "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.0",
+ "vimeo/psalm": "4.10.0"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
@@ -658,11 +660,6 @@
"bin/doctrine-dbal"
],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.0.x-dev"
- }
- },
"autoload": {
"psr-4": {
"Doctrine\\DBAL\\": "src"
@@ -714,7 +711,7 @@
],
"support": {
"issues": "https://github.com/doctrine/dbal/issues",
- "source": "https://github.com/doctrine/dbal/tree/3.0.0"
+ "source": "https://github.com/doctrine/dbal/tree/3.1.3"
},
"funding": [
{
@@ -730,7 +727,50 @@
"type": "tidelift"
}
],
- "time": "2020-11-15T18:20:41+00:00"
+ "time": "2021-10-02T16:15:05+00:00"
+ },
+ {
+ "name": "doctrine/deprecations",
+ "version": "v0.5.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/deprecations.git",
+ "reference": "9504165960a1f83cc1480e2be1dd0a0478561314"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/9504165960a1f83cc1480e2be1dd0a0478561314",
+ "reference": "9504165960a1f83cc1480e2be1dd0a0478561314",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1|^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^6.0|^7.0|^8.0",
+ "phpunit/phpunit": "^7.0|^8.0|^9.0",
+ "psr/log": "^1.0"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+ "homepage": "https://www.doctrine-project.org/",
+ "support": {
+ "issues": "https://github.com/doctrine/deprecations/issues",
+ "source": "https://github.com/doctrine/deprecations/tree/v0.5.3"
+ },
+ "time": "2021-03-21T12:59:47+00:00"
},
{
"name": "doctrine/event-manager",
diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php
index 9336a93b..8c32a709 100644
--- a/composer/autoload_classmap.php
+++ b/composer/autoload_classmap.php
@@ -902,37 +902,19 @@ return array(
'Cose\\Key\\RsaKey' => $vendorDir . '/web-auth/cose-lib/src/Key/RsaKey.php',
'Cose\\Key\\SymmetricKey' => $vendorDir . '/web-auth/cose-lib/src/Key/SymmetricKey.php',
'Cose\\Verifier' => $vendorDir . '/web-auth/cose-lib/src/Verifier.php',
- 'Doctrine\\Common\\Cache\\ApcCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php',
- 'Doctrine\\Common\\Cache\\ApcuCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php',
- 'Doctrine\\Common\\Cache\\ArrayCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php',
'Doctrine\\Common\\Cache\\Cache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php',
'Doctrine\\Common\\Cache\\CacheProvider' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php',
- 'Doctrine\\Common\\Cache\\ChainCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php',
'Doctrine\\Common\\Cache\\ClearableCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php',
- 'Doctrine\\Common\\Cache\\CouchbaseBucketCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php',
- 'Doctrine\\Common\\Cache\\CouchbaseCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php',
- 'Doctrine\\Common\\Cache\\ExtMongoDBCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php',
- 'Doctrine\\Common\\Cache\\FileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php',
- 'Doctrine\\Common\\Cache\\FilesystemCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php',
'Doctrine\\Common\\Cache\\FlushableCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php',
- 'Doctrine\\Common\\Cache\\InvalidCacheId' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php',
- 'Doctrine\\Common\\Cache\\LegacyMongoDBCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php',
- 'Doctrine\\Common\\Cache\\MemcacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php',
- 'Doctrine\\Common\\Cache\\MemcachedCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php',
- 'Doctrine\\Common\\Cache\\MongoDBCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php',
'Doctrine\\Common\\Cache\\MultiDeleteCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php',
'Doctrine\\Common\\Cache\\MultiGetCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php',
'Doctrine\\Common\\Cache\\MultiOperationCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiOperationCache.php',
'Doctrine\\Common\\Cache\\MultiPutCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php',
- 'Doctrine\\Common\\Cache\\PhpFileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php',
- 'Doctrine\\Common\\Cache\\PredisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php',
- 'Doctrine\\Common\\Cache\\RedisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php',
- 'Doctrine\\Common\\Cache\\SQLite3Cache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php',
- 'Doctrine\\Common\\Cache\\Version' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Version.php',
- 'Doctrine\\Common\\Cache\\VoidCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php',
- 'Doctrine\\Common\\Cache\\WinCacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php',
- 'Doctrine\\Common\\Cache\\XcacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php',
- 'Doctrine\\Common\\Cache\\ZendDataCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php',
+ 'Doctrine\\Common\\Cache\\Psr6\\CacheAdapter' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php',
+ 'Doctrine\\Common\\Cache\\Psr6\\CacheItem' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php',
+ 'Doctrine\\Common\\Cache\\Psr6\\DoctrineProvider' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php',
+ 'Doctrine\\Common\\Cache\\Psr6\\InvalidArgument' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php',
+ 'Doctrine\\Common\\Cache\\Psr6\\TypedCacheItem' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php',
'Doctrine\\Common\\EventArgs' => $vendorDir . '/doctrine/event-manager/lib/Doctrine/Common/EventArgs.php',
'Doctrine\\Common\\EventManager' => $vendorDir . '/doctrine/event-manager/lib/Doctrine/Common/EventManager.php',
'Doctrine\\Common\\EventSubscriber' => $vendorDir . '/doctrine/event-manager/lib/Doctrine/Common/EventSubscriber.php',
@@ -1026,7 +1008,6 @@ return array(
'Doctrine\\DBAL\\Driver\\SQLSrv\\Connection' => $vendorDir . '/doctrine/dbal/src/Driver/SQLSrv/Connection.php',
'Doctrine\\DBAL\\Driver\\SQLSrv\\Driver' => $vendorDir . '/doctrine/dbal/src/Driver/SQLSrv/Driver.php',
'Doctrine\\DBAL\\Driver\\SQLSrv\\Exception\\Error' => $vendorDir . '/doctrine/dbal/src/Driver/SQLSrv/Exception/Error.php',
- 'Doctrine\\DBAL\\Driver\\SQLSrv\\LastInsertId' => $vendorDir . '/doctrine/dbal/src/Driver/SQLSrv/LastInsertId.php',
'Doctrine\\DBAL\\Driver\\SQLSrv\\Result' => $vendorDir . '/doctrine/dbal/src/Driver/SQLSrv/Result.php',
'Doctrine\\DBAL\\Driver\\SQLSrv\\Statement' => $vendorDir . '/doctrine/dbal/src/Driver/SQLSrv/Statement.php',
'Doctrine\\DBAL\\Driver\\ServerInfoAwareConnection' => $vendorDir . '/doctrine/dbal/src/Driver/ServerInfoAwareConnection.php',
@@ -1195,6 +1176,8 @@ return array(
'Doctrine\\DBAL\\Types\\VarDateTimeImmutableType' => $vendorDir . '/doctrine/dbal/src/Types/VarDateTimeImmutableType.php',
'Doctrine\\DBAL\\Types\\VarDateTimeType' => $vendorDir . '/doctrine/dbal/src/Types/VarDateTimeType.php',
'Doctrine\\DBAL\\VersionAwarePlatformDriver' => $vendorDir . '/doctrine/dbal/src/VersionAwarePlatformDriver.php',
+ 'Doctrine\\Deprecations\\Deprecation' => $vendorDir . '/doctrine/deprecations/lib/Doctrine/Deprecations/Deprecation.php',
+ 'Doctrine\\Deprecations\\PHPUnit\\VerifyDeprecations' => $vendorDir . '/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php',
'Ds\\Collection' => $vendorDir . '/php-ds/php-ds/src/Collection.php',
'Ds\\Deque' => $vendorDir . '/php-ds/php-ds/src/Deque.php',
'Ds\\Hashable' => $vendorDir . '/php-ds/php-ds/src/Hashable.php',
diff --git a/composer/autoload_psr4.php b/composer/autoload_psr4.php
index 1ed7d0d5..30c5203b 100644
--- a/composer/autoload_psr4.php
+++ b/composer/autoload_psr4.php
@@ -75,6 +75,7 @@ return array(
'FG\\' => array($vendorDir . '/fgrosse/phpasn1/lib'),
'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/src'),
'Ds\\' => array($vendorDir . '/php-ds/php-ds/src'),
+ 'Doctrine\\Deprecations\\' => array($vendorDir . '/doctrine/deprecations/lib/Doctrine/Deprecations'),
'Doctrine\\DBAL\\' => array($vendorDir . '/doctrine/dbal/src'),
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer'),
'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache'),
diff --git a/composer/autoload_static.php b/composer/autoload_static.php
index 112037af..0248df8f 100644
--- a/composer/autoload_static.php
+++ b/composer/autoload_static.php
@@ -257,6 +257,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'D' =>
array (
'Ds\\' => 3,
+ 'Doctrine\\Deprecations\\' => 22,
'Doctrine\\DBAL\\' => 14,
'Doctrine\\Common\\Lexer\\' => 22,
'Doctrine\\Common\\Cache\\' => 22,
@@ -560,6 +561,10 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
array (
0 => __DIR__ . '/..' . '/php-ds/php-ds/src',
),
+ 'Doctrine\\Deprecations\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/doctrine/deprecations/lib/Doctrine/Deprecations',
+ ),
'Doctrine\\DBAL\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/dbal/src',
@@ -1527,37 +1532,19 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Cose\\Key\\RsaKey' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Key/RsaKey.php',
'Cose\\Key\\SymmetricKey' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Key/SymmetricKey.php',
'Cose\\Verifier' => __DIR__ . '/..' . '/web-auth/cose-lib/src/Verifier.php',
- 'Doctrine\\Common\\Cache\\ApcCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php',
- 'Doctrine\\Common\\Cache\\ApcuCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php',
- 'Doctrine\\Common\\Cache\\ArrayCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php',
'Doctrine\\Common\\Cache\\Cache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php',
'Doctrine\\Common\\Cache\\CacheProvider' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php',
- 'Doctrine\\Common\\Cache\\ChainCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php',
'Doctrine\\Common\\Cache\\ClearableCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php',
- 'Doctrine\\Common\\Cache\\CouchbaseBucketCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php',
- 'Doctrine\\Common\\Cache\\CouchbaseCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php',
- 'Doctrine\\Common\\Cache\\ExtMongoDBCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php',
- 'Doctrine\\Common\\Cache\\FileCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php',
- 'Doctrine\\Common\\Cache\\FilesystemCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php',
'Doctrine\\Common\\Cache\\FlushableCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php',
- 'Doctrine\\Common\\Cache\\InvalidCacheId' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php',
- 'Doctrine\\Common\\Cache\\LegacyMongoDBCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php',
- 'Doctrine\\Common\\Cache\\MemcacheCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php',
- 'Doctrine\\Common\\Cache\\MemcachedCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php',
- 'Doctrine\\Common\\Cache\\MongoDBCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php',
'Doctrine\\Common\\Cache\\MultiDeleteCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php',
'Doctrine\\Common\\Cache\\MultiGetCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php',
'Doctrine\\Common\\Cache\\MultiOperationCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiOperationCache.php',
'Doctrine\\Common\\Cache\\MultiPutCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php',
- 'Doctrine\\Common\\Cache\\PhpFileCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php',
- 'Doctrine\\Common\\Cache\\PredisCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php',
- 'Doctrine\\Common\\Cache\\RedisCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php',
- 'Doctrine\\Common\\Cache\\SQLite3Cache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php',
- 'Doctrine\\Common\\Cache\\Version' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Version.php',
- 'Doctrine\\Common\\Cache\\VoidCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php',
- 'Doctrine\\Common\\Cache\\WinCacheCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php',
- 'Doctrine\\Common\\Cache\\XcacheCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php',
- 'Doctrine\\Common\\Cache\\ZendDataCache' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php',
+ 'Doctrine\\Common\\Cache\\Psr6\\CacheAdapter' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php',
+ 'Doctrine\\Common\\Cache\\Psr6\\CacheItem' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php',
+ 'Doctrine\\Common\\Cache\\Psr6\\DoctrineProvider' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php',
+ 'Doctrine\\Common\\Cache\\Psr6\\InvalidArgument' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php',
+ 'Doctrine\\Common\\Cache\\Psr6\\TypedCacheItem' => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php',
'Doctrine\\Common\\EventArgs' => __DIR__ . '/..' . '/doctrine/event-manager/lib/Doctrine/Common/EventArgs.php',
'Doctrine\\Common\\EventManager' => __DIR__ . '/..' . '/doctrine/event-manager/lib/Doctrine/Common/EventManager.php',
'Doctrine\\Common\\EventSubscriber' => __DIR__ . '/..' . '/doctrine/event-manager/lib/Doctrine/Common/EventSubscriber.php',
@@ -1651,7 +1638,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Doctrine\\DBAL\\Driver\\SQLSrv\\Connection' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/SQLSrv/Connection.php',
'Doctrine\\DBAL\\Driver\\SQLSrv\\Driver' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/SQLSrv/Driver.php',
'Doctrine\\DBAL\\Driver\\SQLSrv\\Exception\\Error' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/SQLSrv/Exception/Error.php',
- 'Doctrine\\DBAL\\Driver\\SQLSrv\\LastInsertId' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/SQLSrv/LastInsertId.php',
'Doctrine\\DBAL\\Driver\\SQLSrv\\Result' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/SQLSrv/Result.php',
'Doctrine\\DBAL\\Driver\\SQLSrv\\Statement' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/SQLSrv/Statement.php',
'Doctrine\\DBAL\\Driver\\ServerInfoAwareConnection' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/ServerInfoAwareConnection.php',
@@ -1820,6 +1806,8 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Doctrine\\DBAL\\Types\\VarDateTimeImmutableType' => __DIR__ . '/..' . '/doctrine/dbal/src/Types/VarDateTimeImmutableType.php',
'Doctrine\\DBAL\\Types\\VarDateTimeType' => __DIR__ . '/..' . '/doctrine/dbal/src/Types/VarDateTimeType.php',
'Doctrine\\DBAL\\VersionAwarePlatformDriver' => __DIR__ . '/..' . '/doctrine/dbal/src/VersionAwarePlatformDriver.php',
+ 'Doctrine\\Deprecations\\Deprecation' => __DIR__ . '/..' . '/doctrine/deprecations/lib/Doctrine/Deprecations/Deprecation.php',
+ 'Doctrine\\Deprecations\\PHPUnit\\VerifyDeprecations' => __DIR__ . '/..' . '/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php',
'Ds\\Collection' => __DIR__ . '/..' . '/php-ds/php-ds/src/Collection.php',
'Ds\\Deque' => __DIR__ . '/..' . '/php-ds/php-ds/src/Deque.php',
'Ds\\Hashable' => __DIR__ . '/..' . '/php-ds/php-ds/src/Hashable.php',
diff --git a/composer/installed.json b/composer/installed.json
index 2c9049ef..803f729f 100644
--- a/composer/installed.json
+++ b/composer/installed.json
@@ -300,17 +300,17 @@
},
{
"name": "composer/package-versions-deprecated",
- "version": "1.11.99.1",
- "version_normalized": "1.11.99.1",
+ "version": "1.11.99.4",
+ "version_normalized": "1.11.99.4",
"source": {
"type": "git",
"url": "https://github.com/composer/package-versions-deprecated.git",
- "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6"
+ "reference": "b174585d1fe49ceed21928a945138948cb394600"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/7413f0b55a051e89485c5cb9f765fe24bb02a7b6",
- "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6",
+ "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600",
+ "reference": "b174585d1fe49ceed21928a945138948cb394600",
"shasum": ""
},
"require": {
@@ -325,7 +325,7 @@
"ext-zip": "^1.13",
"phpunit/phpunit": "^6.5 || ^7"
},
- "time": "2020-11-11T10:22:58+00:00",
+ "time": "2021-09-13T08:41:34+00:00",
"type": "composer-plugin",
"extra": {
"class": "PackageVersions\\Installer",
@@ -356,7 +356,7 @@
"description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
"support": {
"issues": "https://github.com/composer/package-versions-deprecated/issues",
- "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.1"
+ "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.4"
},
"funding": [
{
@@ -544,17 +544,17 @@
},
{
"name": "doctrine/cache",
- "version": "1.10.2",
- "version_normalized": "1.10.2.0",
+ "version": "2.1.1",
+ "version_normalized": "2.1.1.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
- "reference": "13e3381b25847283a91948d04640543941309727"
+ "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/cache/zipball/13e3381b25847283a91948d04640543941309727",
- "reference": "13e3381b25847283a91948d04640543941309727",
+ "url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce",
+ "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce",
"shasum": ""
},
"require": {
@@ -565,21 +565,20 @@
},
"require-dev": {
"alcaeus/mongo-php-adapter": "^1.1",
- "doctrine/coding-standard": "^6.0",
+ "cache/integration-tests": "dev-master",
+ "doctrine/coding-standard": "^8.0",
"mongodb/mongodb": "^1.1",
- "phpunit/phpunit": "^7.0",
- "predis/predis": "~1.0"
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
+ "predis/predis": "~1.0",
+ "psr/cache": "^1.0 || ^2.0 || ^3.0",
+ "symfony/cache": "^4.4 || ^5.2 || ^6.0@dev",
+ "symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev"
},
"suggest": {
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
},
- "time": "2020-07-07T18:54:01+00:00",
+ "time": "2021-07-17T14:49:29+00:00",
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.9.x-dev"
- }
- },
"installation-source": "dist",
"autoload": {
"psr-4": {
@@ -627,7 +626,7 @@
],
"support": {
"issues": "https://github.com/doctrine/cache/issues",
- "source": "https://github.com/doctrine/cache/tree/1.10.x"
+ "source": "https://github.com/doctrine/cache/tree/2.1.1"
},
"funding": [
{
@@ -647,48 +646,46 @@
},
{
"name": "doctrine/dbal",
- "version": "3.0.0",
- "version_normalized": "3.0.0.0",
+ "version": "3.1.3",
+ "version_normalized": "3.1.3.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
- "reference": "ee6d1260d5cc20ec506455a585945d7bdb98662c"
+ "reference": "96b0053775a544b4a6ab47654dac0621be8b4cf8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/dbal/zipball/ee6d1260d5cc20ec506455a585945d7bdb98662c",
- "reference": "ee6d1260d5cc20ec506455a585945d7bdb98662c",
+ "url": "https://api.github.com/repos/doctrine/dbal/zipball/96b0053775a544b4a6ab47654dac0621be8b4cf8",
+ "reference": "96b0053775a544b4a6ab47654dac0621be8b4cf8",
"shasum": ""
},
"require": {
"composer/package-versions-deprecated": "^1.11.99",
- "doctrine/cache": "^1.0",
+ "doctrine/cache": "^1.0|^2.0",
+ "doctrine/deprecations": "^0.5.3",
"doctrine/event-manager": "^1.0",
"php": "^7.3 || ^8.0"
},
"require-dev": {
- "doctrine/coding-standard": "^8.1",
- "jetbrains/phpstorm-stubs": "^2019.1",
- "phpstan/phpstan": "^0.12.40",
- "phpstan/phpstan-strict-rules": "^0.12.2",
- "phpunit/phpunit": "^9.4",
- "psalm/plugin-phpunit": "^0.10.0",
- "symfony/console": "^2.0.5|^3.0|^4.0|^5.0",
- "vimeo/psalm": "^3.17.2"
+ "doctrine/coding-standard": "9.0.0",
+ "jetbrains/phpstorm-stubs": "2021.1",
+ "phpstan/phpstan": "0.12.99",
+ "phpstan/phpstan-strict-rules": "^0.12.11",
+ "phpunit/phpunit": "9.5.10",
+ "psalm/plugin-phpunit": "0.16.1",
+ "squizlabs/php_codesniffer": "3.6.0",
+ "symfony/cache": "^5.2|^6.0",
+ "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.0",
+ "vimeo/psalm": "4.10.0"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
},
- "time": "2020-11-15T18:20:41+00:00",
+ "time": "2021-10-02T16:15:05+00:00",
"bin": [
"bin/doctrine-dbal"
],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.0.x-dev"
- }
- },
"installation-source": "dist",
"autoload": {
"psr-4": {
@@ -741,7 +738,7 @@
],
"support": {
"issues": "https://github.com/doctrine/dbal/issues",
- "source": "https://github.com/doctrine/dbal/tree/3.0.0"
+ "source": "https://github.com/doctrine/dbal/tree/3.1.3"
},
"funding": [
{
@@ -760,6 +757,52 @@
"install-path": "../doctrine/dbal"
},
{
+ "name": "doctrine/deprecations",
+ "version": "v0.5.3",
+ "version_normalized": "0.5.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/deprecations.git",
+ "reference": "9504165960a1f83cc1480e2be1dd0a0478561314"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/9504165960a1f83cc1480e2be1dd0a0478561314",
+ "reference": "9504165960a1f83cc1480e2be1dd0a0478561314",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1|^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^6.0|^7.0|^8.0",
+ "phpunit/phpunit": "^7.0|^8.0|^9.0",
+ "psr/log": "^1.0"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ },
+ "time": "2021-03-21T12:59:47+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+ "homepage": "https://www.doctrine-project.org/",
+ "support": {
+ "issues": "https://github.com/doctrine/deprecations/issues",
+ "source": "https://github.com/doctrine/deprecations/tree/v0.5.3"
+ },
+ "install-path": "../doctrine/deprecations"
+ },
+ {
"name": "doctrine/event-manager",
"version": "1.1.1",
"version_normalized": "1.1.1.0",
diff --git a/composer/installed.php b/composer/installed.php
index ade31e6d..686943ff 100644
--- a/composer/installed.php
+++ b/composer/installed.php
@@ -5,7 +5,7 @@
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
- 'reference' => 'f43adb17395165d337ee76ca5c1b9cc2e85f666c',
+ 'reference' => '1d7fff4111e438dd496fb8a5d518ea6b8b910b83',
'name' => 'nextcloud/3rdparty',
'dev' => false,
),
@@ -56,12 +56,12 @@
'dev_requirement' => false,
),
'composer/package-versions-deprecated' => array(
- 'pretty_version' => '1.11.99.1',
- 'version' => '1.11.99.1',
+ 'pretty_version' => '1.11.99.4',
+ 'version' => '1.11.99.4',
'type' => 'composer-plugin',
'install_path' => __DIR__ . '/./package-versions-deprecated',
'aliases' => array(),
- 'reference' => '7413f0b55a051e89485c5cb9f765fe24bb02a7b6',
+ 'reference' => 'b174585d1fe49ceed21928a945138948cb394600',
'dev_requirement' => false,
),
'cweagans/composer-patches' => array(
@@ -92,21 +92,30 @@
'dev_requirement' => false,
),
'doctrine/cache' => array(
- 'pretty_version' => '1.10.2',
- 'version' => '1.10.2.0',
+ 'pretty_version' => '2.1.1',
+ 'version' => '2.1.1.0',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/cache',
'aliases' => array(),
- 'reference' => '13e3381b25847283a91948d04640543941309727',
+ 'reference' => '331b4d5dbaeab3827976273e9356b3b453c300ce',
'dev_requirement' => false,
),
'doctrine/dbal' => array(
- 'pretty_version' => '3.0.0',
- 'version' => '3.0.0.0',
+ 'pretty_version' => '3.1.3',
+ 'version' => '3.1.3.0',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/dbal',
'aliases' => array(),
- 'reference' => 'ee6d1260d5cc20ec506455a585945d7bdb98662c',
+ 'reference' => '96b0053775a544b4a6ab47654dac0621be8b4cf8',
+ 'dev_requirement' => false,
+ ),
+ 'doctrine/deprecations' => array(
+ 'pretty_version' => 'v0.5.3',
+ 'version' => '0.5.3.0',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../doctrine/deprecations',
+ 'aliases' => array(),
+ 'reference' => '9504165960a1f83cc1480e2be1dd0a0478561314',
'dev_requirement' => false,
),
'doctrine/event-manager' => array(
@@ -277,7 +286,7 @@
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
- 'reference' => 'f43adb17395165d337ee76ca5c1b9cc2e85f666c',
+ 'reference' => '1d7fff4111e438dd496fb8a5d518ea6b8b910b83',
'dev_requirement' => false,
),
'nextcloud/lognormalizer' => array(
diff --git a/composer/package-versions-deprecated/README.md b/composer/package-versions-deprecated/README.md
index c5f5bba1..7fe2097d 100644
--- a/composer/package-versions-deprecated/README.md
+++ b/composer/package-versions-deprecated/README.md
@@ -2,4 +2,4 @@
**`composer/package-versions-deprecated` is a fully-compatible fork of [`ocramius/package-versions`](https://github.com/Ocramius/PackageVersions)** which provides compatibility with Composer 1 and 2 on PHP 7+. It replaces ocramius/package-versions so if you have a dependency requiring it and you want to use Composer v2 but can not upgrade to PHP 7.4 just yet, you can require this package instead.
-If you have a direct dependency on ocramius/package-versions, we recommend instead that once you migrated to Composer 2 you also migrate to use the `Composer\Versions` class which offers the functionality present here out of the box.
+If you have a direct dependency on ocramius/package-versions, we recommend instead that once you migrated to Composer 2 you also migrate to use the `Composer\InstalledVersions` class which offers the functionality present here out of the box.
diff --git a/composer/package-versions-deprecated/phpcs.xml.dist b/composer/package-versions-deprecated/phpcs.xml.dist
deleted file mode 100644
index e169c616..00000000
--- a/composer/package-versions-deprecated/phpcs.xml.dist
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0"?>
-<ruleset>
- <arg name="basepath" value="."/>
- <arg name="extensions" value="php"/>
- <arg name="parallel" value="80"/>
- <arg name="cache" value=".phpcs-cache"/>
- <arg name="colors"/>
-
- <arg value="nps"/>
-
- <file>src</file>
- <file>test</file>
-
- <rule ref="Doctrine">
- <exclude-pattern>src/PackageVersions/Versions.php</exclude-pattern>
- </rule>
-
- <rule ref="Generic.Strings.UnnecessaryStringConcat.Found">
- <exclude-pattern>src/PackageVersions/Installer.php</exclude-pattern>
- </rule>
-</ruleset>
diff --git a/composer/package-versions-deprecated/src/PackageVersions/Installer.php b/composer/package-versions-deprecated/src/PackageVersions/Installer.php
index c0853c16..05bdac9a 100644
--- a/composer/package-versions-deprecated/src/PackageVersions/Installer.php
+++ b/composer/package-versions-deprecated/src/PackageVersions/Installer.php
@@ -82,7 +82,7 @@ class_exists(InstalledVersions::class);
*/
public static function rootPackageName() : string
{
- if (!class_exists(InstalledVersions::class, false) || !InstalledVersions::getRawData()) {
+ if (!self::composer2ApiUsable()) {
return self::ROOT_PACKAGE_NAME;
}
@@ -100,7 +100,7 @@ class_exists(InstalledVersions::class);
*/
public static function getVersion(string $packageName): string
{
- if (class_exists(InstalledVersions::class, false) && InstalledVersions::getRawData()) {
+ if (self::composer2ApiUsable()) {
return InstalledVersions::getPrettyVersion($packageName)
. '@' . InstalledVersions::getReference($packageName);
}
@@ -113,6 +113,27 @@ class_exists(InstalledVersions::class);
'Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files'
);
}
+
+ private static function composer2ApiUsable(): bool
+ {
+ if (!class_exists(InstalledVersions::class, false)) {
+ return false;
+ }
+
+ if (method_exists(InstalledVersions::class, 'getAllRawData')) {
+ $rawData = InstalledVersions::getAllRawData();
+ if (count($rawData) === 1 && count($rawData[0]) === 0) {
+ return false;
+ }
+ } else {
+ $rawData = InstalledVersions::getRawData();
+ if ($rawData === null || $rawData === []) {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
PHP;
diff --git a/composer/package-versions-deprecated/src/PackageVersions/Versions.php b/composer/package-versions-deprecated/src/PackageVersions/Versions.php
index 6ddb041e..9d9dd6a5 100644
--- a/composer/package-versions-deprecated/src/PackageVersions/Versions.php
+++ b/composer/package-versions-deprecated/src/PackageVersions/Versions.php
@@ -38,12 +38,13 @@ final class Versions
'beberlei/assert' => 'v3.3.1@5e721d7e937ca3ba2cdec1e1adf195f9e5188372',
'brick/math' => '0.9.2@dff976c2f3487d42c1db75a3b180e2b9f0e72ce0',
'christophwurst/id3parser' => 'v0.1.2@d7f5e9e7db69a24e3111a2033cbdf640f9456f2f',
- 'composer/package-versions-deprecated' => '1.11.99.1@7413f0b55a051e89485c5cb9f765fe24bb02a7b6',
+ 'composer/package-versions-deprecated' => '1.11.99.4@b174585d1fe49ceed21928a945138948cb394600',
'cweagans/composer-patches' => '1.7.1@9888dcc74993c030b75f3dd548bb5e20cdbd740c',
'deepdiver/zipstreamer' => '2.0.0@b8c59647ff34fb97e8937aefb2a65de2bc4b4755',
'deepdiver1975/tarstreamer' => '2.0.0@ad48505d1ab54a8e94e6b1cc5297bbed72e956de',
- 'doctrine/cache' => '1.10.2@13e3381b25847283a91948d04640543941309727',
- 'doctrine/dbal' => '3.0.0@ee6d1260d5cc20ec506455a585945d7bdb98662c',
+ 'doctrine/cache' => '2.1.1@331b4d5dbaeab3827976273e9356b3b453c300ce',
+ 'doctrine/dbal' => '3.1.3@96b0053775a544b4a6ab47654dac0621be8b4cf8',
+ 'doctrine/deprecations' => 'v0.5.3@9504165960a1f83cc1480e2be1dd0a0478561314',
'doctrine/event-manager' => '1.1.1@41370af6a30faa9dc0368c4a6814d596e81aba7f',
'doctrine/lexer' => '1.2.1@e864bbf5904cb8f5bb334f99209b48018522f042',
'egulias/email-validator' => '3.1.1@c81f18a3efb941d8c4d2e025f6183b5c6d697307',
@@ -118,7 +119,7 @@ final class Versions
'web-auth/cose-lib' => 'v3.3.9@ed172d2dc1a6b87b5c644c07c118cd30c1b3819b',
'web-auth/metadata-service' => 'v3.3.9@8488d3a832a38cc81c670fce05de1e515c6e64b1',
'web-auth/webauthn-lib' => 'v3.3.9@04b98ee3d39cb79dad68a7c15c297c085bf66bfe',
- 'nextcloud/3rdparty' => 'dev-master@f43adb17395165d337ee76ca5c1b9cc2e85f666c',
+ 'nextcloud/3rdparty' => 'dev-master@1d7fff4111e438dd496fb8a5d518ea6b8b910b83',
);
private function __construct()
@@ -133,7 +134,7 @@ final class Versions
*/
public static function rootPackageName() : string
{
- if (!class_exists(InstalledVersions::class, false) || !InstalledVersions::getRawData()) {
+ if (!self::composer2ApiUsable()) {
return self::ROOT_PACKAGE_NAME;
}
@@ -151,7 +152,7 @@ final class Versions
*/
public static function getVersion(string $packageName): string
{
- if (class_exists(InstalledVersions::class, false) && InstalledVersions::getRawData()) {
+ if (self::composer2ApiUsable()) {
return InstalledVersions::getPrettyVersion($packageName)
. '@' . InstalledVersions::getReference($packageName);
}
@@ -164,4 +165,25 @@ final class Versions
'Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files'
);
}
+
+ private static function composer2ApiUsable(): bool
+ {
+ if (!class_exists(InstalledVersions::class, false)) {
+ return false;
+ }
+
+ if (method_exists(InstalledVersions::class, 'getAllRawData')) {
+ $rawData = InstalledVersions::getAllRawData();
+ if (count($rawData) === 1 && count($rawData[0]) === 0) {
+ return false;
+ }
+ } else {
+ $rawData = InstalledVersions::getRawData();
+ if ($rawData === null || $rawData === []) {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
diff --git a/doctrine/cache/UPGRADE-1.11.md b/doctrine/cache/UPGRADE-1.11.md
new file mode 100644
index 00000000..a33be230
--- /dev/null
+++ b/doctrine/cache/UPGRADE-1.11.md
@@ -0,0 +1,15 @@
+# Upgrade to 1.11
+
+doctrine/cache will no longer be maintained and all cache implementations have
+been marked as deprecated. These implementations will be removed in 2.0, which
+will only contain interfaces to provide a lightweight package for backward
+compatibility.
+
+There are two new classes to use in the `Doctrine\Common\Cache\Psr6` namespace:
+* The `CacheAdapter` class allows using any Doctrine Cache as PSR-6 cache. This
+ is useful to provide a forward compatibility layer in libraries that accept
+ Doctrine cache implementations and switch to PSR-6.
+* The `DoctrineProvider` class allows using any PSR-6 cache as Doctrine cache.
+ This implementation is designed for libraries that leak the cache and want to
+ switch to allowing PSR-6 implementations. This class is design to be used
+ during the transition phase of sunsetting doctrine/cache support.
diff --git a/doctrine/cache/UPGRADE.md b/doctrine/cache/UPGRADE-1.4.md
index e1f8a503..e1f8a503 100644
--- a/doctrine/cache/UPGRADE.md
+++ b/doctrine/cache/UPGRADE-1.4.md
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php
deleted file mode 100644
index 138d49a5..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php
+++ /dev/null
@@ -1,105 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use const PHP_VERSION_ID;
-use function apc_cache_info;
-use function apc_clear_cache;
-use function apc_delete;
-use function apc_exists;
-use function apc_fetch;
-use function apc_sma_info;
-use function apc_store;
-
-/**
- * APC cache provider.
- *
- * @deprecated since version 1.6, use ApcuCache instead
- *
- * @link www.doctrine-project.org
- */
-class ApcCache extends CacheProvider
-{
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- return apc_fetch($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- return apc_exists($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- return apc_store($id, $data, $lifeTime);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- // apc_delete returns false if the id does not exist
- return apc_delete($id) || ! apc_exists($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- return apc_clear_cache() && apc_clear_cache('user');
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetchMultiple(array $keys)
- {
- return apc_fetch($keys) ?: [];
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
- {
- $result = apc_store($keysAndValues, null, $lifetime);
-
- return empty($result);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $info = apc_cache_info('', true);
- $sma = apc_sma_info();
-
- // @TODO - Temporary fix @see https://github.com/krakjoe/apcu/pull/42
- if (PHP_VERSION_ID >= 50500) {
- $info['num_hits'] = $info['num_hits'] ?? $info['nhits'];
- $info['num_misses'] = $info['num_misses'] ?? $info['nmisses'];
- $info['start_time'] = $info['start_time'] ?? $info['stime'];
- }
-
- return [
- Cache::STATS_HITS => $info['num_hits'],
- Cache::STATS_MISSES => $info['num_misses'],
- Cache::STATS_UPTIME => $info['start_time'],
- Cache::STATS_MEMORY_USAGE => $info['mem_size'],
- Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'],
- ];
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php
deleted file mode 100644
index a7252136..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use function apcu_cache_info;
-use function apcu_clear_cache;
-use function apcu_delete;
-use function apcu_exists;
-use function apcu_fetch;
-use function apcu_sma_info;
-use function apcu_store;
-use function count;
-
-/**
- * APCu cache provider.
- *
- * @link www.doctrine-project.org
- */
-class ApcuCache extends CacheProvider
-{
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- return apcu_fetch($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- return apcu_exists($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- return apcu_store($id, $data, $lifeTime);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- // apcu_delete returns false if the id does not exist
- return apcu_delete($id) || ! apcu_exists($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDeleteMultiple(array $keys)
- {
- $result = apcu_delete($keys);
-
- return $result !== false && count($result) !== count($keys);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- return apcu_clear_cache();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetchMultiple(array $keys)
- {
- return apcu_fetch($keys) ?: [];
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
- {
- $result = apcu_store($keysAndValues, null, $lifetime);
-
- return empty($result);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $info = apcu_cache_info(true);
- $sma = apcu_sma_info();
-
- return [
- Cache::STATS_HITS => $info['num_hits'],
- Cache::STATS_MISSES => $info['num_misses'],
- Cache::STATS_UPTIME => $info['start_time'],
- Cache::STATS_MEMORY_USAGE => $info['mem_size'],
- Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'],
- ];
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php
deleted file mode 100644
index 1beb7098..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php
+++ /dev/null
@@ -1,113 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use function time;
-
-/**
- * Array cache driver.
- *
- * @link www.doctrine-project.org
- */
-class ArrayCache extends CacheProvider
-{
- /** @var array[] $data each element being a tuple of [$data, $expiration], where the expiration is int|bool */
- private $data = [];
-
- /** @var int */
- private $hitsCount = 0;
-
- /** @var int */
- private $missesCount = 0;
-
- /** @var int */
- private $upTime;
-
- /**
- * {@inheritdoc}
- */
- public function __construct()
- {
- $this->upTime = time();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- if (! $this->doContains($id)) {
- $this->missesCount += 1;
-
- return false;
- }
-
- $this->hitsCount += 1;
-
- return $this->data[$id][0];
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- if (! isset($this->data[$id])) {
- return false;
- }
-
- $expiration = $this->data[$id][1];
-
- if ($expiration && $expiration < time()) {
- $this->doDelete($id);
-
- return false;
- }
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- $this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false];
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- unset($this->data[$id]);
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- $this->data = [];
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- return [
- Cache::STATS_HITS => $this->hitsCount,
- Cache::STATS_MISSES => $this->missesCount,
- Cache::STATS_UPTIME => $this->upTime,
- Cache::STATS_MEMORY_USAGE => null,
- Cache::STATS_MEMORY_AVAILABLE => null,
- ];
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php b/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php
index 45697442..4cfab6c0 100644
--- a/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php
+++ b/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php
@@ -84,7 +84,7 @@ interface Cache
* - <b>memory_available</b>
* Memory allowed to use for storage.
*
- * @return array|null An associative array with server's statistics if available, NULL otherwise.
+ * @return mixed[]|null An associative array with server's statistics if available, NULL otherwise.
*/
public function getStats();
}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php b/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php
index 43d414f3..180482a7 100644
--- a/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php
+++ b/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php
@@ -171,7 +171,7 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M
*
* @return string The namespaced id.
*/
- private function getNamespacedId(string $id) : string
+ private function getNamespacedId(string $id): string
{
$namespaceVersion = $this->getNamespaceVersion();
@@ -181,7 +181,7 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M
/**
* Returns the namespace cache key.
*/
- private function getNamespaceCacheKey() : string
+ private function getNamespaceCacheKey(): string
{
return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
}
@@ -189,7 +189,7 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M
/**
* Returns the namespace version.
*/
- private function getNamespaceVersion() : int
+ private function getNamespaceVersion(): int
{
if ($this->namespaceVersion !== null) {
return $this->namespaceVersion;
@@ -204,9 +204,9 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M
/**
* Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it.
*
- * @param array $keys Array of keys to retrieve from cache
+ * @param string[] $keys Array of keys to retrieve from cache
*
- * @return array Array of values retrieved for the given keys.
+ * @return mixed[] Array of values retrieved for the given keys.
*/
protected function doFetchMultiple(array $keys)
{
@@ -245,9 +245,9 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M
/**
* Default implementation of doSaveMultiple. Each driver that supports multi-put should override it.
*
- * @param array $keysAndValues Array of keys and values to save in cache
- * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these
- * cache entries (0 => infinite lifeTime).
+ * @param mixed[] $keysAndValues Array of keys and values to save in cache
+ * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these
+ * cache entries (0 => infinite lifeTime).
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't.
*/
@@ -281,7 +281,7 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M
/**
* Default implementation of doDeleteMultiple. Each driver that supports multi-delete should override it.
*
- * @param array $keys Array of keys to delete from cache
+ * @param string[] $keys Array of keys to delete from cache
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't
*/
@@ -319,7 +319,7 @@ abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, M
/**
* Retrieves cached information from the data store.
*
- * @return array|null An associative array with server's statistics if available, NULL otherwise.
+ * @return mixed[]|null An associative array with server's statistics if available, NULL otherwise.
*/
abstract protected function doGetStats();
}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php
deleted file mode 100644
index 8f85845c..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php
+++ /dev/null
@@ -1,195 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use Traversable;
-use function array_values;
-use function count;
-use function iterator_to_array;
-
-/**
- * Cache provider that allows to easily chain multiple cache providers
- */
-class ChainCache extends CacheProvider
-{
- /** @var CacheProvider[] */
- private $cacheProviders = [];
-
- /** @var int */
- private $defaultLifeTimeForDownstreamCacheProviders = 0;
-
- /**
- * @param CacheProvider[] $cacheProviders
- */
- public function __construct($cacheProviders = [])
- {
- $this->cacheProviders = $cacheProviders instanceof Traversable
- ? iterator_to_array($cacheProviders, false)
- : array_values($cacheProviders);
- }
-
- public function setDefaultLifeTimeForDownstreamCacheProviders(int $defaultLifeTimeForDownstreamCacheProviders) : void
- {
- $this->defaultLifeTimeForDownstreamCacheProviders = $defaultLifeTimeForDownstreamCacheProviders;
- }
-
- /**
- * {@inheritDoc}
- */
- public function setNamespace($namespace)
- {
- parent::setNamespace($namespace);
-
- foreach ($this->cacheProviders as $cacheProvider) {
- $cacheProvider->setNamespace($namespace);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doFetch($id)
- {
- foreach ($this->cacheProviders as $key => $cacheProvider) {
- if ($cacheProvider->doContains($id)) {
- $value = $cacheProvider->doFetch($id);
-
- // We populate all the previous cache layers (that are assumed to be faster)
- for ($subKey = $key - 1; $subKey >= 0; $subKey--) {
- $this->cacheProviders[$subKey]->doSave($id, $value, $this->defaultLifeTimeForDownstreamCacheProviders);
- }
-
- return $value;
- }
- }
-
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetchMultiple(array $keys)
- {
- /** @var CacheProvider[] $traversedProviders */
- $traversedProviders = [];
- $keysCount = count($keys);
- $fetchedValues = [];
-
- foreach ($this->cacheProviders as $key => $cacheProvider) {
- $fetchedValues = $cacheProvider->doFetchMultiple($keys);
-
- // We populate all the previous cache layers (that are assumed to be faster)
- if (count($fetchedValues) === $keysCount) {
- foreach ($traversedProviders as $previousCacheProvider) {
- $previousCacheProvider->doSaveMultiple($fetchedValues, $this->defaultLifeTimeForDownstreamCacheProviders);
- }
-
- return $fetchedValues;
- }
-
- $traversedProviders[] = $cacheProvider;
- }
-
- return $fetchedValues;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doContains($id)
- {
- foreach ($this->cacheProviders as $cacheProvider) {
- if ($cacheProvider->doContains($id)) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- $stored = true;
-
- foreach ($this->cacheProviders as $cacheProvider) {
- $stored = $cacheProvider->doSave($id, $data, $lifeTime) && $stored;
- }
-
- return $stored;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
- {
- $stored = true;
-
- foreach ($this->cacheProviders as $cacheProvider) {
- $stored = $cacheProvider->doSaveMultiple($keysAndValues, $lifetime) && $stored;
- }
-
- return $stored;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doDelete($id)
- {
- $deleted = true;
-
- foreach ($this->cacheProviders as $cacheProvider) {
- $deleted = $cacheProvider->doDelete($id) && $deleted;
- }
-
- return $deleted;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDeleteMultiple(array $keys)
- {
- $deleted = true;
-
- foreach ($this->cacheProviders as $cacheProvider) {
- $deleted = $cacheProvider->doDeleteMultiple($keys) && $deleted;
- }
-
- return $deleted;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doFlush()
- {
- $flushed = true;
-
- foreach ($this->cacheProviders as $cacheProvider) {
- $flushed = $cacheProvider->doFlush() && $flushed;
- }
-
- return $flushed;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doGetStats()
- {
- // We return all the stats from all adapters
- $stats = [];
-
- foreach ($this->cacheProviders as $cacheProvider) {
- $stats[] = $cacheProvider->doGetStats();
- }
-
- return $stats;
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php
deleted file mode 100644
index b27720c3..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseBucketCache.php
+++ /dev/null
@@ -1,197 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Doctrine\Common\Cache;
-
-use Couchbase\Bucket;
-use Couchbase\Document;
-use Couchbase\Exception;
-use RuntimeException;
-use function phpversion;
-use function serialize;
-use function sprintf;
-use function substr;
-use function time;
-use function unserialize;
-use function version_compare;
-
-/**
- * Couchbase ^2.3.0 cache provider.
- */
-final class CouchbaseBucketCache extends CacheProvider
-{
- private const MINIMUM_VERSION = '2.3.0';
-
- private const KEY_NOT_FOUND = 13;
-
- private const MAX_KEY_LENGTH = 250;
-
- private const THIRTY_DAYS_IN_SECONDS = 2592000;
-
- /** @var Bucket */
- private $bucket;
-
- public function __construct(Bucket $bucket)
- {
- if (version_compare(phpversion('couchbase'), self::MINIMUM_VERSION) < 0) {
- // Manager is required to flush cache and pull stats.
- throw new RuntimeException(sprintf('ext-couchbase:^%s is required.', self::MINIMUM_VERSION));
- }
-
- $this->bucket = $bucket;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- $id = $this->normalizeKey($id);
-
- try {
- $document = $this->bucket->get($id);
- } catch (Exception $e) {
- return false;
- }
-
- if ($document instanceof Document && $document->value !== false) {
- return unserialize($document->value);
- }
-
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- $id = $this->normalizeKey($id);
-
- try {
- $document = $this->bucket->get($id);
- } catch (Exception $e) {
- return false;
- }
-
- if ($document instanceof Document) {
- return ! $document->error;
- }
-
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- $id = $this->normalizeKey($id);
-
- $lifeTime = $this->normalizeExpiry($lifeTime);
-
- try {
- $encoded = serialize($data);
-
- $document = $this->bucket->upsert($id, $encoded, [
- 'expiry' => (int) $lifeTime,
- ]);
- } catch (Exception $e) {
- return false;
- }
-
- if ($document instanceof Document) {
- return ! $document->error;
- }
-
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- $id = $this->normalizeKey($id);
-
- try {
- $document = $this->bucket->remove($id);
- } catch (Exception $e) {
- return $e->getCode() === self::KEY_NOT_FOUND;
- }
-
- if ($document instanceof Document) {
- return ! $document->error;
- }
-
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- $manager = $this->bucket->manager();
-
- // Flush does not return with success or failure, and must be enabled per bucket on the server.
- // Store a marker item so that we will know if it was successful.
- $this->doSave(__METHOD__, true, 60);
-
- $manager->flush();
-
- if ($this->doContains(__METHOD__)) {
- $this->doDelete(__METHOD__);
-
- return false;
- }
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $manager = $this->bucket->manager();
- $stats = $manager->info();
- $nodes = $stats['nodes'];
- $node = $nodes[0];
- $interestingStats = $node['interestingStats'];
-
- return [
- Cache::STATS_HITS => $interestingStats['get_hits'],
- Cache::STATS_MISSES => $interestingStats['cmd_get'] - $interestingStats['get_hits'],
- Cache::STATS_UPTIME => $node['uptime'],
- Cache::STATS_MEMORY_USAGE => $interestingStats['mem_used'],
- Cache::STATS_MEMORY_AVAILABLE => $node['memoryFree'],
- ];
- }
-
- private function normalizeKey(string $id) : string
- {
- $normalized = substr($id, 0, self::MAX_KEY_LENGTH);
-
- if ($normalized === false) {
- return $id;
- }
-
- return $normalized;
- }
-
- /**
- * Expiry treated as a unix timestamp instead of an offset if expiry is greater than 30 days.
- *
- * @src https://developer.couchbase.com/documentation/server/4.1/developer-guide/expiry.html
- */
- private function normalizeExpiry(int $expiry) : int
- {
- if ($expiry > self::THIRTY_DAYS_IN_SECONDS) {
- return time() + $expiry;
- }
-
- return $expiry;
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php
deleted file mode 100644
index 2c62c2ea..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php
+++ /dev/null
@@ -1,105 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use Couchbase;
-use function explode;
-use function time;
-
-/**
- * Couchbase cache provider.
- *
- * @deprecated Couchbase SDK 1.x is now deprecated. Use \Doctrine\Common\Cache\CouchbaseBucketCache instead.
- * https://developer.couchbase.com/documentation/server/current/sdk/php/compatibility-versions-features.html
- *
- * @link www.doctrine-project.org
- */
-class CouchbaseCache extends CacheProvider
-{
- /** @var Couchbase|null */
- private $couchbase;
-
- /**
- * Sets the Couchbase instance to use.
- *
- * @return void
- */
- public function setCouchbase(Couchbase $couchbase)
- {
- $this->couchbase = $couchbase;
- }
-
- /**
- * Gets the Couchbase instance used by the cache.
- *
- * @return Couchbase|null
- */
- public function getCouchbase()
- {
- return $this->couchbase;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- return $this->couchbase->get($id) ?: false;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- return $this->couchbase->get($id) !== null;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- if ($lifeTime > 30 * 24 * 3600) {
- $lifeTime = time() + $lifeTime;
- }
-
- return $this->couchbase->set($id, $data, (int) $lifeTime);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- return $this->couchbase->delete($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- return $this->couchbase->flush();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $stats = $this->couchbase->getStats();
- $servers = $this->couchbase->getServers();
- $server = explode(':', $servers[0]);
- $key = $server[0] . ':11210';
- $stats = $stats[$key];
-
- return [
- Cache::STATS_HITS => $stats['get_hits'],
- Cache::STATS_MISSES => $stats['get_misses'],
- Cache::STATS_UPTIME => $stats['uptime'],
- Cache::STATS_MEMORY_USAGE => $stats['bytes'],
- Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
- ];
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php
deleted file mode 100644
index b06f8623..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php
+++ /dev/null
@@ -1,198 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Doctrine\Common\Cache;
-
-use DateTime;
-use MongoDB\BSON\Binary;
-use MongoDB\BSON\UTCDateTime;
-use MongoDB\Collection;
-use MongoDB\Database;
-use MongoDB\Driver\Exception\Exception;
-use MongoDB\Model\BSONDocument;
-use function serialize;
-use function time;
-use function unserialize;
-
-/**
- * MongoDB cache provider for ext-mongodb
- *
- * @internal Do not use - will be removed in 2.0. Use MongoDBCache instead
- */
-class ExtMongoDBCache extends CacheProvider
-{
- /** @var Database */
- private $database;
-
- /** @var Collection */
- private $collection;
-
- /** @var bool */
- private $expirationIndexCreated = false;
-
- /**
- * This provider will default to the write concern and read preference
- * options set on the Database instance (or inherited from MongoDB or
- * Client). Using an unacknowledged write concern (< 1) may make the return
- * values of delete() and save() unreliable. Reading from secondaries may
- * make contain() and fetch() unreliable.
- *
- * @see http://www.php.net/manual/en/mongo.readpreferences.php
- * @see http://www.php.net/manual/en/mongo.writeconcerns.php
- */
- public function __construct(Collection $collection)
- {
- // Ensure there is no typemap set - we want to use our own
- $this->collection = $collection->withOptions(['typeMap' => null]);
- $this->database = new Database($collection->getManager(), $collection->getDatabaseName());
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::DATA_FIELD, MongoDBCache::EXPIRATION_FIELD]);
-
- if ($document === null) {
- return false;
- }
-
- if ($this->isExpired($document)) {
- $this->createExpirationIndex();
- $this->doDelete($id);
-
- return false;
- }
-
- return unserialize($document[MongoDBCache::DATA_FIELD]->getData());
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::EXPIRATION_FIELD]);
-
- if ($document === null) {
- return false;
- }
-
- if ($this->isExpired($document)) {
- $this->createExpirationIndex();
- $this->doDelete($id);
-
- return false;
- }
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- try {
- $this->collection->updateOne(
- ['_id' => $id],
- [
- '$set' => [
- MongoDBCache::EXPIRATION_FIELD => ($lifeTime > 0 ? new UTCDateTime((time() + $lifeTime) * 1000): null),
- MongoDBCache::DATA_FIELD => new Binary(serialize($data), Binary::TYPE_GENERIC),
- ],
- ],
- ['upsert' => true]
- );
- } catch (Exception $e) {
- return false;
- }
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- try {
- $this->collection->deleteOne(['_id' => $id]);
- } catch (Exception $e) {
- return false;
- }
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- try {
- // Use remove() in lieu of drop() to maintain any collection indexes
- $this->collection->deleteMany([]);
- } catch (Exception $e) {
- return false;
- }
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $uptime = null;
- $memoryUsage = null;
-
- try {
- $serverStatus = $this->database->command([
- 'serverStatus' => 1,
- 'locks' => 0,
- 'metrics' => 0,
- 'recordStats' => 0,
- 'repl' => 0,
- ])->toArray()[0];
- $uptime = $serverStatus['uptime'] ?? null;
- } catch (Exception $e) {
- }
-
- try {
- $collStats = $this->database->command(['collStats' => $this->collection->getCollectionName()])->toArray()[0];
- $memoryUsage = $collStats['size'] ?? null;
- } catch (Exception $e) {
- }
-
- return [
- Cache::STATS_HITS => null,
- Cache::STATS_MISSES => null,
- Cache::STATS_UPTIME => $uptime,
- Cache::STATS_MEMORY_USAGE => $memoryUsage,
- Cache::STATS_MEMORY_AVAILABLE => null,
- ];
- }
-
- /**
- * Check if the document is expired.
- */
- private function isExpired(BSONDocument $document) : bool
- {
- return isset($document[MongoDBCache::EXPIRATION_FIELD]) &&
- $document[MongoDBCache::EXPIRATION_FIELD] instanceof UTCDateTime &&
- $document[MongoDBCache::EXPIRATION_FIELD]->toDateTime() < new DateTime();
- }
-
- private function createExpirationIndex() : void
- {
- if ($this->expirationIndexCreated) {
- return;
- }
-
- $this->collection->createIndex([MongoDBCache::EXPIRATION_FIELD => 1], ['background' => true, 'expireAfterSeconds' => 0]);
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php
deleted file mode 100644
index 4b485205..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php
+++ /dev/null
@@ -1,281 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use FilesystemIterator;
-use InvalidArgumentException;
-use Iterator;
-use RecursiveDirectoryIterator;
-use RecursiveIteratorIterator;
-use const DIRECTORY_SEPARATOR;
-use const PATHINFO_DIRNAME;
-use function bin2hex;
-use function chmod;
-use function defined;
-use function disk_free_space;
-use function file_exists;
-use function file_put_contents;
-use function gettype;
-use function hash;
-use function is_dir;
-use function is_int;
-use function is_writable;
-use function mkdir;
-use function pathinfo;
-use function realpath;
-use function rename;
-use function rmdir;
-use function sprintf;
-use function strlen;
-use function strrpos;
-use function substr;
-use function tempnam;
-use function unlink;
-
-/**
- * Base file cache driver.
- */
-abstract class FileCache extends CacheProvider
-{
- /**
- * The cache directory.
- *
- * @var string
- */
- protected $directory;
-
- /**
- * The cache file extension.
- *
- * @var string
- */
- private $extension;
-
- /** @var int */
- private $umask;
-
- /** @var int */
- private $directoryStringLength;
-
- /** @var int */
- private $extensionStringLength;
-
- /** @var bool */
- private $isRunningOnWindows;
-
- /**
- * @param string $directory The cache directory.
- * @param string $extension The cache file extension.
- *
- * @throws InvalidArgumentException
- */
- public function __construct($directory, $extension = '', $umask = 0002)
- {
- // YES, this needs to be *before* createPathIfNeeded()
- if (! is_int($umask)) {
- throw new InvalidArgumentException(sprintf(
- 'The umask parameter is required to be integer, was: %s',
- gettype($umask)
- ));
- }
- $this->umask = $umask;
-
- if (! $this->createPathIfNeeded($directory)) {
- throw new InvalidArgumentException(sprintf(
- 'The directory "%s" does not exist and could not be created.',
- $directory
- ));
- }
-
- if (! is_writable($directory)) {
- throw new InvalidArgumentException(sprintf(
- 'The directory "%s" is not writable.',
- $directory
- ));
- }
-
- // YES, this needs to be *after* createPathIfNeeded()
- $this->directory = realpath($directory);
- $this->extension = (string) $extension;
-
- $this->directoryStringLength = strlen($this->directory);
- $this->extensionStringLength = strlen($this->extension);
- $this->isRunningOnWindows = defined('PHP_WINDOWS_VERSION_BUILD');
- }
-
- /**
- * Gets the cache directory.
- *
- * @return string
- */
- public function getDirectory()
- {
- return $this->directory;
- }
-
- /**
- * Gets the cache file extension.
- *
- * @return string
- */
- public function getExtension()
- {
- return $this->extension;
- }
-
- /**
- * @param string $id
- *
- * @return string
- */
- protected function getFilename($id)
- {
- $hash = hash('sha256', $id);
-
- // This ensures that the filename is unique and that there are no invalid chars in it.
- if ($id === ''
- || ((strlen($id) * 2 + $this->extensionStringLength) > 255)
- || ($this->isRunningOnWindows && ($this->directoryStringLength + 4 + strlen($id) * 2 + $this->extensionStringLength) > 258)
- ) {
- // Most filesystems have a limit of 255 chars for each path component. On Windows the the whole path is limited
- // to 260 chars (including terminating null char). Using long UNC ("\\?\" prefix) does not work with the PHP API.
- // And there is a bug in PHP (https://bugs.php.net/bug.php?id=70943) with path lengths of 259.
- // So if the id in hex representation would surpass the limit, we use the hash instead. The prefix prevents
- // collisions between the hash and bin2hex.
- $filename = '_' . $hash;
- } else {
- $filename = bin2hex($id);
- }
-
- return $this->directory
- . DIRECTORY_SEPARATOR
- . substr($hash, 0, 2)
- . DIRECTORY_SEPARATOR
- . $filename
- . $this->extension;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- $filename = $this->getFilename($id);
-
- return @unlink($filename) || ! file_exists($filename);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- foreach ($this->getIterator() as $name => $file) {
- if ($file->isDir()) {
- // Remove the intermediate directories which have been created to balance the tree. It only takes effect
- // if the directory is empty. If several caches share the same directory but with different file extensions,
- // the other ones are not removed.
- @rmdir($name);
- } elseif ($this->isFilenameEndingWithExtension($name)) {
- // If an extension is set, only remove files which end with the given extension.
- // If no extension is set, we have no other choice than removing everything.
- @unlink($name);
- }
- }
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $usage = 0;
- foreach ($this->getIterator() as $name => $file) {
- if ($file->isDir() || ! $this->isFilenameEndingWithExtension($name)) {
- continue;
- }
-
- $usage += $file->getSize();
- }
-
- $free = disk_free_space($this->directory);
-
- return [
- Cache::STATS_HITS => null,
- Cache::STATS_MISSES => null,
- Cache::STATS_UPTIME => null,
- Cache::STATS_MEMORY_USAGE => $usage,
- Cache::STATS_MEMORY_AVAILABLE => $free,
- ];
- }
-
- /**
- * Create path if needed.
- *
- * @return bool TRUE on success or if path already exists, FALSE if path cannot be created.
- */
- private function createPathIfNeeded(string $path) : bool
- {
- if (! is_dir($path)) {
- if (@mkdir($path, 0777 & (~$this->umask), true) === false && ! is_dir($path)) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Writes a string content to file in an atomic way.
- *
- * @param string $filename Path to the file where to write the data.
- * @param string $content The content to write
- *
- * @return bool TRUE on success, FALSE if path cannot be created, if path is not writable or an any other error.
- */
- protected function writeFile(string $filename, string $content) : bool
- {
- $filepath = pathinfo($filename, PATHINFO_DIRNAME);
-
- if (! $this->createPathIfNeeded($filepath)) {
- return false;
- }
-
- if (! is_writable($filepath)) {
- return false;
- }
-
- $tmpFile = tempnam($filepath, 'swap');
- @chmod($tmpFile, 0666 & (~$this->umask));
-
- if (file_put_contents($tmpFile, $content) !== false) {
- @chmod($tmpFile, 0666 & (~$this->umask));
- if (@rename($tmpFile, $filename)) {
- return true;
- }
-
- @unlink($tmpFile);
- }
-
- return false;
- }
-
- private function getIterator() : Iterator
- {
- return new RecursiveIteratorIterator(
- new RecursiveDirectoryIterator($this->directory, FilesystemIterator::SKIP_DOTS),
- RecursiveIteratorIterator::CHILD_FIRST
- );
- }
-
- /**
- * @param string $name The filename
- */
- private function isFilenameEndingWithExtension(string $name) : bool
- {
- return $this->extension === ''
- || strrpos($name, $this->extension) === (strlen($name) - $this->extensionStringLength);
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php
deleted file mode 100644
index 8f34c9cb..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use const PHP_EOL;
-use function fclose;
-use function fgets;
-use function fopen;
-use function is_file;
-use function serialize;
-use function time;
-use function unserialize;
-
-/**
- * Filesystem cache driver.
- */
-class FilesystemCache extends FileCache
-{
- public const EXTENSION = '.doctrinecache.data';
-
- /**
- * {@inheritdoc}
- */
- public function __construct($directory, $extension = self::EXTENSION, $umask = 0002)
- {
- parent::__construct($directory, $extension, $umask);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- $data = '';
- $lifetime = -1;
- $filename = $this->getFilename($id);
-
- if (! is_file($filename)) {
- return false;
- }
-
- $resource = fopen($filename, 'r');
- $line = fgets($resource);
-
- if ($line !== false) {
- $lifetime = (int) $line;
- }
-
- if ($lifetime !== 0 && $lifetime < time()) {
- fclose($resource);
-
- return false;
- }
-
- while (($line = fgets($resource)) !== false) {
- $data .= $line;
- }
-
- fclose($resource);
-
- return unserialize($data);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- $lifetime = -1;
- $filename = $this->getFilename($id);
-
- if (! is_file($filename)) {
- return false;
- }
-
- $resource = fopen($filename, 'r');
- $line = fgets($resource);
-
- if ($line !== false) {
- $lifetime = (int) $line;
- }
-
- fclose($resource);
-
- return $lifetime === 0 || $lifetime > time();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- if ($lifeTime > 0) {
- $lifeTime = time() + $lifeTime;
- }
-
- $data = serialize($data);
- $filename = $this->getFilename($id);
-
- return $this->writeFile($filename, $lifeTime . PHP_EOL . $data);
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php b/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php
deleted file mode 100644
index 0a7fe659..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/InvalidCacheId.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace Doctrine\Common\Cache;
-
-use InvalidArgumentException;
-use function sprintf;
-
-final class InvalidCacheId extends InvalidArgumentException
-{
- public static function exceedsMaxLength($id, int $maxLength) : self
- {
- return new self(sprintf('Cache id "%s" exceeds maximum length %d', $id, $maxLength));
- }
-
- public static function containsUnauthorizedCharacter($id, string $character) : self
- {
- return new self(sprintf('Cache id "%s" contains unauthorized character "%s"', $id, $character));
- }
-
- public static function containsControlCharacter($id) : self
- {
- return new self(sprintf('Cache id "%s" contains at least one control character', $id));
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php
deleted file mode 100644
index fe5dc4b8..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/LegacyMongoDBCache.php
+++ /dev/null
@@ -1,175 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use MongoBinData;
-use MongoCollection;
-use MongoCursorException;
-use MongoDate;
-use const E_USER_DEPRECATED;
-use function serialize;
-use function time;
-use function trigger_error;
-use function unserialize;
-
-/**
- * MongoDB cache provider.
- *
- * @internal Do not use - will be removed in 2.0. Use MongoDBCache instead
- */
-class LegacyMongoDBCache extends CacheProvider
-{
- /** @var MongoCollection */
- private $collection;
-
- /** @var bool */
- private $expirationIndexCreated = false;
-
- /**
- * This provider will default to the write concern and read preference
- * options set on the MongoCollection instance (or inherited from MongoDB or
- * MongoClient). Using an unacknowledged write concern (< 1) may make the
- * return values of delete() and save() unreliable. Reading from secondaries
- * may make contain() and fetch() unreliable.
- *
- * @see http://www.php.net/manual/en/mongo.readpreferences.php
- * @see http://www.php.net/manual/en/mongo.writeconcerns.php
- */
- public function __construct(MongoCollection $collection)
- {
- @trigger_error('Using the legacy MongoDB cache provider is deprecated and will be removed in 2.0', E_USER_DEPRECATED);
- $this->collection = $collection;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::DATA_FIELD, MongoDBCache::EXPIRATION_FIELD]);
-
- if ($document === null) {
- return false;
- }
-
- if ($this->isExpired($document)) {
- $this->createExpirationIndex();
- $this->doDelete($id);
-
- return false;
- }
-
- return unserialize($document[MongoDBCache::DATA_FIELD]->bin);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::EXPIRATION_FIELD]);
-
- if ($document === null) {
- return false;
- }
-
- if ($this->isExpired($document)) {
- $this->createExpirationIndex();
- $this->doDelete($id);
-
- return false;
- }
-
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- try {
- $result = $this->collection->update(
- ['_id' => $id],
- [
- '$set' => [
- MongoDBCache::EXPIRATION_FIELD => ($lifeTime > 0 ? new MongoDate(time() + $lifeTime) : null),
- MongoDBCache::DATA_FIELD => new MongoBinData(serialize($data), MongoBinData::BYTE_ARRAY),
- ],
- ],
- ['upsert' => true, 'multiple' => false]
- );
- } catch (MongoCursorException $e) {
- return false;
- }
-
- return ($result['ok'] ?? 1) == 1;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- $result = $this->collection->remove(['_id' => $id]);
-
- return ($result['ok'] ?? 1) == 1;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- // Use remove() in lieu of drop() to maintain any collection indexes
- $result = $this->collection->remove();
-
- return ($result['ok'] ?? 1) == 1;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $serverStatus = $this->collection->db->command([
- 'serverStatus' => 1,
- 'locks' => 0,
- 'metrics' => 0,
- 'recordStats' => 0,
- 'repl' => 0,
- ]);
-
- $collStats = $this->collection->db->command(['collStats' => 1]);
-
- return [
- Cache::STATS_HITS => null,
- Cache::STATS_MISSES => null,
- Cache::STATS_UPTIME => $serverStatus['uptime'] ?? null,
- Cache::STATS_MEMORY_USAGE => $collStats['size'] ?? null,
- Cache::STATS_MEMORY_AVAILABLE => null,
- ];
- }
-
- /**
- * Check if the document is expired.
- *
- * @param array $document
- */
- private function isExpired(array $document) : bool
- {
- return isset($document[MongoDBCache::EXPIRATION_FIELD]) &&
- $document[MongoDBCache::EXPIRATION_FIELD] instanceof MongoDate &&
- $document[MongoDBCache::EXPIRATION_FIELD]->sec < time();
- }
-
- private function createExpirationIndex() : void
- {
- if ($this->expirationIndexCreated) {
- return;
- }
-
- $this->expirationIndexCreated = true;
- $this->collection->createIndex([MongoDBCache::EXPIRATION_FIELD => 1], ['background' => true, 'expireAfterSeconds' => 0]);
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php
deleted file mode 100644
index 42bbd2ce..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php
+++ /dev/null
@@ -1,104 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use Memcache;
-use function time;
-
-/**
- * Memcache cache provider.
- *
- * @deprecated
- *
- * @link www.doctrine-project.org
- */
-class MemcacheCache extends CacheProvider
-{
- /** @var Memcache|null */
- private $memcache;
-
- /**
- * Sets the memcache instance to use.
- *
- * @return void
- */
- public function setMemcache(Memcache $memcache)
- {
- $this->memcache = $memcache;
- }
-
- /**
- * Gets the memcache instance used by the cache.
- *
- * @return Memcache|null
- */
- public function getMemcache()
- {
- return $this->memcache;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- return $this->memcache->get($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- $flags = null;
- $this->memcache->get($id, $flags);
-
- //if memcache has changed the value of "flags", it means the value exists
- return $flags !== null;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- if ($lifeTime > 30 * 24 * 3600) {
- $lifeTime = time() + $lifeTime;
- }
-
- return $this->memcache->set($id, $data, 0, (int) $lifeTime);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- // Memcache::delete() returns false if entry does not exist
- return $this->memcache->delete($id) || ! $this->doContains($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- return $this->memcache->flush();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $stats = $this->memcache->getStats();
-
- return [
- Cache::STATS_HITS => $stats['get_hits'],
- Cache::STATS_MISSES => $stats['get_misses'],
- Cache::STATS_UPTIME => $stats['uptime'],
- Cache::STATS_MEMORY_USAGE => $stats['bytes'],
- Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
- ];
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php
deleted file mode 100644
index da966ae2..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php
+++ /dev/null
@@ -1,170 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use Memcached;
-use function array_keys;
-use function preg_match;
-use function strlen;
-use function strpos;
-use function time;
-
-/**
- * Memcached cache provider.
- *
- * @link www.doctrine-project.org
- */
-class MemcachedCache extends CacheProvider
-{
- public const CACHE_ID_MAX_LENGTH = 250;
-
- /** @var Memcached|null */
- private $memcached;
-
- /**
- * Sets the memcache instance to use.
- *
- * @return void
- */
- public function setMemcached(Memcached $memcached)
- {
- $this->memcached = $memcached;
- }
-
- /**
- * Gets the memcached instance used by the cache.
- *
- * @return Memcached|null
- */
- public function getMemcached()
- {
- return $this->memcached;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- return $this->memcached->get($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetchMultiple(array $keys)
- {
- return $this->memcached->getMulti($keys) ?: [];
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
- {
- foreach (array_keys($keysAndValues) as $id) {
- $this->validateCacheId($id);
- }
-
- if ($lifetime > 30 * 24 * 3600) {
- $lifetime = time() + $lifetime;
- }
-
- return $this->memcached->setMulti($keysAndValues, $lifetime);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- $this->memcached->get($id);
-
- return $this->memcached->getResultCode() === Memcached::RES_SUCCESS;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- $this->validateCacheId($id);
-
- if ($lifeTime > 30 * 24 * 3600) {
- $lifeTime = time() + $lifeTime;
- }
-
- return $this->memcached->set($id, $data, (int) $lifeTime);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDeleteMultiple(array $keys)
- {
- return $this->memcached->deleteMulti($keys)
- || $this->memcached->getResultCode() === Memcached::RES_NOTFOUND;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- return $this->memcached->delete($id)
- || $this->memcached->getResultCode() === Memcached::RES_NOTFOUND;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- return $this->memcached->flush();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $stats = $this->memcached->getStats();
- $servers = $this->memcached->getServerList();
- $key = $servers[0]['host'] . ':' . $servers[0]['port'];
- $stats = $stats[$key];
-
- return [
- Cache::STATS_HITS => $stats['get_hits'],
- Cache::STATS_MISSES => $stats['get_misses'],
- Cache::STATS_UPTIME => $stats['uptime'],
- Cache::STATS_MEMORY_USAGE => $stats['bytes'],
- Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
- ];
- }
-
- /**
- * Validate the cache id
- *
- * @see https://github.com/memcached/memcached/blob/1.5.12/doc/protocol.txt#L41-L49
- *
- * @param string $id
- *
- * @return void
- *
- * @throws InvalidCacheId
- */
- private function validateCacheId($id)
- {
- if (strlen($id) > self::CACHE_ID_MAX_LENGTH) {
- throw InvalidCacheId::exceedsMaxLength($id, self::CACHE_ID_MAX_LENGTH);
- }
-
- if (strpos($id, ' ') !== false) {
- throw InvalidCacheId::containsUnauthorizedCharacter($id, ' ');
- }
-
- if (preg_match('/[\t\r\n]/', $id) === 1) {
- throw InvalidCacheId::containsControlCharacter($id);
- }
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php
deleted file mode 100644
index 861e4dda..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php
+++ /dev/null
@@ -1,112 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use InvalidArgumentException;
-use MongoCollection;
-use MongoDB\Collection;
-use const E_USER_DEPRECATED;
-use function trigger_error;
-
-/**
- * MongoDB cache provider.
- */
-class MongoDBCache extends CacheProvider
-{
- /**
- * The data field will store the serialized PHP value.
- */
- public const DATA_FIELD = 'd';
-
- /**
- * The expiration field will store a MongoDate value indicating when the
- * cache entry should expire.
- *
- * With MongoDB 2.2+, entries can be automatically deleted by MongoDB by
- * indexing this field with the "expireAfterSeconds" option equal to zero.
- * This will direct MongoDB to regularly query for and delete any entries
- * whose date is older than the current time. Entries without a date value
- * in this field will be ignored.
- *
- * The cache provider will also check dates on its own, in case expired
- * entries are fetched before MongoDB's TTLMonitor pass can expire them.
- *
- * @see http://docs.mongodb.org/manual/tutorial/expire-data/
- */
- public const EXPIRATION_FIELD = 'e';
-
- /** @var CacheProvider */
- private $provider;
-
- /**
- * This provider will default to the write concern and read preference
- * options set on the collection instance (or inherited from MongoDB or
- * MongoClient). Using an unacknowledged write concern (< 1) may make the
- * return values of delete() and save() unreliable. Reading from secondaries
- * may make contain() and fetch() unreliable.
- *
- * @see http://www.php.net/manual/en/mongo.readpreferences.php
- * @see http://www.php.net/manual/en/mongo.writeconcerns.php
- *
- * @param MongoCollection|Collection $collection
- */
- public function __construct($collection)
- {
- if ($collection instanceof MongoCollection) {
- @trigger_error('Using a MongoCollection instance for creating a cache adapter is deprecated and will be removed in 2.0', E_USER_DEPRECATED);
- $this->provider = new LegacyMongoDBCache($collection);
- } elseif ($collection instanceof Collection) {
- $this->provider = new ExtMongoDBCache($collection);
- } else {
- throw new InvalidArgumentException('Invalid collection given - expected a MongoCollection or MongoDB\Collection instance');
- }
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- return $this->provider->doFetch($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- return $this->provider->doContains($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- return $this->provider->doSave($id, $data, $lifeTime);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- return $this->provider->doDelete($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- return $this->provider->doFlush();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- return $this->provider->doGetStats();
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php
index 6f059c16..b7c06d39 100644
--- a/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php
+++ b/doctrine/cache/lib/Doctrine/Common/Cache/MultiPutCache.php
@@ -14,9 +14,9 @@ interface MultiPutCache
/**
* Returns a boolean value indicating if the operation succeeded.
*
- * @param array $keysAndValues Array of keys and values to save in cache
- * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these
- * cache entries (0 => infinite lifeTime).
+ * @param mixed[] $keysAndValues Array of keys and values to save in cache
+ * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these
+ * cache entries (0 => infinite lifeTime).
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't.
*/
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php
deleted file mode 100644
index c0619991..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php
+++ /dev/null
@@ -1,118 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use function is_object;
-use function method_exists;
-use function restore_error_handler;
-use function serialize;
-use function set_error_handler;
-use function sprintf;
-use function time;
-use function var_export;
-
-/**
- * Php file cache driver.
- */
-class PhpFileCache extends FileCache
-{
- public const EXTENSION = '.doctrinecache.php';
-
- /**
- * @var callable
- *
- * This is cached in a local static variable to avoid instantiating a closure each time we need an empty handler
- */
- private static $emptyErrorHandler;
-
- /**
- * {@inheritdoc}
- */
- public function __construct($directory, $extension = self::EXTENSION, $umask = 0002)
- {
- parent::__construct($directory, $extension, $umask);
-
- self::$emptyErrorHandler = static function () {
- };
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- $value = $this->includeFileForId($id);
-
- if ($value === null) {
- return false;
- }
-
- if ($value['lifetime'] !== 0 && $value['lifetime'] < time()) {
- return false;
- }
-
- return $value['data'];
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- $value = $this->includeFileForId($id);
-
- if ($value === null) {
- return false;
- }
-
- return $value['lifetime'] === 0 || $value['lifetime'] > time();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- if ($lifeTime > 0) {
- $lifeTime = time() + $lifeTime;
- }
-
- $filename = $this->getFilename($id);
-
- $value = [
- 'lifetime' => $lifeTime,
- 'data' => $data,
- ];
-
- if (is_object($data) && method_exists($data, '__set_state')) {
- $value = var_export($value, true);
- $code = sprintf('<?php return %s;', $value);
- } else {
- $value = var_export(serialize($value), true);
- $code = sprintf('<?php return unserialize(%s);', $value);
- }
-
- return $this->writeFile($filename, $code);
- }
-
- /**
- * @return array|null
- */
- private function includeFileForId(string $id) : ?array
- {
- $fileName = $this->getFilename($id);
-
- // note: error suppression is still faster than `file_exists`, `is_file` and `is_readable`
- set_error_handler(self::$emptyErrorHandler);
-
- $value = include $fileName;
-
- restore_error_handler();
-
- if (! isset($value['lifetime'])) {
- return null;
- }
-
- return $value;
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php
deleted file mode 100644
index 6430d52d..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php
+++ /dev/null
@@ -1,143 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use Predis\ClientInterface;
-use function array_combine;
-use function array_filter;
-use function array_map;
-use function call_user_func_array;
-use function serialize;
-use function unserialize;
-
-/**
- * Predis cache provider.
- */
-class PredisCache extends CacheProvider
-{
- /** @var ClientInterface */
- private $client;
-
- public function __construct(ClientInterface $client)
- {
- $this->client = $client;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- $result = $this->client->get($id);
- if ($result === null) {
- return false;
- }
-
- return unserialize($result);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetchMultiple(array $keys)
- {
- $fetchedItems = call_user_func_array([$this->client, 'mget'], $keys);
-
- return array_map('unserialize', array_filter(array_combine($keys, $fetchedItems)));
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
- {
- if ($lifetime) {
- $success = true;
-
- // Keys have lifetime, use SETEX for each of them
- foreach ($keysAndValues as $key => $value) {
- $response = (string) $this->client->setex($key, $lifetime, serialize($value));
-
- if ($response == 'OK') {
- continue;
- }
-
- $success = false;
- }
-
- return $success;
- }
-
- // No lifetime, use MSET
- $response = $this->client->mset(array_map(static function ($value) {
- return serialize($value);
- }, $keysAndValues));
-
- return (string) $response == 'OK';
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- return (bool) $this->client->exists($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- $data = serialize($data);
- if ($lifeTime > 0) {
- $response = $this->client->setex($id, $lifeTime, $data);
- } else {
- $response = $this->client->set($id, $data);
- }
-
- return $response === true || $response == 'OK';
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- return $this->client->del($id) >= 0;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDeleteMultiple(array $keys)
- {
- return $this->client->del($keys) >= 0;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- $response = $this->client->flushdb();
-
- return $response === true || $response == 'OK';
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $info = $this->client->info();
-
- return [
- Cache::STATS_HITS => $info['Stats']['keyspace_hits'],
- Cache::STATS_MISSES => $info['Stats']['keyspace_misses'],
- Cache::STATS_UPTIME => $info['Server']['uptime_in_seconds'],
- Cache::STATS_MEMORY_USAGE => $info['Memory']['used_memory'],
- Cache::STATS_MEMORY_AVAILABLE => false,
- ];
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php
new file mode 100644
index 00000000..d3693b7c
--- /dev/null
+++ b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php
@@ -0,0 +1,340 @@
+<?php
+
+namespace Doctrine\Common\Cache\Psr6;
+
+use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Cache\ClearableCache;
+use Doctrine\Common\Cache\MultiDeleteCache;
+use Doctrine\Common\Cache\MultiGetCache;
+use Doctrine\Common\Cache\MultiPutCache;
+use Psr\Cache\CacheItemInterface;
+use Psr\Cache\CacheItemPoolInterface;
+use Symfony\Component\Cache\DoctrineProvider as SymfonyDoctrineProvider;
+
+use function array_key_exists;
+use function assert;
+use function count;
+use function current;
+use function get_class;
+use function gettype;
+use function is_object;
+use function is_string;
+use function microtime;
+use function sprintf;
+use function strpbrk;
+
+use const PHP_VERSION_ID;
+
+final class CacheAdapter implements CacheItemPoolInterface
+{
+ private const RESERVED_CHARACTERS = '{}()/\@:';
+
+ /** @var Cache */
+ private $cache;
+
+ /** @var array<CacheItem|TypedCacheItem> */
+ private $deferredItems = [];
+
+ public static function wrap(Cache $cache): CacheItemPoolInterface
+ {
+ if ($cache instanceof DoctrineProvider && ! $cache->getNamespace()) {
+ return $cache->getPool();
+ }
+
+ if ($cache instanceof SymfonyDoctrineProvider && ! $cache->getNamespace()) {
+ $getPool = function () {
+ // phpcs:ignore Squiz.Scope.StaticThisUsage.Found
+ return $this->pool;
+ };
+
+ return $getPool->bindTo($cache, SymfonyDoctrineProvider::class)();
+ }
+
+ return new self($cache);
+ }
+
+ private function __construct(Cache $cache)
+ {
+ $this->cache = $cache;
+ }
+
+ /** @internal */
+ public function getCache(): Cache
+ {
+ return $this->cache;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getItem($key): CacheItemInterface
+ {
+ assert(self::validKey($key));
+
+ if (isset($this->deferredItems[$key])) {
+ $this->commit();
+ }
+
+ $value = $this->cache->fetch($key);
+
+ if (PHP_VERSION_ID >= 80000) {
+ if ($value !== false) {
+ return new TypedCacheItem($key, $value, true);
+ }
+
+ return new TypedCacheItem($key, null, false);
+ }
+
+ if ($value !== false) {
+ return new CacheItem($key, $value, true);
+ }
+
+ return new CacheItem($key, null, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getItems(array $keys = []): array
+ {
+ if ($this->deferredItems) {
+ $this->commit();
+ }
+
+ assert(self::validKeys($keys));
+
+ $values = $this->doFetchMultiple($keys);
+ $items = [];
+
+ if (PHP_VERSION_ID >= 80000) {
+ foreach ($keys as $key) {
+ if (array_key_exists($key, $values)) {
+ $items[$key] = new TypedCacheItem($key, $values[$key], true);
+ } else {
+ $items[$key] = new TypedCacheItem($key, null, false);
+ }
+ }
+
+ return $items;
+ }
+
+ foreach ($keys as $key) {
+ if (array_key_exists($key, $values)) {
+ $items[$key] = new CacheItem($key, $values[$key], true);
+ } else {
+ $items[$key] = new CacheItem($key, null, false);
+ }
+ }
+
+ return $items;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function hasItem($key): bool
+ {
+ assert(self::validKey($key));
+
+ if (isset($this->deferredItems[$key])) {
+ $this->commit();
+ }
+
+ return $this->cache->contains($key);
+ }
+
+ public function clear(): bool
+ {
+ $this->deferredItems = [];
+
+ if (! $this->cache instanceof ClearableCache) {
+ return false;
+ }
+
+ return $this->cache->deleteAll();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function deleteItem($key): bool
+ {
+ assert(self::validKey($key));
+ unset($this->deferredItems[$key]);
+
+ return $this->cache->delete($key);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function deleteItems(array $keys): bool
+ {
+ foreach ($keys as $key) {
+ assert(self::validKey($key));
+ unset($this->deferredItems[$key]);
+ }
+
+ return $this->doDeleteMultiple($keys);
+ }
+
+ public function save(CacheItemInterface $item): bool
+ {
+ return $this->saveDeferred($item) && $this->commit();
+ }
+
+ public function saveDeferred(CacheItemInterface $item): bool
+ {
+ if (! $item instanceof CacheItem && ! $item instanceof TypedCacheItem) {
+ return false;
+ }
+
+ $this->deferredItems[$item->getKey()] = $item;
+
+ return true;
+ }
+
+ public function commit(): bool
+ {
+ if (! $this->deferredItems) {
+ return true;
+ }
+
+ $now = microtime(true);
+ $itemsCount = 0;
+ $byLifetime = [];
+ $expiredKeys = [];
+
+ foreach ($this->deferredItems as $key => $item) {
+ $lifetime = ($item->getExpiry() ?? $now) - $now;
+
+ if ($lifetime < 0) {
+ $expiredKeys[] = $key;
+
+ continue;
+ }
+
+ ++$itemsCount;
+ $byLifetime[(int) $lifetime][$key] = $item->get();
+ }
+
+ $this->deferredItems = [];
+
+ switch (count($expiredKeys)) {
+ case 0:
+ break;
+ case 1:
+ $this->cache->delete(current($expiredKeys));
+ break;
+ default:
+ $this->doDeleteMultiple($expiredKeys);
+ break;
+ }
+
+ if ($itemsCount === 1) {
+ return $this->cache->save($key, $item->get(), (int) $lifetime);
+ }
+
+ $success = true;
+ foreach ($byLifetime as $lifetime => $values) {
+ $success = $this->doSaveMultiple($values, $lifetime) && $success;
+ }
+
+ return $success;
+ }
+
+ public function __destruct()
+ {
+ $this->commit();
+ }
+
+ /**
+ * @param mixed $key
+ */
+ private static function validKey($key): bool
+ {
+ if (! is_string($key)) {
+ throw new InvalidArgument(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
+ }
+
+ if ($key === '') {
+ throw new InvalidArgument('Cache key length must be greater than zero.');
+ }
+
+ if (strpbrk($key, self::RESERVED_CHARACTERS) !== false) {
+ throw new InvalidArgument(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS));
+ }
+
+ return true;
+ }
+
+ /**
+ * @param mixed[] $keys
+ */
+ private static function validKeys(array $keys): bool
+ {
+ foreach ($keys as $key) {
+ self::validKey($key);
+ }
+
+ return true;
+ }
+
+ /**
+ * @param mixed[] $keys
+ */
+ private function doDeleteMultiple(array $keys): bool
+ {
+ if ($this->cache instanceof MultiDeleteCache) {
+ return $this->cache->deleteMultiple($keys);
+ }
+
+ $success = true;
+ foreach ($keys as $key) {
+ $success = $this->cache->delete($key) && $success;
+ }
+
+ return $success;
+ }
+
+ /**
+ * @param mixed[] $keys
+ *
+ * @return mixed[]
+ */
+ private function doFetchMultiple(array $keys): array
+ {
+ if ($this->cache instanceof MultiGetCache) {
+ return $this->cache->fetchMultiple($keys);
+ }
+
+ $values = [];
+ foreach ($keys as $key) {
+ $value = $this->cache->fetch($key);
+ if (! $value) {
+ continue;
+ }
+
+ $values[$key] = $value;
+ }
+
+ return $values;
+ }
+
+ /**
+ * @param mixed[] $keysAndValues
+ */
+ private function doSaveMultiple(array $keysAndValues, int $lifetime = 0): bool
+ {
+ if ($this->cache instanceof MultiPutCache) {
+ return $this->cache->saveMultiple($keysAndValues, $lifetime);
+ }
+
+ $success = true;
+ foreach ($keysAndValues as $key => $value) {
+ $success = $this->cache->save($key, $value, $lifetime) && $success;
+ }
+
+ return $success;
+ }
+}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php
new file mode 100644
index 00000000..0b6f0a28
--- /dev/null
+++ b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php
@@ -0,0 +1,118 @@
+<?php
+
+namespace Doctrine\Common\Cache\Psr6;
+
+use DateInterval;
+use DateTime;
+use DateTimeInterface;
+use Psr\Cache\CacheItemInterface;
+use TypeError;
+
+use function get_class;
+use function gettype;
+use function is_int;
+use function is_object;
+use function microtime;
+use function sprintf;
+
+final class CacheItem implements CacheItemInterface
+{
+ /** @var string */
+ private $key;
+ /** @var mixed */
+ private $value;
+ /** @var bool */
+ private $isHit;
+ /** @var float|null */
+ private $expiry;
+
+ /**
+ * @internal
+ *
+ * @param mixed $data
+ */
+ public function __construct(string $key, $data, bool $isHit)
+ {
+ $this->key = $key;
+ $this->value = $data;
+ $this->isHit = $isHit;
+ }
+
+ public function getKey(): string
+ {
+ return $this->key;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return mixed
+ */
+ public function get()
+ {
+ return $this->value;
+ }
+
+ public function isHit(): bool
+ {
+ return $this->isHit;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function set($value): self
+ {
+ $this->value = $value;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function expiresAt($expiration): self
+ {
+ if ($expiration === null) {
+ $this->expiry = null;
+ } elseif ($expiration instanceof DateTimeInterface) {
+ $this->expiry = (float) $expiration->format('U.u');
+ } else {
+ throw new TypeError(sprintf(
+ 'Expected $expiration to be an instance of DateTimeInterface or null, got %s',
+ is_object($expiration) ? get_class($expiration) : gettype($expiration)
+ ));
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function expiresAfter($time): self
+ {
+ if ($time === null) {
+ $this->expiry = null;
+ } elseif ($time instanceof DateInterval) {
+ $this->expiry = microtime(true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
+ } elseif (is_int($time)) {
+ $this->expiry = $time + microtime(true);
+ } else {
+ throw new TypeError(sprintf(
+ 'Expected $time to be either an integer, an instance of DateInterval or null, got %s',
+ is_object($time) ? get_class($time) : gettype($time)
+ ));
+ }
+
+ return $this;
+ }
+
+ /**
+ * @internal
+ */
+ public function getExpiry(): ?float
+ {
+ return $this->expiry;
+ }
+}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php
new file mode 100644
index 00000000..c15497e5
--- /dev/null
+++ b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php
@@ -0,0 +1,125 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Doctrine\Common\Cache\Psr6;
+
+use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Cache\CacheProvider;
+use Psr\Cache\CacheItemPoolInterface;
+use Symfony\Component\Cache\Adapter\DoctrineAdapter as SymfonyDoctrineAdapter;
+
+use function rawurlencode;
+
+/**
+ * This class was copied from the Symfony Framework, see the original copyright
+ * notice above. The code is distributed subject to the license terms in
+ * https://github.com/symfony/symfony/blob/ff0cf61278982539c49e467db9ab13cbd342f76d/LICENSE
+ */
+final class DoctrineProvider extends CacheProvider
+{
+ /** @var CacheItemPoolInterface */
+ private $pool;
+
+ public static function wrap(CacheItemPoolInterface $pool): Cache
+ {
+ if ($pool instanceof CacheAdapter) {
+ return $pool->getCache();
+ }
+
+ if ($pool instanceof SymfonyDoctrineAdapter) {
+ $getCache = function () {
+ // phpcs:ignore Squiz.Scope.StaticThisUsage.Found
+ return $this->provider;
+ };
+
+ return $getCache->bindTo($pool, SymfonyDoctrineAdapter::class)();
+ }
+
+ return new self($pool);
+ }
+
+ private function __construct(CacheItemPoolInterface $pool)
+ {
+ $this->pool = $pool;
+ }
+
+ /** @internal */
+ public function getPool(): CacheItemPoolInterface
+ {
+ return $this->pool;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doFetch($id)
+ {
+ $item = $this->pool->getItem(rawurlencode($id));
+
+ return $item->isHit() ? $item->get() : false;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ protected function doContains($id)
+ {
+ return $this->pool->hasItem(rawurlencode($id));
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ protected function doSave($id, $data, $lifeTime = 0)
+ {
+ $item = $this->pool->getItem(rawurlencode($id));
+
+ if (0 < $lifeTime) {
+ $item->expiresAfter($lifeTime);
+ }
+
+ return $this->pool->save($item->set($data));
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ protected function doDelete($id)
+ {
+ return $this->pool->deleteItem(rawurlencode($id));
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return bool
+ */
+ protected function doFlush()
+ {
+ return $this->pool->clear();
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @return array|null
+ */
+ protected function doGetStats()
+ {
+ return null;
+ }
+}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php
new file mode 100644
index 00000000..196f1bca
--- /dev/null
+++ b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Doctrine\Common\Cache\Psr6;
+
+use InvalidArgumentException;
+use Psr\Cache\InvalidArgumentException as PsrInvalidArgumentException;
+
+/**
+ * @internal
+ */
+final class InvalidArgument extends InvalidArgumentException implements PsrInvalidArgumentException
+{
+}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php
new file mode 100644
index 00000000..60f37967
--- /dev/null
+++ b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace Doctrine\Common\Cache\Psr6;
+
+use DateInterval;
+use DateTime;
+use DateTimeInterface;
+use Psr\Cache\CacheItemInterface;
+use TypeError;
+
+use function get_debug_type;
+use function is_int;
+use function microtime;
+use function sprintf;
+
+final class TypedCacheItem implements CacheItemInterface
+{
+ private ?float $expiry = null;
+
+ /**
+ * @internal
+ */
+ public function __construct(
+ private string $key,
+ private mixed $value,
+ private bool $isHit,
+ ) {
+ }
+
+ public function getKey(): string
+ {
+ return $this->key;
+ }
+
+ public function get(): mixed
+ {
+ return $this->value;
+ }
+
+ public function isHit(): bool
+ {
+ return $this->isHit;
+ }
+
+ public function set(mixed $value): static
+ {
+ $this->value = $value;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function expiresAt($expiration): static
+ {
+ if ($expiration === null) {
+ $this->expiry = null;
+ } elseif ($expiration instanceof DateTimeInterface) {
+ $this->expiry = (float) $expiration->format('U.u');
+ } else {
+ throw new TypeError(sprintf(
+ 'Expected $expiration to be an instance of DateTimeInterface or null, got %s',
+ get_debug_type($expiration)
+ ));
+ }
+
+ return $this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function expiresAfter($time): static
+ {
+ if ($time === null) {
+ $this->expiry = null;
+ } elseif ($time instanceof DateInterval) {
+ $this->expiry = microtime(true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
+ } elseif (is_int($time)) {
+ $this->expiry = $time + microtime(true);
+ } else {
+ throw new TypeError(sprintf(
+ 'Expected $time to be either an integer, an instance of DateInterval or null, got %s',
+ get_debug_type($time)
+ ));
+ }
+
+ return $this;
+ }
+
+ /**
+ * @internal
+ */
+ public function getExpiry(): ?float
+ {
+ return $this->expiry;
+ }
+}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php
deleted file mode 100644
index 32457058..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php
+++ /dev/null
@@ -1,181 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use Redis;
-use function array_combine;
-use function array_diff_key;
-use function array_fill_keys;
-use function array_filter;
-use function array_keys;
-use function count;
-use function defined;
-use function extension_loaded;
-use function is_bool;
-
-/**
- * Redis cache provider.
- *
- * @link www.doctrine-project.org
- */
-class RedisCache extends CacheProvider
-{
- /** @var Redis|null */
- private $redis;
-
- /**
- * Sets the redis instance to use.
- *
- * @return void
- */
- public function setRedis(Redis $redis)
- {
- $redis->setOption(Redis::OPT_SERIALIZER, $this->getSerializerValue());
- $this->redis = $redis;
- }
-
- /**
- * Gets the redis instance used by the cache.
- *
- * @return Redis|null
- */
- public function getRedis()
- {
- return $this->redis;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- return $this->redis->get($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetchMultiple(array $keys)
- {
- $fetchedItems = array_combine($keys, $this->redis->mget($keys));
-
- // Redis mget returns false for keys that do not exist. So we need to filter those out unless it's the real data.
- $keysToFilter = array_keys(array_filter($fetchedItems, static function ($item) : bool {
- return $item === false;
- }));
-
- if ($keysToFilter) {
- $multi = $this->redis->multi(Redis::PIPELINE);
- foreach ($keysToFilter as $key) {
- $multi->exists($key);
- }
- $existItems = array_filter($multi->exec());
- $missedItemKeys = array_diff_key($keysToFilter, $existItems);
- $fetchedItems = array_diff_key($fetchedItems, array_fill_keys($missedItemKeys, true));
- }
-
- return $fetchedItems;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
- {
- if ($lifetime) {
- // Keys have lifetime, use SETEX for each of them
- $multi = $this->redis->multi(Redis::PIPELINE);
- foreach ($keysAndValues as $key => $value) {
- $multi->setex($key, $lifetime, $value);
- }
- $succeeded = array_filter($multi->exec());
-
- return count($succeeded) == count($keysAndValues);
- }
-
- // No lifetime, use MSET
- return (bool) $this->redis->mset($keysAndValues);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- $exists = $this->redis->exists($id);
-
- if (is_bool($exists)) {
- return $exists;
- }
-
- return $exists > 0;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- if ($lifeTime > 0) {
- return $this->redis->setex($id, $lifeTime, $data);
- }
-
- return $this->redis->set($id, $data);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- return $this->redis->del($id) >= 0;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDeleteMultiple(array $keys)
- {
- return $this->redis->del($keys) >= 0;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- return $this->redis->flushDB();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $info = $this->redis->info();
-
- return [
- Cache::STATS_HITS => $info['keyspace_hits'],
- Cache::STATS_MISSES => $info['keyspace_misses'],
- Cache::STATS_UPTIME => $info['uptime_in_seconds'],
- Cache::STATS_MEMORY_USAGE => $info['used_memory'],
- Cache::STATS_MEMORY_AVAILABLE => false,
- ];
- }
-
- /**
- * Returns the serializer constant to use. If Redis is compiled with
- * igbinary support, that is used. Otherwise the default PHP serializer is
- * used.
- *
- * @return int One of the Redis::SERIALIZER_* constants
- */
- protected function getSerializerValue()
- {
- if (defined('Redis::SERIALIZER_IGBINARY') && extension_loaded('igbinary')) {
- return Redis::SERIALIZER_IGBINARY;
- }
-
- return Redis::SERIALIZER_PHP;
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php b/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php
deleted file mode 100644
index 56deb077..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php
+++ /dev/null
@@ -1,206 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use SQLite3;
-use SQLite3Result;
-use const SQLITE3_ASSOC;
-use const SQLITE3_BLOB;
-use const SQLITE3_TEXT;
-use function array_search;
-use function implode;
-use function serialize;
-use function sprintf;
-use function time;
-use function unserialize;
-
-/**
- * SQLite3 cache provider.
- */
-class SQLite3Cache extends CacheProvider
-{
- /**
- * The ID field will store the cache key.
- */
- public const ID_FIELD = 'k';
-
- /**
- * The data field will store the serialized PHP value.
- */
- public const DATA_FIELD = 'd';
-
- /**
- * The expiration field will store a date value indicating when the
- * cache entry should expire.
- */
- public const EXPIRATION_FIELD = 'e';
-
- /** @var SQLite3 */
- private $sqlite;
-
- /** @var string */
- private $table;
-
- /**
- * Calling the constructor will ensure that the database file and table
- * exist and will create both if they don't.
- *
- * @param string $table
- */
- public function __construct(SQLite3 $sqlite, $table)
- {
- $this->sqlite = $sqlite;
- $this->table = (string) $table;
-
- $this->ensureTableExists();
- }
-
- private function ensureTableExists() : void
- {
- $this->sqlite->exec(
- sprintf(
- 'CREATE TABLE IF NOT EXISTS %s(%s TEXT PRIMARY KEY NOT NULL, %s BLOB, %s INTEGER)',
- $this->table,
- static::ID_FIELD,
- static::DATA_FIELD,
- static::EXPIRATION_FIELD
- )
- );
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- $item = $this->findById($id);
-
- if (! $item) {
- return false;
- }
-
- return unserialize($item[self::DATA_FIELD]);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- return $this->findById($id, false) !== null;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- $statement = $this->sqlite->prepare(sprintf(
- 'INSERT OR REPLACE INTO %s (%s) VALUES (:id, :data, :expire)',
- $this->table,
- implode(',', $this->getFields())
- ));
-
- $statement->bindValue(':id', $id);
- $statement->bindValue(':data', serialize($data), SQLITE3_BLOB);
- $statement->bindValue(':expire', $lifeTime > 0 ? time() + $lifeTime : null);
-
- return $statement->execute() instanceof SQLite3Result;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- [$idField] = $this->getFields();
-
- $statement = $this->sqlite->prepare(sprintf(
- 'DELETE FROM %s WHERE %s = :id',
- $this->table,
- $idField
- ));
-
- $statement->bindValue(':id', $id);
-
- return $statement->execute() instanceof SQLite3Result;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- return $this->sqlite->exec(sprintf('DELETE FROM %s', $this->table));
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- // no-op.
- }
-
- /**
- * Find a single row by ID.
- *
- * @param mixed $id
- *
- * @return array|null
- */
- private function findById($id, bool $includeData = true) : ?array
- {
- [$idField] = $fields = $this->getFields();
-
- if (! $includeData) {
- $key = array_search(static::DATA_FIELD, $fields);
- unset($fields[$key]);
- }
-
- $statement = $this->sqlite->prepare(sprintf(
- 'SELECT %s FROM %s WHERE %s = :id LIMIT 1',
- implode(',', $fields),
- $this->table,
- $idField
- ));
-
- $statement->bindValue(':id', $id, SQLITE3_TEXT);
-
- $item = $statement->execute()->fetchArray(SQLITE3_ASSOC);
-
- if ($item === false) {
- return null;
- }
-
- if ($this->isExpired($item)) {
- $this->doDelete($id);
-
- return null;
- }
-
- return $item;
- }
-
- /**
- * Gets an array of the fields in our table.
- *
- * @return array
- */
- private function getFields() : array
- {
- return [static::ID_FIELD, static::DATA_FIELD, static::EXPIRATION_FIELD];
- }
-
- /**
- * Check if the item is expired.
- *
- * @param array $item
- */
- private function isExpired(array $item) : bool
- {
- return isset($item[static::EXPIRATION_FIELD]) &&
- $item[self::EXPIRATION_FIELD] !== null &&
- $item[self::EXPIRATION_FIELD] < time();
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/Version.php b/doctrine/cache/lib/Doctrine/Common/Cache/Version.php
deleted file mode 100644
index 834b5b7d..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/Version.php
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-class Version
-{
- public const VERSION = '1.9.0-DEV';
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php
deleted file mode 100644
index b58f613a..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-/**
- * Void cache driver. The cache could be of use in tests where you don`t need to cache anything.
- *
- * @link www.doctrine-project.org
- */
-class VoidCache extends CacheProvider
-{
- /**
- * {@inheritDoc}
- */
- protected function doFetch($id)
- {
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doContains($id)
- {
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doDelete($id)
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doFlush()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doGetStats()
- {
- return;
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php
deleted file mode 100644
index 972f92f9..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use function count;
-use function is_array;
-use function wincache_ucache_clear;
-use function wincache_ucache_delete;
-use function wincache_ucache_exists;
-use function wincache_ucache_get;
-use function wincache_ucache_info;
-use function wincache_ucache_meminfo;
-use function wincache_ucache_set;
-
-/**
- * WinCache cache provider.
- *
- * @link www.doctrine-project.org
- */
-class WinCacheCache extends CacheProvider
-{
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- return wincache_ucache_get($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- return wincache_ucache_exists($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- return wincache_ucache_set($id, $data, $lifeTime);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- return wincache_ucache_delete($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- return wincache_ucache_clear();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFetchMultiple(array $keys)
- {
- return wincache_ucache_get($keys);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
- {
- $result = wincache_ucache_set($keysAndValues, null, $lifetime);
-
- return empty($result);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDeleteMultiple(array $keys)
- {
- $result = wincache_ucache_delete($keys);
-
- return is_array($result) && count($result) !== count($keys);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $info = wincache_ucache_info();
- $meminfo = wincache_ucache_meminfo();
-
- return [
- Cache::STATS_HITS => $info['total_hit_count'],
- Cache::STATS_MISSES => $info['total_miss_count'],
- Cache::STATS_UPTIME => $info['total_cache_uptime'],
- Cache::STATS_MEMORY_USAGE => $meminfo['memory_total'],
- Cache::STATS_MEMORY_AVAILABLE => $meminfo['memory_free'],
- ];
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php
deleted file mode 100644
index 9b3a485e..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php
+++ /dev/null
@@ -1,104 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use BadMethodCallException;
-use const XC_TYPE_VAR;
-use function ini_get;
-use function serialize;
-use function unserialize;
-use function xcache_clear_cache;
-use function xcache_get;
-use function xcache_info;
-use function xcache_isset;
-use function xcache_set;
-use function xcache_unset;
-
-/**
- * Xcache cache driver.
- *
- * @deprecated
- *
- * @link www.doctrine-project.org
- */
-class XcacheCache extends CacheProvider
-{
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- return $this->doContains($id) ? unserialize(xcache_get($id)) : false;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- return xcache_isset($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- return xcache_set($id, serialize($data), (int) $lifeTime);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- return xcache_unset($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- $this->checkAuthorization();
-
- xcache_clear_cache(XC_TYPE_VAR);
-
- return true;
- }
-
- /**
- * Checks that xcache.admin.enable_auth is Off.
- *
- * @return void
- *
- * @throws BadMethodCallException When xcache.admin.enable_auth is On.
- */
- protected function checkAuthorization()
- {
- if (ini_get('xcache.admin.enable_auth')) {
- throw new BadMethodCallException(
- 'To use all features of \Doctrine\Common\Cache\XcacheCache, '
- . 'you must set "xcache.admin.enable_auth" to "Off" in your php.ini.'
- );
- }
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- $this->checkAuthorization();
-
- $info = xcache_info(XC_TYPE_VAR, 0);
-
- return [
- Cache::STATS_HITS => $info['hits'],
- Cache::STATS_MISSES => $info['misses'],
- Cache::STATS_UPTIME => null,
- Cache::STATS_MEMORY_USAGE => $info['size'],
- Cache::STATS_MEMORY_AVAILABLE => $info['avail'],
- ];
- }
-}
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php b/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php
deleted file mode 100644
index a6b67ef8..00000000
--- a/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-
-namespace Doctrine\Common\Cache;
-
-use function zend_shm_cache_clear;
-use function zend_shm_cache_delete;
-use function zend_shm_cache_fetch;
-use function zend_shm_cache_store;
-
-/**
- * Zend Data Cache cache driver.
- *
- * @link www.doctrine-project.org
- */
-class ZendDataCache extends CacheProvider
-{
- /**
- * {@inheritdoc}
- */
- protected function doFetch($id)
- {
- return zend_shm_cache_fetch($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doContains($id)
- {
- return zend_shm_cache_fetch($id) !== false;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doSave($id, $data, $lifeTime = 0)
- {
- return zend_shm_cache_store($id, $data, $lifeTime);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doDelete($id)
- {
- return zend_shm_cache_delete($id);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doFlush()
- {
- $namespace = $this->getNamespace();
- if (empty($namespace)) {
- return zend_shm_cache_clear();
- }
-
- return zend_shm_cache_clear($namespace);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function doGetStats()
- {
- return null;
- }
-}
diff --git a/doctrine/dbal/README.md b/doctrine/dbal/README.md
index 259f7c62..43caa5a5 100644
--- a/doctrine/dbal/README.md
+++ b/doctrine/dbal/README.md
@@ -1,11 +1,11 @@
# Doctrine DBAL
-| [Master][Master] | [2.12][2.12] |
-|:----------------:|:----------:|
-| [![Build status][Master image]][Master] | [![Build status][2.12 image]][2.12] |
-| [![GitHub Actions][GA master image]][GA master] | [![GitHub Actions][GA 2.12 image]][GA 2.12] |
-| [![AppVeyor][AppVeyor master image]][AppVeyor master] | [![AppVeyor][AppVeyor 2.12 image]][AppVeyor 2.12] |
-| [![Code Coverage][Coverage image]][CodeCov Master] | [![Code Coverage][Coverage 2.12 image]][CodeCov 2.12] |
+| [4.0-dev][4.0] | [3.1][3.1] | [2.13][2.13] |
+|:----------------:|:----------:|:----------:|
+| [![GitHub Actions][GA 4.0 image]][GA 4.0] | [![GitHub Actions][GA 3.1 image]][GA 3.1] | [![GitHub Actions][GA 2.13 image]][GA 2.13] |
+| [![AppVeyor][AppVeyor 4.0 image]][AppVeyor 4.0] | [![AppVeyor][AppVeyor 3.1 image]][AppVeyor 3.1] | [![AppVeyor][AppVeyor 2.13 image]][AppVeyor 2.13] |
+| [![Code Coverage][Coverage image]][CodeCov 4.0] | [![Code Coverage][Coverage 3.1 image]][CodeCov 3.1] | [![Code Coverage][Coverage 2.13 image]][CodeCov 2.13] |
+| N/A | [![Code Coverage][TypeCov 3.1 image]][TypeCov 3.1] | N/A |
Powerful database abstraction layer with many features for database schema introspection, schema management and PDO abstraction.
@@ -15,20 +15,28 @@ Powerful database abstraction layer with many features for database schema intro
* [Documentation](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/)
* [Issue Tracker](https://github.com/doctrine/dbal/issues)
- [Master image]: https://img.shields.io/travis/doctrine/dbal/master.svg?style=flat-square
- [Coverage image]: https://codecov.io/gh/doctrine/dbal/branch/master/graph/badge.svg
- [Master]: https://travis-ci.org/doctrine/dbal
- [CodeCov Master]: https://codecov.io/gh/doctrine/dbal/branch/master
- [AppVeyor master]: https://ci.appveyor.com/project/doctrine/dbal/branch/master
- [AppVeyor master image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/master?svg=true
- [GA master]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3Amaster
- [GA master image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg
+ [Coverage image]: https://codecov.io/gh/doctrine/dbal/branch/4.0.x/graph/badge.svg
+ [4.0]: https://github.com/doctrine/dbal/tree/4.0.x
+ [CodeCov 4.0]: https://codecov.io/gh/doctrine/dbal/branch/4.0.x
+ [AppVeyor 4.0]: https://ci.appveyor.com/project/doctrine/dbal/branch/4.0.x
+ [AppVeyor 4.0 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/4.0.x?svg=true
+ [GA 4.0]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A4.0.x
+ [GA 4.0 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg
- [2.12 image]: https://img.shields.io/travis/doctrine/dbal/2.12.x.svg?style=flat-square
- [Coverage 2.12 image]: https://codecov.io/gh/doctrine/dbal/branch/2.12.x/graph/badge.svg
- [2.12]: https://github.com/doctrine/dbal/tree/2.12.x
- [CodeCov 2.12]: https://codecov.io/gh/doctrine/dbal/branch/2.12.x
- [AppVeyor 2.12]: https://ci.appveyor.com/project/doctrine/dbal/branch/2.12.x
- [AppVeyor 2.12 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/2.12.x?svg=true
- [GA 2.12]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A2.12.x
- [GA 2.12 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=2.12.x
+ [Coverage 3.1 image]: https://codecov.io/gh/doctrine/dbal/branch/3.1.x/graph/badge.svg
+ [3.1]: https://github.com/doctrine/dbal/tree/3.1.x
+ [CodeCov 3.1]: https://codecov.io/gh/doctrine/dbal/branch/3.1.x
+ [AppVeyor 3.1]: https://ci.appveyor.com/project/doctrine/dbal/branch/3.1.x
+ [AppVeyor 3.1 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/3.1.x?svg=true
+ [GA 3.1]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A3.1.x
+ [GA 3.1 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=3.1.x
+
+ [Coverage 2.13 image]: https://codecov.io/gh/doctrine/dbal/branch/2.13.x/graph/badge.svg
+ [2.13]: https://github.com/doctrine/dbal/tree/2.13.x
+ [CodeCov 2.13]: https://codecov.io/gh/doctrine/dbal/branch/2.13.x
+ [AppVeyor 2.13]: https://ci.appveyor.com/project/doctrine/dbal/branch/2.13.x
+ [AppVeyor 2.13 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/2.13.x?svg=true
+ [GA 2.13]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A2.13.x
+ [GA 2.13 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=2.13.x
+ [TypeCov 3.1]: https://shepherd.dev/github/doctrine/dbal
+ [TypeCov 3.1 image]: https://shepherd.dev/github/doctrine/dbal/coverage.svg
diff --git a/doctrine/dbal/composer.json b/doctrine/dbal/composer.json
index 09095660..013b6b8d 100644
--- a/doctrine/dbal/composer.json
+++ b/doctrine/dbal/composer.json
@@ -33,27 +33,27 @@
"require": {
"php": "^7.3 || ^8.0",
"composer/package-versions-deprecated": "^1.11.99",
- "doctrine/cache": "^1.0",
+ "doctrine/cache": "^1.0|^2.0",
+ "doctrine/deprecations": "^0.5.3",
"doctrine/event-manager": "^1.0"
},
"require-dev": {
- "doctrine/coding-standard": "^8.1",
- "jetbrains/phpstorm-stubs": "^2019.1",
- "phpstan/phpstan": "^0.12.40",
- "phpstan/phpstan-strict-rules": "^0.12.2",
- "phpunit/phpunit": "^9.4",
- "psalm/plugin-phpunit": "^0.10.0",
- "symfony/console": "^2.0.5|^3.0|^4.0|^5.0",
- "vimeo/psalm": "^3.17.2"
+ "doctrine/coding-standard": "9.0.0",
+ "jetbrains/phpstorm-stubs": "2021.1",
+ "phpstan/phpstan": "0.12.99",
+ "phpstan/phpstan-strict-rules": "^0.12.11",
+ "phpunit/phpunit": "9.5.10",
+ "psalm/plugin-phpunit": "0.16.1",
+ "squizlabs/php_codesniffer": "3.6.0",
+ "symfony/cache": "^5.2|^6.0",
+ "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.0",
+ "vimeo/psalm": "4.10.0"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
},
"bin": ["bin/doctrine-dbal"],
"config": {
- "platform": {
- "php": "7.3.0"
- },
"sort-packages": true
},
"autoload": {
@@ -61,10 +61,5 @@
},
"autoload-dev": {
"psr-4": { "Doctrine\\DBAL\\Tests\\": "tests" }
- },
- "extra": {
- "branch-alias": {
- "dev-master": "4.0.x-dev"
- }
}
}
diff --git a/doctrine/dbal/src/Cache/ArrayResult.php b/doctrine/dbal/src/Cache/ArrayResult.php
index f8fa8344..e2dc6e11 100644
--- a/doctrine/dbal/src/Cache/ArrayResult.php
+++ b/doctrine/dbal/src/Cache/ArrayResult.php
@@ -98,10 +98,6 @@ final class ArrayResult implements Result
public function rowCount(): int
{
- if ($this->data === null) {
- return 0;
- }
-
return count($this->data);
}
diff --git a/doctrine/dbal/src/Cache/QueryCacheProfile.php b/doctrine/dbal/src/Cache/QueryCacheProfile.php
index 3d5b814d..44f5868c 100644
--- a/doctrine/dbal/src/Cache/QueryCacheProfile.php
+++ b/doctrine/dbal/src/Cache/QueryCacheProfile.php
@@ -20,7 +20,7 @@ class QueryCacheProfile
private $resultCacheDriver;
/** @var int */
- private $lifetime = 0;
+ private $lifetime;
/** @var string|null */
private $cacheKey;
diff --git a/doctrine/dbal/src/Connection.php b/doctrine/dbal/src/Connection.php
index 9477b54e..46648423 100644
--- a/doctrine/dbal/src/Connection.php
+++ b/doctrine/dbal/src/Connection.php
@@ -21,6 +21,7 @@ use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\SQL\Parser;
use Doctrine\DBAL\Types\Type;
+use Doctrine\Deprecations\Deprecation;
use Throwable;
use Traversable;
@@ -35,6 +36,8 @@ use function key;
/**
* A database abstraction-level connection that implements features like events, transaction isolation levels,
* configuration, emulated transaction nesting, lazy connecting and more.
+ *
+ * @psalm-import-type Params from DriverManager
*/
class Connection
{
@@ -66,7 +69,11 @@ class Connection
/** @var EventManager */
protected $_eventManager;
- /** @var ExpressionBuilder */
+ /**
+ * @deprecated Use {@link createExpressionBuilder()} instead.
+ *
+ * @var ExpressionBuilder
+ */
protected $_expr;
/**
@@ -84,9 +91,9 @@ class Connection
private $transactionNestingLevel = 0;
/**
- * The currently active transaction isolation level.
+ * The currently active transaction isolation level or NULL before it has been determined.
*
- * @var int
+ * @var int|null
*/
private $transactionIsolationLevel;
@@ -100,15 +107,16 @@ class Connection
/**
* The parameters used during creation of the Connection instance.
*
- * @var mixed[]
+ * @var array<string,mixed>
+ * @phpstan-var array<string,mixed>
+ * @psalm-var Params
*/
- private $params = [];
+ private $params;
/**
- * The DatabasePlatform object that provides information about the
- * database platform used by the connection.
+ * The database platform object used by the connection or NULL before it's initialized.
*
- * @var AbstractPlatform
+ * @var AbstractPlatform|null
*/
private $platform;
@@ -121,6 +129,8 @@ class Connection
/**
* The schema manager.
*
+ * @deprecated Use {@link createSchemaManager()} instead.
+ *
* @var AbstractSchemaManager|null
*/
protected $_schemaManager;
@@ -144,10 +154,12 @@ class Connection
*
* @internal The connection can be only instantiated by the driver manager.
*
- * @param mixed[] $params The connection parameters.
- * @param Driver $driver The driver to use.
- * @param Configuration|null $config The configuration, optional.
- * @param EventManager|null $eventManager The event manager, optional.
+ * @param array<string,mixed> $params The connection parameters.
+ * @param Driver $driver The driver to use.
+ * @param Configuration|null $config The configuration, optional.
+ * @param EventManager|null $eventManager The event manager, optional.
+ * @psalm-param Params $params
+ * @phpstan-param array<string,mixed> $params
*
* @throws Exception
*/
@@ -180,7 +192,7 @@ class Connection
$this->_config = $config;
$this->_eventManager = $eventManager;
- $this->_expr = new Query\Expression\ExpressionBuilder($this);
+ $this->_expr = $this->createExpressionBuilder();
$this->autoCommit = $config->getAutoCommit();
}
@@ -190,7 +202,9 @@ class Connection
*
* @internal
*
- * @return mixed[]
+ * @return array<string,mixed>
+ * @psalm-return Params
+ * @phpstan-return array<string,mixed>
*/
public function getParams()
{
@@ -257,19 +271,37 @@ class Connection
public function getDatabasePlatform()
{
if ($this->platform === null) {
- $this->detectDatabasePlatform();
+ $this->platform = $this->detectDatabasePlatform();
+ $this->platform->setEventManager($this->_eventManager);
}
return $this->platform;
}
/**
+ * Creates an expression builder for the connection.
+ */
+ public function createExpressionBuilder(): ExpressionBuilder
+ {
+ return new ExpressionBuilder($this);
+ }
+
+ /**
* Gets the ExpressionBuilder for the connection.
*
+ * @deprecated Use {@link createExpressionBuilder()} instead.
+ *
* @return ExpressionBuilder
*/
public function getExpressionBuilder()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4515',
+ 'Connection::getExpressionBuilder() is deprecated,'
+ . ' use Connection::createExpressionBuilder() instead.'
+ );
+
return $this->_expr;
}
@@ -293,8 +325,6 @@ class Connection
throw $this->convertException($e);
}
- $this->transactionNestingLevel = 0;
-
if ($this->autoCommit === false) {
$this->beginTransaction();
}
@@ -314,19 +344,17 @@ class Connection
*
* @throws Exception If an invalid platform was specified for this connection.
*/
- private function detectDatabasePlatform(): void
+ private function detectDatabasePlatform(): AbstractPlatform
{
$version = $this->getDatabasePlatformVersion();
if ($version !== null) {
assert($this->_driver instanceof VersionAwarePlatformDriver);
- $this->platform = $this->_driver->createDatabasePlatformForVersion($version);
- } else {
- $this->platform = $this->_driver->getDatabasePlatform();
+ return $this->_driver->createDatabasePlatformForVersion($version);
}
- $this->platform->setEventManager($this->_eventManager);
+ return $this->_driver->getDatabasePlatform();
}
/**
@@ -364,23 +392,21 @@ class Connection
// The database to connect to might not yet exist.
// Retry detection without database name connection parameter.
- $databaseName = $this->params['dbname'];
- $this->params['dbname'] = null;
+ $params = $this->params;
+
+ unset($this->params['dbname']);
try {
$this->connect();
} catch (Exception $fallbackException) {
// Either the platform does not support database-less connections
// or something else went wrong.
- // Reset connection parameters and rethrow the original exception.
- $this->params['dbname'] = $databaseName;
-
throw $originalException;
+ } finally {
+ $this->params = $params;
}
- // Reset connection parameters.
- $this->params['dbname'] = $databaseName;
- $serverVersion = $this->getServerVersion();
+ $serverVersion = $this->getServerVersion();
// Close "temporary" connection to allow connecting to the real database again.
$this->close();
@@ -549,10 +575,10 @@ class Connection
/**
* Adds condition based on the criteria to the query components
*
- * @param mixed[] $criteria Map of key columns to their values
- * @param string[] $columns Column names
- * @param mixed[] $values Column values
- * @param string[] $conditions Key conditions
+ * @param array<string,mixed> $criteria Map of key columns to their values
+ * @param string[] $columns Column names
+ * @param mixed[] $values Column values
+ * @param string[] $conditions Key conditions
*
* @throws Exception
*/
@@ -613,7 +639,8 @@ class Connection
*/
public function close()
{
- $this->_conn = null;
+ $this->_conn = null;
+ $this->transactionNestingLevel = 0;
}
/**
@@ -733,7 +760,7 @@ class Connection
{
$typeValues = [];
- foreach ($columnList as $columnIndex => $columnName) {
+ foreach ($columnList as $columnName) {
$typeValues[] = $types[$columnName] ?? ParameterType::STRING;
}
@@ -836,9 +863,9 @@ class Connection
* to the first column and the values being an associative array representing the rest of the columns
* and their values.
*
- * @param string $query SQL query
- * @param list<mixed>|array<string, mixed> $params Query parameters
- * @param array<int, int|string>|array<string, int|string> $types Parameter types
+ * @param string $query SQL query
+ * @param list<mixed>|array<string, mixed> $params Query parameters
+ * @param array<int, int|string|Type|null>|array<string, int|string|Type|null> $types Parameter types
*
* @return array<mixed,array<string,mixed>>
*
@@ -1427,11 +1454,13 @@ class Connection
*/
public function createSavepoint($savepoint)
{
- if (! $this->getDatabasePlatform()->supportsSavepoints()) {
+ $platform = $this->getDatabasePlatform();
+
+ if (! $platform->supportsSavepoints()) {
throw ConnectionException::savepointsNotSupported();
}
- $this->executeStatement($this->platform->createSavePoint($savepoint));
+ $this->executeStatement($platform->createSavePoint($savepoint));
}
/**
@@ -1445,15 +1474,17 @@ class Connection
*/
public function releaseSavepoint($savepoint)
{
- if (! $this->getDatabasePlatform()->supportsSavepoints()) {
+ $platform = $this->getDatabasePlatform();
+
+ if (! $platform->supportsSavepoints()) {
throw ConnectionException::savepointsNotSupported();
}
- if (! $this->platform->supportsReleaseSavepoints()) {
+ if (! $platform->supportsReleaseSavepoints()) {
return;
}
- $this->executeStatement($this->platform->releaseSavePoint($savepoint));
+ $this->executeStatement($platform->releaseSavePoint($savepoint));
}
/**
@@ -1467,11 +1498,13 @@ class Connection
*/
public function rollbackSavepoint($savepoint)
{
- if (! $this->getDatabasePlatform()->supportsSavepoints()) {
+ $platform = $this->getDatabasePlatform();
+
+ if (! $platform->supportsSavepoints()) {
throw ConnectionException::savepointsNotSupported();
}
- $this->executeStatement($this->platform->rollbackSavePoint($savepoint));
+ $this->executeStatement($platform->rollbackSavePoint($savepoint));
}
/**
@@ -1491,20 +1524,39 @@ class Connection
}
/**
+ * Creates a SchemaManager that can be used to inspect or change the
+ * database schema through the connection.
+ *
+ * @throws Exception
+ */
+ public function createSchemaManager(): AbstractSchemaManager
+ {
+ return $this->_driver->getSchemaManager(
+ $this,
+ $this->getDatabasePlatform()
+ );
+ }
+
+ /**
* Gets the SchemaManager that can be used to inspect or change the
* database schema through the connection.
*
+ * @deprecated Use {@link createSchemaManager()} instead.
+ *
* @return AbstractSchemaManager
*
* @throws Exception
*/
public function getSchemaManager()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4515',
+ 'Connection::getSchemaManager() is deprecated, use Connection::createSchemaManager() instead.'
+ );
+
if ($this->_schemaManager === null) {
- $this->_schemaManager = $this->_driver->getSchemaManager(
- $this,
- $this->getDatabasePlatform()
- );
+ $this->_schemaManager = $this->createSchemaManager();
}
return $this->_schemaManager;
diff --git a/doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php b/doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php
index 8d52d859..9d38f904 100644
--- a/doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php
+++ b/doctrine/dbal/src/Connections/PrimaryReadReplicaConnection.php
@@ -8,6 +8,7 @@ use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\Driver\Exception as DriverException;
+use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Event\ConnectionEventArgs;
use Doctrine\DBAL\Events;
use Doctrine\DBAL\Exception;
@@ -56,6 +57,7 @@ use function count;
*
* Instantiation through the DriverManager looks like:
*
+ * @psalm-import-type Params from DriverManager
* @example
*
* $conn = DriverManager::getConnection(array(
@@ -93,7 +95,9 @@ class PrimaryReadReplicaConnection extends Connection
*
* @internal The connection can be only instantiated by the driver manager.
*
- * @param mixed[] $params
+ * @param array<string,mixed> $params
+ * @psalm-param Params $params
+ * @phpstan-param array<string,mixed> $params
*
* @throws Exception
* @throws InvalidArgumentException
@@ -112,9 +116,12 @@ class PrimaryReadReplicaConnection extends Connection
throw new InvalidArgumentException('You have to configure at least one replica.');
}
- $params['primary']['driver'] = $params['driver'];
- foreach ($params['replica'] as $replicaKey => $replica) {
- $params['replica'][$replicaKey]['driver'] = $params['driver'];
+ if (isset($params['driver'])) {
+ $params['primary']['driver'] = $params['driver'];
+
+ foreach ($params['replica'] as $replicaKey => $replica) {
+ $params['replica'][$replicaKey]['driver'] = $params['driver'];
+ }
}
$this->keepReplica = (bool) ($params['keepReplica'] ?? false);
diff --git a/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php b/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php
index 04f58516..9abc0c16 100644
--- a/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php
+++ b/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php
@@ -27,8 +27,8 @@ use Doctrine\DBAL\Query;
final class ExceptionConverter implements ExceptionConverterInterface
{
/**
- * @link https://dev.mysql.com/doc/refman/8.0/en/client-error-reference.html
- * @link https://dev.mysql.com/doc/refman/8.0/en/server-error-reference.html
+ * @link https://dev.mysql.com/doc/mysql-errors/8.0/en/client-error-reference.html
+ * @link https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html
*/
public function convert(Exception $exception, ?Query $query): DriverException
{
diff --git a/doctrine/dbal/src/Driver/IBMDB2/Statement.php b/doctrine/dbal/src/Driver/IBMDB2/Statement.php
index 1820a735..c655ea74 100644
--- a/doctrine/dbal/src/Driver/IBMDB2/Statement.php
+++ b/doctrine/dbal/src/Driver/IBMDB2/Statement.php
@@ -125,7 +125,7 @@ final class Statement implements StatementInterface
$params = [];
- foreach ($this->bindParam as $column => $value) {
+ foreach ($this->bindParam as $value) {
$params[] = $value;
}
}
diff --git a/doctrine/dbal/src/Driver/Mysqli/Connection.php b/doctrine/dbal/src/Driver/Mysqli/Connection.php
index eb964a9e..bec38011 100644
--- a/doctrine/dbal/src/Driver/Mysqli/Connection.php
+++ b/doctrine/dbal/src/Driver/Mysqli/Connection.php
@@ -11,6 +11,7 @@ use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
use mysqli;
+use function assert;
use function floor;
use function mysqli_init;
use function stripos;
@@ -45,6 +46,7 @@ final class Connection implements ServerInfoAwareConnection
iterable $postInitializers = []
) {
$connection = mysqli_init();
+ assert($connection !== false);
foreach ($preInitializers as $initializer) {
$initializer->initialize($connection);
diff --git a/doctrine/dbal/src/Driver/Mysqli/Result.php b/doctrine/dbal/src/Driver/Mysqli/Result.php
index 9d6665e9..11e00f0b 100644
--- a/doctrine/dbal/src/Driver/Mysqli/Result.php
+++ b/doctrine/dbal/src/Driver/Mysqli/Result.php
@@ -131,10 +131,7 @@ final class Result implements ResultInterface
return false;
}
- $row = array_combine($this->columnNames, $values);
- assert(is_array($row));
-
- return $row;
+ return array_combine($this->columnNames, $values);
}
/**
diff --git a/doctrine/dbal/src/Driver/Mysqli/Statement.php b/doctrine/dbal/src/Driver/Mysqli/Statement.php
index b3a5ca87..9f802e11 100644
--- a/doctrine/dbal/src/Driver/Mysqli/Statement.php
+++ b/doctrine/dbal/src/Driver/Mysqli/Statement.php
@@ -43,7 +43,7 @@ final class Statement implements StatementInterface
/** @var mysqli_stmt */
protected $_stmt;
- /** @var mixed[] */
+ /** @var mixed[]|null */
protected $_bindedValues;
/** @var string */
diff --git a/doctrine/dbal/src/Driver/OCI8/Connection.php b/doctrine/dbal/src/Driver/OCI8/Connection.php
index 3921b956..1bc5c62c 100644
--- a/doctrine/dbal/src/Driver/OCI8/Connection.php
+++ b/doctrine/dbal/src/Driver/OCI8/Connection.php
@@ -115,6 +115,8 @@ final class Connection implements ServerInfoAwareConnection
/**
* {@inheritdoc}
*
+ * @param string|null $name
+ *
* @return int|false
*/
public function lastInsertId($name = null)
diff --git a/doctrine/dbal/src/Driver/OCI8/Result.php b/doctrine/dbal/src/Driver/OCI8/Result.php
index 5cbf007a..8f77da75 100644
--- a/doctrine/dbal/src/Driver/OCI8/Result.php
+++ b/doctrine/dbal/src/Driver/OCI8/Result.php
@@ -4,10 +4,13 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Driver\OCI8;
+use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\FetchUtils;
+use Doctrine\DBAL\Driver\OCI8\Exception\Error;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use function oci_cancel;
+use function oci_error;
use function oci_fetch_all;
use function oci_fetch_array;
use function oci_num_fields;
@@ -112,13 +115,18 @@ final class Result implements ResultInterface
/**
* @return mixed|false
+ *
+ * @throws Exception
*/
private function fetch(int $mode)
{
- return oci_fetch_array(
- $this->statement,
- $mode | OCI_RETURN_NULLS | OCI_RETURN_LOBS
- );
+ $result = oci_fetch_array($this->statement, $mode | OCI_RETURN_NULLS | OCI_RETURN_LOBS);
+
+ if ($result === false && oci_error($this->statement) !== false) {
+ throw Error::new($this->statement);
+ }
+
+ return $result;
}
/**
diff --git a/doctrine/dbal/src/Driver/OCI8/Statement.php b/doctrine/dbal/src/Driver/OCI8/Statement.php
index a1621c7e..1f3afda2 100644
--- a/doctrine/dbal/src/Driver/OCI8/Statement.php
+++ b/doctrine/dbal/src/Driver/OCI8/Statement.php
@@ -101,7 +101,7 @@ final class Statement implements StatementInterface
assert($lob !== false);
- $lob->writetemporary($variable, OCI_TEMP_BLOB);
+ $lob->writeTemporary($variable, OCI_TEMP_BLOB);
$variable =& $lob;
}
diff --git a/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php b/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php
index 40cd2446..d2da1625 100644
--- a/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php
+++ b/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php
@@ -6,8 +6,11 @@ use Doctrine\DBAL\Driver\PDO\Statement as PDOStatement;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
+use Doctrine\Deprecations\Deprecation;
use PDO;
+use function func_num_args;
+
final class Statement implements StatementInterface
{
/** @var PDOStatement */
@@ -24,10 +27,22 @@ final class Statement implements StatementInterface
/**
* {@inheritdoc}
*
- * @param mixed $driverOptions
+ * @param string|int $param
+ * @param mixed $variable
+ * @param int $type
+ * @param int|null $length
+ * @param mixed $driverOptions The usage of the argument is deprecated.
*/
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
{
+ if (func_num_args() > 4) {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4533',
+ 'The $driverOptions argument of Statement::bindParam() is deprecated.'
+ );
+ }
+
switch ($type) {
case ParameterType::LARGE_OBJECT:
case ParameterType::BINARY:
diff --git a/doctrine/dbal/src/Driver/PDO/Statement.php b/doctrine/dbal/src/Driver/PDO/Statement.php
index 7107fa2d..1461239e 100644
--- a/doctrine/dbal/src/Driver/PDO/Statement.php
+++ b/doctrine/dbal/src/Driver/PDO/Statement.php
@@ -7,12 +7,14 @@ use Doctrine\DBAL\Driver\Exception\UnknownParameterType;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
+use Doctrine\Deprecations\Deprecation;
use PDO;
use PDOException;
use PDOStatement;
use function array_slice;
use function func_get_args;
+use function func_num_args;
final class Statement implements StatementInterface
{
@@ -58,12 +60,20 @@ final class Statement implements StatementInterface
* @param mixed $variable
* @param int $type
* @param int|null $length
- * @param mixed $driverOptions
+ * @param mixed $driverOptions The usage of the argument is deprecated.
*
* @return bool
*/
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
{
+ if (func_num_args() > 4) {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4533',
+ 'The $driverOptions argument of Statement::bindParam() is deprecated.'
+ );
+ }
+
$type = $this->convertParamType($type);
try {
diff --git a/doctrine/dbal/src/Driver/SQLSrv/Connection.php b/doctrine/dbal/src/Driver/SQLSrv/Connection.php
index 902a1167..e37ea900 100644
--- a/doctrine/dbal/src/Driver/SQLSrv/Connection.php
+++ b/doctrine/dbal/src/Driver/SQLSrv/Connection.php
@@ -27,9 +27,6 @@ final class Connection implements ServerInfoAwareConnection
/** @var resource */
protected $conn;
- /** @var LastInsertId */
- protected $lastInsertId;
-
/**
* @internal The connection can be only instantiated by its driver.
*
@@ -50,8 +47,7 @@ final class Connection implements ServerInfoAwareConnection
throw Error::new();
}
- $this->conn = $conn;
- $this->lastInsertId = new LastInsertId();
+ $this->conn = $conn;
}
/**
@@ -66,7 +62,7 @@ final class Connection implements ServerInfoAwareConnection
public function prepare(string $sql): DriverStatement
{
- return new Statement($this->conn, $sql, $this->lastInsertId);
+ return new Statement($this->conn, $sql);
}
public function query(string $sql): ResultInterface
diff --git a/doctrine/dbal/src/Driver/SQLSrv/LastInsertId.php b/doctrine/dbal/src/Driver/SQLSrv/LastInsertId.php
deleted file mode 100644
index 0948e587..00000000
--- a/doctrine/dbal/src/Driver/SQLSrv/LastInsertId.php
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-
-namespace Doctrine\DBAL\Driver\SQLSrv;
-
-/**
- * Last Id Data Container.
- *
- * @internal
- */
-final class LastInsertId
-{
- /** @var int */
- private $id;
-
- /**
- * @param int $id
- *
- * @return void
- */
- public function setId($id)
- {
- $this->id = $id;
- }
-
- /**
- * @return int
- */
- public function getId()
- {
- return $this->id;
- }
-}
diff --git a/doctrine/dbal/src/Driver/SQLSrv/Result.php b/doctrine/dbal/src/Driver/SQLSrv/Result.php
index 7fe5ca19..0e24002c 100644
--- a/doctrine/dbal/src/Driver/SQLSrv/Result.php
+++ b/doctrine/dbal/src/Driver/SQLSrv/Result.php
@@ -80,10 +80,6 @@ final class Result implements ResultInterface
public function rowCount(): int
{
- if ($this->statement === null) {
- return 0;
- }
-
$count = sqlsrv_rows_affected($this->statement);
if ($count !== false) {
@@ -95,10 +91,6 @@ final class Result implements ResultInterface
public function columnCount(): int
{
- if ($this->statement === null) {
- return 0;
- }
-
$count = sqlsrv_num_fields($this->statement);
if ($count !== false) {
diff --git a/doctrine/dbal/src/Driver/SQLSrv/Statement.php b/doctrine/dbal/src/Driver/SQLSrv/Statement.php
index ba2e29f9..8267bc0d 100644
--- a/doctrine/dbal/src/Driver/SQLSrv/Statement.php
+++ b/doctrine/dbal/src/Driver/SQLSrv/Statement.php
@@ -11,9 +11,6 @@ use Doctrine\DBAL\ParameterType;
use function assert;
use function is_int;
use function sqlsrv_execute;
-use function sqlsrv_fetch;
-use function sqlsrv_get_field;
-use function sqlsrv_next_result;
use function SQLSRV_PHPTYPE_STREAM;
use function SQLSRV_PHPTYPE_STRING;
use function sqlsrv_prepare;
@@ -62,13 +59,6 @@ final class Statement implements StatementInterface
private $types = [];
/**
- * The last insert ID.
- *
- * @var LastInsertId|null
- */
- private $lastInsertId;
-
- /**
* Append to any INSERT query to retrieve the last insert id.
*/
private const LAST_INSERT_ID_SQL = ';SELECT SCOPE_IDENTITY() AS LastInsertId;';
@@ -79,7 +69,7 @@ final class Statement implements StatementInterface
* @param resource $conn
* @param string $sql
*/
- public function __construct($conn, $sql, ?LastInsertId $lastInsertId = null)
+ public function __construct($conn, $sql)
{
$this->conn = $conn;
$this->sql = $sql;
@@ -88,8 +78,7 @@ final class Statement implements StatementInterface
return;
}
- $this->sql .= self::LAST_INSERT_ID_SQL;
- $this->lastInsertId = $lastInsertId;
+ $this->sql .= self::LAST_INSERT_ID_SQL;
}
/**
@@ -144,12 +133,6 @@ final class Statement implements StatementInterface
throw Error::new();
}
- if ($this->lastInsertId !== null) {
- sqlsrv_next_result($this->stmt);
- sqlsrv_fetch($this->stmt);
- $this->lastInsertId->setId(sqlsrv_get_field($this->stmt, 0));
- }
-
return new Result($this->stmt);
}
diff --git a/doctrine/dbal/src/DriverManager.php b/doctrine/dbal/src/DriverManager.php
index dd02fcd7..58a0cc57 100644
--- a/doctrine/dbal/src/DriverManager.php
+++ b/doctrine/dbal/src/DriverManager.php
@@ -25,15 +25,54 @@ use function strpos;
use function substr;
/**
- * Factory for creating Doctrine\DBAL\Connection instances.
+ * Factory for creating {@link Connection} instances.
+ *
+ * @psalm-type OverrideParams = array{
+ * charset?: string,
+ * dbname?: string,
+ * default_dbname?: string,
+ * driver?: key-of<self::DRIVER_MAP>,
+ * driverClass?: class-string<Driver>,
+ * driverOptions?: array<mixed>,
+ * host?: string,
+ * password?: string,
+ * path?: string,
+ * pdo?: \PDO,
+ * platform?: Platforms\AbstractPlatform,
+ * port?: int,
+ * user?: string,
+ * }
+ * @psalm-type Params = array{
+ * charset?: string,
+ * dbname?: string,
+ * default_dbname?: string,
+ * driver?: key-of<self::DRIVER_MAP>,
+ * driverClass?: class-string<Driver>,
+ * driverOptions?: array<mixed>,
+ * host?: string,
+ * keepSlave?: bool,
+ * keepReplica?: bool,
+ * master?: OverrideParams,
+ * memory?: bool,
+ * password?: string,
+ * path?: string,
+ * pdo?: \PDO,
+ * platform?: Platforms\AbstractPlatform,
+ * port?: int,
+ * primary?: OverrideParams,
+ * replica?: array<OverrideParams>,
+ * sharding?: array<string,mixed>,
+ * slaves?: array<OverrideParams>,
+ * user?: string,
+ * wrapperClass?: class-string<Connection>,
+ * }
*/
final class DriverManager
{
/**
* List of supported drivers and their mappings to the driver classes.
*
- * To add your own driver use the 'driverClass' parameter to
- * {@link DriverManager::getConnection()}.
+ * To add your own driver use the 'driverClass' parameter to {@link DriverManager::getConnection()}.
*/
private const DRIVER_MAP = [
'pdo_mysql' => PDO\MySQL\Driver::class,
@@ -103,13 +142,39 @@ final class DriverManager
* <b>driverClass</b>:
* The driver class to use.
*
- * @param array{wrapperClass?: class-string<T>} $params
- * @param Configuration|null $config The configuration to use.
- * @param EventManager|null $eventManager The event manager to use.
+ * @param array<string,mixed> $params
+ * @param Configuration|null $config The configuration to use.
+ * @param EventManager|null $eventManager The event manager to use.
+ * @psalm-param array{
+ * charset?: string,
+ * dbname?: string,
+ * default_dbname?: string,
+ * driver?: key-of<self::DRIVER_MAP>,
+ * driverClass?: class-string<Driver>,
+ * driverOptions?: array<mixed>,
+ * host?: string,
+ * keepSlave?: bool,
+ * keepReplica?: bool,
+ * master?: OverrideParams,
+ * memory?: bool,
+ * password?: string,
+ * path?: string,
+ * pdo?: \PDO,
+ * platform?: Platforms\AbstractPlatform,
+ * port?: int,
+ * primary?: OverrideParams,
+ * replica?: array<OverrideParams>,
+ * sharding?: array<string,mixed>,
+ * slaves?: array<OverrideParams>,
+ * user?: string,
+ * wrapperClass?: class-string<T>,
+ * } $params
+ * @phpstan-param array<string,mixed> $params
+ *
+ * @psalm-return ($params is array{wrapperClass:mixed} ? T : Connection)
*
* @throws Exception
*
- * @psalm-return ($params is array{wrapperClass:mixed} ? T : Connection)
* @template T of Connection
*/
public static function getConnection(
@@ -139,24 +204,7 @@ final class DriverManager
}
}
- if (isset($params['driverClass'])) {
- if (! in_array(Driver::class, class_implements($params['driverClass']), true)) {
- throw Exception::invalidDriverClass($params['driverClass']);
- }
-
- /** @var class-string<Driver> $driverClass */
- $driverClass = $params['driverClass'];
- } elseif (isset($params['driver'])) {
- if (! isset(self::DRIVER_MAP[$params['driver']])) {
- throw Exception::unknownDriver($params['driver'], array_keys(self::DRIVER_MAP));
- }
-
- $driverClass = self::DRIVER_MAP[$params['driver']];
- } else {
- throw Exception::driverRequired();
- }
-
- $driver = new $driverClass();
+ $driver = self::createDriver($params);
foreach ($config->getMiddlewares() as $middleware) {
$driver = $middleware->wrap($driver);
@@ -186,6 +234,38 @@ final class DriverManager
}
/**
+ * @param array<string,mixed> $params
+ * @psalm-param Params $params
+ * @phpstan-param array<string,mixed> $params
+ *
+ * @throws Exception
+ */
+ private static function createDriver(array $params): Driver
+ {
+ if (isset($params['driverClass'])) {
+ $interfaces = class_implements($params['driverClass']);
+
+ if ($interfaces === false || ! in_array(Driver::class, $interfaces, true)) {
+ throw Exception::invalidDriverClass($params['driverClass']);
+ }
+
+ return new $params['driverClass']();
+ }
+
+ if (isset($params['driver'])) {
+ if (! isset(self::DRIVER_MAP[$params['driver']])) {
+ throw Exception::unknownDriver($params['driver'], array_keys(self::DRIVER_MAP));
+ }
+
+ $class = self::DRIVER_MAP[$params['driver']];
+
+ return new $class();
+ }
+
+ throw Exception::driverRequired();
+ }
+
+ /**
* Normalizes the given connection URL path.
*
* @return string The normalized connection URL path
@@ -201,9 +281,13 @@ final class DriverManager
* updated list of parameters.
*
* @param mixed[] $params The list of parameters.
+ * @psalm-param Params $params
+ * @phpstan-param array<string,mixed> $params
*
* @return mixed[] A modified list of parameters with info from a database
* URL extracted into indidivual parameter parts.
+ * @psalm-return Params
+ * @phpstan-return array<string,mixed>
*
* @throws Exception
*/
diff --git a/doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php b/doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php
index 30a1a9ca..e61a48d0 100644
--- a/doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php
+++ b/doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php
@@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Event;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\TableDiff;
+use Doctrine\Deprecations\Deprecation;
use function array_merge;
use function func_get_args;
@@ -67,6 +68,15 @@ class SchemaAlterTableAddColumnEventArgs extends SchemaEventArgs
*/
public function addSql($sql)
{
+ if (is_array($sql)) {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3580',
+ 'Passing multiple SQL statements as an array to SchemaAlterTableAddColumnEventaArrgs::addSql() ' .
+ 'is deprecated. Pass each statement as an individual argument instead.'
+ );
+ }
+
$this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args());
return $this;
diff --git a/doctrine/dbal/src/Logging/LoggerChain.php b/doctrine/dbal/src/Logging/LoggerChain.php
index 27b8516e..9b44dc0e 100644
--- a/doctrine/dbal/src/Logging/LoggerChain.php
+++ b/doctrine/dbal/src/Logging/LoggerChain.php
@@ -8,7 +8,7 @@ namespace Doctrine\DBAL\Logging;
class LoggerChain implements SQLLogger
{
/** @var iterable<SQLLogger> */
- private $loggers = [];
+ private $loggers;
/**
* @param iterable<SQLLogger> $loggers
diff --git a/doctrine/dbal/src/Platforms/AbstractPlatform.php b/doctrine/dbal/src/Platforms/AbstractPlatform.php
index 042fae29..e7f0819b 100644
--- a/doctrine/dbal/src/Platforms/AbstractPlatform.php
+++ b/doctrine/dbal/src/Platforms/AbstractPlatform.php
@@ -30,6 +30,7 @@ use Doctrine\DBAL\SQL\Parser;
use Doctrine\DBAL\TransactionIsolationLevel;
use Doctrine\DBAL\Types;
use Doctrine\DBAL\Types\Type;
+use Doctrine\Deprecations\Deprecation;
use InvalidArgumentException;
use UnexpectedValueException;
@@ -58,9 +59,6 @@ use function strlen;
use function strpos;
use function strtolower;
use function strtoupper;
-use function trigger_error;
-
-use const E_USER_DEPRECATED;
/**
* Base class for all DatabasePlatforms. The DatabasePlatforms are the central
@@ -245,12 +243,14 @@ abstract class AbstractPlatform
if ($column['length'] > $maxLength) {
if ($maxLength > 0) {
- @trigger_error(sprintf(
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3187',
'Binary column length %d is greater than supported by the platform (%d).'
. ' Reduce the column length or use a BLOB column instead.',
$column['length'],
$maxLength
- ), E_USER_DEPRECATED);
+ );
}
return $this->getBlobTypeDeclarationSQL($column);
@@ -1352,13 +1352,21 @@ abstract class AbstractPlatform
/**
* Returns the SQL snippet to drop an existing database.
*
- * @param string $database The name of the database that should be dropped.
+ * @param string $name The name of the database that should be dropped.
*
* @return string
*/
- public function getDropDatabaseSQL($database)
+ public function getDropDatabaseSQL($name)
{
- return 'DROP DATABASE ' . $database;
+ return 'DROP DATABASE ' . $name;
+ }
+
+ /**
+ * Returns the SQL snippet to drop a schema.
+ */
+ public function getDropSchemaSQL(string $schemaName): string
+ {
+ return 'DROP SCHEMA ' . $schemaName;
}
/**
@@ -1768,6 +1776,8 @@ abstract class AbstractPlatform
'Can only create primary or unique constraints, no common indexes with getCreateConstraintSQL().'
);
}
+ } elseif ($constraint instanceof UniqueConstraint) {
+ $query .= ' UNIQUE';
} elseif ($constraint instanceof ForeignKeyConstraint) {
$query .= ' FOREIGN KEY';
@@ -2742,12 +2752,21 @@ abstract class AbstractPlatform
/**
* Returns the SQL statement for retrieving the namespaces defined in the database.
*
+ * @deprecated Use {@link AbstractSchemaManager::listSchemaNames()} instead.
+ *
* @return string
*
* @throws Exception If not supported on this platform.
*/
public function getListNamespacesSQL()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4503',
+ 'AbstractPlatform::getListNamespacesSQL() is deprecated,'
+ . ' use AbstractSchemaManager::listSchemaNames() instead.'
+ );
+
throw Exception::notSupported(__METHOD__);
}
@@ -2910,13 +2929,13 @@ abstract class AbstractPlatform
/**
* Returns the SQL to create a new database.
*
- * @param string $database The name of the database that should be created.
+ * @param string $name The name of the database that should be created.
*
* @return string
*
* @throws Exception If not supported on this platform.
*/
- public function getCreateDatabaseSQL($database)
+ public function getCreateDatabaseSQL($name)
{
throw Exception::notSupported(__METHOD__);
}
@@ -3480,31 +3499,51 @@ abstract class AbstractPlatform
final public function getReservedKeywordsList()
{
// Check for an existing instantiation of the keywords class.
- if ($this->_keywords !== null) {
- return $this->_keywords;
+ if ($this->_keywords === null) {
+ // Store the instance so it doesn't need to be generated on every request.
+ $this->_keywords = $this->createReservedKeywordsList();
}
+ return $this->_keywords;
+ }
+
+ /**
+ * Creates an instance of the reserved keyword list of this platform.
+ *
+ * This method will become @abstract in DBAL 4.0.0.
+ *
+ * @throws Exception
+ */
+ protected function createReservedKeywordsList(): KeywordList
+ {
$class = $this->getReservedKeywordsClass();
$keywords = new $class();
if (! $keywords instanceof KeywordList) {
throw Exception::notSupported(__METHOD__);
}
- // Store the instance so it doesn't need to be generated on every request.
- $this->_keywords = $keywords;
-
return $keywords;
}
/**
* Returns the class name of the reserved keywords list.
*
+ * @deprecated Implement {@link createReservedKeywordsList()} instead.
+ *
* @return string
+ * @psalm-return class-string<KeywordList>
*
* @throws Exception If not supported on this platform.
*/
protected function getReservedKeywordsClass()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'AbstractPlatform::getReservedKeywordsClass() is deprecated,'
+ . ' use AbstractPlatform::createReservedKeywordsList() instead.'
+ );
+
throw Exception::notSupported(__METHOD__);
}
diff --git a/doctrine/dbal/src/Platforms/DB2Platform.php b/doctrine/dbal/src/Platforms/DB2Platform.php
index 16d4839f..03631054 100644
--- a/doctrine/dbal/src/Platforms/DB2Platform.php
+++ b/doctrine/dbal/src/Platforms/DB2Platform.php
@@ -9,6 +9,7 @@ use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
+use Doctrine\Deprecations\Deprecation;
use function array_merge;
use function count;
@@ -290,6 +291,7 @@ class DB2Platform extends AbstractPlatform
c.colname,
c.colno,
c.typename,
+ c.codepage,
c.nulls,
c.length,
c.scale,
@@ -413,17 +415,17 @@ class DB2Platform extends AbstractPlatform
/**
* {@inheritDoc}
*/
- public function getCreateDatabaseSQL($database)
+ public function getCreateDatabaseSQL($name)
{
- return 'CREATE DATABASE ' . $database;
+ return 'CREATE DATABASE ' . $name;
}
/**
* {@inheritDoc}
*/
- public function getDropDatabaseSQL($database)
+ public function getDropDatabaseSQL($name)
{
- return 'DROP DATABASE ' . $database;
+ return 'DROP DATABASE ' . $name;
}
/**
@@ -896,9 +898,18 @@ class DB2Platform extends AbstractPlatform
/**
* {@inheritDoc}
+ *
+ * @deprecated Implement {@link createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'DB2Platform::getReservedKeywordsClass() is deprecated,'
+ . ' use DB2Platform::createReservedKeywordsList() instead.'
+ );
+
return Keywords\DB2Keywords::class;
}
diff --git a/doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php b/doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php
index ff03432e..a6da7746 100644
--- a/doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php
+++ b/doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php
@@ -17,7 +17,7 @@ use function str_replace;
class ReservedKeywordsValidator implements Visitor
{
/** @var KeywordList[] */
- private $keywordLists = [];
+ private $keywordLists;
/** @var string[] */
private $violations = [];
diff --git a/doctrine/dbal/src/Platforms/MariaDb1027Platform.php b/doctrine/dbal/src/Platforms/MariaDb1027Platform.php
index 054f6539..9fa84e98 100644
--- a/doctrine/dbal/src/Platforms/MariaDb1027Platform.php
+++ b/doctrine/dbal/src/Platforms/MariaDb1027Platform.php
@@ -3,6 +3,7 @@
namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Types\Types;
+use Doctrine\Deprecations\Deprecation;
/**
* Provides the behavior, features and SQL dialect of the MariaDB 10.2 (10.2.7 GA) database platform.
@@ -21,8 +22,18 @@ final class MariaDb1027Platform extends MySQLPlatform
return 'LONGTEXT';
}
+ /**
+ * @deprecated Implement {@link createReservedKeywordsList()} instead.
+ */
protected function getReservedKeywordsClass(): string
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'MariaDb1027Platform::getReservedKeywordsClass() is deprecated,'
+ . ' use MariaDb1027Platform::createReservedKeywordsList() instead.'
+ );
+
return Keywords\MariaDb102Keywords::class;
}
diff --git a/doctrine/dbal/src/Platforms/MySQL57Platform.php b/doctrine/dbal/src/Platforms/MySQL57Platform.php
index a3ec5044..f29204cf 100644
--- a/doctrine/dbal/src/Platforms/MySQL57Platform.php
+++ b/doctrine/dbal/src/Platforms/MySQL57Platform.php
@@ -6,6 +6,7 @@ use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\SQL\Parser;
use Doctrine\DBAL\Types\Types;
+use Doctrine\Deprecations\Deprecation;
/**
* Provides the behavior, features and SQL dialect of the MySQL 5.7 (5.7.9 GA) database platform.
@@ -59,9 +60,18 @@ class MySQL57Platform extends MySQLPlatform
/**
* {@inheritdoc}
+ *
+ * @deprecated Implement {@link createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'MySQL57Platform::getReservedKeywordsClass() is deprecated,'
+ . ' use MySQL57Platform::createReservedKeywordsList() instead.'
+ );
+
return Keywords\MySQL57Keywords::class;
}
diff --git a/doctrine/dbal/src/Platforms/MySQL80Platform.php b/doctrine/dbal/src/Platforms/MySQL80Platform.php
index f6d4be9d..808e9344 100644
--- a/doctrine/dbal/src/Platforms/MySQL80Platform.php
+++ b/doctrine/dbal/src/Platforms/MySQL80Platform.php
@@ -2,6 +2,8 @@
namespace Doctrine\DBAL\Platforms;
+use Doctrine\Deprecations\Deprecation;
+
/**
* Provides the behavior, features and SQL dialect of the MySQL 8.0 (8.0 GA) database platform.
*/
@@ -9,9 +11,18 @@ class MySQL80Platform extends MySQL57Platform
{
/**
* {@inheritdoc}
+ *
+ * @deprecated Implement {@link createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'MySQL80Platform::getReservedKeywordsClass() is deprecated,'
+ . ' use MySQL80Platform::createReservedKeywordsList() instead.'
+ );
+
return Keywords\MySQL80Keywords::class;
}
}
diff --git a/doctrine/dbal/src/Platforms/MySQLPlatform.php b/doctrine/dbal/src/Platforms/MySQLPlatform.php
index d9607c3e..06bc5975 100644
--- a/doctrine/dbal/src/Platforms/MySQLPlatform.php
+++ b/doctrine/dbal/src/Platforms/MySQLPlatform.php
@@ -11,6 +11,7 @@ use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\TransactionIsolationLevel;
use Doctrine\DBAL\Types\BlobType;
use Doctrine\DBAL\Types\TextType;
+use Doctrine\Deprecations\Deprecation;
use InvalidArgumentException;
use function array_diff_key;
@@ -32,8 +33,6 @@ use function trim;
* The MySQLPlatform provides the behavior, features and SQL dialect of the
* MySQL database platform. This platform represents a MySQL 5.0 or greater platform that
* uses the InnoDB storage engine.
- *
- * @todo Rename: MySQLPlatform
*/
class MySQLPlatform extends AbstractPlatform
{
@@ -1105,9 +1104,18 @@ SQL
/**
* {@inheritDoc}
+ *
+ * @deprecated Implement {@link createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'MySQLPlatform::getReservedKeywordsClass() is deprecated,'
+ . ' use MySQLPlatform::createReservedKeywordsList() instead.'
+ );
+
return Keywords\MySQLKeywords::class;
}
diff --git a/doctrine/dbal/src/Platforms/OraclePlatform.php b/doctrine/dbal/src/Platforms/OraclePlatform.php
index cbbfb07d..7be7621d 100644
--- a/doctrine/dbal/src/Platforms/OraclePlatform.php
+++ b/doctrine/dbal/src/Platforms/OraclePlatform.php
@@ -11,6 +11,7 @@ use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\TransactionIsolationLevel;
use Doctrine\DBAL\Types\BinaryType;
+use Doctrine\Deprecations\Deprecation;
use InvalidArgumentException;
use function array_merge;
@@ -506,8 +507,10 @@ class OraclePlatform extends AbstractPlatform
$sql[] = "DECLARE
constraints_Count NUMBER;
BEGIN
- SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = '" . $unquotedTableName
- . "' AND CONSTRAINT_TYPE = 'P';
+ SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count
+ FROM USER_CONSTRAINTS
+ WHERE TABLE_NAME = '" . $unquotedTableName . "'
+ AND CONSTRAINT_TYPE = 'P';
IF constraints_Count = 0 OR constraints_Count = '' THEN
EXECUTE IMMEDIATE '" . $this->getCreateConstraintSQL($idx, $quotedTableName) . "';
END IF;
@@ -528,7 +531,6 @@ DECLARE
last_Sequence NUMBER;
last_InsertID NUMBER;
BEGIN
- SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $quotedName . ' FROM DUAL;
IF (:NEW.' . $quotedName . ' IS NULL OR :NEW.' . $quotedName . ' = 0) THEN
SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $quotedName . ' FROM DUAL;
ELSE
@@ -539,6 +541,7 @@ BEGIN
WHILE (last_InsertID > last_Sequence) LOOP
SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL;
END LOOP;
+ SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL;
END IF;
END;';
@@ -783,9 +786,9 @@ SQL
/**
* {@inheritDoc}
*/
- public function getDropDatabaseSQL($database)
+ public function getDropDatabaseSQL($name)
{
- return 'DROP USER ' . $database . ' CASCADE';
+ return 'DROP USER ' . $name . ' CASCADE';
}
/**
@@ -1160,9 +1163,18 @@ SQL
/**
* {@inheritDoc}
+ *
+ * @deprecated Implement {@link createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'OraclePlatform::getReservedKeywordsClass() is deprecated,'
+ . ' use OraclePlatform::createReservedKeywordsList() instead.'
+ );
+
return Keywords\OracleKeywords::class;
}
diff --git a/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php b/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php
index f5610056..c9ca509d 100644
--- a/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php
+++ b/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php
@@ -5,14 +5,25 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Platforms\Keywords\PostgreSQL100Keywords;
+use Doctrine\Deprecations\Deprecation;
/**
* Provides the behavior, features and SQL dialect of the PostgreSQL 10.0 database platform.
*/
class PostgreSQL100Platform extends PostgreSQL94Platform
{
+ /**
+ * @deprecated Implement {@link createReservedKeywordsList()} instead.
+ */
protected function getReservedKeywordsClass(): string
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'PostgreSQL100Platform::getReservedKeywordsClass() is deprecated,'
+ . ' use PostgreSQL100Platform::createReservedKeywordsList() instead.'
+ );
+
return PostgreSQL100Keywords::class;
}
diff --git a/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php b/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php
index a00a43e2..bf21477c 100644
--- a/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php
+++ b/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php
@@ -14,6 +14,7 @@ use Doctrine\DBAL\Types\BinaryType;
use Doctrine\DBAL\Types\BlobType;
use Doctrine\DBAL\Types\IntegerType;
use Doctrine\DBAL\Types\Type;
+use Doctrine\Deprecations\Deprecation;
use UnexpectedValueException;
use function array_diff;
@@ -227,9 +228,18 @@ class PostgreSQL94Platform extends AbstractPlatform
/**
* {@inheritDoc}
+ *
+ * @deprecated Use {@link PostgreSQLSchemaManager::listSchemaNames()} instead.
*/
public function getListNamespacesSQL()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4503',
+ 'PostgreSQL94Platform::getListNamespacesSQL() is deprecated,'
+ . ' use PostgreSQLSchemaManager::listSchemaNames() instead.'
+ );
+
return "SELECT schema_name AS nspname
FROM information_schema.schemata
WHERE schema_name NOT LIKE 'pg\_%'
@@ -775,6 +785,12 @@ SQL
}
}
+ if (isset($options['uniqueConstraints'])) {
+ foreach ($options['uniqueConstraints'] as $uniqueConstraint) {
+ $sql[] = $this->getCreateConstraintSQL($uniqueConstraint, $name);
+ }
+ }
+
if (isset($options['foreignKeys'])) {
foreach ((array) $options['foreignKeys'] as $definition) {
$sql[] = $this->getCreateForeignKeySQL($definition, $name);
@@ -864,12 +880,15 @@ SQL
return $this->doConvertBooleans(
$item,
- static function ($boolean) {
- if ($boolean === null) {
+ /**
+ * @param mixed $value
+ */
+ static function ($value) {
+ if ($value === null) {
return 'NULL';
}
- return $boolean === true ? 'true' : 'false';
+ return $value === true ? 'true' : 'false';
}
);
}
@@ -885,8 +904,11 @@ SQL
return $this->doConvertBooleans(
$item,
- static function ($boolean): ?int {
- return $boolean === null ? null : (int) $boolean;
+ /**
+ * @param mixed $value
+ */
+ static function ($value): ?int {
+ return $value === null ? null : (int) $value;
}
);
}
@@ -896,7 +918,7 @@ SQL
*/
public function convertFromBoolean($item)
{
- if (in_array(strtolower($item), $this->booleanLiterals['false'], true)) {
+ if ($item !== null && in_array(strtolower($item), $this->booleanLiterals['false'], true)) {
return false;
}
@@ -1168,9 +1190,18 @@ SQL
/**
* {@inheritDoc}
+ *
+ * @deprecated Implement {@link createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'PostgreSQL94Platform::getReservedKeywordsClass() is deprecated,'
+ . ' use PostgreSQL94Platform::createReservedKeywordsList() instead.'
+ );
+
return Keywords\PostgreSQL94Keywords::class;
}
diff --git a/doctrine/dbal/src/Platforms/SQLServer2012Platform.php b/doctrine/dbal/src/Platforms/SQLServer2012Platform.php
index 5e7c428d..d94784d6 100644
--- a/doctrine/dbal/src/Platforms/SQLServer2012Platform.php
+++ b/doctrine/dbal/src/Platforms/SQLServer2012Platform.php
@@ -12,6 +12,7 @@ use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff;
+use Doctrine\Deprecations\Deprecation;
use InvalidArgumentException;
use function array_merge;
@@ -282,11 +283,11 @@ class SQLServer2012Platform extends AbstractPlatform
return sprintf(
<<<SQL
-IF EXISTS (SELECT * FROM sysobjects WHERE name = '%s')
- ALTER TABLE %s DROP CONSTRAINT %s
-ELSE
- DROP INDEX %s ON %s
-SQL
+ IF EXISTS (SELECT * FROM sysobjects WHERE name = '%s')
+ ALTER TABLE %s DROP CONSTRAINT %s
+ ELSE
+ DROP INDEX %s ON %s
+ SQL
,
$index,
$table,
@@ -524,12 +525,15 @@ SQL
}
$columnDef = $column->toArray();
- $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef);
-
+ $addColumnSql = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef);
if (isset($columnDef['default'])) {
- $queryParts[] = $this->getAlterTableAddDefaultConstraintClause($diff->name, $column);
+ $addColumnSql .= ' CONSTRAINT ' .
+ $this->generateDefaultConstraintName($diff->name, $column->getQuotedName($this)) .
+ $this->getDefaultValueDeclarationSQL($columnDef);
}
+ $queryParts[] = $addColumnSql;
+
$comment = $this->getColumnComment($column);
if (empty($comment) && ! is_numeric($comment)) {
@@ -1157,9 +1161,18 @@ SQL
/**
* {@inheritDoc}
+ *
+ * @deprecated Use {@link SQLServerSchemaManager::listSchemaNames()} instead.
*/
public function getListNamespacesSQL()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4503',
+ 'SQLServer2012Platform::getListNamespacesSQL() is deprecated,'
+ . ' use SQLServerSchemaManager::listSchemaNames() instead.'
+ );
+
return "SELECT name FROM sys.schemas WHERE name NOT IN('guest', 'INFORMATION_SCHEMA', 'sys')";
}
@@ -1337,20 +1350,7 @@ SQL
return $query;
}
- // Queries using OFFSET... FETCH MUST have an ORDER BY clause
- // Find the position of the last instance of ORDER BY and ensure it is not within a parenthetical statement
- // but can be in a newline
- $matches = [];
- $matchesCount = preg_match_all('/[\\s]+order\\s+by\\s/im', $query, $matches, PREG_OFFSET_CAPTURE);
- $orderByPos = false;
- if ($matchesCount > 0) {
- $orderByPos = $matches[0][$matchesCount - 1][1];
- }
-
- if (
- $orderByPos === false
- || substr_count($query, '(', $orderByPos) !== substr_count($query, ')', $orderByPos)
- ) {
+ if ($this->shouldAddOrderBy($query)) {
if (preg_match('/^SELECT\s+DISTINCT/im', $query) > 0) {
// SQL Server won't let us order by a non-selected column in a DISTINCT query,
// so we have to do this madness. This says, order by the first column in the
@@ -1470,6 +1470,7 @@ SQL
'bigint' => 'bigint',
'binary' => 'binary',
'bit' => 'boolean',
+ 'blob' => 'blob',
'char' => 'string',
'date' => 'date',
'datetime' => 'datetime',
@@ -1564,9 +1565,18 @@ SQL
/**
* {@inheritDoc}
+ *
+ * @deprecated Implement {@link createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'QLServer2012Platform::getReservedKeywordsClass() is deprecated,'
+ . ' use QLServer2012Platform::createReservedKeywordsList() instead.'
+ );
+
return Keywords\SQLServer2012Keywords::class;
}
@@ -1575,7 +1585,7 @@ SQL
*/
public function quoteSingleIdentifier($str)
{
- return '[' . str_replace(']', '][', $str) . ']';
+ return '[' . str_replace(']', ']]', $str) . ']';
}
/**
@@ -1661,10 +1671,10 @@ SQL
{
return sprintf(
<<<'SQL'
-EXEC sys.sp_addextendedproperty @name=N'MS_Description',
- @value=N%s, @level0type=N'SCHEMA', @level0name=N'dbo',
- @level1type=N'TABLE', @level1name=N%s
-SQL
+ EXEC sys.sp_addextendedproperty @name=N'MS_Description',
+ @value=N%s, @level0type=N'SCHEMA', @level0name=N'dbo',
+ @level1type=N'TABLE', @level1name=N%s
+ SQL
,
$this->quoteStringLiteral((string) $comment),
$this->quoteStringLiteral($tableName)
@@ -1675,16 +1685,47 @@ SQL
{
return sprintf(
<<<'SQL'
-SELECT
- p.value AS [table_comment]
-FROM
- sys.tables AS tbl
- INNER JOIN sys.extended_properties AS p ON p.major_id=tbl.object_id AND p.minor_id=0 AND p.class=1
-WHERE
- (tbl.name=N%s and SCHEMA_NAME(tbl.schema_id)=N'dbo' and p.name=N'MS_Description')
-SQL
+ SELECT
+ p.value AS [table_comment]
+ FROM
+ sys.tables AS tbl
+ INNER JOIN sys.extended_properties AS p ON p.major_id=tbl.object_id AND p.minor_id=0 AND p.class=1
+ WHERE
+ (tbl.name=N%s and SCHEMA_NAME(tbl.schema_id)=N'dbo' and p.name=N'MS_Description')
+ SQL
,
$this->quoteStringLiteral($table)
);
}
+
+ /**
+ * @param string $query
+ */
+ private function shouldAddOrderBy($query): bool
+ {
+ // Find the position of the last instance of ORDER BY and ensure it is not within a parenthetical statement
+ // but can be in a newline
+ $matches = [];
+ $matchesCount = preg_match_all('/[\\s]+order\\s+by\\s/im', $query, $matches, PREG_OFFSET_CAPTURE);
+ if ($matchesCount === 0) {
+ return true;
+ }
+
+ // ORDER BY instance may be in a subquery after ORDER BY
+ // e.g. SELECT col1 FROM test ORDER BY (SELECT col2 from test ORDER BY col2)
+ // if in the searched query ORDER BY clause was found where
+ // number of open parentheses after the occurrence of the clause is equal to
+ // number of closed brackets after the occurrence of the clause,
+ // it means that ORDER BY is included in the query being checked
+ while ($matchesCount > 0) {
+ $orderByPos = $matches[0][--$matchesCount][1];
+ $openBracketsCount = substr_count($query, '(', $orderByPos);
+ $closedBracketsCount = substr_count($query, ')', $orderByPos);
+ if ($openBracketsCount === $closedBracketsCount) {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
diff --git a/doctrine/dbal/src/Platforms/SqlitePlatform.php b/doctrine/dbal/src/Platforms/SqlitePlatform.php
index 6d85de4e..5dc1747c 100644
--- a/doctrine/dbal/src/Platforms/SqlitePlatform.php
+++ b/doctrine/dbal/src/Platforms/SqlitePlatform.php
@@ -3,16 +3,22 @@
namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Exception;
+use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Constraint;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Identifier;
use Doctrine\DBAL\Schema\Index;
+use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\TransactionIsolationLevel;
use Doctrine\DBAL\Types;
+use Doctrine\Deprecations\Deprecation;
+use function array_combine;
+use function array_keys;
use function array_merge;
+use function array_search;
use function array_unique;
use function array_values;
use function implode;
@@ -684,9 +690,18 @@ class SqlitePlatform extends AbstractPlatform
/**
* {@inheritDoc}
+ *
+ * @deprecated Implement {@link createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'SqlitePlatform::getReservedKeywordsClass() is deprecated,'
+ . ' use SqlitePlatform::createReservedKeywordsList() instead.'
+ );
+
return Keywords\SQLiteKeywords::class;
}
@@ -905,12 +920,7 @@ class SqlitePlatform extends AbstractPlatform
continue;
}
- $oldColumnName = strtolower($oldColumnName);
- if (isset($columns[$oldColumnName])) {
- unset($columns[$oldColumnName]);
- }
-
- $columns[strtolower($column->getName())] = $column;
+ $columns = $this->replaceColumn($diff->name, $columns, $oldColumnName, $column);
if (! isset($newColumnNames[$oldColumnName])) {
continue;
@@ -924,11 +934,7 @@ class SqlitePlatform extends AbstractPlatform
continue;
}
- if (isset($columns[$oldColumnName])) {
- unset($columns[$oldColumnName]);
- }
-
- $columns[strtolower($columnDiff->column->getName())] = $columnDiff->column;
+ $columns = $this->replaceColumn($diff->name, $columns, $oldColumnName, $columnDiff->column);
if (! isset($newColumnNames[$oldColumnName])) {
continue;
@@ -997,6 +1003,34 @@ class SqlitePlatform extends AbstractPlatform
}
/**
+ * Replace the column with the given name with the new column.
+ *
+ * @param string $tableName
+ * @param array<string,Column> $columns
+ * @param string $columnName
+ *
+ * @return array<string,Column>
+ *
+ * @throws Exception
+ */
+ private function replaceColumn($tableName, array $columns, $columnName, Column $column): array
+ {
+ $keys = array_keys($columns);
+ $index = array_search(strtolower($columnName), $keys, true);
+
+ if ($index === false) {
+ throw SchemaException::columnDoesNotExist($columnName, $tableName);
+ }
+
+ $values = array_values($columns);
+
+ $keys[$index] = strtolower($column->getName());
+ $values[$index] = $column;
+
+ return array_combine($keys, $values);
+ }
+
+ /**
* @return string[]|false
*
* @throws Exception
diff --git a/doctrine/dbal/src/Portability/Converter.php b/doctrine/dbal/src/Portability/Converter.php
index eba144a1..5763c260 100644
--- a/doctrine/dbal/src/Portability/Converter.php
+++ b/doctrine/dbal/src/Portability/Converter.php
@@ -38,21 +38,17 @@ final class Converter
*/
public function __construct(bool $convertEmptyStringToNull, bool $rightTrimString, ?int $case)
{
- $id = static function ($value) {
- return $value;
- };
-
$convertValue = $this->createConvertValue($convertEmptyStringToNull, $rightTrimString);
$convertNumeric = $this->createConvertRow($convertValue, null);
$convertAssociative = $this->createConvertRow($convertValue, $case);
- $this->convertNumeric = $this->createConvert($convertNumeric, $id);
- $this->convertAssociative = $this->createConvert($convertAssociative, $id);
- $this->convertOne = $this->createConvert($convertValue, $id);
+ $this->convertNumeric = $this->createConvert($convertNumeric, [self::class, 'id']);
+ $this->convertAssociative = $this->createConvert($convertAssociative, [self::class, 'id']);
+ $this->convertOne = $this->createConvert($convertValue, [self::class, 'id']);
- $this->convertAllNumeric = $this->createConvertAll($convertNumeric, $id);
- $this->convertAllAssociative = $this->createConvertAll($convertAssociative, $id);
- $this->convertFirstColumn = $this->createConvertAll($convertValue, $id);
+ $this->convertAllNumeric = $this->createConvertAll($convertNumeric, [self::class, 'id']);
+ $this->convertAllAssociative = $this->createConvertAll($convertAssociative, [self::class, 'id']);
+ $this->convertFirstColumn = $this->createConvertAll($convertValue, [self::class, 'id']);
}
/**
@@ -116,6 +112,51 @@ final class Converter
}
/**
+ * @param T $value
+ *
+ * @return T
+ *
+ * @template T
+ */
+ private static function id($value)
+ {
+ return $value;
+ }
+
+ /**
+ * @param T $value
+ *
+ * @return T|null
+ *
+ * @template T
+ */
+ private static function convertEmptyStringToNull($value)
+ {
+ if ($value === '') {
+ return null;
+ }
+
+ return $value;
+ }
+
+ /**
+ * @param T $value
+ *
+ * @return T|string
+ * @psalm-return (T is string ? string : T)
+ *
+ * @template T
+ */
+ private static function rightTrimString($value)
+ {
+ if (! is_string($value)) {
+ return $value;
+ }
+
+ return rtrim($value);
+ }
+
+ /**
* Creates a function that will convert each individual value retrieved from the database
*
* @param bool $convertEmptyStringToNull Whether each empty string should be converted to NULL
@@ -128,23 +169,11 @@ final class Converter
$functions = [];
if ($convertEmptyStringToNull) {
- $functions[] = static function ($value) {
- if ($value === '') {
- return null;
- }
-
- return $value;
- };
+ $functions[] = [self::class, 'convertEmptyStringToNull'];
}
if ($rightTrimString) {
- $functions[] = static function ($value) {
- if (! is_string($value)) {
- return $value;
- }
-
- return rtrim($value);
- };
+ $functions[] = [self::class, 'rightTrimString'];
}
return $this->compose(...$functions);
@@ -188,13 +217,20 @@ final class Converter
return $id;
}
- return static function ($value) use ($function) {
- if ($value === false) {
- return false;
- }
+ return /**
+ * @param T $value
+ *
+ * @psalm-return (T is false ? false : T)
+ *
+ * @template T
+ */
+ static function ($value) use ($function) {
+ if ($value === false) {
+ return false;
+ }
- return $function($value);
- };
+ return $function($value);
+ };
}
/**
@@ -228,9 +264,11 @@ final class Converter
/**
* Creates a composition of the given set of functions
*
- * @param callable ...$functions The functions to compose
+ * @param callable(T):T ...$functions The functions to compose
*
- * @return callable|null The composition or NULL if an empty set is provided
+ * @return callable(T):T|null
+ *
+ * @template T
*/
private function compose(callable ...$functions): ?callable
{
@@ -239,9 +277,16 @@ final class Converter
return $item;
}
- return static function ($value) use ($carry, $item) {
- return $item($carry($value));
- };
+ return /**
+ * @param T $value
+ *
+ * @return T
+ *
+ * @template T
+ */
+ static function ($value) use ($carry, $item) {
+ return $item($carry($value));
+ };
});
}
}
diff --git a/doctrine/dbal/src/Query/Expression/CompositeExpression.php b/doctrine/dbal/src/Query/Expression/CompositeExpression.php
index 4e551e95..85de9ae9 100644
--- a/doctrine/dbal/src/Query/Expression/CompositeExpression.php
+++ b/doctrine/dbal/src/Query/Expression/CompositeExpression.php
@@ -3,6 +3,8 @@
namespace Doctrine\DBAL\Query\Expression;
use Countable;
+use Doctrine\Deprecations\Deprecation;
+use ReturnTypeWillChange;
use function array_merge;
use function count;
@@ -48,6 +50,12 @@ class CompositeExpression implements Countable
$this->type = $type;
$this->addMultiple($parts);
+
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/3864',
+ 'Do not use CompositeExpression constructor directly, use static and() and or() factory methods.'
+ );
}
/**
@@ -79,6 +87,12 @@ class CompositeExpression implements Countable
*/
public function addMultiple(array $parts = [])
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3844',
+ 'CompositeExpression::addMultiple() is deprecated, use CompositeExpression::with() instead.'
+ );
+
foreach ($parts as $part) {
$this->add($part);
}
@@ -97,6 +111,12 @@ class CompositeExpression implements Countable
*/
public function add($part)
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3844',
+ 'CompositeExpression::add() is deprecated, use CompositeExpression::with() instead.'
+ );
+
if ($part === null) {
return $this;
}
@@ -130,6 +150,7 @@ class CompositeExpression implements Countable
*
* @return int
*/
+ #[ReturnTypeWillChange]
public function count()
{
return count($this->parts);
diff --git a/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php b/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php
index f12ef0fa..8cb53150 100644
--- a/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php
+++ b/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php
@@ -3,6 +3,7 @@
namespace Doctrine\DBAL\Query\Expression;
use Doctrine\DBAL\Connection;
+use Doctrine\Deprecations\Deprecation;
use function func_get_arg;
use function func_get_args;
@@ -71,6 +72,12 @@ class ExpressionBuilder
*/
public function andX($x = null)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/3851',
+ 'ExpressionBuilder::andX() is deprecated, use ExpressionBuilder::and() instead.'
+ );
+
return new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
}
@@ -84,6 +91,12 @@ class ExpressionBuilder
*/
public function orX($x = null)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/3851',
+ 'ExpressionBuilder::orX() is deprecated, use ExpressionBuilder::or() instead.'
+ );
+
return new CompositeExpression(CompositeExpression::TYPE_OR, func_get_args());
}
@@ -243,8 +256,8 @@ class ExpressionBuilder
/**
* Creates a LIKE() comparison expression with the given arguments.
*
- * @param string $x Field in string format to be inspected by LIKE() comparison.
- * @param mixed $y Argument to be used in LIKE() comparison.
+ * @param string $x The expression to be inspected by the LIKE comparison
+ * @param mixed $y The pattern to compare against
*
* @return string
*/
@@ -257,8 +270,8 @@ class ExpressionBuilder
/**
* Creates a NOT LIKE() comparison expression with the given arguments.
*
- * @param string $x Field in string format to be inspected by NOT LIKE() comparison.
- * @param mixed $y Argument to be used in NOT LIKE() comparison.
+ * @param string $x The expression to be inspected by the NOT LIKE comparison
+ * @param mixed $y The pattern to compare against
*
* @return string
*/
@@ -269,10 +282,10 @@ class ExpressionBuilder
}
/**
- * Creates a IN () comparison expression with the given arguments.
+ * Creates an IN () comparison expression with the given arguments.
*
- * @param string $x The field in string format to be inspected by IN() comparison.
- * @param string|string[] $y The placeholder or the array of values to be used by IN() comparison.
+ * @param string $x The SQL expression to be matched against the set.
+ * @param string|string[] $y The SQL expression or an array of SQL expressions representing the set.
*
* @return string
*/
@@ -284,8 +297,8 @@ class ExpressionBuilder
/**
* Creates a NOT IN () comparison expression with the given arguments.
*
- * @param string $x The expression to be inspected by NOT IN() comparison.
- * @param string|string[] $y The placeholder or the array of values to be used by NOT IN() comparison.
+ * @param string $x The SQL expression to be matched against the set.
+ * @param string|string[] $y The SQL expression or an array of SQL expressions representing the set.
*
* @return string
*/
diff --git a/doctrine/dbal/src/Query/QueryBuilder.php b/doctrine/dbal/src/Query/QueryBuilder.php
index 86e509ca..246cde1a 100644
--- a/doctrine/dbal/src/Query/QueryBuilder.php
+++ b/doctrine/dbal/src/Query/QueryBuilder.php
@@ -10,6 +10,7 @@ use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Statement;
use Doctrine\DBAL\Types\Type;
+use Doctrine\Deprecations\Deprecation;
use function array_key_exists;
use function array_keys;
@@ -83,7 +84,7 @@ class QueryBuilder
/**
* The complete SQL string for this query.
*
- * @var string
+ * @var string|null
*/
private $sql;
@@ -120,7 +121,7 @@ class QueryBuilder
*
* @var int
*/
- private $firstResult;
+ private $firstResult = 0;
/**
* The maximum number of results to retrieve or NULL to retrieve all results.
@@ -198,8 +199,136 @@ class QueryBuilder
}
/**
+ * Prepares and executes an SQL query and returns the first row of the result
+ * as an associative array.
+ *
+ * @return array<string, mixed>|false False is returned if no rows are found.
+ *
+ * @throws Exception
+ */
+ public function fetchAssociative()
+ {
+ return $this->connection->fetchAssociative($this->getSQL(), $this->params, $this->paramTypes);
+ }
+
+ /**
+ * Prepares and executes an SQL query and returns the first row of the result
+ * as a numerically indexed array.
+ *
+ * @return array<int, mixed>|false False is returned if no rows are found.
+ *
+ * @throws Exception
+ */
+ public function fetchNumeric()
+ {
+ return $this->connection->fetchNumeric($this->getSQL(), $this->params, $this->paramTypes);
+ }
+
+ /**
+ * Prepares and executes an SQL query and returns the value of a single column
+ * of the first row of the result.
+ *
+ * @return mixed|false False is returned if no rows are found.
+ *
+ * @throws Exception
+ */
+ public function fetchOne()
+ {
+ return $this->connection->fetchOne($this->getSQL(), $this->params, $this->paramTypes);
+ }
+
+ /**
+ * Prepares and executes an SQL query and returns the result as an array of numeric arrays.
+ *
+ * @return array<int,array<int,mixed>>
+ *
+ * @throws Exception
+ */
+ public function fetchAllNumeric(): array
+ {
+ return $this->connection->fetchAllNumeric($this->getSQL(), $this->params, $this->paramTypes);
+ }
+
+ /**
+ * Prepares and executes an SQL query and returns the result as an array of associative arrays.
+ *
+ * @return array<int,array<string,mixed>>
+ *
+ * @throws Exception
+ */
+ public function fetchAllAssociative(): array
+ {
+ return $this->connection->fetchAllAssociative($this->getSQL(), $this->params, $this->paramTypes);
+ }
+
+ /**
+ * Prepares and executes an SQL query and returns the result as an associative array with the keys
+ * mapped to the first column and the values mapped to the second column.
+ *
+ * @return array<mixed,mixed>
+ *
+ * @throws Exception
+ */
+ public function fetchAllKeyValue(): array
+ {
+ return $this->connection->fetchAllKeyValue($this->getSQL(), $this->params, $this->paramTypes);
+ }
+
+ /**
+ * Prepares and executes an SQL query and returns the result as an associative array with the keys mapped
+ * to the first column and the values being an associative array representing the rest of the columns
+ * and their values.
+ *
+ * @return array<mixed,array<string,mixed>>
+ *
+ * @throws Exception
+ */
+ public function fetchAllAssociativeIndexed(): array
+ {
+ return $this->connection->fetchAllAssociativeIndexed($this->getSQL(), $this->params, $this->paramTypes);
+ }
+
+ /**
+ * Prepares and executes an SQL query and returns the result as an array of the first column values.
+ *
+ * @return array<int,mixed>
+ *
+ * @throws Exception
+ */
+ public function fetchFirstColumn(): array
+ {
+ return $this->connection->fetchFirstColumn($this->getSQL(), $this->params, $this->paramTypes);
+ }
+
+ /**
+ * Executes an SQL query (SELECT) and returns a Result.
+ *
+ * @throws Exception
+ */
+ public function executeQuery(): Result
+ {
+ return $this->connection->executeQuery($this->getSQL(), $this->params, $this->paramTypes);
+ }
+
+ /**
+ * Executes an SQL statement and returns the number of affected rows.
+ *
+ * Should be used for INSERT, UPDATE and DELETE
+ *
+ * @return int The number of affected rows.
+ *
+ * @throws Exception
+ */
+ public function executeStatement(): int
+ {
+ return $this->connection->executeStatement($this->getSQL(), $this->params, $this->paramTypes);
+ }
+
+ /**
* Executes this query using the bound parameters and their types.
*
+ * @deprecated Use {@link executeQuery()} or {@link executeStatement()} instead.
+ *
* @return Result|int
*
* @throws Exception
@@ -207,9 +336,21 @@ class QueryBuilder
public function execute()
{
if ($this->type === self::SELECT) {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4578',
+ 'QueryBuilder::execute() is deprecated, use QueryBuilder::executeQuery() for SQL queries instead.'
+ );
+
return $this->connection->executeQuery($this->getSQL(), $this->params, $this->paramTypes);
}
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4578',
+ 'QueryBuilder::execute() is deprecated, use QueryBuilder::executeStatement() for SQL statements instead.'
+ );
+
return $this->connection->executeStatement($this->getSQL(), $this->params, $this->paramTypes);
}
@@ -269,7 +410,7 @@ class QueryBuilder
*
* @param int|string $key Parameter position or name
* @param mixed $value Parameter value
- * @param int|string|Type|null $type One of the {@link ParameterType} constants or DBAL type
+ * @param int|string|Type|null $type Parameter type
*
* @return $this This QueryBuilder instance.
*/
@@ -483,6 +624,15 @@ class QueryBuilder
return $this;
}
+ if (is_array($select)) {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3837',
+ 'Passing an array for the first argument to QueryBuilder::select() is deprecated, ' .
+ 'pass each value as an individual variadic argument instead.'
+ );
+ }
+
$selects = is_array($select) ? $select : func_get_args();
return $this->add('select', $selects);
@@ -533,6 +683,15 @@ class QueryBuilder
return $this;
}
+ if (is_array($select)) {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3837',
+ 'Passing an array for the first argument to QueryBuilder::addSelect() is deprecated, ' .
+ 'pass each value as an individual variadic argument instead.'
+ );
+ }
+
$selects = is_array($select) ? $select : func_get_args();
return $this->add('select', $selects, true);
@@ -905,6 +1064,15 @@ class QueryBuilder
return $this;
}
+ if (is_array($groupBy)) {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3837',
+ 'Passing an array for the first argument to QueryBuilder::groupBy() is deprecated, ' .
+ 'pass each value as an individual variadic argument instead.'
+ );
+ }
+
$groupBy = is_array($groupBy) ? $groupBy : func_get_args();
return $this->add('groupBy', $groupBy, false);
@@ -934,6 +1102,15 @@ class QueryBuilder
return $this;
}
+ if (is_array($groupBy)) {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3837',
+ 'Passing an array for the first argument to QueryBuilder::addGroupBy() is deprecated, ' .
+ 'pass each value as an individual variadic argument instead.'
+ );
+ }
+
$groupBy = is_array($groupBy) ? $groupBy : func_get_args();
return $this->add('groupBy', $groupBy, true);
@@ -1213,7 +1390,7 @@ class QueryBuilder
*/
private function isLimitQuery()
{
- return $this->maxResults !== null || $this->firstResult !== null;
+ return $this->maxResults !== null || $this->firstResult !== 0;
}
/**
diff --git a/doctrine/dbal/src/Schema/AbstractAsset.php b/doctrine/dbal/src/Schema/AbstractAsset.php
index 8f0c1d46..e6b383a6 100644
--- a/doctrine/dbal/src/Schema/AbstractAsset.php
+++ b/doctrine/dbal/src/Schema/AbstractAsset.php
@@ -24,7 +24,7 @@ use function substr;
abstract class AbstractAsset
{
/** @var string */
- protected $_name;
+ protected $_name = '';
/**
* Namespace of the asset. If none isset the default namespace is assumed.
@@ -102,7 +102,7 @@ abstract class AbstractAsset
}
/**
- * The normalized name is full-qualified and lowerspaced. Lowerspacing is
+ * The normalized name is full-qualified and lower-cased. Lower-casing is
* actually wrong, but we have to do it to keep our sanity. If you are
* using database objects that only differentiate in the casing (FOO vs
* Foo) then you will NOT be able to use Doctrine Schema abstraction.
diff --git a/doctrine/dbal/src/Schema/AbstractSchemaManager.php b/doctrine/dbal/src/Schema/AbstractSchemaManager.php
index 6b7d162e..50b9face 100644
--- a/doctrine/dbal/src/Schema/AbstractSchemaManager.php
+++ b/doctrine/dbal/src/Schema/AbstractSchemaManager.php
@@ -8,6 +8,7 @@ use Doctrine\DBAL\Event\SchemaIndexDefinitionEventArgs;
use Doctrine\DBAL\Events;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\AbstractPlatform;
+use Doctrine\Deprecations\Deprecation;
use Throwable;
use function array_filter;
@@ -19,6 +20,7 @@ use function call_user_func_array;
use function count;
use function func_get_args;
use function is_callable;
+use function is_string;
use function preg_match;
use function str_replace;
use function strtolower;
@@ -107,12 +109,21 @@ abstract class AbstractSchemaManager
/**
* Returns a list of all namespaces in the current database.
*
+ * @deprecated Use {@link listSchemaNames()} instead.
+ *
* @return string[]
*
* @throws Exception
*/
public function listNamespaceNames()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4503',
+ 'AbstractSchemaManager::listNamespaceNames() is deprecated,'
+ . ' use AbstractSchemaManager::listSchemaNames() instead.'
+ );
+
$sql = $this->_platform->getListNamespacesSQL();
$namespaces = $this->_conn->fetchAllAssociative($sql);
@@ -121,6 +132,18 @@ abstract class AbstractSchemaManager
}
/**
+ * Returns a list of the names of all schemata in the current database.
+ *
+ * @return list<string>
+ *
+ * @throws Exception
+ */
+ public function listSchemaNames(): array
+ {
+ throw Exception::notSupported(__METHOD__);
+ }
+
+ /**
* Lists the available sequences for this connection.
*
* @param string|null $database
@@ -205,6 +228,15 @@ abstract class AbstractSchemaManager
*/
public function tablesExist($names)
{
+ if (is_string($names)) {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3580',
+ 'The usage of a string $tableNames in AbstractSchemaManager::tablesExist() is deprecated. ' .
+ 'Pass a one-element array instead.'
+ );
+ }
+
$names = array_map('strtolower', (array) $names);
return count($names) === count(array_intersect($names, array_map('strtolower', $this->listTableNames())));
@@ -342,6 +374,16 @@ abstract class AbstractSchemaManager
}
/**
+ * Drops a schema.
+ *
+ * @throws Exception
+ */
+ public function dropSchema(string $schemaName): void
+ {
+ $this->_execSql($this->_platform->getDropSchemaSQL($schemaName));
+ }
+
+ /**
* Drops the given table.
*
* @param string $name The name of the table to drop.
@@ -646,9 +688,7 @@ abstract class AbstractSchemaManager
*/
public function alterTable(TableDiff $tableDiff)
{
- $queries = $this->_platform->getAlterTableSQL($tableDiff);
-
- foreach ($queries as $ddlQuery) {
+ foreach ($this->_platform->getAlterTableSQL($tableDiff) as $ddlQuery) {
$this->_execSql($ddlQuery);
}
}
@@ -693,6 +733,8 @@ abstract class AbstractSchemaManager
/**
* Converts a list of namespace names from the native DBMS data definition to a portable Doctrine definition.
*
+ * @deprecated Use {@link listSchemaNames()} instead.
+ *
* @param array<int, array<string, mixed>> $namespaces The list of namespace names
* in the native DBMS data definition.
*
@@ -700,6 +742,13 @@ abstract class AbstractSchemaManager
*/
protected function getPortableNamespacesList(array $namespaces)
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4503',
+ 'AbstractSchemaManager::getPortableNamespacesList() is deprecated,'
+ . ' use AbstractSchemaManager::listSchemaNames() instead.'
+ );
+
$namespacesList = [];
foreach ($namespaces as $namespace) {
@@ -722,12 +771,21 @@ abstract class AbstractSchemaManager
/**
* Converts a namespace definition from the native DBMS data definition to a portable Doctrine definition.
*
+ * @deprecated Use {@link listSchemaNames()} instead.
+ *
* @param array<string, mixed> $namespace The native DBMS namespace definition.
*
* @return mixed
*/
protected function getPortableNamespaceDefinition(array $namespace)
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4503',
+ 'AbstractSchemaManager::getPortableNamespaceDefinition() is deprecated,'
+ . ' use AbstractSchemaManager::listSchemaNames() instead.'
+ );
+
return $namespace;
}
@@ -1059,10 +1117,10 @@ abstract class AbstractSchemaManager
*/
public function createSchema()
{
- $namespaces = [];
+ $schemaNames = [];
if ($this->_platform->supportsSchemas()) {
- $namespaces = $this->listNamespaceNames();
+ $schemaNames = $this->listNamespaceNames();
}
$sequences = [];
@@ -1073,7 +1131,7 @@ abstract class AbstractSchemaManager
$tables = $this->listTables();
- return new Schema($tables, $sequences, $this->createSchemaConfig(), $namespaces);
+ return new Schema($tables, $sequences, $this->createSchemaConfig(), $schemaNames);
}
/**
diff --git a/doctrine/dbal/src/Schema/DB2SchemaManager.php b/doctrine/dbal/src/Schema/DB2SchemaManager.php
index d956d5b7..82c287e0 100644
--- a/doctrine/dbal/src/Schema/DB2SchemaManager.php
+++ b/doctrine/dbal/src/Schema/DB2SchemaManager.php
@@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\DB2Platform;
use Doctrine\DBAL\Types\Type;
+use Doctrine\DBAL\Types\Types;
use function array_change_key_case;
use function assert;
@@ -69,11 +70,19 @@ class DB2SchemaManager extends AbstractSchemaManager
switch (strtolower($tableColumn['typename'])) {
case 'varchar':
+ if ($tableColumn['codepage'] === 0) {
+ $type = Types::BINARY;
+ }
+
$length = $tableColumn['length'];
$fixed = false;
break;
case 'character':
+ if ($tableColumn['codepage'] === 0) {
+ $type = Types::BINARY;
+ }
+
$length = $tableColumn['length'];
$fixed = true;
break;
@@ -96,7 +105,7 @@ class DB2SchemaManager extends AbstractSchemaManager
'fixed' => (bool) $fixed,
'default' => $default,
'autoincrement' => (bool) $tableColumn['autoincrement'],
- 'notnull' => (bool) ($tableColumn['nulls'] === 'N'),
+ 'notnull' => $tableColumn['nulls'] === 'N',
'scale' => null,
'precision' => null,
'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== ''
diff --git a/doctrine/dbal/src/Schema/Index.php b/doctrine/dbal/src/Schema/Index.php
index 947ec896..508aa403 100644
--- a/doctrine/dbal/src/Schema/Index.php
+++ b/doctrine/dbal/src/Schema/Index.php
@@ -43,7 +43,7 @@ class Index extends AbstractAsset implements Constraint
* @todo $_flags should eventually be refactored into options
* @var mixed[]
*/
- private $options = [];
+ private $options;
/**
* @param string $name
diff --git a/doctrine/dbal/src/Schema/MySQLSchemaManager.php b/doctrine/dbal/src/Schema/MySQLSchemaManager.php
index b27cdcb0..4d54f715 100644
--- a/doctrine/dbal/src/Schema/MySQLSchemaManager.php
+++ b/doctrine/dbal/src/Schema/MySQLSchemaManager.php
@@ -91,7 +91,10 @@ class MySQLSchemaManager extends AbstractSchemaManager
$v['flags'] = ['SPATIAL'];
}
- $v['length'] = isset($v['sub_part']) ? (int) $v['sub_part'] : null;
+ // Ignore prohibited prefix `length` for spatial index
+ if (strpos($v['index_type'], 'SPATIAL') === false) {
+ $v['length'] = isset($v['sub_part']) ? (int) $v['sub_part'] : null;
+ }
$tableIndexes[$k] = $v;
}
diff --git a/doctrine/dbal/src/Schema/OracleSchemaManager.php b/doctrine/dbal/src/Schema/OracleSchemaManager.php
index 757af8bb..e24f79ff 100644
--- a/doctrine/dbal/src/Schema/OracleSchemaManager.php
+++ b/doctrine/dbal/src/Schema/OracleSchemaManager.php
@@ -154,6 +154,11 @@ class OracleSchemaManager extends AbstractSchemaManager
$fixed = false;
break;
+ case 'raw':
+ $length = $tableColumn['data_length'];
+ $fixed = true;
+ break;
+
case 'char':
case 'nchar':
$length = $tableColumn['char_length'];
@@ -162,7 +167,7 @@ class OracleSchemaManager extends AbstractSchemaManager
}
$options = [
- 'notnull' => (bool) ($tableColumn['nullable'] === 'N'),
+ 'notnull' => $tableColumn['nullable'] === 'N',
'fixed' => (bool) $fixed,
'unsigned' => (bool) $unsigned,
'default' => $tableColumn['data_default'],
@@ -249,18 +254,23 @@ class OracleSchemaManager extends AbstractSchemaManager
*/
public function createDatabase($database)
{
- $params = $this->_conn->getParams();
- $username = $database;
- $password = $params['password'];
+ $statement = 'CREATE USER ' . $database;
- $query = 'CREATE USER ' . $username . ' IDENTIFIED BY ' . $password;
- $this->_conn->executeStatement($query);
+ $params = $this->_conn->getParams();
- $query = 'GRANT DBA TO ' . $username;
- $this->_conn->executeStatement($query);
+ if (isset($params['password'])) {
+ $statement .= ' IDENTIFIED BY ' . $params['password'];
+ }
+
+ $this->_conn->executeStatement($statement);
+
+ $statement = 'GRANT DBA TO ' . $database;
+ $this->_conn->executeStatement($statement);
}
/**
+ * @internal The method should be only used from within the OracleSchemaManager class hierarchy.
+ *
* @param string $table
*
* @return bool
diff --git a/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php b/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php
index 9868359f..e353b53e 100644
--- a/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php
+++ b/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php
@@ -6,6 +6,7 @@ use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
+use Doctrine\Deprecations\Deprecation;
use function array_change_key_case;
use function array_filter;
@@ -32,20 +33,42 @@ use const CASE_LOWER;
*/
class PostgreSQLSchemaManager extends AbstractSchemaManager
{
- /** @var string[] */
+ /** @var string[]|null */
private $existingSchemaPaths;
/**
* Gets all the existing schema names.
*
+ * @deprecated Use {@link listSchemaNames()} instead.
+ *
* @return string[]
*
* @throws Exception
*/
public function getSchemaNames()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4503',
+ 'PostgreSQLSchemaManager::getSchemaNames() is deprecated,'
+ . ' use PostgreSQLSchemaManager::listSchemaNames() instead.'
+ );
+
+ return $this->listNamespaceNames();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function listSchemaNames(): array
+ {
return $this->_conn->fetchFirstColumn(
- "SELECT nspname FROM pg_namespace WHERE nspname !~ '^pg_.*' AND nspname != 'information_schema'"
+ <<<'SQL'
+SELECT schema_name
+FROM information_schema.schemata
+WHERE schema_name NOT LIKE 'pg\_%'
+AND schema_name != 'information_schema'
+SQL
);
}
@@ -73,6 +96,8 @@ class PostgreSQLSchemaManager extends AbstractSchemaManager
*
* This is a PostgreSQL only function.
*
+ * @internal The method should be only used from within the PostgreSQLSchemaManager class hierarchy.
+ *
* @return string[]
*/
public function getExistingSchemaSearchPaths()
@@ -89,11 +114,13 @@ class PostgreSQLSchemaManager extends AbstractSchemaManager
*
* This is a PostgreSQL only function.
*
+ * @internal The method should be only used from within the PostgreSQLSchemaManager class hierarchy.
+ *
* @return void
*/
public function determineExistingSchemaSearchPaths()
{
- $names = $this->getSchemaNames();
+ $names = $this->listSchemaNames();
$paths = $this->getSchemaSearchPaths();
$this->existingSchemaPaths = array_filter($paths, static function ($v) use ($names): bool {
@@ -106,11 +133,8 @@ class PostgreSQLSchemaManager extends AbstractSchemaManager
*/
protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
{
- $onUpdate = null;
- $onDelete = null;
- $localColumns = [];
- $foreignColumns = [];
- $foreignTable = null;
+ $onUpdate = null;
+ $onDelete = null;
if (
preg_match(
@@ -267,9 +291,18 @@ class PostgreSQLSchemaManager extends AbstractSchemaManager
/**
* {@inheritdoc}
+ *
+ * @deprecated Use {@link listSchemaNames()} instead.
*/
protected function getPortableNamespaceDefinition(array $namespace)
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4503',
+ 'PostgreSQLSchemaManager::getPortableNamespaceDefinition() is deprecated,'
+ . ' use PostgreSQLSchemaManager::listSchemaNames() instead.'
+ );
+
return $namespace['nspname'];
}
diff --git a/doctrine/dbal/src/Schema/SQLServerSchemaManager.php b/doctrine/dbal/src/Schema/SQLServerSchemaManager.php
index a33bd45c..a448dd14 100644
--- a/doctrine/dbal/src/Schema/SQLServerSchemaManager.php
+++ b/doctrine/dbal/src/Schema/SQLServerSchemaManager.php
@@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\SQLServer2012Platform;
use Doctrine\DBAL\Types\Type;
+use Doctrine\Deprecations\Deprecation;
use PDOException;
use function assert;
@@ -22,6 +23,20 @@ use function strtok;
class SQLServerSchemaManager extends AbstractSchemaManager
{
/**
+ * {@inheritDoc}
+ */
+ public function listSchemaNames(): array
+ {
+ return $this->_conn->fetchFirstColumn(
+ <<<'SQL'
+SELECT name
+FROM sys.schemas
+WHERE name NOT IN('guest', 'INFORMATION_SCHEMA', 'sys')
+SQL
+ );
+ }
+
+ /**
* {@inheritdoc}
*/
protected function _getPortableSequenceDefinition($sequence)
@@ -64,6 +79,13 @@ class SQLServerSchemaManager extends AbstractSchemaManager
}
break;
+
+ case 'varbinary':
+ if ($length === -1) {
+ $dbType = 'blob';
+ }
+
+ break;
}
if ($dbType === 'char' || $dbType === 'nchar' || $dbType === 'binary') {
@@ -85,7 +107,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager
'comment' => $tableColumn['comment'] !== '' ? $tableColumn['comment'] : null,
];
- if ($length !== 0 && ($type === 'text' || $type === 'string')) {
+ if ($length !== 0 && ($type === 'text' || $type === 'string' || $type === 'binary')) {
$options['length'] = $length;
}
@@ -199,9 +221,18 @@ class SQLServerSchemaManager extends AbstractSchemaManager
/**
* {@inheritdoc}
+ *
+ * @deprecated Use {@link listSchemaNames()} instead.
*/
protected function getPortableNamespaceDefinition(array $namespace)
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4503',
+ 'SQLServerSchemaManager::getPortableNamespaceDefinition() is deprecated,'
+ . ' use SQLServerSchemaManager::listSchemaNames() instead.'
+ );
+
return $namespace['name'];
}
diff --git a/doctrine/dbal/src/Schema/SchemaConfig.php b/doctrine/dbal/src/Schema/SchemaConfig.php
index b8c3502f..56d49c4a 100644
--- a/doctrine/dbal/src/Schema/SchemaConfig.php
+++ b/doctrine/dbal/src/Schema/SchemaConfig.php
@@ -13,7 +13,7 @@ class SchemaConfig
/** @var int */
protected $maxIdentifierLength = 63;
- /** @var string */
+ /** @var string|null */
protected $name;
/** @var mixed[] */
@@ -58,7 +58,7 @@ class SchemaConfig
/**
* Gets the default namespace of schema objects.
*
- * @return string
+ * @return string|null
*/
public function getName()
{
diff --git a/doctrine/dbal/src/Schema/Sequence.php b/doctrine/dbal/src/Schema/Sequence.php
index 1a48def8..a634e84f 100644
--- a/doctrine/dbal/src/Schema/Sequence.php
+++ b/doctrine/dbal/src/Schema/Sequence.php
@@ -67,7 +67,7 @@ class Sequence extends AbstractAsset
public function setAllocationSize($allocationSize)
{
if ($allocationSize > 0) {
- $this->allocationSize = (int) $allocationSize;
+ $this->allocationSize = $allocationSize;
} else {
$this->allocationSize = 1;
}
@@ -83,7 +83,7 @@ class Sequence extends AbstractAsset
public function setInitialValue($initialValue)
{
if ($initialValue > 0) {
- $this->initialValue = (int) $initialValue;
+ $this->initialValue = $initialValue;
} else {
$this->initialValue = 1;
}
diff --git a/doctrine/dbal/src/Schema/SqliteSchemaManager.php b/doctrine/dbal/src/Schema/SqliteSchemaManager.php
index 857f90b0..140ebb3c 100644
--- a/doctrine/dbal/src/Schema/SqliteSchemaManager.php
+++ b/doctrine/dbal/src/Schema/SqliteSchemaManager.php
@@ -52,13 +52,12 @@ class SqliteSchemaManager extends AbstractSchemaManager
*/
public function createDatabase($database)
{
- $params = $this->_conn->getParams();
- $driver = $params['driver'];
- $options = [
- 'driver' => $driver,
- 'path' => $database,
- ];
- $conn = DriverManager::getConnection($options);
+ $params = $this->_conn->getParams();
+
+ $params['path'] = $database;
+ unset($params['memory']);
+
+ $conn = DriverManager::getConnection($params);
$conn->connect();
$conn->close();
}
@@ -181,15 +180,23 @@ class SqliteSchemaManager extends AbstractSchemaManager
$this->_conn->quote($tableName)
));
- usort($indexArray, static function ($a, $b) {
- if ($a['pk'] === $b['pk']) {
- return $a['cid'] - $b['cid'];
+ usort(
+ $indexArray,
+ /**
+ * @param array<string,mixed> $a
+ * @param array<string,mixed> $b
+ */
+ static function (array $a, array $b): int {
+ if ($a['pk'] === $b['pk']) {
+ return $a['cid'] - $b['cid'];
+ }
+
+ return $a['pk'] - $b['pk'];
}
+ );
- return $a['pk'] - $b['pk'];
- });
foreach ($indexArray as $indexColumnRow) {
- if ($indexColumnRow['pk'] === '0') {
+ if ($indexColumnRow['pk'] === 0 || $indexColumnRow['pk'] === '0') {
continue;
}
@@ -240,7 +247,7 @@ class SqliteSchemaManager extends AbstractSchemaManager
$autoincrementCount = 0;
foreach ($tableColumns as $tableColumn) {
- if ($tableColumn['pk'] === '0') {
+ if ($tableColumn['pk'] === 0 || $tableColumn['pk'] === '0') {
continue;
}
@@ -362,7 +369,7 @@ class SqliteSchemaManager extends AbstractSchemaManager
$options = [
'length' => $length,
- 'unsigned' => (bool) $unsigned,
+ 'unsigned' => $unsigned,
'fixed' => $fixed,
'notnull' => $notnull,
'default' => $default,
@@ -412,7 +419,12 @@ class SqliteSchemaManager extends AbstractSchemaManager
];
}
- $list[$name]['local'][] = $value['from'];
+ $list[$name]['local'][] = $value['from'];
+
+ if ($value['to'] === null) {
+ continue;
+ }
+
$list[$name]['foreign'][] = $value['to'];
}
@@ -556,4 +568,13 @@ SQL
return $table;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getSchemaSearchPaths()
+ {
+ // SQLite does not support schemas or databases
+ return [];
+ }
}
diff --git a/doctrine/dbal/src/Schema/Table.php b/doctrine/dbal/src/Schema/Table.php
index 181e5dec..d330d03f 100644
--- a/doctrine/dbal/src/Schema/Table.php
+++ b/doctrine/dbal/src/Schema/Table.php
@@ -11,8 +11,6 @@ use function array_filter;
use function array_keys;
use function array_merge;
use function in_array;
-use function is_numeric;
-use function is_string;
use function preg_match;
use function strlen;
use function strtolower;
@@ -688,7 +686,7 @@ class Table extends AbstractAsset
{
$name = $this->normalizeIdentifier($name);
- if (! $this->hasForeignKey($name)) {
+ if (! $this->hasUniqueConstraint($name)) {
throw SchemaException::uniqueConstraintDoesNotExist($name, $this->_name);
}
@@ -737,7 +735,7 @@ class Table extends AbstractAsset
*/
private function filterColumns(array $columnNames, bool $reverse = false): array
{
- return array_filter($this->_columns, static function ($columnName) use ($columnNames, $reverse): bool {
+ return array_filter($this->_columns, static function (string $columnName) use ($columnNames, $reverse): bool {
return in_array($columnName, $columnNames, true) !== $reverse;
}, ARRAY_FILTER_USE_KEY);
}
@@ -967,11 +965,7 @@ class Table extends AbstractAsset
throw SchemaException::indexNameInvalid($indexName);
}
- foreach ($columnNames as $columnName => $indexColOptions) {
- if (is_numeric($columnName) && is_string($indexColOptions)) {
- $columnName = $indexColOptions;
- }
-
+ foreach ($columnNames as $columnName) {
if (! $this->hasColumn($columnName)) {
throw SchemaException::columnDoesNotExist($columnName, $this->_name);
}
diff --git a/doctrine/dbal/src/Schema/UniqueConstraint.php b/doctrine/dbal/src/Schema/UniqueConstraint.php
index 87a5f6e3..cb91becb 100644
--- a/doctrine/dbal/src/Schema/UniqueConstraint.php
+++ b/doctrine/dbal/src/Schema/UniqueConstraint.php
@@ -34,7 +34,7 @@ class UniqueConstraint extends AbstractAsset implements Constraint
*
* @var mixed[]
*/
- private $options = [];
+ private $options;
/**
* @param string[] $columns
diff --git a/doctrine/dbal/src/Schema/Visitor/DropSchemaSqlCollector.php b/doctrine/dbal/src/Schema/Visitor/DropSchemaSqlCollector.php
index 9f778109..1b77268b 100644
--- a/doctrine/dbal/src/Schema/Visitor/DropSchemaSqlCollector.php
+++ b/doctrine/dbal/src/Schema/Visitor/DropSchemaSqlCollector.php
@@ -32,7 +32,7 @@ class DropSchemaSqlCollector extends AbstractVisitor
public function __construct(AbstractPlatform $platform)
{
$this->platform = $platform;
- $this->clearQueries();
+ $this->initializeQueries();
}
/**
@@ -68,9 +68,7 @@ class DropSchemaSqlCollector extends AbstractVisitor
*/
public function clearQueries()
{
- $this->constraints = new SplObjectStorage();
- $this->sequences = new SplObjectStorage();
- $this->tables = new SplObjectStorage();
+ $this->initializeQueries();
}
/**
@@ -98,4 +96,11 @@ class DropSchemaSqlCollector extends AbstractVisitor
return $sql;
}
+
+ private function initializeQueries(): void
+ {
+ $this->constraints = new SplObjectStorage();
+ $this->sequences = new SplObjectStorage();
+ $this->tables = new SplObjectStorage();
+ }
}
diff --git a/doctrine/dbal/src/Schema/Visitor/RemoveNamespacedAssets.php b/doctrine/dbal/src/Schema/Visitor/RemoveNamespacedAssets.php
index 001ea2a0..509eac6f 100644
--- a/doctrine/dbal/src/Schema/Visitor/RemoveNamespacedAssets.php
+++ b/doctrine/dbal/src/Schema/Visitor/RemoveNamespacedAssets.php
@@ -20,7 +20,7 @@ use Doctrine\DBAL\Schema\Table;
*/
class RemoveNamespacedAssets extends AbstractVisitor
{
- /** @var Schema */
+ /** @var Schema|null */
private $schema;
/**
@@ -36,6 +36,10 @@ class RemoveNamespacedAssets extends AbstractVisitor
*/
public function acceptTable(Table $table)
{
+ if ($this->schema === null) {
+ return;
+ }
+
if ($table->isInDefaultNamespace($this->schema->getName())) {
return;
}
@@ -48,6 +52,10 @@ class RemoveNamespacedAssets extends AbstractVisitor
*/
public function acceptSequence(Sequence $sequence)
{
+ if ($this->schema === null) {
+ return;
+ }
+
if ($sequence->isInDefaultNamespace($this->schema->getName())) {
return;
}
@@ -60,6 +68,10 @@ class RemoveNamespacedAssets extends AbstractVisitor
*/
public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
{
+ if ($this->schema === null) {
+ return;
+ }
+
// The table may already be deleted in a previous
// RemoveNamespacedAssets#acceptTable call. Removing Foreign keys that
// point to nowhere.
diff --git a/doctrine/dbal/src/Statement.php b/doctrine/dbal/src/Statement.php
index d7a541a8..b7183fa3 100644
--- a/doctrine/dbal/src/Statement.php
+++ b/doctrine/dbal/src/Statement.php
@@ -6,7 +6,9 @@ use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
+use Doctrine\Deprecations\Deprecation;
+use function func_num_args;
use function is_string;
/**
@@ -146,7 +148,11 @@ class Statement
$this->types[$param] = $type;
try {
- return $this->stmt->bindParam($param, $variable, $type, $length);
+ if (func_num_args() > 3) {
+ return $this->stmt->bindParam($param, $variable, $type, $length);
+ }
+
+ return $this->stmt->bindParam($param, $variable, $type);
} catch (Exception $e) {
throw $this->conn->convertException($e);
}
@@ -155,12 +161,20 @@ class Statement
/**
* Executes the statement with the currently bound parameters.
*
+ * @deprecated Statement::execute() is deprecated, use Statement::executeQuery() or executeStatement() instead
+ *
* @param mixed[]|null $params
*
* @throws Exception
*/
public function execute($params = null): Result
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4580',
+ 'Statement::execute() is deprecated, use Statement::executeQuery() or Statement::executeStatement() instead'
+ );
+
if ($params !== null) {
$this->params = $params;
}
@@ -185,6 +199,38 @@ class Statement
}
/**
+ * Executes the statement with the currently bound parameters and return result.
+ *
+ * @param mixed[] $params
+ *
+ * @throws Exception
+ */
+ public function executeQuery(array $params = []): Result
+ {
+ if ($params === []) {
+ $params = null; // Workaround as long execute() exists and used internally.
+ }
+
+ return $this->execute($params);
+ }
+
+ /**
+ * Executes the statement with the currently bound parameters and return affected rows.
+ *
+ * @param mixed[] $params
+ *
+ * @throws Exception
+ */
+ public function executeStatement(array $params = []): int
+ {
+ if ($params === []) {
+ $params = null; // Workaround as long execute() exists and used internally.
+ }
+
+ return $this->execute($params)->rowCount();
+ }
+
+ /**
* Gets the wrapped driver statement.
*
* @return DriverStatement
diff --git a/doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php b/doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php
index a06e2d0f..8cff50f9 100644
--- a/doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php
+++ b/doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php
@@ -17,6 +17,7 @@ use Doctrine\DBAL\Platforms\Keywords\ReservedKeywordsValidator;
use Doctrine\DBAL\Platforms\Keywords\SQLiteKeywords;
use Doctrine\DBAL\Platforms\Keywords\SQLServer2012Keywords;
use Doctrine\DBAL\Tools\Console\ConnectionProvider;
+use Doctrine\Deprecations\Deprecation;
use InvalidArgumentException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
@@ -32,19 +33,8 @@ use function is_string;
class ReservedWordsCommand extends Command
{
- /** @var array<string,class-string<KeywordList>> */
- private $keywordListClasses = [
- 'db2' => DB2Keywords::class,
- 'mysql' => MySQLKeywords::class,
- 'mysql57' => MySQL57Keywords::class,
- 'mysql80' => MySQL80Keywords::class,
- 'mariadb102' => MariaDb102Keywords::class,
- 'oracle' => OracleKeywords::class,
- 'pgsql' => PostgreSQL94Keywords::class,
- 'pgsql100' => PostgreSQL100Keywords::class,
- 'sqlite' => SQLiteKeywords::class,
- 'sqlserver' => SQLServer2012Keywords::class,
- ];
+ /** @var array<string,KeywordList> */
+ private $keywordLists;
/** @var ConnectionProvider */
private $connectionProvider;
@@ -53,6 +43,27 @@ class ReservedWordsCommand extends Command
{
parent::__construct();
$this->connectionProvider = $connectionProvider;
+
+ $this->keywordLists = [
+ 'db2' => new DB2Keywords(),
+ 'mariadb102' => new MariaDb102Keywords(),
+ 'mysql' => new MySQLKeywords(),
+ 'mysql57' => new MySQL57Keywords(),
+ 'mysql80' => new MySQL80Keywords(),
+ 'oracle' => new OracleKeywords(),
+ 'pgsql' => new PostgreSQL94Keywords(),
+ 'pgsql100' => new PostgreSQL100Keywords(),
+ 'sqlite' => new SQLiteKeywords(),
+ 'sqlserver' => new SQLServer2012Keywords(),
+ ];
+ }
+
+ /**
+ * Add or replace a keyword list.
+ */
+ public function setKeywordList(string $name, KeywordList $keywordList): void
+ {
+ $this->keywordLists[$name] = $keywordList;
}
/**
@@ -65,7 +76,14 @@ class ReservedWordsCommand extends Command
*/
public function setKeywordListClass($name, $class)
{
- $this->keywordListClasses[$name] = $class;
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'ReservedWordsCommand::setKeywordListClass() is deprecated,'
+ . ' use ReservedWordsCommand::setKeywordList() instead.'
+ );
+
+ $this->keywordLists[$name] = new $class();
}
/** @return void */
@@ -87,8 +105,7 @@ class ReservedWordsCommand extends Command
Checks if the current database contains tables and columns
with names that are identifiers in this dialect or in other SQL dialects.
-By default SQLite, MySQL, PostgreSQL, Microsoft SQL Server and Oracle
-keywords are checked:
+By default all supported platform keywords are checked:
<info>%command.full_name%</info>
@@ -99,17 +116,16 @@ pass them to the command:
The following keyword lists are currently shipped with Doctrine:
+ * db2
+ * mariadb102
* mysql
* mysql57
* mysql80
- * mariadb102
+ * oracle
* pgsql
* pgsql100
* sqlite
- * oracle
* sqlserver
- * sqlserver2012
- * db2 (Not checked by default)
EOT
);
}
@@ -132,20 +148,19 @@ EOT
}
if (count($keywordLists) === 0) {
- $keywordLists = array_keys($this->keywordListClasses);
+ $keywordLists = array_keys($this->keywordLists);
}
$keywords = [];
foreach ($keywordLists as $keywordList) {
- if (! isset($this->keywordListClasses[$keywordList])) {
+ if (! isset($this->keywordLists[$keywordList])) {
throw new InvalidArgumentException(
"There exists no keyword list with name '" . $keywordList . "'. " .
- 'Known lists: ' . implode(', ', array_keys($this->keywordListClasses))
+ 'Known lists: ' . implode(', ', array_keys($this->keywordLists))
);
}
- $class = $this->keywordListClasses[$keywordList];
- $keywords[] = new $class();
+ $keywords[] = $this->keywordLists[$keywordList];
}
$output->write(
diff --git a/doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php b/doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php
index a4ba7d3b..4ccb3260 100644
--- a/doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php
+++ b/doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php
@@ -44,7 +44,7 @@ class RunSqlCommand extends Command
->setDefinition([
new InputOption('connection', null, InputOption::VALUE_REQUIRED, 'The named database connection'),
new InputArgument('sql', InputArgument::REQUIRED, 'The SQL statement to execute.'),
- new InputOption('depth', null, InputOption::VALUE_REQUIRED, 'Dumping depth of result set.', 7),
+ new InputOption('depth', null, InputOption::VALUE_REQUIRED, 'Dumping depth of result set.', '7'),
new InputOption('force-fetch', null, InputOption::VALUE_NONE, 'Forces fetching the result.'),
])
->setHelp(<<<EOT
diff --git a/doctrine/dbal/src/Tools/Console/ConsoleRunner.php b/doctrine/dbal/src/Tools/Console/ConsoleRunner.php
index 92998188..1cc315de 100644
--- a/doctrine/dbal/src/Tools/Console/ConsoleRunner.php
+++ b/doctrine/dbal/src/Tools/Console/ConsoleRunner.php
@@ -25,9 +25,7 @@ class ConsoleRunner
*/
public static function run(ConnectionProvider $connectionProvider, $commands = [])
{
- $cli = new Application('Doctrine Command Line Interface', Versions::getVersion(
- Versions::rootPackageName()
- ));
+ $cli = new Application('Doctrine Command Line Interface', Versions::getVersion('doctrine/dbal'));
$cli->setCatchExceptions(true);
self::addCommands($cli, $connectionProvider);
diff --git a/doctrine/dbal/src/Tools/Dumper.php b/doctrine/dbal/src/Tools/Dumper.php
index c1e72aa3..23dc7a05 100644
--- a/doctrine/dbal/src/Tools/Dumper.php
+++ b/doctrine/dbal/src/Tools/Dumper.php
@@ -86,8 +86,7 @@ final class Dumper
*/
public static function export($var, int $maxDepth)
{
- $return = null;
- $isObj = is_object($var);
+ $isObj = is_object($var);
if ($var instanceof Collection) {
$var = $var->toArray();
diff --git a/doctrine/dbal/src/Types/DecimalType.php b/doctrine/dbal/src/Types/DecimalType.php
index be76b7c8..f75d3db2 100644
--- a/doctrine/dbal/src/Types/DecimalType.php
+++ b/doctrine/dbal/src/Types/DecimalType.php
@@ -4,6 +4,10 @@ namespace Doctrine\DBAL\Types;
use Doctrine\DBAL\Platforms\AbstractPlatform;
+use function is_float;
+
+use const PHP_VERSION_ID;
+
/**
* Type that maps an SQL DECIMAL to a PHP string.
*/
@@ -30,6 +34,12 @@ class DecimalType extends Type
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
+ // Some drivers starting from PHP 8.1 can represent decimals as float
+ // See also: https://github.com/doctrine/dbal/pull/4818
+ if (PHP_VERSION_ID >= 80100 && is_float($value)) {
+ return (string) $value;
+ }
+
return $value;
}
}
diff --git a/doctrine/dbal/src/Types/Type.php b/doctrine/dbal/src/Types/Type.php
index f86a423e..03e5b824 100644
--- a/doctrine/dbal/src/Types/Type.php
+++ b/doctrine/dbal/src/Types/Type.php
@@ -108,9 +108,6 @@ abstract class Type
*/
abstract public function getName();
- /**
- * @internal This method is only to be used within DBAL for forward compatibility purposes. Do not use directly.
- */
final public static function getTypeRegistry(): TypeRegistry
{
if (self::$typeRegistry === null) {
diff --git a/doctrine/dbal/src/Types/TypeRegistry.php b/doctrine/dbal/src/Types/TypeRegistry.php
index fdae6d60..ce33b951 100644
--- a/doctrine/dbal/src/Types/TypeRegistry.php
+++ b/doctrine/dbal/src/Types/TypeRegistry.php
@@ -12,8 +12,6 @@ use function in_array;
/**
* The type registry is responsible for holding a map of all known DBAL types.
* The types are stored using the flyweight pattern so that one type only exists as exactly one instance.
- *
- * @internal TypeRegistry exists for forward compatibility, its API should not be considered stable.
*/
final class TypeRegistry
{
diff --git a/doctrine/dbal/static-analysis/driver-manager-retrieves-correct-connection-type.php b/doctrine/dbal/static-analysis/driver-manager-retrieves-correct-connection-type.php
new file mode 100644
index 00000000..566db247
--- /dev/null
+++ b/doctrine/dbal/static-analysis/driver-manager-retrieves-correct-connection-type.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\StaticAnalysis\DBAL;
+
+use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\DriverManager;
+
+final class MyConnection extends Connection
+{
+}
+
+function makeMeACustomConnection(): MyConnection
+{
+ return DriverManager::getConnection([
+ 'wrapperClass' => MyConnection::class,
+ ]);
+}
diff --git a/doctrine/deprecations/.gitignore b/doctrine/deprecations/.gitignore
new file mode 100644
index 00000000..2ee7dedc
--- /dev/null
+++ b/doctrine/deprecations/.gitignore
@@ -0,0 +1,3 @@
+vendor
+.phpcs-cache
+composer.lock
diff --git a/doctrine/deprecations/README.md b/doctrine/deprecations/README.md
new file mode 100644
index 00000000..d6682221
--- /dev/null
+++ b/doctrine/deprecations/README.md
@@ -0,0 +1,147 @@
+# Doctrine Deprecations
+
+A small (side-effect free by default) layer on top of
+`trigger_error(E_USER_DEPRECATED)` or PSR-3 logging.
+
+- no side-effects by default, making it a perfect fit for libraries that don't know how the error handler works they operate under
+- options to avoid having to rely on error handlers global state by using PSR-3 logging
+- deduplicate deprecation messages to avoid excessive triggering and reduce overhead
+
+We recommend to collect Deprecations using a PSR logger instead of relying on
+the global error handler.
+
+## Usage from consumer perspective:
+
+Enable Doctrine deprecations to be sent to a PSR3 logger:
+
+```php
+\Doctrine\Deprecations\Deprecation::enableWithPsrLogger($logger);
+```
+
+Enable Doctrine deprecations to be sent as `@trigger_error($message, E_USER_DEPRECATED)`
+messages.
+
+```php
+\Doctrine\Deprecations\Deprecation::enableWithTriggerError();
+```
+
+If you only want to enable deprecation tracking, without logging or calling `trigger_error` then call:
+
+```php
+\Doctrine\Deprecations\Deprecation::enableTrackingDeprecations();
+```
+
+Tracking is enabled with all three modes and provides access to all triggered
+deprecations and their individual count:
+
+```php
+$deprecations = \Doctrine\Deprecations\Deprecation::getTriggeredDeprecations();
+
+foreach ($deprecations as $identifier => $count) {
+ echo $identifier . " was triggered " . $count . " times\n";
+}
+```
+
+### Suppressing Specific Deprecations
+
+Disable triggering about specific deprecations:
+
+```php
+\Doctrine\Deprecations\Deprecation::ignoreDeprecations("https://link/to/deprecations-description-identifier");
+```
+
+Disable all deprecations from a package
+
+```php
+\Doctrine\Deprecations\Deprecation::ignorePackage("doctrine/orm");
+```
+
+### Other Operations
+
+When used within PHPUnit or other tools that could collect multiple instances of the same deprecations
+the deduplication can be disabled:
+
+```php
+\Doctrine\Deprecations\Deprecation::withoutDeduplication();
+```
+
+Disable deprecation tracking again:
+
+```php
+\Doctrine\Deprecations\Deprecation::disable();
+```
+
+## Usage from a library/producer perspective:
+
+When you want to unconditionally trigger a deprecation even when called
+from the library itself then the `trigger` method is the way to go:
+
+```php
+\Doctrine\Deprecations\Deprecation::trigger(
+ "doctrine/orm",
+ "https://link/to/deprecations-description",
+ "message"
+);
+```
+
+If variable arguments are provided at the end, they are used with `sprintf` on
+the message.
+
+```php
+\Doctrine\Deprecations\Deprecation::trigger(
+ "doctrine/orm",
+ "https://github.com/doctrine/orm/issue/1234",
+ "message %s %d",
+ "foo",
+ 1234
+);
+```
+
+When you want to trigger a deprecation only when it is called by a function
+outside of the current package, but not trigger when the package itself is the cause,
+then use:
+
+```php
+\Doctrine\Deprecations\Deprecation::triggerIfCalledFromOutside(
+ "doctrine/orm",
+ "https://link/to/deprecations-description",
+ "message"
+);
+```
+
+Based on the issue link each deprecation message is only triggered once per
+request.
+
+A limited stacktrace is included in the deprecation message to find the
+offending location.
+
+Note: A producer/library should never call `Deprecation::enableWith` methods
+and leave the decision how to handle deprecations to application and
+frameworks.
+
+## Usage in PHPUnit tests
+
+There is a `VerifyDeprecations` trait that you can use to make assertions on
+the occurrence of deprecations within a test.
+
+```php
+use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
+
+class MyTest extends TestCase
+{
+ use VerifyDeprecations;
+
+ public function testSomethingDeprecation()
+ {
+ $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/issue/1234');
+
+ triggerTheCodeWithDeprecation();
+ }
+}
+```
+
+## What is a deprecation identifier?
+
+An identifier for deprecations is just a link to any resource, most often a
+Github Issue or Pull Request explaining the deprecation and potentially its
+alternative.
diff --git a/doctrine/deprecations/composer.json b/doctrine/deprecations/composer.json
new file mode 100644
index 00000000..5cc7ac13
--- /dev/null
+++ b/doctrine/deprecations/composer.json
@@ -0,0 +1,27 @@
+{
+ "name": "doctrine/deprecations",
+ "type": "library",
+ "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+ "homepage": "https://www.doctrine-project.org/",
+ "license": "MIT",
+ "require": {
+ "php": "^7.1|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0|^8.0|^9.0",
+ "psr/log": "^1.0",
+ "doctrine/coding-standard": "^6.0|^7.0|^8.0"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ },
+ "autoload": {
+ "psr-4": {"Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"}
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "DeprecationTests\\": "test_fixtures/src",
+ "Doctrine\\Foo\\": "test_fixtures/vendor/doctrine/foo"
+ }
+ }
+}
diff --git a/doctrine/deprecations/lib/Doctrine/Deprecations/Deprecation.php b/doctrine/deprecations/lib/Doctrine/Deprecations/Deprecation.php
new file mode 100644
index 00000000..1029372f
--- /dev/null
+++ b/doctrine/deprecations/lib/Doctrine/Deprecations/Deprecation.php
@@ -0,0 +1,266 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\Deprecations;
+
+use Psr\Log\LoggerInterface;
+
+use function array_key_exists;
+use function array_reduce;
+use function debug_backtrace;
+use function sprintf;
+use function strpos;
+use function strrpos;
+use function substr;
+use function trigger_error;
+
+use const DEBUG_BACKTRACE_IGNORE_ARGS;
+use const DIRECTORY_SEPARATOR;
+use const E_USER_DEPRECATED;
+
+/**
+ * Manages Deprecation logging in different ways.
+ *
+ * By default triggered exceptions are not logged.
+ *
+ * To enable different deprecation logging mechanisms you can call the
+ * following methods:
+ *
+ * - Minimal collection of deprecations via getTriggeredDeprecations()
+ * \Doctrine\Deprecations\Deprecation::enableTrackingDeprecations();
+ *
+ * - Uses @trigger_error with E_USER_DEPRECATED
+ * \Doctrine\Deprecations\Deprecation::enableWithTriggerError();
+ *
+ * - Sends deprecation messages via a PSR-3 logger
+ * \Doctrine\Deprecations\Deprecation::enableWithPsrLogger($logger);
+ *
+ * Packages that trigger deprecations should use the `trigger()` or
+ * `triggerIfCalledFromOutside()` methods.
+ */
+class Deprecation
+{
+ private const TYPE_NONE = 0;
+ private const TYPE_TRACK_DEPRECATIONS = 1;
+ private const TYPE_TRIGGER_ERROR = 2;
+ private const TYPE_PSR_LOGGER = 4;
+
+ /** @var int */
+ private static $type = self::TYPE_NONE;
+
+ /** @var LoggerInterface|null */
+ private static $logger;
+
+ /** @var array<string,bool> */
+ private static $ignoredPackages = [];
+
+ /** @var array<string,int> */
+ private static $ignoredLinks = [];
+
+ /** @var bool */
+ private static $deduplication = true;
+
+ /**
+ * Trigger a deprecation for the given package and identfier.
+ *
+ * The link should point to a Github issue or Wiki entry detailing the
+ * deprecation. It is additionally used to de-duplicate the trigger of the
+ * same deprecation during a request.
+ *
+ * @param mixed $args
+ */
+ public static function trigger(string $package, string $link, string $message, ...$args): void
+ {
+ if (self::$type === self::TYPE_NONE) {
+ return;
+ }
+
+ if (array_key_exists($link, self::$ignoredLinks)) {
+ self::$ignoredLinks[$link]++;
+ } else {
+ self::$ignoredLinks[$link] = 1;
+ }
+
+ if (self::$deduplication === true && self::$ignoredLinks[$link] > 1) {
+ return;
+ }
+
+ if (isset(self::$ignoredPackages[$package])) {
+ return;
+ }
+
+ $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
+
+ $message = sprintf($message, ...$args);
+
+ self::delegateTriggerToBackend($message, $backtrace, $link, $package);
+ }
+
+ /**
+ * Trigger a deprecation for the given package and identifier when called from outside.
+ *
+ * "Outside" means we assume that $package is currently installed as a
+ * dependency and the caller is not a file in that package. When $package
+ * is installed as a root package then deprecations triggered from the
+ * tests folder are also considered "outside".
+ *
+ * This deprecation method assumes that you are using Composer to install
+ * the dependency and are using the default /vendor/ folder and not a
+ * Composer plugin to change the install location. The assumption is also
+ * that $package is the exact composer packge name.
+ *
+ * Compared to {@link trigger()} this method causes some overhead when
+ * deprecation tracking is enabled even during deduplication, because it
+ * needs to call {@link debug_backtrace()}
+ *
+ * @param mixed $args
+ */
+ public static function triggerIfCalledFromOutside(string $package, string $link, string $message, ...$args): void
+ {
+ if (self::$type === self::TYPE_NONE) {
+ return;
+ }
+
+ $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
+
+ // first check that the caller is not from a tests folder, in which case we always let deprecations pass
+ if (strpos($backtrace[1]['file'], DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR) === false) {
+ $path = DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package . DIRECTORY_SEPARATOR;
+
+ if (strpos($backtrace[0]['file'], $path) === false) {
+ return;
+ }
+
+ if (strpos($backtrace[1]['file'], $path) !== false) {
+ return;
+ }
+ }
+
+ if (array_key_exists($link, self::$ignoredLinks)) {
+ self::$ignoredLinks[$link]++;
+ } else {
+ self::$ignoredLinks[$link] = 1;
+ }
+
+ if (self::$deduplication === true && self::$ignoredLinks[$link] > 1) {
+ return;
+ }
+
+ if (isset(self::$ignoredPackages[$package])) {
+ return;
+ }
+
+ $message = sprintf($message, ...$args);
+
+ self::delegateTriggerToBackend($message, $backtrace, $link, $package);
+ }
+
+ /**
+ * @param array<mixed> $backtrace
+ */
+ private static function delegateTriggerToBackend(string $message, array $backtrace, string $link, string $package): void
+ {
+ if ((self::$type & self::TYPE_PSR_LOGGER) > 0) {
+ $context = [
+ 'file' => $backtrace[0]['file'],
+ 'line' => $backtrace[0]['line'],
+ 'package' => $package,
+ 'link' => $link,
+ ];
+
+ self::$logger->notice($message, $context);
+ }
+
+ if (! ((self::$type & self::TYPE_TRIGGER_ERROR) > 0)) {
+ return;
+ }
+
+ $message .= sprintf(
+ ' (%s:%d called by %s:%d, %s, package %s)',
+ self::basename($backtrace[0]['file']),
+ $backtrace[0]['line'],
+ self::basename($backtrace[1]['file']),
+ $backtrace[1]['line'],
+ $link,
+ $package
+ );
+
+ @trigger_error($message, E_USER_DEPRECATED);
+ }
+
+ /**
+ * A non-local-aware version of PHPs basename function.
+ */
+ private static function basename(string $filename): string
+ {
+ $pos = strrpos($filename, DIRECTORY_SEPARATOR);
+
+ if ($pos === false) {
+ return $filename;
+ }
+
+ return substr($filename, $pos + 1);
+ }
+
+ public static function enableTrackingDeprecations(): void
+ {
+ self::$type |= self::TYPE_TRACK_DEPRECATIONS;
+ }
+
+ public static function enableWithTriggerError(): void
+ {
+ self::$type |= self::TYPE_TRIGGER_ERROR;
+ }
+
+ public static function enableWithPsrLogger(LoggerInterface $logger): void
+ {
+ self::$type |= self::TYPE_PSR_LOGGER;
+ self::$logger = $logger;
+ }
+
+ public static function withoutDeduplication(): void
+ {
+ self::$deduplication = false;
+ }
+
+ public static function disable(): void
+ {
+ self::$type = self::TYPE_NONE;
+ self::$logger = null;
+ self::$deduplication = true;
+
+ foreach (self::$ignoredLinks as $link => $count) {
+ self::$ignoredLinks[$link] = 0;
+ }
+ }
+
+ public static function ignorePackage(string $packageName): void
+ {
+ self::$ignoredPackages[$packageName] = true;
+ }
+
+ public static function ignoreDeprecations(string ...$links): void
+ {
+ foreach ($links as $link) {
+ self::$ignoredLinks[$link] = 0;
+ }
+ }
+
+ public static function getUniqueTriggeredDeprecationsCount(): int
+ {
+ return array_reduce(self::$ignoredLinks, static function (int $carry, int $count) {
+ return $carry + $count;
+ }, 0);
+ }
+
+ /**
+ * Returns each triggered deprecation link identifier and the amount of occurrences.
+ *
+ * @return array<string,int>
+ */
+ public static function getTriggeredDeprecations(): array
+ {
+ return self::$ignoredLinks;
+ }
+}
diff --git a/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php b/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php
new file mode 100644
index 00000000..4c3366a9
--- /dev/null
+++ b/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php
@@ -0,0 +1,66 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\Deprecations\PHPUnit;
+
+use Doctrine\Deprecations\Deprecation;
+
+use function sprintf;
+
+trait VerifyDeprecations
+{
+ /** @var array<string,int> */
+ private $doctrineDeprecationsExpectations = [];
+
+ /** @var array<string,int> */
+ private $doctrineNoDeprecationsExpectations = [];
+
+ public function expectDeprecationWithIdentifier(string $identifier): void
+ {
+ $this->doctrineDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
+ }
+
+ public function expectNoDeprecationWithIdentifier(string $identifier): void
+ {
+ $this->doctrineNoDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
+ }
+
+ /**
+ * @before
+ */
+ public function enableDeprecationTracking(): void
+ {
+ Deprecation::enableTrackingDeprecations();
+ }
+
+ /**
+ * @after
+ */
+ public function verifyDeprecationsAreTriggered(): void
+ {
+ foreach ($this->doctrineDeprecationsExpectations as $identifier => $expectation) {
+ $actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
+
+ $this->assertTrue(
+ $actualCount > $expectation,
+ sprintf(
+ "Expected deprecation with identifier '%s' was not triggered by code executed in test.",
+ $identifier
+ )
+ );
+ }
+
+ foreach ($this->doctrineNoDeprecationsExpectations as $identifier => $expectation) {
+ $actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0;
+
+ $this->assertTrue(
+ $actualCount === $expectation,
+ sprintf(
+ "Expected deprecation with identifier '%s' was triggered by code executed in test, but expected not to.",
+ $identifier
+ )
+ );
+ }
+ }
+}
diff --git a/doctrine/deprecations/phpcs.xml b/doctrine/deprecations/phpcs.xml
new file mode 100644
index 00000000..4e0cc21f
--- /dev/null
+++ b/doctrine/deprecations/phpcs.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<ruleset>
+ <arg name="basepath" value="."/>
+ <arg name="extensions" value="php"/>
+ <arg name="parallel" value="80"/>
+ <arg name="cache" value=".phpcs-cache"/>
+ <arg name="colors"/>
+
+ <!-- Ignore warnings, show progress of the run and show sniff names -->
+ <arg value="nps"/>
+
+ <!-- Directories to be checked -->
+ <file>lib</file>
+ <file>tests</file>
+
+ <!-- Include full Doctrine Coding Standard -->
+ <rule ref="Doctrine">
+ <exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint" />
+ </rule>
+</ruleset>
diff --git a/doctrine/deprecations/phpunit.xml.dist b/doctrine/deprecations/phpunit.xml.dist
new file mode 100644
index 00000000..4740c060
--- /dev/null
+++ b/doctrine/deprecations/phpunit.xml.dist
@@ -0,0 +1,8 @@
+<?xml version="1.0" ?>
+<phpunit bootstrap="vendor/autoload.php">
+ <testsuites>
+ <testsuite name="Doctrine Deprecations">
+ <directory>tests</directory>
+ </testsuite>
+ </testsuites>
+</phpunit>
diff --git a/doctrine/deprecations/test_fixtures/src/Foo.php b/doctrine/deprecations/test_fixtures/src/Foo.php
new file mode 100644
index 00000000..c4b8ebec
--- /dev/null
+++ b/doctrine/deprecations/test_fixtures/src/Foo.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace DeprecationTests;
+
+use Doctrine\Foo\Bar;
+
+class Foo
+{
+ public static function triggerDependencyWithDeprecation(): void
+ {
+ $bar = new Bar();
+ $bar->oldFunc();
+ }
+
+ public static function triggerDependencyWithDeprecationFromInside(): void
+ {
+ $bar = new Bar();
+ $bar->newFunc();
+ }
+}
diff --git a/doctrine/deprecations/test_fixtures/src/RootDeprecation.php b/doctrine/deprecations/test_fixtures/src/RootDeprecation.php
new file mode 100644
index 00000000..feccd486
--- /dev/null
+++ b/doctrine/deprecations/test_fixtures/src/RootDeprecation.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace DeprecationTests;
+
+use Doctrine\Deprecations\Deprecation;
+
+class RootDeprecation
+{
+ public static function run()
+ {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/orm',
+ 'https://github.com/doctrine/deprecations/4444',
+ 'this is deprecated %s %d',
+ 'foo',
+ 1234
+ );
+
+ }
+}