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:
authordependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>2022-06-18 05:50:25 +0300
committernextcloud-command <nextcloud-command@users.noreply.github.com>2022-06-24 16:48:35 +0300
commit58cd2d57fb06b93e15c8d8c406c98f7ac6345227 (patch)
tree3d243fbbe0e9726847bec8f8b4d25a26c110993b
parentb7964c17e8a2198313ee31f6117c1eb692f6e2c9 (diff)
Bump doctrine/dbal from 3.1.4 to 3.3.7dependabot/composer/stable24/doctrine/dbal-3.3.7
Bumps [doctrine/dbal](https://github.com/doctrine/dbal) from 3.1.4 to 3.3.7. - [Release notes](https://github.com/doctrine/dbal/releases) - [Commits](https://github.com/doctrine/dbal/compare/3.1.4...3.3.7) --- updated-dependencies: - dependency-name: doctrine/dbal dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
-rw-r--r--composer.json2
-rw-r--r--composer.lock204
-rw-r--r--composer/InstalledVersions.php14
-rw-r--r--composer/autoload_classmap.php35
-rw-r--r--composer/autoload_psr4.php2
-rw-r--r--composer/autoload_static.php45
-rw-r--r--composer/installed.json216
-rw-r--r--composer/installed.php216
-rw-r--r--composer/package-versions-deprecated/CHANGELOG.md120
-rw-r--r--composer/package-versions-deprecated/CONTRIBUTING.md39
-rw-r--r--composer/package-versions-deprecated/README.md5
-rw-r--r--composer/package-versions-deprecated/SECURITY.md5
-rw-r--r--composer/package-versions-deprecated/composer.json48
-rw-r--r--composer/package-versions-deprecated/composer.lock2603
-rw-r--r--composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php128
-rw-r--r--composer/package-versions-deprecated/src/PackageVersions/Installer.php290
-rw-r--r--composer/package-versions-deprecated/src/PackageVersions/Versions.php92
-rw-r--r--doctrine/cache/UPGRADE-1.11.md12
-rw-r--r--doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php10
-rw-r--r--doctrine/dbal/README.md38
-rw-r--r--doctrine/dbal/composer.json30
-rw-r--r--doctrine/dbal/src/Cache/ArrayResult.php6
-rw-r--r--doctrine/dbal/src/Cache/CachingResult.php184
-rw-r--r--doctrine/dbal/src/Cache/QueryCacheProfile.php80
-rw-r--r--doctrine/dbal/src/Configuration.php49
-rw-r--r--doctrine/dbal/src/Connection.php240
-rw-r--r--doctrine/dbal/src/Driver/API/ExceptionConverter.php4
-rw-r--r--doctrine/dbal/src/Driver/API/IBMDB2/ExceptionConverter.php44
-rw-r--r--doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php5
-rw-r--r--doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php10
-rw-r--r--doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php8
-rw-r--r--doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php48
-rw-r--r--doctrine/dbal/src/Driver/API/SQLite/UserDefinedFunctions.php48
-rw-r--r--doctrine/dbal/src/Driver/AbstractDB2Driver.php6
-rw-r--r--doctrine/dbal/src/Driver/AbstractException.php2
-rw-r--r--doctrine/dbal/src/Driver/AbstractMySQLDriver.php16
-rw-r--r--doctrine/dbal/src/Driver/AbstractOracleDriver.php6
-rw-r--r--doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php14
-rw-r--r--doctrine/dbal/src/Driver/AbstractSQLServerDriver.php6
-rw-r--r--doctrine/dbal/src/Driver/AbstractSQLiteDriver.php6
-rw-r--r--doctrine/dbal/src/Driver/Connection.php5
-rw-r--r--doctrine/dbal/src/Driver/IBMDB2/Connection.php88
-rw-r--r--doctrine/dbal/src/Driver/IBMDB2/Driver.php28
-rw-r--r--doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionError.php7
-rw-r--r--doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionFailed.php7
-rw-r--r--doctrine/dbal/src/Driver/IBMDB2/Exception/Factory.php35
-rw-r--r--doctrine/dbal/src/Driver/IBMDB2/Exception/StatementError.php16
-rw-r--r--doctrine/dbal/src/Driver/IBMDB2/Statement.php6
-rw-r--r--doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php116
-rw-r--r--doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php61
-rw-r--r--doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php79
-rw-r--r--doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php42
-rw-r--r--doctrine/dbal/src/Driver/Mysqli/Connection.php141
-rw-r--r--doctrine/dbal/src/Driver/Mysqli/Driver.php43
-rw-r--r--doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php7
-rw-r--r--doctrine/dbal/src/Driver/Mysqli/Result.php15
-rw-r--r--doctrine/dbal/src/Driver/Mysqli/Statement.php98
-rw-r--r--doctrine/dbal/src/Driver/OCI8/Connection.php114
-rw-r--r--doctrine/dbal/src/Driver/OCI8/Driver.php40
-rw-r--r--doctrine/dbal/src/Driver/OCI8/Statement.php71
-rw-r--r--doctrine/dbal/src/Driver/PDO/Connection.php68
-rw-r--r--doctrine/dbal/src/Driver/PDO/Exception.php4
-rw-r--r--doctrine/dbal/src/Driver/PDO/MySQL/Driver.php24
-rw-r--r--doctrine/dbal/src/Driver/PDO/OCI/Driver.php24
-rw-r--r--doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php35
-rw-r--r--doctrine/dbal/src/Driver/PDO/Result.php9
-rw-r--r--doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php72
-rw-r--r--doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php27
-rw-r--r--doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php26
-rw-r--r--doctrine/dbal/src/Driver/PDO/SQLite/Driver.php35
-rw-r--r--doctrine/dbal/src/Driver/PDO/Statement.php19
-rw-r--r--doctrine/dbal/src/Driver/SQLSrv/Connection.php66
-rw-r--r--doctrine/dbal/src/Driver/SQLSrv/Driver.php16
-rw-r--r--doctrine/dbal/src/Driver/SQLSrv/Statement.php8
-rw-r--r--doctrine/dbal/src/Driver/ServerInfoAwareConnection.php5
-rw-r--r--doctrine/dbal/src/Driver/Statement.php8
-rw-r--r--doctrine/dbal/src/DriverManager.php22
-rw-r--r--doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php2
-rw-r--r--doctrine/dbal/src/Event/SchemaAlterTableChangeColumnEventArgs.php2
-rw-r--r--doctrine/dbal/src/Event/SchemaAlterTableEventArgs.php2
-rw-r--r--doctrine/dbal/src/Event/SchemaAlterTableRemoveColumnEventArgs.php2
-rw-r--r--doctrine/dbal/src/Event/SchemaAlterTableRenameColumnEventArgs.php2
-rw-r--r--doctrine/dbal/src/Event/SchemaColumnDefinitionEventArgs.php2
-rw-r--r--doctrine/dbal/src/Event/SchemaCreateTableColumnEventArgs.php2
-rw-r--r--doctrine/dbal/src/Event/SchemaCreateTableEventArgs.php2
-rw-r--r--doctrine/dbal/src/Event/SchemaDropTableEventArgs.php2
-rw-r--r--doctrine/dbal/src/Event/SchemaIndexDefinitionEventArgs.php2
-rw-r--r--doctrine/dbal/src/Event/TransactionBeginEventArgs.php9
-rw-r--r--doctrine/dbal/src/Event/TransactionCommitEventArgs.php9
-rw-r--r--doctrine/dbal/src/Event/TransactionEventArgs.php24
-rw-r--r--doctrine/dbal/src/Event/TransactionRollBackEventArgs.php9
-rw-r--r--doctrine/dbal/src/Events.php3
-rw-r--r--doctrine/dbal/src/Exception.php5
-rw-r--r--doctrine/dbal/src/Exception/DatabaseDoesNotExist.php10
-rw-r--r--doctrine/dbal/src/Exception/SchemaDoesNotExist.php10
-rw-r--r--doctrine/dbal/src/ExpandArrayParameters.php6
-rw-r--r--doctrine/dbal/src/Id/TableGenerator.php9
-rw-r--r--doctrine/dbal/src/Id/TableGeneratorSchemaVisitor.php10
-rw-r--r--doctrine/dbal/src/Logging/Connection.php85
-rw-r--r--doctrine/dbal/src/Logging/DebugStack.php13
-rw-r--r--doctrine/dbal/src/Logging/Driver.php56
-rw-r--r--doctrine/dbal/src/Logging/LoggerChain.php10
-rw-r--r--doctrine/dbal/src/Logging/Middleware.php25
-rw-r--r--doctrine/dbal/src/Logging/SQLLogger.php3
-rw-r--r--doctrine/dbal/src/Logging/Statement.php76
-rw-r--r--doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php1188
-rw-r--r--doctrine/dbal/src/Platforms/AbstractPlatform.php607
-rw-r--r--doctrine/dbal/src/Platforms/DB2Platform.php77
-rw-r--r--doctrine/dbal/src/Platforms/Keywords/KeywordList.php2
-rw-r--r--doctrine/dbal/src/Platforms/Keywords/MariaDBKeywords.php267
-rw-r--r--doctrine/dbal/src/Platforms/Keywords/MariaDb102Keywords.php259
-rw-r--r--doctrine/dbal/src/Platforms/Keywords/MySQL57Keywords.php2
-rw-r--r--doctrine/dbal/src/Platforms/Keywords/PostgreSQL100Keywords.php2
-rw-r--r--doctrine/dbal/src/Platforms/Keywords/PostgreSQL94Keywords.php119
-rw-r--r--doctrine/dbal/src/Platforms/Keywords/PostgreSQLKeywords.php125
-rw-r--r--doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php6
-rw-r--r--doctrine/dbal/src/Platforms/Keywords/SQLServer2012Keywords.php207
-rw-r--r--doctrine/dbal/src/Platforms/Keywords/SQLServerKeywords.php214
-rw-r--r--doctrine/dbal/src/Platforms/MariaDBPlatform.php44
-rw-r--r--doctrine/dbal/src/Platforms/MariaDb1027Platform.php39
-rw-r--r--doctrine/dbal/src/Platforms/MySQL/Comparator.php66
-rw-r--r--doctrine/dbal/src/Platforms/MySQL57Platform.php5
-rw-r--r--doctrine/dbal/src/Platforms/MySQL80Platform.php2
-rw-r--r--doctrine/dbal/src/Platforms/MySQLPlatform.php1189
-rw-r--r--doctrine/dbal/src/Platforms/OraclePlatform.php92
-rw-r--r--doctrine/dbal/src/Platforms/PostgreSQL100Platform.php5
-rw-r--r--doctrine/dbal/src/Platforms/PostgreSQL94Platform.php1301
-rw-r--r--doctrine/dbal/src/Platforms/PostgreSQLPlatform.php1276
-rw-r--r--doctrine/dbal/src/Platforms/SQLServer/Comparator.php56
-rw-r--r--doctrine/dbal/src/Platforms/SQLServer2012Platform.php1727
-rw-r--r--doctrine/dbal/src/Platforms/SQLServerPlatform.php1660
-rw-r--r--doctrine/dbal/src/Platforms/SQLite/Comparator.php53
-rw-r--r--doctrine/dbal/src/Platforms/SqlitePlatform.php92
-rw-r--r--doctrine/dbal/src/Portability/Connection.php61
-rw-r--r--doctrine/dbal/src/Portability/Converter.php2
-rw-r--r--doctrine/dbal/src/Portability/Driver.php61
-rw-r--r--doctrine/dbal/src/Portability/OptimizeFlags.php14
-rw-r--r--doctrine/dbal/src/Portability/Result.php36
-rw-r--r--doctrine/dbal/src/Portability/Statement.php28
-rw-r--r--doctrine/dbal/src/Query/Expression/ExpressionBuilder.php5
-rw-r--r--doctrine/dbal/src/Query/QueryBuilder.php33
-rw-r--r--doctrine/dbal/src/Result.php34
-rw-r--r--doctrine/dbal/src/SQL/Parser.php2
-rw-r--r--doctrine/dbal/src/Schema/AbstractAsset.php10
-rw-r--r--doctrine/dbal/src/Schema/AbstractSchemaManager.php186
-rw-r--r--doctrine/dbal/src/Schema/ColumnDiff.php11
-rw-r--r--doctrine/dbal/src/Schema/Comparator.php139
-rw-r--r--doctrine/dbal/src/Schema/Constraint.php2
-rw-r--r--doctrine/dbal/src/Schema/DB2SchemaManager.php7
-rw-r--r--doctrine/dbal/src/Schema/ForeignKeyConstraint.php14
-rw-r--r--doctrine/dbal/src/Schema/Index.php4
-rw-r--r--doctrine/dbal/src/Schema/MySQLSchemaManager.php33
-rw-r--r--doctrine/dbal/src/Schema/OracleSchemaManager.php18
-rw-r--r--doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php53
-rw-r--r--doctrine/dbal/src/Schema/SQLServerSchemaManager.php83
-rw-r--r--doctrine/dbal/src/Schema/Schema.php46
-rw-r--r--doctrine/dbal/src/Schema/SchemaConfig.php24
-rw-r--r--doctrine/dbal/src/Schema/SchemaDiff.php5
-rw-r--r--doctrine/dbal/src/Schema/SqliteSchemaManager.php76
-rw-r--r--doctrine/dbal/src/Schema/Table.php4
-rw-r--r--doctrine/dbal/src/Schema/Visitor/CreateSchemaSqlCollector.php2
-rw-r--r--doctrine/dbal/src/Schema/Visitor/Graphviz.php15
-rw-r--r--doctrine/dbal/src/Statement.php33
-rw-r--r--doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php44
-rw-r--r--doctrine/dbal/src/Tools/Console/ConsoleRunner.php11
-rw-r--r--doctrine/dbal/src/Tools/Dumper.php181
-rw-r--r--doctrine/dbal/src/Types/AsciiStringType.php7
-rw-r--r--doctrine/dbal/src/Types/BooleanType.php11
-rw-r--r--doctrine/dbal/src/Types/ConversionException.php10
-rw-r--r--doctrine/dbal/src/Types/DecimalType.php5
-rw-r--r--doctrine/dbal/src/Types/JsonType.php26
-rw-r--r--doctrine/dbal/src/Types/Type.php13
-rw-r--r--doctrine/dbal/src/VersionAwarePlatformDriver.php2
-rw-r--r--doctrine/deprecations/.gitignore3
-rw-r--r--doctrine/deprecations/LICENSE (renamed from composer/package-versions-deprecated/LICENSE)2
-rw-r--r--doctrine/deprecations/README.md7
-rw-r--r--doctrine/deprecations/composer.json11
-rw-r--r--doctrine/deprecations/phpcs.xml2
-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
-rw-r--r--psr/cache/LICENSE.txt19
-rw-r--r--psr/cache/README.md9
-rw-r--r--psr/cache/composer.json25
-rw-r--r--psr/cache/src/CacheException.php10
-rw-r--r--psr/cache/src/CacheItemInterface.php105
-rw-r--r--psr/cache/src/CacheItemPoolInterface.php138
-rw-r--r--psr/cache/src/InvalidArgumentException.php13
188 files changed, 8848 insertions, 10394 deletions
diff --git a/composer.json b/composer.json
index eeae51e5..b236fcd6 100644
--- a/composer.json
+++ b/composer.json
@@ -23,7 +23,7 @@
"cweagans/composer-patches": "^1.7",
"deepdiver/zipstreamer": "2.0.0",
"deepdiver1975/tarstreamer": "v2.0.0",
- "doctrine/dbal": "3.1.4",
+ "doctrine/dbal": "3.3.7",
"egulias/email-validator": "3.1.1",
"giggsey/libphonenumber-for-php": "^8.12.37",
"guzzlehttp/guzzle": "^7.4.0",
diff --git a/composer.lock b/composer.lock
index a03c64d6..1a450db2 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": "7461dcd296fb237e529761da75c52926",
+ "content-hash": "072f60e4e10d9a0f3f299c806a2a5eee",
"packages": [
{
"name": "aws/aws-sdk-php",
@@ -290,79 +290,6 @@
"time": "2021-11-29T15:02:22+00:00"
},
{
- "name": "composer/package-versions-deprecated",
- "version": "1.11.99.4",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/package-versions-deprecated.git",
- "reference": "b174585d1fe49ceed21928a945138948cb394600"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600",
- "reference": "b174585d1fe49ceed21928a945138948cb394600",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^1.1.0 || ^2.0",
- "php": "^7 || ^8"
- },
- "replace": {
- "ocramius/package-versions": "1.11.99"
- },
- "require-dev": {
- "composer/composer": "^1.9.3 || ^2.0@dev",
- "ext-zip": "^1.13",
- "phpunit/phpunit": "^6.5 || ^7"
- },
- "type": "composer-plugin",
- "extra": {
- "class": "PackageVersions\\Installer",
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "PackageVersions\\": "src/PackageVersions"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com"
- },
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be"
- }
- ],
- "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.4"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2021-09-13T08:41:34+00:00"
- },
- {
"name": "cweagans/composer-patches",
"version": "1.7.1",
"source": {
@@ -523,16 +450,16 @@
},
{
"name": "doctrine/cache",
- "version": "2.1.1",
+ "version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
- "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce"
+ "reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce",
- "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce",
+ "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
+ "reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
"shasum": ""
},
"require": {
@@ -542,18 +469,12 @@
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
- "alcaeus/mongo-php-adapter": "^1.1",
"cache/integration-tests": "dev-master",
- "doctrine/coding-standard": "^8.0",
- "mongodb/mongodb": "^1.1",
- "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
- "predis/predis": "~1.0",
+ "doctrine/coding-standard": "^9",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"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"
+ "symfony/cache": "^4.4 || ^5.4 || ^6",
+ "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
},
"type": "library",
"autoload": {
@@ -602,7 +523,7 @@
],
"support": {
"issues": "https://github.com/doctrine/cache/issues",
- "source": "https://github.com/doctrine/cache/tree/2.1.1"
+ "source": "https://github.com/doctrine/cache/tree/2.2.0"
},
"funding": [
{
@@ -618,40 +539,42 @@
"type": "tidelift"
}
],
- "time": "2021-07-17T14:49:29+00:00"
+ "time": "2022-05-20T20:07:39+00:00"
},
{
"name": "doctrine/dbal",
- "version": "3.1.4",
+ "version": "3.3.7",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
- "reference": "821b4f01a36ce63ed36c090ea74767b72db367e9"
+ "reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/dbal/zipball/821b4f01a36ce63ed36c090ea74767b72db367e9",
- "reference": "821b4f01a36ce63ed36c090ea74767b72db367e9",
+ "url": "https://api.github.com/repos/doctrine/dbal/zipball/9f79d4650430b582f4598fe0954ef4d52fbc0a8a",
+ "reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a",
"shasum": ""
},
"require": {
- "composer/package-versions-deprecated": "^1.11.99",
- "doctrine/cache": "^1.0|^2.0",
- "doctrine/deprecations": "^0.5.3",
+ "composer-runtime-api": "^2",
+ "doctrine/cache": "^1.11|^2.0",
+ "doctrine/deprecations": "^0.5.3|^1",
"doctrine/event-manager": "^1.0",
- "php": "^7.3 || ^8.0"
+ "php": "^7.3 || ^8.0",
+ "psr/cache": "^1|^2|^3",
+ "psr/log": "^1|^2|^3"
},
"require-dev": {
"doctrine/coding-standard": "9.0.0",
- "jetbrains/phpstorm-stubs": "2021.1",
- "phpstan/phpstan": "1.1.1",
- "phpstan/phpstan-strict-rules": "^1",
- "phpunit/phpunit": "9.5.10",
+ "jetbrains/phpstorm-stubs": "2022.1",
+ "phpstan/phpstan": "1.7.13",
+ "phpstan/phpstan-strict-rules": "^1.2",
+ "phpunit/phpunit": "9.5.20",
"psalm/plugin-phpunit": "0.16.1",
- "squizlabs/php_codesniffer": "3.6.1",
+ "squizlabs/php_codesniffer": "3.7.0",
"symfony/cache": "^5.2|^6.0",
- "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.0",
- "vimeo/psalm": "4.12.0"
+ "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
+ "vimeo/psalm": "4.23.0"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
@@ -711,7 +634,7 @@
],
"support": {
"issues": "https://github.com/doctrine/dbal/issues",
- "source": "https://github.com/doctrine/dbal/tree/3.1.4"
+ "source": "https://github.com/doctrine/dbal/tree/3.3.7"
},
"funding": [
{
@@ -727,29 +650,29 @@
"type": "tidelift"
}
],
- "time": "2021-11-15T16:44:33+00:00"
+ "time": "2022-06-13T21:43:03+00:00"
},
{
"name": "doctrine/deprecations",
- "version": "v0.5.3",
+ "version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/deprecations.git",
- "reference": "9504165960a1f83cc1480e2be1dd0a0478561314"
+ "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/deprecations/zipball/9504165960a1f83cc1480e2be1dd0a0478561314",
- "reference": "9504165960a1f83cc1480e2be1dd0a0478561314",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
+ "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
"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"
+ "doctrine/coding-standard": "^9",
+ "phpunit/phpunit": "^7.5|^8.5|^9.5",
+ "psr/log": "^1|^2|^3"
},
"suggest": {
"psr/log": "Allows logging deprecations via PSR-3 logger implementation"
@@ -768,9 +691,9 @@
"homepage": "https://www.doctrine-project.org/",
"support": {
"issues": "https://github.com/doctrine/deprecations/issues",
- "source": "https://github.com/doctrine/deprecations/tree/v0.5.3"
+ "source": "https://github.com/doctrine/deprecations/tree/v1.0.0"
},
- "time": "2021-03-21T12:59:47+00:00"
+ "time": "2022-05-02T15:47:09+00:00"
},
{
"name": "doctrine/event-manager",
@@ -2961,6 +2884,55 @@
"time": "2021-10-28T11:13:42+00:00"
},
{
+ "name": "psr/cache",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/cache.git",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Cache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for caching libraries",
+ "keywords": [
+ "cache",
+ "psr",
+ "psr-6"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/cache/tree/master"
+ },
+ "time": "2016-08-06T20:24:11+00:00"
+ },
+ {
"name": "psr/container",
"version": "1.1.1",
"source": {
diff --git a/composer/InstalledVersions.php b/composer/InstalledVersions.php
index 41bc143c..c6b54af7 100644
--- a/composer/InstalledVersions.php
+++ b/composer/InstalledVersions.php
@@ -28,7 +28,7 @@ class InstalledVersions
{
/**
* @var mixed[]|null
- * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
+ * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
@@ -39,7 +39,7 @@ class InstalledVersions
/**
* @var array[]
- * @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
+ * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
@@ -243,7 +243,7 @@ class InstalledVersions
/**
* @return array
- * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
+ * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
@@ -257,7 +257,7 @@ class InstalledVersions
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
- * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
+ * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@@ -280,7 +280,7 @@ class InstalledVersions
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
- * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
+ * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
@@ -303,7 +303,7 @@ class InstalledVersions
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
- * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
+ * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
@@ -313,7 +313,7 @@ class InstalledVersions
/**
* @return array[]
- * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
+ * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php
index 7092f706..7f3568a7 100644
--- a/composer/autoload_classmap.php
+++ b/composer/autoload_classmap.php
@@ -924,7 +924,6 @@ return array(
'Doctrine\\DBAL\\ArrayParameters\\Exception\\MissingPositionalParameter' => $vendorDir . '/doctrine/dbal/src/ArrayParameters/Exception/MissingPositionalParameter.php',
'Doctrine\\DBAL\\Cache\\ArrayResult' => $vendorDir . '/doctrine/dbal/src/Cache/ArrayResult.php',
'Doctrine\\DBAL\\Cache\\CacheException' => $vendorDir . '/doctrine/dbal/src/Cache/CacheException.php',
- 'Doctrine\\DBAL\\Cache\\CachingResult' => $vendorDir . '/doctrine/dbal/src/Cache/CachingResult.php',
'Doctrine\\DBAL\\Cache\\QueryCacheProfile' => $vendorDir . '/doctrine/dbal/src/Cache/QueryCacheProfile.php',
'Doctrine\\DBAL\\ColumnCase' => $vendorDir . '/doctrine/dbal/src/ColumnCase.php',
'Doctrine\\DBAL\\Configuration' => $vendorDir . '/doctrine/dbal/src/Configuration.php',
@@ -940,6 +939,7 @@ return array(
'Doctrine\\DBAL\\Driver\\API\\PostgreSQL\\ExceptionConverter' => $vendorDir . '/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php',
'Doctrine\\DBAL\\Driver\\API\\SQLSrv\\ExceptionConverter' => $vendorDir . '/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php',
'Doctrine\\DBAL\\Driver\\API\\SQLite\\ExceptionConverter' => $vendorDir . '/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php',
+ 'Doctrine\\DBAL\\Driver\\API\\SQLite\\UserDefinedFunctions' => $vendorDir . '/doctrine/dbal/src/Driver/API/SQLite/UserDefinedFunctions.php',
'Doctrine\\DBAL\\Driver\\AbstractDB2Driver' => $vendorDir . '/doctrine/dbal/src/Driver/AbstractDB2Driver.php',
'Doctrine\\DBAL\\Driver\\AbstractException' => $vendorDir . '/doctrine/dbal/src/Driver/AbstractException.php',
'Doctrine\\DBAL\\Driver\\AbstractMySQLDriver' => $vendorDir . '/doctrine/dbal/src/Driver/AbstractMySQLDriver.php',
@@ -961,11 +961,16 @@ return array(
'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\CannotWriteToTemporaryFile' => $vendorDir . '/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotWriteToTemporaryFile.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\ConnectionError' => $vendorDir . '/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionError.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\ConnectionFailed' => $vendorDir . '/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionFailed.php',
+ 'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\Factory' => $vendorDir . '/doctrine/dbal/src/Driver/IBMDB2/Exception/Factory.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\PrepareFailed' => $vendorDir . '/doctrine/dbal/src/Driver/IBMDB2/Exception/PrepareFailed.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\StatementError' => $vendorDir . '/doctrine/dbal/src/Driver/IBMDB2/Exception/StatementError.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Result' => $vendorDir . '/doctrine/dbal/src/Driver/IBMDB2/Result.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Statement' => $vendorDir . '/doctrine/dbal/src/Driver/IBMDB2/Statement.php',
'Doctrine\\DBAL\\Driver\\Middleware' => $vendorDir . '/doctrine/dbal/src/Driver/Middleware.php',
+ 'Doctrine\\DBAL\\Driver\\Middleware\\AbstractConnectionMiddleware' => $vendorDir . '/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php',
+ 'Doctrine\\DBAL\\Driver\\Middleware\\AbstractDriverMiddleware' => $vendorDir . '/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php',
+ 'Doctrine\\DBAL\\Driver\\Middleware\\AbstractResultMiddleware' => $vendorDir . '/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php',
+ 'Doctrine\\DBAL\\Driver\\Middleware\\AbstractStatementMiddleware' => $vendorDir . '/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php',
'Doctrine\\DBAL\\Driver\\Mysqli\\Connection' => $vendorDir . '/doctrine/dbal/src/Driver/Mysqli/Connection.php',
'Doctrine\\DBAL\\Driver\\Mysqli\\Driver' => $vendorDir . '/doctrine/dbal/src/Driver/Mysqli/Driver.php',
'Doctrine\\DBAL\\Driver\\Mysqli\\Exception\\ConnectionError' => $vendorDir . '/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionError.php',
@@ -1026,11 +1031,16 @@ return array(
'Doctrine\\DBAL\\Event\\SchemaDropTableEventArgs' => $vendorDir . '/doctrine/dbal/src/Event/SchemaDropTableEventArgs.php',
'Doctrine\\DBAL\\Event\\SchemaEventArgs' => $vendorDir . '/doctrine/dbal/src/Event/SchemaEventArgs.php',
'Doctrine\\DBAL\\Event\\SchemaIndexDefinitionEventArgs' => $vendorDir . '/doctrine/dbal/src/Event/SchemaIndexDefinitionEventArgs.php',
+ 'Doctrine\\DBAL\\Event\\TransactionBeginEventArgs' => $vendorDir . '/doctrine/dbal/src/Event/TransactionBeginEventArgs.php',
+ 'Doctrine\\DBAL\\Event\\TransactionCommitEventArgs' => $vendorDir . '/doctrine/dbal/src/Event/TransactionCommitEventArgs.php',
+ 'Doctrine\\DBAL\\Event\\TransactionEventArgs' => $vendorDir . '/doctrine/dbal/src/Event/TransactionEventArgs.php',
+ 'Doctrine\\DBAL\\Event\\TransactionRollBackEventArgs' => $vendorDir . '/doctrine/dbal/src/Event/TransactionRollBackEventArgs.php',
'Doctrine\\DBAL\\Events' => $vendorDir . '/doctrine/dbal/src/Events.php',
'Doctrine\\DBAL\\Exception' => $vendorDir . '/doctrine/dbal/src/Exception.php',
'Doctrine\\DBAL\\Exception\\ConnectionException' => $vendorDir . '/doctrine/dbal/src/Exception/ConnectionException.php',
'Doctrine\\DBAL\\Exception\\ConnectionLost' => $vendorDir . '/doctrine/dbal/src/Exception/ConnectionLost.php',
'Doctrine\\DBAL\\Exception\\ConstraintViolationException' => $vendorDir . '/doctrine/dbal/src/Exception/ConstraintViolationException.php',
+ 'Doctrine\\DBAL\\Exception\\DatabaseDoesNotExist' => $vendorDir . '/doctrine/dbal/src/Exception/DatabaseDoesNotExist.php',
'Doctrine\\DBAL\\Exception\\DatabaseObjectExistsException' => $vendorDir . '/doctrine/dbal/src/Exception/DatabaseObjectExistsException.php',
'Doctrine\\DBAL\\Exception\\DatabaseObjectNotFoundException' => $vendorDir . '/doctrine/dbal/src/Exception/DatabaseObjectNotFoundException.php',
'Doctrine\\DBAL\\Exception\\DeadlockException' => $vendorDir . '/doctrine/dbal/src/Exception/DeadlockException.php',
@@ -1045,6 +1055,7 @@ return array(
'Doctrine\\DBAL\\Exception\\NotNullConstraintViolationException' => $vendorDir . '/doctrine/dbal/src/Exception/NotNullConstraintViolationException.php',
'Doctrine\\DBAL\\Exception\\ReadOnlyException' => $vendorDir . '/doctrine/dbal/src/Exception/ReadOnlyException.php',
'Doctrine\\DBAL\\Exception\\RetryableException' => $vendorDir . '/doctrine/dbal/src/Exception/RetryableException.php',
+ 'Doctrine\\DBAL\\Exception\\SchemaDoesNotExist' => $vendorDir . '/doctrine/dbal/src/Exception/SchemaDoesNotExist.php',
'Doctrine\\DBAL\\Exception\\ServerException' => $vendorDir . '/doctrine/dbal/src/Exception/ServerException.php',
'Doctrine\\DBAL\\Exception\\SyntaxErrorException' => $vendorDir . '/doctrine/dbal/src/Exception/SyntaxErrorException.php',
'Doctrine\\DBAL\\Exception\\TableExistsException' => $vendorDir . '/doctrine/dbal/src/Exception/TableExistsException.php',
@@ -1055,15 +1066,21 @@ return array(
'Doctrine\\DBAL\\Id\\TableGenerator' => $vendorDir . '/doctrine/dbal/src/Id/TableGenerator.php',
'Doctrine\\DBAL\\Id\\TableGeneratorSchemaVisitor' => $vendorDir . '/doctrine/dbal/src/Id/TableGeneratorSchemaVisitor.php',
'Doctrine\\DBAL\\LockMode' => $vendorDir . '/doctrine/dbal/src/LockMode.php',
+ 'Doctrine\\DBAL\\Logging\\Connection' => $vendorDir . '/doctrine/dbal/src/Logging/Connection.php',
'Doctrine\\DBAL\\Logging\\DebugStack' => $vendorDir . '/doctrine/dbal/src/Logging/DebugStack.php',
+ 'Doctrine\\DBAL\\Logging\\Driver' => $vendorDir . '/doctrine/dbal/src/Logging/Driver.php',
'Doctrine\\DBAL\\Logging\\LoggerChain' => $vendorDir . '/doctrine/dbal/src/Logging/LoggerChain.php',
+ 'Doctrine\\DBAL\\Logging\\Middleware' => $vendorDir . '/doctrine/dbal/src/Logging/Middleware.php',
'Doctrine\\DBAL\\Logging\\SQLLogger' => $vendorDir . '/doctrine/dbal/src/Logging/SQLLogger.php',
+ 'Doctrine\\DBAL\\Logging\\Statement' => $vendorDir . '/doctrine/dbal/src/Logging/Statement.php',
'Doctrine\\DBAL\\ParameterType' => $vendorDir . '/doctrine/dbal/src/ParameterType.php',
+ 'Doctrine\\DBAL\\Platforms\\AbstractMySQLPlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php',
'Doctrine\\DBAL\\Platforms\\AbstractPlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/AbstractPlatform.php',
'Doctrine\\DBAL\\Platforms\\DB2Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/DB2Platform.php',
'Doctrine\\DBAL\\Platforms\\DateIntervalUnit' => $vendorDir . '/doctrine/dbal/src/Platforms/DateIntervalUnit.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\DB2Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/DB2Keywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\KeywordList' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/KeywordList.php',
+ 'Doctrine\\DBAL\\Platforms\\Keywords\\MariaDBKeywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/MariaDBKeywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\MariaDb102Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/MariaDb102Keywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\MySQL57Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/MySQL57Keywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\MySQL80Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/MySQL80Keywords.php',
@@ -1071,17 +1088,25 @@ return array(
'Doctrine\\DBAL\\Platforms\\Keywords\\OracleKeywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/OracleKeywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\PostgreSQL100Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/PostgreSQL100Keywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\PostgreSQL94Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/PostgreSQL94Keywords.php',
+ 'Doctrine\\DBAL\\Platforms\\Keywords\\PostgreSQLKeywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/PostgreSQLKeywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\ReservedKeywordsValidator' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\SQLServer2012Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/SQLServer2012Keywords.php',
+ 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLServerKeywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/SQLServerKeywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\SQLiteKeywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/SQLiteKeywords.php',
+ 'Doctrine\\DBAL\\Platforms\\MariaDBPlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDBPlatform.php',
'Doctrine\\DBAL\\Platforms\\MariaDb1027Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDb1027Platform.php',
'Doctrine\\DBAL\\Platforms\\MySQL57Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MySQL57Platform.php',
'Doctrine\\DBAL\\Platforms\\MySQL80Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MySQL80Platform.php',
'Doctrine\\DBAL\\Platforms\\MySQLPlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/MySQLPlatform.php',
+ 'Doctrine\\DBAL\\Platforms\\MySQL\\Comparator' => $vendorDir . '/doctrine/dbal/src/Platforms/MySQL/Comparator.php',
'Doctrine\\DBAL\\Platforms\\OraclePlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/OraclePlatform.php',
'Doctrine\\DBAL\\Platforms\\PostgreSQL100Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php',
'Doctrine\\DBAL\\Platforms\\PostgreSQL94Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php',
+ 'Doctrine\\DBAL\\Platforms\\PostgreSQLPlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/PostgreSQLPlatform.php',
'Doctrine\\DBAL\\Platforms\\SQLServer2012Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/SQLServer2012Platform.php',
+ 'Doctrine\\DBAL\\Platforms\\SQLServerPlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/SQLServerPlatform.php',
+ 'Doctrine\\DBAL\\Platforms\\SQLServer\\Comparator' => $vendorDir . '/doctrine/dbal/src/Platforms/SQLServer/Comparator.php',
+ 'Doctrine\\DBAL\\Platforms\\SQLite\\Comparator' => $vendorDir . '/doctrine/dbal/src/Platforms/SQLite/Comparator.php',
'Doctrine\\DBAL\\Platforms\\SqlitePlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/SqlitePlatform.php',
'Doctrine\\DBAL\\Platforms\\TrimMode' => $vendorDir . '/doctrine/dbal/src/Platforms/TrimMode.php',
'Doctrine\\DBAL\\Portability\\Connection' => $vendorDir . '/doctrine/dbal/src/Portability/Connection.php',
@@ -1142,7 +1167,6 @@ return array(
'Doctrine\\DBAL\\Tools\\Console\\ConnectionProvider' => $vendorDir . '/doctrine/dbal/src/Tools/Console/ConnectionProvider.php',
'Doctrine\\DBAL\\Tools\\Console\\ConnectionProvider\\SingleConnectionProvider' => $vendorDir . '/doctrine/dbal/src/Tools/Console/ConnectionProvider/SingleConnectionProvider.php',
'Doctrine\\DBAL\\Tools\\Console\\ConsoleRunner' => $vendorDir . '/doctrine/dbal/src/Tools/Console/ConsoleRunner.php',
- 'Doctrine\\DBAL\\Tools\\Dumper' => $vendorDir . '/doctrine/dbal/src/Tools/Dumper.php',
'Doctrine\\DBAL\\TransactionIsolationLevel' => $vendorDir . '/doctrine/dbal/src/TransactionIsolationLevel.php',
'Doctrine\\DBAL\\Types\\ArrayType' => $vendorDir . '/doctrine/dbal/src/Types/ArrayType.php',
'Doctrine\\DBAL\\Types\\AsciiStringType' => $vendorDir . '/doctrine/dbal/src/Types/AsciiStringType.php',
@@ -1813,9 +1837,6 @@ return array(
'PEAR' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php',
'PEAR_ErrorStack' => $vendorDir . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php',
'PEAR_Exception' => $vendorDir . '/pear/pear_exception/PEAR/Exception.php',
- 'PackageVersions\\FallbackVersions' => $vendorDir . '/composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php',
- 'PackageVersions\\Installer' => $vendorDir . '/composer/package-versions-deprecated/src/PackageVersions/Installer.php',
- 'PackageVersions\\Versions' => $vendorDir . '/composer/package-versions-deprecated/src/PackageVersions/Versions.php',
'PhpParser\\Builder' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder.php',
'PhpParser\\BuilderFactory' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php',
'PhpParser\\BuilderHelpers' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderHelpers.php',
@@ -2066,6 +2087,10 @@ return array(
'Pimple\\Psr11\\ServiceLocator' => $vendorDir . '/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php',
'Pimple\\ServiceIterator' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceIterator.php',
'Pimple\\ServiceProviderInterface' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
+ 'Psr\\Cache\\CacheException' => $vendorDir . '/psr/cache/src/CacheException.php',
+ 'Psr\\Cache\\CacheItemInterface' => $vendorDir . '/psr/cache/src/CacheItemInterface.php',
+ 'Psr\\Cache\\CacheItemPoolInterface' => $vendorDir . '/psr/cache/src/CacheItemPoolInterface.php',
+ 'Psr\\Cache\\InvalidArgumentException' => $vendorDir . '/psr/cache/src/InvalidArgumentException.php',
'Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php',
'Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php',
'Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php',
diff --git a/composer/autoload_psr4.php b/composer/autoload_psr4.php
index 518c268b..9bc21fdc 100644
--- a/composer/autoload_psr4.php
+++ b/composer/autoload_psr4.php
@@ -52,8 +52,8 @@ return array(
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'),
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
+ 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
- 'PackageVersions\\' => array($vendorDir . '/composer/package-versions-deprecated/src/PackageVersions'),
'Opis\\Closure\\' => array($vendorDir . '/opis/closure/src'),
'OpenStack\\' => array($vendorDir . '/php-opencloud/openstack/src'),
'Nextcloud\\LogNormalizer\\' => array($vendorDir . '/nextcloud/lognormalizer/src'),
diff --git a/composer/autoload_static.php b/composer/autoload_static.php
index 94aa4916..c579fbe2 100644
--- a/composer/autoload_static.php
+++ b/composer/autoload_static.php
@@ -202,8 +202,8 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Psr\\Http\\Client\\' => 16,
'Psr\\EventDispatcher\\' => 20,
'Psr\\Container\\' => 14,
+ 'Psr\\Cache\\' => 10,
'PhpParser\\' => 10,
- 'PackageVersions\\' => 16,
),
'O' =>
array (
@@ -469,13 +469,13 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
array (
0 => __DIR__ . '/..' . '/psr/container/src',
),
- 'PhpParser\\' =>
+ 'Psr\\Cache\\' =>
array (
- 0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser',
+ 0 => __DIR__ . '/..' . '/psr/cache/src',
),
- 'PackageVersions\\' =>
+ 'PhpParser\\' =>
array (
- 0 => __DIR__ . '/..' . '/composer/package-versions-deprecated/src/PackageVersions',
+ 0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser',
),
'Opis\\Closure\\' =>
array (
@@ -1555,7 +1555,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Doctrine\\DBAL\\ArrayParameters\\Exception\\MissingPositionalParameter' => __DIR__ . '/..' . '/doctrine/dbal/src/ArrayParameters/Exception/MissingPositionalParameter.php',
'Doctrine\\DBAL\\Cache\\ArrayResult' => __DIR__ . '/..' . '/doctrine/dbal/src/Cache/ArrayResult.php',
'Doctrine\\DBAL\\Cache\\CacheException' => __DIR__ . '/..' . '/doctrine/dbal/src/Cache/CacheException.php',
- 'Doctrine\\DBAL\\Cache\\CachingResult' => __DIR__ . '/..' . '/doctrine/dbal/src/Cache/CachingResult.php',
'Doctrine\\DBAL\\Cache\\QueryCacheProfile' => __DIR__ . '/..' . '/doctrine/dbal/src/Cache/QueryCacheProfile.php',
'Doctrine\\DBAL\\ColumnCase' => __DIR__ . '/..' . '/doctrine/dbal/src/ColumnCase.php',
'Doctrine\\DBAL\\Configuration' => __DIR__ . '/..' . '/doctrine/dbal/src/Configuration.php',
@@ -1571,6 +1570,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Doctrine\\DBAL\\Driver\\API\\PostgreSQL\\ExceptionConverter' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php',
'Doctrine\\DBAL\\Driver\\API\\SQLSrv\\ExceptionConverter' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php',
'Doctrine\\DBAL\\Driver\\API\\SQLite\\ExceptionConverter' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php',
+ 'Doctrine\\DBAL\\Driver\\API\\SQLite\\UserDefinedFunctions' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/API/SQLite/UserDefinedFunctions.php',
'Doctrine\\DBAL\\Driver\\AbstractDB2Driver' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/AbstractDB2Driver.php',
'Doctrine\\DBAL\\Driver\\AbstractException' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/AbstractException.php',
'Doctrine\\DBAL\\Driver\\AbstractMySQLDriver' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/AbstractMySQLDriver.php',
@@ -1592,11 +1592,16 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\CannotWriteToTemporaryFile' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotWriteToTemporaryFile.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\ConnectionError' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionError.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\ConnectionFailed' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionFailed.php',
+ 'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\Factory' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/IBMDB2/Exception/Factory.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\PrepareFailed' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/IBMDB2/Exception/PrepareFailed.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Exception\\StatementError' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/IBMDB2/Exception/StatementError.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Result' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/IBMDB2/Result.php',
'Doctrine\\DBAL\\Driver\\IBMDB2\\Statement' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/IBMDB2/Statement.php',
'Doctrine\\DBAL\\Driver\\Middleware' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/Middleware.php',
+ 'Doctrine\\DBAL\\Driver\\Middleware\\AbstractConnectionMiddleware' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php',
+ 'Doctrine\\DBAL\\Driver\\Middleware\\AbstractDriverMiddleware' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php',
+ 'Doctrine\\DBAL\\Driver\\Middleware\\AbstractResultMiddleware' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php',
+ 'Doctrine\\DBAL\\Driver\\Middleware\\AbstractStatementMiddleware' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php',
'Doctrine\\DBAL\\Driver\\Mysqli\\Connection' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/Mysqli/Connection.php',
'Doctrine\\DBAL\\Driver\\Mysqli\\Driver' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/Mysqli/Driver.php',
'Doctrine\\DBAL\\Driver\\Mysqli\\Exception\\ConnectionError' => __DIR__ . '/..' . '/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionError.php',
@@ -1657,11 +1662,16 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Doctrine\\DBAL\\Event\\SchemaDropTableEventArgs' => __DIR__ . '/..' . '/doctrine/dbal/src/Event/SchemaDropTableEventArgs.php',
'Doctrine\\DBAL\\Event\\SchemaEventArgs' => __DIR__ . '/..' . '/doctrine/dbal/src/Event/SchemaEventArgs.php',
'Doctrine\\DBAL\\Event\\SchemaIndexDefinitionEventArgs' => __DIR__ . '/..' . '/doctrine/dbal/src/Event/SchemaIndexDefinitionEventArgs.php',
+ 'Doctrine\\DBAL\\Event\\TransactionBeginEventArgs' => __DIR__ . '/..' . '/doctrine/dbal/src/Event/TransactionBeginEventArgs.php',
+ 'Doctrine\\DBAL\\Event\\TransactionCommitEventArgs' => __DIR__ . '/..' . '/doctrine/dbal/src/Event/TransactionCommitEventArgs.php',
+ 'Doctrine\\DBAL\\Event\\TransactionEventArgs' => __DIR__ . '/..' . '/doctrine/dbal/src/Event/TransactionEventArgs.php',
+ 'Doctrine\\DBAL\\Event\\TransactionRollBackEventArgs' => __DIR__ . '/..' . '/doctrine/dbal/src/Event/TransactionRollBackEventArgs.php',
'Doctrine\\DBAL\\Events' => __DIR__ . '/..' . '/doctrine/dbal/src/Events.php',
'Doctrine\\DBAL\\Exception' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception.php',
'Doctrine\\DBAL\\Exception\\ConnectionException' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/ConnectionException.php',
'Doctrine\\DBAL\\Exception\\ConnectionLost' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/ConnectionLost.php',
'Doctrine\\DBAL\\Exception\\ConstraintViolationException' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/ConstraintViolationException.php',
+ 'Doctrine\\DBAL\\Exception\\DatabaseDoesNotExist' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/DatabaseDoesNotExist.php',
'Doctrine\\DBAL\\Exception\\DatabaseObjectExistsException' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/DatabaseObjectExistsException.php',
'Doctrine\\DBAL\\Exception\\DatabaseObjectNotFoundException' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/DatabaseObjectNotFoundException.php',
'Doctrine\\DBAL\\Exception\\DeadlockException' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/DeadlockException.php',
@@ -1676,6 +1686,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Doctrine\\DBAL\\Exception\\NotNullConstraintViolationException' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/NotNullConstraintViolationException.php',
'Doctrine\\DBAL\\Exception\\ReadOnlyException' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/ReadOnlyException.php',
'Doctrine\\DBAL\\Exception\\RetryableException' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/RetryableException.php',
+ 'Doctrine\\DBAL\\Exception\\SchemaDoesNotExist' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/SchemaDoesNotExist.php',
'Doctrine\\DBAL\\Exception\\ServerException' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/ServerException.php',
'Doctrine\\DBAL\\Exception\\SyntaxErrorException' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/SyntaxErrorException.php',
'Doctrine\\DBAL\\Exception\\TableExistsException' => __DIR__ . '/..' . '/doctrine/dbal/src/Exception/TableExistsException.php',
@@ -1686,15 +1697,21 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Doctrine\\DBAL\\Id\\TableGenerator' => __DIR__ . '/..' . '/doctrine/dbal/src/Id/TableGenerator.php',
'Doctrine\\DBAL\\Id\\TableGeneratorSchemaVisitor' => __DIR__ . '/..' . '/doctrine/dbal/src/Id/TableGeneratorSchemaVisitor.php',
'Doctrine\\DBAL\\LockMode' => __DIR__ . '/..' . '/doctrine/dbal/src/LockMode.php',
+ 'Doctrine\\DBAL\\Logging\\Connection' => __DIR__ . '/..' . '/doctrine/dbal/src/Logging/Connection.php',
'Doctrine\\DBAL\\Logging\\DebugStack' => __DIR__ . '/..' . '/doctrine/dbal/src/Logging/DebugStack.php',
+ 'Doctrine\\DBAL\\Logging\\Driver' => __DIR__ . '/..' . '/doctrine/dbal/src/Logging/Driver.php',
'Doctrine\\DBAL\\Logging\\LoggerChain' => __DIR__ . '/..' . '/doctrine/dbal/src/Logging/LoggerChain.php',
+ 'Doctrine\\DBAL\\Logging\\Middleware' => __DIR__ . '/..' . '/doctrine/dbal/src/Logging/Middleware.php',
'Doctrine\\DBAL\\Logging\\SQLLogger' => __DIR__ . '/..' . '/doctrine/dbal/src/Logging/SQLLogger.php',
+ 'Doctrine\\DBAL\\Logging\\Statement' => __DIR__ . '/..' . '/doctrine/dbal/src/Logging/Statement.php',
'Doctrine\\DBAL\\ParameterType' => __DIR__ . '/..' . '/doctrine/dbal/src/ParameterType.php',
+ 'Doctrine\\DBAL\\Platforms\\AbstractMySQLPlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php',
'Doctrine\\DBAL\\Platforms\\AbstractPlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/AbstractPlatform.php',
'Doctrine\\DBAL\\Platforms\\DB2Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/DB2Platform.php',
'Doctrine\\DBAL\\Platforms\\DateIntervalUnit' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/DateIntervalUnit.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\DB2Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/DB2Keywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\KeywordList' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/KeywordList.php',
+ 'Doctrine\\DBAL\\Platforms\\Keywords\\MariaDBKeywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/MariaDBKeywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\MariaDb102Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/MariaDb102Keywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\MySQL57Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/MySQL57Keywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\MySQL80Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/MySQL80Keywords.php',
@@ -1702,17 +1719,25 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Doctrine\\DBAL\\Platforms\\Keywords\\OracleKeywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/OracleKeywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\PostgreSQL100Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/PostgreSQL100Keywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\PostgreSQL94Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/PostgreSQL94Keywords.php',
+ 'Doctrine\\DBAL\\Platforms\\Keywords\\PostgreSQLKeywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/PostgreSQLKeywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\ReservedKeywordsValidator' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\SQLServer2012Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/SQLServer2012Keywords.php',
+ 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLServerKeywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/SQLServerKeywords.php',
'Doctrine\\DBAL\\Platforms\\Keywords\\SQLiteKeywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/SQLiteKeywords.php',
+ 'Doctrine\\DBAL\\Platforms\\MariaDBPlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDBPlatform.php',
'Doctrine\\DBAL\\Platforms\\MariaDb1027Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDb1027Platform.php',
'Doctrine\\DBAL\\Platforms\\MySQL57Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MySQL57Platform.php',
'Doctrine\\DBAL\\Platforms\\MySQL80Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MySQL80Platform.php',
'Doctrine\\DBAL\\Platforms\\MySQLPlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MySQLPlatform.php',
+ 'Doctrine\\DBAL\\Platforms\\MySQL\\Comparator' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MySQL/Comparator.php',
'Doctrine\\DBAL\\Platforms\\OraclePlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/OraclePlatform.php',
'Doctrine\\DBAL\\Platforms\\PostgreSQL100Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php',
'Doctrine\\DBAL\\Platforms\\PostgreSQL94Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php',
+ 'Doctrine\\DBAL\\Platforms\\PostgreSQLPlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/PostgreSQLPlatform.php',
'Doctrine\\DBAL\\Platforms\\SQLServer2012Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/SQLServer2012Platform.php',
+ 'Doctrine\\DBAL\\Platforms\\SQLServerPlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/SQLServerPlatform.php',
+ 'Doctrine\\DBAL\\Platforms\\SQLServer\\Comparator' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/SQLServer/Comparator.php',
+ 'Doctrine\\DBAL\\Platforms\\SQLite\\Comparator' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/SQLite/Comparator.php',
'Doctrine\\DBAL\\Platforms\\SqlitePlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/SqlitePlatform.php',
'Doctrine\\DBAL\\Platforms\\TrimMode' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/TrimMode.php',
'Doctrine\\DBAL\\Portability\\Connection' => __DIR__ . '/..' . '/doctrine/dbal/src/Portability/Connection.php',
@@ -1773,7 +1798,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Doctrine\\DBAL\\Tools\\Console\\ConnectionProvider' => __DIR__ . '/..' . '/doctrine/dbal/src/Tools/Console/ConnectionProvider.php',
'Doctrine\\DBAL\\Tools\\Console\\ConnectionProvider\\SingleConnectionProvider' => __DIR__ . '/..' . '/doctrine/dbal/src/Tools/Console/ConnectionProvider/SingleConnectionProvider.php',
'Doctrine\\DBAL\\Tools\\Console\\ConsoleRunner' => __DIR__ . '/..' . '/doctrine/dbal/src/Tools/Console/ConsoleRunner.php',
- 'Doctrine\\DBAL\\Tools\\Dumper' => __DIR__ . '/..' . '/doctrine/dbal/src/Tools/Dumper.php',
'Doctrine\\DBAL\\TransactionIsolationLevel' => __DIR__ . '/..' . '/doctrine/dbal/src/TransactionIsolationLevel.php',
'Doctrine\\DBAL\\Types\\ArrayType' => __DIR__ . '/..' . '/doctrine/dbal/src/Types/ArrayType.php',
'Doctrine\\DBAL\\Types\\AsciiStringType' => __DIR__ . '/..' . '/doctrine/dbal/src/Types/AsciiStringType.php',
@@ -2444,9 +2468,6 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'PEAR' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR.php',
'PEAR_ErrorStack' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php',
'PEAR_Exception' => __DIR__ . '/..' . '/pear/pear_exception/PEAR/Exception.php',
- 'PackageVersions\\FallbackVersions' => __DIR__ . '/..' . '/composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php',
- 'PackageVersions\\Installer' => __DIR__ . '/..' . '/composer/package-versions-deprecated/src/PackageVersions/Installer.php',
- 'PackageVersions\\Versions' => __DIR__ . '/..' . '/composer/package-versions-deprecated/src/PackageVersions/Versions.php',
'PhpParser\\Builder' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder.php',
'PhpParser\\BuilderFactory' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php',
'PhpParser\\BuilderHelpers' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderHelpers.php',
@@ -2697,6 +2718,10 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652
'Pimple\\Psr11\\ServiceLocator' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php',
'Pimple\\ServiceIterator' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/ServiceIterator.php',
'Pimple\\ServiceProviderInterface' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
+ 'Psr\\Cache\\CacheException' => __DIR__ . '/..' . '/psr/cache/src/CacheException.php',
+ 'Psr\\Cache\\CacheItemInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemInterface.php',
+ 'Psr\\Cache\\CacheItemPoolInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemPoolInterface.php',
+ 'Psr\\Cache\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/cache/src/InvalidArgumentException.php',
'Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php',
'Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php',
'Psr\\Container\\NotFoundExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/NotFoundExceptionInterface.php',
diff --git a/composer/installed.json b/composer/installed.json
index ca3f50b8..f10ef5ae 100644
--- a/composer/installed.json
+++ b/composer/installed.json
@@ -299,82 +299,6 @@
"install-path": "../christophwurst/id3parser"
},
{
- "name": "composer/package-versions-deprecated",
- "version": "1.11.99.4",
- "version_normalized": "1.11.99.4",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/package-versions-deprecated.git",
- "reference": "b174585d1fe49ceed21928a945138948cb394600"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600",
- "reference": "b174585d1fe49ceed21928a945138948cb394600",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^1.1.0 || ^2.0",
- "php": "^7 || ^8"
- },
- "replace": {
- "ocramius/package-versions": "1.11.99"
- },
- "require-dev": {
- "composer/composer": "^1.9.3 || ^2.0@dev",
- "ext-zip": "^1.13",
- "phpunit/phpunit": "^6.5 || ^7"
- },
- "time": "2021-09-13T08:41:34+00:00",
- "type": "composer-plugin",
- "extra": {
- "class": "PackageVersions\\Installer",
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "installation-source": "dist",
- "autoload": {
- "psr-4": {
- "PackageVersions\\": "src/PackageVersions"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com"
- },
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be"
- }
- ],
- "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.4"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "install-path": "./package-versions-deprecated"
- },
- {
"name": "cweagans/composer-patches",
"version": "1.7.1",
"version_normalized": "1.7.1.0",
@@ -544,17 +468,17 @@
},
{
"name": "doctrine/cache",
- "version": "2.1.1",
- "version_normalized": "2.1.1.0",
+ "version": "2.2.0",
+ "version_normalized": "2.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
- "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce"
+ "reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce",
- "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce",
+ "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
+ "reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
"shasum": ""
},
"require": {
@@ -564,20 +488,14 @@
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
- "alcaeus/mongo-php-adapter": "^1.1",
"cache/integration-tests": "dev-master",
- "doctrine/coding-standard": "^8.0",
- "mongodb/mongodb": "^1.1",
- "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
- "predis/predis": "~1.0",
+ "doctrine/coding-standard": "^9",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"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"
+ "symfony/cache": "^4.4 || ^5.4 || ^6",
+ "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
},
- "suggest": {
- "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
- },
- "time": "2021-07-17T14:49:29+00:00",
+ "time": "2022-05-20T20:07:39+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -626,7 +544,7 @@
],
"support": {
"issues": "https://github.com/doctrine/cache/issues",
- "source": "https://github.com/doctrine/cache/tree/2.1.1"
+ "source": "https://github.com/doctrine/cache/tree/2.2.0"
},
"funding": [
{
@@ -646,42 +564,44 @@
},
{
"name": "doctrine/dbal",
- "version": "3.1.4",
- "version_normalized": "3.1.4.0",
+ "version": "3.3.7",
+ "version_normalized": "3.3.7.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
- "reference": "821b4f01a36ce63ed36c090ea74767b72db367e9"
+ "reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/dbal/zipball/821b4f01a36ce63ed36c090ea74767b72db367e9",
- "reference": "821b4f01a36ce63ed36c090ea74767b72db367e9",
+ "url": "https://api.github.com/repos/doctrine/dbal/zipball/9f79d4650430b582f4598fe0954ef4d52fbc0a8a",
+ "reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a",
"shasum": ""
},
"require": {
- "composer/package-versions-deprecated": "^1.11.99",
- "doctrine/cache": "^1.0|^2.0",
- "doctrine/deprecations": "^0.5.3",
+ "composer-runtime-api": "^2",
+ "doctrine/cache": "^1.11|^2.0",
+ "doctrine/deprecations": "^0.5.3|^1",
"doctrine/event-manager": "^1.0",
- "php": "^7.3 || ^8.0"
+ "php": "^7.3 || ^8.0",
+ "psr/cache": "^1|^2|^3",
+ "psr/log": "^1|^2|^3"
},
"require-dev": {
"doctrine/coding-standard": "9.0.0",
- "jetbrains/phpstorm-stubs": "2021.1",
- "phpstan/phpstan": "1.1.1",
- "phpstan/phpstan-strict-rules": "^1",
- "phpunit/phpunit": "9.5.10",
+ "jetbrains/phpstorm-stubs": "2022.1",
+ "phpstan/phpstan": "1.7.13",
+ "phpstan/phpstan-strict-rules": "^1.2",
+ "phpunit/phpunit": "9.5.20",
"psalm/plugin-phpunit": "0.16.1",
- "squizlabs/php_codesniffer": "3.6.1",
+ "squizlabs/php_codesniffer": "3.7.0",
"symfony/cache": "^5.2|^6.0",
- "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.0",
- "vimeo/psalm": "4.12.0"
+ "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
+ "vimeo/psalm": "4.23.0"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
},
- "time": "2021-11-15T16:44:33+00:00",
+ "time": "2022-06-13T21:43:03+00:00",
"bin": [
"bin/doctrine-dbal"
],
@@ -738,7 +658,7 @@
],
"support": {
"issues": "https://github.com/doctrine/dbal/issues",
- "source": "https://github.com/doctrine/dbal/tree/3.1.4"
+ "source": "https://github.com/doctrine/dbal/tree/3.3.7"
},
"funding": [
{
@@ -758,31 +678,31 @@
},
{
"name": "doctrine/deprecations",
- "version": "v0.5.3",
- "version_normalized": "0.5.3.0",
+ "version": "v1.0.0",
+ "version_normalized": "1.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/deprecations.git",
- "reference": "9504165960a1f83cc1480e2be1dd0a0478561314"
+ "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/deprecations/zipball/9504165960a1f83cc1480e2be1dd0a0478561314",
- "reference": "9504165960a1f83cc1480e2be1dd0a0478561314",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
+ "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
"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"
+ "doctrine/coding-standard": "^9",
+ "phpunit/phpunit": "^7.5|^8.5|^9.5",
+ "psr/log": "^1|^2|^3"
},
"suggest": {
"psr/log": "Allows logging deprecations via PSR-3 logger implementation"
},
- "time": "2021-03-21T12:59:47+00:00",
+ "time": "2022-05-02T15:47:09+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -798,7 +718,7 @@
"homepage": "https://www.doctrine-project.org/",
"support": {
"issues": "https://github.com/doctrine/deprecations/issues",
- "source": "https://github.com/doctrine/deprecations/tree/v0.5.3"
+ "source": "https://github.com/doctrine/deprecations/tree/v1.0.0"
},
"install-path": "../doctrine/deprecations"
},
@@ -3087,6 +3007,58 @@
"install-path": "../pimple/pimple"
},
{
+ "name": "psr/cache",
+ "version": "1.0.1",
+ "version_normalized": "1.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/cache.git",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "time": "2016-08-06T20:24:11+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Cache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for caching libraries",
+ "keywords": [
+ "cache",
+ "psr",
+ "psr-6"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/cache/tree/master"
+ },
+ "install-path": "../psr/cache"
+ },
+ {
"name": "psr/container",
"version": "1.1.1",
"version_normalized": "1.1.1.0",
@@ -6372,6 +6344,6 @@
"install-path": "../web-auth/webauthn-lib"
}
],
- "dev": true,
+ "dev": false,
"dev-package-names": []
}
diff --git a/composer/installed.php b/composer/installed.php
index 8e52ef36..2c894977 100644
--- a/composer/installed.php
+++ b/composer/installed.php
@@ -1,370 +1,355 @@
<?php return array(
'root' => array(
+ 'name' => 'nextcloud/3rdparty',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
+ 'reference' => 'cf36c9bd42b49cf5e7aa78a9dec8961518ca4f1c',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
- 'reference' => '6d82f0c103262a2f7c26514b5debe55557cfe7b6',
- 'name' => 'nextcloud/3rdparty',
- 'dev' => true,
+ 'dev' => false,
),
'versions' => array(
'aws/aws-sdk-php' => array(
'pretty_version' => '3.184.6',
'version' => '3.184.6.0',
+ 'reference' => '0b7187c96ced465d400ad9427157e05ddee68edc',
'type' => 'library',
'install_path' => __DIR__ . '/../aws/aws-sdk-php',
'aliases' => array(),
- 'reference' => '0b7187c96ced465d400ad9427157e05ddee68edc',
'dev_requirement' => false,
),
'bantu/ini-get-wrapper' => array(
'pretty_version' => 'v1.0.1',
'version' => '1.0.1.0',
+ 'reference' => '4770c7feab370c62e23db4f31c112b7c6d90aee2',
'type' => 'library',
'install_path' => __DIR__ . '/../bantu/ini-get-wrapper',
'aliases' => array(),
- 'reference' => '4770c7feab370c62e23db4f31c112b7c6d90aee2',
'dev_requirement' => false,
),
'beberlei/assert' => array(
'pretty_version' => 'v3.3.1',
'version' => '3.3.1.0',
+ 'reference' => '5e721d7e937ca3ba2cdec1e1adf195f9e5188372',
'type' => 'library',
'install_path' => __DIR__ . '/../beberlei/assert',
'aliases' => array(),
- 'reference' => '5e721d7e937ca3ba2cdec1e1adf195f9e5188372',
'dev_requirement' => false,
),
'brick/math' => array(
'pretty_version' => '0.9.2',
'version' => '0.9.2.0',
+ 'reference' => 'dff976c2f3487d42c1db75a3b180e2b9f0e72ce0',
'type' => 'library',
'install_path' => __DIR__ . '/../brick/math',
'aliases' => array(),
- 'reference' => 'dff976c2f3487d42c1db75a3b180e2b9f0e72ce0',
'dev_requirement' => false,
),
'christophwurst/id3parser' => array(
'pretty_version' => 'v0.1.4',
'version' => '0.1.4.0',
+ 'reference' => '050c9d81ea89b0cf53e23a27efc4e1840f9ab260',
'type' => 'library',
'install_path' => __DIR__ . '/../christophwurst/id3parser',
'aliases' => array(),
- 'reference' => '050c9d81ea89b0cf53e23a27efc4e1840f9ab260',
- 'dev_requirement' => false,
- ),
- 'composer/package-versions-deprecated' => array(
- 'pretty_version' => '1.11.99.4',
- 'version' => '1.11.99.4',
- 'type' => 'composer-plugin',
- 'install_path' => __DIR__ . '/./package-versions-deprecated',
- 'aliases' => array(),
- 'reference' => 'b174585d1fe49ceed21928a945138948cb394600',
'dev_requirement' => false,
),
'cweagans/composer-patches' => array(
'pretty_version' => '1.7.1',
'version' => '1.7.1.0',
+ 'reference' => '9888dcc74993c030b75f3dd548bb5e20cdbd740c',
'type' => 'composer-plugin',
'install_path' => __DIR__ . '/../cweagans/composer-patches',
'aliases' => array(),
- 'reference' => '9888dcc74993c030b75f3dd548bb5e20cdbd740c',
'dev_requirement' => false,
),
'deepdiver/zipstreamer' => array(
'pretty_version' => '2.0.0',
'version' => '2.0.0.0',
+ 'reference' => 'b8c59647ff34fb97e8937aefb2a65de2bc4b4755',
'type' => 'library',
'install_path' => __DIR__ . '/../deepdiver/zipstreamer',
'aliases' => array(),
- 'reference' => 'b8c59647ff34fb97e8937aefb2a65de2bc4b4755',
'dev_requirement' => false,
),
'deepdiver1975/tarstreamer' => array(
'pretty_version' => '2.0.0',
'version' => '2.0.0.0',
+ 'reference' => 'ad48505d1ab54a8e94e6b1cc5297bbed72e956de',
'type' => 'library',
'install_path' => __DIR__ . '/../deepdiver1975/tarstreamer',
'aliases' => array(),
- 'reference' => 'ad48505d1ab54a8e94e6b1cc5297bbed72e956de',
'dev_requirement' => false,
),
'doctrine/cache' => array(
- 'pretty_version' => '2.1.1',
- 'version' => '2.1.1.0',
+ 'pretty_version' => '2.2.0',
+ 'version' => '2.2.0.0',
+ 'reference' => '1ca8f21980e770095a31456042471a57bc4c68fb',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/cache',
'aliases' => array(),
- 'reference' => '331b4d5dbaeab3827976273e9356b3b453c300ce',
'dev_requirement' => false,
),
'doctrine/dbal' => array(
- 'pretty_version' => '3.1.4',
- 'version' => '3.1.4.0',
+ 'pretty_version' => '3.3.7',
+ 'version' => '3.3.7.0',
+ 'reference' => '9f79d4650430b582f4598fe0954ef4d52fbc0a8a',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/dbal',
'aliases' => array(),
- 'reference' => '821b4f01a36ce63ed36c090ea74767b72db367e9',
'dev_requirement' => false,
),
'doctrine/deprecations' => array(
- 'pretty_version' => 'v0.5.3',
- 'version' => '0.5.3.0',
+ 'pretty_version' => 'v1.0.0',
+ 'version' => '1.0.0.0',
+ 'reference' => '0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/deprecations',
'aliases' => array(),
- 'reference' => '9504165960a1f83cc1480e2be1dd0a0478561314',
'dev_requirement' => false,
),
'doctrine/event-manager' => array(
'pretty_version' => '1.1.1',
'version' => '1.1.1.0',
+ 'reference' => '41370af6a30faa9dc0368c4a6814d596e81aba7f',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/event-manager',
'aliases' => array(),
- 'reference' => '41370af6a30faa9dc0368c4a6814d596e81aba7f',
'dev_requirement' => false,
),
'doctrine/lexer' => array(
'pretty_version' => '1.2.1',
'version' => '1.2.1.0',
+ 'reference' => 'e864bbf5904cb8f5bb334f99209b48018522f042',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/lexer',
'aliases' => array(),
- 'reference' => 'e864bbf5904cb8f5bb334f99209b48018522f042',
'dev_requirement' => false,
),
'egulias/email-validator' => array(
'pretty_version' => '3.1.1',
'version' => '3.1.1.0',
+ 'reference' => 'c81f18a3efb941d8c4d2e025f6183b5c6d697307',
'type' => 'library',
'install_path' => __DIR__ . '/../egulias/email-validator',
'aliases' => array(),
- 'reference' => 'c81f18a3efb941d8c4d2e025f6183b5c6d697307',
'dev_requirement' => false,
),
'fgrosse/phpasn1' => array(
'pretty_version' => 'v2.3.0',
'version' => '2.3.0.0',
+ 'reference' => '20299033c35f4300eb656e7e8e88cf52d1d6694e',
'type' => 'library',
'install_path' => __DIR__ . '/../fgrosse/phpasn1',
'aliases' => array(),
- 'reference' => '20299033c35f4300eb656e7e8e88cf52d1d6694e',
'dev_requirement' => false,
),
'giggsey/libphonenumber-for-php' => array(
'pretty_version' => '8.12.38',
'version' => '8.12.38.0',
+ 'reference' => '0a6293c57de9256f4bd0d673280fbfbfd1e47533',
'type' => 'library',
'install_path' => __DIR__ . '/../giggsey/libphonenumber-for-php',
'aliases' => array(),
- 'reference' => '0a6293c57de9256f4bd0d673280fbfbfd1e47533',
'dev_requirement' => false,
),
'giggsey/locale' => array(
'pretty_version' => '2.1',
'version' => '2.1.0.0',
+ 'reference' => '8d324583b5899e6280a875c43bf1fc9658bc6962',
'type' => 'library',
'install_path' => __DIR__ . '/../giggsey/locale',
'aliases' => array(),
- 'reference' => '8d324583b5899e6280a875c43bf1fc9658bc6962',
'dev_requirement' => false,
),
'guzzlehttp/guzzle' => array(
'pretty_version' => '7.4.0',
'version' => '7.4.0.0',
+ 'reference' => '868b3571a039f0ebc11ac8f344f4080babe2cb94',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
'aliases' => array(),
- 'reference' => '868b3571a039f0ebc11ac8f344f4080babe2cb94',
'dev_requirement' => false,
),
'guzzlehttp/promises' => array(
'pretty_version' => '1.5.1',
'version' => '1.5.1.0',
+ 'reference' => 'fe752aedc9fd8fcca3fe7ad05d419d32998a06da',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/promises',
'aliases' => array(),
- 'reference' => 'fe752aedc9fd8fcca3fe7ad05d419d32998a06da',
'dev_requirement' => false,
),
'guzzlehttp/psr7' => array(
'pretty_version' => '1.8.5',
'version' => '1.8.5.0',
+ 'reference' => '337e3ad8e5716c15f9657bd214d16cc5e69df268',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
'aliases' => array(),
- 'reference' => '337e3ad8e5716c15f9657bd214d16cc5e69df268',
'dev_requirement' => false,
),
'guzzlehttp/uri-template' => array(
'pretty_version' => 'v0.2.0',
'version' => '0.2.0.0',
+ 'reference' => 'db46525d6d8fee71033b73cc07160f3e5271a8ce',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/uri-template',
'aliases' => array(),
- 'reference' => 'db46525d6d8fee71033b73cc07160f3e5271a8ce',
'dev_requirement' => false,
),
'icewind/searchdav' => array(
'pretty_version' => 'v3.0.1',
'version' => '3.0.1.0',
+ 'reference' => '52c8cfc21bd69271f224671c4924d260b0a8d4fb',
'type' => 'library',
'install_path' => __DIR__ . '/../icewind/searchdav',
'aliases' => array(),
- 'reference' => '52c8cfc21bd69271f224671c4924d260b0a8d4fb',
'dev_requirement' => false,
),
'icewind/streams' => array(
'pretty_version' => 'v0.7.5',
'version' => '0.7.5.0',
+ 'reference' => '0c6aae16ebdadb257f0bd089c1e1e4cf5e20ddc2',
'type' => 'library',
'install_path' => __DIR__ . '/../icewind/streams',
'aliases' => array(),
- 'reference' => '0c6aae16ebdadb257f0bd089c1e1e4cf5e20ddc2',
'dev_requirement' => false,
),
'justinrainbow/json-schema' => array(
'pretty_version' => '5.2.10',
'version' => '5.2.10.0',
+ 'reference' => '2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b',
'type' => 'library',
'install_path' => __DIR__ . '/../justinrainbow/json-schema',
'aliases' => array(),
- 'reference' => '2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b',
'dev_requirement' => false,
),
'league/uri' => array(
'pretty_version' => '6.4.0',
'version' => '6.4.0.0',
+ 'reference' => '09da64118eaf4c5d52f9923a1e6a5be1da52fd9a',
'type' => 'library',
'install_path' => __DIR__ . '/../league/uri',
'aliases' => array(),
- 'reference' => '09da64118eaf4c5d52f9923a1e6a5be1da52fd9a',
'dev_requirement' => false,
),
'league/uri-interfaces' => array(
'pretty_version' => '2.2.0',
'version' => '2.2.0.0',
+ 'reference' => '667f150e589d65d79c89ffe662e426704f84224f',
'type' => 'library',
'install_path' => __DIR__ . '/../league/uri-interfaces',
'aliases' => array(),
- 'reference' => '667f150e589d65d79c89ffe662e426704f84224f',
'dev_requirement' => false,
),
'microsoft/azure-storage-blob' => array(
'pretty_version' => '1.5.2',
'version' => '1.5.2.0',
+ 'reference' => '2475330963372d519387cb8135d6a9cfd42272da',
'type' => 'library',
'install_path' => __DIR__ . '/../microsoft/azure-storage-blob',
'aliases' => array(),
- 'reference' => '2475330963372d519387cb8135d6a9cfd42272da',
'dev_requirement' => false,
),
'microsoft/azure-storage-common' => array(
'pretty_version' => '1.5.1',
'version' => '1.5.1.0',
+ 'reference' => 'e5738035891546075bd369954e8af121d65ebd6d',
'type' => 'library',
'install_path' => __DIR__ . '/../microsoft/azure-storage-common',
'aliases' => array(),
- 'reference' => 'e5738035891546075bd369954e8af121d65ebd6d',
'dev_requirement' => false,
),
'mtdowling/jmespath.php' => array(
'pretty_version' => '2.6.1',
'version' => '2.6.1.0',
+ 'reference' => '9b87907a81b87bc76d19a7fb2d61e61486ee9edb',
'type' => 'library',
'install_path' => __DIR__ . '/../mtdowling/jmespath.php',
'aliases' => array(),
- 'reference' => '9b87907a81b87bc76d19a7fb2d61e61486ee9edb',
'dev_requirement' => false,
),
'nextcloud/3rdparty' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
+ 'reference' => 'cf36c9bd42b49cf5e7aa78a9dec8961518ca4f1c',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
- 'reference' => '6d82f0c103262a2f7c26514b5debe55557cfe7b6',
'dev_requirement' => false,
),
'nextcloud/lognormalizer' => array(
'pretty_version' => 'v1.0.0',
'version' => '1.0.0.0',
+ 'reference' => '87445d69225c247aaff64643b1fc83c6d6df741f',
'type' => 'library',
'install_path' => __DIR__ . '/../nextcloud/lognormalizer',
'aliases' => array(),
- 'reference' => '87445d69225c247aaff64643b1fc83c6d6df741f',
'dev_requirement' => false,
),
'nikic/php-parser' => array(
'pretty_version' => 'v4.10.5',
'version' => '4.10.5.0',
+ 'reference' => '4432ba399e47c66624bc73c8c0f811e5c109576f',
'type' => 'library',
'install_path' => __DIR__ . '/../nikic/php-parser',
'aliases' => array(),
- 'reference' => '4432ba399e47c66624bc73c8c0f811e5c109576f',
- 'dev_requirement' => false,
- ),
- 'ocramius/package-versions' => array(
'dev_requirement' => false,
- 'replaced' => array(
- 0 => '1.11.99',
- ),
),
'opis/closure' => array(
'pretty_version' => '3.6.2',
'version' => '3.6.2.0',
+ 'reference' => '06e2ebd25f2869e54a306dda991f7db58066f7f6',
'type' => 'library',
'install_path' => __DIR__ . '/../opis/closure',
'aliases' => array(),
- 'reference' => '06e2ebd25f2869e54a306dda991f7db58066f7f6',
'dev_requirement' => false,
),
'pear/archive_tar' => array(
'pretty_version' => '1.4.14',
'version' => '1.4.14.0',
+ 'reference' => '4d761c5334c790e45ef3245f0864b8955c562caa',
'type' => 'library',
'install_path' => __DIR__ . '/../pear/archive_tar',
'aliases' => array(),
- 'reference' => '4d761c5334c790e45ef3245f0864b8955c562caa',
'dev_requirement' => false,
),
'pear/console_getopt' => array(
'pretty_version' => 'v1.4.3',
'version' => '1.4.3.0',
+ 'reference' => 'a41f8d3e668987609178c7c4a9fe48fecac53fa0',
'type' => 'library',
'install_path' => __DIR__ . '/../pear/console_getopt',
'aliases' => array(),
- 'reference' => 'a41f8d3e668987609178c7c4a9fe48fecac53fa0',
'dev_requirement' => false,
),
'pear/pear-core-minimal' => array(
'pretty_version' => 'v1.10.10',
'version' => '1.10.10.0',
+ 'reference' => '625a3c429d9b2c1546438679074cac1b089116a7',
'type' => 'library',
'install_path' => __DIR__ . '/../pear/pear-core-minimal',
'aliases' => array(),
- 'reference' => '625a3c429d9b2c1546438679074cac1b089116a7',
'dev_requirement' => false,
),
'pear/pear_exception' => array(
'pretty_version' => 'v1.0.2',
'version' => '1.0.2.0',
+ 'reference' => 'b14fbe2ddb0b9f94f5b24cf08783d599f776fff0',
'type' => 'class',
'install_path' => __DIR__ . '/../pear/pear_exception',
'aliases' => array(),
- 'reference' => 'b14fbe2ddb0b9f94f5b24cf08783d599f776fff0',
'dev_requirement' => false,
),
'php-ds/php-ds' => array(
'pretty_version' => 'v1.3.0',
'version' => '1.3.0.0',
+ 'reference' => 'b98396862fb8a13cbdbbaf4d18be28ee5c01ed3c',
'type' => 'library',
'install_path' => __DIR__ . '/../php-ds/php-ds',
'aliases' => array(),
- 'reference' => 'b98396862fb8a13cbdbbaf4d18be28ee5c01ed3c',
'dev_requirement' => false,
),
'php-http/async-client-implementation' => array(
@@ -382,73 +367,82 @@
'php-http/guzzle7-adapter' => array(
'pretty_version' => '1.0.0',
'version' => '1.0.0.0',
+ 'reference' => 'fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01',
'type' => 'library',
'install_path' => __DIR__ . '/../php-http/guzzle7-adapter',
'aliases' => array(),
- 'reference' => 'fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01',
'dev_requirement' => false,
),
'php-http/httplug' => array(
'pretty_version' => '2.2.0',
'version' => '2.2.0.0',
+ 'reference' => '191a0a1b41ed026b717421931f8d3bd2514ffbf9',
'type' => 'library',
'install_path' => __DIR__ . '/../php-http/httplug',
'aliases' => array(),
- 'reference' => '191a0a1b41ed026b717421931f8d3bd2514ffbf9',
'dev_requirement' => false,
),
'php-http/promise' => array(
'pretty_version' => '1.1.0',
'version' => '1.1.0.0',
+ 'reference' => '4c4c1f9b7289a2ec57cde7f1e9762a5789506f88',
'type' => 'library',
'install_path' => __DIR__ . '/../php-http/promise',
'aliases' => array(),
- 'reference' => '4c4c1f9b7289a2ec57cde7f1e9762a5789506f88',
'dev_requirement' => false,
),
'php-opencloud/openstack' => array(
'pretty_version' => 'v3.1.0',
'version' => '3.1.0.0',
+ 'reference' => '7b0eeb63defe533fb802514af3c70855c45eaf1e',
'type' => 'library',
'install_path' => __DIR__ . '/../php-opencloud/openstack',
'aliases' => array(),
- 'reference' => '7b0eeb63defe533fb802514af3c70855c45eaf1e',
'dev_requirement' => false,
),
'phpseclib/phpseclib' => array(
'pretty_version' => '2.0.32',
'version' => '2.0.32.0',
+ 'reference' => 'f5c4c19880d45d0be3e7d24ae8ac434844a898cd',
'type' => 'library',
'install_path' => __DIR__ . '/../phpseclib/phpseclib',
'aliases' => array(),
- 'reference' => 'f5c4c19880d45d0be3e7d24ae8ac434844a898cd',
'dev_requirement' => false,
),
'pimple/pimple' => array(
'pretty_version' => 'v3.5.0',
'version' => '3.5.0.0',
+ 'reference' => 'a94b3a4db7fb774b3d78dad2315ddc07629e1bed',
'type' => 'library',
'install_path' => __DIR__ . '/../pimple/pimple',
'aliases' => array(),
- 'reference' => 'a94b3a4db7fb774b3d78dad2315ddc07629e1bed',
+ 'dev_requirement' => false,
+ ),
+ 'psr/cache' => array(
+ 'pretty_version' => '1.0.1',
+ 'version' => '1.0.1.0',
+ 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../psr/cache',
+ 'aliases' => array(),
'dev_requirement' => false,
),
'psr/container' => array(
'pretty_version' => '1.1.1',
'version' => '1.1.1.0',
+ 'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/container',
'aliases' => array(),
- 'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf',
'dev_requirement' => false,
),
'psr/event-dispatcher' => array(
'pretty_version' => '1.0.0',
'version' => '1.0.0.0',
+ 'reference' => 'dbefd12671e8a14ec7f180cab83036ed26714bb0',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/event-dispatcher',
'aliases' => array(),
- 'reference' => 'dbefd12671e8a14ec7f180cab83036ed26714bb0',
'dev_requirement' => false,
),
'psr/event-dispatcher-implementation' => array(
@@ -460,10 +454,10 @@
'psr/http-client' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
+ 'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-client',
'aliases' => array(),
- 'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621',
'dev_requirement' => false,
),
'psr/http-client-implementation' => array(
@@ -475,19 +469,19 @@
'psr/http-factory' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
+ 'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-factory',
'aliases' => array(),
- 'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
'dev_requirement' => false,
),
'psr/http-message' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
+ 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(),
- 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
'dev_requirement' => false,
),
'psr/http-message-implementation' => array(
@@ -499,10 +493,10 @@
'psr/log' => array(
'pretty_version' => '1.1.4',
'version' => '1.1.4.0',
+ 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/log',
'aliases' => array(),
- 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11',
'dev_requirement' => false,
),
'psr/log-implementation' => array(
@@ -526,37 +520,37 @@
'punic/punic' => array(
'pretty_version' => '1.6.5',
'version' => '1.6.5.0',
+ 'reference' => '7bc85ce1137cf52db4d2a6298256a4c4a24da99a',
'type' => 'library',
'install_path' => __DIR__ . '/../punic/punic',
'aliases' => array(),
- 'reference' => '7bc85ce1137cf52db4d2a6298256a4c4a24da99a',
'dev_requirement' => false,
),
'ralouphie/getallheaders' => array(
'pretty_version' => '3.0.3',
'version' => '3.0.3.0',
+ 'reference' => '120b605dfeb996808c31b6477290a714d356e822',
'type' => 'library',
'install_path' => __DIR__ . '/../ralouphie/getallheaders',
'aliases' => array(),
- 'reference' => '120b605dfeb996808c31b6477290a714d356e822',
'dev_requirement' => false,
),
'ramsey/collection' => array(
'pretty_version' => '1.1.3',
'version' => '1.1.3.0',
+ 'reference' => '28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1',
'type' => 'library',
'install_path' => __DIR__ . '/../ramsey/collection',
'aliases' => array(),
- 'reference' => '28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1',
'dev_requirement' => false,
),
'ramsey/uuid' => array(
'pretty_version' => '4.1.1',
'version' => '4.1.1.0',
+ 'reference' => 'cd4032040a750077205918c86049aa0f43d22947',
'type' => 'library',
'install_path' => __DIR__ . '/../ramsey/uuid',
'aliases' => array(),
- 'reference' => 'cd4032040a750077205918c86049aa0f43d22947',
'dev_requirement' => false,
),
'rhumsaa/uuid' => array(
@@ -574,136 +568,136 @@
'sabre/dav' => array(
'pretty_version' => '4.2.1',
'version' => '4.2.1.0',
+ 'reference' => '5e651f9ddc2b05745f5b28cd697c8e8c6a0b6146',
'type' => 'library',
'install_path' => __DIR__ . '/../sabre/dav',
'aliases' => array(),
- 'reference' => '5e651f9ddc2b05745f5b28cd697c8e8c6a0b6146',
'dev_requirement' => false,
),
'sabre/event' => array(
'pretty_version' => '5.1.4',
'version' => '5.1.4.0',
+ 'reference' => 'd7da22897125d34d7eddf7977758191c06a74497',
'type' => 'library',
'install_path' => __DIR__ . '/../sabre/event',
'aliases' => array(),
- 'reference' => 'd7da22897125d34d7eddf7977758191c06a74497',
'dev_requirement' => false,
),
'sabre/http' => array(
'pretty_version' => '5.1.3',
'version' => '5.1.3.0',
+ 'reference' => '315f592adfcba8aeb73c2fd64285205747acbbd7',
'type' => 'library',
'install_path' => __DIR__ . '/../sabre/http',
'aliases' => array(),
- 'reference' => '315f592adfcba8aeb73c2fd64285205747acbbd7',
'dev_requirement' => false,
),
'sabre/uri' => array(
'pretty_version' => '2.2.2',
'version' => '2.2.2.0',
+ 'reference' => '7cb0f489578afad5006e85cd60f18ff33f2d440d',
'type' => 'library',
'install_path' => __DIR__ . '/../sabre/uri',
'aliases' => array(),
- 'reference' => '7cb0f489578afad5006e85cd60f18ff33f2d440d',
'dev_requirement' => false,
),
'sabre/vobject' => array(
'pretty_version' => '4.4.1',
'version' => '4.4.1.0',
+ 'reference' => '06feff370141fd3118609f808e86d9315864bf14',
'type' => 'library',
'install_path' => __DIR__ . '/../sabre/vobject',
'aliases' => array(),
- 'reference' => '06feff370141fd3118609f808e86d9315864bf14',
'dev_requirement' => false,
),
'sabre/xml' => array(
'pretty_version' => '2.2.5',
'version' => '2.2.5.0',
+ 'reference' => 'a6af111850e7536d200d9637c34885cd3c77a86c',
'type' => 'library',
'install_path' => __DIR__ . '/../sabre/xml',
'aliases' => array(),
- 'reference' => 'a6af111850e7536d200d9637c34885cd3c77a86c',
'dev_requirement' => false,
),
'scssphp/scssphp' => array(
'pretty_version' => 'v1.8.1',
'version' => '1.8.1.0',
+ 'reference' => '5e37759a63caf54392a4b709358a39ac7425a69f',
'type' => 'library',
'install_path' => __DIR__ . '/../scssphp/scssphp',
'aliases' => array(),
- 'reference' => '5e37759a63caf54392a4b709358a39ac7425a69f',
'dev_requirement' => false,
),
'spomky-labs/base64url' => array(
'pretty_version' => 'v2.0.4',
'version' => '2.0.4.0',
+ 'reference' => '7752ce931ec285da4ed1f4c5aa27e45e097be61d',
'type' => 'library',
'install_path' => __DIR__ . '/../spomky-labs/base64url',
'aliases' => array(),
- 'reference' => '7752ce931ec285da4ed1f4c5aa27e45e097be61d',
'dev_requirement' => false,
),
'spomky-labs/cbor-php' => array(
'pretty_version' => 'v2.0.1',
'version' => '2.0.1.0',
+ 'reference' => '9776578000be884cd7864eeb7c37a4ac92d8c995',
'type' => 'library',
'install_path' => __DIR__ . '/../spomky-labs/cbor-php',
'aliases' => array(),
- 'reference' => '9776578000be884cd7864eeb7c37a4ac92d8c995',
'dev_requirement' => false,
),
'stecman/symfony-console-completion' => array(
'pretty_version' => '0.11.0',
'version' => '0.11.0.0',
+ 'reference' => 'a9502dab59405e275a9f264536c4e1cb61fc3518',
'type' => 'library',
'install_path' => __DIR__ . '/../stecman/symfony-console-completion',
'aliases' => array(),
- 'reference' => 'a9502dab59405e275a9f264536c4e1cb61fc3518',
'dev_requirement' => false,
),
'swiftmailer/swiftmailer' => array(
'pretty_version' => 'v6.2.7',
'version' => '6.2.7.0',
+ 'reference' => '15f7faf8508e04471f666633addacf54c0ab5933',
'type' => 'library',
'install_path' => __DIR__ . '/../swiftmailer/swiftmailer',
'aliases' => array(),
- 'reference' => '15f7faf8508e04471f666633addacf54c0ab5933',
'dev_requirement' => false,
),
'symfony/console' => array(
'pretty_version' => 'v4.4.30',
'version' => '4.4.30.0',
+ 'reference' => 'a3f7189a0665ee33b50e9e228c46f50f5acbed22',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/console',
'aliases' => array(),
- 'reference' => 'a3f7189a0665ee33b50e9e228c46f50f5acbed22',
'dev_requirement' => false,
),
'symfony/deprecation-contracts' => array(
'pretty_version' => 'v2.5.0',
'version' => '2.5.0.0',
+ 'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
'aliases' => array(),
- 'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8',
'dev_requirement' => false,
),
'symfony/event-dispatcher' => array(
'pretty_version' => 'v4.4.30',
'version' => '4.4.30.0',
+ 'reference' => '2fe81680070043c4c80e7cedceb797e34f377bac',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher',
'aliases' => array(),
- 'reference' => '2fe81680070043c4c80e7cedceb797e34f377bac',
'dev_requirement' => false,
),
'symfony/event-dispatcher-contracts' => array(
'pretty_version' => 'v1.1.9',
'version' => '1.1.9.0',
+ 'reference' => '84e23fdcd2517bf37aecbd16967e83f0caee25a7',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts',
'aliases' => array(),
- 'reference' => '84e23fdcd2517bf37aecbd16967e83f0caee25a7',
'dev_requirement' => false,
),
'symfony/event-dispatcher-implementation' => array(
@@ -715,127 +709,127 @@
'symfony/polyfill-ctype' => array(
'pretty_version' => 'v1.23.0',
'version' => '1.23.0.0',
+ 'reference' => '46cd95797e9df938fdd2b03693b5fca5e64b01ce',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
'aliases' => array(),
- 'reference' => '46cd95797e9df938fdd2b03693b5fca5e64b01ce',
'dev_requirement' => false,
),
'symfony/polyfill-iconv' => array(
'pretty_version' => 'v1.23.0',
'version' => '1.23.0.0',
+ 'reference' => '63b5bb7db83e5673936d6e3b8b3e022ff6474933',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-iconv',
'aliases' => array(),
- 'reference' => '63b5bb7db83e5673936d6e3b8b3e022ff6474933',
'dev_requirement' => false,
),
'symfony/polyfill-intl-grapheme' => array(
'pretty_version' => 'v1.23.1',
'version' => '1.23.1.0',
+ 'reference' => '16880ba9c5ebe3642d1995ab866db29270b36535',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme',
'aliases' => array(),
- 'reference' => '16880ba9c5ebe3642d1995ab866db29270b36535',
'dev_requirement' => false,
),
'symfony/polyfill-intl-idn' => array(
'pretty_version' => 'v1.23.0',
'version' => '1.23.0.0',
+ 'reference' => '65bd267525e82759e7d8c4e8ceea44f398838e65',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
'aliases' => array(),
- 'reference' => '65bd267525e82759e7d8c4e8ceea44f398838e65',
'dev_requirement' => false,
),
'symfony/polyfill-intl-normalizer' => array(
'pretty_version' => 'v1.23.0',
'version' => '1.23.0.0',
+ 'reference' => '8590a5f561694770bdcd3f9b5c69dde6945028e8',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
'aliases' => array(),
- 'reference' => '8590a5f561694770bdcd3f9b5c69dde6945028e8',
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.23.1',
'version' => '1.23.1.0',
+ 'reference' => '9174a3d80210dca8daa7f31fec659150bbeabfc6',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
- 'reference' => '9174a3d80210dca8daa7f31fec659150bbeabfc6',
'dev_requirement' => false,
),
'symfony/polyfill-php72' => array(
'pretty_version' => 'v1.23.0',
'version' => '1.23.0.0',
+ 'reference' => '9a142215a36a3888e30d0a9eeea9766764e96976',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
'aliases' => array(),
- 'reference' => '9a142215a36a3888e30d0a9eeea9766764e96976',
'dev_requirement' => false,
),
'symfony/polyfill-php73' => array(
'pretty_version' => 'v1.23.0',
'version' => '1.23.0.0',
+ 'reference' => 'fba8933c384d6476ab14fb7b8526e5287ca7e010',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php73',
'aliases' => array(),
- 'reference' => 'fba8933c384d6476ab14fb7b8526e5287ca7e010',
'dev_requirement' => false,
),
'symfony/polyfill-php80' => array(
'pretty_version' => 'v1.23.1',
'version' => '1.23.1.0',
+ 'reference' => '1100343ed1a92e3a38f9ae122fc0eb21602547be',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
'aliases' => array(),
- 'reference' => '1100343ed1a92e3a38f9ae122fc0eb21602547be',
'dev_requirement' => false,
),
'symfony/process' => array(
'pretty_version' => 'v4.4.30',
'version' => '4.4.30.0',
+ 'reference' => '13d3161ef63a8ec21eeccaaf9a4d7f784a87a97d',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/process',
'aliases' => array(),
- 'reference' => '13d3161ef63a8ec21eeccaaf9a4d7f784a87a97d',
'dev_requirement' => false,
),
'symfony/routing' => array(
'pretty_version' => 'v4.4.30',
'version' => '4.4.30.0',
+ 'reference' => '9ddf033927ad9f30ba2bfd167a7b342cafa13e8e',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/routing',
'aliases' => array(),
- 'reference' => '9ddf033927ad9f30ba2bfd167a7b342cafa13e8e',
'dev_requirement' => false,
),
'symfony/service-contracts' => array(
'pretty_version' => 'v2.4.0',
'version' => '2.4.0.0',
+ 'reference' => 'f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/service-contracts',
'aliases' => array(),
- 'reference' => 'f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb',
'dev_requirement' => false,
),
'symfony/translation' => array(
'pretty_version' => 'v4.4.41',
'version' => '4.4.41.0',
+ 'reference' => 'dcb67eae126e74507e0b4f0b9ac6ef35b37c3331',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/translation',
'aliases' => array(),
- 'reference' => 'dcb67eae126e74507e0b4f0b9ac6ef35b37c3331',
'dev_requirement' => false,
),
'symfony/translation-contracts' => array(
'pretty_version' => 'v2.4.0',
'version' => '2.4.0.0',
+ 'reference' => '95c812666f3e91db75385749fe219c5e494c7f95',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/translation-contracts',
'aliases' => array(),
- 'reference' => '95c812666f3e91db75385749fe219c5e494c7f95',
'dev_requirement' => false,
),
'symfony/translation-implementation' => array(
@@ -847,37 +841,37 @@
'thecodingmachine/safe' => array(
'pretty_version' => 'v1.3.3',
'version' => '1.3.3.0',
+ 'reference' => 'a8ab0876305a4cdaef31b2350fcb9811b5608dbc',
'type' => 'library',
'install_path' => __DIR__ . '/../thecodingmachine/safe',
'aliases' => array(),
- 'reference' => 'a8ab0876305a4cdaef31b2350fcb9811b5608dbc',
'dev_requirement' => false,
),
'web-auth/cose-lib' => array(
'pretty_version' => 'v3.3.9',
'version' => '3.3.9.0',
+ 'reference' => 'ed172d2dc1a6b87b5c644c07c118cd30c1b3819b',
'type' => 'library',
'install_path' => __DIR__ . '/../web-auth/cose-lib',
'aliases' => array(),
- 'reference' => 'ed172d2dc1a6b87b5c644c07c118cd30c1b3819b',
'dev_requirement' => false,
),
'web-auth/metadata-service' => array(
'pretty_version' => 'v3.3.9',
'version' => '3.3.9.0',
+ 'reference' => '8488d3a832a38cc81c670fce05de1e515c6e64b1',
'type' => 'library',
'install_path' => __DIR__ . '/../web-auth/metadata-service',
'aliases' => array(),
- 'reference' => '8488d3a832a38cc81c670fce05de1e515c6e64b1',
'dev_requirement' => false,
),
'web-auth/webauthn-lib' => array(
'pretty_version' => 'v3.3.9',
'version' => '3.3.9.0',
+ 'reference' => '04b98ee3d39cb79dad68a7c15c297c085bf66bfe',
'type' => 'library',
'install_path' => __DIR__ . '/../web-auth/webauthn-lib',
'aliases' => array(),
- 'reference' => '04b98ee3d39cb79dad68a7c15c297c085bf66bfe',
'dev_requirement' => false,
),
),
diff --git a/composer/package-versions-deprecated/CHANGELOG.md b/composer/package-versions-deprecated/CHANGELOG.md
deleted file mode 100644
index a838c56a..00000000
--- a/composer/package-versions-deprecated/CHANGELOG.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# CHANGELOG
-
-## 1.1.3 - 2017-09-06
-
-This release fixes a bug that caused PackageVersions to prevent
-the `composer remove` and `composer update` commands to fail when
-this package is removed.
-
-In addition to that, mutation testing has been added to the suite,
-ensuring that the package is accurately and extensively tested.
-
-Total issues resolved: **3**
-
-- [40: Mutation testing, PHP 7.1 testing](https://github.com/Ocramius/PackageVersions/pull/40) thanks to @Ocramius
-- [41: Removing this package on install results in file access error](https://github.com/Ocramius/PackageVersions/issues/41) thanks to @Xerkus
-- [46: #41 Avoid issues when the package is scheduled for removal](https://github.com/Ocramius/PackageVersions/pull/46) thanks to @Jean85
-
-## 1.1.2 - 2016-12-30
-
-This release fixes a bug that caused PackageVersions to be enabled
-even when it was part of a globally installed package.
-
-Total issues resolved: **3**
-
-- [35: remove all temp directories](https://github.com/Ocramius/PackageVersions/pull/35)
-- [38: Interferes with other projects when installed globally](https://github.com/Ocramius/PackageVersions/issues/38)
-- [39: Ignore the global plugin when updating local projects](https://github.com/Ocramius/PackageVersions/pull/39)
-
-## 1.1.1 - 2016-07-25
-
-This release removes the [`"files"`](https://getcomposer.org/doc/04-schema.md#files) directive from
-[`composer.json`](https://github.com/Ocramius/PackageVersions/commit/86f2636f7c5e7b56fa035fa3826d5fcf80b6dc72),
-as it is no longer needed for `composer install --classmap-authoritative`.
-Also, that directive was causing issues with HHVM installations, since
-PackageVersions is not compatible with it.
-
-Total issues resolved: **1**
-
-- [34: Fatal error during travis build after update to 1.1.0](https://github.com/Ocramius/PackageVersions/issues/34)
-
-## 1.1.0 - 2016-07-22
-
-This release introduces support for running `composer install --classmap-authoritative`
-and `composer install --no-scripts`. Please note that performance
-while using these modes may be degraded, but the package will
-still work.
-
-Additionally, the package was tuned to prevent the plugin from
-running twice at installation.
-
-Total issues resolved: **10**
-
-- [18: Fails when using composer install --no-scripts](https://github.com/Ocramius/PackageVersions/issues/18)
-- [20: CS (spacing)](https://github.com/Ocramius/PackageVersions/pull/20)
-- [22: Document the way the require-dev section is treated](https://github.com/Ocramius/PackageVersions/issues/22)
-- [23: Underline that composer.lock is used as source of information](https://github.com/Ocramius/PackageVersions/pull/23)
-- [27: Fix incompatibility with --classmap-authoritative](https://github.com/Ocramius/PackageVersions/pull/27)
-- [29: mention optimize-autoloader composer.json config option in README](https://github.com/Ocramius/PackageVersions/pull/29)
-- [30: The version class is generated twice during composer update](https://github.com/Ocramius/PackageVersions/issues/30)
-- [31: Remove double registration of the event listeners](https://github.com/Ocramius/PackageVersions/pull/31)
-- [32: Update the usage of mock APIs to use the new API](https://github.com/Ocramius/PackageVersions/pull/32)
-- [33: Fix for #18 - support running with --no-scripts flag](https://github.com/Ocramius/PackageVersions/pull/33)
-
-## 1.0.4 - 2016-04-23
-
-This release includes a fix/workaround for composer/composer#5237,
-which causes `ocramius/package-versions` to sometimes generate a
-`Versions` class with malformed name (something like
-`Versions_composer_tmp0`) when running `composer require <package-name>`.
-
-Total issues resolved: **2**
-
-- [16: Workaround for composer/composer#5237 - class parsing](https://github.com/Ocramius/PackageVersions/pull/16)
-- [17: Weird Class name being generated](https://github.com/Ocramius/PackageVersions/issues/17)
-
-## 1.0.3 - 2016-02-26
-
-This release fixes an issue related to concurrent autoloader
-re-generation caused by multiple composer plugins being installed.
-The issue was solved by removing autoloader re-generation from this
-package, but it may still affect other packages.
-
-It is now recommended that you run `composer dump-autoload --optimize`
-after installation when using this particular package.
-Please note that `composer (install|update) -o` is not sufficient
-to avoid autoload overhead when using this particular package.
-
-Total issues resolved: **1**
-
-- [15: Remove autoload re-dump optimization](https://github.com/Ocramius/PackageVersions/pull/15)
-
-## 1.0.2 - 2016-02-24
-
-This release fixes issues related to installing the component without
-any dev dependencies or with packages that don't have a source or dist
-reference, which is usual with packages defined directly in the
-`composer.json`.
-
-Total issues resolved: **3**
-
-- [11: fix composer install --no-dev PHP7](https://github.com/Ocramius/PackageVersions/pull/11)
-- [12: Packages don't always have a source/reference](https://github.com/Ocramius/PackageVersions/issues/12)
-- [13: Fix #12 - support dist and missing package version references](https://github.com/Ocramius/PackageVersions/pull/13)
-
-## 1.0.1 - 2016-02-01
-
-This release fixes an issue related with composer updates to
-already installed versions.
-Using `composer require` within a package that already used
-`ocramius/package-versions` caused the installation to be unable
-to write the `PackageVersions\Versions` class to a file.
-
-Total issues resolved: **6**
-
-- [2: remove unused use statement](https://github.com/Ocramius/PackageVersions/pull/2)
-- [3: Remove useless files from dist package](https://github.com/Ocramius/PackageVersions/pull/3)
-- [5: failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly](https://github.com/Ocramius/PackageVersions/issues/5)
-- [6: Fix/#5 use composer vendor dir](https://github.com/Ocramius/PackageVersions/pull/6)
-- [7: Hotfix - #5 generate package versions also when in phar context](https://github.com/Ocramius/PackageVersions/pull/7)
-- [8: Versions class should be ignored by VCS, as it is an install-time artifact](https://github.com/Ocramius/PackageVersions/pull/8)
diff --git a/composer/package-versions-deprecated/CONTRIBUTING.md b/composer/package-versions-deprecated/CONTRIBUTING.md
deleted file mode 100644
index 71806175..00000000
--- a/composer/package-versions-deprecated/CONTRIBUTING.md
+++ /dev/null
@@ -1,39 +0,0 @@
----
-title: Contributing
----
-
-# Contributing
-
- * Coding standard for the project is [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
- * The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php)
- * Any contribution must provide tests for additional introduced conditions
- * Any un-confirmed issue needs a failing test case before being accepted
- * Pull requests must be sent from a new hotfix/feature branch, not from `master`.
-
-## Installation
-
-To install the project and run the tests, you need to clone it first:
-
-```sh
-$ git clone git://github.com/Ocramius/PackageVersions.git
-```
-
-You will then need to run a composer installation:
-
-```sh
-$ cd PackageVersions
-$ curl -s https://getcomposer.org/installer | php
-$ php composer.phar update
-```
-
-## Testing
-
-The PHPUnit version to be used is the one installed as a dev- dependency via composer:
-
-```sh
-$ ./vendor/bin/phpunit
-```
-
-Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement
-won't be merged.
-
diff --git a/composer/package-versions-deprecated/README.md b/composer/package-versions-deprecated/README.md
deleted file mode 100644
index 7fe2097d..00000000
--- a/composer/package-versions-deprecated/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Package Versions
-
-**`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\InstalledVersions` class which offers the functionality present here out of the box.
diff --git a/composer/package-versions-deprecated/SECURITY.md b/composer/package-versions-deprecated/SECURITY.md
deleted file mode 100644
index da9c516d..00000000
--- a/composer/package-versions-deprecated/SECURITY.md
+++ /dev/null
@@ -1,5 +0,0 @@
-## Security contact information
-
-To report a security vulnerability, please use the
-[Tidelift security contact](https://tidelift.com/security).
-Tidelift will coordinate the fix and disclosure.
diff --git a/composer/package-versions-deprecated/composer.json b/composer/package-versions-deprecated/composer.json
deleted file mode 100644
index d5a40daa..00000000
--- a/composer/package-versions-deprecated/composer.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "name": "composer/package-versions-deprecated",
- "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
- "type": "composer-plugin",
- "license": "MIT",
- "authors": [
- {
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com"
- },
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be"
- }
- ],
- "require": {
- "php": "^7 || ^8",
- "composer-plugin-api": "^1.1.0 || ^2.0"
- },
- "replace": {
- "ocramius/package-versions": "1.11.99"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.5 || ^7",
- "composer/composer": "^1.9.3 || ^2.0@dev",
- "ext-zip": "^1.13"
- },
- "autoload": {
- "psr-4": {
- "PackageVersions\\": "src/PackageVersions"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "PackageVersionsTest\\": "test/PackageVersionsTest"
- }
- },
- "extra": {
- "class": "PackageVersions\\Installer",
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "scripts": {
- "post-update-cmd": "PackageVersions\\Installer::dumpVersionsClass",
- "post-install-cmd": "PackageVersions\\Installer::dumpVersionsClass"
- }
-}
diff --git a/composer/package-versions-deprecated/composer.lock b/composer/package-versions-deprecated/composer.lock
deleted file mode 100644
index b711f6b1..00000000
--- a/composer/package-versions-deprecated/composer.lock
+++ /dev/null
@@ -1,2603 +0,0 @@
-{
- "_readme": [
- "This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
- "This file is @generated automatically"
- ],
- "content-hash": "6bfe0a7d7a51c4bdf14a2d7ea1d22d11",
- "packages": [],
- "packages-dev": [
- {
- "name": "composer/ca-bundle",
- "version": "1.2.7",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/ca-bundle.git",
- "reference": "95c63ab2117a72f48f5a55da9740a3273d45b7fd"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/ca-bundle/zipball/95c63ab2117a72f48f5a55da9740a3273d45b7fd",
- "reference": "95c63ab2117a72f48f5a55da9740a3273d45b7fd",
- "shasum": ""
- },
- "require": {
- "ext-openssl": "*",
- "ext-pcre": "*",
- "php": "^5.3.2 || ^7.0 || ^8.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8",
- "psr/log": "^1.0",
- "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\CaBundle\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- }
- ],
- "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
- "keywords": [
- "cabundle",
- "cacert",
- "certificate",
- "ssl",
- "tls"
- ],
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2020-04-08T08:27:21+00:00"
- },
- {
- "name": "composer/composer",
- "version": "dev-master",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/composer.git",
- "reference": "a8c105da344dd84ebd5d11be7943a45b09dc076f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/composer/zipball/a8c105da344dd84ebd5d11be7943a45b09dc076f",
- "reference": "a8c105da344dd84ebd5d11be7943a45b09dc076f",
- "shasum": ""
- },
- "require": {
- "composer/ca-bundle": "^1.0",
- "composer/semver": "^1.0",
- "composer/spdx-licenses": "^1.2",
- "composer/xdebug-handler": "^1.1",
- "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0",
- "php": "^5.3.2 || ^7.0",
- "psr/log": "^1.0",
- "seld/jsonlint": "^1.4",
- "seld/phar-utils": "^1.0",
- "symfony/console": "^2.7 || ^3.0 || ^4.0 || ^5.0",
- "symfony/filesystem": "^2.7 || ^3.0 || ^4.0 || ^5.0",
- "symfony/finder": "^2.7 || ^3.0 || ^4.0 || ^5.0",
- "symfony/process": "^2.7 || ^3.0 || ^4.0 || ^5.0"
- },
- "conflict": {
- "symfony/console": "2.8.38"
- },
- "require-dev": {
- "phpspec/prophecy": "^1.10",
- "symfony/phpunit-bridge": "^3.4"
- },
- "suggest": {
- "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages",
- "ext-zip": "Enabling the zip extension allows you to unzip archives",
- "ext-zlib": "Allow gzip compression of HTTP requests"
- },
- "bin": [
- "bin/composer"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.10-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\": "src/Composer"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nils Adermann",
- "email": "naderman@naderman.de",
- "homepage": "http://www.naderman.de"
- },
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- }
- ],
- "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.",
- "homepage": "https://getcomposer.org/",
- "keywords": [
- "autoload",
- "dependency",
- "package"
- ],
- "support": {
- "irc": "irc://irc.freenode.org/composer",
- "issues": "https://github.com/composer/composer/issues",
- "source": "https://github.com/composer/composer/tree/master"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2020-03-29T14:59:26+00:00"
- },
- {
- "name": "composer/semver",
- "version": "1.5.1",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/semver.git",
- "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/semver/zipball/c6bea70230ef4dd483e6bbcab6005f682ed3a8de",
- "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de",
- "shasum": ""
- },
- "require": {
- "php": "^5.3.2 || ^7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.5 || ^5.0.5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\Semver\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nils Adermann",
- "email": "naderman@naderman.de",
- "homepage": "http://www.naderman.de"
- },
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- },
- {
- "name": "Rob Bast",
- "email": "rob.bast@gmail.com",
- "homepage": "http://robbast.nl"
- }
- ],
- "description": "Semver library that offers utilities, version constraint parsing and validation.",
- "keywords": [
- "semantic",
- "semver",
- "validation",
- "versioning"
- ],
- "support": {
- "irc": "irc://irc.freenode.org/composer",
- "issues": "https://github.com/composer/semver/issues",
- "source": "https://github.com/composer/semver/tree/1.5.1"
- },
- "time": "2020-01-13T12:06:48+00:00"
- },
- {
- "name": "composer/spdx-licenses",
- "version": "1.5.3",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/spdx-licenses.git",
- "reference": "0c3e51e1880ca149682332770e25977c70cf9dae"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/0c3e51e1880ca149682332770e25977c70cf9dae",
- "reference": "0c3e51e1880ca149682332770e25977c70cf9dae",
- "shasum": ""
- },
- "require": {
- "php": "^5.3.2 || ^7.0 || ^8.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\Spdx\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nils Adermann",
- "email": "naderman@naderman.de",
- "homepage": "http://www.naderman.de"
- },
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- },
- {
- "name": "Rob Bast",
- "email": "rob.bast@gmail.com",
- "homepage": "http://robbast.nl"
- }
- ],
- "description": "SPDX licenses list and validation library.",
- "keywords": [
- "license",
- "spdx",
- "validator"
- ],
- "time": "2020-02-14T07:44:31+00:00"
- },
- {
- "name": "composer/xdebug-handler",
- "version": "1.4.1",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/xdebug-handler.git",
- "reference": "1ab9842d69e64fb3a01be6b656501032d1b78cb7"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/1ab9842d69e64fb3a01be6b656501032d1b78cb7",
- "reference": "1ab9842d69e64fb3a01be6b656501032d1b78cb7",
- "shasum": ""
- },
- "require": {
- "php": "^5.3.2 || ^7.0 || ^8.0",
- "psr/log": "^1.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Composer\\XdebugHandler\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "John Stevenson",
- "email": "john-stevenson@blueyonder.co.uk"
- }
- ],
- "description": "Restarts a process without Xdebug.",
- "keywords": [
- "Xdebug",
- "performance"
- ],
- "support": {
- "irc": "irc://irc.freenode.org/composer",
- "issues": "https://github.com/composer/xdebug-handler/issues",
- "source": "https://github.com/composer/xdebug-handler/tree/master"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- }
- ],
- "time": "2020-03-01T12:26:26+00:00"
- },
- {
- "name": "doctrine/instantiator",
- "version": "1.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/instantiator.git",
- "reference": "ae466f726242e637cebdd526a7d991b9433bacf1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1",
- "reference": "ae466f726242e637cebdd526a7d991b9433bacf1",
- "shasum": ""
- },
- "require": {
- "php": "^7.1"
- },
- "require-dev": {
- "doctrine/coding-standard": "^6.0",
- "ext-pdo": "*",
- "ext-phar": "*",
- "phpbench/phpbench": "^0.13",
- "phpstan/phpstan-phpunit": "^0.11",
- "phpstan/phpstan-shim": "^0.11",
- "phpunit/phpunit": "^7.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.2.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com",
- "homepage": "http://ocramius.github.com/"
- }
- ],
- "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
- "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
- "keywords": [
- "constructor",
- "instantiate"
- ],
- "support": {
- "issues": "https://github.com/doctrine/instantiator/issues",
- "source": "https://github.com/doctrine/instantiator/tree/master"
- },
- "time": "2019-10-21T16:45:58+00:00"
- },
- {
- "name": "justinrainbow/json-schema",
- "version": "5.2.9",
- "source": {
- "type": "git",
- "url": "https://github.com/justinrainbow/json-schema.git",
- "reference": "44c6787311242a979fa15c704327c20e7221a0e4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/44c6787311242a979fa15c704327c20e7221a0e4",
- "reference": "44c6787311242a979fa15c704327c20e7221a0e4",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
- "json-schema/json-schema-test-suite": "1.2.0",
- "phpunit/phpunit": "^4.8.35"
- },
- "bin": [
- "bin/validate-json"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "JsonSchema\\": "src/JsonSchema/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Bruno Prieto Reis",
- "email": "bruno.p.reis@gmail.com"
- },
- {
- "name": "Justin Rainbow",
- "email": "justin.rainbow@gmail.com"
- },
- {
- "name": "Igor Wiedler",
- "email": "igor@wiedler.ch"
- },
- {
- "name": "Robert Schönthal",
- "email": "seroscho@googlemail.com"
- }
- ],
- "description": "A library to validate a json schema.",
- "homepage": "https://github.com/justinrainbow/json-schema",
- "keywords": [
- "json",
- "schema"
- ],
- "support": {
- "issues": "https://github.com/justinrainbow/json-schema/issues",
- "source": "https://github.com/justinrainbow/json-schema/tree/5.2.9"
- },
- "time": "2019-09-25T14:49:45+00:00"
- },
- {
- "name": "myclabs/deep-copy",
- "version": "1.9.5",
- "source": {
- "type": "git",
- "url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef",
- "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef",
- "shasum": ""
- },
- "require": {
- "php": "^7.1"
- },
- "replace": {
- "myclabs/deep-copy": "self.version"
- },
- "require-dev": {
- "doctrine/collections": "^1.0",
- "doctrine/common": "^2.6",
- "phpunit/phpunit": "^7.1"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "DeepCopy\\": "src/DeepCopy/"
- },
- "files": [
- "src/DeepCopy/deep_copy.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "Create deep copies (clones) of your objects",
- "keywords": [
- "clone",
- "copy",
- "duplicate",
- "object",
- "object graph"
- ],
- "support": {
- "issues": "https://github.com/myclabs/DeepCopy/issues",
- "source": "https://github.com/myclabs/DeepCopy/tree/1.9.5"
- },
- "time": "2020-01-17T21:11:47+00:00"
- },
- {
- "name": "phar-io/manifest",
- "version": "1.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/phar-io/manifest.git",
- "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
- "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-phar": "*",
- "phar-io/version": "^2.0",
- "php": "^5.6 || ^7.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Heuer",
- "email": "sebastian@phpeople.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "Developer"
- }
- ],
- "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
- "time": "2018-07-08T19:23:20+00:00"
- },
- {
- "name": "phar-io/version",
- "version": "2.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phar-io/version.git",
- "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
- "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
- "shasum": ""
- },
- "require": {
- "php": "^5.6 || ^7.0"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Heuer",
- "email": "sebastian@phpeople.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "Developer"
- }
- ],
- "description": "Library for handling version information and constraints",
- "time": "2018-07-08T19:19:57+00:00"
- },
- {
- "name": "phpdocumentor/reflection-common",
- "version": "2.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a",
- "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "~6"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
- "homepage": "http://www.phpdoc.org",
- "time": "2018-08-07T13:53:10+00:00"
- },
- {
- "name": "phpdocumentor/reflection-docblock",
- "version": "5.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e",
- "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e",
- "shasum": ""
- },
- "require": {
- "ext-filter": "^7.1",
- "php": "^7.2",
- "phpdocumentor/reflection-common": "^2.0",
- "phpdocumentor/type-resolver": "^1.0",
- "webmozart/assert": "^1"
- },
- "require-dev": {
- "doctrine/instantiator": "^1",
- "mockery/mockery": "^1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- },
- {
- "name": "Jaap van Otterdijk",
- "email": "account@ijaap.nl"
- }
- ],
- "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
- "time": "2020-02-22T12:28:44+00:00"
- },
- {
- "name": "phpdocumentor/type-resolver",
- "version": "1.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "7462d5f123dfc080dfdf26897032a6513644fc95"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/7462d5f123dfc080dfdf26897032a6513644fc95",
- "reference": "7462d5f123dfc080dfdf26897032a6513644fc95",
- "shasum": ""
- },
- "require": {
- "php": "^7.2",
- "phpdocumentor/reflection-common": "^2.0"
- },
- "require-dev": {
- "ext-tokenizer": "^7.2",
- "mockery/mockery": "~1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- }
- ],
- "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
- "support": {
- "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
- "source": "https://github.com/phpDocumentor/TypeResolver/tree/master"
- },
- "time": "2020-02-18T18:59:58+00:00"
- },
- {
- "name": "phpspec/prophecy",
- "version": "v1.10.3",
- "source": {
- "type": "git",
- "url": "https://github.com/phpspec/prophecy.git",
- "reference": "451c3cd1418cf640de218914901e51b064abb093"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093",
- "reference": "451c3cd1418cf640de218914901e51b064abb093",
- "shasum": ""
- },
- "require": {
- "doctrine/instantiator": "^1.0.2",
- "php": "^5.3|^7.0",
- "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
- "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0",
- "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0"
- },
- "require-dev": {
- "phpspec/phpspec": "^2.5 || ^3.2",
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.10.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Prophecy\\": "src/Prophecy"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com",
- "homepage": "http://everzet.com"
- },
- {
- "name": "Marcello Duarte",
- "email": "marcello.duarte@gmail.com"
- }
- ],
- "description": "Highly opinionated mocking framework for PHP 5.3+",
- "homepage": "https://github.com/phpspec/prophecy",
- "keywords": [
- "Double",
- "Dummy",
- "fake",
- "mock",
- "spy",
- "stub"
- ],
- "support": {
- "issues": "https://github.com/phpspec/prophecy/issues",
- "source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
- },
- "time": "2020-03-05T15:02:03+00:00"
- },
- {
- "name": "phpunit/php-code-coverage",
- "version": "6.1.4",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
- "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-xmlwriter": "*",
- "php": "^7.1",
- "phpunit/php-file-iterator": "^2.0",
- "phpunit/php-text-template": "^1.2.1",
- "phpunit/php-token-stream": "^3.0",
- "sebastian/code-unit-reverse-lookup": "^1.0.1",
- "sebastian/environment": "^3.1 || ^4.0",
- "sebastian/version": "^2.0.1",
- "theseer/tokenizer": "^1.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.0"
- },
- "suggest": {
- "ext-xdebug": "^2.6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "6.1-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
- "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
- "keywords": [
- "coverage",
- "testing",
- "xunit"
- ],
- "time": "2018-10-31T16:06:48+00:00"
- },
- {
- "name": "phpunit/php-file-iterator",
- "version": "2.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "050bedf145a257b1ff02746c31894800e5122946"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946",
- "reference": "050bedf145a257b1ff02746c31894800e5122946",
- "shasum": ""
- },
- "require": {
- "php": "^7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "FilterIterator implementation that filters files based on a list of suffixes.",
- "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
- "keywords": [
- "filesystem",
- "iterator"
- ],
- "time": "2018-09-13T20:33:42+00:00"
- },
- {
- "name": "phpunit/php-text-template",
- "version": "1.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-text-template.git",
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Simple template engine.",
- "homepage": "https://github.com/sebastianbergmann/php-text-template/",
- "keywords": [
- "template"
- ],
- "time": "2015-06-21T13:50:34+00:00"
- },
- {
- "name": "phpunit/php-timer",
- "version": "2.1.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "1038454804406b0b5f5f520358e78c1c2f71501e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e",
- "reference": "1038454804406b0b5f5f520358e78c1c2f71501e",
- "shasum": ""
- },
- "require": {
- "php": "^7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.1-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Utility class for timing",
- "homepage": "https://github.com/sebastianbergmann/php-timer/",
- "keywords": [
- "timer"
- ],
- "time": "2019-06-07T04:22:29+00:00"
- },
- {
- "name": "phpunit/php-token-stream",
- "version": "3.1.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff",
- "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff",
- "shasum": ""
- },
- "require": {
- "ext-tokenizer": "*",
- "php": "^7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.1-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Wrapper around PHP's tokenizer extension.",
- "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
- "keywords": [
- "tokenizer"
- ],
- "time": "2019-09-17T06:23:10+00:00"
- },
- {
- "name": "phpunit/phpunit",
- "version": "7.5.20",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "9467db479d1b0487c99733bb1e7944d32deded2c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c",
- "reference": "9467db479d1b0487c99733bb1e7944d32deded2c",
- "shasum": ""
- },
- "require": {
- "doctrine/instantiator": "^1.1",
- "ext-dom": "*",
- "ext-json": "*",
- "ext-libxml": "*",
- "ext-mbstring": "*",
- "ext-xml": "*",
- "myclabs/deep-copy": "^1.7",
- "phar-io/manifest": "^1.0.2",
- "phar-io/version": "^2.0",
- "php": "^7.1",
- "phpspec/prophecy": "^1.7",
- "phpunit/php-code-coverage": "^6.0.7",
- "phpunit/php-file-iterator": "^2.0.1",
- "phpunit/php-text-template": "^1.2.1",
- "phpunit/php-timer": "^2.1",
- "sebastian/comparator": "^3.0",
- "sebastian/diff": "^3.0",
- "sebastian/environment": "^4.0",
- "sebastian/exporter": "^3.1",
- "sebastian/global-state": "^2.0",
- "sebastian/object-enumerator": "^3.0.3",
- "sebastian/resource-operations": "^2.0",
- "sebastian/version": "^2.0.1"
- },
- "conflict": {
- "phpunit/phpunit-mock-objects": "*"
- },
- "require-dev": {
- "ext-pdo": "*"
- },
- "suggest": {
- "ext-soap": "*",
- "ext-xdebug": "*",
- "phpunit/php-invoker": "^2.0"
- },
- "bin": [
- "phpunit"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "7.5-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "The PHP Unit Testing framework.",
- "homepage": "https://phpunit.de/",
- "keywords": [
- "phpunit",
- "testing",
- "xunit"
- ],
- "time": "2020-01-08T08:45:45+00:00"
- },
- {
- "name": "psr/container",
- "version": "1.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/container.git",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Container\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common Container Interface (PHP FIG PSR-11)",
- "homepage": "https://github.com/php-fig/container",
- "keywords": [
- "PSR-11",
- "container",
- "container-interface",
- "container-interop",
- "psr"
- ],
- "time": "2017-02-14T16:28:37+00:00"
- },
- {
- "name": "psr/log",
- "version": "1.1.3",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/log.git",
- "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
- "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Log\\": "Psr/Log/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interface for logging libraries",
- "homepage": "https://github.com/php-fig/log",
- "keywords": [
- "log",
- "psr",
- "psr-3"
- ],
- "time": "2020-03-23T09:12:05+00:00"
- },
- {
- "name": "sebastian/code-unit-reverse-lookup",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
- "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
- "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
- "shasum": ""
- },
- "require": {
- "php": "^5.6 || ^7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^5.7 || ^6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Looks up which function or method a line of code belongs to",
- "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
- "time": "2017-03-04T06:30:41+00:00"
- },
- {
- "name": "sebastian/comparator",
- "version": "3.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
- "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
- "shasum": ""
- },
- "require": {
- "php": "^7.1",
- "sebastian/diff": "^3.0",
- "sebastian/exporter": "^3.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Volker Dusch",
- "email": "github@wallbash.com"
- },
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@2bepublished.at"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Provides the functionality to compare PHP values for equality",
- "homepage": "https://github.com/sebastianbergmann/comparator",
- "keywords": [
- "comparator",
- "compare",
- "equality"
- ],
- "time": "2018-07-12T15:12:46+00:00"
- },
- {
- "name": "sebastian/diff",
- "version": "3.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
- "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
- "shasum": ""
- },
- "require": {
- "php": "^7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.5 || ^8.0",
- "symfony/process": "^2 || ^3.3 || ^4"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Kore Nordmann",
- "email": "mail@kore-nordmann.de"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Diff implementation",
- "homepage": "https://github.com/sebastianbergmann/diff",
- "keywords": [
- "diff",
- "udiff",
- "unidiff",
- "unified diff"
- ],
- "time": "2019-02-04T06:01:07+00:00"
- },
- {
- "name": "sebastian/environment",
- "version": "4.2.3",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
- "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
- "shasum": ""
- },
- "require": {
- "php": "^7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.5"
- },
- "suggest": {
- "ext-posix": "*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Provides functionality to handle HHVM/PHP environments",
- "homepage": "http://www.github.com/sebastianbergmann/environment",
- "keywords": [
- "Xdebug",
- "environment",
- "hhvm"
- ],
- "time": "2019-11-20T08:46:58+00:00"
- },
- {
- "name": "sebastian/exporter",
- "version": "3.1.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e",
- "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e",
- "shasum": ""
- },
- "require": {
- "php": "^7.0",
- "sebastian/recursion-context": "^3.0"
- },
- "require-dev": {
- "ext-mbstring": "*",
- "phpunit/phpunit": "^6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.1.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Volker Dusch",
- "email": "github@wallbash.com"
- },
- {
- "name": "Adam Harvey",
- "email": "aharvey@php.net"
- },
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@gmail.com"
- }
- ],
- "description": "Provides the functionality to export PHP variables for visualization",
- "homepage": "http://www.github.com/sebastianbergmann/exporter",
- "keywords": [
- "export",
- "exporter"
- ],
- "time": "2019-09-14T09:02:43+00:00"
- },
- {
- "name": "sebastian/global-state",
- "version": "2.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
- "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
- "shasum": ""
- },
- "require": {
- "php": "^7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.0"
- },
- "suggest": {
- "ext-uopz": "*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Snapshotting of global state",
- "homepage": "http://www.github.com/sebastianbergmann/global-state",
- "keywords": [
- "global state"
- ],
- "time": "2017-04-27T15:39:26+00:00"
- },
- {
- "name": "sebastian/object-enumerator",
- "version": "3.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/object-enumerator.git",
- "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5",
- "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5",
- "shasum": ""
- },
- "require": {
- "php": "^7.0",
- "sebastian/object-reflector": "^1.1.1",
- "sebastian/recursion-context": "^3.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Traverses array structures and object graphs to enumerate all referenced objects",
- "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
- "time": "2017-08-03T12:35:26+00:00"
- },
- {
- "name": "sebastian/object-reflector",
- "version": "1.1.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/object-reflector.git",
- "reference": "773f97c67f28de00d397be301821b06708fca0be"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be",
- "reference": "773f97c67f28de00d397be301821b06708fca0be",
- "shasum": ""
- },
- "require": {
- "php": "^7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Allows reflection of object attributes, including inherited and non-public ones",
- "homepage": "https://github.com/sebastianbergmann/object-reflector/",
- "time": "2017-03-29T09:07:27+00:00"
- },
- {
- "name": "sebastian/recursion-context",
- "version": "3.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
- "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
- "shasum": ""
- },
- "require": {
- "php": "^7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Adam Harvey",
- "email": "aharvey@php.net"
- }
- ],
- "description": "Provides functionality to recursively process PHP variables",
- "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
- "time": "2017-03-03T06:23:57+00:00"
- },
- {
- "name": "sebastian/resource-operations",
- "version": "2.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/resource-operations.git",
- "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
- "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
- "shasum": ""
- },
- "require": {
- "php": "^7.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Provides a list of PHP built-in functions that operate on resources",
- "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
- "time": "2018-10-04T04:07:39+00:00"
- },
- {
- "name": "sebastian/version",
- "version": "2.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/version.git",
- "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
- "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
- "shasum": ""
- },
- "require": {
- "php": ">=5.6"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Library that helps with managing the version number of Git-hosted PHP projects",
- "homepage": "https://github.com/sebastianbergmann/version",
- "time": "2016-10-03T07:35:21+00:00"
- },
- {
- "name": "seld/jsonlint",
- "version": "1.7.2",
- "source": {
- "type": "git",
- "url": "https://github.com/Seldaek/jsonlint.git",
- "reference": "e2e5d290e4d2a4f0eb449f510071392e00e10d19"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/e2e5d290e4d2a4f0eb449f510071392e00e10d19",
- "reference": "e2e5d290e4d2a4f0eb449f510071392e00e10d19",
- "shasum": ""
- },
- "require": {
- "php": "^5.3 || ^7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
- },
- "bin": [
- "bin/jsonlint"
- ],
- "type": "library",
- "autoload": {
- "psr-4": {
- "Seld\\JsonLint\\": "src/Seld/JsonLint/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- }
- ],
- "description": "JSON Linter",
- "keywords": [
- "json",
- "linter",
- "parser",
- "validator"
- ],
- "support": {
- "issues": "https://github.com/Seldaek/jsonlint/issues",
- "source": "https://github.com/Seldaek/jsonlint/tree/1.7.2"
- },
- "time": "2019-10-24T14:27:39+00:00"
- },
- {
- "name": "seld/phar-utils",
- "version": "1.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/Seldaek/phar-utils.git",
- "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8800503d56b9867d43d9c303b9cbcc26016e82f0",
- "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Seld\\PharUtils\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be"
- }
- ],
- "description": "PHAR file format utilities, for when PHP phars you up",
- "keywords": [
- "phar"
- ],
- "support": {
- "issues": "https://github.com/Seldaek/phar-utils/issues",
- "source": "https://github.com/Seldaek/phar-utils/tree/1.1.0"
- },
- "time": "2020-02-14T15:25:33+00:00"
- },
- {
- "name": "symfony/console",
- "version": "v5.0.7",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/console.git",
- "reference": "5fa1caadc8cdaa17bcfb25219f3b53fe294a9935"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/5fa1caadc8cdaa17bcfb25219f3b53fe294a9935",
- "reference": "5fa1caadc8cdaa17bcfb25219f3b53fe294a9935",
- "shasum": ""
- },
- "require": {
- "php": "^7.2.5",
- "symfony/polyfill-mbstring": "~1.0",
- "symfony/polyfill-php73": "^1.8",
- "symfony/service-contracts": "^1.1|^2"
- },
- "conflict": {
- "symfony/dependency-injection": "<4.4",
- "symfony/event-dispatcher": "<4.4",
- "symfony/lock": "<4.4",
- "symfony/process": "<4.4"
- },
- "provide": {
- "psr/log-implementation": "1.0"
- },
- "require-dev": {
- "psr/log": "~1.0",
- "symfony/config": "^4.4|^5.0",
- "symfony/dependency-injection": "^4.4|^5.0",
- "symfony/event-dispatcher": "^4.4|^5.0",
- "symfony/lock": "^4.4|^5.0",
- "symfony/process": "^4.4|^5.0",
- "symfony/var-dumper": "^4.4|^5.0"
- },
- "suggest": {
- "psr/log": "For using the console logger",
- "symfony/event-dispatcher": "",
- "symfony/lock": "",
- "symfony/process": ""
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.0-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Console\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony Console Component",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/console/tree/v5.0.7"
- },
- "time": "2020-03-30T11:42:42+00:00"
- },
- {
- "name": "symfony/filesystem",
- "version": "v5.0.7",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/filesystem.git",
- "reference": "ca3b87dd09fff9b771731637f5379965fbfab420"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/ca3b87dd09fff9b771731637f5379965fbfab420",
- "reference": "ca3b87dd09fff9b771731637f5379965fbfab420",
- "shasum": ""
- },
- "require": {
- "php": "^7.2.5",
- "symfony/polyfill-ctype": "~1.8"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.0-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Filesystem\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony Filesystem Component",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/filesystem/tree/v5.0.7"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2020-03-27T16:56:45+00:00"
- },
- {
- "name": "symfony/finder",
- "version": "v5.0.7",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/finder.git",
- "reference": "600a52c29afc0d1caa74acbec8d3095ca7e9910d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/600a52c29afc0d1caa74acbec8d3095ca7e9910d",
- "reference": "600a52c29afc0d1caa74acbec8d3095ca7e9910d",
- "shasum": ""
- },
- "require": {
- "php": "^7.2.5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.0-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Finder\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony Finder Component",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/finder/tree/5.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2020-03-27T16:56:45+00:00"
- },
- {
- "name": "symfony/polyfill-ctype",
- "version": "v1.15.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/4719fa9c18b0464d399f1a63bf624b42b6fa8d14",
- "reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "suggest": {
- "ext-ctype": "For best performance"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.15-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for ctype functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "ctype",
- "polyfill",
- "portable"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.15.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2020-02-27T09:26:54+00:00"
- },
- {
- "name": "symfony/polyfill-mbstring",
- "version": "v1.15.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
- "reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "suggest": {
- "ext-mbstring": "For best performance"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.15-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Mbstring\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for the Mbstring extension",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "mbstring",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.15.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2020-03-09T19:04:49+00:00"
- },
- {
- "name": "symfony/polyfill-php73",
- "version": "v1.15.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php73.git",
- "reference": "0f27e9f464ea3da33cbe7ca3bdf4eb66def9d0f7"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f27e9f464ea3da33cbe7ca3bdf4eb66def9d0f7",
- "reference": "0f27e9f464ea3da33cbe7ca3bdf4eb66def9d0f7",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.15-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Php73\\": ""
- },
- "files": [
- "bootstrap.php"
- ],
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-php73/tree/v1.15.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2020-02-27T09:26:54+00:00"
- },
- {
- "name": "symfony/process",
- "version": "v5.0.7",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/process.git",
- "reference": "c5ca4a0fc16a0c888067d43fbcfe1f8a53d8e70e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/c5ca4a0fc16a0c888067d43fbcfe1f8a53d8e70e",
- "reference": "c5ca4a0fc16a0c888067d43fbcfe1f8a53d8e70e",
- "shasum": ""
- },
- "require": {
- "php": "^7.2.5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.0-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Process\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony Process Component",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/process/tree/v5.0.7"
- },
- "time": "2020-03-27T16:56:45+00:00"
- },
- {
- "name": "symfony/service-contracts",
- "version": "v2.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/service-contracts.git",
- "reference": "144c5e51266b281231e947b51223ba14acf1a749"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/144c5e51266b281231e947b51223ba14acf1a749",
- "reference": "144c5e51266b281231e947b51223ba14acf1a749",
- "shasum": ""
- },
- "require": {
- "php": "^7.2.5",
- "psr/container": "^1.0"
- },
- "suggest": {
- "symfony/service-implementation": ""
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Contracts\\Service\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Generic abstractions related to writing services",
- "homepage": "https://symfony.com",
- "keywords": [
- "abstractions",
- "contracts",
- "decoupling",
- "interfaces",
- "interoperability",
- "standards"
- ],
- "support": {
- "source": "https://github.com/symfony/service-contracts/tree/v2.0.1"
- },
- "time": "2019-11-18T17:27:11+00:00"
- },
- {
- "name": "theseer/tokenizer",
- "version": "1.1.3",
- "source": {
- "type": "git",
- "url": "https://github.com/theseer/tokenizer.git",
- "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
- "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-tokenizer": "*",
- "ext-xmlwriter": "*",
- "php": "^7.0"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- }
- ],
- "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
- "time": "2019-06-13T22:48:21+00:00"
- },
- {
- "name": "webmozart/assert",
- "version": "1.8.0",
- "source": {
- "type": "git",
- "url": "https://github.com/webmozart/assert.git",
- "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/ab2cb0b3b559010b75981b1bdce728da3ee90ad6",
- "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6",
- "shasum": ""
- },
- "require": {
- "php": "^5.3.3 || ^7.0",
- "symfony/polyfill-ctype": "^1.8"
- },
- "conflict": {
- "vimeo/psalm": "<3.9.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.8.36 || ^7.5.13"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Webmozart\\Assert\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@gmail.com"
- }
- ],
- "description": "Assertions to validate method input/output with nice error messages.",
- "keywords": [
- "assert",
- "check",
- "validate"
- ],
- "support": {
- "issues": "https://github.com/webmozart/assert/issues",
- "source": "https://github.com/webmozart/assert/tree/master"
- },
- "time": "2020-04-18T12:12:48+00:00"
- }
- ],
- "aliases": [],
- "minimum-stability": "stable",
- "stability-flags": {
- "composer/composer": 20
- },
- "prefer-stable": false,
- "prefer-lowest": false,
- "platform": {
- "php": "^7",
- "composer-plugin-api": "^1.1.0 || ^2.0"
- },
- "platform-dev": {
- "ext-zip": "^1.13"
- },
- "plugin-api-version": "1.1.0"
-}
diff --git a/composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php b/composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php
deleted file mode 100644
index 18e5fe64..00000000
--- a/composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php
+++ /dev/null
@@ -1,128 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace PackageVersions;
-
-use Generator;
-use OutOfBoundsException;
-use UnexpectedValueException;
-use function array_key_exists;
-use function array_merge;
-use function basename;
-use function file_exists;
-use function file_get_contents;
-use function getcwd;
-use function iterator_to_array;
-use function json_decode;
-use function json_encode;
-use function sprintf;
-
-/**
- * @internal
- *
- * This is a fallback for {@see \PackageVersions\Versions::getVersion()}
- * Do not use this class directly: it is intended to be only used when
- * {@see \PackageVersions\Versions} fails to be generated, which typically
- * happens when running composer with `--no-scripts` flag)
- */
-final class FallbackVersions
-{
- const ROOT_PACKAGE_NAME = 'unknown/root-package@UNKNOWN';
-
- private function __construct()
- {
- }
-
- /**
- * @throws OutOfBoundsException If a version cannot be located.
- * @throws UnexpectedValueException If the composer.lock file could not be located.
- */
- public static function getVersion(string $packageName): string
- {
- $versions = iterator_to_array(self::getVersions(self::getPackageData()));
-
- if (! array_key_exists($packageName, $versions)) {
- throw new OutOfBoundsException(
- 'Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files'
- );
- }
-
- return $versions[$packageName];
- }
-
- /**
- * @return mixed[]
- *
- * @throws UnexpectedValueException
- */
- private static function getPackageData(): array
- {
- $checkedPaths = [
- // The top-level project's ./vendor/composer/installed.json
- getcwd() . '/vendor/composer/installed.json',
- __DIR__ . '/../../../../composer/installed.json',
- // The top-level project's ./composer.lock
- getcwd() . '/composer.lock',
- __DIR__ . '/../../../../../composer.lock',
- // This package's composer.lock
- __DIR__ . '/../../composer.lock',
- ];
-
- $packageData = [];
- foreach ($checkedPaths as $path) {
- if (! file_exists($path)) {
- continue;
- }
-
- $data = json_decode(file_get_contents($path), true);
- switch (basename($path)) {
- case 'installed.json':
- // composer 2.x installed.json format
- if (isset($data['packages'])) {
- $packageData[] = $data['packages'];
- } else {
- // composer 1.x installed.json format
- $packageData[] = $data;
- }
-
- break;
- case 'composer.lock':
- $packageData[] = $data['packages'] + ($data['packages-dev'] ?? []);
- break;
- default:
- // intentionally left blank
- }
- }
-
- if ($packageData !== []) {
- return array_merge(...$packageData);
- }
-
- throw new UnexpectedValueException(sprintf(
- 'PackageVersions could not locate the `vendor/composer/installed.json` or your `composer.lock` '
- . 'location. This is assumed to be in %s. If you customized your composer vendor directory and ran composer '
- . 'installation with --no-scripts, or if you deployed without the required composer files, PackageVersions '
- . 'can\'t detect installed versions.',
- json_encode($checkedPaths)
- ));
- }
-
- /**
- * @param mixed[] $packageData
- *
- * @return Generator&string[]
- *
- * @psalm-return Generator<string, string>
- */
- private static function getVersions(array $packageData): Generator
- {
- foreach ($packageData as $package) {
- yield $package['name'] => $package['version'] . '@' . (
- $package['source']['reference'] ?? $package['dist']['reference'] ?? ''
- );
- }
-
- yield self::ROOT_PACKAGE_NAME => self::ROOT_PACKAGE_NAME;
- }
-}
diff --git a/composer/package-versions-deprecated/src/PackageVersions/Installer.php b/composer/package-versions-deprecated/src/PackageVersions/Installer.php
deleted file mode 100644
index 05bdac9a..00000000
--- a/composer/package-versions-deprecated/src/PackageVersions/Installer.php
+++ /dev/null
@@ -1,290 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace PackageVersions;
-
-use Composer\Composer;
-use Composer\Config;
-use Composer\EventDispatcher\EventSubscriberInterface;
-use Composer\IO\IOInterface;
-use Composer\Package\AliasPackage;
-use Composer\Package\Locker;
-use Composer\Package\PackageInterface;
-use Composer\Package\RootPackageInterface;
-use Composer\Plugin\PluginInterface;
-use Composer\Script\Event;
-use Composer\Script\ScriptEvents;
-use Generator;
-use RuntimeException;
-
-use function array_key_exists;
-use function array_merge;
-use function chmod;
-use function dirname;
-use function file_exists;
-use function file_put_contents;
-use function is_writable;
-use function iterator_to_array;
-use function rename;
-use function sprintf;
-use function uniqid;
-use function var_export;
-
-final class Installer implements PluginInterface, EventSubscriberInterface
-{
- private static $generatedClassTemplate = <<<'PHP'
-<?php
-
-declare(strict_types=1);
-
-namespace PackageVersions;
-
-use Composer\InstalledVersions;
-use OutOfBoundsException;
-
-class_exists(InstalledVersions::class);
-
-/**
- * This class is generated by composer/package-versions-deprecated, specifically by
- * @see \PackageVersions\Installer
- *
- * This file is overwritten at every run of `composer install` or `composer update`.
- *
- * @deprecated in favor of the Composer\InstalledVersions class provided by Composer 2. Require composer-runtime-api:^2 to ensure it is present.
- */
-%s
-{
- /**
- * @deprecated please use {@see self::rootPackageName()} instead.
- * This constant will be removed in version 2.0.0.
- */
- const ROOT_PACKAGE_NAME = '%s';
-
- /**
- * Array of all available composer packages.
- * Dont read this array from your calling code, but use the \PackageVersions\Versions::getVersion() method instead.
- *
- * @var array<string, string>
- * @internal
- */
- const VERSIONS = %s;
-
- private function __construct()
- {
- }
-
- /**
- * @psalm-pure
- *
- * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
- * cause any side effects here.
- */
- public static function rootPackageName() : string
- {
- if (!self::composer2ApiUsable()) {
- return self::ROOT_PACKAGE_NAME;
- }
-
- return InstalledVersions::getRootPackage()['name'];
- }
-
- /**
- * @throws OutOfBoundsException If a version cannot be located.
- *
- * @psalm-param key-of<self::VERSIONS> $packageName
- * @psalm-pure
- *
- * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
- * cause any side effects here.
- */
- public static function getVersion(string $packageName): string
- {
- if (self::composer2ApiUsable()) {
- return InstalledVersions::getPrettyVersion($packageName)
- . '@' . InstalledVersions::getReference($packageName);
- }
-
- if (isset(self::VERSIONS[$packageName])) {
- return self::VERSIONS[$packageName];
- }
-
- throw new OutOfBoundsException(
- '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;
-
- public function activate(Composer $composer, IOInterface $io)
- {
- // Nothing to do here, as all features are provided through event listeners
- }
-
- public function deactivate(Composer $composer, IOInterface $io)
- {
- // Nothing to do here, as all features are provided through event listeners
- }
-
- public function uninstall(Composer $composer, IOInterface $io)
- {
- // Nothing to do here, as all features are provided through event listeners
- }
-
- /**
- * {@inheritDoc}
- */
- public static function getSubscribedEvents(): array
- {
- return [ScriptEvents::POST_AUTOLOAD_DUMP => 'dumpVersionsClass'];
- }
-
- /**
- * @throws RuntimeException
- */
- public static function dumpVersionsClass(Event $composerEvent)
- {
- $composer = $composerEvent->getComposer();
- $rootPackage = $composer->getPackage();
- $versions = iterator_to_array(self::getVersions($composer->getLocker(), $rootPackage));
-
- if (! array_key_exists('composer/package-versions-deprecated', $versions)) {
- //plugin must be globally installed - we only want to generate versions for projects which specifically
- //require composer/package-versions-deprecated
- return;
- }
-
- $versionClass = self::generateVersionsClass($rootPackage->getName(), $versions);
-
- self::writeVersionClassToFile($versionClass, $composer, $composerEvent->getIO());
- }
-
- /**
- * @param string[] $versions
- */
- private static function generateVersionsClass(string $rootPackageName, array $versions): string
- {
- return sprintf(
- self::$generatedClassTemplate,
- 'fin' . 'al ' . 'cla' . 'ss ' . 'Versions', // note: workaround for regex-based code parsers :-(
- $rootPackageName,
- var_export($versions, true)
- );
- }
-
- /**
- * @throws RuntimeException
- */
- private static function writeVersionClassToFile(string $versionClassSource, Composer $composer, IOInterface $io)
- {
- $installPath = self::locateRootPackageInstallPath($composer->getConfig(), $composer->getPackage())
- . '/src/PackageVersions/Versions.php';
-
- $installDir = dirname($installPath);
- if (! file_exists($installDir)) {
- $io->write('<info>composer/package-versions-deprecated:</info> Package not found (probably scheduled for removal); generation of version class skipped.');
-
- return;
- }
-
- if (! is_writable($installDir)) {
- $io->write(
- sprintf(
- '<info>composer/package-versions-deprecated:</info> %s is not writable; generation of version class skipped.',
- $installDir
- )
- );
-
- return;
- }
-
- $io->write('<info>composer/package-versions-deprecated:</info> Generating version class...');
-
- $installPathTmp = $installPath . '_' . uniqid('tmp', true);
- file_put_contents($installPathTmp, $versionClassSource);
- chmod($installPathTmp, 0664);
- rename($installPathTmp, $installPath);
-
- $io->write('<info>composer/package-versions-deprecated:</info> ...done generating version class');
- }
-
- /**
- * @throws RuntimeException
- */
- private static function locateRootPackageInstallPath(
- Config $composerConfig,
- RootPackageInterface $rootPackage
- ): string {
- if (self::getRootPackageAlias($rootPackage)->getName() === 'composer/package-versions-deprecated') {
- return dirname($composerConfig->get('vendor-dir'));
- }
-
- return $composerConfig->get('vendor-dir') . '/composer/package-versions-deprecated';
- }
-
- private static function getRootPackageAlias(RootPackageInterface $rootPackage): PackageInterface
- {
- $package = $rootPackage;
-
- while ($package instanceof AliasPackage) {
- $package = $package->getAliasOf();
- }
-
- return $package;
- }
-
- /**
- * @return Generator&string[]
- *
- * @psalm-return Generator<string, string>
- */
- private static function getVersions(Locker $locker, RootPackageInterface $rootPackage): Generator
- {
- $lockData = $locker->getLockData();
-
- $lockData['packages-dev'] = $lockData['packages-dev'] ?? [];
-
- $packages = $lockData['packages'];
- if (getenv('COMPOSER_DEV_MODE') !== '0') {
- $packages = array_merge($packages, $lockData['packages-dev']);
- }
- foreach ($packages as $package) {
- yield $package['name'] => $package['version'] . '@' . (
- $package['source']['reference'] ?? $package['dist']['reference'] ?? ''
- );
- }
-
- foreach ($rootPackage->getReplaces() as $replace) {
- $version = $replace->getPrettyConstraint();
- if ($version === 'self.version') {
- $version = $rootPackage->getPrettyVersion();
- }
-
- yield $replace->getTarget() => $version . '@' . $rootPackage->getSourceReference();
- }
-
- yield $rootPackage->getName() => $rootPackage->getPrettyVersion() . '@' . $rootPackage->getSourceReference();
- }
-}
diff --git a/composer/package-versions-deprecated/src/PackageVersions/Versions.php b/composer/package-versions-deprecated/src/PackageVersions/Versions.php
deleted file mode 100644
index 9cbf1877..00000000
--- a/composer/package-versions-deprecated/src/PackageVersions/Versions.php
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace PackageVersions;
-
-use Composer\InstalledVersions;
-use OutOfBoundsException;
-use UnexpectedValueException;
-
-class_exists(InstalledVersions::class);
-
-/**
- * This is a stub class: it is in place only for scenarios where PackageVersions
- * is installed with a `--no-scripts` flag, in which scenarios the Versions class
- * is not being replaced.
- *
- * If you are reading this docBlock inside your `vendor/` dir, then this means
- * that PackageVersions didn't correctly install, and is in "fallback" mode.
- */
-final class Versions
-{
- /**
- * @deprecated please use {@see self::rootPackageName()} instead.
- * This constant will be removed in version 2.0.0.
- */
- const ROOT_PACKAGE_NAME = 'unknown/root-package@UNKNOWN';
-
- /** @internal */
- const VERSIONS = [];
-
- private function __construct()
- {
- }
-
- /**
- * @psalm-pure
- *
- * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
- * cause any side effects here.
- */
- public static function rootPackageName() : string
- {
- if (!class_exists(InstalledVersions::class, false) || !InstalledVersions::getRawData()) {
- return self::ROOT_PACKAGE_NAME;
- }
-
- return InstalledVersions::getRootPackage()['name'];
- }
-
- /**
- * @throws OutOfBoundsException if a version cannot be located.
- * @throws UnexpectedValueException if the composer.lock file could not be located.
- */
- public static function getVersion(string $packageName): string
- {
- if (!self::composer2ApiUsable()) {
- return FallbackVersions::getVersion($packageName);
- }
-
- /** @psalm-suppress DeprecatedConstant */
- if ($packageName === self::ROOT_PACKAGE_NAME) {
- $rootPackage = InstalledVersions::getRootPackage();
-
- return $rootPackage['pretty_version'] . '@' . $rootPackage['reference'];
- }
-
- return InstalledVersions::getPrettyVersion($packageName)
- . '@' . InstalledVersions::getReference($packageName);
- }
-
- 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
index a33be230..6c5ddb55 100644
--- a/doctrine/cache/UPGRADE-1.11.md
+++ b/doctrine/cache/UPGRADE-1.11.md
@@ -13,3 +13,15 @@ There are two new classes to use in the `Doctrine\Common\Cache\Psr6` namespace:
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.
+
+A full example to setup a filesystem based PSR-6 cache with symfony/cache
+using the `DoctrineProvider` to convert back to Doctrine's `Cache` interface:
+
+```php
+use Doctrine\Common\Cache\Psr6\DoctrineProvider;
+use Symfony\Component\Cache\Adapter\FilesystemAdapter;
+
+$cachePool = new FilesystemAdapter();
+$cache = DoctrineProvider::wrap($cachePool);
+// $cache instanceof \Doctrine\Common\Cache\Cache
+```
diff --git a/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php
index c15497e5..3b0f416c 100644
--- a/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php
+++ b/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php
@@ -15,6 +15,7 @@ use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Cache\CacheProvider;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\DoctrineAdapter as SymfonyDoctrineAdapter;
+use Symfony\Contracts\Service\ResetInterface;
use function rawurlencode;
@@ -57,6 +58,15 @@ final class DoctrineProvider extends CacheProvider
return $this->pool;
}
+ public function reset(): void
+ {
+ if ($this->pool instanceof ResetInterface) {
+ $this->pool->reset();
+ }
+
+ $this->setNamespace($this->getNamespace());
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/doctrine/dbal/README.md b/doctrine/dbal/README.md
index 8a175788..21888b6f 100644
--- a/doctrine/dbal/README.md
+++ b/doctrine/dbal/README.md
@@ -1,11 +1,11 @@
# Doctrine DBAL
-| [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 |
+| [4.0-dev][4.0] | [3.3][3.3] |
+|:-----------------------------------------------:|:---------------------------------------------------:|
+| [![GitHub Actions][GA 4.0 image]][GA 4.0] | [![GitHub Actions][GA 3.3 image]][GA 3.3] |
+| [![AppVeyor][AppVeyor 4.0 image]][AppVeyor 4.0] | [![AppVeyor][AppVeyor 3.3 image]][AppVeyor 3.3] |
+| [![Code Coverage][Coverage image]][CodeCov 4.0] | [![Code Coverage][Coverage 3.3 image]][CodeCov 3.3] |
+| N/A | [![Code Coverage][TypeCov 3.3 image]][TypeCov 3.3] |
Powerful ***D***ata***B***ase ***A***bstraction ***L***ayer with many features for database schema introspection and schema management.
@@ -23,20 +23,12 @@ Powerful ***D***ata***B***ase ***A***bstraction ***L***ayer with many features f
[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
- [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
+ [Coverage 3.3 image]: https://codecov.io/gh/doctrine/dbal/branch/3.3.x/graph/badge.svg
+ [3.3]: https://github.com/doctrine/dbal/tree/3.3.x
+ [CodeCov 3.3]: https://codecov.io/gh/doctrine/dbal/branch/3.3.x
+ [AppVeyor 3.3]: https://ci.appveyor.com/project/doctrine/dbal/branch/3.3.x
+ [AppVeyor 3.3 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/3.3.x?svg=true
+ [GA 3.3]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A3.3.x
+ [GA 3.3 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=3.3.x
+ [TypeCov 3.3]: https://shepherd.dev/github/doctrine/dbal
+ [TypeCov 3.3 image]: https://shepherd.dev/github/doctrine/dbal/coverage.svg
diff --git a/doctrine/dbal/composer.json b/doctrine/dbal/composer.json
index 2374d79c..b0805793 100644
--- a/doctrine/dbal/composer.json
+++ b/doctrine/dbal/composer.json
@@ -32,29 +32,35 @@
],
"require": {
"php": "^7.3 || ^8.0",
- "composer/package-versions-deprecated": "^1.11.99",
- "doctrine/cache": "^1.0|^2.0",
- "doctrine/deprecations": "^0.5.3",
- "doctrine/event-manager": "^1.0"
+ "composer-runtime-api": "^2",
+ "doctrine/cache": "^1.11|^2.0",
+ "doctrine/deprecations": "^0.5.3|^1",
+ "doctrine/event-manager": "^1.0",
+ "psr/cache": "^1|^2|^3",
+ "psr/log": "^1|^2|^3"
},
"require-dev": {
"doctrine/coding-standard": "9.0.0",
- "jetbrains/phpstorm-stubs": "2021.1",
- "phpstan/phpstan": "1.1.1",
- "phpstan/phpstan-strict-rules": "^1",
- "phpunit/phpunit": "9.5.10",
+ "jetbrains/phpstorm-stubs": "2022.1",
+ "phpstan/phpstan": "1.7.13",
+ "phpstan/phpstan-strict-rules": "^1.2",
+ "phpunit/phpunit": "9.5.20",
"psalm/plugin-phpunit": "0.16.1",
- "squizlabs/php_codesniffer": "3.6.1",
+ "squizlabs/php_codesniffer": "3.7.0",
"symfony/cache": "^5.2|^6.0",
- "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.0",
- "vimeo/psalm": "4.12.0"
+ "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
+ "vimeo/psalm": "4.23.0"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
},
"bin": ["bin/doctrine-dbal"],
"config": {
- "sort-packages": true
+ "sort-packages": true,
+ "allow-plugins": {
+ "dealerdirect/phpcodesniffer-composer-installer": true,
+ "composer/package-versions-deprecated": true
+ }
},
"autoload": {
"psr-4": { "Doctrine\\DBAL\\": "src" }
diff --git a/doctrine/dbal/src/Cache/ArrayResult.php b/doctrine/dbal/src/Cache/ArrayResult.php
index e2dc6e11..3b70d0c9 100644
--- a/doctrine/dbal/src/Cache/ArrayResult.php
+++ b/doctrine/dbal/src/Cache/ArrayResult.php
@@ -14,7 +14,7 @@ use function reset;
*/
final class ArrayResult implements Result
{
- /** @var mixed[] */
+ /** @var list<array<string, mixed>> */
private $data;
/** @var int */
@@ -24,7 +24,7 @@ final class ArrayResult implements Result
private $num = 0;
/**
- * @param mixed[] $data
+ * @param list<array<string, mixed>> $data
*/
public function __construct(array $data)
{
@@ -112,7 +112,7 @@ final class ArrayResult implements Result
}
/**
- * @return mixed|false
+ * @return array<string, mixed>|false
*/
private function fetch()
{
diff --git a/doctrine/dbal/src/Cache/CachingResult.php b/doctrine/dbal/src/Cache/CachingResult.php
deleted file mode 100644
index c060673c..00000000
--- a/doctrine/dbal/src/Cache/CachingResult.php
+++ /dev/null
@@ -1,184 +0,0 @@
-<?php
-
-namespace Doctrine\DBAL\Cache;
-
-use Doctrine\Common\Cache\Cache;
-use Doctrine\DBAL\Driver\Exception;
-use Doctrine\DBAL\Driver\FetchUtils;
-use Doctrine\DBAL\Driver\Result as DriverResult;
-use Doctrine\DBAL\Result;
-
-use function array_map;
-use function array_values;
-
-/**
- * A result is saved in multiple cache keys, there is the originally specified
- * cache key which is just pointing to result rows by key. The following things
- * have to be ensured:
- *
- * 1. lifetime of the original key has to be longer than that of all the individual rows keys
- * 2. if any one row key is missing the query has to be re-executed.
- *
- * Also you have to realize that the cache will load the whole result into memory at once to ensure 2.
- * This means that the memory usage for cached results might increase by using this feature.
- *
- * @internal The class is internal to the caching layer implementation.
- */
-class CachingResult implements DriverResult
-{
- /** @var Cache */
- private $cache;
-
- /** @var string */
- private $cacheKey;
-
- /** @var string */
- private $realKey;
-
- /** @var int */
- private $lifetime;
-
- /** @var Result */
- private $result;
-
- /** @var array<int,array<string,mixed>>|null */
- private $data;
-
- /**
- * @param string $cacheKey
- * @param string $realKey
- * @param int $lifetime
- */
- public function __construct(Result $result, Cache $cache, $cacheKey, $realKey, $lifetime)
- {
- $this->result = $result;
- $this->cache = $cache;
- $this->cacheKey = $cacheKey;
- $this->realKey = $realKey;
- $this->lifetime = $lifetime;
- }
-
- /**
- * {@inheritdoc}
- */
- public function fetchNumeric()
- {
- $row = $this->fetch();
-
- if ($row === false) {
- return false;
- }
-
- return array_values($row);
- }
-
- /**
- * {@inheritdoc}
- */
- public function fetchAssociative()
- {
- return $this->fetch();
- }
-
- /**
- * {@inheritdoc}
- */
- public function fetchOne()
- {
- return FetchUtils::fetchOne($this);
- }
-
- /**
- * {@inheritdoc}
- */
- public function fetchAllNumeric(): array
- {
- return array_map('array_values', $this->fetchAllAssociative());
- }
-
- /**
- * {@inheritdoc}
- */
- public function fetchAllAssociative(): array
- {
- $data = $this->result->fetchAllAssociative();
-
- $this->store($data);
-
- return $data;
- }
-
- /**
- * {@inheritdoc}
- */
- public function fetchFirstColumn(): array
- {
- return FetchUtils::fetchFirstColumn($this);
- }
-
- public function rowCount(): int
- {
- return $this->result->rowCount();
- }
-
- public function columnCount(): int
- {
- return $this->result->columnCount();
- }
-
- public function free(): void
- {
- $this->data = null;
- }
-
- /**
- * @return array<string,mixed>|false
- *
- * @throws Exception
- */
- private function fetch()
- {
- if ($this->data === null) {
- $this->data = [];
- }
-
- $row = $this->result->fetchAssociative();
-
- if ($row !== false) {
- $this->data[] = $row;
-
- return $row;
- }
-
- $this->saveToCache();
-
- return false;
- }
-
- /**
- * @param array<int,array<string,mixed>> $data
- */
- private function store(array $data): void
- {
- $this->data = $data;
-
- $this->saveToCache();
- }
-
- private function saveToCache(): void
- {
- if ($this->data === null) {
- return;
- }
-
- $data = $this->cache->fetch($this->cacheKey);
-
- if ($data === false) {
- $data = [];
- }
-
- $data[$this->realKey] = $this->data;
-
- $this->cache->save($this->cacheKey, $data, $this->lifetime);
- }
-}
diff --git a/doctrine/dbal/src/Cache/QueryCacheProfile.php b/doctrine/dbal/src/Cache/QueryCacheProfile.php
index 21bd144d..7115cc72 100644
--- a/doctrine/dbal/src/Cache/QueryCacheProfile.php
+++ b/doctrine/dbal/src/Cache/QueryCacheProfile.php
@@ -3,11 +3,18 @@
namespace Doctrine\DBAL\Cache;
use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Cache\Psr6\CacheAdapter;
+use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\DBAL\Types\Type;
+use Doctrine\Deprecations\Deprecation;
+use Psr\Cache\CacheItemPoolInterface;
+use TypeError;
+use function get_class;
use function hash;
use function serialize;
use function sha1;
+use function sprintf;
/**
* Query Cache Profile handles the data relevant for query caching.
@@ -16,8 +23,8 @@ use function sha1;
*/
class QueryCacheProfile
{
- /** @var Cache|null */
- private $resultCacheDriver;
+ /** @var CacheItemPoolInterface|null */
+ private $resultCache;
/** @var int */
private $lifetime;
@@ -26,22 +33,57 @@ class QueryCacheProfile
private $cacheKey;
/**
- * @param int $lifetime
- * @param string|null $cacheKey
+ * @param int $lifetime
+ * @param string|null $cacheKey
+ * @param CacheItemPoolInterface|Cache|null $resultCache
*/
- public function __construct($lifetime = 0, $cacheKey = null, ?Cache $resultCache = null)
+ public function __construct($lifetime = 0, $cacheKey = null, ?object $resultCache = null)
+ {
+ $this->lifetime = $lifetime;
+ $this->cacheKey = $cacheKey;
+ if ($resultCache instanceof CacheItemPoolInterface) {
+ $this->resultCache = $resultCache;
+ } elseif ($resultCache instanceof Cache) {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4620',
+ 'Passing an instance of %s to %s as $resultCache is deprecated. Pass an instance of %s instead.',
+ Cache::class,
+ __METHOD__,
+ CacheItemPoolInterface::class
+ );
+
+ $this->resultCache = CacheAdapter::wrap($resultCache);
+ } elseif ($resultCache !== null) {
+ throw new TypeError(sprintf(
+ '$resultCache: Expected either null or an instance of %s or %s, got %s.',
+ CacheItemPoolInterface::class,
+ Cache::class,
+ get_class($resultCache)
+ ));
+ }
+ }
+
+ public function getResultCache(): ?CacheItemPoolInterface
{
- $this->lifetime = $lifetime;
- $this->cacheKey = $cacheKey;
- $this->resultCacheDriver = $resultCache;
+ return $this->resultCache;
}
/**
+ * @deprecated Use {@see getResultCache()} instead.
+ *
* @return Cache|null
*/
public function getResultCacheDriver()
{
- return $this->resultCacheDriver;
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4620',
+ '%s is deprecated, call getResultCache() instead.',
+ __METHOD__
+ );
+
+ return $this->resultCache !== null ? DoctrineProvider::wrap($this->resultCache) : null;
}
/**
@@ -97,12 +139,26 @@ class QueryCacheProfile
return [$cacheKey, $realCacheKey];
}
+ public function setResultCache(CacheItemPoolInterface $cache): QueryCacheProfile
+ {
+ return new QueryCacheProfile($this->lifetime, $this->cacheKey, $cache);
+ }
+
/**
+ * @deprecated Use {@see setResultCache()} instead.
+ *
* @return QueryCacheProfile
*/
public function setResultCacheDriver(Cache $cache)
{
- return new QueryCacheProfile($this->lifetime, $this->cacheKey, $cache);
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4620',
+ '%s is deprecated, call setResultCache() instead.',
+ __METHOD__
+ );
+
+ return new QueryCacheProfile($this->lifetime, $this->cacheKey, CacheAdapter::wrap($cache));
}
/**
@@ -112,7 +168,7 @@ class QueryCacheProfile
*/
public function setCacheKey($cacheKey)
{
- return new QueryCacheProfile($this->lifetime, $cacheKey, $this->resultCacheDriver);
+ return new QueryCacheProfile($this->lifetime, $cacheKey, $this->resultCache);
}
/**
@@ -122,6 +178,6 @@ class QueryCacheProfile
*/
public function setLifetime($lifetime)
{
- return new QueryCacheProfile($lifetime, $this->cacheKey, $this->resultCacheDriver);
+ return new QueryCacheProfile($lifetime, $this->cacheKey, $this->resultCache);
}
}
diff --git a/doctrine/dbal/src/Configuration.php b/doctrine/dbal/src/Configuration.php
index 109289f5..2d27d733 100644
--- a/doctrine/dbal/src/Configuration.php
+++ b/doctrine/dbal/src/Configuration.php
@@ -3,8 +3,12 @@
namespace Doctrine\DBAL;
use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Cache\Psr6\CacheAdapter;
+use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\DBAL\Driver\Middleware;
use Doctrine\DBAL\Logging\SQLLogger;
+use Doctrine\Deprecations\Deprecation;
+use Psr\Cache\CacheItemPoolInterface;
/**
* Configuration container for the Doctrine DBAL.
@@ -24,6 +28,15 @@ class Configuration
/**
* The cache driver implementation that is used for query result caching.
*
+ * @var CacheItemPoolInterface|null
+ */
+ private $resultCache;
+
+ /**
+ * The cache driver implementation that is used for query result caching.
+ *
+ * @deprecated Use {@see $resultCache} instead.
+ *
* @var Cache|null
*/
protected $resultCacheImpl;
@@ -61,17 +74,53 @@ class Configuration
/**
* Gets the cache driver implementation that is used for query result caching.
*/
+ public function getResultCache(): ?CacheItemPoolInterface
+ {
+ return $this->resultCache;
+ }
+
+ /**
+ * Gets the cache driver implementation that is used for query result caching.
+ *
+ * @deprecated Use {@see getResultCache()} instead.
+ */
public function getResultCacheImpl(): ?Cache
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4620',
+ '%s is deprecated, call getResultCache() instead.',
+ __METHOD__
+ );
+
return $this->resultCacheImpl;
}
/**
* Sets the cache driver implementation that is used for query result caching.
*/
+ public function setResultCache(CacheItemPoolInterface $cache): void
+ {
+ $this->resultCacheImpl = DoctrineProvider::wrap($cache);
+ $this->resultCache = $cache;
+ }
+
+ /**
+ * Sets the cache driver implementation that is used for query result caching.
+ *
+ * @deprecated Use {@see setResultCache()} instead.
+ */
public function setResultCacheImpl(Cache $cacheImpl): void
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4620',
+ '%s is deprecated, call setResultCache() instead.',
+ __METHOD__
+ );
+
$this->resultCacheImpl = $cacheImpl;
+ $this->resultCache = CacheAdapter::wrap($cacheImpl);
}
/**
diff --git a/doctrine/dbal/src/Connection.php b/doctrine/dbal/src/Connection.php
index 7b3686c6..9e4b1d23 100644
--- a/doctrine/dbal/src/Connection.php
+++ b/doctrine/dbal/src/Connection.php
@@ -6,12 +6,14 @@ use Closure;
use Doctrine\Common\EventManager;
use Doctrine\DBAL\Cache\ArrayResult;
use Doctrine\DBAL\Cache\CacheException;
-use Doctrine\DBAL\Cache\CachingResult;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Driver\API\ExceptionConverter;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
+use Doctrine\DBAL\Event\TransactionBeginEventArgs;
+use Doctrine\DBAL\Event\TransactionCommitEventArgs;
+use Doctrine\DBAL\Event\TransactionRollBackEventArgs;
use Doctrine\DBAL\Exception\ConnectionLost;
use Doctrine\DBAL\Exception\DriverException;
use Doctrine\DBAL\Exception\InvalidArgumentException;
@@ -22,22 +24,26 @@ use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\SQL\Parser;
use Doctrine\DBAL\Types\Type;
use Doctrine\Deprecations\Deprecation;
+use LogicException;
use Throwable;
use Traversable;
-use function array_key_exists;
use function assert;
use function count;
+use function get_class;
use function implode;
use function is_int;
use function is_string;
use function key;
+use function method_exists;
+use function sprintf;
/**
* 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
+ * @psalm-consistent-constructor
*/
class Connection
{
@@ -52,6 +58,11 @@ class Connection
public const PARAM_STR_ARRAY = ParameterType::STRING + self::ARRAY_PARAM_OFFSET;
/**
+ * Represents an array of ascii strings to be expanded by Doctrine SQL parsing.
+ */
+ public const PARAM_ASCII_STR_ARRAY = ParameterType::ASCII + self::ARRAY_PARAM_OFFSET;
+
+ /**
* Offset by which PARAM_* constants are detected as arrays of the param type.
*/
public const ARRAY_PARAM_OFFSET = 100;
@@ -70,7 +81,7 @@ class Connection
protected $_eventManager;
/**
- * @deprecated Use {@link createExpressionBuilder()} instead.
+ * @deprecated Use {@see createExpressionBuilder()} instead.
*
* @var ExpressionBuilder
*/
@@ -108,7 +119,6 @@ class Connection
* The parameters used during creation of the Connection instance.
*
* @var array<string,mixed>
- * @phpstan-var array<string,mixed>
* @psalm-var Params
*/
private $params;
@@ -129,7 +139,7 @@ class Connection
/**
* The schema manager.
*
- * @deprecated Use {@link createSchemaManager()} instead.
+ * @deprecated Use {@see createSchemaManager()} instead.
*
* @var AbstractSchemaManager|null
*/
@@ -172,14 +182,6 @@ class Connection
$this->_driver = $driver;
$this->params = $params;
- if (isset($params['platform'])) {
- if (! $params['platform'] instanceof Platforms\AbstractPlatform) {
- throw Exception::invalidPlatformType($params['platform']);
- }
-
- $this->platform = $params['platform'];
- }
-
// Create default config and event manager if none given
if ($config === null) {
$config = new Configuration();
@@ -192,6 +194,15 @@ class Connection
$this->_config = $config;
$this->_eventManager = $eventManager;
+ if (isset($params['platform'])) {
+ if (! $params['platform'] instanceof Platforms\AbstractPlatform) {
+ throw Exception::invalidPlatformType($params['platform']);
+ }
+
+ $this->platform = $params['platform'];
+ $this->platform->setEventManager($this->_eventManager);
+ }
+
$this->_expr = $this->createExpressionBuilder();
$this->autoCommit = $config->getAutoCommit();
@@ -204,7 +215,6 @@ class Connection
*
* @return array<string,mixed>
* @psalm-return Params
- * @phpstan-return array<string,mixed>
*/
public function getParams()
{
@@ -289,7 +299,7 @@ class Connection
/**
* Gets the ExpressionBuilder for the connection.
*
- * @deprecated Use {@link createExpressionBuilder()} instead.
+ * @deprecated Use {@see createExpressionBuilder()} instead.
*
* @return ExpressionBuilder
*/
@@ -308,6 +318,8 @@ class Connection
/**
* Establishes the connection with the database.
*
+ * @internal This method will be made protected in DBAL 4.0.
+ *
* @return bool TRUE if the connection was successfully established, FALSE if
* the connection is already open.
*
@@ -315,6 +327,12 @@ class Connection
*/
public function connect()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4966',
+ 'Public access to Connection::connect() is deprecated.'
+ );
+
if ($this->_conn !== null) {
return false;
}
@@ -438,6 +456,13 @@ class Connection
}
}
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4750',
+ 'Not implementing the ServerInfoAwareConnection interface in %s is deprecated',
+ get_class($connection)
+ );
+
// Unable to detect platform version.
return null;
}
@@ -503,11 +528,7 @@ class Connection
*/
public function fetchAssociative(string $query, array $params = [], array $types = [])
{
- try {
- return $this->executeQuery($query, $params, $types)->fetchAssociative();
- } catch (Driver\Exception $e) {
- throw $this->convertExceptionDuringQuery($e, $query, $params, $types);
- }
+ return $this->executeQuery($query, $params, $types)->fetchAssociative();
}
/**
@@ -518,17 +539,13 @@ class Connection
* @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 list< mixed>|false False is returned if no rows are found.
+ * @return list<mixed>|false False is returned if no rows are found.
*
* @throws Exception
*/
public function fetchNumeric(string $query, array $params = [], array $types = [])
{
- try {
- return $this->executeQuery($query, $params, $types)->fetchNumeric();
- } catch (Driver\Exception $e) {
- throw $this->convertExceptionDuringQuery($e, $query, $params, $types);
- }
+ return $this->executeQuery($query, $params, $types)->fetchNumeric();
}
/**
@@ -545,11 +562,7 @@ class Connection
*/
public function fetchOne(string $query, array $params = [], array $types = [])
{
- try {
- return $this->executeQuery($query, $params, $types)->fetchOne();
- } catch (Driver\Exception $e) {
- throw $this->convertExceptionDuringQuery($e, $query, $params, $types);
- }
+ return $this->executeQuery($query, $params, $types)->fetchOne();
}
/**
@@ -611,7 +624,7 @@ class Connection
* @param array<string, mixed> $criteria Deletion criteria
* @param array<int, int|string|Type|null>|array<string, int|string|Type|null> $types Parameter types
*
- * @return int The number of affected rows.
+ * @return int|string The number of affected rows.
*
* @throws Exception
*/
@@ -648,7 +661,7 @@ class Connection
*
* @param int $level The level to set.
*
- * @return int
+ * @return int|string
*
* @throws Exception
*/
@@ -685,7 +698,7 @@ class Connection
* @param array<string, mixed> $criteria Update criteria
* @param array<int, int|string|Type|null>|array<string, int|string|Type|null> $types Parameter types
*
- * @return int The number of affected rows.
+ * @return int|string The number of affected rows.
*
* @throws Exception
*/
@@ -720,7 +733,7 @@ class Connection
* @param array<string, mixed> $data Column-value pairs
* @param array<int, int|string|Type|null>|array<string, int|string|Type|null> $types Parameter types
*
- * @return int The number of affected rows.
+ * @return int|string The number of affected rows.
*
* @throws Exception
*/
@@ -756,7 +769,7 @@ class Connection
*
* @return array<int, int|string|Type|null>|array<string, int|string|Type|null>
*/
- private function extractTypeValues(array $columnList, array $types)
+ private function extractTypeValues(array $columnList, array $types): array
{
$typeValues = [];
@@ -787,6 +800,9 @@ class Connection
}
/**
+ * The usage of this method is discouraged. Use prepared statements
+ * or {@see AbstractPlatform::quoteStringLiteral()} instead.
+ *
* @param mixed $value
* @param int|string|Type|null $type
*
@@ -814,11 +830,7 @@ class Connection
*/
public function fetchAllNumeric(string $query, array $params = [], array $types = []): array
{
- try {
- return $this->executeQuery($query, $params, $types)->fetchAllNumeric();
- } catch (Driver\Exception $e) {
- throw $this->convertExceptionDuringQuery($e, $query, $params, $types);
- }
+ return $this->executeQuery($query, $params, $types)->fetchAllNumeric();
}
/**
@@ -834,11 +846,7 @@ class Connection
*/
public function fetchAllAssociative(string $query, array $params = [], array $types = []): array
{
- try {
- return $this->executeQuery($query, $params, $types)->fetchAllAssociative();
- } catch (Driver\Exception $e) {
- throw $this->convertExceptionDuringQuery($e, $query, $params, $types);
- }
+ return $this->executeQuery($query, $params, $types)->fetchAllAssociative();
}
/**
@@ -889,11 +897,7 @@ class Connection
*/
public function fetchFirstColumn(string $query, array $params = [], array $types = []): array
{
- try {
- return $this->executeQuery($query, $params, $types)->fetchFirstColumn();
- } catch (Driver\Exception $e) {
- throw $this->convertExceptionDuringQuery($e, $query, $params, $types);
- }
+ return $this->executeQuery($query, $params, $types)->fetchFirstColumn();
}
/**
@@ -909,15 +913,7 @@ class Connection
*/
public function iterateNumeric(string $query, array $params = [], array $types = []): Traversable
{
- try {
- $result = $this->executeQuery($query, $params, $types);
-
- while (($row = $result->fetchNumeric()) !== false) {
- yield $row;
- }
- } catch (Driver\Exception $e) {
- throw $this->convertExceptionDuringQuery($e, $query, $params, $types);
- }
+ return $this->executeQuery($query, $params, $types)->iterateNumeric();
}
/**
@@ -934,15 +930,7 @@ class Connection
*/
public function iterateAssociative(string $query, array $params = [], array $types = []): Traversable
{
- try {
- $result = $this->executeQuery($query, $params, $types);
-
- while (($row = $result->fetchAssociative()) !== false) {
- yield $row;
- }
- } catch (Driver\Exception $e) {
- throw $this->convertExceptionDuringQuery($e, $query, $params, $types);
- }
+ return $this->executeQuery($query, $params, $types)->iterateAssociative();
}
/**
@@ -993,15 +981,7 @@ class Connection
*/
public function iterateColumn(string $query, array $params = [], array $types = []): Traversable
{
- try {
- $result = $this->executeQuery($query, $params, $types);
-
- while (($value = $result->fetchOne()) !== false) {
- yield $value;
- }
- } catch (Driver\Exception $e) {
- throw $this->convertExceptionDuringQuery($e, $query, $params, $types);
- }
+ return $this->executeQuery($query, $params, $types)->iterateColumn();
}
/**
@@ -1013,7 +993,15 @@ class Connection
*/
public function prepare(string $sql): Statement
{
- return new Statement($sql, $this);
+ $connection = $this->getWrappedConnection();
+
+ try {
+ $statement = $connection->prepare($sql);
+ } catch (Driver\Exception $e) {
+ throw $this->convertExceptionDuringQuery($e, $sql);
+ }
+
+ return new Statement($this, $statement, $sql);
}
/**
@@ -1084,7 +1072,7 @@ class Connection
*/
public function executeCacheQuery($sql, $params, $types, QueryCacheProfile $qcp): Result
{
- $resultCache = $qcp->getResultCacheDriver() ?? $this->_config->getResultCacheImpl();
+ $resultCache = $qcp->getResultCache() ?? $this->_config->getResultCache();
if ($resultCache === null) {
throw CacheException::noResultDriverConfigured();
@@ -1095,29 +1083,31 @@ class Connection
[$cacheKey, $realKey] = $qcp->generateCacheKeys($sql, $params, $types, $connectionParams);
- // fetch the row pointers entry
- $data = $resultCache->fetch($cacheKey);
+ $item = $resultCache->getItem($cacheKey);
- if ($data !== false) {
- // is the real key part of this row pointers map or is the cache only pointing to other cache keys?
- if (isset($data[$realKey])) {
- $result = new ArrayResult($data[$realKey]);
- } elseif (array_key_exists($realKey, $data)) {
- $result = new ArrayResult([]);
+ if ($item->isHit()) {
+ $value = $item->get();
+ if (isset($value[$realKey])) {
+ return new Result(new ArrayResult($value[$realKey]), $this);
}
+ } else {
+ $value = [];
}
- if (! isset($result)) {
- $result = new CachingResult(
- $this->executeQuery($sql, $params, $types),
- $resultCache,
- $cacheKey,
- $realKey,
- $qcp->getLifetime()
- );
+ $data = $this->fetchAllAssociative($sql, $params, $types);
+
+ $value[$realKey] = $data;
+
+ $item->set($value);
+
+ $lifetime = $qcp->getLifetime();
+ if ($lifetime > 0) {
+ $item->expiresAfter($lifetime);
}
- return new Result($result, $this);
+ $resultCache->save($item);
+
+ return new Result(new ArrayResult($data), $this);
}
/**
@@ -1136,7 +1126,7 @@ class Connection
* @param list<mixed>|array<string, mixed> $params Statement parameters
* @param array<int, int|string|Type|null>|array<string, int|string|Type|null> $types Parameter types
*
- * @return int The number of affected rows.
+ * @return int|string The number of affected rows.
*
* @throws Exception
*/
@@ -1204,6 +1194,14 @@ class Connection
*/
public function lastInsertId($name = null)
{
+ if ($name !== null) {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4687',
+ 'The usage of Connection::lastInsertId() with a sequence name is deprecated.'
+ );
+ }
+
try {
return $this->getWrappedConnection()->lastInsertId($name);
} catch (Driver\Exception $e) {
@@ -1273,10 +1271,9 @@ class Connection
}
/**
- * Returns the savepoint name to use for nested transactions are false if they are not supported
- * "savepointFormat" parameter is not set
+ * Returns the savepoint name to use for nested transactions.
*
- * @return mixed A string with the savepoint name or false.
+ * @return string
*/
protected function _getNestedTransactionSavePointName()
{
@@ -1317,6 +1314,8 @@ class Connection
}
}
+ $this->getEventManager()->dispatchEvent(Events::onTransactionBegin, new TransactionBeginEventArgs($this));
+
return true;
}
@@ -1364,6 +1363,8 @@ class Connection
--$this->transactionNestingLevel;
+ $this->getEventManager()->dispatchEvent(Events::onTransactionCommit, new TransactionCommitEventArgs($this));
+
if ($this->autoCommit !== false || $this->transactionNestingLevel !== 0) {
return $result;
}
@@ -1440,6 +1441,8 @@ class Connection
--$this->transactionNestingLevel;
}
+ $this->getEventManager()->dispatchEvent(Events::onTransactionRollBack, new TransactionRollBackEventArgs($this));
+
return true;
}
@@ -1510,12 +1513,21 @@ class Connection
/**
* Gets the wrapped driver connection.
*
+ * @deprecated Use {@link getNativeConnection()} to access the native connection.
+ *
* @return DriverConnection
*
* @throws Exception
*/
public function getWrappedConnection()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4966',
+ 'Connection::getWrappedConnection() is deprecated.'
+ . ' Use Connection::getNativeConnection() to access the native connection.'
+ );
+
$this->connect();
assert($this->_conn !== null);
@@ -1524,6 +1536,24 @@ class Connection
}
/**
+ * @return resource|object
+ */
+ public function getNativeConnection()
+ {
+ $this->connect();
+
+ assert($this->_conn !== null);
+ if (! method_exists($this->_conn, 'getNativeConnection')) {
+ throw new LogicException(sprintf(
+ 'The driver connection %s does not support accessing the native connection.',
+ get_class($this->_conn)
+ ));
+ }
+
+ return $this->_conn->getNativeConnection();
+ }
+
+ /**
* Creates a SchemaManager that can be used to inspect or change the
* database schema through the connection.
*
@@ -1541,7 +1571,7 @@ class Connection
* Gets the SchemaManager that can be used to inspect or change the
* database schema through the connection.
*
- * @deprecated Use {@link createSchemaManager()} instead.
+ * @deprecated Use {@see createSchemaManager()} instead.
*
* @return AbstractSchemaManager
*
@@ -1761,7 +1791,11 @@ class Connection
}
foreach ($types as $type) {
- if ($type === self::PARAM_INT_ARRAY || $type === self::PARAM_STR_ARRAY) {
+ if (
+ $type === self::PARAM_INT_ARRAY
+ || $type === self::PARAM_STR_ARRAY
+ || $type === self::PARAM_ASCII_STR_ARRAY
+ ) {
return true;
}
}
diff --git a/doctrine/dbal/src/Driver/API/ExceptionConverter.php b/doctrine/dbal/src/Driver/API/ExceptionConverter.php
index b848b0e2..a7bf2713 100644
--- a/doctrine/dbal/src/Driver/API/ExceptionConverter.php
+++ b/doctrine/dbal/src/Driver/API/ExceptionConverter.php
@@ -14,12 +14,12 @@ interface ExceptionConverter
* Converts a given driver-level exception into a DBAL-level driver exception.
*
* Implementors should use the vendor-specific error code and SQLSTATE of the exception
- * and instantiate the most appropriate specialized {@link DriverException} subclass.
+ * and instantiate the most appropriate specialized {@see DriverException} subclass.
*
* @param Exception $exception The driver exception to convert.
* @param Query|null $query The SQL query that triggered the exception, if any.
*
- * @return DriverException An instance of {@link DriverException} or one of its subclasses.
+ * @return DriverException An instance of {@see DriverException} or one of its subclasses.
*/
public function convert(Exception $exception, ?Query $query): DriverException;
}
diff --git a/doctrine/dbal/src/Driver/API/IBMDB2/ExceptionConverter.php b/doctrine/dbal/src/Driver/API/IBMDB2/ExceptionConverter.php
index 20831e0f..dbde0b10 100644
--- a/doctrine/dbal/src/Driver/API/IBMDB2/ExceptionConverter.php
+++ b/doctrine/dbal/src/Driver/API/IBMDB2/ExceptionConverter.php
@@ -6,16 +6,60 @@ namespace Doctrine\DBAL\Driver\API\IBMDB2;
use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
use Doctrine\DBAL\Driver\Exception;
+use Doctrine\DBAL\Exception\ConnectionException;
use Doctrine\DBAL\Exception\DriverException;
+use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
+use Doctrine\DBAL\Exception\InvalidFieldNameException;
+use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
+use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
+use Doctrine\DBAL\Exception\SyntaxErrorException;
+use Doctrine\DBAL\Exception\TableExistsException;
+use Doctrine\DBAL\Exception\TableNotFoundException;
+use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Doctrine\DBAL\Query;
/**
* @internal
+ *
+ * @link https://www.ibm.com/docs/en/db2/11.5?topic=messages-sql
*/
final class ExceptionConverter implements ExceptionConverterInterface
{
public function convert(Exception $exception, ?Query $query): DriverException
{
+ switch ($exception->getCode()) {
+ case -104:
+ return new SyntaxErrorException($exception, $query);
+
+ case -203:
+ return new NonUniqueFieldNameException($exception, $query);
+
+ case -204:
+ return new TableNotFoundException($exception, $query);
+
+ case -206:
+ return new InvalidFieldNameException($exception, $query);
+
+ case -407:
+ return new NotNullConstraintViolationException($exception, $query);
+
+ case -530:
+ case -531:
+ case -532:
+ case -20356:
+ return new ForeignKeyConstraintViolationException($exception, $query);
+
+ case -601:
+ return new TableExistsException($exception, $query);
+
+ case -803:
+ return new UniqueConstraintViolationException($exception, $query);
+
+ case -1336:
+ case -30082:
+ return new ConnectionException($exception, $query);
+ }
+
return new DriverException($exception, $query);
}
}
diff --git a/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php b/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php
index 9abc0c16..c851949b 100644
--- a/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php
+++ b/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php
@@ -8,6 +8,7 @@ use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Exception\ConnectionException;
use Doctrine\DBAL\Exception\ConnectionLost;
+use Doctrine\DBAL\Exception\DatabaseDoesNotExist;
use Doctrine\DBAL\Exception\DeadlockException;
use Doctrine\DBAL\Exception\DriverException;
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
@@ -33,6 +34,9 @@ final class ExceptionConverter implements ExceptionConverterInterface
public function convert(Exception $exception, ?Query $query): DriverException
{
switch ($exception->getCode()) {
+ case 1008:
+ return new DatabaseDoesNotExist($exception, $query);
+
case 1213:
return new DeadlockException($exception, $query);
@@ -95,6 +99,7 @@ final class ExceptionConverter implements ExceptionConverterInterface
case 1429:
case 2002:
case 2005:
+ case 2054:
return new ConnectionException($exception, $query);
case 2006:
diff --git a/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php b/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php
index f25e58d6..727a605d 100644
--- a/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php
+++ b/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php
@@ -7,6 +7,8 @@ namespace Doctrine\DBAL\Driver\API\OCI;
use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Exception\ConnectionException;
+use Doctrine\DBAL\Exception\DatabaseDoesNotExist;
+use Doctrine\DBAL\Exception\DatabaseObjectNotFoundException;
use Doctrine\DBAL\Exception\DriverException;
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
use Doctrine\DBAL\Exception\InvalidFieldNameException;
@@ -57,6 +59,14 @@ final class ExceptionConverter implements ExceptionConverterInterface
case 1400:
return new NotNullConstraintViolationException($exception, $query);
+ case 1918:
+ return new DatabaseDoesNotExist($exception, $query);
+
+ case 2289:
+ case 2443:
+ case 4080:
+ return new DatabaseObjectNotFoundException($exception, $query);
+
case 2266:
case 2291:
case 2292:
diff --git a/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php b/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php
index b9530d0b..df34802c 100644
--- a/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php
+++ b/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php
@@ -7,12 +7,14 @@ namespace Doctrine\DBAL\Driver\API\PostgreSQL;
use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Exception\ConnectionException;
+use Doctrine\DBAL\Exception\DatabaseDoesNotExist;
use Doctrine\DBAL\Exception\DeadlockException;
use Doctrine\DBAL\Exception\DriverException;
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
use Doctrine\DBAL\Exception\InvalidFieldNameException;
use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
+use Doctrine\DBAL\Exception\SchemaDoesNotExist;
use Doctrine\DBAL\Exception\SyntaxErrorException;
use Doctrine\DBAL\Exception\TableExistsException;
use Doctrine\DBAL\Exception\TableNotFoundException;
@@ -54,6 +56,12 @@ final class ExceptionConverter implements ExceptionConverterInterface
case '23505':
return new UniqueConstraintViolationException($exception, $query);
+ case '3D000':
+ return new DatabaseDoesNotExist($exception, $query);
+
+ case '3F000':
+ return new SchemaDoesNotExist($exception, $query);
+
case '42601':
return new SyntaxErrorException($exception, $query);
diff --git a/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php b/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php
index 3fc3ff08..d0e8e9f4 100644
--- a/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php
+++ b/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php
@@ -6,16 +6,64 @@ namespace Doctrine\DBAL\Driver\API\SQLSrv;
use Doctrine\DBAL\Driver\API\ExceptionConverter as ExceptionConverterInterface;
use Doctrine\DBAL\Driver\Exception;
+use Doctrine\DBAL\Exception\ConnectionException;
+use Doctrine\DBAL\Exception\DatabaseObjectNotFoundException;
use Doctrine\DBAL\Exception\DriverException;
+use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
+use Doctrine\DBAL\Exception\InvalidFieldNameException;
+use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
+use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
+use Doctrine\DBAL\Exception\SyntaxErrorException;
+use Doctrine\DBAL\Exception\TableExistsException;
+use Doctrine\DBAL\Exception\TableNotFoundException;
+use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Doctrine\DBAL\Query;
/**
* @internal
+ *
+ * @link https://docs.microsoft.com/en-us/sql/relational-databases/errors-events/database-engine-events-and-errors
*/
final class ExceptionConverter implements ExceptionConverterInterface
{
public function convert(Exception $exception, ?Query $query): DriverException
{
+ switch ($exception->getCode()) {
+ case 102:
+ return new SyntaxErrorException($exception, $query);
+
+ case 207:
+ return new InvalidFieldNameException($exception, $query);
+
+ case 208:
+ return new TableNotFoundException($exception, $query);
+
+ case 209:
+ return new NonUniqueFieldNameException($exception, $query);
+
+ case 515:
+ return new NotNullConstraintViolationException($exception, $query);
+
+ case 547:
+ case 4712:
+ return new ForeignKeyConstraintViolationException($exception, $query);
+
+ case 2601:
+ case 2627:
+ return new UniqueConstraintViolationException($exception, $query);
+
+ case 2714:
+ return new TableExistsException($exception, $query);
+
+ case 3701:
+ case 15151:
+ return new DatabaseObjectNotFoundException($exception, $query);
+
+ case 11001:
+ case 18456:
+ return new ConnectionException($exception, $query);
+ }
+
return new DriverException($exception, $query);
}
}
diff --git a/doctrine/dbal/src/Driver/API/SQLite/UserDefinedFunctions.php b/doctrine/dbal/src/Driver/API/SQLite/UserDefinedFunctions.php
new file mode 100644
index 00000000..29e73d1f
--- /dev/null
+++ b/doctrine/dbal/src/Driver/API/SQLite/UserDefinedFunctions.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Doctrine\DBAL\Driver\API\SQLite;
+
+use function strpos;
+
+/**
+ * User-defined SQLite functions.
+ *
+ * @internal
+ */
+final class UserDefinedFunctions
+{
+ /**
+ * User-defined function that implements MOD().
+ *
+ * @param int $a
+ * @param int $b
+ */
+ public static function mod($a, $b): int
+ {
+ return $a % $b;
+ }
+
+ /**
+ * User-defined function that implements LOCATE().
+ *
+ * @param string $str
+ * @param string $substr
+ * @param int $offset
+ */
+ public static function locate($str, $substr, $offset = 0): int
+ {
+ // SQL's LOCATE function works on 1-based positions, while PHP's strpos works on 0-based positions.
+ // So we have to make them compatible if an offset is given.
+ if ($offset > 0) {
+ $offset -= 1;
+ }
+
+ $pos = strpos($str, $substr, $offset);
+
+ if ($pos !== false) {
+ return $pos + 1;
+ }
+
+ return 0;
+ }
+}
diff --git a/doctrine/dbal/src/Driver/AbstractDB2Driver.php b/doctrine/dbal/src/Driver/AbstractDB2Driver.php
index d8c707bb..38a46086 100644
--- a/doctrine/dbal/src/Driver/AbstractDB2Driver.php
+++ b/doctrine/dbal/src/Driver/AbstractDB2Driver.php
@@ -10,8 +10,10 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\DB2Platform;
use Doctrine\DBAL\Schema\DB2SchemaManager;
+use function assert;
+
/**
- * Abstract base implementation of the {@link Driver} interface for IBM DB2 based drivers.
+ * Abstract base implementation of the {@see Driver} interface for IBM DB2 based drivers.
*/
abstract class AbstractDB2Driver implements Driver
{
@@ -28,6 +30,8 @@ abstract class AbstractDB2Driver implements Driver
*/
public function getSchemaManager(Connection $conn, AbstractPlatform $platform)
{
+ assert($platform instanceof DB2Platform);
+
return new DB2SchemaManager($conn, $platform);
}
diff --git a/doctrine/dbal/src/Driver/AbstractException.php b/doctrine/dbal/src/Driver/AbstractException.php
index d3866935..f14501b2 100644
--- a/doctrine/dbal/src/Driver/AbstractException.php
+++ b/doctrine/dbal/src/Driver/AbstractException.php
@@ -8,7 +8,7 @@ use Exception as BaseException;
use Throwable;
/**
- * Base implementation of the {@link Exception} interface.
+ * Base implementation of the {@see Exception} interface.
*
* @internal
*
diff --git a/doctrine/dbal/src/Driver/AbstractMySQLDriver.php b/doctrine/dbal/src/Driver/AbstractMySQLDriver.php
index 31949b9c..7f74e42d 100644
--- a/doctrine/dbal/src/Driver/AbstractMySQLDriver.php
+++ b/doctrine/dbal/src/Driver/AbstractMySQLDriver.php
@@ -6,6 +6,7 @@ use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\API\ExceptionConverter;
use Doctrine\DBAL\Driver\API\MySQL;
use Doctrine\DBAL\Exception;
+use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\MariaDb1027Platform;
use Doctrine\DBAL\Platforms\MySQL57Platform;
@@ -13,13 +14,15 @@ use Doctrine\DBAL\Platforms\MySQL80Platform;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\MySQLSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
+use Doctrine\Deprecations\Deprecation;
+use function assert;
use function preg_match;
use function stripos;
use function version_compare;
/**
- * Abstract base implementation of the {@link Driver} interface for MySQL based drivers.
+ * Abstract base implementation of the {@see Driver} interface for MySQL based drivers.
*/
abstract class AbstractMySQLDriver implements VersionAwarePlatformDriver
{
@@ -46,6 +49,13 @@ abstract class AbstractMySQLDriver implements VersionAwarePlatformDriver
}
}
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/5060',
+ 'MySQL 5.6 support is deprecated and will be removed in DBAL 4.'
+ . ' Consider upgrading to MySQL 5.7 or later.'
+ );
+
return $this->getDatabasePlatform();
}
@@ -112,7 +122,7 @@ abstract class AbstractMySQLDriver implements VersionAwarePlatformDriver
/**
* {@inheritdoc}
*
- * @return MySQLPlatform
+ * @return AbstractMySQLPlatform
*/
public function getDatabasePlatform()
{
@@ -126,6 +136,8 @@ abstract class AbstractMySQLDriver implements VersionAwarePlatformDriver
*/
public function getSchemaManager(Connection $conn, AbstractPlatform $platform)
{
+ assert($platform instanceof AbstractMySQLPlatform);
+
return new MySQLSchemaManager($conn, $platform);
}
diff --git a/doctrine/dbal/src/Driver/AbstractOracleDriver.php b/doctrine/dbal/src/Driver/AbstractOracleDriver.php
index 80e4a02c..c62c87d9 100644
--- a/doctrine/dbal/src/Driver/AbstractOracleDriver.php
+++ b/doctrine/dbal/src/Driver/AbstractOracleDriver.php
@@ -11,8 +11,10 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Schema\OracleSchemaManager;
+use function assert;
+
/**
- * Abstract base implementation of the {@link Driver} interface for Oracle based drivers.
+ * Abstract base implementation of the {@see Driver} interface for Oracle based drivers.
*/
abstract class AbstractOracleDriver implements Driver
{
@@ -29,6 +31,8 @@ abstract class AbstractOracleDriver implements Driver
*/
public function getSchemaManager(Connection $conn, AbstractPlatform $platform)
{
+ assert($platform instanceof OraclePlatform);
+
return new OracleSchemaManager($conn, $platform);
}
diff --git a/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php b/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php
index 6b11d617..adc0be09 100644
--- a/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php
+++ b/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php
@@ -9,14 +9,17 @@ use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\PostgreSQL100Platform;
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
+use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\DBAL\Schema\PostgreSQLSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
+use Doctrine\Deprecations\Deprecation;
+use function assert;
use function preg_match;
use function version_compare;
/**
- * Abstract base implementation of the {@link Driver} interface for PostgreSQL based drivers.
+ * Abstract base implementation of the {@see Driver} interface for PostgreSQL based drivers.
*/
abstract class AbstractPostgreSQLDriver implements VersionAwarePlatformDriver
{
@@ -41,6 +44,13 @@ abstract class AbstractPostgreSQLDriver implements VersionAwarePlatformDriver
return new PostgreSQL100Platform();
}
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/5060',
+ 'PostgreSQL 9 support is deprecated and will be removed in DBAL 4.'
+ . ' Consider upgrading to Postgres 10 or later.'
+ );
+
return new PostgreSQL94Platform();
}
@@ -57,6 +67,8 @@ abstract class AbstractPostgreSQLDriver implements VersionAwarePlatformDriver
*/
public function getSchemaManager(Connection $conn, AbstractPlatform $platform)
{
+ assert($platform instanceof PostgreSQLPlatform);
+
return new PostgreSQLSchemaManager($conn, $platform);
}
diff --git a/doctrine/dbal/src/Driver/AbstractSQLServerDriver.php b/doctrine/dbal/src/Driver/AbstractSQLServerDriver.php
index b3d0928b..adf31f55 100644
--- a/doctrine/dbal/src/Driver/AbstractSQLServerDriver.php
+++ b/doctrine/dbal/src/Driver/AbstractSQLServerDriver.php
@@ -10,8 +10,10 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\SQLServer2012Platform;
use Doctrine\DBAL\Schema\SQLServerSchemaManager;
+use function assert;
+
/**
- * Abstract base implementation of the {@link Driver} interface for Microsoft SQL Server based drivers.
+ * Abstract base implementation of the {@see Driver} interface for Microsoft SQL Server based drivers.
*/
abstract class AbstractSQLServerDriver implements Driver
{
@@ -28,6 +30,8 @@ abstract class AbstractSQLServerDriver implements Driver
*/
public function getSchemaManager(Connection $conn, AbstractPlatform $platform)
{
+ assert($platform instanceof SQLServer2012Platform);
+
return new SQLServerSchemaManager($conn, $platform);
}
diff --git a/doctrine/dbal/src/Driver/AbstractSQLiteDriver.php b/doctrine/dbal/src/Driver/AbstractSQLiteDriver.php
index 12b4cfa6..b6479267 100644
--- a/doctrine/dbal/src/Driver/AbstractSQLiteDriver.php
+++ b/doctrine/dbal/src/Driver/AbstractSQLiteDriver.php
@@ -10,8 +10,10 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Schema\SqliteSchemaManager;
+use function assert;
+
/**
- * Abstract base implementation of the {@link Doctrine\DBAL\Driver} interface for SQLite based drivers.
+ * Abstract base implementation of the {@see Doctrine\DBAL\Driver} interface for SQLite based drivers.
*/
abstract class AbstractSQLiteDriver implements Driver
{
@@ -28,6 +30,8 @@ abstract class AbstractSQLiteDriver implements Driver
*/
public function getSchemaManager(Connection $conn, AbstractPlatform $platform)
{
+ assert($platform instanceof SqlitePlatform);
+
return new SqliteSchemaManager($conn, $platform);
}
diff --git a/doctrine/dbal/src/Driver/Connection.php b/doctrine/dbal/src/Driver/Connection.php
index 9febe72a..2f460fd1 100644
--- a/doctrine/dbal/src/Driver/Connection.php
+++ b/doctrine/dbal/src/Driver/Connection.php
@@ -7,6 +7,8 @@ use Doctrine\DBAL\ParameterType;
/**
* Connection interface.
* Driver connections must implement this interface.
+ *
+ * @method resource|object getNativeConnection()
*/
interface Connection
{
@@ -27,6 +29,9 @@ interface Connection
/**
* Quotes a string for use in a query.
*
+ * The usage of this method is discouraged. Use prepared statements
+ * or {@see AbstractPlatform::quoteStringLiteral()} instead.
+ *
* @param mixed $value
* @param int $type
*
diff --git a/doctrine/dbal/src/Driver/IBMDB2/Connection.php b/doctrine/dbal/src/Driver/IBMDB2/Connection.php
index c8e36da3..aca2a02c 100644
--- a/doctrine/dbal/src/Driver/IBMDB2/Connection.php
+++ b/doctrine/dbal/src/Driver/IBMDB2/Connection.php
@@ -2,25 +2,23 @@
namespace Doctrine\DBAL\Driver\IBMDB2;
-use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionError;
-use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionFailed;
use Doctrine\DBAL\Driver\IBMDB2\Exception\PrepareFailed;
+use Doctrine\DBAL\Driver\IBMDB2\Exception\StatementError;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
+use Doctrine\Deprecations\Deprecation;
use stdClass;
use function assert;
use function db2_autocommit;
use function db2_commit;
-use function db2_connect;
use function db2_escape_string;
use function db2_exec;
use function db2_last_insert_id;
use function db2_num_rows;
-use function db2_pconnect;
use function db2_prepare;
use function db2_rollback;
use function db2_server_info;
@@ -33,33 +31,16 @@ use const DB2_AUTOCOMMIT_ON;
final class Connection implements ServerInfoAwareConnection
{
/** @var resource */
- private $conn;
+ private $connection;
/**
* @internal The connection can be only instantiated by its driver.
*
- * @param array<string,mixed> $driverOptions
- *
- * @throws Exception
+ * @param resource $connection
*/
- public function __construct(
- string $database,
- bool $persistent,
- string $username,
- string $password,
- array $driverOptions = []
- ) {
- if ($persistent) {
- $conn = db2_pconnect($database, $username, $password, $driverOptions);
- } else {
- $conn = db2_connect($database, $username, $password, $driverOptions);
- }
-
- if ($conn === false) {
- throw ConnectionFailed::new();
- }
-
- $this->conn = $conn;
+ public function __construct($connection)
+ {
+ $this->connection = $connection;
}
/**
@@ -67,7 +48,7 @@ final class Connection implements ServerInfoAwareConnection
*/
public function getServerVersion()
{
- $serverInfo = db2_server_info($this->conn);
+ $serverInfo = db2_server_info($this->connection);
assert($serverInfo instanceof stdClass);
return $serverInfo->DBMS_VER;
@@ -75,7 +56,7 @@ final class Connection implements ServerInfoAwareConnection
public function prepare(string $sql): DriverStatement
{
- $stmt = @db2_prepare($this->conn, $sql);
+ $stmt = @db2_prepare($this->connection, $sql);
if ($stmt === false) {
throw PrepareFailed::new(error_get_last());
@@ -105,10 +86,10 @@ final class Connection implements ServerInfoAwareConnection
public function exec(string $sql): int
{
- $stmt = @db2_exec($this->conn, $sql);
+ $stmt = @db2_exec($this->connection, $sql);
if ($stmt === false) {
- throw ConnectionError::new($this->conn);
+ throw StatementError::new();
}
return db2_num_rows($stmt);
@@ -119,47 +100,54 @@ final class Connection implements ServerInfoAwareConnection
*/
public function lastInsertId($name = null)
{
- return db2_last_insert_id($this->conn);
+ if ($name !== null) {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4687',
+ 'The usage of Connection::lastInsertId() with a sequence name is deprecated.'
+ );
+ }
+
+ return db2_last_insert_id($this->connection) ?? false;
}
- /**
- * {@inheritdoc}
- */
- public function beginTransaction()
+ public function beginTransaction(): bool
{
- $result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_OFF);
+ $result = db2_autocommit($this->connection, DB2_AUTOCOMMIT_OFF);
assert(is_bool($result));
return $result;
}
- /**
- * {@inheritdoc}
- */
- public function commit()
+ public function commit(): bool
{
- if (! db2_commit($this->conn)) {
- throw ConnectionError::new($this->conn);
+ if (! db2_commit($this->connection)) {
+ throw ConnectionError::new($this->connection);
}
- $result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
+ $result = db2_autocommit($this->connection, DB2_AUTOCOMMIT_ON);
assert(is_bool($result));
return $result;
}
- /**
- * {@inheritdoc}
- */
- public function rollBack()
+ public function rollBack(): bool
{
- if (! db2_rollback($this->conn)) {
- throw ConnectionError::new($this->conn);
+ if (! db2_rollback($this->connection)) {
+ throw ConnectionError::new($this->connection);
}
- $result = db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
+ $result = db2_autocommit($this->connection, DB2_AUTOCOMMIT_ON);
assert(is_bool($result));
return $result;
}
+
+ /**
+ * @return resource
+ */
+ public function getNativeConnection()
+ {
+ return $this->connection;
+ }
}
diff --git a/doctrine/dbal/src/Driver/IBMDB2/Driver.php b/doctrine/dbal/src/Driver/IBMDB2/Driver.php
index c0816552..142b369b 100644
--- a/doctrine/dbal/src/Driver/IBMDB2/Driver.php
+++ b/doctrine/dbal/src/Driver/IBMDB2/Driver.php
@@ -3,6 +3,10 @@
namespace Doctrine\DBAL\Driver\IBMDB2;
use Doctrine\DBAL\Driver\AbstractDB2Driver;
+use Doctrine\DBAL\Driver\IBMDB2\Exception\ConnectionFailed;
+
+use function db2_connect;
+use function db2_pconnect;
final class Driver extends AbstractDB2Driver
{
@@ -13,12 +17,22 @@ final class Driver extends AbstractDB2Driver
*/
public function connect(array $params)
{
- return new Connection(
- DataSourceName::fromConnectionParameters($params)->toString(),
- isset($params['persistent']) && $params['persistent'] === true,
- $params['user'] ?? '',
- $params['password'] ?? '',
- $params['driverOptions'] ?? []
- );
+ $dataSourceName = DataSourceName::fromConnectionParameters($params)->toString();
+
+ $username = $params['user'] ?? '';
+ $password = $params['password'] ?? '';
+ $driverOptions = $params['driverOptions'] ?? [];
+
+ if (! empty($params['persistent'])) {
+ $connection = db2_pconnect($dataSourceName, $username, $password, $driverOptions);
+ } else {
+ $connection = db2_connect($dataSourceName, $username, $password, $driverOptions);
+ }
+
+ if ($connection === false) {
+ throw ConnectionFailed::new();
+ }
+
+ return new Connection($connection);
}
}
diff --git a/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionError.php b/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionError.php
index 97bff611..a27a99a1 100644
--- a/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionError.php
+++ b/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionError.php
@@ -21,6 +21,11 @@ final class ConnectionError extends AbstractException
*/
public static function new($connection): self
{
- return new self(db2_conn_errormsg($connection), db2_conn_error($connection));
+ $message = db2_conn_errormsg($connection);
+ $sqlState = db2_conn_error($connection);
+
+ return Factory::create($message, static function (int $code) use ($message, $sqlState): self {
+ return new self($message, $sqlState, $code);
+ });
}
}
diff --git a/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionFailed.php b/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionFailed.php
index fe79c227..9dd04434 100644
--- a/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionFailed.php
+++ b/doctrine/dbal/src/Driver/IBMDB2/Exception/ConnectionFailed.php
@@ -18,6 +18,11 @@ final class ConnectionFailed extends AbstractException
{
public static function new(): self
{
- return new self(db2_conn_errormsg(), db2_conn_error());
+ $message = db2_conn_errormsg();
+ $sqlState = db2_conn_error();
+
+ return Factory::create($message, static function (int $code) use ($message, $sqlState): self {
+ return new self($message, $sqlState, $code);
+ });
}
}
diff --git a/doctrine/dbal/src/Driver/IBMDB2/Exception/Factory.php b/doctrine/dbal/src/Driver/IBMDB2/Exception/Factory.php
new file mode 100644
index 00000000..91b9b439
--- /dev/null
+++ b/doctrine/dbal/src/Driver/IBMDB2/Exception/Factory.php
@@ -0,0 +1,35 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\DBAL\Driver\IBMDB2\Exception;
+
+use Doctrine\DBAL\Driver\AbstractException;
+
+use function preg_match;
+
+/**
+ * @internal
+ *
+ * @psalm-immutable
+ */
+final class Factory
+{
+ /**
+ * @param callable(int): T $constructor
+ *
+ * @return T
+ *
+ * @template T of AbstractException
+ */
+ public static function create(string $message, callable $constructor): AbstractException
+ {
+ $code = 0;
+
+ if (preg_match('/ SQL(\d+)N /', $message, $matches) === 1) {
+ $code = -(int) $matches[1];
+ }
+
+ return $constructor($code);
+ }
+}
diff --git a/doctrine/dbal/src/Driver/IBMDB2/Exception/StatementError.php b/doctrine/dbal/src/Driver/IBMDB2/Exception/StatementError.php
index c3c5f87a..5c30d1ca 100644
--- a/doctrine/dbal/src/Driver/IBMDB2/Exception/StatementError.php
+++ b/doctrine/dbal/src/Driver/IBMDB2/Exception/StatementError.php
@@ -17,10 +17,20 @@ use function db2_stmt_errormsg;
final class StatementError extends AbstractException
{
/**
- * @param resource $statement
+ * @param resource|null $statement
*/
- public static function new($statement): self
+ public static function new($statement = null): self
{
- return new self(db2_stmt_errormsg($statement), db2_stmt_error($statement));
+ if ($statement !== null) {
+ $message = db2_stmt_errormsg($statement);
+ $sqlState = db2_stmt_error($statement);
+ } else {
+ $message = db2_stmt_errormsg();
+ $sqlState = db2_stmt_error();
+ }
+
+ return Factory::create($message, static function (int $code) use ($message, $sqlState): self {
+ return new self($message, $sqlState, $code);
+ });
}
}
diff --git a/doctrine/dbal/src/Driver/IBMDB2/Statement.php b/doctrine/dbal/src/Driver/IBMDB2/Statement.php
index c655ea74..39cd6a47 100644
--- a/doctrine/dbal/src/Driver/IBMDB2/Statement.php
+++ b/doctrine/dbal/src/Driver/IBMDB2/Statement.php
@@ -59,7 +59,7 @@ final class Statement implements StatementInterface
/**
* {@inheritdoc}
*/
- public function bindValue($param, $value, $type = ParameterType::STRING)
+ public function bindValue($param, $value, $type = ParameterType::STRING): bool
{
assert(is_int($param));
@@ -69,7 +69,7 @@ final class Statement implements StatementInterface
/**
* {@inheritdoc}
*/
- public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
+ public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool
{
assert(is_int($param));
@@ -140,7 +140,7 @@ final class Statement implements StatementInterface
$this->writeStringToStream($source, $target);
}
- $result = db2_execute($this->stmt, $params);
+ $result = @db2_execute($this->stmt, $params);
foreach ($this->lobs as [, $handle]) {
fclose($handle);
diff --git a/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php b/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php
new file mode 100644
index 00000000..a0e69a5e
--- /dev/null
+++ b/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace Doctrine\DBAL\Driver\Middleware;
+
+use Doctrine\DBAL\Driver\Connection;
+use Doctrine\DBAL\Driver\Result;
+use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
+use Doctrine\DBAL\Driver\Statement;
+use Doctrine\DBAL\ParameterType;
+use Doctrine\Deprecations\Deprecation;
+use LogicException;
+
+use function get_class;
+use function method_exists;
+use function sprintf;
+
+abstract class AbstractConnectionMiddleware implements ServerInfoAwareConnection
+{
+ /** @var Connection */
+ private $wrappedConnection;
+
+ public function __construct(Connection $wrappedConnection)
+ {
+ $this->wrappedConnection = $wrappedConnection;
+ }
+
+ public function prepare(string $sql): Statement
+ {
+ return $this->wrappedConnection->prepare($sql);
+ }
+
+ public function query(string $sql): Result
+ {
+ return $this->wrappedConnection->query($sql);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function quote($value, $type = ParameterType::STRING)
+ {
+ return $this->wrappedConnection->quote($value, $type);
+ }
+
+ public function exec(string $sql): int
+ {
+ return $this->wrappedConnection->exec($sql);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function lastInsertId($name = null)
+ {
+ if ($name !== null) {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4687',
+ 'The usage of Connection::lastInsertId() with a sequence name is deprecated.'
+ );
+ }
+
+ return $this->wrappedConnection->lastInsertId($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function beginTransaction()
+ {
+ return $this->wrappedConnection->beginTransaction();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function commit()
+ {
+ return $this->wrappedConnection->commit();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function rollBack()
+ {
+ return $this->wrappedConnection->rollBack();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getServerVersion()
+ {
+ if (! $this->wrappedConnection instanceof ServerInfoAwareConnection) {
+ throw new LogicException('The underlying connection is not a ServerInfoAwareConnection');
+ }
+
+ return $this->wrappedConnection->getServerVersion();
+ }
+
+ /**
+ * @return resource|object
+ */
+ public function getNativeConnection()
+ {
+ if (! method_exists($this->wrappedConnection, 'getNativeConnection')) {
+ throw new LogicException(sprintf(
+ 'The driver connection %s does not support accessing the native connection.',
+ get_class($this->wrappedConnection)
+ ));
+ }
+
+ return $this->wrappedConnection->getNativeConnection();
+ }
+}
diff --git a/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php b/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php
new file mode 100644
index 00000000..ab1f508f
--- /dev/null
+++ b/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Doctrine\DBAL\Driver\Middleware;
+
+use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\Driver;
+use Doctrine\DBAL\Driver\API\ExceptionConverter;
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+use Doctrine\DBAL\VersionAwarePlatformDriver;
+
+abstract class AbstractDriverMiddleware implements VersionAwarePlatformDriver
+{
+ /** @var Driver */
+ private $wrappedDriver;
+
+ public function __construct(Driver $wrappedDriver)
+ {
+ $this->wrappedDriver = $wrappedDriver;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function connect(array $params)
+ {
+ return $this->wrappedDriver->connect($params);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDatabasePlatform()
+ {
+ return $this->wrappedDriver->getDatabasePlatform();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSchemaManager(Connection $conn, AbstractPlatform $platform)
+ {
+ return $this->wrappedDriver->getSchemaManager($conn, $platform);
+ }
+
+ public function getExceptionConverter(): ExceptionConverter
+ {
+ return $this->wrappedDriver->getExceptionConverter();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createDatabasePlatformForVersion($version)
+ {
+ if ($this->wrappedDriver instanceof VersionAwarePlatformDriver) {
+ return $this->wrappedDriver->createDatabasePlatformForVersion($version);
+ }
+
+ return $this->wrappedDriver->getDatabasePlatform();
+ }
+}
diff --git a/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php b/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php
new file mode 100644
index 00000000..ebc63c57
--- /dev/null
+++ b/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Doctrine\DBAL\Driver\Middleware;
+
+use Doctrine\DBAL\Driver\Result;
+
+abstract class AbstractResultMiddleware implements Result
+{
+ /** @var Result */
+ private $wrappedResult;
+
+ public function __construct(Result $result)
+ {
+ $this->wrappedResult = $result;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function fetchNumeric()
+ {
+ return $this->wrappedResult->fetchNumeric();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function fetchAssociative()
+ {
+ return $this->wrappedResult->fetchAssociative();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function fetchOne()
+ {
+ return $this->wrappedResult->fetchOne();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function fetchAllNumeric(): array
+ {
+ return $this->wrappedResult->fetchAllNumeric();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function fetchAllAssociative(): array
+ {
+ return $this->wrappedResult->fetchAllAssociative();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function fetchFirstColumn(): array
+ {
+ return $this->wrappedResult->fetchFirstColumn();
+ }
+
+ public function rowCount(): int
+ {
+ return $this->wrappedResult->rowCount();
+ }
+
+ public function columnCount(): int
+ {
+ return $this->wrappedResult->columnCount();
+ }
+
+ public function free(): void
+ {
+ $this->wrappedResult->free();
+ }
+}
diff --git a/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php b/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php
new file mode 100644
index 00000000..a646cd30
--- /dev/null
+++ b/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Doctrine\DBAL\Driver\Middleware;
+
+use Doctrine\DBAL\Driver\Result;
+use Doctrine\DBAL\Driver\Statement;
+use Doctrine\DBAL\ParameterType;
+
+abstract class AbstractStatementMiddleware implements Statement
+{
+ /** @var Statement */
+ private $wrappedStatement;
+
+ public function __construct(Statement $wrappedStatement)
+ {
+ $this->wrappedStatement = $wrappedStatement;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function bindValue($param, $value, $type = ParameterType::STRING)
+ {
+ return $this->wrappedStatement->bindValue($param, $value, $type);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
+ {
+ return $this->wrappedStatement->bindParam($param, $variable, $type, $length);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function execute($params = null): Result
+ {
+ return $this->wrappedStatement->execute($params);
+ }
+}
diff --git a/doctrine/dbal/src/Driver/Mysqli/Connection.php b/doctrine/dbal/src/Driver/Mysqli/Connection.php
index 73634536..8453f740 100644
--- a/doctrine/dbal/src/Driver/Mysqli/Connection.php
+++ b/doctrine/dbal/src/Driver/Mysqli/Connection.php
@@ -2,21 +2,15 @@
namespace Doctrine\DBAL\Driver\Mysqli;
-use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
-use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionFailed;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
+use Doctrine\Deprecations\Deprecation;
use mysqli;
use mysqli_sql_exception;
-use function assert;
-use function floor;
-use function mysqli_init;
-use function stripos;
-
final class Connection implements ServerInfoAwareConnection
{
/**
@@ -25,49 +19,14 @@ final class Connection implements ServerInfoAwareConnection
public const OPTION_FLAGS = 'flags';
/** @var mysqli */
- private $conn;
+ private $connection;
/**
* @internal The connection can be only instantiated by its driver.
- *
- * @param iterable<Initializer> $preInitializers
- * @param iterable<Initializer> $postInitializers
- *
- * @throws Exception
*/
- public function __construct(
- ?string $host = null,
- ?string $username = null,
- ?string $password = null,
- ?string $database = null,
- ?int $port = null,
- ?string $socket = null,
- int $flags = 0,
- iterable $preInitializers = [],
- iterable $postInitializers = []
- ) {
- $connection = mysqli_init();
- assert($connection !== false);
-
- foreach ($preInitializers as $initializer) {
- $initializer->initialize($connection);
- }
-
- try {
- $success = @$connection->real_connect($host, $username, $password, $database, $port, $socket, $flags);
- } catch (mysqli_sql_exception $e) {
- throw ConnectionFailed::upcast($e);
- }
-
- if (! $success) {
- throw ConnectionFailed::new($connection);
- }
-
- foreach ($postInitializers as $initializer) {
- $initializer->initialize($connection);
- }
-
- $this->conn = $connection;
+ public function __construct(mysqli $connection)
+ {
+ $this->connection = $connection;
}
/**
@@ -75,38 +34,38 @@ final class Connection implements ServerInfoAwareConnection
*
* Could be used if part of your application is not using DBAL.
*
- * @return mysqli
+ * @deprecated Call {@see getNativeConnection()} instead.
*/
- public function getWrappedResourceHandle()
+ public function getWrappedResourceHandle(): mysqli
{
- return $this->conn;
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/5037',
+ '%s is deprecated, call getNativeConnection() instead.',
+ __METHOD__
+ );
+
+ return $this->getNativeConnection();
}
- /**
- * {@inheritdoc}
- *
- * The server version detection includes a special case for MariaDB
- * to support '5.5.5-' prefixed versions introduced in Maria 10+
- *
- * @link https://jira.mariadb.org/browse/MDEV-4088
- */
- public function getServerVersion()
+ public function getServerVersion(): string
{
- $serverInfos = $this->conn->get_server_info();
- if (stripos($serverInfos, 'mariadb') !== false) {
- return $serverInfos;
- }
-
- $majorVersion = floor($this->conn->server_version / 10000);
- $minorVersion = floor(($this->conn->server_version - $majorVersion * 10000) / 100);
- $patchVersion = floor($this->conn->server_version - $majorVersion * 10000 - $minorVersion * 100);
-
- return $majorVersion . '.' . $minorVersion . '.' . $patchVersion;
+ return $this->connection->get_server_info();
}
public function prepare(string $sql): DriverStatement
{
- return new Statement($this->conn, $sql);
+ try {
+ $stmt = $this->connection->prepare($sql);
+ } catch (mysqli_sql_exception $e) {
+ throw ConnectionError::upcast($e);
+ }
+
+ if ($stmt === false) {
+ throw ConnectionError::new($this->connection);
+ }
+
+ return new Statement($stmt);
}
public function query(string $sql): ResultInterface
@@ -119,22 +78,22 @@ final class Connection implements ServerInfoAwareConnection
*/
public function quote($value, $type = ParameterType::STRING)
{
- return "'" . $this->conn->escape_string($value) . "'";
+ return "'" . $this->connection->escape_string($value) . "'";
}
public function exec(string $sql): int
{
try {
- $result = $this->conn->query($sql);
+ $result = $this->connection->query($sql);
} catch (mysqli_sql_exception $e) {
throw ConnectionError::upcast($e);
}
if ($result === false) {
- throw ConnectionError::new($this->conn);
+ throw ConnectionError::new($this->connection);
}
- return $this->conn->affected_rows;
+ return $this->connection->affected_rows;
}
/**
@@ -142,40 +101,44 @@ final class Connection implements ServerInfoAwareConnection
*/
public function lastInsertId($name = null)
{
- return $this->conn->insert_id;
+ if ($name !== null) {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4687',
+ 'The usage of Connection::lastInsertId() with a sequence name is deprecated.'
+ );
+ }
+
+ return $this->connection->insert_id;
}
- /**
- * {@inheritdoc}
- */
- public function beginTransaction()
+ public function beginTransaction(): bool
{
- $this->conn->query('START TRANSACTION');
+ $this->connection->begin_transaction();
return true;
}
- /**
- * {@inheritdoc}
- */
- public function commit()
+ public function commit(): bool
{
try {
- return $this->conn->commit();
+ return $this->connection->commit();
} catch (mysqli_sql_exception $e) {
return false;
}
}
- /**
- * {@inheritdoc}
- */
- public function rollBack()
+ public function rollBack(): bool
{
try {
- return $this->conn->rollback();
+ return $this->connection->rollback();
} catch (mysqli_sql_exception $e) {
return false;
}
}
+
+ public function getNativeConnection(): mysqli
+ {
+ return $this->connection;
+ }
}
diff --git a/doctrine/dbal/src/Driver/Mysqli/Driver.php b/doctrine/dbal/src/Driver/Mysqli/Driver.php
index d459863d..41a66a73 100644
--- a/doctrine/dbal/src/Driver/Mysqli/Driver.php
+++ b/doctrine/dbal/src/Driver/Mysqli/Driver.php
@@ -3,10 +3,13 @@
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
+use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionFailed;
use Doctrine\DBAL\Driver\Mysqli\Exception\HostRequired;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Charset;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Options;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Secure;
+use mysqli;
+use mysqli_sql_exception;
use function count;
@@ -47,17 +50,35 @@ final class Driver extends AbstractMySQLDriver
$preInitializers = $this->withSecure($preInitializers, $params);
$postInitializers = $this->withCharset($postInitializers, $params);
- return new Connection(
- $host,
- $params['user'] ?? null,
- $params['password'] ?? null,
- $params['dbname'] ?? null,
- $params['port'] ?? null,
- $params['unix_socket'] ?? null,
- $flags,
- $preInitializers,
- $postInitializers
- );
+ $connection = new mysqli();
+
+ foreach ($preInitializers as $initializer) {
+ $initializer->initialize($connection);
+ }
+
+ try {
+ $success = @$connection->real_connect(
+ $host,
+ $params['user'] ?? null,
+ $params['password'] ?? null,
+ $params['dbname'] ?? null,
+ $params['port'] ?? null,
+ $params['unix_socket'] ?? null,
+ $flags
+ );
+ } catch (mysqli_sql_exception $e) {
+ throw ConnectionFailed::upcast($e);
+ }
+
+ if (! $success) {
+ throw ConnectionFailed::new($connection);
+ }
+
+ foreach ($postInitializers as $initializer) {
+ $initializer->initialize($connection);
+ }
+
+ return new Connection($connection);
}
/**
diff --git a/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php b/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php
index faceeb08..44a8cab9 100644
--- a/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php
+++ b/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php
@@ -9,6 +9,8 @@ use mysqli;
use mysqli_sql_exception;
use ReflectionProperty;
+use function assert;
+
/**
* @internal
*
@@ -18,7 +20,10 @@ final class ConnectionFailed extends AbstractException
{
public static function new(mysqli $connection): self
{
- return new self($connection->connect_error, 'HY000', $connection->connect_errno);
+ $error = $connection->connect_error;
+ assert($error !== null);
+
+ return new self($error, 'HY000', $connection->connect_errno);
}
public static function upcast(mysqli_sql_exception $exception): self
diff --git a/doctrine/dbal/src/Driver/Mysqli/Result.php b/doctrine/dbal/src/Driver/Mysqli/Result.php
index 23047152..ac36df03 100644
--- a/doctrine/dbal/src/Driver/Mysqli/Result.php
+++ b/doctrine/dbal/src/Driver/Mysqli/Result.php
@@ -10,11 +10,10 @@ use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use mysqli_sql_exception;
use mysqli_stmt;
-use stdClass;
+use function array_column;
use function array_combine;
use function array_fill;
-use function array_map;
use function count;
final class Result implements ResultInterface
@@ -58,11 +57,7 @@ final class Result implements ResultInterface
$this->hasColumns = true;
- $fields = $meta->fetch_fields();
-
- $this->columnNames = array_map(static function (stdClass $field): string {
- return $field->name;
- }, $fields);
+ $this->columnNames = array_column($meta->fetch_fields(), 'name');
$meta->free();
@@ -84,10 +79,8 @@ final class Result implements ResultInterface
// to the length of the ones fetched during the previous execution.
$this->boundValues = array_fill(0, count($this->columnNames), null);
- $refs = [];
- foreach ($this->boundValues as &$value) {
- $refs[] =& $value;
- }
+ // The following is necessary as PHP cannot handle references to properties properly
+ $refs = &$this->boundValues;
if (! $this->statement->bind_result(...$refs)) {
throw StatementError::new($this->statement);
diff --git a/doctrine/dbal/src/Driver/Mysqli/Statement.php b/doctrine/dbal/src/Driver/Mysqli/Statement.php
index 249cb2c8..6e493c9e 100644
--- a/doctrine/dbal/src/Driver/Mysqli/Statement.php
+++ b/doctrine/dbal/src/Driver/Mysqli/Statement.php
@@ -4,14 +4,12 @@ namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\Exception\UnknownParameterType;
-use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
use Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset;
use Doctrine\DBAL\Driver\Mysqli\Exception\NonStreamResourceUsedAsLargeObject;
use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
-use mysqli;
use mysqli_sql_exception;
use mysqli_stmt;
@@ -28,7 +26,7 @@ use function str_repeat;
final class Statement implements StatementInterface
{
/** @var string[] */
- protected static $_paramTypeMap = [
+ private static $paramTypeMap = [
ParameterType::ASCII => 's',
ParameterType::STRING => 's',
ParameterType::BINARY => 's',
@@ -38,66 +36,47 @@ final class Statement implements StatementInterface
ParameterType::LARGE_OBJECT => 'b',
];
- /** @var mysqli */
- protected $_conn;
-
/** @var mysqli_stmt */
- protected $_stmt;
+ private $stmt;
/** @var mixed[] */
- protected $_bindedValues;
+ private $boundValues;
/** @var string */
- protected $types;
+ private $types;
/**
* Contains ref values for bindValue().
*
* @var mixed[]
*/
- protected $_values = [];
+ private $values = [];
/**
* @internal The statement can be only instantiated by its driver connection.
- *
- * @param string $prepareString
- *
- * @throws Exception
*/
- public function __construct(mysqli $conn, $prepareString)
+ public function __construct(mysqli_stmt $stmt)
{
- $this->_conn = $conn;
-
- try {
- $stmt = $conn->prepare($prepareString);
- } catch (mysqli_sql_exception $e) {
- throw ConnectionError::upcast($e);
- }
+ $this->stmt = $stmt;
- if ($stmt === false) {
- throw ConnectionError::new($this->_conn);
- }
-
- $this->_stmt = $stmt;
-
- $paramCount = $this->_stmt->param_count;
- $this->types = str_repeat('s', $paramCount);
- $this->_bindedValues = array_fill(1, $paramCount, null);
+ $paramCount = $this->stmt->param_count;
+ $this->types = str_repeat('s', $paramCount);
+ $this->boundValues = array_fill(1, $paramCount, null);
}
/**
* {@inheritdoc}
*/
- public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
+ public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool
{
assert(is_int($param));
- if (! isset(self::$_paramTypeMap[$type])) {
+ if (! isset(self::$paramTypeMap[$type])) {
throw UnknownParameterType::new($type);
}
- $this->_bindedValues[$param] =& $variable;
- $this->types[$param - 1] = self::$_paramTypeMap[$type];
+ $this->boundValues[$param] =& $variable;
+ $this->types[$param - 1] = self::$paramTypeMap[$type];
return true;
}
@@ -105,17 +84,17 @@ final class Statement implements StatementInterface
/**
* {@inheritdoc}
*/
- public function bindValue($param, $value, $type = ParameterType::STRING)
+ public function bindValue($param, $value, $type = ParameterType::STRING): bool
{
assert(is_int($param));
- if (! isset(self::$_paramTypeMap[$type])) {
+ if (! isset(self::$paramTypeMap[$type])) {
throw UnknownParameterType::new($type);
}
- $this->_values[$param] = $value;
- $this->_bindedValues[$param] =& $this->_values[$param];
- $this->types[$param - 1] = self::$_paramTypeMap[$type];
+ $this->values[$param] = $value;
+ $this->boundValues[$param] =& $this->values[$param];
+ $this->types[$param - 1] = self::$paramTypeMap[$type];
return true;
}
@@ -127,23 +106,23 @@ final class Statement implements StatementInterface
{
if ($params !== null && count($params) > 0) {
if (! $this->bindUntypedValues($params)) {
- throw StatementError::new($this->_stmt);
+ throw StatementError::new($this->stmt);
}
- } elseif (count($this->_bindedValues) > 0) {
+ } elseif (count($this->boundValues) > 0) {
$this->bindTypedParameters();
}
try {
- $result = $this->_stmt->execute();
+ $result = $this->stmt->execute();
} catch (mysqli_sql_exception $e) {
throw StatementError::upcast($e);
}
if (! $result) {
- throw StatementError::new($this->_stmt);
+ throw StatementError::new($this->stmt);
}
- return new Result($this->_stmt);
+ return new Result($this->stmt);
}
/**
@@ -156,14 +135,14 @@ final class Statement implements StatementInterface
$streams = $values = [];
$types = $this->types;
- foreach ($this->_bindedValues as $parameter => $value) {
+ foreach ($this->boundValues as $parameter => $value) {
assert(is_int($parameter));
if (! isset($types[$parameter - 1])) {
- $types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING];
+ $types[$parameter - 1] = self::$paramTypeMap[ParameterType::STRING];
}
- if ($types[$parameter - 1] === static::$_paramTypeMap[ParameterType::LARGE_OBJECT]) {
+ if ($types[$parameter - 1] === self::$paramTypeMap[ParameterType::LARGE_OBJECT]) {
if (is_resource($value)) {
if (get_resource_type($value) !== 'stream') {
throw NonStreamResourceUsedAsLargeObject::new($parameter);
@@ -174,14 +153,14 @@ final class Statement implements StatementInterface
continue;
}
- $types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING];
+ $types[$parameter - 1] = self::$paramTypeMap[ParameterType::STRING];
}
$values[$parameter] = $value;
}
- if (! $this->_stmt->bind_param($types, ...$values)) {
- throw StatementError::new($this->_stmt);
+ if (! $this->stmt->bind_param($types, ...$values)) {
+ throw StatementError::new($this->stmt);
}
$this->sendLongData($streams);
@@ -204,8 +183,8 @@ final class Statement implements StatementInterface
throw FailedReadingStreamOffset::new($paramNr);
}
- if (! $this->_stmt->send_long_data($paramNr - 1, $chunk)) {
- throw StatementError::new($this->_stmt);
+ if (! $this->stmt->send_long_data($paramNr - 1, $chunk)) {
+ throw StatementError::new($this->stmt);
}
}
}
@@ -215,18 +194,9 @@ final class Statement implements StatementInterface
* Binds a array of values to bound parameters.
*
* @param mixed[] $values
- *
- * @return bool
*/
- private function bindUntypedValues(array $values)
+ private function bindUntypedValues(array $values): bool
{
- $params = [];
- $types = str_repeat('s', count($values));
-
- foreach ($values as &$v) {
- $params[] =& $v;
- }
-
- return $this->_stmt->bind_param($types, ...$params);
+ return $this->stmt->bind_param(str_repeat('s', count($values)), ...$values);
}
}
diff --git a/doctrine/dbal/src/Driver/OCI8/Connection.php b/doctrine/dbal/src/Driver/OCI8/Connection.php
index b05892f9..46ff4186 100644
--- a/doctrine/dbal/src/Driver/OCI8/Connection.php
+++ b/doctrine/dbal/src/Driver/OCI8/Connection.php
@@ -3,79 +3,56 @@
namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\Exception;
-use Doctrine\DBAL\Driver\OCI8\Exception\ConnectionFailed;
use Doctrine\DBAL\Driver\OCI8\Exception\Error;
use Doctrine\DBAL\Driver\OCI8\Exception\SequenceDoesNotExist;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
+use Doctrine\DBAL\SQL\Parser;
+use Doctrine\Deprecations\Deprecation;
use function addcslashes;
use function assert;
use function is_float;
use function is_int;
+use function is_resource;
use function oci_commit;
-use function oci_connect;
-use function oci_pconnect;
+use function oci_parse;
use function oci_rollback;
use function oci_server_version;
use function preg_match;
use function str_replace;
-use const OCI_NO_AUTO_COMMIT;
-
final class Connection implements ServerInfoAwareConnection
{
/** @var resource */
- protected $dbh;
+ private $connection;
+
+ /** @var Parser */
+ private $parser;
/** @var ExecutionMode */
private $executionMode;
/**
- * Creates a Connection to an Oracle Database using oci8 extension.
- *
* @internal The connection can be only instantiated by its driver.
*
- * @param string $username
- * @param string $password
- * @param string $db
- * @param string $charset
- * @param int $sessionMode
- * @param bool $persistent
- *
- * @throws Exception
+ * @param resource $connection
*/
- public function __construct(
- $username,
- $password,
- $db,
- $charset = '',
- $sessionMode = OCI_NO_AUTO_COMMIT,
- $persistent = false
- ) {
- $dbh = $persistent
- ? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
- : @oci_connect($username, $password, $db, $charset, $sessionMode);
-
- if ($dbh === false) {
- throw ConnectionFailed::new();
- }
-
- $this->dbh = $dbh;
+ public function __construct($connection)
+ {
+ $this->connection = $connection;
+ $this->parser = new Parser(false);
$this->executionMode = new ExecutionMode();
}
- /**
- * {@inheritdoc}
- */
- public function getServerVersion()
+ public function getServerVersion(): string
{
- $version = oci_server_version($this->dbh);
+ $version = oci_server_version($this->connection);
if ($version === false) {
- throw Error::new($this->dbh);
+ throw Error::new($this->connection);
}
$result = preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches);
@@ -84,11 +61,25 @@ final class Connection implements ServerInfoAwareConnection
return $matches[1];
}
+ /**
+ * @throws Parser\Exception
+ */
public function prepare(string $sql): DriverStatement
{
- return new Statement($this->dbh, $sql, $this->executionMode);
+ $visitor = new ConvertPositionalToNamedPlaceholders();
+
+ $this->parser->parse($sql, $visitor);
+
+ $statement = oci_parse($this->connection, $visitor->getSQL());
+ assert(is_resource($statement));
+
+ return new Statement($this->connection, $statement, $visitor->getParameterMap(), $this->executionMode);
}
+ /**
+ * @throws Exception
+ * @throws Parser\Exception
+ */
public function query(string $sql): ResultInterface
{
return $this->prepare($sql)->execute();
@@ -108,6 +99,10 @@ final class Connection implements ServerInfoAwareConnection
return "'" . addcslashes($value, "\000\n\r\\\032") . "'";
}
+ /**
+ * @throws Exception
+ * @throws Parser\Exception
+ */
public function exec(string $sql): int
{
return $this->prepare($sql)->execute()->rowCount();
@@ -119,6 +114,8 @@ final class Connection implements ServerInfoAwareConnection
* @param string|null $name
*
* @return int|false
+ *
+ * @throws Parser\Exception
*/
public function lastInsertId($name = null)
{
@@ -126,6 +123,12 @@ final class Connection implements ServerInfoAwareConnection
return false;
}
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4687',
+ 'The usage of Connection::lastInsertId() with a sequence name is deprecated.'
+ );
+
$result = $this->query('SELECT ' . $name . '.CURRVAL FROM DUAL')->fetchOne();
if ($result === false) {
@@ -135,23 +138,17 @@ final class Connection implements ServerInfoAwareConnection
return (int) $result;
}
- /**
- * {@inheritdoc}
- */
- public function beginTransaction()
+ public function beginTransaction(): bool
{
$this->executionMode->disableAutoCommit();
return true;
}
- /**
- * {@inheritdoc}
- */
- public function commit()
+ public function commit(): bool
{
- if (! oci_commit($this->dbh)) {
- throw Error::new($this->dbh);
+ if (! oci_commit($this->connection)) {
+ throw Error::new($this->connection);
}
$this->executionMode->enableAutoCommit();
@@ -159,17 +156,22 @@ final class Connection implements ServerInfoAwareConnection
return true;
}
- /**
- * {@inheritdoc}
- */
- public function rollBack()
+ public function rollBack(): bool
{
- if (! oci_rollback($this->dbh)) {
- throw Error::new($this->dbh);
+ if (! oci_rollback($this->connection)) {
+ throw Error::new($this->connection);
}
$this->executionMode->enableAutoCommit();
return true;
}
+
+ /**
+ * @return resource
+ */
+ public function getNativeConnection()
+ {
+ return $this->connection;
+ }
}
diff --git a/doctrine/dbal/src/Driver/OCI8/Driver.php b/doctrine/dbal/src/Driver/OCI8/Driver.php
index 351ffb87..48ef0bbe 100644
--- a/doctrine/dbal/src/Driver/OCI8/Driver.php
+++ b/doctrine/dbal/src/Driver/OCI8/Driver.php
@@ -3,6 +3,10 @@
namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\AbstractOracleDriver;
+use Doctrine\DBAL\Driver\OCI8\Exception\ConnectionFailed;
+
+use function oci_connect;
+use function oci_pconnect;
use const OCI_NO_AUTO_COMMIT;
@@ -18,25 +22,23 @@ final class Driver extends AbstractOracleDriver
*/
public function connect(array $params)
{
- return new Connection(
- $params['user'] ?? '',
- $params['password'] ?? '',
- $this->_constructDsn($params),
- $params['charset'] ?? '',
- $params['sessionMode'] ?? OCI_NO_AUTO_COMMIT,
- $params['persistent'] ?? false
- );
- }
+ $username = $params['user'] ?? '';
+ $password = $params['password'] ?? '';
+ $charset = $params['charset'] ?? '';
+ $sessionMode = $params['sessionMode'] ?? OCI_NO_AUTO_COMMIT;
- /**
- * Constructs the Oracle DSN.
- *
- * @param mixed[] $params
- *
- * @return string The DSN.
- */
- protected function _constructDsn(array $params)
- {
- return $this->getEasyConnectString($params);
+ $connectionString = $this->getEasyConnectString($params);
+
+ if (! empty($params['persistent'])) {
+ $connection = @oci_pconnect($username, $password, $connectionString, $charset, $sessionMode);
+ } else {
+ $connection = @oci_connect($username, $password, $connectionString, $charset, $sessionMode);
+ }
+
+ if ($connection === false) {
+ throw ConnectionFailed::new();
+ }
+
+ return new Connection($connection);
}
}
diff --git a/doctrine/dbal/src/Driver/OCI8/Statement.php b/doctrine/dbal/src/Driver/OCI8/Statement.php
index 56602a36..8caa9f28 100644
--- a/doctrine/dbal/src/Driver/OCI8/Statement.php
+++ b/doctrine/dbal/src/Driver/OCI8/Statement.php
@@ -2,21 +2,16 @@
namespace Doctrine\DBAL\Driver\OCI8;
-use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\OCI8\Exception\Error;
use Doctrine\DBAL\Driver\OCI8\Exception\UnknownParameterIndex;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
-use Doctrine\DBAL\SQL\Parser;
-use function assert;
use function is_int;
-use function is_resource;
use function oci_bind_by_name;
use function oci_execute;
use function oci_new_descriptor;
-use function oci_parse;
use const OCI_B_BIN;
use const OCI_B_BLOB;
@@ -29,84 +24,62 @@ use const SQLT_CHR;
final class Statement implements StatementInterface
{
/** @var resource */
- protected $_dbh;
+ private $connection;
/** @var resource */
- protected $_sth;
+ private $statement;
+
+ /** @var array<int,string> */
+ private $parameterMap;
/** @var ExecutionMode */
private $executionMode;
- /** @var string[] */
- protected $_paramMap = [];
-
- /**
- * Holds references to bound parameter values.
- *
- * This is a new requirement for PHP7's oci8 extension that prevents bound values from being garbage collected.
- *
- * @var mixed[]
- */
- private $boundValues = [];
-
/**
- * Creates a new OCI8Statement that uses the given connection handle and SQL statement.
- *
* @internal The statement can be only instantiated by its driver connection.
*
- * @param resource $dbh The connection handle.
- * @param string $query The SQL query.
- *
- * @throws Exception
+ * @param resource $connection
+ * @param resource $statement
+ * @param array<int,string> $parameterMap
*/
- public function __construct($dbh, $query, ExecutionMode $executionMode)
+ public function __construct($connection, $statement, array $parameterMap, ExecutionMode $executionMode)
{
- $parser = new Parser(false);
- $visitor = new ConvertPositionalToNamedPlaceholders();
-
- $parser->parse($query, $visitor);
-
- $stmt = oci_parse($dbh, $visitor->getSQL());
- assert(is_resource($stmt));
-
- $this->_sth = $stmt;
- $this->_dbh = $dbh;
- $this->_paramMap = $visitor->getParameterMap();
+ $this->connection = $connection;
+ $this->statement = $statement;
+ $this->parameterMap = $parameterMap;
$this->executionMode = $executionMode;
}
/**
* {@inheritdoc}
*/
- public function bindValue($param, $value, $type = ParameterType::STRING)
+ public function bindValue($param, $value, $type = ParameterType::STRING): bool
{
- return $this->bindParam($param, $value, $type, null);
+ return $this->bindParam($param, $value, $type);
}
/**
* {@inheritdoc}
*/
- public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
+ public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool
{
if (is_int($param)) {
- if (! isset($this->_paramMap[$param])) {
+ if (! isset($this->parameterMap[$param])) {
throw UnknownParameterIndex::new($param);
}
- $param = $this->_paramMap[$param];
+ $param = $this->parameterMap[$param];
}
if ($type === ParameterType::LARGE_OBJECT) {
- $lob = oci_new_descriptor($this->_dbh, OCI_D_LOB);
+ $lob = oci_new_descriptor($this->connection, OCI_D_LOB);
$lob->writeTemporary($variable, OCI_TEMP_BLOB);
$variable =& $lob;
}
- $this->boundValues[$param] =& $variable;
-
return oci_bind_by_name(
- $this->_sth,
+ $this->statement,
$param,
$variable,
$length ?? -1,
@@ -152,11 +125,11 @@ final class Statement implements StatementInterface
$mode = OCI_NO_AUTO_COMMIT;
}
- $ret = @oci_execute($this->_sth, $mode);
+ $ret = @oci_execute($this->statement, $mode);
if (! $ret) {
- throw Error::new($this->_sth);
+ throw Error::new($this->statement);
}
- return new Result($this->_sth);
+ return new Result($this->statement);
}
}
diff --git a/doctrine/dbal/src/Driver/PDO/Connection.php b/doctrine/dbal/src/Driver/PDO/Connection.php
index 16901693..505acba5 100644
--- a/doctrine/dbal/src/Driver/PDO/Connection.php
+++ b/doctrine/dbal/src/Driver/PDO/Connection.php
@@ -2,11 +2,11 @@
namespace Doctrine\DBAL\Driver\PDO;
-use Doctrine\DBAL\Driver\Exception as ExceptionInterface;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
+use Doctrine\Deprecations\Deprecation;
use PDO;
use PDOException;
use PDOStatement;
@@ -20,22 +20,12 @@ final class Connection implements ServerInfoAwareConnection
/**
* @internal The connection can be only instantiated by its driver.
- *
- * @param string $dsn
- * @param string|null $user
- * @param string|null $password
- * @param mixed[]|null $options
- *
- * @throws ExceptionInterface
*/
- public function __construct($dsn, $user = null, $password = null, ?array $options = null)
+ public function __construct(PDO $connection)
{
- try {
- $this->connection = new PDO($dsn, (string) $user, (string) $password, (array) $options);
- $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- } catch (PDOException $exception) {
- throw Exception::new($exception);
- }
+ $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+ $this->connection = $connection;
}
public function exec(string $sql): int
@@ -70,7 +60,7 @@ final class Connection implements ServerInfoAwareConnection
$stmt = $this->connection->prepare($sql);
assert($stmt instanceof PDOStatement);
- return $this->createStatement($stmt);
+ return new Statement($stmt);
} catch (PDOException $exception) {
throw Exception::new($exception);
}
@@ -106,46 +96,50 @@ final class Connection implements ServerInfoAwareConnection
return $this->connection->lastInsertId();
}
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4687',
+ 'The usage of Connection::lastInsertId() with a sequence name is deprecated.'
+ );
+
return $this->connection->lastInsertId($name);
} catch (PDOException $exception) {
throw Exception::new($exception);
}
}
- /**
- * Creates a wrapped statement
- */
- protected function createStatement(PDOStatement $stmt): Statement
- {
- return new Statement($stmt);
- }
-
- /**
- * {@inheritDoc}
- */
- public function beginTransaction()
+ public function beginTransaction(): bool
{
return $this->connection->beginTransaction();
}
- /**
- * {@inheritDoc}
- */
- public function commit()
+ public function commit(): bool
{
return $this->connection->commit();
}
- /**
- * {@inheritDoc}
- */
- public function rollBack()
+ public function rollBack(): bool
{
return $this->connection->rollBack();
}
- public function getWrappedConnection(): PDO
+ public function getNativeConnection(): PDO
{
return $this->connection;
}
+
+ /**
+ * @deprecated Call {@see getNativeConnection()} instead.
+ */
+ public function getWrappedConnection(): PDO
+ {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/5037',
+ '%s is deprecated, call getNativeConnection() instead.',
+ __METHOD__
+ );
+
+ return $this->getNativeConnection();
+ }
}
diff --git a/doctrine/dbal/src/Driver/PDO/Exception.php b/doctrine/dbal/src/Driver/PDO/Exception.php
index 49f55951..7036a0e4 100644
--- a/doctrine/dbal/src/Driver/PDO/Exception.php
+++ b/doctrine/dbal/src/Driver/PDO/Exception.php
@@ -18,6 +18,10 @@ final class Exception extends AbstractException
{
if ($exception->errorInfo !== null) {
[$sqlState, $code] = $exception->errorInfo;
+
+ if ($code === null) {
+ $code = 0;
+ }
} else {
$code = $exception->getCode();
$sqlState = null;
diff --git a/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php b/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php
index 50c05a40..8aeb2696 100644
--- a/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php
+++ b/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php
@@ -4,7 +4,9 @@ namespace Doctrine\DBAL\Driver\PDO\MySQL;
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
use Doctrine\DBAL\Driver\PDO\Connection;
+use Doctrine\DBAL\Driver\PDO\Exception;
use PDO;
+use PDOException;
final class Driver extends AbstractMySQLDriver
{
@@ -21,22 +23,26 @@ final class Driver extends AbstractMySQLDriver
$driverOptions[PDO::ATTR_PERSISTENT] = true;
}
- return new Connection(
- $this->constructPdoDsn($params),
- $params['user'] ?? '',
- $params['password'] ?? '',
- $driverOptions
- );
+ try {
+ $pdo = new PDO(
+ $this->constructPdoDsn($params),
+ $params['user'] ?? '',
+ $params['password'] ?? '',
+ $driverOptions
+ );
+ } catch (PDOException $exception) {
+ throw Exception::new($exception);
+ }
+
+ return new Connection($pdo);
}
/**
* Constructs the MySQL PDO DSN.
*
* @param mixed[] $params
- *
- * @return string The DSN.
*/
- protected function constructPdoDsn(array $params)
+ private function constructPdoDsn(array $params): string
{
$dsn = 'mysql:';
if (isset($params['host']) && $params['host'] !== '') {
diff --git a/doctrine/dbal/src/Driver/PDO/OCI/Driver.php b/doctrine/dbal/src/Driver/PDO/OCI/Driver.php
index a2c1f465..705db611 100644
--- a/doctrine/dbal/src/Driver/PDO/OCI/Driver.php
+++ b/doctrine/dbal/src/Driver/PDO/OCI/Driver.php
@@ -4,7 +4,9 @@ namespace Doctrine\DBAL\Driver\PDO\OCI;
use Doctrine\DBAL\Driver\AbstractOracleDriver;
use Doctrine\DBAL\Driver\PDO\Connection;
+use Doctrine\DBAL\Driver\PDO\Exception;
use PDO;
+use PDOException;
final class Driver extends AbstractOracleDriver
{
@@ -21,22 +23,26 @@ final class Driver extends AbstractOracleDriver
$driverOptions[PDO::ATTR_PERSISTENT] = true;
}
- return new Connection(
- $this->constructPdoDsn($params),
- $params['user'] ?? '',
- $params['password'] ?? '',
- $driverOptions
- );
+ try {
+ $pdo = new PDO(
+ $this->constructPdoDsn($params),
+ $params['user'] ?? '',
+ $params['password'] ?? '',
+ $driverOptions
+ );
+ } catch (PDOException $exception) {
+ throw Exception::new($exception);
+ }
+
+ return new Connection($pdo);
}
/**
* Constructs the Oracle PDO DSN.
*
* @param mixed[] $params
- *
- * @return string The DSN.
*/
- private function constructPdoDsn(array $params)
+ private function constructPdoDsn(array $params): string
{
$dsn = 'oci:dbname=' . $this->getEasyConnectString($params);
diff --git a/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php b/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php
index e9620bde..b90e4726 100644
--- a/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php
+++ b/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php
@@ -4,9 +4,9 @@ namespace Doctrine\DBAL\Driver\PDO\PgSQL;
use Doctrine\DBAL\Driver\AbstractPostgreSQLDriver;
use Doctrine\DBAL\Driver\PDO\Connection;
+use Doctrine\DBAL\Driver\PDO\Exception;
use PDO;
-
-use function defined;
+use PDOException;
final class Driver extends AbstractPostgreSQLDriver
{
@@ -23,24 +23,27 @@ final class Driver extends AbstractPostgreSQLDriver
$driverOptions[PDO::ATTR_PERSISTENT] = true;
}
- $connection = new Connection(
- $this->_constructPdoDsn($params),
- $params['user'] ?? '',
- $params['password'] ?? '',
- $driverOptions,
- );
+ try {
+ $pdo = new PDO(
+ $this->constructPdoDsn($params),
+ $params['user'] ?? '',
+ $params['password'] ?? '',
+ $driverOptions
+ );
+ } catch (PDOException $exception) {
+ throw Exception::new($exception);
+ }
if (
- defined('PDO::PGSQL_ATTR_DISABLE_PREPARES')
- && (! isset($driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES])
- || $driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES] === true
- )
+ ! isset($driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES])
+ || $driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES] === true
) {
- $connection->getWrappedConnection()->setAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES, true);
+ $pdo->setAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES, true);
}
+ $connection = new Connection($pdo);
+
/* defining client_encoding via SET NAMES to avoid inconsistent DSN support
- * - the 'client_encoding' connection param only works with postgres >= 9.1
* - passing client_encoding via the 'options' param breaks pgbouncer support
*/
if (isset($params['charset'])) {
@@ -54,10 +57,8 @@ final class Driver extends AbstractPostgreSQLDriver
* Constructs the Postgres PDO DSN.
*
* @param mixed[] $params
- *
- * @return string The DSN.
*/
- private function _constructPdoDsn(array $params)
+ private function constructPdoDsn(array $params): string
{
$dsn = 'pgsql:';
diff --git a/doctrine/dbal/src/Driver/PDO/Result.php b/doctrine/dbal/src/Driver/PDO/Result.php
index 888716d8..b0efdf2e 100644
--- a/doctrine/dbal/src/Driver/PDO/Result.php
+++ b/doctrine/dbal/src/Driver/PDO/Result.php
@@ -9,9 +9,6 @@ use PDO;
use PDOException;
use PDOStatement;
-use function assert;
-use function is_array;
-
final class Result implements ResultInterface
{
/** @var PDOStatement */
@@ -118,13 +115,9 @@ final class Result implements ResultInterface
private function fetchAll(int $mode): array
{
try {
- $data = $this->statement->fetchAll($mode);
+ return $this->statement->fetchAll($mode);
} catch (PDOException $exception) {
throw Exception::new($exception);
}
-
- assert(is_array($data));
-
- return $data;
}
}
diff --git a/doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php b/doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php
index a64f4245..0c34d4b9 100644
--- a/doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php
+++ b/doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php
@@ -2,20 +2,21 @@
namespace Doctrine\DBAL\Driver\PDO\SQLSrv;
+use Doctrine\DBAL\Driver\Middleware\AbstractConnectionMiddleware;
use Doctrine\DBAL\Driver\PDO\Connection as PDOConnection;
-use Doctrine\DBAL\Driver\Result;
-use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
-use Doctrine\DBAL\ParameterType;
+use Doctrine\Deprecations\Deprecation;
use PDO;
-final class Connection implements ServerInfoAwareConnection
+final class Connection extends AbstractConnectionMiddleware
{
/** @var PDOConnection */
private $connection;
public function __construct(PDOConnection $connection)
{
+ parent::__construct($connection);
+
$this->connection = $connection;
}
@@ -26,72 +27,43 @@ final class Connection implements ServerInfoAwareConnection
);
}
- public function query(string $sql): Result
- {
- return $this->connection->query($sql);
- }
-
- /**
- * {@inheritDoc}
- */
- public function quote($value, $type = ParameterType::STRING)
- {
- return $this->connection->quote($value, $type);
- }
-
- public function exec(string $sql): int
- {
- return $this->connection->exec($sql);
- }
-
/**
* {@inheritDoc}
*/
public function lastInsertId($name = null)
{
if ($name === null) {
- return $this->connection->lastInsertId($name);
+ return parent::lastInsertId($name);
}
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4687',
+ 'The usage of Connection::lastInsertId() with a sequence name is deprecated.'
+ );
+
return $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?')
->execute([$name])
->fetchOne();
}
- /**
- * {@inheritDoc}
- */
- public function beginTransaction()
- {
- return $this->connection->beginTransaction();
- }
-
- /**
- * {@inheritDoc}
- */
- public function commit()
- {
- return $this->connection->commit();
- }
-
- /**
- * {@inheritDoc}
- */
- public function rollBack()
+ public function getNativeConnection(): PDO
{
- return $this->connection->rollBack();
+ return $this->connection->getNativeConnection();
}
/**
- * {@inheritDoc}
+ * @deprecated Call {@see getNativeConnection()} instead.
*/
- public function getServerVersion()
- {
- return $this->connection->getServerVersion();
- }
-
public function getWrappedConnection(): PDO
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/5037',
+ '%s is deprecated, call getNativeConnection() instead.',
+ __METHOD__
+ );
+
return $this->connection->getWrappedConnection();
}
}
diff --git a/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php b/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php
index c4842504..b664950f 100644
--- a/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php
+++ b/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php
@@ -6,6 +6,7 @@ use Doctrine\DBAL\Driver\AbstractSQLServerDriver;
use Doctrine\DBAL\Driver\AbstractSQLServerDriver\Exception\PortWithoutHost;
use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\PDO\Connection as PDOConnection;
+use Doctrine\DBAL\Driver\PDO\Exception as PDOException;
use PDO;
use function is_int;
@@ -20,12 +21,12 @@ final class Driver extends AbstractSQLServerDriver
*/
public function connect(array $params)
{
- $pdoOptions = $dsnOptions = [];
+ $driverOptions = $dsnOptions = [];
if (isset($params['driverOptions'])) {
foreach ($params['driverOptions'] as $option => $value) {
if (is_int($option)) {
- $pdoOptions[$option] = $value;
+ $driverOptions[$option] = $value;
} else {
$dsnOptions[$option] = $value;
}
@@ -33,17 +34,21 @@ final class Driver extends AbstractSQLServerDriver
}
if (! empty($params['persistent'])) {
- $pdoOptions[PDO::ATTR_PERSISTENT] = true;
+ $driverOptions[PDO::ATTR_PERSISTENT] = true;
}
- return new Connection(
- new PDOConnection(
- $this->_constructPdoDsn($params, $dsnOptions),
+ try {
+ $pdo = new PDO(
+ $this->constructDsn($params, $dsnOptions),
$params['user'] ?? '',
$params['password'] ?? '',
- $pdoOptions
- )
- );
+ $driverOptions
+ );
+ } catch (\PDOException $exception) {
+ throw PDOException::new($exception);
+ }
+
+ return new Connection(new PDOConnection($pdo));
}
/**
@@ -52,11 +57,9 @@ final class Driver extends AbstractSQLServerDriver
* @param mixed[] $params
* @param string[] $connectionOptions
*
- * @return string The DSN.
- *
* @throws Exception
*/
- private function _constructPdoDsn(array $params, array $connectionOptions)
+ private function constructDsn(array $params, array $connectionOptions): string
{
$dsn = 'sqlsrv:server=';
diff --git a/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php b/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php
index 2f48874e..43b07a3a 100644
--- a/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php
+++ b/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php
@@ -2,16 +2,15 @@
namespace Doctrine\DBAL\Driver\PDO\SQLSrv;
+use Doctrine\DBAL\Driver\Middleware\AbstractStatementMiddleware;
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
+final class Statement extends AbstractStatementMiddleware
{
/** @var PDOStatement */
private $statement;
@@ -21,6 +20,8 @@ final class Statement implements StatementInterface
*/
public function __construct(PDOStatement $statement)
{
+ parent::__construct($statement);
+
$this->statement = $statement;
}
@@ -33,8 +34,13 @@ final class Statement implements StatementInterface
* @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)
- {
+ public function bindParam(
+ $param,
+ &$variable,
+ $type = ParameterType::STRING,
+ $length = null,
+ $driverOptions = null
+ ): bool {
if (func_num_args() > 4) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
@@ -65,16 +71,8 @@ final class Statement implements StatementInterface
/**
* {@inheritdoc}
*/
- public function bindValue($param, $value, $type = ParameterType::STRING)
+ public function bindValue($param, $value, $type = ParameterType::STRING): bool
{
return $this->bindParam($param, $value, $type);
}
-
- /**
- * {@inheritdoc}
- */
- public function execute($params = null): Result
- {
- return $this->statement->execute($params);
- }
}
diff --git a/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php b/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php
index d85ba28f..5e72de08 100644
--- a/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php
+++ b/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php
@@ -4,14 +4,17 @@ namespace Doctrine\DBAL\Driver\PDO\SQLite;
use Doctrine\DBAL\Driver\AbstractSQLiteDriver;
use Doctrine\DBAL\Driver\PDO\Connection;
+use Doctrine\DBAL\Driver\PDO\Exception;
use Doctrine\DBAL\Platforms\SqlitePlatform;
+use PDO;
+use PDOException;
use function array_merge;
final class Driver extends AbstractSQLiteDriver
{
/** @var mixed[] */
- protected $_userDefinedFunctions = [
+ private $userDefinedFunctions = [
'sqrt' => ['callback' => [SqlitePlatform::class, 'udfSqrt'], 'numArgs' => 1],
'mod' => ['callback' => [SqlitePlatform::class, 'udfMod'], 'numArgs' => 2],
'locate' => ['callback' => [SqlitePlatform::class, 'udfLocate'], 'numArgs' => -1],
@@ -27,37 +30,37 @@ final class Driver extends AbstractSQLiteDriver
$driverOptions = $params['driverOptions'] ?? [];
if (isset($driverOptions['userDefinedFunctions'])) {
- $this->_userDefinedFunctions = array_merge(
- $this->_userDefinedFunctions,
+ $this->userDefinedFunctions = array_merge(
+ $this->userDefinedFunctions,
$driverOptions['userDefinedFunctions']
);
unset($driverOptions['userDefinedFunctions']);
}
- $connection = new Connection(
- $this->_constructPdoDsn($params),
- $params['user'] ?? '',
- $params['password'] ?? '',
- $driverOptions
- );
-
- $pdo = $connection->getWrappedConnection();
+ try {
+ $pdo = new PDO(
+ $this->constructPdoDsn($params),
+ $params['user'] ?? '',
+ $params['password'] ?? '',
+ $driverOptions
+ );
+ } catch (PDOException $exception) {
+ throw Exception::new($exception);
+ }
- foreach ($this->_userDefinedFunctions as $fn => $data) {
+ foreach ($this->userDefinedFunctions as $fn => $data) {
$pdo->sqliteCreateFunction($fn, $data['callback'], $data['numArgs']);
}
- return $connection;
+ return new Connection($pdo);
}
/**
* Constructs the Sqlite PDO DSN.
*
* @param mixed[] $params
- *
- * @return string The DSN.
*/
- protected function _constructPdoDsn(array $params)
+ private function constructPdoDsn(array $params): string
{
$dsn = 'sqlite:';
if (isset($params['path'])) {
diff --git a/doctrine/dbal/src/Driver/PDO/Statement.php b/doctrine/dbal/src/Driver/PDO/Statement.php
index 1461239e..bb137708 100644
--- a/doctrine/dbal/src/Driver/PDO/Statement.php
+++ b/doctrine/dbal/src/Driver/PDO/Statement.php
@@ -61,11 +61,14 @@ final class Statement implements StatementInterface
* @param int $type
* @param int|null $length
* @param mixed $driverOptions The usage of the argument is deprecated.
- *
- * @return bool
*/
- public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
- {
+ public function bindParam(
+ $param,
+ &$variable,
+ $type = ParameterType::STRING,
+ $length = null,
+ $driverOptions = null
+ ): bool {
if (func_num_args() > 4) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
@@ -77,7 +80,13 @@ final class Statement implements StatementInterface
$type = $this->convertParamType($type);
try {
- return $this->stmt->bindParam($param, $variable, $type, ...array_slice(func_get_args(), 3));
+ return $this->stmt->bindParam(
+ $param,
+ $variable,
+ $type,
+ $length ?? 0,
+ ...array_slice(func_get_args(), 4)
+ );
} catch (PDOException $exception) {
throw Exception::new($exception);
}
diff --git a/doctrine/dbal/src/Driver/SQLSrv/Connection.php b/doctrine/dbal/src/Driver/SQLSrv/Connection.php
index e37ea900..0295db7e 100644
--- a/doctrine/dbal/src/Driver/SQLSrv/Connection.php
+++ b/doctrine/dbal/src/Driver/SQLSrv/Connection.php
@@ -2,20 +2,18 @@
namespace Doctrine\DBAL\Driver\SQLSrv;
-use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Driver\SQLSrv\Exception\Error;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
use Doctrine\DBAL\ParameterType;
+use Doctrine\Deprecations\Deprecation;
use function is_float;
use function is_int;
use function sprintf;
use function sqlsrv_begin_transaction;
use function sqlsrv_commit;
-use function sqlsrv_configure;
-use function sqlsrv_connect;
use function sqlsrv_query;
use function sqlsrv_rollback;
use function sqlsrv_rows_affected;
@@ -25,29 +23,16 @@ use function str_replace;
final class Connection implements ServerInfoAwareConnection
{
/** @var resource */
- protected $conn;
+ private $connection;
/**
* @internal The connection can be only instantiated by its driver.
*
- * @param string $serverName
- * @param mixed[] $connectionOptions
- *
- * @throws Exception
+ * @param resource $connection
*/
- public function __construct($serverName, $connectionOptions)
+ public function __construct($connection)
{
- if (! sqlsrv_configure('WarningsReturnAsErrors', 0)) {
- throw Error::new();
- }
-
- $conn = sqlsrv_connect($serverName, $connectionOptions);
-
- if ($conn === false) {
- throw Error::new();
- }
-
- $this->conn = $conn;
+ $this->connection = $connection;
}
/**
@@ -55,14 +40,14 @@ final class Connection implements ServerInfoAwareConnection
*/
public function getServerVersion()
{
- $serverInfo = sqlsrv_server_info($this->conn);
+ $serverInfo = sqlsrv_server_info($this->connection);
return $serverInfo['SQLServerVersion'];
}
public function prepare(string $sql): DriverStatement
{
- return new Statement($this->conn, $sql);
+ return new Statement($this->connection, $sql);
}
public function query(string $sql): ResultInterface
@@ -88,7 +73,7 @@ final class Connection implements ServerInfoAwareConnection
public function exec(string $sql): int
{
- $stmt = sqlsrv_query($this->conn, $sql);
+ $stmt = sqlsrv_query($this->connection, $sql);
if ($stmt === false) {
throw Error::new();
@@ -109,6 +94,12 @@ final class Connection implements ServerInfoAwareConnection
public function lastInsertId($name = null)
{
if ($name !== null) {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4687',
+ 'The usage of Connection::lastInsertId() with a sequence name is deprecated.'
+ );
+
$result = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?')
->execute([$name]);
} else {
@@ -118,39 +109,38 @@ final class Connection implements ServerInfoAwareConnection
return $result->fetchOne();
}
- /**
- * {@inheritDoc}
- */
- public function beginTransaction()
+ public function beginTransaction(): bool
{
- if (! sqlsrv_begin_transaction($this->conn)) {
+ if (! sqlsrv_begin_transaction($this->connection)) {
throw Error::new();
}
return true;
}
- /**
- * {@inheritDoc}
- */
- public function commit()
+ public function commit(): bool
{
- if (! sqlsrv_commit($this->conn)) {
+ if (! sqlsrv_commit($this->connection)) {
throw Error::new();
}
return true;
}
- /**
- * {@inheritDoc}
- */
- public function rollBack()
+ public function rollBack(): bool
{
- if (! sqlsrv_rollback($this->conn)) {
+ if (! sqlsrv_rollback($this->connection)) {
throw Error::new();
}
return true;
}
+
+ /**
+ * @return resource
+ */
+ public function getNativeConnection()
+ {
+ return $this->connection;
+ }
}
diff --git a/doctrine/dbal/src/Driver/SQLSrv/Driver.php b/doctrine/dbal/src/Driver/SQLSrv/Driver.php
index efa9ccfe..085b2241 100644
--- a/doctrine/dbal/src/Driver/SQLSrv/Driver.php
+++ b/doctrine/dbal/src/Driver/SQLSrv/Driver.php
@@ -4,6 +4,10 @@ namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\AbstractSQLServerDriver;
use Doctrine\DBAL\Driver\AbstractSQLServerDriver\Exception\PortWithoutHost;
+use Doctrine\DBAL\Driver\SQLSrv\Exception\Error;
+
+use function sqlsrv_configure;
+use function sqlsrv_connect;
/**
* Driver for ext/sqlsrv.
@@ -51,6 +55,16 @@ final class Driver extends AbstractSQLServerDriver
$driverOptions['ReturnDatesAsStrings'] = 1;
}
- return new Connection($serverName, $driverOptions);
+ if (! sqlsrv_configure('WarningsReturnAsErrors', 0)) {
+ throw Error::new();
+ }
+
+ $connection = sqlsrv_connect($serverName, $driverOptions);
+
+ if ($connection === false) {
+ throw Error::new();
+ }
+
+ return new Connection($connection);
}
}
diff --git a/doctrine/dbal/src/Driver/SQLSrv/Statement.php b/doctrine/dbal/src/Driver/SQLSrv/Statement.php
index 8267bc0d..035567a3 100644
--- a/doctrine/dbal/src/Driver/SQLSrv/Statement.php
+++ b/doctrine/dbal/src/Driver/SQLSrv/Statement.php
@@ -47,14 +47,14 @@ final class Statement implements StatementInterface
/**
* References to the variables bound as statement parameters.
*
- * @var mixed
+ * @var array<int, mixed>
*/
private $variables = [];
/**
* Bound parameter types.
*
- * @var int[]
+ * @var array<int, int>
*/
private $types = [];
@@ -84,7 +84,7 @@ final class Statement implements StatementInterface
/**
* {@inheritdoc}
*/
- public function bindValue($param, $value, $type = ParameterType::STRING)
+ public function bindValue($param, $value, $type = ParameterType::STRING): bool
{
assert(is_int($param));
@@ -97,7 +97,7 @@ final class Statement implements StatementInterface
/**
* {@inheritdoc}
*/
- public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
+ public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool
{
assert(is_int($param));
diff --git a/doctrine/dbal/src/Driver/ServerInfoAwareConnection.php b/doctrine/dbal/src/Driver/ServerInfoAwareConnection.php
index 622f98c6..5687ab0b 100644
--- a/doctrine/dbal/src/Driver/ServerInfoAwareConnection.php
+++ b/doctrine/dbal/src/Driver/ServerInfoAwareConnection.php
@@ -4,11 +4,14 @@ namespace Doctrine\DBAL\Driver;
/**
* Contract for a connection that is able to provide information about the server it is connected to.
+ *
+ * @deprecated The methods defined in this interface will be made part of the {@see Driver} interface
+ * in the next major release.
*/
interface ServerInfoAwareConnection extends Connection
{
/**
- * Returns the version number of the database server connected to.
+ * Returns information about the version of the database server connected to.
*
* @return string
*
diff --git a/doctrine/dbal/src/Driver/Statement.php b/doctrine/dbal/src/Driver/Statement.php
index 334634a8..50fac842 100644
--- a/doctrine/dbal/src/Driver/Statement.php
+++ b/doctrine/dbal/src/Driver/Statement.php
@@ -20,7 +20,7 @@ interface Statement
* this will be a parameter name of the form :name. For a prepared statement
* using question mark placeholders, this will be the 1-indexed position of the parameter.
* @param mixed $value The value to bind to the parameter.
- * @param int $type Explicit data type for the parameter using the {@link ParameterType}
+ * @param int $type Explicit data type for the parameter using the {@see ParameterType}
* constants.
*
* @return bool TRUE on success or FALSE on failure.
@@ -31,7 +31,7 @@ interface Statement
/**
* Binds a PHP variable to a corresponding named (not supported by mysqli driver, see comment below) or question
- * mark placeholder in the SQL statement that was use to prepare the statement. Unlike {@link bindValue()},
+ * mark placeholder in the SQL statement that was use to prepare the statement. Unlike {@see bindValue()},
* the variable is bound as a reference and will only be evaluated at the time
* that PDOStatement->execute() is called.
*
@@ -47,7 +47,7 @@ interface Statement
* this will be a parameter name of the form :name. For a prepared statement using
* question mark placeholders, this will be the 1-indexed position of the parameter.
* @param mixed $variable Name of the PHP variable to bind to the SQL statement parameter.
- * @param int $type Explicit data type for the parameter using the {@link ParameterType}
+ * @param int $type Explicit data type for the parameter using the {@see ParameterType}
* constants.
* @param int|null $length You must specify maxlength when using an OUT bind
* so that PHP allocates enough memory to hold the returned value.
@@ -62,7 +62,7 @@ interface Statement
* Executes a prepared statement
*
* If the prepared statement included parameter markers, you must either:
- * call {@link bindParam()} to bind PHP variables to the parameter markers:
+ * call {@see bindParam()} to bind PHP variables to the parameter markers:
* bound variables pass their value as input and receive the output value,
* if any, of their associated parameter markers or pass an array of input-only
* parameter values.
diff --git a/doctrine/dbal/src/DriverManager.php b/doctrine/dbal/src/DriverManager.php
index 698e0438..a2ed2361 100644
--- a/doctrine/dbal/src/DriverManager.php
+++ b/doctrine/dbal/src/DriverManager.php
@@ -24,7 +24,7 @@ use function strpos;
use function substr;
/**
- * Factory for creating {@link Connection} instances.
+ * Factory for creating {@see Connection} instances.
*
* @psalm-type OverrideParams = array{
* charset?: string,
@@ -40,10 +40,12 @@ use function substr;
* platform?: Platforms\AbstractPlatform,
* port?: int,
* user?: string,
+ * unix_socket?: string,
* }
* @psalm-type Params = array{
* charset?: string,
* dbname?: string,
+ * defaultTableOptions?: array<string, mixed>,
* default_dbname?: string,
* driver?: key-of<self::DRIVER_MAP>,
* driverClass?: class-string<Driver>,
@@ -60,10 +62,12 @@ use function substr;
* port?: int,
* primary?: OverrideParams,
* replica?: array<OverrideParams>,
+ * serverVersion?: string,
* sharding?: array<string,mixed>,
* slaves?: array<OverrideParams>,
* user?: string,
* wrapperClass?: class-string<Connection>,
+ * unix_socket?: string,
* }
*/
final class DriverManager
@@ -71,7 +75,7 @@ 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 {@see DriverManager::getConnection()}.
*/
private const DRIVER_MAP = [
'pdo_mysql' => PDO\MySQL\Driver::class,
@@ -118,7 +122,7 @@ final class DriverManager
*
* $params must contain at least one of the following.
*
- * Either 'driver' with one of the array keys of {@link DRIVER_MAP},
+ * Either 'driver' with one of the array keys of {@see DRIVER_MAP},
* OR 'driverClass' that contains the full class name (with namespace) of the
* driver class to instantiate.
*
@@ -141,9 +145,8 @@ final class DriverManager
* <b>driverClass</b>:
* The driver class to use.
*
- * @param array<string,mixed> $params
- * @param Configuration|null $config The configuration to use.
- * @param EventManager|null $eventManager The event manager to use.
+ * @param Configuration|null $config The configuration to use.
+ * @param EventManager|null $eventManager The event manager to use.
* @psalm-param array{
* charset?: string,
* dbname?: string,
@@ -168,7 +171,6 @@ final class DriverManager
* user?: string,
* wrapperClass?: class-string<T>,
* } $params
- * @phpstan-param array<string,mixed> $params
*
* @psalm-return ($params is array{wrapperClass:mixed} ? T : Connection)
*
@@ -340,7 +342,7 @@ final class DriverManager
* Parses the given connection URL and resolves the given connection parameters.
*
* Assumes that the connection URL scheme is already parsed and resolved into the given connection parameters
- * via {@link parseDatabaseUrlScheme}.
+ * via {@see parseDatabaseUrlScheme}.
*
* @see parseDatabaseUrlScheme
*
@@ -394,7 +396,7 @@ final class DriverManager
/**
* Parses the given regular connection URL and resolves the given connection parameters.
*
- * Assumes that the "path" URL part is already normalized via {@link normalizeDatabaseUrlPath}.
+ * Assumes that the "path" URL part is already normalized via {@see normalizeDatabaseUrlPath}.
*
* @see normalizeDatabaseUrlPath
*
@@ -413,7 +415,7 @@ final class DriverManager
/**
* Parses the given SQLite connection URL and resolves the given connection parameters.
*
- * Assumes that the "path" URL part is already normalized via {@link normalizeDatabaseUrlPath}.
+ * Assumes that the "path" URL part is already normalized via {@see normalizeDatabaseUrlPath}.
*
* @see normalizeDatabaseUrlPath
*
diff --git a/doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php b/doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php
index e61a48d0..5a1160a9 100644
--- a/doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php
+++ b/doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php
@@ -12,7 +12,7 @@ use function func_get_args;
use function is_array;
/**
- * Event Arguments used when SQL queries for adding table columns are generated inside {@link AbstractPlatform}.
+ * Event Arguments used when SQL queries for adding table columns are generated inside {@see AbstractPlatform}.
*/
class SchemaAlterTableAddColumnEventArgs extends SchemaEventArgs
{
diff --git a/doctrine/dbal/src/Event/SchemaAlterTableChangeColumnEventArgs.php b/doctrine/dbal/src/Event/SchemaAlterTableChangeColumnEventArgs.php
index e9ebb66c..e3fe778d 100644
--- a/doctrine/dbal/src/Event/SchemaAlterTableChangeColumnEventArgs.php
+++ b/doctrine/dbal/src/Event/SchemaAlterTableChangeColumnEventArgs.php
@@ -11,7 +11,7 @@ use function func_get_args;
use function is_array;
/**
- * Event Arguments used when SQL queries for changing table columns are generated inside {@link AbstractPlatform}.
+ * Event Arguments used when SQL queries for changing table columns are generated inside {@see AbstractPlatform}.
*/
class SchemaAlterTableChangeColumnEventArgs extends SchemaEventArgs
{
diff --git a/doctrine/dbal/src/Event/SchemaAlterTableEventArgs.php b/doctrine/dbal/src/Event/SchemaAlterTableEventArgs.php
index 9c2b9b31..d51b4a20 100644
--- a/doctrine/dbal/src/Event/SchemaAlterTableEventArgs.php
+++ b/doctrine/dbal/src/Event/SchemaAlterTableEventArgs.php
@@ -10,7 +10,7 @@ use function func_get_args;
use function is_array;
/**
- * Event Arguments used when SQL queries for creating tables are generated inside {@link AbstractPlatform}.
+ * Event Arguments used when SQL queries for creating tables are generated inside {@see AbstractPlatform}.
*/
class SchemaAlterTableEventArgs extends SchemaEventArgs
{
diff --git a/doctrine/dbal/src/Event/SchemaAlterTableRemoveColumnEventArgs.php b/doctrine/dbal/src/Event/SchemaAlterTableRemoveColumnEventArgs.php
index d32af597..47ed242b 100644
--- a/doctrine/dbal/src/Event/SchemaAlterTableRemoveColumnEventArgs.php
+++ b/doctrine/dbal/src/Event/SchemaAlterTableRemoveColumnEventArgs.php
@@ -11,7 +11,7 @@ use function func_get_args;
use function is_array;
/**
- * Event Arguments used when SQL queries for removing table columns are generated inside {@link AbstractPlatform}.
+ * Event Arguments used when SQL queries for removing table columns are generated inside {@see AbstractPlatform}.
*/
class SchemaAlterTableRemoveColumnEventArgs extends SchemaEventArgs
{
diff --git a/doctrine/dbal/src/Event/SchemaAlterTableRenameColumnEventArgs.php b/doctrine/dbal/src/Event/SchemaAlterTableRenameColumnEventArgs.php
index 6d52b6c0..2b2cb220 100644
--- a/doctrine/dbal/src/Event/SchemaAlterTableRenameColumnEventArgs.php
+++ b/doctrine/dbal/src/Event/SchemaAlterTableRenameColumnEventArgs.php
@@ -11,7 +11,7 @@ use function func_get_args;
use function is_array;
/**
- * Event Arguments used when SQL queries for renaming table columns are generated inside {@link AbstractPlatform}.
+ * Event Arguments used when SQL queries for renaming table columns are generated inside {@see AbstractPlatform}.
*/
class SchemaAlterTableRenameColumnEventArgs extends SchemaEventArgs
{
diff --git a/doctrine/dbal/src/Event/SchemaColumnDefinitionEventArgs.php b/doctrine/dbal/src/Event/SchemaColumnDefinitionEventArgs.php
index 58efa7b5..997a90d1 100644
--- a/doctrine/dbal/src/Event/SchemaColumnDefinitionEventArgs.php
+++ b/doctrine/dbal/src/Event/SchemaColumnDefinitionEventArgs.php
@@ -6,7 +6,7 @@ use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\Column;
/**
- * Event Arguments used when the portable column definition is generated inside {@link AbstractPlatform}.
+ * Event Arguments used when the portable column definition is generated inside {@see AbstractPlatform}.
*/
class SchemaColumnDefinitionEventArgs extends SchemaEventArgs
{
diff --git a/doctrine/dbal/src/Event/SchemaCreateTableColumnEventArgs.php b/doctrine/dbal/src/Event/SchemaCreateTableColumnEventArgs.php
index 246d2de0..6ba1bc70 100644
--- a/doctrine/dbal/src/Event/SchemaCreateTableColumnEventArgs.php
+++ b/doctrine/dbal/src/Event/SchemaCreateTableColumnEventArgs.php
@@ -11,7 +11,7 @@ use function func_get_args;
use function is_array;
/**
- * Event Arguments used when SQL queries for creating table columns are generated inside {@link AbstractPlatform}.
+ * Event Arguments used when SQL queries for creating table columns are generated inside {@see AbstractPlatform}.
*/
class SchemaCreateTableColumnEventArgs extends SchemaEventArgs
{
diff --git a/doctrine/dbal/src/Event/SchemaCreateTableEventArgs.php b/doctrine/dbal/src/Event/SchemaCreateTableEventArgs.php
index e9829a64..d83f7a26 100644
--- a/doctrine/dbal/src/Event/SchemaCreateTableEventArgs.php
+++ b/doctrine/dbal/src/Event/SchemaCreateTableEventArgs.php
@@ -10,7 +10,7 @@ use function func_get_args;
use function is_array;
/**
- * Event Arguments used when SQL queries for creating tables are generated inside {@link AbstractPlatform}.
+ * Event Arguments used when SQL queries for creating tables are generated inside {@see AbstractPlatform}.
*/
class SchemaCreateTableEventArgs extends SchemaEventArgs
{
diff --git a/doctrine/dbal/src/Event/SchemaDropTableEventArgs.php b/doctrine/dbal/src/Event/SchemaDropTableEventArgs.php
index 072e1efb..3d5dd3c0 100644
--- a/doctrine/dbal/src/Event/SchemaDropTableEventArgs.php
+++ b/doctrine/dbal/src/Event/SchemaDropTableEventArgs.php
@@ -7,7 +7,7 @@ use Doctrine\DBAL\Schema\Table;
use InvalidArgumentException;
/**
- * Event Arguments used when the SQL query for dropping tables are generated inside {@link AbstractPlatform}.
+ * Event Arguments used when the SQL query for dropping tables are generated inside {@see AbstractPlatform}.
*/
class SchemaDropTableEventArgs extends SchemaEventArgs
{
diff --git a/doctrine/dbal/src/Event/SchemaIndexDefinitionEventArgs.php b/doctrine/dbal/src/Event/SchemaIndexDefinitionEventArgs.php
index 82c17a26..7e9f0db6 100644
--- a/doctrine/dbal/src/Event/SchemaIndexDefinitionEventArgs.php
+++ b/doctrine/dbal/src/Event/SchemaIndexDefinitionEventArgs.php
@@ -6,7 +6,7 @@ use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\Index;
/**
- * Event Arguments used when the portable index definition is generated inside {@link AbstractSchemaManager}.
+ * Event Arguments used when the portable index definition is generated inside {@see AbstractSchemaManager}.
*/
class SchemaIndexDefinitionEventArgs extends SchemaEventArgs
{
diff --git a/doctrine/dbal/src/Event/TransactionBeginEventArgs.php b/doctrine/dbal/src/Event/TransactionBeginEventArgs.php
new file mode 100644
index 00000000..946e8f2e
--- /dev/null
+++ b/doctrine/dbal/src/Event/TransactionBeginEventArgs.php
@@ -0,0 +1,9 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\DBAL\Event;
+
+class TransactionBeginEventArgs extends TransactionEventArgs
+{
+}
diff --git a/doctrine/dbal/src/Event/TransactionCommitEventArgs.php b/doctrine/dbal/src/Event/TransactionCommitEventArgs.php
new file mode 100644
index 00000000..c87d0575
--- /dev/null
+++ b/doctrine/dbal/src/Event/TransactionCommitEventArgs.php
@@ -0,0 +1,9 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\DBAL\Event;
+
+class TransactionCommitEventArgs extends TransactionEventArgs
+{
+}
diff --git a/doctrine/dbal/src/Event/TransactionEventArgs.php b/doctrine/dbal/src/Event/TransactionEventArgs.php
new file mode 100644
index 00000000..e56e214c
--- /dev/null
+++ b/doctrine/dbal/src/Event/TransactionEventArgs.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\DBAL\Event;
+
+use Doctrine\Common\EventArgs;
+use Doctrine\DBAL\Connection;
+
+abstract class TransactionEventArgs extends EventArgs
+{
+ /** @var Connection */
+ private $connection;
+
+ public function __construct(Connection $connection)
+ {
+ $this->connection = $connection;
+ }
+
+ public function getConnection(): Connection
+ {
+ return $this->connection;
+ }
+}
diff --git a/doctrine/dbal/src/Event/TransactionRollBackEventArgs.php b/doctrine/dbal/src/Event/TransactionRollBackEventArgs.php
new file mode 100644
index 00000000..607a5f94
--- /dev/null
+++ b/doctrine/dbal/src/Event/TransactionRollBackEventArgs.php
@@ -0,0 +1,9 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\DBAL\Event;
+
+class TransactionRollBackEventArgs extends TransactionEventArgs
+{
+}
diff --git a/doctrine/dbal/src/Events.php b/doctrine/dbal/src/Events.php
index de30815c..1c0b9559 100644
--- a/doctrine/dbal/src/Events.php
+++ b/doctrine/dbal/src/Events.php
@@ -30,4 +30,7 @@ final class Events
public const onSchemaAlterTableRenameColumn = 'onSchemaAlterTableRenameColumn';
public const onSchemaColumnDefinition = 'onSchemaColumnDefinition';
public const onSchemaIndexDefinition = 'onSchemaIndexDefinition';
+ public const onTransactionBegin = 'onTransactionBegin';
+ public const onTransactionCommit = 'onTransactionCommit';
+ public const onTransactionRollBack = 'onTransactionRollBack';
}
diff --git a/doctrine/dbal/src/Exception.php b/doctrine/dbal/src/Exception.php
index 56c4cc21..b8d7804d 100644
--- a/doctrine/dbal/src/Exception.php
+++ b/doctrine/dbal/src/Exception.php
@@ -110,11 +110,6 @@ class Exception extends \Exception
return new self('No columns specified for table ' . $tableName);
}
- public static function limitOffsetInvalid(): self
- {
- return new self('Invalid Offset in Limit Query, it has to be larger than or equal to 0.');
- }
-
public static function typeExists(string $name): self
{
return new self('Type ' . $name . ' already exists.');
diff --git a/doctrine/dbal/src/Exception/DatabaseDoesNotExist.php b/doctrine/dbal/src/Exception/DatabaseDoesNotExist.php
new file mode 100644
index 00000000..87eb1381
--- /dev/null
+++ b/doctrine/dbal/src/Exception/DatabaseDoesNotExist.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace Doctrine\DBAL\Exception;
+
+/**
+ * @psalm-immutable
+ */
+class DatabaseDoesNotExist extends DatabaseObjectNotFoundException
+{
+}
diff --git a/doctrine/dbal/src/Exception/SchemaDoesNotExist.php b/doctrine/dbal/src/Exception/SchemaDoesNotExist.php
new file mode 100644
index 00000000..cbb0658b
--- /dev/null
+++ b/doctrine/dbal/src/Exception/SchemaDoesNotExist.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace Doctrine\DBAL\Exception;
+
+/**
+ * @psalm-immutable
+ */
+class SchemaDoesNotExist extends DatabaseObjectNotFoundException
+{
+}
diff --git a/doctrine/dbal/src/ExpandArrayParameters.php b/doctrine/dbal/src/ExpandArrayParameters.php
index 063fd3f9..6c4e532a 100644
--- a/doctrine/dbal/src/ExpandArrayParameters.php
+++ b/doctrine/dbal/src/ExpandArrayParameters.php
@@ -100,7 +100,11 @@ final class ExpandArrayParameters implements Visitor
$type = $this->originalTypes[$key];
- if ($type !== Connection::PARAM_INT_ARRAY && $type !== Connection::PARAM_STR_ARRAY) {
+ if (
+ $type !== Connection::PARAM_INT_ARRAY
+ && $type !== Connection::PARAM_STR_ARRAY
+ && $type !== Connection::PARAM_ASCII_STR_ARRAY
+ ) {
$this->appendTypedParameter([$value], $type);
return;
diff --git a/doctrine/dbal/src/Id/TableGenerator.php b/doctrine/dbal/src/Id/TableGenerator.php
index 4058bcb6..d4f97fce 100644
--- a/doctrine/dbal/src/Id/TableGenerator.php
+++ b/doctrine/dbal/src/Id/TableGenerator.php
@@ -7,6 +7,7 @@ use Doctrine\DBAL\Driver;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\LockMode;
+use Doctrine\Deprecations\Deprecation;
use Throwable;
use function array_change_key_case;
@@ -51,6 +52,8 @@ use const CASE_LOWER;
*
* If no row is present for a given sequence a new one will be created with the
* default values 'value' = 1 and 'increment_by' = 1
+ *
+ * @deprecated
*/
class TableGenerator
{
@@ -70,6 +73,12 @@ class TableGenerator
*/
public function __construct(Connection $conn, $generatorTableName = 'sequences')
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4681',
+ 'The TableGenerator class is is deprecated.',
+ );
+
if ($conn->getDriver() instanceof Driver\PDO\SQLite\Driver) {
throw new Exception('Cannot use TableGenerator with SQLite.');
}
diff --git a/doctrine/dbal/src/Id/TableGeneratorSchemaVisitor.php b/doctrine/dbal/src/Id/TableGeneratorSchemaVisitor.php
index 3ec22f37..f47c9a91 100644
--- a/doctrine/dbal/src/Id/TableGeneratorSchemaVisitor.php
+++ b/doctrine/dbal/src/Id/TableGeneratorSchemaVisitor.php
@@ -9,7 +9,11 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\Visitor\Visitor;
+use Doctrine\Deprecations\Deprecation;
+/**
+ * @deprecated
+ */
class TableGeneratorSchemaVisitor implements Visitor
{
/** @var string */
@@ -20,6 +24,12 @@ class TableGeneratorSchemaVisitor implements Visitor
*/
public function __construct($generatorTableName = 'sequences')
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4681',
+ 'The TableGeneratorSchemaVisitor class is is deprecated.',
+ );
+
$this->generatorTableName = $generatorTableName;
}
diff --git a/doctrine/dbal/src/Logging/Connection.php b/doctrine/dbal/src/Logging/Connection.php
new file mode 100644
index 00000000..2175dc46
--- /dev/null
+++ b/doctrine/dbal/src/Logging/Connection.php
@@ -0,0 +1,85 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\DBAL\Logging;
+
+use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
+use Doctrine\DBAL\Driver\Middleware\AbstractConnectionMiddleware;
+use Doctrine\DBAL\Driver\Result;
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
+use Psr\Log\LoggerInterface;
+
+final class Connection extends AbstractConnectionMiddleware
+{
+ /** @var LoggerInterface */
+ private $logger;
+
+ /**
+ * @internal This connection can be only instantiated by its driver.
+ */
+ public function __construct(ConnectionInterface $connection, LoggerInterface $logger)
+ {
+ parent::__construct($connection);
+
+ $this->logger = $logger;
+ }
+
+ public function __destruct()
+ {
+ $this->logger->info('Disconnecting');
+ }
+
+ public function prepare(string $sql): DriverStatement
+ {
+ return new Statement(
+ parent::prepare($sql),
+ $this->logger,
+ $sql
+ );
+ }
+
+ public function query(string $sql): Result
+ {
+ $this->logger->debug('Executing query: {sql}', ['sql' => $sql]);
+
+ return parent::query($sql);
+ }
+
+ public function exec(string $sql): int
+ {
+ $this->logger->debug('Executing statement: {sql}', ['sql' => $sql]);
+
+ return parent::exec($sql);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function beginTransaction()
+ {
+ $this->logger->debug('Beginning transaction');
+
+ return parent::beginTransaction();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function commit()
+ {
+ $this->logger->debug('Committing transaction');
+
+ return parent::commit();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function rollBack()
+ {
+ $this->logger->debug('Rolling back transaction');
+
+ return parent::rollBack();
+ }
+}
diff --git a/doctrine/dbal/src/Logging/DebugStack.php b/doctrine/dbal/src/Logging/DebugStack.php
index 6a9fab5a..24a2d68c 100644
--- a/doctrine/dbal/src/Logging/DebugStack.php
+++ b/doctrine/dbal/src/Logging/DebugStack.php
@@ -2,10 +2,14 @@
namespace Doctrine\DBAL\Logging;
+use Doctrine\Deprecations\Deprecation;
+
use function microtime;
/**
* Includes executed SQLs in a Debug Stack.
+ *
+ * @deprecated
*/
class DebugStack implements SQLLogger
{
@@ -29,6 +33,15 @@ class DebugStack implements SQLLogger
/** @var int */
public $currentQuery = 0;
+ public function __construct()
+ {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4967',
+ 'DebugStack is deprecated.'
+ );
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/doctrine/dbal/src/Logging/Driver.php b/doctrine/dbal/src/Logging/Driver.php
new file mode 100644
index 00000000..533dcc05
--- /dev/null
+++ b/doctrine/dbal/src/Logging/Driver.php
@@ -0,0 +1,56 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\DBAL\Logging;
+
+use Doctrine\DBAL\Driver as DriverInterface;
+use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
+use Psr\Log\LoggerInterface;
+
+final class Driver extends AbstractDriverMiddleware
+{
+ /** @var LoggerInterface */
+ private $logger;
+
+ /**
+ * @internal This driver can be only instantiated by its middleware.
+ */
+ public function __construct(DriverInterface $driver, LoggerInterface $logger)
+ {
+ parent::__construct($driver);
+
+ $this->logger = $logger;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function connect(array $params)
+ {
+ $this->logger->info('Connecting with parameters {params}', ['params' => $this->maskPassword($params)]);
+
+ return new Connection(
+ parent::connect($params),
+ $this->logger
+ );
+ }
+
+ /**
+ * @param array<string,mixed> $params Connection parameters
+ *
+ * @return array<string,mixed>
+ */
+ private function maskPassword(array $params): array
+ {
+ if (isset($params['password'])) {
+ $params['password'] = '<redacted>';
+ }
+
+ if (isset($params['url'])) {
+ $params['url'] = '<redacted>';
+ }
+
+ return $params;
+ }
+}
diff --git a/doctrine/dbal/src/Logging/LoggerChain.php b/doctrine/dbal/src/Logging/LoggerChain.php
index 9b44dc0e..c256dd72 100644
--- a/doctrine/dbal/src/Logging/LoggerChain.php
+++ b/doctrine/dbal/src/Logging/LoggerChain.php
@@ -2,8 +2,12 @@
namespace Doctrine\DBAL\Logging;
+use Doctrine\Deprecations\Deprecation;
+
/**
* Chains multiple SQLLogger.
+ *
+ * @deprecated
*/
class LoggerChain implements SQLLogger
{
@@ -15,6 +19,12 @@ class LoggerChain implements SQLLogger
*/
public function __construct(iterable $loggers = [])
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4967',
+ 'LoggerChain is deprecated'
+ );
+
$this->loggers = $loggers;
}
diff --git a/doctrine/dbal/src/Logging/Middleware.php b/doctrine/dbal/src/Logging/Middleware.php
new file mode 100644
index 00000000..4d5c6b06
--- /dev/null
+++ b/doctrine/dbal/src/Logging/Middleware.php
@@ -0,0 +1,25 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\DBAL\Logging;
+
+use Doctrine\DBAL\Driver as DriverInterface;
+use Doctrine\DBAL\Driver\Middleware as MiddlewareInterface;
+use Psr\Log\LoggerInterface;
+
+final class Middleware implements MiddlewareInterface
+{
+ /** @var LoggerInterface */
+ private $logger;
+
+ public function __construct(LoggerInterface $logger)
+ {
+ $this->logger = $logger;
+ }
+
+ public function wrap(DriverInterface $driver): DriverInterface
+ {
+ return new Driver($driver, $this->logger);
+ }
+}
diff --git a/doctrine/dbal/src/Logging/SQLLogger.php b/doctrine/dbal/src/Logging/SQLLogger.php
index a0bdf1bf..dab4a3a7 100644
--- a/doctrine/dbal/src/Logging/SQLLogger.php
+++ b/doctrine/dbal/src/Logging/SQLLogger.php
@@ -6,6 +6,9 @@ use Doctrine\DBAL\Types\Type;
/**
* Interface for SQL loggers.
+ *
+ * @deprecated Use {@see \Doctrine\DBAL\Logging\Middleware} or implement
+ * {@see \Doctrine\DBAL\Driver\Middleware} instead.
*/
interface SQLLogger
{
diff --git a/doctrine/dbal/src/Logging/Statement.php b/doctrine/dbal/src/Logging/Statement.php
new file mode 100644
index 00000000..e993767a
--- /dev/null
+++ b/doctrine/dbal/src/Logging/Statement.php
@@ -0,0 +1,76 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Doctrine\DBAL\Logging;
+
+use Doctrine\DBAL\Driver\Middleware\AbstractStatementMiddleware;
+use Doctrine\DBAL\Driver\Result as ResultInterface;
+use Doctrine\DBAL\Driver\Statement as StatementInterface;
+use Doctrine\DBAL\ParameterType;
+use Psr\Log\LoggerInterface;
+
+use function array_slice;
+use function func_get_args;
+
+final class Statement extends AbstractStatementMiddleware
+{
+ /** @var LoggerInterface */
+ private $logger;
+
+ /** @var string */
+ private $sql;
+
+ /** @var array<int,mixed>|array<string,mixed> */
+ private $params = [];
+
+ /** @var array<int,int>|array<string,int> */
+ private $types = [];
+
+ /**
+ * @internal This statement can be only instantiated by its connection.
+ */
+ public function __construct(StatementInterface $statement, LoggerInterface $logger, string $sql)
+ {
+ parent::__construct($statement);
+
+ $this->logger = $logger;
+ $this->sql = $sql;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
+ {
+ $this->params[$param] = &$variable;
+ $this->types[$param] = $type;
+
+ return parent::bindParam($param, $variable, $type, ...array_slice(func_get_args(), 3));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function bindValue($param, $value, $type = ParameterType::STRING)
+ {
+ $this->params[$param] = $value;
+ $this->types[$param] = $type;
+
+ return parent::bindValue($param, $value, $type);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function execute($params = null): ResultInterface
+ {
+ $this->logger->debug('Executing statement: {sql} (parameters: {params}, types: {types})', [
+ 'sql' => $this->sql,
+ 'params' => $params ?? $this->params,
+ 'types' => $this->types,
+ ]);
+
+ return parent::execute($params);
+ }
+}
diff --git a/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php b/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php
new file mode 100644
index 00000000..b8029149
--- /dev/null
+++ b/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php
@@ -0,0 +1,1188 @@
+<?php
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\Exception;
+use Doctrine\DBAL\Schema\ForeignKeyConstraint;
+use Doctrine\DBAL\Schema\Identifier;
+use Doctrine\DBAL\Schema\Index;
+use Doctrine\DBAL\Schema\Table;
+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;
+use function array_merge;
+use function array_unique;
+use function array_values;
+use function count;
+use function func_get_args;
+use function implode;
+use function in_array;
+use function is_numeric;
+use function is_string;
+use function sprintf;
+use function str_replace;
+use function strtoupper;
+use function trim;
+
+/**
+ * Provides the base implementation for the lowest versions of supported MySQL-like database platforms.
+ */
+abstract class AbstractMySQLPlatform extends AbstractPlatform
+{
+ public const LENGTH_LIMIT_TINYTEXT = 255;
+ public const LENGTH_LIMIT_TEXT = 65535;
+ public const LENGTH_LIMIT_MEDIUMTEXT = 16777215;
+
+ public const LENGTH_LIMIT_TINYBLOB = 255;
+ public const LENGTH_LIMIT_BLOB = 65535;
+ public const LENGTH_LIMIT_MEDIUMBLOB = 16777215;
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function doModifyLimitQuery($query, $limit, $offset)
+ {
+ if ($limit !== null) {
+ $query .= sprintf(' LIMIT %d', $limit);
+
+ if ($offset > 0) {
+ $query .= sprintf(' OFFSET %d', $offset);
+ }
+ } elseif ($offset > 0) {
+ // 2^64-1 is the maximum of unsigned BIGINT, the biggest limit possible
+ $query .= sprintf(' LIMIT 18446744073709551615 OFFSET %d', $offset);
+ }
+
+ return $query;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getIdentifierQuoteCharacter()
+ {
+ return '`';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getRegexpExpression()
+ {
+ return 'RLIKE';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getLocateExpression($str, $substr, $startPos = false)
+ {
+ if ($startPos === false) {
+ return 'LOCATE(' . $substr . ', ' . $str . ')';
+ }
+
+ return 'LOCATE(' . $substr . ', ' . $str . ', ' . $startPos . ')';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getConcatExpression()
+ {
+ return sprintf('CONCAT(%s)', implode(', ', func_get_args()));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit)
+ {
+ $function = $operator === '+' ? 'DATE_ADD' : 'DATE_SUB';
+
+ return $function . '(' . $date . ', INTERVAL ' . $interval . ' ' . $unit . ')';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateDiffExpression($date1, $date2)
+ {
+ return 'DATEDIFF(' . $date1 . ', ' . $date2 . ')';
+ }
+
+ public function getCurrentDatabaseExpression(): string
+ {
+ return 'DATABASE()';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getLengthExpression($column)
+ {
+ return 'CHAR_LENGTH(' . $column . ')';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListDatabasesSQL()
+ {
+ return 'SHOW DATABASES';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListTableConstraintsSQL($table)
+ {
+ return 'SHOW INDEX FROM ' . $table;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Two approaches to listing the table indexes. The information_schema is
+ * preferred, because it doesn't cause problems with SQL keywords such as "order" or "table".
+ */
+ public function getListTableIndexesSQL($table, $database = null)
+ {
+ if ($database !== null) {
+ return 'SELECT NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, COLUMN_NAME AS Column_Name,' .
+ ' SUB_PART AS Sub_Part, INDEX_TYPE AS Index_Type' .
+ ' FROM information_schema.STATISTICS WHERE TABLE_NAME = ' . $this->quoteStringLiteral($table) .
+ ' AND TABLE_SCHEMA = ' . $this->quoteStringLiteral($database) .
+ ' ORDER BY SEQ_IN_INDEX ASC';
+ }
+
+ return 'SHOW INDEX FROM ' . $table;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListViewsSQL($database)
+ {
+ return 'SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = ' . $this->quoteStringLiteral($database);
+ }
+
+ /**
+ * @param string $table
+ * @param string|null $database
+ *
+ * @return string
+ */
+ public function getListTableForeignKeysSQL($table, $database = null)
+ {
+ // The schema name is passed multiple times as a literal in the WHERE clause instead of using a JOIN condition
+ // in order to avoid performance issues on MySQL older than 8.0 and the corresponding MariaDB versions
+ // caused by https://bugs.mysql.com/bug.php?id=81347
+ return 'SELECT k.CONSTRAINT_NAME, k.COLUMN_NAME, k.REFERENCED_TABLE_NAME, ' .
+ 'k.REFERENCED_COLUMN_NAME /*!50116 , c.UPDATE_RULE, c.DELETE_RULE */ ' .
+ 'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE k /*!50116 ' .
+ 'INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS c ON ' .
+ 'c.CONSTRAINT_NAME = k.CONSTRAINT_NAME AND ' .
+ 'c.TABLE_NAME = k.TABLE_NAME */ ' .
+ 'WHERE k.TABLE_NAME = ' . $this->quoteStringLiteral($table) . ' ' .
+ 'AND k.TABLE_SCHEMA = ' . $this->getDatabaseNameSQL($database) . ' /*!50116 ' .
+ 'AND c.CONSTRAINT_SCHEMA = ' . $this->getDatabaseNameSQL($database) . ' */' .
+ 'ORDER BY k.ORDINAL_POSITION';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
+ {
+ return $fixed ? ($length > 0 ? 'CHAR(' . $length . ')' : 'CHAR(255)')
+ : ($length > 0 ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
+ {
+ return $fixed
+ ? 'BINARY(' . ($length > 0 ? $length : 255) . ')'
+ : 'VARBINARY(' . ($length > 0 ? $length : 255) . ')';
+ }
+
+ /**
+ * Gets the SQL snippet used to declare a CLOB column type.
+ * TINYTEXT : 2 ^ 8 - 1 = 255
+ * TEXT : 2 ^ 16 - 1 = 65535
+ * MEDIUMTEXT : 2 ^ 24 - 1 = 16777215
+ * LONGTEXT : 2 ^ 32 - 1 = 4294967295
+ *
+ * {@inheritDoc}
+ */
+ public function getClobTypeDeclarationSQL(array $column)
+ {
+ if (! empty($column['length']) && is_numeric($column['length'])) {
+ $length = $column['length'];
+
+ if ($length <= static::LENGTH_LIMIT_TINYTEXT) {
+ return 'TINYTEXT';
+ }
+
+ if ($length <= static::LENGTH_LIMIT_TEXT) {
+ return 'TEXT';
+ }
+
+ if ($length <= static::LENGTH_LIMIT_MEDIUMTEXT) {
+ return 'MEDIUMTEXT';
+ }
+ }
+
+ return 'LONGTEXT';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTimeTypeDeclarationSQL(array $column)
+ {
+ if (isset($column['version']) && $column['version'] === true) {
+ return 'TIMESTAMP';
+ }
+
+ return 'DATETIME';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTypeDeclarationSQL(array $column)
+ {
+ return 'DATE';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getTimeTypeDeclarationSQL(array $column)
+ {
+ return 'TIME';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getBooleanTypeDeclarationSQL(array $column)
+ {
+ return 'TINYINT(1)';
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated
+ *
+ * MySQL prefers "autoincrement" identity columns since sequences can only
+ * be emulated with a table.
+ */
+ public function prefersIdentityColumns()
+ {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/1519',
+ 'AbstractMySQLPlatform::prefersIdentityColumns() is deprecated.'
+ );
+
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * MySQL supports this through AUTO_INCREMENT columns.
+ */
+ public function supportsIdentityColumns()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supportsInlineColumnComments()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supportsColumnCollation()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListTablesSQL()
+ {
+ return "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListTableColumnsSQL($table, $database = null)
+ {
+ return 'SELECT COLUMN_NAME AS Field, COLUMN_TYPE AS Type, IS_NULLABLE AS `Null`, ' .
+ 'COLUMN_KEY AS `Key`, COLUMN_DEFAULT AS `Default`, EXTRA AS Extra, COLUMN_COMMENT AS Comment, ' .
+ 'CHARACTER_SET_NAME AS CharacterSet, COLLATION_NAME AS Collation ' .
+ 'FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ' . $this->getDatabaseNameSQL($database) .
+ ' AND TABLE_NAME = ' . $this->quoteStringLiteral($table) .
+ ' ORDER BY ORDINAL_POSITION ASC';
+ }
+
+ public function getListTableMetadataSQL(string $table, ?string $database = null): string
+ {
+ return sprintf(
+ <<<'SQL'
+SELECT t.ENGINE,
+ t.AUTO_INCREMENT,
+ t.TABLE_COMMENT,
+ t.CREATE_OPTIONS,
+ t.TABLE_COLLATION,
+ ccsa.CHARACTER_SET_NAME
+FROM information_schema.TABLES t
+ INNER JOIN information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` ccsa
+ ON ccsa.COLLATION_NAME = t.TABLE_COLLATION
+WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA = %s AND TABLE_NAME = %s
+SQL
+ ,
+ $this->getDatabaseNameSQL($database),
+ $this->quoteStringLiteral($table)
+ );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function _getCreateTableSQL($name, array $columns, array $options = [])
+ {
+ $queryFields = $this->getColumnDeclarationListSQL($columns);
+
+ if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
+ foreach ($options['uniqueConstraints'] as $constraintName => $definition) {
+ $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($constraintName, $definition);
+ }
+ }
+
+ // add all indexes
+ if (isset($options['indexes']) && ! empty($options['indexes'])) {
+ foreach ($options['indexes'] as $indexName => $definition) {
+ $queryFields .= ', ' . $this->getIndexDeclarationSQL($indexName, $definition);
+ }
+ }
+
+ // attach all primary keys
+ if (isset($options['primary']) && ! empty($options['primary'])) {
+ $keyColumns = array_unique(array_values($options['primary']));
+ $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
+ }
+
+ $query = 'CREATE ';
+
+ if (! empty($options['temporary'])) {
+ $query .= 'TEMPORARY ';
+ }
+
+ $query .= 'TABLE ' . $name . ' (' . $queryFields . ') ';
+ $query .= $this->buildTableOptions($options);
+ $query .= $this->buildPartitionOptions($options);
+
+ $sql = [$query];
+ $engine = 'INNODB';
+
+ if (isset($options['engine'])) {
+ $engine = strtoupper(trim($options['engine']));
+ }
+
+ // Propagate foreign key constraints only for InnoDB.
+ if (isset($options['foreignKeys']) && $engine === 'INNODB') {
+ foreach ((array) $options['foreignKeys'] as $definition) {
+ $sql[] = $this->getCreateForeignKeySQL($definition, $name);
+ }
+ }
+
+ return $sql;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultValueDeclarationSQL($column)
+ {
+ // Unset the default value if the given column definition does not allow default values.
+ if ($column['type'] instanceof TextType || $column['type'] instanceof BlobType) {
+ $column['default'] = null;
+ }
+
+ return parent::getDefaultValueDeclarationSQL($column);
+ }
+
+ /**
+ * Build SQL for table options
+ *
+ * @param mixed[] $options
+ */
+ private function buildTableOptions(array $options): string
+ {
+ if (isset($options['table_options'])) {
+ return $options['table_options'];
+ }
+
+ $tableOptions = [];
+
+ // Charset
+ if (! isset($options['charset'])) {
+ $options['charset'] = 'utf8';
+ }
+
+ $tableOptions[] = sprintf('DEFAULT CHARACTER SET %s', $options['charset']);
+
+ if (isset($options['collate'])) {
+ $options['collation'] = $options['collate'];
+ }
+
+ // Collation
+ if (! isset($options['collation'])) {
+ $options['collation'] = $options['charset'] . '_unicode_ci';
+ }
+
+ $tableOptions[] = $this->getColumnCollationDeclarationSQL($options['collation']);
+
+ // Engine
+ if (! isset($options['engine'])) {
+ $options['engine'] = 'InnoDB';
+ }
+
+ $tableOptions[] = sprintf('ENGINE = %s', $options['engine']);
+
+ // Auto increment
+ if (isset($options['auto_increment'])) {
+ $tableOptions[] = sprintf('AUTO_INCREMENT = %s', $options['auto_increment']);
+ }
+
+ // Comment
+ if (isset($options['comment'])) {
+ $tableOptions[] = sprintf('COMMENT = %s ', $this->quoteStringLiteral($options['comment']));
+ }
+
+ // Row format
+ if (isset($options['row_format'])) {
+ $tableOptions[] = sprintf('ROW_FORMAT = %s', $options['row_format']);
+ }
+
+ return implode(' ', $tableOptions);
+ }
+
+ /**
+ * Build SQL for partition options.
+ *
+ * @param mixed[] $options
+ */
+ private function buildPartitionOptions(array $options): string
+ {
+ return isset($options['partition_options'])
+ ? ' ' . $options['partition_options']
+ : '';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAlterTableSQL(TableDiff $diff)
+ {
+ $columnSql = [];
+ $queryParts = [];
+ $newName = $diff->getNewName();
+
+ if ($newName !== false) {
+ $queryParts[] = 'RENAME TO ' . $newName->getQuotedName($this);
+ }
+
+ foreach ($diff->addedColumns as $column) {
+ if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
+ continue;
+ }
+
+ $columnArray = array_merge($column->toArray(), [
+ 'comment' => $this->getColumnComment($column),
+ ]);
+
+ $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
+ }
+
+ foreach ($diff->removedColumns as $column) {
+ if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
+ continue;
+ }
+
+ $queryParts[] = 'DROP ' . $column->getQuotedName($this);
+ }
+
+ foreach ($diff->changedColumns as $columnDiff) {
+ if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
+ continue;
+ }
+
+ $column = $columnDiff->column;
+ $columnArray = $column->toArray();
+
+ // Don't propagate default value changes for unsupported column types.
+ if (
+ $columnDiff->hasChanged('default') &&
+ count($columnDiff->changedProperties) === 1 &&
+ ($columnArray['type'] instanceof TextType || $columnArray['type'] instanceof BlobType)
+ ) {
+ continue;
+ }
+
+ $columnArray['comment'] = $this->getColumnComment($column);
+ $queryParts[] = 'CHANGE ' . ($columnDiff->getOldColumnName()->getQuotedName($this)) . ' '
+ . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
+ }
+
+ foreach ($diff->renamedColumns as $oldColumnName => $column) {
+ if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
+ continue;
+ }
+
+ $oldColumnName = new Identifier($oldColumnName);
+ $columnArray = $column->toArray();
+ $columnArray['comment'] = $this->getColumnComment($column);
+ $queryParts[] = 'CHANGE ' . $oldColumnName->getQuotedName($this) . ' '
+ . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
+ }
+
+ if (isset($diff->addedIndexes['primary'])) {
+ $keyColumns = array_unique(array_values($diff->addedIndexes['primary']->getColumns()));
+ $queryParts[] = 'ADD PRIMARY KEY (' . implode(', ', $keyColumns) . ')';
+ unset($diff->addedIndexes['primary']);
+ } elseif (isset($diff->changedIndexes['primary'])) {
+ // Necessary in case the new primary key includes a new auto_increment column
+ foreach ($diff->changedIndexes['primary']->getColumns() as $columnName) {
+ if (isset($diff->addedColumns[$columnName]) && $diff->addedColumns[$columnName]->getAutoincrement()) {
+ $keyColumns = array_unique(array_values($diff->changedIndexes['primary']->getColumns()));
+ $queryParts[] = 'DROP PRIMARY KEY';
+ $queryParts[] = 'ADD PRIMARY KEY (' . implode(', ', $keyColumns) . ')';
+ unset($diff->changedIndexes['primary']);
+ break;
+ }
+ }
+ }
+
+ $sql = [];
+ $tableSql = [];
+
+ if (! $this->onSchemaAlterTable($diff, $tableSql)) {
+ if (count($queryParts) > 0) {
+ $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' '
+ . implode(', ', $queryParts);
+ }
+
+ $sql = array_merge(
+ $this->getPreAlterTableIndexForeignKeySQL($diff),
+ $sql,
+ $this->getPostAlterTableIndexForeignKeySQL($diff)
+ );
+ }
+
+ return array_merge($sql, $tableSql, $columnSql);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
+ {
+ $sql = [];
+ $table = $diff->getName($this)->getQuotedName($this);
+
+ foreach ($diff->changedIndexes as $changedIndex) {
+ $sql = array_merge($sql, $this->getPreAlterTableAlterPrimaryKeySQL($diff, $changedIndex));
+ }
+
+ foreach ($diff->removedIndexes as $remKey => $remIndex) {
+ $sql = array_merge($sql, $this->getPreAlterTableAlterPrimaryKeySQL($diff, $remIndex));
+
+ foreach ($diff->addedIndexes as $addKey => $addIndex) {
+ if ($remIndex->getColumns() !== $addIndex->getColumns()) {
+ continue;
+ }
+
+ $indexClause = 'INDEX ' . $addIndex->getName();
+
+ if ($addIndex->isPrimary()) {
+ $indexClause = 'PRIMARY KEY';
+ } elseif ($addIndex->isUnique()) {
+ $indexClause = 'UNIQUE INDEX ' . $addIndex->getName();
+ }
+
+ $query = 'ALTER TABLE ' . $table . ' DROP INDEX ' . $remIndex->getName() . ', ';
+ $query .= 'ADD ' . $indexClause;
+ $query .= ' (' . $this->getIndexFieldDeclarationListSQL($addIndex) . ')';
+
+ $sql[] = $query;
+
+ unset($diff->removedIndexes[$remKey], $diff->addedIndexes[$addKey]);
+
+ break;
+ }
+ }
+
+ $engine = 'INNODB';
+
+ if ($diff->fromTable instanceof Table && $diff->fromTable->hasOption('engine')) {
+ $engine = strtoupper(trim($diff->fromTable->getOption('engine')));
+ }
+
+ // Suppress foreign key constraint propagation on non-supporting engines.
+ if ($engine !== 'INNODB') {
+ $diff->addedForeignKeys = [];
+ $diff->changedForeignKeys = [];
+ $diff->removedForeignKeys = [];
+ }
+
+ $sql = array_merge(
+ $sql,
+ $this->getPreAlterTableAlterIndexForeignKeySQL($diff),
+ parent::getPreAlterTableIndexForeignKeySQL($diff),
+ $this->getPreAlterTableRenameIndexForeignKeySQL($diff)
+ );
+
+ return $sql;
+ }
+
+ /**
+ * @return string[]
+ *
+ * @throws Exception
+ */
+ private function getPreAlterTableAlterPrimaryKeySQL(TableDiff $diff, Index $index): array
+ {
+ $sql = [];
+
+ if (! $index->isPrimary() || ! $diff->fromTable instanceof Table) {
+ return $sql;
+ }
+
+ $tableName = $diff->getName($this)->getQuotedName($this);
+
+ // Dropping primary keys requires to unset autoincrement attribute on the particular column first.
+ foreach ($index->getColumns() as $columnName) {
+ if (! $diff->fromTable->hasColumn($columnName)) {
+ continue;
+ }
+
+ $column = $diff->fromTable->getColumn($columnName);
+
+ if ($column->getAutoincrement() !== true) {
+ continue;
+ }
+
+ $column->setAutoincrement(false);
+
+ $sql[] = 'ALTER TABLE ' . $tableName . ' MODIFY ' .
+ $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
+
+ // original autoincrement information might be needed later on by other parts of the table alteration
+ $column->setAutoincrement(true);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * @param TableDiff $diff The table diff to gather the SQL for.
+ *
+ * @return string[]
+ *
+ * @throws Exception
+ */
+ private function getPreAlterTableAlterIndexForeignKeySQL(TableDiff $diff): array
+ {
+ $sql = [];
+ $table = $diff->getName($this)->getQuotedName($this);
+
+ foreach ($diff->changedIndexes as $changedIndex) {
+ // Changed primary key
+ if (! $changedIndex->isPrimary() || ! ($diff->fromTable instanceof Table)) {
+ continue;
+ }
+
+ foreach ($diff->fromTable->getPrimaryKeyColumns() as $columnName => $column) {
+ // Check if an autoincrement column was dropped from the primary key.
+ if (! $column->getAutoincrement() || in_array($columnName, $changedIndex->getColumns(), true)) {
+ continue;
+ }
+
+ // The autoincrement attribute needs to be removed from the dropped column
+ // before we can drop and recreate the primary key.
+ $column->setAutoincrement(false);
+
+ $sql[] = 'ALTER TABLE ' . $table . ' MODIFY ' .
+ $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
+
+ // Restore the autoincrement attribute as it might be needed later on
+ // by other parts of the table alteration.
+ $column->setAutoincrement(true);
+ }
+ }
+
+ return $sql;
+ }
+
+ /**
+ * @param TableDiff $diff The table diff to gather the SQL for.
+ *
+ * @return string[]
+ */
+ protected function getPreAlterTableRenameIndexForeignKeySQL(TableDiff $diff)
+ {
+ $sql = [];
+ $tableName = $diff->getName($this)->getQuotedName($this);
+
+ foreach ($this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) as $foreignKey) {
+ if (in_array($foreignKey, $diff->changedForeignKeys, true)) {
+ continue;
+ }
+
+ $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Returns the remaining foreign key constraints that require one of the renamed indexes.
+ *
+ * "Remaining" here refers to the diff between the foreign keys currently defined in the associated
+ * table and the foreign keys to be removed.
+ *
+ * @param TableDiff $diff The table diff to evaluate.
+ *
+ * @return ForeignKeyConstraint[]
+ */
+ private function getRemainingForeignKeyConstraintsRequiringRenamedIndexes(TableDiff $diff): array
+ {
+ if (empty($diff->renamedIndexes) || ! $diff->fromTable instanceof Table) {
+ return [];
+ }
+
+ $foreignKeys = [];
+ /** @var ForeignKeyConstraint[] $remainingForeignKeys */
+ $remainingForeignKeys = array_diff_key(
+ $diff->fromTable->getForeignKeys(),
+ $diff->removedForeignKeys
+ );
+
+ foreach ($remainingForeignKeys as $foreignKey) {
+ foreach ($diff->renamedIndexes as $index) {
+ if ($foreignKey->intersectsIndexColumns($index)) {
+ $foreignKeys[] = $foreignKey;
+
+ break;
+ }
+ }
+ }
+
+ return $foreignKeys;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
+ {
+ return array_merge(
+ parent::getPostAlterTableIndexForeignKeySQL($diff),
+ $this->getPostAlterTableRenameIndexForeignKeySQL($diff)
+ );
+ }
+
+ /**
+ * @param TableDiff $diff The table diff to gather the SQL for.
+ *
+ * @return string[]
+ */
+ protected function getPostAlterTableRenameIndexForeignKeySQL(TableDiff $diff)
+ {
+ $sql = [];
+ $newName = $diff->getNewName();
+
+ if ($newName !== false) {
+ $tableName = $newName->getQuotedName($this);
+ } else {
+ $tableName = $diff->getName($this)->getQuotedName($this);
+ }
+
+ foreach ($this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) as $foreignKey) {
+ if (in_array($foreignKey, $diff->changedForeignKeys, true)) {
+ continue;
+ }
+
+ $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function getCreateIndexSQLFlags(Index $index)
+ {
+ $type = '';
+ if ($index->isUnique()) {
+ $type .= 'UNIQUE ';
+ } elseif ($index->hasFlag('fulltext')) {
+ $type .= 'FULLTEXT ';
+ } elseif ($index->hasFlag('spatial')) {
+ $type .= 'SPATIAL ';
+ }
+
+ return $type;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getIntegerTypeDeclarationSQL(array $column)
+ {
+ return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getBigIntTypeDeclarationSQL(array $column)
+ {
+ return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getSmallIntTypeDeclarationSQL(array $column)
+ {
+ return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFloatDeclarationSQL(array $column)
+ {
+ return 'DOUBLE PRECISION' . $this->getUnsignedDeclaration($column);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDecimalTypeDeclarationSQL(array $column)
+ {
+ return parent::getDecimalTypeDeclarationSQL($column) . $this->getUnsignedDeclaration($column);
+ }
+
+ /**
+ * Get unsigned declaration for a column.
+ *
+ * @param mixed[] $columnDef
+ */
+ private function getUnsignedDeclaration(array $columnDef): string
+ {
+ return ! empty($columnDef['unsigned']) ? ' UNSIGNED' : '';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function _getCommonIntegerTypeDeclarationSQL(array $column)
+ {
+ $autoinc = '';
+ if (! empty($column['autoincrement'])) {
+ $autoinc = ' AUTO_INCREMENT';
+ }
+
+ return $this->getUnsignedDeclaration($column) . $autoinc;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getColumnCharsetDeclarationSQL($charset)
+ {
+ return 'CHARACTER SET ' . $charset;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getColumnCollationDeclarationSQL($collation)
+ {
+ return 'COLLATE ' . $this->quoteSingleIdentifier($collation);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey)
+ {
+ $query = '';
+ if ($foreignKey->hasOption('match')) {
+ $query .= ' MATCH ' . $foreignKey->getOption('match');
+ }
+
+ $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
+
+ return $query;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDropIndexSQL($index, $table = null)
+ {
+ if ($index instanceof Index) {
+ $indexName = $index->getQuotedName($this);
+ } elseif (is_string($index)) {
+ $indexName = $index;
+ } else {
+ throw new InvalidArgumentException(
+ __METHOD__ . '() expects $index parameter to be string or ' . Index::class . '.'
+ );
+ }
+
+ if ($table instanceof Table) {
+ $table = $table->getQuotedName($this);
+ } elseif (! is_string($table)) {
+ throw new InvalidArgumentException(
+ __METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.'
+ );
+ }
+
+ if ($index instanceof Index && $index->isPrimary()) {
+ // MySQL primary keys are always named "PRIMARY",
+ // so we cannot use them in statements because of them being keyword.
+ return $this->getDropPrimaryKeySQL($table);
+ }
+
+ return 'DROP INDEX ' . $indexName . ' ON ' . $table;
+ }
+
+ /**
+ * @param string $table
+ *
+ * @return string
+ */
+ protected function getDropPrimaryKeySQL($table)
+ {
+ return 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY';
+ }
+
+ /**
+ * The `ALTER TABLE ... DROP CONSTRAINT` syntax is only available as of MySQL 8.0.19.
+ *
+ * @link https://dev.mysql.com/doc/refman/8.0/en/alter-table.html
+ */
+ public function getDropUniqueConstraintSQL(string $name, string $tableName): string
+ {
+ return $this->getDropIndexSQL($name, $tableName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getSetTransactionIsolationSQL($level)
+ {
+ return 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getName()
+ {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4749',
+ 'AbstractMySQLPlatform::getName() is deprecated. Identify platforms by their class.'
+ );
+
+ return 'mysql';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getReadLockSQL()
+ {
+ return 'LOCK IN SHARE MODE';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function initializeDoctrineTypeMappings()
+ {
+ $this->doctrineTypeMapping = [
+ 'bigint' => 'bigint',
+ 'binary' => 'binary',
+ 'blob' => 'blob',
+ 'char' => 'string',
+ 'date' => 'date',
+ 'datetime' => 'datetime',
+ 'decimal' => 'decimal',
+ 'double' => 'float',
+ 'float' => 'float',
+ 'int' => 'integer',
+ 'integer' => 'integer',
+ 'longblob' => 'blob',
+ 'longtext' => 'text',
+ 'mediumblob' => 'blob',
+ 'mediumint' => 'integer',
+ 'mediumtext' => 'text',
+ 'numeric' => 'decimal',
+ 'real' => 'float',
+ 'set' => 'simple_array',
+ 'smallint' => 'smallint',
+ 'string' => 'string',
+ 'text' => 'text',
+ 'time' => 'time',
+ 'timestamp' => 'datetime',
+ 'tinyblob' => 'blob',
+ 'tinyint' => 'boolean',
+ 'tinytext' => 'text',
+ 'varbinary' => 'binary',
+ 'varchar' => 'string',
+ 'year' => 'date',
+ ];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getVarcharMaxLength()
+ {
+ return 65535;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBinaryMaxLength()
+ {
+ return 65535;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated Implement {@see createReservedKeywordsList()} instead.
+ */
+ protected function getReservedKeywordsClass()
+ {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'AbstractMySQLPlatform::getReservedKeywordsClass() is deprecated,'
+ . ' use AbstractMySQLPlatform::createReservedKeywordsList() instead.'
+ );
+
+ return Keywords\MySQLKeywords::class;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * MySQL commits a transaction implicitly when DROP TABLE is executed, however not
+ * if DROP TEMPORARY TABLE is executed.
+ */
+ public function getDropTemporaryTableSQL($table)
+ {
+ if ($table instanceof Table) {
+ $table = $table->getQuotedName($this);
+ } elseif (! is_string($table)) {
+ throw new InvalidArgumentException(
+ __METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.'
+ );
+ }
+
+ return 'DROP TEMPORARY TABLE ' . $table;
+ }
+
+ /**
+ * Gets the SQL Snippet used to declare a BLOB column type.
+ * TINYBLOB : 2 ^ 8 - 1 = 255
+ * BLOB : 2 ^ 16 - 1 = 65535
+ * MEDIUMBLOB : 2 ^ 24 - 1 = 16777215
+ * LONGBLOB : 2 ^ 32 - 1 = 4294967295
+ *
+ * {@inheritDoc}
+ */
+ public function getBlobTypeDeclarationSQL(array $column)
+ {
+ if (! empty($column['length']) && is_numeric($column['length'])) {
+ $length = $column['length'];
+
+ if ($length <= static::LENGTH_LIMIT_TINYBLOB) {
+ return 'TINYBLOB';
+ }
+
+ if ($length <= static::LENGTH_LIMIT_BLOB) {
+ return 'BLOB';
+ }
+
+ if ($length <= static::LENGTH_LIMIT_MEDIUMBLOB) {
+ return 'MEDIUMBLOB';
+ }
+ }
+
+ return 'LONGBLOB';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function quoteStringLiteral($str)
+ {
+ $str = str_replace('\\', '\\\\', $str); // MySQL requires backslashes to be escaped aswell.
+
+ return parent::quoteStringLiteral($str);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultTransactionIsolationLevel()
+ {
+ return TransactionIsolationLevel::REPEATABLE_READ;
+ }
+
+ public function supportsColumnLengthIndexes(): bool
+ {
+ return true;
+ }
+
+ private function getDatabaseNameSQL(?string $databaseName): string
+ {
+ if ($databaseName !== null) {
+ return $this->quoteStringLiteral($databaseName);
+ }
+
+ return $this->getCurrentDatabaseExpression();
+ }
+}
diff --git a/doctrine/dbal/src/Platforms/AbstractPlatform.php b/doctrine/dbal/src/Platforms/AbstractPlatform.php
index f22fab5b..e143c6dc 100644
--- a/doctrine/dbal/src/Platforms/AbstractPlatform.php
+++ b/doctrine/dbal/src/Platforms/AbstractPlatform.php
@@ -80,6 +80,8 @@ abstract class AbstractPlatform
* Contains a list of all columns that should generate parseable column comments for type-detection
* in reverse engineering scenarios.
*
+ * @deprecated This property is deprecated and will be removed in Doctrine DBAL 4.0.
+ *
* @var string[]|null
*/
protected $doctrineTypeComments;
@@ -94,10 +96,6 @@ abstract class AbstractPlatform
*/
protected $_keywords;
- public function __construct()
- {
- }
-
/**
* Sets the EventManager used by the Platform.
*
@@ -173,10 +171,8 @@ abstract class AbstractPlatform
/**
* Initializes Doctrine Type Mappings with the platform defaults
* and with all additional type mappings.
- *
- * @return void
*/
- private function initializeAllDoctrineTypeMappings()
+ private function initializeAllDoctrineTypeMappings(): void
{
$this->initializeDoctrineTypeMappings();
@@ -341,6 +337,8 @@ abstract class AbstractPlatform
/**
* Gets the name of the platform.
*
+ * @deprecated Identify platforms by their class.
+ *
* @return string
*/
abstract public function getName();
@@ -424,10 +422,19 @@ abstract class AbstractPlatform
/**
* Initializes the Doctrine Type comments instance variable for in_array() checks.
*
+ * @deprecated This API will be removed in Doctrine DBAL 4.0.
+ *
* @return void
*/
protected function initializeCommentedDoctrineTypes()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/5058',
+ '%s is deprecated and will be removed in Doctrine DBAL 4.0.',
+ __METHOD__
+ );
+
$this->doctrineTypeComments = [];
foreach (Type::getTypesMap() as $typeName => $className) {
@@ -444,17 +451,24 @@ abstract class AbstractPlatform
/**
* Is it necessary for the platform to add a parsable type comment to allow reverse engineering the given type?
*
+ * @deprecated Use {@link Type::requiresSQLCommentHint()} instead.
+ *
* @return bool
*/
public function isCommentedDoctrineType(Type $doctrineType)
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/5058',
+ '%s is deprecated and will be removed in Doctrine DBAL 4.0. Use Type::requiresSQLCommentHint() instead.',
+ __METHOD__
+ );
+
if ($this->doctrineTypeComments === null) {
$this->initializeCommentedDoctrineTypes();
}
- assert(is_array($this->doctrineTypeComments));
-
- return in_array($doctrineType->getName(), $this->doctrineTypeComments, true);
+ return $doctrineType->requiresSQLCommentHint($this);
}
/**
@@ -466,6 +480,13 @@ abstract class AbstractPlatform
*/
public function markDoctrineTypeCommented($doctrineType)
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/5058',
+ '%s is deprecated and will be removed in Doctrine DBAL 4.0. Use Type::requiresSQLCommentHint() instead.',
+ __METHOD__
+ );
+
if ($this->doctrineTypeComments === null) {
$this->initializeCommentedDoctrineTypes();
}
@@ -494,7 +515,7 @@ abstract class AbstractPlatform
{
$comment = $column->getComment();
- if ($this->isCommentedDoctrineType($column->getType())) {
+ if ($column->getType()->requiresSQLCommentHint($this)) {
$comment .= $this->getDoctrineTypeComment($column->getType());
}
@@ -514,78 +535,143 @@ abstract class AbstractPlatform
/**
* Gets the string portion that starts an SQL comment.
*
+ * @deprecated
+ *
* @return string
*/
public function getSqlCommentStartString()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getSqlCommentStartString() is deprecated.'
+ );
+
return '--';
}
/**
* Gets the string portion that ends an SQL comment.
*
+ * @deprecated
+ *
* @return string
*/
public function getSqlCommentEndString()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getSqlCommentEndString() is deprecated.'
+ );
+
return "\n";
}
/**
* Gets the maximum length of a char column.
+ *
+ * @deprecated
*/
public function getCharMaxLength(): int
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3263',
+ 'AbstractPlatform::getCharMaxLength() is deprecated.'
+ );
+
return $this->getVarcharMaxLength();
}
/**
* Gets the maximum length of a varchar column.
*
+ * @deprecated
+ *
* @return int
*/
public function getVarcharMaxLength()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3263',
+ 'AbstractPlatform::getVarcharMaxLength() is deprecated.'
+ );
+
return 4000;
}
/**
* Gets the default length of a varchar column.
*
+ * @deprecated
+ *
* @return int
*/
public function getVarcharDefaultLength()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3263',
+ 'Relying on the default varchar column length is deprecated, specify the length explicitly.'
+ );
+
return 255;
}
/**
* Gets the maximum length of a binary column.
*
+ * @deprecated
+ *
* @return int
*/
public function getBinaryMaxLength()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3263',
+ 'AbstractPlatform::getBinaryMaxLength() is deprecated.'
+ );
+
return 4000;
}
/**
* Gets the default length of a binary column.
*
+ * @deprecated
+ *
* @return int
*/
public function getBinaryDefaultLength()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/3263',
+ 'Relying on the default binary column length is deprecated, specify the length explicitly.'
+ );
+
return 255;
}
/**
* Gets all SQL wildcard characters of the platform.
*
+ * @deprecated Use {@see AbstractPlatform::getLikeWildcardCharacters()} instead.
+ *
* @return string[]
*/
public function getWildcards()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getWildcards() is deprecated.'
+ . ' Use AbstractPlatform::getLikeWildcardCharacters() instead.'
+ );
+
return ['%', '_'];
}
@@ -604,12 +690,20 @@ abstract class AbstractPlatform
/**
* Returns the SQL snippet to get the average value of a column.
*
+ * @deprecated Use AVG() in SQL instead.
+ *
* @param string $column The column to use.
*
* @return string Generated SQL including an AVG aggregate function.
*/
public function getAvgExpression($column)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getAvgExpression() is deprecated. Use AVG() in SQL instead.'
+ );
+
return 'AVG(' . $column . ')';
}
@@ -618,48 +712,80 @@ abstract class AbstractPlatform
*
* If a '*' is used instead of a column the number of selected rows is returned.
*
+ * @deprecated Use COUNT() in SQL instead.
+ *
* @param string|int $column The column to use.
*
* @return string Generated SQL including a COUNT aggregate function.
*/
public function getCountExpression($column)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getCountExpression() is deprecated. Use COUNT() in SQL instead.'
+ );
+
return 'COUNT(' . $column . ')';
}
/**
* Returns the SQL snippet to get the highest value of a column.
*
+ * @deprecated Use MAX() in SQL instead.
+ *
* @param string $column The column to use.
*
* @return string Generated SQL including a MAX aggregate function.
*/
public function getMaxExpression($column)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getMaxExpression() is deprecated. Use MAX() in SQL instead.'
+ );
+
return 'MAX(' . $column . ')';
}
/**
* Returns the SQL snippet to get the lowest value of a column.
*
+ * @deprecated Use MIN() in SQL instead.
+ *
* @param string $column The column to use.
*
* @return string Generated SQL including a MIN aggregate function.
*/
public function getMinExpression($column)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getMinExpression() is deprecated. Use MIN() in SQL instead.'
+ );
+
return 'MIN(' . $column . ')';
}
/**
* Returns the SQL snippet to get the total sum of a column.
*
+ * @deprecated Use SUM() in SQL instead.
+ *
* @param string $column The column to use.
*
* @return string Generated SQL including a SUM aggregate function.
*/
public function getSumExpression($column)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getSumExpression() is deprecated. Use SUM() in SQL instead.'
+ );
+
return 'SUM(' . $column . ')';
}
@@ -670,17 +796,25 @@ abstract class AbstractPlatform
*
* Note: Not SQL92, but common functionality.
*
+ * @deprecated
+ *
* @param string $column
*
* @return string
*/
public function getMd5Expression($column)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getMd5Expression() is deprecated.'
+ );
+
return 'MD5(' . $column . ')';
}
/**
- * Returns the SQL snippet to get the length of a text column.
+ * Returns the SQL snippet to get the length of a text column in characters.
*
* @param string $column
*
@@ -694,25 +828,41 @@ abstract class AbstractPlatform
/**
* Returns the SQL snippet to get the squared value of a column.
*
+ * @deprecated Use SQRT() in SQL instead.
+ *
* @param string $column The column to use.
*
* @return string Generated SQL including an SQRT aggregate function.
*/
public function getSqrtExpression($column)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getSqrtExpression() is deprecated. Use SQRT() in SQL instead.'
+ );
+
return 'SQRT(' . $column . ')';
}
/**
* Returns the SQL snippet to round a numeric column to the number of decimals specified.
*
- * @param string $column
- * @param int $decimals
+ * @deprecated Use ROUND() in SQL instead.
+ *
+ * @param string $column
+ * @param string|int $decimals
*
* @return string
*/
public function getRoundExpression($column, $decimals = 0)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getRoundExpression() is deprecated. Use ROUND() in SQL instead.'
+ );
+
return 'ROUND(' . $column . ', ' . $decimals . ')';
}
@@ -770,24 +920,40 @@ abstract class AbstractPlatform
/**
* Returns the SQL snippet to trim trailing space characters from the expression.
*
+ * @deprecated Use RTRIM() in SQL instead.
+ *
* @param string $str Literal string or column name.
*
* @return string
*/
public function getRtrimExpression($str)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getRtrimExpression() is deprecated. Use RTRIM() in SQL instead.'
+ );
+
return 'RTRIM(' . $str . ')';
}
/**
* Returns the SQL snippet to trim leading space characters from the expression.
*
+ * @deprecated Use LTRIM() in SQL instead.
+ *
* @param string $str Literal string or column name.
*
* @return string
*/
public function getLtrimExpression($str)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getLtrimExpression() is deprecated. Use LTRIM() in SQL instead.'
+ );
+
return 'LTRIM(' . $str . ')';
}
@@ -795,12 +961,20 @@ abstract class AbstractPlatform
* Returns the SQL snippet to change all characters from the expression to uppercase,
* according to the current character set mapping.
*
+ * @deprecated Use UPPER() in SQL instead.
+ *
* @param string $str Literal string or column name.
*
* @return string
*/
public function getUpperExpression($str)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getUpperExpression() is deprecated. Use UPPER() in SQL instead.'
+ );
+
return 'UPPER(' . $str . ')';
}
@@ -808,21 +982,29 @@ abstract class AbstractPlatform
* Returns the SQL snippet to change all characters from the expression to lowercase,
* according to the current character set mapping.
*
+ * @deprecated Use LOWER() in SQL instead.
+ *
* @param string $str Literal string or column name.
*
* @return string
*/
public function getLowerExpression($str)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getLowerExpression() is deprecated. Use LOWER() in SQL instead.'
+ );
+
return 'LOWER(' . $str . ')';
}
/**
* Returns the SQL snippet to get the position of the first occurrence of substring $substr in string $str.
*
- * @param string $str Literal string.
- * @param string $substr Literal string to find.
- * @param int|false $startPos Position to start at, beginning of string by default.
+ * @param string $str Literal string.
+ * @param string $substr Literal string to find.
+ * @param string|int|false $startPos Position to start at, beginning of string by default.
*
* @return string
*
@@ -836,10 +1018,18 @@ abstract class AbstractPlatform
/**
* Returns the SQL snippet to get the current system date.
*
+ * @deprecated Generate dates within the application.
+ *
* @return string
*/
public function getNowExpression()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4753',
+ 'AbstractPlatform::getNowExpression() is deprecated. Generate dates within the application.'
+ );
+
return 'NOW()';
}
@@ -850,9 +1040,9 @@ abstract class AbstractPlatform
*
* SQLite only supports the 2 parameter variant of this function.
*
- * @param string $string An sql string literal or column name/alias.
- * @param int $start Where to start the substring portion.
- * @param int|null $length The substring portion length.
+ * @param string $string An sql string literal or column name/alias.
+ * @param string|int $start Where to start the substring portion.
+ * @param string|int|null $length The substring portion length.
*
* @return string
*/
@@ -888,36 +1078,60 @@ abstract class AbstractPlatform
* ->where($e->eq('id', $e->not('null'));
* </code>
*
+ * @deprecated Use NOT() in SQL instead.
+ *
* @param string $expression
*
* @return string The logical expression.
*/
public function getNotExpression($expression)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getNotExpression() is deprecated. Use NOT() in SQL instead.'
+ );
+
return 'NOT(' . $expression . ')';
}
/**
* Returns the SQL that checks if an expression is null.
*
+ * @deprecated Use IS NULL in SQL instead.
+ *
* @param string $expression The expression that should be compared to null.
*
* @return string The logical expression.
*/
public function getIsNullExpression($expression)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getIsNullExpression() is deprecated. Use IS NULL in SQL instead.'
+ );
+
return $expression . ' IS NULL';
}
/**
* Returns the SQL that checks if an expression is not null.
*
+ * @deprecated Use IS NOT NULL in SQL instead.
+ *
* @param string $expression The expression that should be compared to null.
*
* @return string The logical expression.
*/
public function getIsNotNullExpression($expression)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getIsNotNullExpression() is deprecated. Use IS NOT NULL in SQL instead.'
+ );
+
return $expression . ' IS NOT NULL';
}
@@ -930,6 +1144,8 @@ abstract class AbstractPlatform
* http://www.w3schools.com/sql/sql_between.asp. If you want complete database
* independence you should avoid using between().
*
+ * @deprecated Use BETWEEN in SQL instead.
+ *
* @param string $expression The value to compare to.
* @param string $value1 The lower value to compare with.
* @param string $value2 The higher value to compare with.
@@ -938,52 +1154,90 @@ abstract class AbstractPlatform
*/
public function getBetweenExpression($expression, $value1, $value2)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getBetweenExpression() is deprecated. Use BETWEEN in SQL instead.'
+ );
+
return $expression . ' BETWEEN ' . $value1 . ' AND ' . $value2;
}
/**
* Returns the SQL to get the arccosine of a value.
*
+ * @deprecated Use ACOS() in SQL instead.
+ *
* @param string $value
*
* @return string
*/
public function getAcosExpression($value)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getAcosExpression() is deprecated. Use ACOS() in SQL instead.'
+ );
+
return 'ACOS(' . $value . ')';
}
/**
* Returns the SQL to get the sine of a value.
*
+ * @deprecated Use SIN() in SQL instead.
+ *
* @param string $value
*
* @return string
*/
public function getSinExpression($value)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getSinExpression() is deprecated. Use SIN() in SQL instead.'
+ );
+
return 'SIN(' . $value . ')';
}
/**
* Returns the SQL to get the PI value.
*
+ * @deprecated Use PI() in SQL instead.
+ *
* @return string
*/
public function getPiExpression()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getPiExpression() is deprecated. Use PI() in SQL instead.'
+ );
+
return 'PI()';
}
/**
* Returns the SQL to get the cosine of a value.
*
+ * @deprecated Use COS() in SQL instead.
+ *
* @param string $value
*
* @return string
*/
public function getCosExpression($value)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getCosExpression() is deprecated. Use COS() in SQL instead.'
+ );
+
return 'COS(' . $value . ')';
}
@@ -1309,6 +1563,7 @@ abstract class AbstractPlatform
*
* @param string $fromClause The FROM clause to append the hint for the given lock mode to
* @param int $lockMode One of the Doctrine\DBAL\LockMode::* constants
+ * @psalm-param LockMode::* $lockMode
*/
public function appendLockHint(string $fromClause, int $lockMode): string
{
@@ -1350,26 +1605,6 @@ abstract class AbstractPlatform
}
/**
- * Returns the SQL snippet to drop an existing database.
- *
- * @param string $name The name of the database that should be dropped.
- *
- * @return string
- */
- public function getDropDatabaseSQL($name)
- {
- return 'DROP DATABASE ' . $name;
- }
-
- /**
- * Returns the SQL snippet to drop a schema.
- */
- public function getDropSchemaSQL(string $schemaName): string
- {
- return 'DROP SCHEMA ' . $schemaName;
- }
-
- /**
* Returns the SQL snippet to drop an existing table.
*
* @param Table|string $table
@@ -1425,8 +1660,8 @@ abstract class AbstractPlatform
/**
* Returns the SQL to drop an index from a table.
*
- * @param Index|string $index
- * @param Table|string $table
+ * @param Index|string $index
+ * @param Table|string|null $table
*
* @return string
*
@@ -1448,6 +1683,8 @@ abstract class AbstractPlatform
/**
* Returns the SQL to drop a constraint.
*
+ * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy.
+ *
* @param Constraint|string $constraint
* @param Table|string $table
*
@@ -1494,6 +1731,14 @@ abstract class AbstractPlatform
}
/**
+ * Returns the SQL to drop a unique constraint.
+ */
+ public function getDropUniqueConstraintSQL(string $name, string $tableName): string
+ {
+ return $this->getDropConstraintSQL($name, $tableName);
+ }
+
+ /**
* Returns the SQL statement(s) to create a table with the specified name, columns and constraints
* on this platform.
*
@@ -1566,23 +1811,13 @@ abstract class AbstractPlatform
}
}
- $name = $column->getQuotedName($this);
-
- $columnData = array_merge($column->toArray(), [
- 'name' => $name,
- 'version' => $column->hasPlatformOption('version') ? $column->getPlatformOption('version') : false,
- 'comment' => $this->getColumnComment($column),
- ]);
-
- if ($columnData['type'] instanceof Types\StringType && $columnData['length'] === null) {
- $columnData['length'] = 255;
- }
+ $columnData = $this->columnToArray($column);
if (in_array($column->getName(), $options['primary'], true)) {
$columnData['primary'] = true;
}
- $columns[$name] = $columnData;
+ $columns[$columnData['name']] = $columnData;
}
if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) {
@@ -1747,8 +1982,33 @@ abstract class AbstractPlatform
}
/**
+ * Returns the SQL snippet to drop an existing sequence.
+ *
+ * @param Sequence|string $sequence
+ *
+ * @return string
+ *
+ * @throws Exception If not supported on this platform.
+ */
+ public function getDropSequenceSQL($sequence)
+ {
+ if (! $this->supportsSequences()) {
+ throw Exception::notSupported(__METHOD__);
+ }
+
+ if ($sequence instanceof Sequence) {
+ $sequence = $sequence->getQuotedName($this);
+ }
+
+ return 'DROP SEQUENCE ' . $sequence;
+ }
+
+ /**
* Returns the SQL to create a constraint on a table on this platform.
*
+ * @deprecated Use {@see getCreateIndexSQL()}, {@see getCreateForeignKeySQL()}
+ * or {@see getCreateUniqueConstraintSQL()} instead.
+ *
* @param Table|string $table
*
* @return string
@@ -1873,7 +2133,33 @@ abstract class AbstractPlatform
*/
public function getCreateSchemaSQL($schemaName)
{
- throw Exception::notSupported(__METHOD__);
+ if (! $this->supportsSchemas()) {
+ throw Exception::notSupported(__METHOD__);
+ }
+
+ return 'CREATE SCHEMA ' . $schemaName;
+ }
+
+ /**
+ * Returns the SQL to create a unique constraint on a table on this platform.
+ */
+ public function getCreateUniqueConstraintSQL(UniqueConstraint $constraint, string $tableName): string
+ {
+ return $this->getCreateConstraintSQL($constraint, $tableName);
+ }
+
+ /**
+ * Returns the SQL snippet to drop a schema.
+ *
+ * @throws Exception If not supported on this platform.
+ */
+ public function getDropSchemaSQL(string $schemaName): string
+ {
+ if (! $this->supportsSchemas()) {
+ throw Exception::notSupported(__METHOD__);
+ }
+
+ return 'DROP SCHEMA ' . $schemaName;
}
/**
@@ -2312,7 +2598,7 @@ abstract class AbstractPlatform
}
if ($type instanceof Types\BooleanType) {
- return " DEFAULT '" . $this->convertBooleans($default) . "'";
+ return ' DEFAULT ' . $this->convertBooleans($default);
}
return ' DEFAULT ' . $this->quoteStringLiteral($default);
@@ -2452,11 +2738,19 @@ abstract class AbstractPlatform
* SQL error for any database that does not support temporary tables, or that
* requires a different SQL command from "CREATE TEMPORARY TABLE".
*
+ * @deprecated
+ *
* @return string The string required to be placed between "CREATE" and "TABLE"
* to generate a temporary table, if possible.
*/
public function getTemporaryTableSQL()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getTemporaryTableSQL() is deprecated.'
+ );
+
return 'TEMPORARY';
}
@@ -2573,11 +2867,19 @@ abstract class AbstractPlatform
* Obtains DBMS specific SQL code portion needed to set the UNIQUE constraint
* of a column declaration to be used in statements like CREATE TABLE.
*
+ * @deprecated Use UNIQUE in SQL instead.
+ *
* @return string DBMS specific SQL code portion needed to set the UNIQUE constraint
* of a column declaration.
*/
public function getUniqueFieldDeclarationSQL()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getUniqueFieldDeclarationSQL() is deprecated. Use UNIQUE in SQL instead.'
+ );
+
return 'UNIQUE';
}
@@ -2613,10 +2915,18 @@ abstract class AbstractPlatform
* Whether the platform prefers identity columns (eg. autoincrement) for ID generation.
* Subclasses should override this method to return TRUE if they prefer identity columns.
*
+ * @deprecated
+ *
* @return bool
*/
public function prefersIdentityColumns()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/1519',
+ 'AbstractPlatform::prefersIdentityColumns() is deprecated.'
+ );
+
return false;
}
@@ -2752,7 +3062,7 @@ abstract class AbstractPlatform
/**
* Returns the SQL statement for retrieving the namespaces defined in the database.
*
- * @deprecated Use {@link AbstractSchemaManager::listSchemaNames()} instead.
+ * @deprecated Use {@see AbstractSchemaManager::listSchemaNames()} instead.
*
* @return string
*
@@ -2818,12 +3128,20 @@ abstract class AbstractPlatform
}
/**
+ * @deprecated
+ *
* @return string
*
* @throws Exception If not supported on this platform.
*/
public function getListUsersSQL()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::getListUsersSQL() is deprecated.'
+ );
+
throw Exception::notSupported(__METHOD__);
}
@@ -2880,64 +3198,66 @@ abstract class AbstractPlatform
* @param string $sql
*
* @return string
- *
- * @throws Exception If not supported on this platform.
*/
public function getCreateViewSQL($name, $sql)
{
- throw Exception::notSupported(__METHOD__);
+ return 'CREATE VIEW ' . $name . ' AS ' . $sql;
}
/**
* @param string $name
*
* @return string
- *
- * @throws Exception If not supported on this platform.
*/
public function getDropViewSQL($name)
{
- throw Exception::notSupported(__METHOD__);
+ return 'DROP VIEW ' . $name;
}
/**
- * Returns the SQL snippet to drop an existing sequence.
- *
- * @param Sequence|string $sequence
+ * @param string $sequence
*
* @return string
*
* @throws Exception If not supported on this platform.
*/
- public function getDropSequenceSQL($sequence)
+ public function getSequenceNextValSQL($sequence)
{
throw Exception::notSupported(__METHOD__);
}
/**
- * @param string $sequence
+ * Returns the SQL to create a new database.
+ *
+ * @param string $name The name of the database that should be created.
*
* @return string
*
* @throws Exception If not supported on this platform.
*/
- public function getSequenceNextValSQL($sequence)
+ public function getCreateDatabaseSQL($name)
{
- throw Exception::notSupported(__METHOD__);
+ if (! $this->supportsCreateDropDatabase()) {
+ throw Exception::notSupported(__METHOD__);
+ }
+
+ return 'CREATE DATABASE ' . $name;
}
/**
- * Returns the SQL to create a new database.
+ * Returns the SQL snippet to drop an existing database.
*
- * @param string $name The name of the database that should be created.
+ * @param string $name The name of the database that should be dropped.
*
* @return string
- *
- * @throws Exception If not supported on this platform.
*/
- public function getCreateDatabaseSQL($name)
+ public function getDropDatabaseSQL($name)
{
- throw Exception::notSupported(__METHOD__);
+ if (! $this->supportsCreateDropDatabase()) {
+ throw Exception::notSupported(__METHOD__);
+ }
+
+ return 'DROP DATABASE ' . $name;
}
/**
@@ -3092,10 +3412,18 @@ abstract class AbstractPlatform
/**
* Whether the platform supports indexes.
*
+ * @deprecated
+ *
* @return bool
*/
public function supportsIndexes()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::supportsIndexes() is deprecated.'
+ );
+
return true;
}
@@ -3120,20 +3448,36 @@ abstract class AbstractPlatform
/**
* Whether the platform supports altering tables.
*
+ * @deprecated All platforms must implement altering tables.
+ *
* @return bool
*/
public function supportsAlterTable()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::supportsAlterTable() is deprecated. All platforms must implement altering tables.'
+ );
+
return true;
}
/**
* Whether the platform supports transactions.
*
+ * @deprecated
+ *
* @return bool
*/
public function supportsTransactions()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::supportsTransactions() is deprecated.'
+ );
+
return true;
}
@@ -3160,10 +3504,18 @@ abstract class AbstractPlatform
/**
* Whether the platform supports primary key constraints.
*
+ * @deprecated
+ *
* @return bool
*/
public function supportsPrimaryConstraints()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::supportsPrimaryConstraints() is deprecated.'
+ );
+
return true;
}
@@ -3190,13 +3542,21 @@ abstract class AbstractPlatform
/**
* Whether this platform can emulate schemas.
*
+ * @deprecated
+ *
* Platforms that either support or emulate schemas don't automatically
- * filter a schema for the namespaced elements in {@link AbstractManager::createSchema()}.
+ * filter a schema for the namespaced elements in {@see AbstractManager::createSchema()}.
*
* @return bool
*/
public function canEmulateSchemas()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4805',
+ 'AbstractPlatform::canEmulateSchemas() is deprecated.'
+ );
+
return false;
}
@@ -3227,10 +3587,18 @@ abstract class AbstractPlatform
/**
* Whether the platform supports getting the affected rows of a recent update/delete type query.
*
+ * @deprecated
+ *
* @return bool
*/
public function supportsGettingAffectedRows()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::supportsGettingAffectedRows() is deprecated.'
+ );
+
return true;
}
@@ -3277,10 +3645,18 @@ abstract class AbstractPlatform
/**
* Whether this platform supports views.
*
+ * @deprecated All platforms must implement support for views.
+ *
* @return bool
*/
public function supportsViews()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::supportsViews() is deprecated. All platforms must implement support for views.'
+ );
+
return true;
}
@@ -3345,11 +3721,9 @@ abstract class AbstractPlatform
* @param int|null $limit
* @param int $offset
*
- * @return string
- *
* @throws Exception
*/
- final public function modifyLimitQuery($query, $limit, $offset = 0)
+ final public function modifyLimitQuery($query, $limit, $offset = 0): string
{
if ($offset < 0) {
throw new Exception(sprintf(
@@ -3384,11 +3758,11 @@ abstract class AbstractPlatform
protected function doModifyLimitQuery($query, $limit, $offset)
{
if ($limit !== null) {
- $query .= ' LIMIT ' . $limit;
+ $query .= sprintf(' LIMIT %d', $limit);
}
if ($offset > 0) {
- $query .= ' OFFSET ' . $offset;
+ $query .= sprintf(' OFFSET %d', $offset);
}
return $query;
@@ -3397,10 +3771,19 @@ abstract class AbstractPlatform
/**
* Whether the database platform support offsets in modify limit clauses.
*
+ * @deprecated All platforms must implement support for offsets in modify limit clauses.
+ *
* @return bool
*/
public function supportsLimitOffset()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/4724',
+ 'AbstractPlatform::supportsViews() is deprecated.'
+ . ' All platforms must implement support for offsets in modify limit clauses.'
+ );
+
return true;
}
@@ -3496,11 +3879,9 @@ abstract class AbstractPlatform
/**
* Returns the keyword list instance of this platform.
*
- * @return KeywordList
- *
* @throws Exception If no keyword list is specified.
*/
- final public function getReservedKeywordsList()
+ final public function getReservedKeywordsList(): KeywordList
{
// Check for an existing instantiation of the keywords class.
if ($this->_keywords === null) {
@@ -3532,7 +3913,7 @@ abstract class AbstractPlatform
/**
* Returns the class name of the reserved keywords list.
*
- * @deprecated Implement {@link createReservedKeywordsList()} instead.
+ * @deprecated Implement {@see createReservedKeywordsList()} instead.
*
* @return string
* @psalm-return class-string<KeywordList>
@@ -3596,6 +3977,27 @@ abstract class AbstractPlatform
}
/**
+ * @return array<string,mixed> An associative array with the name of the properties
+ * of the column being declared as array indexes.
+ */
+ private function columnToArray(Column $column): array
+ {
+ $name = $column->getQuotedName($this);
+
+ $columnData = array_merge($column->toArray(), [
+ 'name' => $name,
+ 'version' => $column->hasPlatformOption('version') ? $column->getPlatformOption('version') : false,
+ 'comment' => $this->getColumnComment($column),
+ ]);
+
+ if ($columnData['type'] instanceof Types\StringType && $columnData['length'] === null) {
+ $columnData['length'] = $this->getVarcharDefaultLength();
+ }
+
+ return $columnData;
+ }
+
+ /**
* @internal
*/
public function createSQLParser(): Parser
@@ -3607,4 +4009,37 @@ abstract class AbstractPlatform
{
return '%_';
}
+
+ /**
+ * Compares the definitions of the given columns in the context of this platform.
+ *
+ * @throws Exception
+ */
+ public function columnsEqual(Column $column1, Column $column2): bool
+ {
+ $column1Array = $this->columnToArray($column1);
+ $column2Array = $this->columnToArray($column2);
+
+ // ignore explicit columnDefinition since it's not set on the Column generated by the SchemaManager
+ unset($column1Array['columnDefinition']);
+ unset($column2Array['columnDefinition']);
+
+ if (
+ $this->getColumnDeclarationSQL('', $column1Array)
+ !== $this->getColumnDeclarationSQL('', $column2Array)
+ ) {
+ return false;
+ }
+
+ // If the platform supports inline comments, all comparison is already done above
+ if ($this->supportsInlineColumnComments()) {
+ return true;
+ }
+
+ if ($column1->getComment() !== $column2->getComment()) {
+ return false;
+ }
+
+ return $column1->getType() === $column2->getType();
+ }
}
diff --git a/doctrine/dbal/src/Platforms/DB2Platform.php b/doctrine/dbal/src/Platforms/DB2Platform.php
index 03631054..979bb2c8 100644
--- a/doctrine/dbal/src/Platforms/DB2Platform.php
+++ b/doctrine/dbal/src/Platforms/DB2Platform.php
@@ -69,7 +69,7 @@ class DB2Platform extends AbstractPlatform
/**
* {@inheritDoc}
*/
- public function initializeDoctrineTypeMappings()
+ protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = [
'bigint' => 'bigint',
@@ -95,6 +95,13 @@ class DB2Platform extends AbstractPlatform
*/
public function isCommentedDoctrineType(Type $doctrineType)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/5058',
+ '%s is deprecated and will be removed in Doctrine DBAL 4.0. Use Type::requiresSQLCommentHint() instead.',
+ __METHOD__
+ );
+
if ($doctrineType->getName() === Types::BOOLEAN) {
// We require a commented boolean type in order to distinguish between boolean and smallint
// as both (have to) map to the same native type.
@@ -135,6 +142,12 @@ class DB2Platform extends AbstractPlatform
*/
public function getName()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4749',
+ 'DB2Platform::getName() is deprecated. Identify platforms by their class.'
+ );
+
return 'db2';
}
@@ -399,52 +412,12 @@ class DB2Platform extends AbstractPlatform
/**
* {@inheritDoc}
*/
- public function getCreateViewSQL($name, $sql)
- {
- return 'CREATE VIEW ' . $name . ' AS ' . $sql;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropViewSQL($name)
- {
- return 'DROP VIEW ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateDatabaseSQL($name)
- {
- return 'CREATE DATABASE ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropDatabaseSQL($name)
- {
- return 'DROP DATABASE ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
public function supportsCreateDropDatabase()
{
return false;
}
/**
- * {@inheritDoc}
- */
- public function supportsReleaseSavepoints()
- {
- return false;
- }
-
- /**
* {@inheritdoc}
*/
public function supportsCommentOnStatement()
@@ -659,11 +632,9 @@ class DB2Platform extends AbstractPlatform
/**
* Returns the ALTER COLUMN SQL clauses for altering a column described by the given column diff.
*
- * @param ColumnDiff $columnDiff The column diff to evaluate.
- *
* @return string[]
*/
- private function getAlterColumnClausesSQL(ColumnDiff $columnDiff)
+ private function getAlterColumnClausesSQL(ColumnDiff $columnDiff): array
{
$column = $columnDiff->column->toArray();
@@ -845,6 +816,14 @@ class DB2Platform extends AbstractPlatform
return 'SUBSTR(' . $string . ', ' . $start . ', ' . $length . ')';
}
+ /**
+ * {@inheritDoc}
+ */
+ public function getLengthExpression($column)
+ {
+ return 'LENGTH(' . $column . ', CODEUNITS32)';
+ }
+
public function getCurrentDatabaseExpression(): string
{
return 'CURRENT_USER';
@@ -860,9 +839,17 @@ class DB2Platform extends AbstractPlatform
/**
* {@inheritDoc}
+ *
+ * @deprecated
*/
public function prefersIdentityColumns()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/1519',
+ 'DB2Platform::prefersIdentityColumns() is deprecated.'
+ );
+
return true;
}
@@ -899,7 +886,7 @@ class DB2Platform extends AbstractPlatform
/**
* {@inheritDoc}
*
- * @deprecated Implement {@link createReservedKeywordsList()} instead.
+ * @deprecated Implement {@see createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
diff --git a/doctrine/dbal/src/Platforms/Keywords/KeywordList.php b/doctrine/dbal/src/Platforms/Keywords/KeywordList.php
index 852a58ab..34b703f3 100644
--- a/doctrine/dbal/src/Platforms/Keywords/KeywordList.php
+++ b/doctrine/dbal/src/Platforms/Keywords/KeywordList.php
@@ -8,6 +8,8 @@ use function strtoupper;
/**
* Abstract interface for a SQL reserved keyword dictionary.
+ *
+ * @psalm-consistent-constructor
*/
abstract class KeywordList
{
diff --git a/doctrine/dbal/src/Platforms/Keywords/MariaDBKeywords.php b/doctrine/dbal/src/Platforms/Keywords/MariaDBKeywords.php
new file mode 100644
index 00000000..93c595f2
--- /dev/null
+++ b/doctrine/dbal/src/Platforms/Keywords/MariaDBKeywords.php
@@ -0,0 +1,267 @@
+<?php
+
+namespace Doctrine\DBAL\Platforms\Keywords;
+
+class MariaDBKeywords extends MySQLKeywords
+{
+ public function getName(): string
+ {
+ return 'MariaDB';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getKeywords(): array
+ {
+ return [
+ 'ACCESSIBLE',
+ 'ADD',
+ 'ALL',
+ 'ALTER',
+ 'ANALYZE',
+ 'AND',
+ 'AS',
+ 'ASC',
+ 'ASENSITIVE',
+ 'BEFORE',
+ 'BETWEEN',
+ 'BIGINT',
+ 'BINARY',
+ 'BLOB',
+ 'BOTH',
+ 'BY',
+ 'CALL',
+ 'CASCADE',
+ 'CASE',
+ 'CHANGE',
+ 'CHAR',
+ 'CHARACTER',
+ 'CHECK',
+ 'COLLATE',
+ 'COLUMN',
+ 'CONDITION',
+ 'CONSTRAINT',
+ 'CONTINUE',
+ 'CONVERT',
+ 'CREATE',
+ 'CROSS',
+ 'CURRENT_DATE',
+ 'CURRENT_TIME',
+ 'CURRENT_TIMESTAMP',
+ 'CURRENT_USER',
+ 'CURSOR',
+ 'DATABASE',
+ 'DATABASES',
+ 'DAY_HOUR',
+ 'DAY_MICROSECOND',
+ 'DAY_MINUTE',
+ 'DAY_SECOND',
+ 'DEC',
+ 'DECIMAL',
+ 'DECLARE',
+ 'DEFAULT',
+ 'DELAYED',
+ 'DELETE',
+ 'DESC',
+ 'DESCRIBE',
+ 'DETERMINISTIC',
+ 'DISTINCT',
+ 'DISTINCTROW',
+ 'DIV',
+ 'DOUBLE',
+ 'DROP',
+ 'DUAL',
+ 'EACH',
+ 'ELSE',
+ 'ELSEIF',
+ 'ENCLOSED',
+ 'ESCAPED',
+ 'EXCEPT',
+ 'EXISTS',
+ 'EXIT',
+ 'EXPLAIN',
+ 'FALSE',
+ 'FETCH',
+ 'FLOAT',
+ 'FLOAT4',
+ 'FLOAT8',
+ 'FOR',
+ 'FORCE',
+ 'FOREIGN',
+ 'FROM',
+ 'FULLTEXT',
+ 'GENERATED',
+ 'GET',
+ 'GENERAL',
+ 'GRANT',
+ 'GROUP',
+ 'HAVING',
+ 'HIGH_PRIORITY',
+ 'HOUR_MICROSECOND',
+ 'HOUR_MINUTE',
+ 'HOUR_SECOND',
+ 'IF',
+ 'IGNORE',
+ 'IGNORE_SERVER_IDS',
+ 'IN',
+ 'INDEX',
+ 'INFILE',
+ 'INNER',
+ 'INOUT',
+ 'INSENSITIVE',
+ 'INSERT',
+ 'INT',
+ 'INT1',
+ 'INT2',
+ 'INT3',
+ 'INT4',
+ 'INT8',
+ 'INTEGER',
+ 'INTERSECT',
+ 'INTERVAL',
+ 'INTO',
+ 'IO_AFTER_GTIDS',
+ 'IO_BEFORE_GTIDS',
+ 'IS',
+ 'ITERATE',
+ 'JOIN',
+ 'KEY',
+ 'KEYS',
+ 'KILL',
+ 'LEADING',
+ 'LEAVE',
+ 'LEFT',
+ 'LIKE',
+ 'LIMIT',
+ 'LINEAR',
+ 'LINES',
+ 'LOAD',
+ 'LOCALTIME',
+ 'LOCALTIMESTAMP',
+ 'LOCK',
+ 'LONG',
+ 'LONGBLOB',
+ 'LONGTEXT',
+ 'LOOP',
+ 'LOW_PRIORITY',
+ 'MASTER_BIND',
+ 'MASTER_HEARTBEAT_PERIOD',
+ 'MASTER_SSL_VERIFY_SERVER_CERT',
+ 'MATCH',
+ 'MAXVALUE',
+ 'MEDIUMBLOB',
+ 'MEDIUMINT',
+ 'MEDIUMTEXT',
+ 'MIDDLEINT',
+ 'MINUTE_MICROSECOND',
+ 'MINUTE_SECOND',
+ 'MOD',
+ 'MODIFIES',
+ 'NATURAL',
+ 'NO_WRITE_TO_BINLOG',
+ 'NOT',
+ 'NULL',
+ 'NUMERIC',
+ 'OFFSET',
+ 'ON',
+ 'OPTIMIZE',
+ 'OPTIMIZER_COSTS',
+ 'OPTION',
+ 'OPTIONALLY',
+ 'OR',
+ 'ORDER',
+ 'OUT',
+ 'OUTER',
+ 'OUTFILE',
+ 'OVER',
+ 'PARTITION',
+ 'PRECISION',
+ 'PRIMARY',
+ 'PROCEDURE',
+ 'PURGE',
+ 'RANGE',
+ 'READ',
+ 'READ_WRITE',
+ 'READS',
+ 'REAL',
+ 'RECURSIVE',
+ 'REFERENCES',
+ 'REGEXP',
+ 'RELEASE',
+ 'RENAME',
+ 'REPEAT',
+ 'REPLACE',
+ 'REQUIRE',
+ 'RESIGNAL',
+ 'RESTRICT',
+ 'RETURN',
+ 'RETURNING',
+ 'REVOKE',
+ 'RIGHT',
+ 'RLIKE',
+ 'ROWS',
+ 'SCHEMA',
+ 'SCHEMAS',
+ 'SECOND_MICROSECOND',
+ 'SELECT',
+ 'SENSITIVE',
+ 'SEPARATOR',
+ 'SET',
+ 'SHOW',
+ 'SIGNAL',
+ 'SLOW',
+ 'SMALLINT',
+ 'SPATIAL',
+ 'SPECIFIC',
+ 'SQL',
+ 'SQL_BIG_RESULT',
+ 'SQL_CALC_FOUND_ROWS',
+ 'SQL_SMALL_RESULT',
+ 'SQLEXCEPTION',
+ 'SQLSTATE',
+ 'SQLWARNING',
+ 'SSL',
+ 'STARTING',
+ 'STORED',
+ 'STRAIGHT_JOIN',
+ 'TABLE',
+ 'TERMINATED',
+ 'THEN',
+ 'TINYBLOB',
+ 'TINYINT',
+ 'TINYTEXT',
+ 'TO',
+ 'TRAILING',
+ 'TRIGGER',
+ 'TRUE',
+ 'UNDO',
+ 'UNION',
+ 'UNIQUE',
+ 'UNLOCK',
+ 'UNSIGNED',
+ 'UPDATE',
+ 'USAGE',
+ 'USE',
+ 'USING',
+ 'UTC_DATE',
+ 'UTC_TIME',
+ 'UTC_TIMESTAMP',
+ 'VALUES',
+ 'VARBINARY',
+ 'VARCHAR',
+ 'VARCHARACTER',
+ 'VARYING',
+ 'VIRTUAL',
+ 'WHEN',
+ 'WHERE',
+ 'WHILE',
+ 'WINDOW',
+ 'WITH',
+ 'WRITE',
+ 'XOR',
+ 'YEAR_MONTH',
+ 'ZEROFILL',
+ ];
+ }
+}
diff --git a/doctrine/dbal/src/Platforms/Keywords/MariaDb102Keywords.php b/doctrine/dbal/src/Platforms/Keywords/MariaDb102Keywords.php
index 8cb2befe..aaa746b8 100644
--- a/doctrine/dbal/src/Platforms/Keywords/MariaDb102Keywords.php
+++ b/doctrine/dbal/src/Platforms/Keywords/MariaDb102Keywords.php
@@ -5,267 +5,14 @@ namespace Doctrine\DBAL\Platforms\Keywords;
/**
* MariaDb reserved keywords list.
*
+ * @deprecated Use {@link MariaDBKeywords} instead.
+ *
* @link https://mariadb.com/kb/en/the-mariadb-library/reserved-words/
*/
-final class MariaDb102Keywords extends MySQLKeywords
+final class MariaDb102Keywords extends MariaDBKeywords
{
public function getName(): string
{
return 'MariaDb102';
}
-
- /**
- * {@inheritdoc}
- */
- protected function getKeywords(): array
- {
- return [
- 'ACCESSIBLE',
- 'ADD',
- 'ALL',
- 'ALTER',
- 'ANALYZE',
- 'AND',
- 'AS',
- 'ASC',
- 'ASENSITIVE',
- 'BEFORE',
- 'BETWEEN',
- 'BIGINT',
- 'BINARY',
- 'BLOB',
- 'BOTH',
- 'BY',
- 'CALL',
- 'CASCADE',
- 'CASE',
- 'CHANGE',
- 'CHAR',
- 'CHARACTER',
- 'CHECK',
- 'COLLATE',
- 'COLUMN',
- 'CONDITION',
- 'CONSTRAINT',
- 'CONTINUE',
- 'CONVERT',
- 'CREATE',
- 'CROSS',
- 'CURRENT_DATE',
- 'CURRENT_TIME',
- 'CURRENT_TIMESTAMP',
- 'CURRENT_USER',
- 'CURSOR',
- 'DATABASE',
- 'DATABASES',
- 'DAY_HOUR',
- 'DAY_MICROSECOND',
- 'DAY_MINUTE',
- 'DAY_SECOND',
- 'DEC',
- 'DECIMAL',
- 'DECLARE',
- 'DEFAULT',
- 'DELAYED',
- 'DELETE',
- 'DESC',
- 'DESCRIBE',
- 'DETERMINISTIC',
- 'DISTINCT',
- 'DISTINCTROW',
- 'DIV',
- 'DOUBLE',
- 'DROP',
- 'DUAL',
- 'EACH',
- 'ELSE',
- 'ELSEIF',
- 'ENCLOSED',
- 'ESCAPED',
- 'EXCEPT',
- 'EXISTS',
- 'EXIT',
- 'EXPLAIN',
- 'FALSE',
- 'FETCH',
- 'FLOAT',
- 'FLOAT4',
- 'FLOAT8',
- 'FOR',
- 'FORCE',
- 'FOREIGN',
- 'FROM',
- 'FULLTEXT',
- 'GENERATED',
- 'GET',
- 'GENERAL',
- 'GRANT',
- 'GROUP',
- 'HAVING',
- 'HIGH_PRIORITY',
- 'HOUR_MICROSECOND',
- 'HOUR_MINUTE',
- 'HOUR_SECOND',
- 'IF',
- 'IGNORE',
- 'IGNORE_SERVER_IDS',
- 'IN',
- 'INDEX',
- 'INFILE',
- 'INNER',
- 'INOUT',
- 'INSENSITIVE',
- 'INSERT',
- 'INT',
- 'INT1',
- 'INT2',
- 'INT3',
- 'INT4',
- 'INT8',
- 'INTEGER',
- 'INTERSECT',
- 'INTERVAL',
- 'INTO',
- 'IO_AFTER_GTIDS',
- 'IO_BEFORE_GTIDS',
- 'IS',
- 'ITERATE',
- 'JOIN',
- 'KEY',
- 'KEYS',
- 'KILL',
- 'LEADING',
- 'LEAVE',
- 'LEFT',
- 'LIKE',
- 'LIMIT',
- 'LINEAR',
- 'LINES',
- 'LOAD',
- 'LOCALTIME',
- 'LOCALTIMESTAMP',
- 'LOCK',
- 'LONG',
- 'LONGBLOB',
- 'LONGTEXT',
- 'LOOP',
- 'LOW_PRIORITY',
- 'MASTER_BIND',
- 'MASTER_HEARTBEAT_PERIOD',
- 'MASTER_SSL_VERIFY_SERVER_CERT',
- 'MATCH',
- 'MAXVALUE',
- 'MEDIUMBLOB',
- 'MEDIUMINT',
- 'MEDIUMTEXT',
- 'MIDDLEINT',
- 'MINUTE_MICROSECOND',
- 'MINUTE_SECOND',
- 'MOD',
- 'MODIFIES',
- 'NATURAL',
- 'NO_WRITE_TO_BINLOG',
- 'NOT',
- 'NULL',
- 'NUMERIC',
- 'ON',
- 'OPTIMIZE',
- 'OPTIMIZER_COSTS',
- 'OPTION',
- 'OPTIONALLY',
- 'OR',
- 'ORDER',
- 'OUT',
- 'OUTER',
- 'OUTFILE',
- 'OVER',
- 'PARTITION',
- 'PRECISION',
- 'PRIMARY',
- 'PROCEDURE',
- 'PURGE',
- 'RANGE',
- 'READ',
- 'READ_WRITE',
- 'READS',
- 'REAL',
- 'RECURSIVE',
- 'REFERENCES',
- 'REGEXP',
- 'RELEASE',
- 'RENAME',
- 'REPEAT',
- 'REPLACE',
- 'REQUIRE',
- 'RESIGNAL',
- 'RESTRICT',
- 'RETURN',
- 'RETURNING',
- 'REVOKE',
- 'RIGHT',
- 'RLIKE',
- 'ROWS',
- 'SCHEMA',
- 'SCHEMAS',
- 'SECOND_MICROSECOND',
- 'SELECT',
- 'SENSITIVE',
- 'SEPARATOR',
- 'SET',
- 'SHOW',
- 'SIGNAL',
- 'SLOW',
- 'SMALLINT',
- 'SPATIAL',
- 'SPECIFIC',
- 'SQL',
- 'SQL_BIG_RESULT',
- 'SQL_CALC_FOUND_ROWS',
- 'SQL_SMALL_RESULT',
- 'SQLEXCEPTION',
- 'SQLSTATE',
- 'SQLWARNING',
- 'SSL',
- 'STARTING',
- 'STORED',
- 'STRAIGHT_JOIN',
- 'TABLE',
- 'TERMINATED',
- 'THEN',
- 'TINYBLOB',
- 'TINYINT',
- 'TINYTEXT',
- 'TO',
- 'TRAILING',
- 'TRIGGER',
- 'TRUE',
- 'UNDO',
- 'UNION',
- 'UNIQUE',
- 'UNLOCK',
- 'UNSIGNED',
- 'UPDATE',
- 'USAGE',
- 'USE',
- 'USING',
- 'UTC_DATE',
- 'UTC_TIME',
- 'UTC_TIMESTAMP',
- 'VALUES',
- 'VARBINARY',
- 'VARCHAR',
- 'VARCHARACTER',
- 'VARYING',
- 'VIRTUAL',
- 'WHEN',
- 'WHERE',
- 'WHILE',
- 'WINDOW',
- 'WITH',
- 'WRITE',
- 'XOR',
- 'YEAR_MONTH',
- 'ZEROFILL',
- ];
- }
}
diff --git a/doctrine/dbal/src/Platforms/Keywords/MySQL57Keywords.php b/doctrine/dbal/src/Platforms/Keywords/MySQL57Keywords.php
index 9b60a3f1..19b49fb9 100644
--- a/doctrine/dbal/src/Platforms/Keywords/MySQL57Keywords.php
+++ b/doctrine/dbal/src/Platforms/Keywords/MySQL57Keywords.php
@@ -4,6 +4,8 @@ namespace Doctrine\DBAL\Platforms\Keywords;
/**
* MySQL 5.7 reserved keywords list.
+ *
+ * @deprecated Use {@link MySQLKeywords} instead.
*/
class MySQL57Keywords extends MySQLKeywords
{
diff --git a/doctrine/dbal/src/Platforms/Keywords/PostgreSQL100Keywords.php b/doctrine/dbal/src/Platforms/Keywords/PostgreSQL100Keywords.php
index dad68ead..fab01864 100644
--- a/doctrine/dbal/src/Platforms/Keywords/PostgreSQL100Keywords.php
+++ b/doctrine/dbal/src/Platforms/Keywords/PostgreSQL100Keywords.php
@@ -6,6 +6,8 @@ namespace Doctrine\DBAL\Platforms\Keywords;
/**
* PostgreSQL 10.0 reserved keywords list.
+ *
+ * @deprecated Use {@link PostgreSQLKeywords} instead.
*/
class PostgreSQL100Keywords extends PostgreSQL94Keywords
{
diff --git a/doctrine/dbal/src/Platforms/Keywords/PostgreSQL94Keywords.php b/doctrine/dbal/src/Platforms/Keywords/PostgreSQL94Keywords.php
index eeff23ca..88d4ac32 100644
--- a/doctrine/dbal/src/Platforms/Keywords/PostgreSQL94Keywords.php
+++ b/doctrine/dbal/src/Platforms/Keywords/PostgreSQL94Keywords.php
@@ -4,122 +4,9 @@ namespace Doctrine\DBAL\Platforms\Keywords;
/**
* PostgreSQL 9.4 reserved keywords list.
+ *
+ * @deprecated Use {@see PostgreSQLKeywords} instead.
*/
-class PostgreSQL94Keywords extends KeywordList
+class PostgreSQL94Keywords extends PostgreSQLKeywords
{
- /**
- * {@inheritdoc}
- */
- public function getName()
- {
- return 'PostgreSQL';
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getKeywords()
- {
- return [
- 'ALL',
- 'ANALYSE',
- 'ANALYZE',
- 'AND',
- 'ANY',
- 'ARRAY',
- 'AS',
- 'ASC',
- 'ASYMMETRIC',
- 'AUTHORIZATION',
- 'BINARY',
- 'BOTH',
- 'CASE',
- 'CAST',
- 'CHECK',
- 'COLLATE',
- 'COLLATION',
- 'COLUMN',
- 'CONCURRENTLY',
- 'CONSTRAINT',
- 'CREATE',
- 'CROSS',
- 'CURRENT_CATALOG',
- 'CURRENT_DATE',
- 'CURRENT_ROLE',
- 'CURRENT_SCHEMA',
- 'CURRENT_TIME',
- 'CURRENT_TIMESTAMP',
- 'CURRENT_USER',
- 'DEFAULT',
- 'DEFERRABLE',
- 'DESC',
- 'DISTINCT',
- 'DO',
- 'ELSE',
- 'END',
- 'EXCEPT',
- 'FALSE',
- 'FETCH',
- 'FOR',
- 'FOREIGN',
- 'FREEZE',
- 'FROM',
- 'FULL',
- 'GRANT',
- 'GROUP',
- 'HAVING',
- 'ILIKE',
- 'IN',
- 'INITIALLY',
- 'INNER',
- 'INTERSECT',
- 'INTO',
- 'IS',
- 'ISNULL',
- 'JOIN',
- 'LATERAL',
- 'LEADING',
- 'LEFT',
- 'LIKE',
- 'LIMIT',
- 'LOCALTIME',
- 'LOCALTIMESTAMP',
- 'NATURAL',
- 'NOT',
- 'NOTNULL',
- 'NULL',
- 'OFFSET',
- 'ON',
- 'ONLY',
- 'OR',
- 'ORDER',
- 'OUTER',
- 'OVERLAPS',
- 'PLACING',
- 'PRIMARY',
- 'REFERENCES',
- 'RETURNING',
- 'RIGHT',
- 'SELECT',
- 'SESSION_USER',
- 'SIMILAR',
- 'SOME',
- 'SYMMETRIC',
- 'TABLE',
- 'THEN',
- 'TO',
- 'TRAILING',
- 'TRUE',
- 'UNION',
- 'UNIQUE',
- 'USER',
- 'USING',
- 'VARIADIC',
- 'VERBOSE',
- 'WHEN',
- 'WHERE',
- 'WINDOW',
- 'WITH',
- ];
- }
}
diff --git a/doctrine/dbal/src/Platforms/Keywords/PostgreSQLKeywords.php b/doctrine/dbal/src/Platforms/Keywords/PostgreSQLKeywords.php
new file mode 100644
index 00000000..47ccfdfb
--- /dev/null
+++ b/doctrine/dbal/src/Platforms/Keywords/PostgreSQLKeywords.php
@@ -0,0 +1,125 @@
+<?php
+
+namespace Doctrine\DBAL\Platforms\Keywords;
+
+/**
+ * Reserved keywords list corresponding to the PostgreSQL database platform of the oldest supported version.
+ */
+class PostgreSQLKeywords extends KeywordList
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'PostgreSQL';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getKeywords()
+ {
+ return [
+ 'ALL',
+ 'ANALYSE',
+ 'ANALYZE',
+ 'AND',
+ 'ANY',
+ 'ARRAY',
+ 'AS',
+ 'ASC',
+ 'ASYMMETRIC',
+ 'AUTHORIZATION',
+ 'BINARY',
+ 'BOTH',
+ 'CASE',
+ 'CAST',
+ 'CHECK',
+ 'COLLATE',
+ 'COLLATION',
+ 'COLUMN',
+ 'CONCURRENTLY',
+ 'CONSTRAINT',
+ 'CREATE',
+ 'CROSS',
+ 'CURRENT_CATALOG',
+ 'CURRENT_DATE',
+ 'CURRENT_ROLE',
+ 'CURRENT_SCHEMA',
+ 'CURRENT_TIME',
+ 'CURRENT_TIMESTAMP',
+ 'CURRENT_USER',
+ 'DEFAULT',
+ 'DEFERRABLE',
+ 'DESC',
+ 'DISTINCT',
+ 'DO',
+ 'ELSE',
+ 'END',
+ 'EXCEPT',
+ 'FALSE',
+ 'FETCH',
+ 'FOR',
+ 'FOREIGN',
+ 'FREEZE',
+ 'FROM',
+ 'FULL',
+ 'GRANT',
+ 'GROUP',
+ 'HAVING',
+ 'ILIKE',
+ 'IN',
+ 'INITIALLY',
+ 'INNER',
+ 'INTERSECT',
+ 'INTO',
+ 'IS',
+ 'ISNULL',
+ 'JOIN',
+ 'LATERAL',
+ 'LEADING',
+ 'LEFT',
+ 'LIKE',
+ 'LIMIT',
+ 'LOCALTIME',
+ 'LOCALTIMESTAMP',
+ 'NATURAL',
+ 'NOT',
+ 'NOTNULL',
+ 'NULL',
+ 'OFFSET',
+ 'ON',
+ 'ONLY',
+ 'OR',
+ 'ORDER',
+ 'OUTER',
+ 'OVERLAPS',
+ 'PLACING',
+ 'PRIMARY',
+ 'REFERENCES',
+ 'RETURNING',
+ 'RIGHT',
+ 'SELECT',
+ 'SESSION_USER',
+ 'SIMILAR',
+ 'SOME',
+ 'SYMMETRIC',
+ 'TABLE',
+ 'THEN',
+ 'TO',
+ 'TRAILING',
+ 'TRUE',
+ 'UNION',
+ 'UNIQUE',
+ 'USER',
+ 'USING',
+ 'VARIADIC',
+ 'VERBOSE',
+ 'WHEN',
+ 'WHERE',
+ 'WINDOW',
+ 'WITH',
+ ];
+ }
+}
diff --git a/doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php b/doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php
index a6da7746..bd4faf50 100644
--- a/doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php
+++ b/doctrine/dbal/src/Platforms/Keywords/ReservedKeywordsValidator.php
@@ -43,7 +43,7 @@ class ReservedKeywordsValidator implements Visitor
*
* @return string[]
*/
- private function isReservedWord($word)
+ private function isReservedWord($word): array
{
if ($word[0] === '`') {
$word = str_replace('`', '', $word);
@@ -64,10 +64,8 @@ class ReservedKeywordsValidator implements Visitor
/**
* @param string $asset
* @param string[] $violatedPlatforms
- *
- * @return void
*/
- private function addViolation($asset, $violatedPlatforms)
+ private function addViolation($asset, $violatedPlatforms): void
{
if (count($violatedPlatforms) === 0) {
return;
diff --git a/doctrine/dbal/src/Platforms/Keywords/SQLServer2012Keywords.php b/doctrine/dbal/src/Platforms/Keywords/SQLServer2012Keywords.php
index 24e190bf..ebc45c40 100644
--- a/doctrine/dbal/src/Platforms/Keywords/SQLServer2012Keywords.php
+++ b/doctrine/dbal/src/Platforms/Keywords/SQLServer2012Keywords.php
@@ -4,210 +4,9 @@ namespace Doctrine\DBAL\Platforms\Keywords;
/**
* Microsoft SQL Server 2012 reserved keyword dictionary.
+ *
+ * @deprecated Use {@see SQLServerKeywords} instead.
*/
-class SQLServer2012Keywords extends KeywordList
+class SQLServer2012Keywords extends SQLServerKeywords
{
- /**
- * {@inheritdoc}
- */
- public function getName()
- {
- return 'SQLServer';
- }
-
- /**
- * {@inheritdoc}
- *
- * @link http://msdn.microsoft.com/en-us/library/aa238507%28v=sql.80%29.aspx
- */
- protected function getKeywords()
- {
- return [
- 'ADD',
- 'ALL',
- 'ALTER',
- 'AND',
- 'ANY',
- 'AS',
- 'ASC',
- 'AUTHORIZATION',
- 'BACKUP',
- 'BEGIN',
- 'BETWEEN',
- 'BREAK',
- 'BROWSE',
- 'BULK',
- 'BY',
- 'CASCADE',
- 'CASE',
- 'CHECK',
- 'CHECKPOINT',
- 'CLOSE',
- 'CLUSTERED',
- 'COALESCE',
- 'COLLATE',
- 'COLUMN',
- 'COMMIT',
- 'COMPUTE',
- 'CONSTRAINT',
- 'CONTAINS',
- 'CONTAINSTABLE',
- 'CONTINUE',
- 'CONVERT',
- 'CREATE',
- 'CROSS',
- 'CURRENT',
- 'CURRENT_DATE',
- 'CURRENT_TIME',
- 'CURRENT_TIMESTAMP',
- 'CURRENT_USER',
- 'CURSOR',
- 'DATABASE',
- 'DBCC',
- 'DEALLOCATE',
- 'DECLARE',
- 'DEFAULT',
- 'DELETE',
- 'DENY',
- 'DESC',
- 'DISK',
- 'DISTINCT',
- 'DISTRIBUTED',
- 'DOUBLE',
- 'DROP',
- 'DUMP',
- 'ELSE',
- 'END',
- 'ERRLVL',
- 'ESCAPE',
- 'EXCEPT',
- 'EXEC',
- 'EXECUTE',
- 'EXISTS',
- 'EXIT',
- 'EXTERNAL',
- 'FETCH',
- 'FILE',
- 'FILLFACTOR',
- 'FOR',
- 'FOREIGN',
- 'FREETEXT',
- 'FREETEXTTABLE',
- 'FROM',
- 'FULL',
- 'FUNCTION',
- 'GOTO',
- 'GRANT',
- 'GROUP',
- 'HAVING',
- 'HOLDLOCK',
- 'IDENTITY',
- 'IDENTITY_INSERT',
- 'IDENTITYCOL',
- 'IF',
- 'IN',
- 'INDEX',
- 'INNER',
- 'INSERT',
- 'INTERSECT',
- 'INTO',
- 'IS',
- 'JOIN',
- 'KEY',
- 'KILL',
- 'LEFT',
- 'LIKE',
- 'LINENO',
- 'LOAD',
- 'MERGE',
- 'NATIONAL',
- 'NOCHECK ',
- 'NONCLUSTERED',
- 'NOT',
- 'NULL',
- 'NULLIF',
- 'OF',
- 'OFF',
- 'OFFSETS',
- 'ON',
- 'OPEN',
- 'OPENDATASOURCE',
- 'OPENQUERY',
- 'OPENROWSET',
- 'OPENXML',
- 'OPTION',
- 'OR',
- 'ORDER',
- 'OUTER',
- 'OVER',
- 'PERCENT',
- 'PIVOT',
- 'PLAN',
- 'PRECISION',
- 'PRIMARY',
- 'PRINT',
- 'PROC',
- 'PROCEDURE',
- 'PUBLIC',
- 'RAISERROR',
- 'READ',
- 'READTEXT',
- 'RECONFIGURE',
- 'REFERENCES',
- 'REPLICATION',
- 'RESTORE',
- 'RESTRICT',
- 'RETURN',
- 'REVERT',
- 'REVOKE',
- 'RIGHT',
- 'ROLLBACK',
- 'ROWCOUNT',
- 'ROWGUIDCOL',
- 'RULE',
- 'SAVE',
- 'SCHEMA',
- 'SECURITYAUDIT',
- 'SELECT',
- 'SEMANTICKEYPHRASETABLE',
- 'SEMANTICSIMILARITYDETAILSTABLE',
- 'SEMANTICSIMILARITYTABLE',
- 'SESSION_USER',
- 'SET',
- 'SETUSER',
- 'SHUTDOWN',
- 'SOME',
- 'STATISTICS',
- 'SYSTEM_USER',
- 'TABLE',
- 'TABLESAMPLE',
- 'TEXTSIZE',
- 'THEN',
- 'TO',
- 'TOP',
- 'TRAN',
- 'TRANSACTION',
- 'TRIGGER',
- 'TRUNCATE',
- 'TRY_CONVERT',
- 'TSEQUAL',
- 'UNION',
- 'UNIQUE',
- 'UNPIVOT',
- 'UPDATE',
- 'UPDATETEXT',
- 'USE',
- 'USER',
- 'VALUES',
- 'VARYING',
- 'VIEW',
- 'WAITFOR',
- 'WHEN',
- 'WHERE',
- 'WHILE',
- 'WITH',
- 'WITHIN GROUP',
- 'WRITETEXT',
- ];
- }
}
diff --git a/doctrine/dbal/src/Platforms/Keywords/SQLServerKeywords.php b/doctrine/dbal/src/Platforms/Keywords/SQLServerKeywords.php
new file mode 100644
index 00000000..0ea413ce
--- /dev/null
+++ b/doctrine/dbal/src/Platforms/Keywords/SQLServerKeywords.php
@@ -0,0 +1,214 @@
+<?php
+
+namespace Doctrine\DBAL\Platforms\Keywords;
+
+/**
+ * Microsoft SQL Server 2012 reserved keyword dictionary.
+ * Reserved keywords list corresponding to the Microsoft SQL Server database platform of the oldest supported version.
+ */
+class SQLServerKeywords extends KeywordList
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'SQLServer';
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @link http://msdn.microsoft.com/en-us/library/aa238507%28v=sql.80%29.aspx
+ */
+ protected function getKeywords()
+ {
+ return [
+ 'ADD',
+ 'ALL',
+ 'ALTER',
+ 'AND',
+ 'ANY',
+ 'AS',
+ 'ASC',
+ 'AUTHORIZATION',
+ 'BACKUP',
+ 'BEGIN',
+ 'BETWEEN',
+ 'BREAK',
+ 'BROWSE',
+ 'BULK',
+ 'BY',
+ 'CASCADE',
+ 'CASE',
+ 'CHECK',
+ 'CHECKPOINT',
+ 'CLOSE',
+ 'CLUSTERED',
+ 'COALESCE',
+ 'COLLATE',
+ 'COLUMN',
+ 'COMMIT',
+ 'COMPUTE',
+ 'CONSTRAINT',
+ 'CONTAINS',
+ 'CONTAINSTABLE',
+ 'CONTINUE',
+ 'CONVERT',
+ 'CREATE',
+ 'CROSS',
+ 'CURRENT',
+ 'CURRENT_DATE',
+ 'CURRENT_TIME',
+ 'CURRENT_TIMESTAMP',
+ 'CURRENT_USER',
+ 'CURSOR',
+ 'DATABASE',
+ 'DBCC',
+ 'DEALLOCATE',
+ 'DECLARE',
+ 'DEFAULT',
+ 'DELETE',
+ 'DENY',
+ 'DESC',
+ 'DISK',
+ 'DISTINCT',
+ 'DISTRIBUTED',
+ 'DOUBLE',
+ 'DROP',
+ 'DUMP',
+ 'ELSE',
+ 'END',
+ 'ERRLVL',
+ 'ESCAPE',
+ 'EXCEPT',
+ 'EXEC',
+ 'EXECUTE',
+ 'EXISTS',
+ 'EXIT',
+ 'EXTERNAL',
+ 'FETCH',
+ 'FILE',
+ 'FILLFACTOR',
+ 'FOR',
+ 'FOREIGN',
+ 'FREETEXT',
+ 'FREETEXTTABLE',
+ 'FROM',
+ 'FULL',
+ 'FUNCTION',
+ 'GOTO',
+ 'GRANT',
+ 'GROUP',
+ 'HAVING',
+ 'HOLDLOCK',
+ 'IDENTITY',
+ 'IDENTITY_INSERT',
+ 'IDENTITYCOL',
+ 'IF',
+ 'IN',
+ 'INDEX',
+ 'INNER',
+ 'INSERT',
+ 'INTERSECT',
+ 'INTO',
+ 'IS',
+ 'JOIN',
+ 'KEY',
+ 'KILL',
+ 'LEFT',
+ 'LIKE',
+ 'LINENO',
+ 'LOAD',
+ 'MERGE',
+ 'NATIONAL',
+ 'NOCHECK ',
+ 'NONCLUSTERED',
+ 'NOT',
+ 'NULL',
+ 'NULLIF',
+ 'OF',
+ 'OFF',
+ 'OFFSETS',
+ 'ON',
+ 'OPEN',
+ 'OPENDATASOURCE',
+ 'OPENQUERY',
+ 'OPENROWSET',
+ 'OPENXML',
+ 'OPTION',
+ 'OR',
+ 'ORDER',
+ 'OUTER',
+ 'OVER',
+ 'PERCENT',
+ 'PIVOT',
+ 'PLAN',
+ 'PRECISION',
+ 'PRIMARY',
+ 'PRINT',
+ 'PROC',
+ 'PROCEDURE',
+ 'PUBLIC',
+ 'RAISERROR',
+ 'READ',
+ 'READTEXT',
+ 'RECONFIGURE',
+ 'REFERENCES',
+ 'REPLICATION',
+ 'RESTORE',
+ 'RESTRICT',
+ 'RETURN',
+ 'REVERT',
+ 'REVOKE',
+ 'RIGHT',
+ 'ROLLBACK',
+ 'ROWCOUNT',
+ 'ROWGUIDCOL',
+ 'RULE',
+ 'SAVE',
+ 'SCHEMA',
+ 'SECURITYAUDIT',
+ 'SELECT',
+ 'SEMANTICKEYPHRASETABLE',
+ 'SEMANTICSIMILARITYDETAILSTABLE',
+ 'SEMANTICSIMILARITYTABLE',
+ 'SESSION_USER',
+ 'SET',
+ 'SETUSER',
+ 'SHUTDOWN',
+ 'SOME',
+ 'STATISTICS',
+ 'SYSTEM_USER',
+ 'TABLE',
+ 'TABLESAMPLE',
+ 'TEXTSIZE',
+ 'THEN',
+ 'TO',
+ 'TOP',
+ 'TRAN',
+ 'TRANSACTION',
+ 'TRIGGER',
+ 'TRUNCATE',
+ 'TRY_CONVERT',
+ 'TSEQUAL',
+ 'UNION',
+ 'UNIQUE',
+ 'UNPIVOT',
+ 'UPDATE',
+ 'UPDATETEXT',
+ 'USE',
+ 'USER',
+ 'VALUES',
+ 'VARYING',
+ 'VIEW',
+ 'WAITFOR',
+ 'WHEN',
+ 'WHERE',
+ 'WHILE',
+ 'WITH',
+ 'WITHIN GROUP',
+ 'WRITETEXT',
+ ];
+ }
+}
diff --git a/doctrine/dbal/src/Platforms/MariaDBPlatform.php b/doctrine/dbal/src/Platforms/MariaDBPlatform.php
new file mode 100644
index 00000000..e877b70f
--- /dev/null
+++ b/doctrine/dbal/src/Platforms/MariaDBPlatform.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\Types\Types;
+use Doctrine\Deprecations\Deprecation;
+
+/**
+ * Provides the behavior, features and SQL dialect of the MariaDB database platform of the oldest supported version.
+ */
+class MariaDBPlatform extends MySQLPlatform
+{
+ /**
+ * {@inheritdoc}
+ *
+ * @link https://mariadb.com/kb/en/library/json-data-type/
+ */
+ public function getJsonTypeDeclarationSQL(array $column): string
+ {
+ return 'LONGTEXT';
+ }
+
+ /**
+ * @deprecated Implement {@see 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;
+ }
+
+ protected function initializeDoctrineTypeMappings(): void
+ {
+ parent::initializeDoctrineTypeMappings();
+
+ $this->doctrineTypeMapping['json'] = Types::JSON;
+ }
+}
diff --git a/doctrine/dbal/src/Platforms/MariaDb1027Platform.php b/doctrine/dbal/src/Platforms/MariaDb1027Platform.php
index bb8e0b88..93c7d348 100644
--- a/doctrine/dbal/src/Platforms/MariaDb1027Platform.php
+++ b/doctrine/dbal/src/Platforms/MariaDb1027Platform.php
@@ -2,45 +2,14 @@
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.
*
* Note: Should not be used with versions prior to 10.2.7.
+ *
+ * @deprecated This class will be merged with {@see MariaDBPlatform} in 4.0 because support for MariaDB
+ * releases prior to 10.2.7 will be dropped.
*/
-class MariaDb1027Platform extends MySQLPlatform
+class MariaDb1027Platform extends MariaDBPlatform
{
- /**
- * {@inheritdoc}
- *
- * @link https://mariadb.com/kb/en/library/json-data-type/
- */
- public function getJsonTypeDeclarationSQL(array $column): string
- {
- 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;
- }
-
- protected function initializeDoctrineTypeMappings(): void
- {
- parent::initializeDoctrineTypeMappings();
-
- $this->doctrineTypeMapping['json'] = Types::JSON;
- }
}
diff --git a/doctrine/dbal/src/Platforms/MySQL/Comparator.php b/doctrine/dbal/src/Platforms/MySQL/Comparator.php
new file mode 100644
index 00000000..81c54dbc
--- /dev/null
+++ b/doctrine/dbal/src/Platforms/MySQL/Comparator.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Doctrine\DBAL\Platforms\MySQL;
+
+use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
+use Doctrine\DBAL\Schema\Comparator as BaseComparator;
+use Doctrine\DBAL\Schema\Table;
+
+use function array_diff_assoc;
+use function array_intersect_key;
+
+/**
+ * Compares schemas in the context of MySQL platform.
+ *
+ * In MySQL, unless specified explicitly, the column's character set and collation are inherited from its containing
+ * table. So during comparison, an omitted value and the value that matches the default value of table in the
+ * desired schema must be considered equal.
+ */
+class Comparator extends BaseComparator
+{
+ /**
+ * @internal The comparator can be only instantiated by a schema manager.
+ */
+ public function __construct(AbstractMySQLPlatform $platform)
+ {
+ parent::__construct($platform);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function diffTable(Table $fromTable, Table $toTable)
+ {
+ return parent::diffTable(
+ $this->normalizeColumns($fromTable),
+ $this->normalizeColumns($toTable)
+ );
+ }
+
+ private function normalizeColumns(Table $table): Table
+ {
+ $defaults = array_intersect_key($table->getOptions(), [
+ 'charset' => null,
+ 'collation' => null,
+ ]);
+
+ if ($defaults === []) {
+ return $table;
+ }
+
+ $table = clone $table;
+
+ foreach ($table->getColumns() as $column) {
+ $options = $column->getPlatformOptions();
+ $diff = array_diff_assoc($options, $defaults);
+
+ if ($diff === $options) {
+ continue;
+ }
+
+ $column->setPlatformOptions($diff);
+ }
+
+ return $table;
+ }
+}
diff --git a/doctrine/dbal/src/Platforms/MySQL57Platform.php b/doctrine/dbal/src/Platforms/MySQL57Platform.php
index f29204cf..3975bf2c 100644
--- a/doctrine/dbal/src/Platforms/MySQL57Platform.php
+++ b/doctrine/dbal/src/Platforms/MySQL57Platform.php
@@ -10,6 +10,9 @@ use Doctrine\Deprecations\Deprecation;
/**
* Provides the behavior, features and SQL dialect of the MySQL 5.7 (5.7.9 GA) database platform.
+ *
+ * @deprecated This class will be merged with {@see MySQLPlatform} in 4.0 because support for MySQL
+ * releases prior to 5.7 will be dropped.
*/
class MySQL57Platform extends MySQLPlatform
{
@@ -61,7 +64,7 @@ class MySQL57Platform extends MySQLPlatform
/**
* {@inheritdoc}
*
- * @deprecated Implement {@link createReservedKeywordsList()} instead.
+ * @deprecated Implement {@see createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
diff --git a/doctrine/dbal/src/Platforms/MySQL80Platform.php b/doctrine/dbal/src/Platforms/MySQL80Platform.php
index 808e9344..536a79f4 100644
--- a/doctrine/dbal/src/Platforms/MySQL80Platform.php
+++ b/doctrine/dbal/src/Platforms/MySQL80Platform.php
@@ -12,7 +12,7 @@ class MySQL80Platform extends MySQL57Platform
/**
* {@inheritdoc}
*
- * @deprecated Implement {@link createReservedKeywordsList()} instead.
+ * @deprecated Implement {@see createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
diff --git a/doctrine/dbal/src/Platforms/MySQLPlatform.php b/doctrine/dbal/src/Platforms/MySQLPlatform.php
index 379616f2..ae2cc9f2 100644
--- a/doctrine/dbal/src/Platforms/MySQLPlatform.php
+++ b/doctrine/dbal/src/Platforms/MySQLPlatform.php
@@ -2,1193 +2,10 @@
namespace Doctrine\DBAL\Platforms;
-use Doctrine\DBAL\Exception;
-use Doctrine\DBAL\Schema\ForeignKeyConstraint;
-use Doctrine\DBAL\Schema\Identifier;
-use Doctrine\DBAL\Schema\Index;
-use Doctrine\DBAL\Schema\Table;
-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;
-use function array_merge;
-use function array_unique;
-use function array_values;
-use function count;
-use function func_get_args;
-use function implode;
-use function in_array;
-use function is_numeric;
-use function is_string;
-use function sprintf;
-use function str_replace;
-use function strtoupper;
-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.
+ * Provides the behavior, features and SQL dialect of the Oracle MySQL database platform
+ * of the oldest supported version.
*/
-class MySQLPlatform extends AbstractPlatform
+class MySQLPlatform extends AbstractMySQLPlatform
{
- public const LENGTH_LIMIT_TINYTEXT = 255;
- public const LENGTH_LIMIT_TEXT = 65535;
- public const LENGTH_LIMIT_MEDIUMTEXT = 16777215;
-
- public const LENGTH_LIMIT_TINYBLOB = 255;
- public const LENGTH_LIMIT_BLOB = 65535;
- public const LENGTH_LIMIT_MEDIUMBLOB = 16777215;
-
- /**
- * {@inheritDoc}
- */
- protected function doModifyLimitQuery($query, $limit, $offset)
- {
- if ($limit !== null) {
- $query .= ' LIMIT ' . $limit;
-
- if ($offset > 0) {
- $query .= ' OFFSET ' . $offset;
- }
- } elseif ($offset > 0) {
- // 2^64-1 is the maximum of unsigned BIGINT, the biggest limit possible
- $query .= ' LIMIT 18446744073709551615 OFFSET ' . $offset;
- }
-
- return $query;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getIdentifierQuoteCharacter()
- {
- return '`';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getRegexpExpression()
- {
- return 'RLIKE';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getLocateExpression($str, $substr, $startPos = false)
- {
- if ($startPos === false) {
- return 'LOCATE(' . $substr . ', ' . $str . ')';
- }
-
- return 'LOCATE(' . $substr . ', ' . $str . ', ' . $startPos . ')';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getConcatExpression()
- {
- return sprintf('CONCAT(%s)', implode(', ', func_get_args()));
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit)
- {
- $function = $operator === '+' ? 'DATE_ADD' : 'DATE_SUB';
-
- return $function . '(' . $date . ', INTERVAL ' . $interval . ' ' . $unit . ')';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateDiffExpression($date1, $date2)
- {
- return 'DATEDIFF(' . $date1 . ', ' . $date2 . ')';
- }
-
- public function getCurrentDatabaseExpression(): string
- {
- return 'DATABASE()';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListDatabasesSQL()
- {
- return 'SHOW DATABASES';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTableConstraintsSQL($table)
- {
- return 'SHOW INDEX FROM ' . $table;
- }
-
- /**
- * {@inheritDoc}
- *
- * Two approaches to listing the table indexes. The information_schema is
- * preferred, because it doesn't cause problems with SQL keywords such as "order" or "table".
- */
- public function getListTableIndexesSQL($table, $database = null)
- {
- if ($database !== null) {
- $database = $this->quoteStringLiteral($database);
- $table = $this->quoteStringLiteral($table);
-
- return 'SELECT NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, COLUMN_NAME AS Column_Name,' .
- ' SUB_PART AS Sub_Part, INDEX_TYPE AS Index_Type' .
- ' FROM information_schema.STATISTICS WHERE TABLE_NAME = ' . $table .
- ' AND TABLE_SCHEMA = ' . $database .
- ' ORDER BY SEQ_IN_INDEX ASC';
- }
-
- return 'SHOW INDEX FROM ' . $table;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListViewsSQL($database)
- {
- $database = $this->quoteStringLiteral($database);
-
- return 'SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = ' . $database;
- }
-
- /**
- * @param string $table
- * @param string|null $database
- *
- * @return string
- */
- public function getListTableForeignKeysSQL($table, $database = null)
- {
- $table = $this->quoteStringLiteral($table);
-
- if ($database !== null) {
- $database = $this->quoteStringLiteral($database);
- }
-
- $sql = 'SELECT DISTINCT k.`CONSTRAINT_NAME`, k.`COLUMN_NAME`, k.`REFERENCED_TABLE_NAME`, ' .
- 'k.`REFERENCED_COLUMN_NAME`, k.`ORDINAL_POSITION` /*!50116 , c.update_rule, c.delete_rule */ ' .
- 'FROM information_schema.key_column_usage k /*!50116 ' .
- 'INNER JOIN information_schema.referential_constraints c ON ' .
- ' c.constraint_name = k.constraint_name AND ' .
- ' c.table_name = ' . $table . ' */ WHERE k.table_name = ' . $table;
-
- $databaseNameSql = $database ?? 'DATABASE()';
-
- return $sql . ' AND k.table_schema = ' . $databaseNameSql
- . ' /*!50116 AND c.constraint_schema = ' . $databaseNameSql . ' */'
- . ' AND k.`REFERENCED_COLUMN_NAME` is not NULL'
- . ' ORDER BY k.`ORDINAL_POSITION`';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateViewSQL($name, $sql)
- {
- return 'CREATE VIEW ' . $name . ' AS ' . $sql;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropViewSQL($name)
- {
- return 'DROP VIEW ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
- {
- return $fixed ? ($length > 0 ? 'CHAR(' . $length . ')' : 'CHAR(255)')
- : ($length > 0 ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
- {
- return $fixed
- ? 'BINARY(' . ($length > 0 ? $length : 255) . ')'
- : 'VARBINARY(' . ($length > 0 ? $length : 255) . ')';
- }
-
- /**
- * Gets the SQL snippet used to declare a CLOB column type.
- * TINYTEXT : 2 ^ 8 - 1 = 255
- * TEXT : 2 ^ 16 - 1 = 65535
- * MEDIUMTEXT : 2 ^ 24 - 1 = 16777215
- * LONGTEXT : 2 ^ 32 - 1 = 4294967295
- *
- * {@inheritDoc}
- */
- public function getClobTypeDeclarationSQL(array $column)
- {
- if (! empty($column['length']) && is_numeric($column['length'])) {
- $length = $column['length'];
-
- if ($length <= static::LENGTH_LIMIT_TINYTEXT) {
- return 'TINYTEXT';
- }
-
- if ($length <= static::LENGTH_LIMIT_TEXT) {
- return 'TEXT';
- }
-
- if ($length <= static::LENGTH_LIMIT_MEDIUMTEXT) {
- return 'MEDIUMTEXT';
- }
- }
-
- return 'LONGTEXT';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTimeTypeDeclarationSQL(array $column)
- {
- if (isset($column['version']) && $column['version'] === true) {
- return 'TIMESTAMP';
- }
-
- return 'DATETIME';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTypeDeclarationSQL(array $column)
- {
- return 'DATE';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getTimeTypeDeclarationSQL(array $column)
- {
- return 'TIME';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getBooleanTypeDeclarationSQL(array $column)
- {
- return 'TINYINT(1)';
- }
-
- /**
- * {@inheritDoc}
- *
- * MySQL prefers "autoincrement" identity columns since sequences can only
- * be emulated with a table.
- */
- public function prefersIdentityColumns()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- *
- * MySQL supports this through AUTO_INCREMENT columns.
- */
- public function supportsIdentityColumns()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsInlineColumnComments()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsColumnCollation()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTablesSQL()
- {
- return "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'";
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTableColumnsSQL($table, $database = null)
- {
- $table = $this->quoteStringLiteral($table);
-
- if ($database !== null) {
- $database = $this->quoteStringLiteral($database);
- } else {
- $database = 'DATABASE()';
- }
-
- return 'SELECT COLUMN_NAME AS Field, COLUMN_TYPE AS Type, IS_NULLABLE AS `Null`, ' .
- 'COLUMN_KEY AS `Key`, COLUMN_DEFAULT AS `Default`, EXTRA AS Extra, COLUMN_COMMENT AS Comment, ' .
- 'CHARACTER_SET_NAME AS CharacterSet, COLLATION_NAME AS Collation ' .
- 'FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ' . $database . ' AND TABLE_NAME = ' . $table .
- ' ORDER BY ORDINAL_POSITION ASC';
- }
-
- public function getListTableMetadataSQL(string $table, ?string $database = null): string
- {
- return sprintf(
- <<<'SQL'
-SELECT ENGINE, AUTO_INCREMENT, TABLE_COLLATION, TABLE_COMMENT, CREATE_OPTIONS
-FROM information_schema.TABLES
-WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA = %s AND TABLE_NAME = %s
-SQL
- ,
- $database !== null ? $this->quoteStringLiteral($database) : 'DATABASE()',
- $this->quoteStringLiteral($table)
- );
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateDatabaseSQL($name)
- {
- return 'CREATE DATABASE ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropDatabaseSQL($name)
- {
- return 'DROP DATABASE ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function _getCreateTableSQL($name, array $columns, array $options = [])
- {
- $queryFields = $this->getColumnDeclarationListSQL($columns);
-
- if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
- foreach ($options['uniqueConstraints'] as $constraintName => $definition) {
- $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($constraintName, $definition);
- }
- }
-
- // add all indexes
- if (isset($options['indexes']) && ! empty($options['indexes'])) {
- foreach ($options['indexes'] as $indexName => $definition) {
- $queryFields .= ', ' . $this->getIndexDeclarationSQL($indexName, $definition);
- }
- }
-
- // attach all primary keys
- if (isset($options['primary']) && ! empty($options['primary'])) {
- $keyColumns = array_unique(array_values($options['primary']));
- $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
- }
-
- $query = 'CREATE ';
-
- if (! empty($options['temporary'])) {
- $query .= 'TEMPORARY ';
- }
-
- $query .= 'TABLE ' . $name . ' (' . $queryFields . ') ';
- $query .= $this->buildTableOptions($options);
- $query .= $this->buildPartitionOptions($options);
-
- $sql = [$query];
- $engine = 'INNODB';
-
- if (isset($options['engine'])) {
- $engine = strtoupper(trim($options['engine']));
- }
-
- // Propagate foreign key constraints only for InnoDB.
- if (isset($options['foreignKeys']) && $engine === 'INNODB') {
- foreach ((array) $options['foreignKeys'] as $definition) {
- $sql[] = $this->getCreateForeignKeySQL($definition, $name);
- }
- }
-
- return $sql;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDefaultValueDeclarationSQL($column)
- {
- // Unset the default value if the given column definition does not allow default values.
- if ($column['type'] instanceof TextType || $column['type'] instanceof BlobType) {
- $column['default'] = null;
- }
-
- return parent::getDefaultValueDeclarationSQL($column);
- }
-
- /**
- * Build SQL for table options
- *
- * @param mixed[] $options
- *
- * @return string
- */
- private function buildTableOptions(array $options)
- {
- if (isset($options['table_options'])) {
- return $options['table_options'];
- }
-
- $tableOptions = [];
-
- // Charset
- if (! isset($options['charset'])) {
- $options['charset'] = 'utf8';
- }
-
- $tableOptions[] = sprintf('DEFAULT CHARACTER SET %s', $options['charset']);
-
- // Collate
- if (! isset($options['collate'])) {
- $options['collate'] = $options['charset'] . '_unicode_ci';
- }
-
- $tableOptions[] = $this->getColumnCollationDeclarationSQL($options['collate']);
-
- // Engine
- if (! isset($options['engine'])) {
- $options['engine'] = 'InnoDB';
- }
-
- $tableOptions[] = sprintf('ENGINE = %s', $options['engine']);
-
- // Auto increment
- if (isset($options['auto_increment'])) {
- $tableOptions[] = sprintf('AUTO_INCREMENT = %s', $options['auto_increment']);
- }
-
- // Comment
- if (isset($options['comment'])) {
- $tableOptions[] = sprintf('COMMENT = %s ', $this->quoteStringLiteral($options['comment']));
- }
-
- // Row format
- if (isset($options['row_format'])) {
- $tableOptions[] = sprintf('ROW_FORMAT = %s', $options['row_format']);
- }
-
- return implode(' ', $tableOptions);
- }
-
- /**
- * Build SQL for partition options.
- *
- * @param mixed[] $options
- *
- * @return string
- */
- private function buildPartitionOptions(array $options)
- {
- return isset($options['partition_options'])
- ? ' ' . $options['partition_options']
- : '';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getAlterTableSQL(TableDiff $diff)
- {
- $columnSql = [];
- $queryParts = [];
- $newName = $diff->getNewName();
-
- if ($newName !== false) {
- $queryParts[] = 'RENAME TO ' . $newName->getQuotedName($this);
- }
-
- foreach ($diff->addedColumns as $column) {
- if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
- continue;
- }
-
- $columnArray = array_merge($column->toArray(), [
- 'comment' => $this->getColumnComment($column),
- ]);
-
- $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
- }
-
- foreach ($diff->removedColumns as $column) {
- if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
- continue;
- }
-
- $queryParts[] = 'DROP ' . $column->getQuotedName($this);
- }
-
- foreach ($diff->changedColumns as $columnDiff) {
- if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
- continue;
- }
-
- $column = $columnDiff->column;
- $columnArray = $column->toArray();
-
- // Don't propagate default value changes for unsupported column types.
- if (
- $columnDiff->hasChanged('default') &&
- count($columnDiff->changedProperties) === 1 &&
- ($columnArray['type'] instanceof TextType || $columnArray['type'] instanceof BlobType)
- ) {
- continue;
- }
-
- $columnArray['comment'] = $this->getColumnComment($column);
- $queryParts[] = 'CHANGE ' . ($columnDiff->getOldColumnName()->getQuotedName($this)) . ' '
- . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
- }
-
- foreach ($diff->renamedColumns as $oldColumnName => $column) {
- if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
- continue;
- }
-
- $oldColumnName = new Identifier($oldColumnName);
- $columnArray = $column->toArray();
- $columnArray['comment'] = $this->getColumnComment($column);
- $queryParts[] = 'CHANGE ' . $oldColumnName->getQuotedName($this) . ' '
- . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray);
- }
-
- if (isset($diff->addedIndexes['primary'])) {
- $keyColumns = array_unique(array_values($diff->addedIndexes['primary']->getColumns()));
- $queryParts[] = 'ADD PRIMARY KEY (' . implode(', ', $keyColumns) . ')';
- unset($diff->addedIndexes['primary']);
- } elseif (isset($diff->changedIndexes['primary'])) {
- // Necessary in case the new primary key includes a new auto_increment column
- foreach ($diff->changedIndexes['primary']->getColumns() as $columnName) {
- if (isset($diff->addedColumns[$columnName]) && $diff->addedColumns[$columnName]->getAutoincrement()) {
- $keyColumns = array_unique(array_values($diff->changedIndexes['primary']->getColumns()));
- $queryParts[] = 'DROP PRIMARY KEY';
- $queryParts[] = 'ADD PRIMARY KEY (' . implode(', ', $keyColumns) . ')';
- unset($diff->changedIndexes['primary']);
- break;
- }
- }
- }
-
- $sql = [];
- $tableSql = [];
-
- if (! $this->onSchemaAlterTable($diff, $tableSql)) {
- if (count($queryParts) > 0) {
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' '
- . implode(', ', $queryParts);
- }
-
- $sql = array_merge(
- $this->getPreAlterTableIndexForeignKeySQL($diff),
- $sql,
- $this->getPostAlterTableIndexForeignKeySQL($diff)
- );
- }
-
- return array_merge($sql, $tableSql, $columnSql);
- }
-
- /**
- * {@inheritDoc}
- */
- protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
- {
- $sql = [];
- $table = $diff->getName($this)->getQuotedName($this);
-
- foreach ($diff->changedIndexes as $changedIndex) {
- $sql = array_merge($sql, $this->getPreAlterTableAlterPrimaryKeySQL($diff, $changedIndex));
- }
-
- foreach ($diff->removedIndexes as $remKey => $remIndex) {
- $sql = array_merge($sql, $this->getPreAlterTableAlterPrimaryKeySQL($diff, $remIndex));
-
- foreach ($diff->addedIndexes as $addKey => $addIndex) {
- if ($remIndex->getColumns() !== $addIndex->getColumns()) {
- continue;
- }
-
- $indexClause = 'INDEX ' . $addIndex->getName();
-
- if ($addIndex->isPrimary()) {
- $indexClause = 'PRIMARY KEY';
- } elseif ($addIndex->isUnique()) {
- $indexClause = 'UNIQUE INDEX ' . $addIndex->getName();
- }
-
- $query = 'ALTER TABLE ' . $table . ' DROP INDEX ' . $remIndex->getName() . ', ';
- $query .= 'ADD ' . $indexClause;
- $query .= ' (' . $this->getIndexFieldDeclarationListSQL($addIndex) . ')';
-
- $sql[] = $query;
-
- unset($diff->removedIndexes[$remKey], $diff->addedIndexes[$addKey]);
-
- break;
- }
- }
-
- $engine = 'INNODB';
-
- if ($diff->fromTable instanceof Table && $diff->fromTable->hasOption('engine')) {
- $engine = strtoupper(trim($diff->fromTable->getOption('engine')));
- }
-
- // Suppress foreign key constraint propagation on non-supporting engines.
- if ($engine !== 'INNODB') {
- $diff->addedForeignKeys = [];
- $diff->changedForeignKeys = [];
- $diff->removedForeignKeys = [];
- }
-
- $sql = array_merge(
- $sql,
- $this->getPreAlterTableAlterIndexForeignKeySQL($diff),
- parent::getPreAlterTableIndexForeignKeySQL($diff),
- $this->getPreAlterTableRenameIndexForeignKeySQL($diff)
- );
-
- return $sql;
- }
-
- /**
- * @return string[]
- *
- * @throws Exception
- */
- private function getPreAlterTableAlterPrimaryKeySQL(TableDiff $diff, Index $index)
- {
- $sql = [];
-
- if (! $index->isPrimary() || ! $diff->fromTable instanceof Table) {
- return $sql;
- }
-
- $tableName = $diff->getName($this)->getQuotedName($this);
-
- // Dropping primary keys requires to unset autoincrement attribute on the particular column first.
- foreach ($index->getColumns() as $columnName) {
- if (! $diff->fromTable->hasColumn($columnName)) {
- continue;
- }
-
- $column = $diff->fromTable->getColumn($columnName);
-
- if ($column->getAutoincrement() !== true) {
- continue;
- }
-
- $column->setAutoincrement(false);
-
- $sql[] = 'ALTER TABLE ' . $tableName . ' MODIFY ' .
- $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
-
- // original autoincrement information might be needed later on by other parts of the table alteration
- $column->setAutoincrement(true);
- }
-
- return $sql;
- }
-
- /**
- * @param TableDiff $diff The table diff to gather the SQL for.
- *
- * @return string[]
- *
- * @throws Exception
- */
- private function getPreAlterTableAlterIndexForeignKeySQL(TableDiff $diff)
- {
- $sql = [];
- $table = $diff->getName($this)->getQuotedName($this);
-
- foreach ($diff->changedIndexes as $changedIndex) {
- // Changed primary key
- if (! $changedIndex->isPrimary() || ! ($diff->fromTable instanceof Table)) {
- continue;
- }
-
- foreach ($diff->fromTable->getPrimaryKeyColumns() as $columnName => $column) {
- // Check if an autoincrement column was dropped from the primary key.
- if (! $column->getAutoincrement() || in_array($columnName, $changedIndex->getColumns(), true)) {
- continue;
- }
-
- // The autoincrement attribute needs to be removed from the dropped column
- // before we can drop and recreate the primary key.
- $column->setAutoincrement(false);
-
- $sql[] = 'ALTER TABLE ' . $table . ' MODIFY ' .
- $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
-
- // Restore the autoincrement attribute as it might be needed later on
- // by other parts of the table alteration.
- $column->setAutoincrement(true);
- }
- }
-
- return $sql;
- }
-
- /**
- * @param TableDiff $diff The table diff to gather the SQL for.
- *
- * @return string[]
- */
- protected function getPreAlterTableRenameIndexForeignKeySQL(TableDiff $diff)
- {
- $sql = [];
- $tableName = $diff->getName($this)->getQuotedName($this);
-
- foreach ($this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) as $foreignKey) {
- if (in_array($foreignKey, $diff->changedForeignKeys, true)) {
- continue;
- }
-
- $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName);
- }
-
- return $sql;
- }
-
- /**
- * Returns the remaining foreign key constraints that require one of the renamed indexes.
- *
- * "Remaining" here refers to the diff between the foreign keys currently defined in the associated
- * table and the foreign keys to be removed.
- *
- * @param TableDiff $diff The table diff to evaluate.
- *
- * @return ForeignKeyConstraint[]
- */
- private function getRemainingForeignKeyConstraintsRequiringRenamedIndexes(TableDiff $diff)
- {
- if (empty($diff->renamedIndexes) || ! $diff->fromTable instanceof Table) {
- return [];
- }
-
- $foreignKeys = [];
- /** @var ForeignKeyConstraint[] $remainingForeignKeys */
- $remainingForeignKeys = array_diff_key(
- $diff->fromTable->getForeignKeys(),
- $diff->removedForeignKeys
- );
-
- foreach ($remainingForeignKeys as $foreignKey) {
- foreach ($diff->renamedIndexes as $index) {
- if ($foreignKey->intersectsIndexColumns($index)) {
- $foreignKeys[] = $foreignKey;
-
- break;
- }
- }
- }
-
- return $foreignKeys;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff)
- {
- return array_merge(
- parent::getPostAlterTableIndexForeignKeySQL($diff),
- $this->getPostAlterTableRenameIndexForeignKeySQL($diff)
- );
- }
-
- /**
- * @param TableDiff $diff The table diff to gather the SQL for.
- *
- * @return string[]
- */
- protected function getPostAlterTableRenameIndexForeignKeySQL(TableDiff $diff)
- {
- $sql = [];
- $newName = $diff->getNewName();
-
- if ($newName !== false) {
- $tableName = $newName->getQuotedName($this);
- } else {
- $tableName = $diff->getName($this)->getQuotedName($this);
- }
-
- foreach ($this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) as $foreignKey) {
- if (in_array($foreignKey, $diff->changedForeignKeys, true)) {
- continue;
- }
-
- $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName);
- }
-
- return $sql;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function getCreateIndexSQLFlags(Index $index)
- {
- $type = '';
- if ($index->isUnique()) {
- $type .= 'UNIQUE ';
- } elseif ($index->hasFlag('fulltext')) {
- $type .= 'FULLTEXT ';
- } elseif ($index->hasFlag('spatial')) {
- $type .= 'SPATIAL ';
- }
-
- return $type;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getIntegerTypeDeclarationSQL(array $column)
- {
- return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getBigIntTypeDeclarationSQL(array $column)
- {
- return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSmallIntTypeDeclarationSQL(array $column)
- {
- return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getFloatDeclarationSQL(array $column)
- {
- return 'DOUBLE PRECISION' . $this->getUnsignedDeclaration($column);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDecimalTypeDeclarationSQL(array $column)
- {
- return parent::getDecimalTypeDeclarationSQL($column) . $this->getUnsignedDeclaration($column);
- }
-
- /**
- * Get unsigned declaration for a column.
- *
- * @param mixed[] $columnDef
- *
- * @return string
- */
- private function getUnsignedDeclaration(array $columnDef)
- {
- return ! empty($columnDef['unsigned']) ? ' UNSIGNED' : '';
- }
-
- /**
- * {@inheritDoc}
- */
- protected function _getCommonIntegerTypeDeclarationSQL(array $column)
- {
- $autoinc = '';
- if (! empty($column['autoincrement'])) {
- $autoinc = ' AUTO_INCREMENT';
- }
-
- return $this->getUnsignedDeclaration($column) . $autoinc;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getColumnCharsetDeclarationSQL($charset)
- {
- return 'CHARACTER SET ' . $charset;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getColumnCollationDeclarationSQL($collation)
- {
- return 'COLLATE ' . $this->quoteSingleIdentifier($collation);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey)
- {
- $query = '';
- if ($foreignKey->hasOption('match')) {
- $query .= ' MATCH ' . $foreignKey->getOption('match');
- }
-
- $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
-
- return $query;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropIndexSQL($index, $table = null)
- {
- if ($index instanceof Index) {
- $indexName = $index->getQuotedName($this);
- } elseif (is_string($index)) {
- $indexName = $index;
- } else {
- throw new InvalidArgumentException(
- __METHOD__ . '() expects $index parameter to be string or ' . Index::class . '.'
- );
- }
-
- if ($table instanceof Table) {
- $table = $table->getQuotedName($this);
- } elseif (! is_string($table)) {
- throw new InvalidArgumentException(
- __METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.'
- );
- }
-
- if ($index instanceof Index && $index->isPrimary()) {
- // MySQL primary keys are always named "PRIMARY",
- // so we cannot use them in statements because of them being keyword.
- return $this->getDropPrimaryKeySQL($table);
- }
-
- return 'DROP INDEX ' . $indexName . ' ON ' . $table;
- }
-
- /**
- * @param string $table
- *
- * @return string
- */
- protected function getDropPrimaryKeySQL($table)
- {
- return 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSetTransactionIsolationSQL($level)
- {
- return 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getName()
- {
- return 'mysql';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getReadLockSQL()
- {
- return 'LOCK IN SHARE MODE';
- }
-
- /**
- * {@inheritDoc}
- */
- protected function initializeDoctrineTypeMappings()
- {
- $this->doctrineTypeMapping = [
- 'bigint' => 'bigint',
- 'binary' => 'binary',
- 'blob' => 'blob',
- 'char' => 'string',
- 'date' => 'date',
- 'datetime' => 'datetime',
- 'decimal' => 'decimal',
- 'double' => 'float',
- 'float' => 'float',
- 'int' => 'integer',
- 'integer' => 'integer',
- 'longblob' => 'blob',
- 'longtext' => 'text',
- 'mediumblob' => 'blob',
- 'mediumint' => 'integer',
- 'mediumtext' => 'text',
- 'numeric' => 'decimal',
- 'real' => 'float',
- 'set' => 'simple_array',
- 'smallint' => 'smallint',
- 'string' => 'string',
- 'text' => 'text',
- 'time' => 'time',
- 'timestamp' => 'datetime',
- 'tinyblob' => 'blob',
- 'tinyint' => 'boolean',
- 'tinytext' => 'text',
- 'varbinary' => 'binary',
- 'varchar' => 'string',
- 'year' => 'date',
- ];
- }
-
- /**
- * {@inheritDoc}
- */
- public function getVarcharMaxLength()
- {
- return 65535;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getBinaryMaxLength()
- {
- return 65535;
- }
-
- /**
- * {@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;
- }
-
- /**
- * {@inheritDoc}
- *
- * MySQL commits a transaction implicitly when DROP TABLE is executed, however not
- * if DROP TEMPORARY TABLE is executed.
- */
- public function getDropTemporaryTableSQL($table)
- {
- if ($table instanceof Table) {
- $table = $table->getQuotedName($this);
- } elseif (! is_string($table)) {
- throw new InvalidArgumentException(
- __METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.'
- );
- }
-
- return 'DROP TEMPORARY TABLE ' . $table;
- }
-
- /**
- * Gets the SQL Snippet used to declare a BLOB column type.
- * TINYBLOB : 2 ^ 8 - 1 = 255
- * BLOB : 2 ^ 16 - 1 = 65535
- * MEDIUMBLOB : 2 ^ 24 - 1 = 16777215
- * LONGBLOB : 2 ^ 32 - 1 = 4294967295
- *
- * {@inheritDoc}
- */
- public function getBlobTypeDeclarationSQL(array $column)
- {
- if (! empty($column['length']) && is_numeric($column['length'])) {
- $length = $column['length'];
-
- if ($length <= static::LENGTH_LIMIT_TINYBLOB) {
- return 'TINYBLOB';
- }
-
- if ($length <= static::LENGTH_LIMIT_BLOB) {
- return 'BLOB';
- }
-
- if ($length <= static::LENGTH_LIMIT_MEDIUMBLOB) {
- return 'MEDIUMBLOB';
- }
- }
-
- return 'LONGBLOB';
- }
-
- /**
- * {@inheritdoc}
- */
- public function quoteStringLiteral($str)
- {
- $str = str_replace('\\', '\\\\', $str); // MySQL requires backslashes to be escaped aswell.
-
- return parent::quoteStringLiteral($str);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDefaultTransactionIsolationLevel()
- {
- return TransactionIsolationLevel::REPEATABLE_READ;
- }
-
- public function supportsColumnLengthIndexes(): bool
- {
- return true;
- }
}
diff --git a/doctrine/dbal/src/Platforms/OraclePlatform.php b/doctrine/dbal/src/Platforms/OraclePlatform.php
index 7be7621d..7eabb7fa 100644
--- a/doctrine/dbal/src/Platforms/OraclePlatform.php
+++ b/doctrine/dbal/src/Platforms/OraclePlatform.php
@@ -35,6 +35,8 @@ class OraclePlatform extends AbstractPlatform
/**
* Assertion for Oracle identifiers.
*
+ * @deprecated
+ *
* @link http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements008.htm
*
* @param string $identifier
@@ -63,12 +65,20 @@ class OraclePlatform extends AbstractPlatform
}
/**
+ * @deprecated Generate dates within the application.
+ *
* @param string $type
*
* @return string
*/
public function getNowExpression($type = 'timestamp')
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4753',
+ 'OraclePlatform::getNowExpression() is deprecated. Generate dates within the application.'
+ );
+
switch ($type) {
case 'date':
case 'time':
@@ -169,6 +179,19 @@ class OraclePlatform extends AbstractPlatform
/**
* {@inheritDoc}
+ */
+ public function getCreatePrimaryKeySQL(Index $index, $table): string
+ {
+ if ($table instanceof Table) {
+ $table = $table->getQuotedName($this);
+ }
+
+ return 'ALTER TABLE ' . $table . ' ADD CONSTRAINT ' . $index->getQuotedName($this)
+ . ' PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index) . ')';
+ }
+
+ /**
+ * {@inheritDoc}
*
* Need to specifiy minvalue, since start with is hidden in the system and MINVALUE <= START WITH.
* Therefore we can use MINVALUE to be able to get a hint what START WITH was for later introspection
@@ -195,10 +218,8 @@ class OraclePlatform extends AbstractPlatform
/**
* Cache definition for sequences
- *
- * @return string
*/
- private function getSequenceCacheSQL(Sequence $sequence)
+ private function getSequenceCacheSQL(Sequence $sequence): string
{
if ($sequence->getCache() === 0) {
return ' NOCACHE';
@@ -401,10 +422,8 @@ class OraclePlatform extends AbstractPlatform
$sql = array_merge($sql, $this->getCreateAutoincrementSql($columnName, $name));
}
- if (isset($indexes) && ! empty($indexes)) {
- foreach ($indexes as $index) {
- $sql[] = $this->getCreateIndexSQL($index, $name);
- }
+ foreach ($indexes as $index) {
+ $sql[] = $this->getCreateIndexSQL($index, $name);
}
return $sql;
@@ -443,6 +462,7 @@ class OraclePlatform extends AbstractPlatform
SELECT ucon.constraint_type
FROM user_constraints ucon
WHERE ucon.index_name = uind_col.index_name
+ AND ucon.table_name = uind_col.table_name
) AS is_primary
FROM user_ind_columns uind_col
WHERE uind_col.table_name = " . $table . '
@@ -466,22 +486,8 @@ class OraclePlatform extends AbstractPlatform
}
/**
- * {@inheritDoc}
- */
- public function getCreateViewSQL($name, $sql)
- {
- return 'CREATE VIEW ' . $name . ' AS ' . $sql;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropViewSQL($name)
- {
- return 'DROP VIEW ' . $name;
- }
-
- /**
+ * @internal The method should be only used from within the OraclePlatform class hierarchy.
+ *
* @param string $name
* @param string $table
* @param int $start
@@ -549,6 +555,8 @@ END;';
}
/**
+ * @internal The method should be only used from within the OracleSchemaManager class hierarchy.
+ *
* Returns the SQL statements to drop the autoincrement for the given table name.
*
* @param string $table The table name to drop the autoincrement for.
@@ -578,10 +586,8 @@ END;';
* to reflect Oracle's internal auto uppercasing strategy of unquoted identifiers.
*
* @param string $name The identifier to normalize.
- *
- * @return Identifier The normalized identifier.
*/
- private function normalizeIdentifier($name)
+ private function normalizeIdentifier($name): Identifier
{
$identifier = new Identifier($name);
@@ -609,12 +615,8 @@ END;';
*
* Quotes the autoincrement primary key identifier name
* if the given table name is quoted by intention.
- *
- * @param Identifier $table The table identifier to return the autoincrement primary key identifier name for.
- *
- * @return string
*/
- private function getAutoincrementIdentifierName(Identifier $table)
+ private function getAutoincrementIdentifierName(Identifier $table): string
{
$identifierName = $this->addSuffix($table->getName(), '_AI_PK');
@@ -713,18 +715,6 @@ SQL
/**
* {@inheritDoc}
*/
- public function getDropSequenceSQL($sequence)
- {
- if ($sequence instanceof Sequence) {
- $sequence = $sequence->getQuotedName($this);
- }
-
- return 'DROP SEQUENCE ' . $sequence;
- }
-
- /**
- * {@inheritDoc}
- */
public function getDropForeignKeySQL($foreignKey, $table)
{
if (! $foreignKey instanceof ForeignKeyConstraint) {
@@ -786,6 +776,14 @@ SQL
/**
* {@inheritDoc}
*/
+ public function getCreateDatabaseSQL($name)
+ {
+ return 'CREATE USER ' . $name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public function getDropDatabaseSQL($name)
{
return 'DROP USER ' . $name . ' CASCADE';
@@ -1008,6 +1006,12 @@ SQL
*/
public function getName()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4749',
+ 'OraclePlatform::getName() is deprecated. Identify platforms by their class.'
+ );
+
return 'oracle';
}
@@ -1164,7 +1168,7 @@ SQL
/**
* {@inheritDoc}
*
- * @deprecated Implement {@link createReservedKeywordsList()} instead.
+ * @deprecated Implement {@see createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
diff --git a/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php b/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php
index c9ca509d..a9419817 100644
--- a/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php
+++ b/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php
@@ -9,11 +9,14 @@ use Doctrine\Deprecations\Deprecation;
/**
* Provides the behavior, features and SQL dialect of the PostgreSQL 10.0 database platform.
+ *
+ * @deprecated This class will be merged with {@see PostgreSQLPlatform} in 4.0 because support for Postgres
+ * releases prior to 10.0 will be dropped.
*/
class PostgreSQL100Platform extends PostgreSQL94Platform
{
/**
- * @deprecated Implement {@link createReservedKeywordsList()} instead.
+ * @deprecated Implement {@see createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass(): string
{
diff --git a/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php b/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php
index bf21477c..2c974c36 100644
--- a/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php
+++ b/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php
@@ -2,1306 +2,11 @@
namespace Doctrine\DBAL\Platforms;
-use Doctrine\DBAL\Schema\Column;
-use Doctrine\DBAL\Schema\ColumnDiff;
-use Doctrine\DBAL\Schema\ForeignKeyConstraint;
-use Doctrine\DBAL\Schema\Identifier;
-use Doctrine\DBAL\Schema\Index;
-use Doctrine\DBAL\Schema\Sequence;
-use Doctrine\DBAL\Schema\TableDiff;
-use Doctrine\DBAL\Types\BigIntType;
-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;
-use function array_merge;
-use function array_unique;
-use function array_values;
-use function count;
-use function explode;
-use function implode;
-use function in_array;
-use function is_array;
-use function is_bool;
-use function is_numeric;
-use function is_string;
-use function sprintf;
-use function strpos;
-use function strtolower;
-use function trim;
-
/**
* Provides the behavior, features and SQL dialect of the PostgreSQL 9.4+ database platform.
+ *
+ * @deprecated Use {@see PostgreSQLPlatform} instead.
*/
-class PostgreSQL94Platform extends AbstractPlatform
+class PostgreSQL94Platform extends PostgreSQLPlatform
{
- /** @var bool */
- private $useBooleanTrueFalseStrings = true;
-
- /** @var string[][] PostgreSQL booleans literals */
- private $booleanLiterals = [
- 'true' => [
- 't',
- 'true',
- 'y',
- 'yes',
- 'on',
- '1',
- ],
- 'false' => [
- 'f',
- 'false',
- 'n',
- 'no',
- 'off',
- '0',
- ],
- ];
-
- /**
- * PostgreSQL has different behavior with some drivers
- * with regard to how booleans have to be handled.
- *
- * Enables use of 'true'/'false' or otherwise 1 and 0 instead.
- *
- * @param bool $flag
- *
- * @return void
- */
- public function setUseBooleanTrueFalseStrings($flag)
- {
- $this->useBooleanTrueFalseStrings = (bool) $flag;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSubstringExpression($string, $start, $length = null)
- {
- if ($length === null) {
- return 'SUBSTRING(' . $string . ' FROM ' . $start . ')';
- }
-
- return 'SUBSTRING(' . $string . ' FROM ' . $start . ' FOR ' . $length . ')';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getNowExpression()
- {
- return 'LOCALTIMESTAMP(0)';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getRegexpExpression()
- {
- return 'SIMILAR TO';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getLocateExpression($str, $substr, $startPos = false)
- {
- if ($startPos !== false) {
- $str = $this->getSubstringExpression($str, $startPos);
-
- return 'CASE WHEN (POSITION(' . $substr . ' IN ' . $str . ') = 0) THEN 0'
- . ' ELSE (POSITION(' . $substr . ' IN ' . $str . ') + ' . ($startPos - 1) . ') END';
- }
-
- return 'POSITION(' . $substr . ' IN ' . $str . ')';
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit)
- {
- if ($unit === DateIntervalUnit::QUARTER) {
- $interval *= 3;
- $unit = DateIntervalUnit::MONTH;
- }
-
- return '(' . $date . ' ' . $operator . ' (' . $interval . " || ' " . $unit . "')::interval)";
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateDiffExpression($date1, $date2)
- {
- return '(DATE(' . $date1 . ')-DATE(' . $date2 . '))';
- }
-
- public function getCurrentDatabaseExpression(): string
- {
- return 'CURRENT_DATABASE()';
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsSequences()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsSchemas()
- {
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDefaultSchemaName()
- {
- return 'public';
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsIdentityColumns()
- {
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- public function supportsPartialIndexes()
- {
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- public function usesSequenceEmulatedIdentityColumns()
- {
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getIdentitySequenceName($tableName, $columnName)
- {
- return $tableName . '_' . $columnName . '_seq';
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsCommentOnStatement()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function hasNativeGuidType()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListDatabasesSQL()
- {
- return 'SELECT datname FROM pg_database';
- }
-
- /**
- * {@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\_%'
- AND schema_name != 'information_schema'";
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListSequencesSQL($database)
- {
- return "SELECT sequence_name AS relname,
- sequence_schema AS schemaname
- FROM information_schema.sequences
- WHERE sequence_schema NOT LIKE 'pg\_%'
- AND sequence_schema != 'information_schema'";
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTablesSQL()
- {
- return "SELECT quote_ident(table_name) AS table_name,
- table_schema AS schema_name
- FROM information_schema.tables
- WHERE table_schema NOT LIKE 'pg\_%'
- AND table_schema != 'information_schema'
- AND table_name != 'geometry_columns'
- AND table_name != 'spatial_ref_sys'
- AND table_type != 'VIEW'";
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListViewsSQL($database)
- {
- return 'SELECT quote_ident(table_name) AS viewname,
- table_schema AS schemaname,
- view_definition AS definition
- FROM information_schema.views
- WHERE view_definition IS NOT NULL';
- }
-
- /**
- * @param string $table
- * @param string|null $database
- *
- * @return string
- */
- public function getListTableForeignKeysSQL($table, $database = null)
- {
- return 'SELECT quote_ident(r.conname) as conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef
- FROM pg_catalog.pg_constraint r
- WHERE r.conrelid =
- (
- SELECT c.oid
- FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n
- WHERE ' . $this->getTableWhereClause($table) . " AND n.oid = c.relnamespace
- )
- AND r.contype = 'f'";
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateViewSQL($name, $sql)
- {
- return 'CREATE VIEW ' . $name . ' AS ' . $sql;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropViewSQL($name)
- {
- return 'DROP VIEW ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTableConstraintsSQL($table)
- {
- $table = new Identifier($table);
- $table = $this->quoteStringLiteral($table->getName());
-
- return sprintf(
- <<<'SQL'
-SELECT
- quote_ident(relname) as relname
-FROM
- pg_class
-WHERE oid IN (
- SELECT indexrelid
- FROM pg_index, pg_class
- WHERE pg_class.relname = %s
- AND pg_class.oid = pg_index.indrelid
- AND (indisunique = 't' OR indisprimary = 't')
- )
-SQL
- ,
- $table
- );
- }
-
- /**
- * {@inheritDoc}
- *
- * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
- */
- public function getListTableIndexesSQL($table, $database = null)
- {
- return 'SELECT quote_ident(relname) as relname, pg_index.indisunique, pg_index.indisprimary,
- pg_index.indkey, pg_index.indrelid,
- pg_get_expr(indpred, indrelid) AS where
- FROM pg_class, pg_index
- WHERE oid IN (
- SELECT indexrelid
- FROM pg_index si, pg_class sc, pg_namespace sn
- WHERE ' . $this->getTableWhereClause($table, 'sc', 'sn') . '
- AND sc.oid=si.indrelid AND sc.relnamespace = sn.oid
- ) AND pg_index.indexrelid = oid';
- }
-
- /**
- * @param string $table
- * @param string $classAlias
- * @param string $namespaceAlias
- *
- * @return string
- */
- private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias = 'n')
- {
- $whereClause = $namespaceAlias . ".nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND ";
- if (strpos($table, '.') !== false) {
- [$schema, $table] = explode('.', $table);
- $schema = $this->quoteStringLiteral($schema);
- } else {
- $schema = 'ANY(current_schemas(false))';
- }
-
- $table = new Identifier($table);
- $table = $this->quoteStringLiteral($table->getName());
-
- return $whereClause . sprintf(
- '%s.relname = %s AND %s.nspname = %s',
- $classAlias,
- $table,
- $namespaceAlias,
- $schema
- );
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTableColumnsSQL($table, $database = null)
- {
- return "SELECT
- a.attnum,
- quote_ident(a.attname) AS field,
- t.typname AS type,
- format_type(a.atttypid, a.atttypmod) AS complete_type,
- (SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation,
- (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type,
- (SELECT format_type(t2.typbasetype, t2.typtypmod) FROM
- pg_catalog.pg_type t2 WHERE t2.typtype = 'd' AND t2.oid = a.atttypid) AS domain_complete_type,
- a.attnotnull AS isnotnull,
- (SELECT 't'
- FROM pg_index
- WHERE c.oid = pg_index.indrelid
- AND pg_index.indkey[0] = a.attnum
- AND pg_index.indisprimary = 't'
- ) AS pri,
- (SELECT pg_get_expr(adbin, adrelid)
- FROM pg_attrdef
- WHERE c.oid = pg_attrdef.adrelid
- AND pg_attrdef.adnum=a.attnum
- ) AS default,
- (SELECT pg_description.description
- FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid
- ) AS comment
- FROM pg_attribute a, pg_class c, pg_type t, pg_namespace n
- WHERE " . $this->getTableWhereClause($table, 'c', 'n') . '
- AND a.attnum > 0
- AND a.attrelid = c.oid
- AND a.atttypid = t.oid
- AND n.oid = c.relnamespace
- ORDER BY a.attnum';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateDatabaseSQL($name)
- {
- return 'CREATE DATABASE ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey)
- {
- $query = '';
-
- if ($foreignKey->hasOption('match')) {
- $query .= ' MATCH ' . $foreignKey->getOption('match');
- }
-
- $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
-
- if ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) {
- $query .= ' DEFERRABLE';
- } else {
- $query .= ' NOT DEFERRABLE';
- }
-
- if (
- ($foreignKey->hasOption('feferred') && $foreignKey->getOption('feferred') !== false)
- || ($foreignKey->hasOption('deferred') && $foreignKey->getOption('deferred') !== false)
- ) {
- $query .= ' INITIALLY DEFERRED';
- } else {
- $query .= ' INITIALLY IMMEDIATE';
- }
-
- return $query;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getAlterTableSQL(TableDiff $diff)
- {
- $sql = [];
- $commentsSQL = [];
- $columnSql = [];
-
- foreach ($diff->addedColumns as $column) {
- if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
- continue;
- }
-
- $query = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
-
- $comment = $this->getColumnComment($column);
-
- if ($comment === null || $comment === '') {
- continue;
- }
-
- $commentsSQL[] = $this->getCommentOnColumnSQL(
- $diff->getName($this)->getQuotedName($this),
- $column->getQuotedName($this),
- $comment
- );
- }
-
- foreach ($diff->removedColumns as $column) {
- if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
- continue;
- }
-
- $query = 'DROP ' . $column->getQuotedName($this);
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
- }
-
- foreach ($diff->changedColumns as $columnDiff) {
- if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
- continue;
- }
-
- if ($this->isUnchangedBinaryColumn($columnDiff)) {
- continue;
- }
-
- $oldColumnName = $columnDiff->getOldColumnName()->getQuotedName($this);
- $column = $columnDiff->column;
-
- if (
- $columnDiff->hasChanged('type')
- || $columnDiff->hasChanged('precision')
- || $columnDiff->hasChanged('scale')
- || $columnDiff->hasChanged('fixed')
- ) {
- $type = $column->getType();
-
- // SERIAL/BIGSERIAL are not "real" types and we can't alter a column to that type
- $columnDefinition = $column->toArray();
- $columnDefinition['autoincrement'] = false;
-
- // here was a server version check before, but DBAL API does not support this anymore.
- $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSQLDeclaration($columnDefinition, $this);
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
- }
-
- if ($columnDiff->hasChanged('default') || $this->typeChangeBreaksDefaultValue($columnDiff)) {
- $defaultClause = $column->getDefault() === null
- ? ' DROP DEFAULT'
- : ' SET' . $this->getDefaultValueDeclarationSQL($column->toArray());
- $query = 'ALTER ' . $oldColumnName . $defaultClause;
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
- }
-
- if ($columnDiff->hasChanged('notnull')) {
- $query = 'ALTER ' . $oldColumnName . ' ' . ($column->getNotnull() ? 'SET' : 'DROP') . ' NOT NULL';
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
- }
-
- if ($columnDiff->hasChanged('autoincrement')) {
- if ($column->getAutoincrement()) {
- // add autoincrement
- $seqName = $this->getIdentitySequenceName($diff->name, $oldColumnName);
-
- $sql[] = 'CREATE SEQUENCE ' . $seqName;
- $sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ') FROM '
- . $diff->getName($this)->getQuotedName($this) . '))';
- $query = 'ALTER ' . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')";
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
- } else {
- // Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have
- $query = 'ALTER ' . $oldColumnName . ' DROP DEFAULT';
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
- }
- }
-
- $newComment = $this->getColumnComment($column);
- $oldComment = $this->getOldColumnComment($columnDiff);
-
- if (
- $columnDiff->hasChanged('comment')
- || ($columnDiff->fromColumn !== null && $oldComment !== $newComment)
- ) {
- $commentsSQL[] = $this->getCommentOnColumnSQL(
- $diff->getName($this)->getQuotedName($this),
- $column->getQuotedName($this),
- $newComment
- );
- }
-
- if (! $columnDiff->hasChanged('length')) {
- continue;
- }
-
- $query = 'ALTER ' . $oldColumnName . ' TYPE '
- . $column->getType()->getSQLDeclaration($column->toArray(), $this);
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
- }
-
- foreach ($diff->renamedColumns as $oldColumnName => $column) {
- if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
- continue;
- }
-
- $oldColumnName = new Identifier($oldColumnName);
-
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) .
- ' RENAME COLUMN ' . $oldColumnName->getQuotedName($this) . ' TO ' . $column->getQuotedName($this);
- }
-
- $tableSql = [];
-
- if (! $this->onSchemaAlterTable($diff, $tableSql)) {
- $sql = array_merge($sql, $commentsSQL);
-
- $newName = $diff->getNewName();
-
- if ($newName !== false) {
- $sql[] = sprintf(
- 'ALTER TABLE %s RENAME TO %s',
- $diff->getName($this)->getQuotedName($this),
- $newName->getQuotedName($this)
- );
- }
-
- $sql = array_merge(
- $this->getPreAlterTableIndexForeignKeySQL($diff),
- $sql,
- $this->getPostAlterTableIndexForeignKeySQL($diff)
- );
- }
-
- return array_merge($sql, $tableSql, $columnSql);
- }
-
- /**
- * Checks whether a given column diff is a logically unchanged binary type column.
- *
- * Used to determine whether a column alteration for a binary type column can be skipped.
- * Doctrine's {@link BinaryType} and {@link BlobType} are mapped to the same database column type on this platform
- * as this platform does not have a native VARBINARY/BINARY column type. Therefore the comparator
- * might detect differences for binary type columns which do not have to be propagated
- * to database as there actually is no difference at database level.
- *
- * @param ColumnDiff $columnDiff The column diff to check against.
- *
- * @return bool True if the given column diff is an unchanged binary type column, false otherwise.
- */
- private function isUnchangedBinaryColumn(ColumnDiff $columnDiff)
- {
- $columnType = $columnDiff->column->getType();
-
- if (! $columnType instanceof BinaryType && ! $columnType instanceof BlobType) {
- return false;
- }
-
- $fromColumn = $columnDiff->fromColumn instanceof Column ? $columnDiff->fromColumn : null;
-
- if ($fromColumn !== null) {
- $fromColumnType = $fromColumn->getType();
-
- if (! $fromColumnType instanceof BinaryType && ! $fromColumnType instanceof BlobType) {
- return false;
- }
-
- return count(array_diff($columnDiff->changedProperties, ['type', 'length', 'fixed'])) === 0;
- }
-
- if ($columnDiff->hasChanged('type')) {
- return false;
- }
-
- return count(array_diff($columnDiff->changedProperties, ['length', 'fixed'])) === 0;
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName)
- {
- if (strpos($tableName, '.') !== false) {
- [$schema] = explode('.', $tableName);
- $oldIndexName = $schema . '.' . $oldIndexName;
- }
-
- return ['ALTER INDEX ' . $oldIndexName . ' RENAME TO ' . $index->getQuotedName($this)];
- }
-
- /**
- * {@inheritdoc}
- */
- public function getCommentOnColumnSQL($tableName, $columnName, $comment)
- {
- $tableName = new Identifier($tableName);
- $columnName = new Identifier($columnName);
- $comment = $comment === null ? 'NULL' : $this->quoteStringLiteral($comment);
-
- return sprintf(
- 'COMMENT ON COLUMN %s.%s IS %s',
- $tableName->getQuotedName($this),
- $columnName->getQuotedName($this),
- $comment
- );
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateSequenceSQL(Sequence $sequence)
- {
- return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
- ' INCREMENT BY ' . $sequence->getAllocationSize() .
- ' MINVALUE ' . $sequence->getInitialValue() .
- ' START ' . $sequence->getInitialValue() .
- $this->getSequenceCacheSQL($sequence);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getAlterSequenceSQL(Sequence $sequence)
- {
- return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
- ' INCREMENT BY ' . $sequence->getAllocationSize() .
- $this->getSequenceCacheSQL($sequence);
- }
-
- /**
- * Cache definition for sequences
- *
- * @return string
- */
- private function getSequenceCacheSQL(Sequence $sequence)
- {
- if ($sequence->getCache() > 1) {
- return ' CACHE ' . $sequence->getCache();
- }
-
- return '';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropSequenceSQL($sequence)
- {
- if ($sequence instanceof Sequence) {
- $sequence = $sequence->getQuotedName($this);
- }
-
- return 'DROP SEQUENCE ' . $sequence . ' CASCADE';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateSchemaSQL($schemaName)
- {
- return 'CREATE SCHEMA ' . $schemaName;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropForeignKeySQL($foreignKey, $table)
- {
- return $this->getDropConstraintSQL($foreignKey, $table);
- }
-
- /**
- * {@inheritDoc}
- */
- protected function _getCreateTableSQL($name, array $columns, array $options = [])
- {
- $queryFields = $this->getColumnDeclarationListSQL($columns);
-
- if (isset($options['primary']) && ! empty($options['primary'])) {
- $keyColumns = array_unique(array_values($options['primary']));
- $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
- }
-
- $query = 'CREATE TABLE ' . $name . ' (' . $queryFields . ')';
-
- $sql = [$query];
-
- if (isset($options['indexes']) && ! empty($options['indexes'])) {
- foreach ($options['indexes'] as $index) {
- $sql[] = $this->getCreateIndexSQL($index, $name);
- }
- }
-
- 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);
- }
- }
-
- return $sql;
- }
-
- /**
- * Converts a single boolean value.
- *
- * First converts the value to its native PHP boolean type
- * and passes it to the given callback function to be reconverted
- * into any custom representation.
- *
- * @param mixed $value The value to convert.
- * @param callable $callback The callback function to use for converting the real boolean value.
- *
- * @return mixed
- *
- * @throws UnexpectedValueException
- */
- private function convertSingleBooleanValue($value, $callback)
- {
- if ($value === null) {
- return $callback(null);
- }
-
- if (is_bool($value) || is_numeric($value)) {
- return $callback((bool) $value);
- }
-
- if (! is_string($value)) {
- return $callback(true);
- }
-
- /**
- * Better safe than sorry: http://php.net/in_array#106319
- */
- if (in_array(strtolower(trim($value)), $this->booleanLiterals['false'], true)) {
- return $callback(false);
- }
-
- if (in_array(strtolower(trim($value)), $this->booleanLiterals['true'], true)) {
- return $callback(true);
- }
-
- throw new UnexpectedValueException("Unrecognized boolean literal '${value}'");
- }
-
- /**
- * Converts one or multiple boolean values.
- *
- * First converts the value(s) to their native PHP boolean type
- * and passes them to the given callback function to be reconverted
- * into any custom representation.
- *
- * @param mixed $item The value(s) to convert.
- * @param callable $callback The callback function to use for converting the real boolean value(s).
- *
- * @return mixed
- */
- private function doConvertBooleans($item, $callback)
- {
- if (is_array($item)) {
- foreach ($item as $key => $value) {
- $item[$key] = $this->convertSingleBooleanValue($value, $callback);
- }
-
- return $item;
- }
-
- return $this->convertSingleBooleanValue($item, $callback);
- }
-
- /**
- * {@inheritDoc}
- *
- * Postgres wants boolean values converted to the strings 'true'/'false'.
- */
- public function convertBooleans($item)
- {
- if (! $this->useBooleanTrueFalseStrings) {
- return parent::convertBooleans($item);
- }
-
- return $this->doConvertBooleans(
- $item,
- /**
- * @param mixed $value
- */
- static function ($value) {
- if ($value === null) {
- return 'NULL';
- }
-
- return $value === true ? 'true' : 'false';
- }
- );
- }
-
- /**
- * {@inheritDoc}
- */
- public function convertBooleansToDatabaseValue($item)
- {
- if (! $this->useBooleanTrueFalseStrings) {
- return parent::convertBooleansToDatabaseValue($item);
- }
-
- return $this->doConvertBooleans(
- $item,
- /**
- * @param mixed $value
- */
- static function ($value): ?int {
- return $value === null ? null : (int) $value;
- }
- );
- }
-
- /**
- * {@inheritDoc}
- */
- public function convertFromBoolean($item)
- {
- if ($item !== null && in_array(strtolower($item), $this->booleanLiterals['false'], true)) {
- return false;
- }
-
- return parent::convertFromBoolean($item);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSequenceNextValSQL($sequence)
- {
- return "SELECT NEXTVAL('" . $sequence . "')";
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSetTransactionIsolationSQL($level)
- {
- return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL '
- . $this->_getTransactionIsolationLevelSQL($level);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getBooleanTypeDeclarationSQL(array $column)
- {
- return 'BOOLEAN';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getIntegerTypeDeclarationSQL(array $column)
- {
- if (! empty($column['autoincrement'])) {
- return 'SERIAL';
- }
-
- return 'INT';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getBigIntTypeDeclarationSQL(array $column)
- {
- if (! empty($column['autoincrement'])) {
- return 'BIGSERIAL';
- }
-
- return 'BIGINT';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSmallIntTypeDeclarationSQL(array $column)
- {
- if (! empty($column['autoincrement'])) {
- return 'SMALLSERIAL';
- }
-
- return 'SMALLINT';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getGuidTypeDeclarationSQL(array $column)
- {
- return 'UUID';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTimeTypeDeclarationSQL(array $column)
- {
- return 'TIMESTAMP(0) WITHOUT TIME ZONE';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTimeTzTypeDeclarationSQL(array $column)
- {
- return 'TIMESTAMP(0) WITH TIME ZONE';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTypeDeclarationSQL(array $column)
- {
- return 'DATE';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getTimeTypeDeclarationSQL(array $column)
- {
- return 'TIME(0) WITHOUT TIME ZONE';
- }
-
- /**
- * {@inheritDoc}
- */
- protected function _getCommonIntegerTypeDeclarationSQL(array $column)
- {
- return '';
- }
-
- /**
- * {@inheritDoc}
- */
- protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
- {
- return $fixed ? ($length > 0 ? 'CHAR(' . $length . ')' : 'CHAR(255)')
- : ($length > 0 ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
- {
- return 'BYTEA';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getClobTypeDeclarationSQL(array $column)
- {
- return 'TEXT';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getName()
- {
- return 'postgresql';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTimeTzFormatString()
- {
- return 'Y-m-d H:i:sO';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
- {
- return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getTruncateTableSQL($tableName, $cascade = false)
- {
- $tableIdentifier = new Identifier($tableName);
- $sql = 'TRUNCATE ' . $tableIdentifier->getQuotedName($this);
-
- if ($cascade) {
- $sql .= ' CASCADE';
- }
-
- return $sql;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getReadLockSQL()
- {
- return 'FOR SHARE';
- }
-
- /**
- * {@inheritDoc}
- */
- protected function initializeDoctrineTypeMappings()
- {
- $this->doctrineTypeMapping = [
- 'bigint' => 'bigint',
- 'bigserial' => 'bigint',
- 'bool' => 'boolean',
- 'boolean' => 'boolean',
- 'bpchar' => 'string',
- 'bytea' => 'blob',
- 'char' => 'string',
- 'date' => 'date',
- 'datetime' => 'datetime',
- 'decimal' => 'decimal',
- 'double' => 'float',
- 'double precision' => 'float',
- 'float' => 'float',
- 'float4' => 'float',
- 'float8' => 'float',
- 'inet' => 'string',
- 'int' => 'integer',
- 'int2' => 'smallint',
- 'int4' => 'integer',
- 'int8' => 'bigint',
- 'integer' => 'integer',
- 'interval' => 'string',
- 'json' => 'json',
- 'jsonb' => 'json',
- 'money' => 'decimal',
- 'numeric' => 'decimal',
- 'serial' => 'integer',
- 'serial4' => 'integer',
- 'serial8' => 'bigint',
- 'real' => 'float',
- 'smallint' => 'smallint',
- 'text' => 'text',
- 'time' => 'time',
- 'timestamp' => 'datetime',
- 'timestamptz' => 'datetimetz',
- 'timetz' => 'time',
- 'tsvector' => 'text',
- 'uuid' => 'guid',
- 'varchar' => 'string',
- 'year' => 'date',
- '_varchar' => 'string',
- ];
- }
-
- /**
- * {@inheritDoc}
- */
- public function getVarcharMaxLength()
- {
- return 65535;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getBinaryMaxLength()
- {
- return 0;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getBinaryDefaultLength()
- {
- return 0;
- }
-
- /**
- * {@inheritdoc}
- */
- public function hasNativeJsonType()
- {
- return true;
- }
-
- /**
- * {@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;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getBlobTypeDeclarationSQL(array $column)
- {
- return 'BYTEA';
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDefaultValueDeclarationSQL($column)
- {
- if ($this->isSerialColumn($column)) {
- return '';
- }
-
- return parent::getDefaultValueDeclarationSQL($column);
- }
-
- /**
- * {@inheritdoc}
- */
- public function supportsColumnCollation()
- {
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getColumnCollationDeclarationSQL($collation)
- {
- return 'COLLATE ' . $this->quoteSingleIdentifier($collation);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getJsonTypeDeclarationSQL(array $column)
- {
- if (! empty($column['jsonb'])) {
- return 'JSONB';
- }
-
- return 'JSON';
- }
-
- /**
- * @param mixed[] $column
- */
- private function isSerialColumn(array $column): bool
- {
- return isset($column['type'], $column['autoincrement'])
- && $column['autoincrement'] === true
- && $this->isNumericType($column['type']);
- }
-
- /**
- * Check whether the type of a column is changed in a way that invalidates the default value for the column
- */
- private function typeChangeBreaksDefaultValue(ColumnDiff $columnDiff): bool
- {
- if ($columnDiff->fromColumn === null) {
- return $columnDiff->hasChanged('type');
- }
-
- $oldTypeIsNumeric = $this->isNumericType($columnDiff->fromColumn->getType());
- $newTypeIsNumeric = $this->isNumericType($columnDiff->column->getType());
-
- // default should not be changed when switching between numeric types and the default comes from a sequence
- return $columnDiff->hasChanged('type')
- && ! ($oldTypeIsNumeric && $newTypeIsNumeric && $columnDiff->column->getAutoincrement());
- }
-
- private function isNumericType(Type $type): bool
- {
- return $type instanceof IntegerType || $type instanceof BigIntType;
- }
-
- private function getOldColumnComment(ColumnDiff $columnDiff): ?string
- {
- return $columnDiff->fromColumn !== null ? $this->getColumnComment($columnDiff->fromColumn) : null;
- }
-
- public function getListTableMetadataSQL(string $table, ?string $schema = null): string
- {
- if ($schema !== null) {
- $table = $schema . '.' . $table;
- }
-
- return sprintf(
- <<<'SQL'
-SELECT obj_description(%s::regclass) AS table_comment;
-SQL
- ,
- $this->quoteStringLiteral($table)
- );
- }
}
diff --git a/doctrine/dbal/src/Platforms/PostgreSQLPlatform.php b/doctrine/dbal/src/Platforms/PostgreSQLPlatform.php
new file mode 100644
index 00000000..477e08af
--- /dev/null
+++ b/doctrine/dbal/src/Platforms/PostgreSQLPlatform.php
@@ -0,0 +1,1276 @@
+<?php
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\Schema\Column;
+use Doctrine\DBAL\Schema\ColumnDiff;
+use Doctrine\DBAL\Schema\ForeignKeyConstraint;
+use Doctrine\DBAL\Schema\Identifier;
+use Doctrine\DBAL\Schema\Index;
+use Doctrine\DBAL\Schema\Sequence;
+use Doctrine\DBAL\Schema\TableDiff;
+use Doctrine\DBAL\Types\BinaryType;
+use Doctrine\DBAL\Types\BlobType;
+use Doctrine\DBAL\Types\PhpIntegerMappingType;
+use Doctrine\DBAL\Types\Type;
+use Doctrine\Deprecations\Deprecation;
+use UnexpectedValueException;
+
+use function array_diff;
+use function array_merge;
+use function array_unique;
+use function array_values;
+use function count;
+use function explode;
+use function implode;
+use function in_array;
+use function is_array;
+use function is_bool;
+use function is_numeric;
+use function is_string;
+use function sprintf;
+use function strpos;
+use function strtolower;
+use function trim;
+
+/**
+ * Provides the behavior, features and SQL dialect of the PostgreSQL database platform of the oldest supported version.
+ */
+class PostgreSQLPlatform extends AbstractPlatform
+{
+ /** @var bool */
+ private $useBooleanTrueFalseStrings = true;
+
+ /** @var string[][] PostgreSQL booleans literals */
+ private $booleanLiterals = [
+ 'true' => [
+ 't',
+ 'true',
+ 'y',
+ 'yes',
+ 'on',
+ '1',
+ ],
+ 'false' => [
+ 'f',
+ 'false',
+ 'n',
+ 'no',
+ 'off',
+ '0',
+ ],
+ ];
+
+ /**
+ * PostgreSQL has different behavior with some drivers
+ * with regard to how booleans have to be handled.
+ *
+ * Enables use of 'true'/'false' or otherwise 1 and 0 instead.
+ *
+ * @param bool $flag
+ *
+ * @return void
+ */
+ public function setUseBooleanTrueFalseStrings($flag)
+ {
+ $this->useBooleanTrueFalseStrings = (bool) $flag;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getSubstringExpression($string, $start, $length = null)
+ {
+ if ($length === null) {
+ return 'SUBSTRING(' . $string . ' FROM ' . $start . ')';
+ }
+
+ return 'SUBSTRING(' . $string . ' FROM ' . $start . ' FOR ' . $length . ')';
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated Generate dates within the application.
+ */
+ public function getNowExpression()
+ {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4753',
+ 'PostgreSQLPlatform::getNowExpression() is deprecated. Generate dates within the application.'
+ );
+
+ return 'LOCALTIMESTAMP(0)';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getRegexpExpression()
+ {
+ return 'SIMILAR TO';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getLocateExpression($str, $substr, $startPos = false)
+ {
+ if ($startPos !== false) {
+ $str = $this->getSubstringExpression($str, $startPos);
+
+ return 'CASE WHEN (POSITION(' . $substr . ' IN ' . $str . ') = 0) THEN 0'
+ . ' ELSE (POSITION(' . $substr . ' IN ' . $str . ') + ' . $startPos . ' - 1) END';
+ }
+
+ return 'POSITION(' . $substr . ' IN ' . $str . ')';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit)
+ {
+ if ($unit === DateIntervalUnit::QUARTER) {
+ $interval *= 3;
+ $unit = DateIntervalUnit::MONTH;
+ }
+
+ return '(' . $date . ' ' . $operator . ' (' . $interval . " || ' " . $unit . "')::interval)";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateDiffExpression($date1, $date2)
+ {
+ return '(DATE(' . $date1 . ')-DATE(' . $date2 . '))';
+ }
+
+ public function getCurrentDatabaseExpression(): string
+ {
+ return 'CURRENT_DATABASE()';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supportsSequences()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supportsSchemas()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultSchemaName()
+ {
+ return 'public';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supportsIdentityColumns()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsPartialIndexes()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function usesSequenceEmulatedIdentityColumns()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getIdentitySequenceName($tableName, $columnName)
+ {
+ return $tableName . '_' . $columnName . '_seq';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supportsCommentOnStatement()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function hasNativeGuidType()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListDatabasesSQL()
+ {
+ return 'SELECT datname FROM pg_database';
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated Use {@see PostgreSQLSchemaManager::listSchemaNames()} instead.
+ */
+ public function getListNamespacesSQL()
+ {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4503',
+ 'PostgreSQLPlatform::getListNamespacesSQL() is deprecated,'
+ . ' use PostgreSQLSchemaManager::listSchemaNames() instead.'
+ );
+
+ return "SELECT schema_name AS nspname
+ FROM information_schema.schemata
+ WHERE schema_name NOT LIKE 'pg\_%'
+ AND schema_name != 'information_schema'";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListSequencesSQL($database)
+ {
+ return "SELECT sequence_name AS relname,
+ sequence_schema AS schemaname
+ FROM information_schema.sequences
+ WHERE sequence_schema NOT LIKE 'pg\_%'
+ AND sequence_schema != 'information_schema'";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListTablesSQL()
+ {
+ return "SELECT quote_ident(table_name) AS table_name,
+ table_schema AS schema_name
+ FROM information_schema.tables
+ WHERE table_schema NOT LIKE 'pg\_%'
+ AND table_schema != 'information_schema'
+ AND table_name != 'geometry_columns'
+ AND table_name != 'spatial_ref_sys'
+ AND table_type != 'VIEW'";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListViewsSQL($database)
+ {
+ return 'SELECT quote_ident(table_name) AS viewname,
+ table_schema AS schemaname,
+ view_definition AS definition
+ FROM information_schema.views
+ WHERE view_definition IS NOT NULL';
+ }
+
+ /**
+ * @param string $table
+ * @param string|null $database
+ *
+ * @return string
+ */
+ public function getListTableForeignKeysSQL($table, $database = null)
+ {
+ return 'SELECT quote_ident(r.conname) as conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef
+ FROM pg_catalog.pg_constraint r
+ WHERE r.conrelid =
+ (
+ SELECT c.oid
+ FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n
+ WHERE ' . $this->getTableWhereClause($table) . " AND n.oid = c.relnamespace
+ )
+ AND r.contype = 'f'";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListTableConstraintsSQL($table)
+ {
+ $table = new Identifier($table);
+ $table = $this->quoteStringLiteral($table->getName());
+
+ return sprintf(
+ <<<'SQL'
+SELECT
+ quote_ident(relname) as relname
+FROM
+ pg_class
+WHERE oid IN (
+ SELECT indexrelid
+ FROM pg_index, pg_class
+ WHERE pg_class.relname = %s
+ AND pg_class.oid = pg_index.indrelid
+ AND (indisunique = 't' OR indisprimary = 't')
+ )
+SQL
+ ,
+ $table
+ );
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
+ */
+ public function getListTableIndexesSQL($table, $database = null)
+ {
+ return 'SELECT quote_ident(relname) as relname, pg_index.indisunique, pg_index.indisprimary,
+ pg_index.indkey, pg_index.indrelid,
+ pg_get_expr(indpred, indrelid) AS where
+ FROM pg_class, pg_index
+ WHERE oid IN (
+ SELECT indexrelid
+ FROM pg_index si, pg_class sc, pg_namespace sn
+ WHERE ' . $this->getTableWhereClause($table, 'sc', 'sn') . '
+ AND sc.oid=si.indrelid AND sc.relnamespace = sn.oid
+ ) AND pg_index.indexrelid = oid';
+ }
+
+ /**
+ * @param string $table
+ * @param string $classAlias
+ * @param string $namespaceAlias
+ */
+ private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias = 'n'): string
+ {
+ $whereClause = $namespaceAlias . ".nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND ";
+ if (strpos($table, '.') !== false) {
+ [$schema, $table] = explode('.', $table);
+ $schema = $this->quoteStringLiteral($schema);
+ } else {
+ $schema = 'ANY(current_schemas(false))';
+ }
+
+ $table = new Identifier($table);
+ $table = $this->quoteStringLiteral($table->getName());
+
+ return $whereClause . sprintf(
+ '%s.relname = %s AND %s.nspname = %s',
+ $classAlias,
+ $table,
+ $namespaceAlias,
+ $schema
+ );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListTableColumnsSQL($table, $database = null)
+ {
+ return "SELECT
+ a.attnum,
+ quote_ident(a.attname) AS field,
+ t.typname AS type,
+ format_type(a.atttypid, a.atttypmod) AS complete_type,
+ (SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation,
+ (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type,
+ (SELECT format_type(t2.typbasetype, t2.typtypmod) FROM
+ pg_catalog.pg_type t2 WHERE t2.typtype = 'd' AND t2.oid = a.atttypid) AS domain_complete_type,
+ a.attnotnull AS isnotnull,
+ (SELECT 't'
+ FROM pg_index
+ WHERE c.oid = pg_index.indrelid
+ AND pg_index.indkey[0] = a.attnum
+ AND pg_index.indisprimary = 't'
+ ) AS pri,
+ (SELECT pg_get_expr(adbin, adrelid)
+ FROM pg_attrdef
+ WHERE c.oid = pg_attrdef.adrelid
+ AND pg_attrdef.adnum=a.attnum
+ ) AS default,
+ (SELECT pg_description.description
+ FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid
+ ) AS comment
+ FROM pg_attribute a, pg_class c, pg_type t, pg_namespace n
+ WHERE " . $this->getTableWhereClause($table, 'c', 'n') . '
+ AND a.attnum > 0
+ AND a.attrelid = c.oid
+ AND a.atttypid = t.oid
+ AND n.oid = c.relnamespace
+ ORDER BY a.attnum';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey)
+ {
+ $query = '';
+
+ if ($foreignKey->hasOption('match')) {
+ $query .= ' MATCH ' . $foreignKey->getOption('match');
+ }
+
+ $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
+
+ if ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) {
+ $query .= ' DEFERRABLE';
+ } else {
+ $query .= ' NOT DEFERRABLE';
+ }
+
+ if (
+ ($foreignKey->hasOption('feferred') && $foreignKey->getOption('feferred') !== false)
+ || ($foreignKey->hasOption('deferred') && $foreignKey->getOption('deferred') !== false)
+ ) {
+ $query .= ' INITIALLY DEFERRED';
+ } else {
+ $query .= ' INITIALLY IMMEDIATE';
+ }
+
+ return $query;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAlterTableSQL(TableDiff $diff)
+ {
+ $sql = [];
+ $commentsSQL = [];
+ $columnSql = [];
+
+ foreach ($diff->addedColumns as $column) {
+ if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
+ continue;
+ }
+
+ $query = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
+ $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
+
+ $comment = $this->getColumnComment($column);
+
+ if ($comment === null || $comment === '') {
+ continue;
+ }
+
+ $commentsSQL[] = $this->getCommentOnColumnSQL(
+ $diff->getName($this)->getQuotedName($this),
+ $column->getQuotedName($this),
+ $comment
+ );
+ }
+
+ foreach ($diff->removedColumns as $column) {
+ if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
+ continue;
+ }
+
+ $query = 'DROP ' . $column->getQuotedName($this);
+ $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
+ }
+
+ foreach ($diff->changedColumns as $columnDiff) {
+ if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
+ continue;
+ }
+
+ if ($this->isUnchangedBinaryColumn($columnDiff)) {
+ continue;
+ }
+
+ $oldColumnName = $columnDiff->getOldColumnName()->getQuotedName($this);
+ $column = $columnDiff->column;
+
+ if (
+ $columnDiff->hasChanged('type')
+ || $columnDiff->hasChanged('precision')
+ || $columnDiff->hasChanged('scale')
+ || $columnDiff->hasChanged('fixed')
+ ) {
+ $type = $column->getType();
+
+ // SERIAL/BIGSERIAL are not "real" types and we can't alter a column to that type
+ $columnDefinition = $column->toArray();
+ $columnDefinition['autoincrement'] = false;
+
+ // here was a server version check before, but DBAL API does not support this anymore.
+ $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSQLDeclaration($columnDefinition, $this);
+ $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
+ }
+
+ if ($columnDiff->hasChanged('default') || $this->typeChangeBreaksDefaultValue($columnDiff)) {
+ $defaultClause = $column->getDefault() === null
+ ? ' DROP DEFAULT'
+ : ' SET' . $this->getDefaultValueDeclarationSQL($column->toArray());
+ $query = 'ALTER ' . $oldColumnName . $defaultClause;
+ $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
+ }
+
+ if ($columnDiff->hasChanged('notnull')) {
+ $query = 'ALTER ' . $oldColumnName . ' ' . ($column->getNotnull() ? 'SET' : 'DROP') . ' NOT NULL';
+ $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
+ }
+
+ if ($columnDiff->hasChanged('autoincrement')) {
+ if ($column->getAutoincrement()) {
+ // add autoincrement
+ $seqName = $this->getIdentitySequenceName($diff->name, $oldColumnName);
+
+ $sql[] = 'CREATE SEQUENCE ' . $seqName;
+ $sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ') FROM '
+ . $diff->getName($this)->getQuotedName($this) . '))';
+ $query = 'ALTER ' . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')";
+ $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
+ } else {
+ // Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have
+ $query = 'ALTER ' . $oldColumnName . ' DROP DEFAULT';
+ $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
+ }
+ }
+
+ $newComment = $this->getColumnComment($column);
+ $oldComment = $this->getOldColumnComment($columnDiff);
+
+ if (
+ $columnDiff->hasChanged('comment')
+ || ($columnDiff->fromColumn !== null && $oldComment !== $newComment)
+ ) {
+ $commentsSQL[] = $this->getCommentOnColumnSQL(
+ $diff->getName($this)->getQuotedName($this),
+ $column->getQuotedName($this),
+ $newComment
+ );
+ }
+
+ if (! $columnDiff->hasChanged('length')) {
+ continue;
+ }
+
+ $query = 'ALTER ' . $oldColumnName . ' TYPE '
+ . $column->getType()->getSQLDeclaration($column->toArray(), $this);
+ $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
+ }
+
+ foreach ($diff->renamedColumns as $oldColumnName => $column) {
+ if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
+ continue;
+ }
+
+ $oldColumnName = new Identifier($oldColumnName);
+
+ $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) .
+ ' RENAME COLUMN ' . $oldColumnName->getQuotedName($this) . ' TO ' . $column->getQuotedName($this);
+ }
+
+ $tableSql = [];
+
+ if (! $this->onSchemaAlterTable($diff, $tableSql)) {
+ $sql = array_merge($sql, $commentsSQL);
+
+ $newName = $diff->getNewName();
+
+ if ($newName !== false) {
+ $sql[] = sprintf(
+ 'ALTER TABLE %s RENAME TO %s',
+ $diff->getName($this)->getQuotedName($this),
+ $newName->getQuotedName($this)
+ );
+ }
+
+ $sql = array_merge(
+ $this->getPreAlterTableIndexForeignKeySQL($diff),
+ $sql,
+ $this->getPostAlterTableIndexForeignKeySQL($diff)
+ );
+ }
+
+ return array_merge($sql, $tableSql, $columnSql);
+ }
+
+ /**
+ * Checks whether a given column diff is a logically unchanged binary type column.
+ *
+ * Used to determine whether a column alteration for a binary type column can be skipped.
+ * Doctrine's {@see BinaryType} and {@see BlobType} are mapped to the same database column type on this platform
+ * as this platform does not have a native VARBINARY/BINARY column type. Therefore the comparator
+ * might detect differences for binary type columns which do not have to be propagated
+ * to database as there actually is no difference at database level.
+ */
+ private function isUnchangedBinaryColumn(ColumnDiff $columnDiff): bool
+ {
+ $columnType = $columnDiff->column->getType();
+
+ if (! $columnType instanceof BinaryType && ! $columnType instanceof BlobType) {
+ return false;
+ }
+
+ $fromColumn = $columnDiff->fromColumn instanceof Column ? $columnDiff->fromColumn : null;
+
+ if ($fromColumn !== null) {
+ $fromColumnType = $fromColumn->getType();
+
+ if (! $fromColumnType instanceof BinaryType && ! $fromColumnType instanceof BlobType) {
+ return false;
+ }
+
+ return count(array_diff($columnDiff->changedProperties, ['type', 'length', 'fixed'])) === 0;
+ }
+
+ if ($columnDiff->hasChanged('type')) {
+ return false;
+ }
+
+ return count(array_diff($columnDiff->changedProperties, ['length', 'fixed'])) === 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName)
+ {
+ if (strpos($tableName, '.') !== false) {
+ [$schema] = explode('.', $tableName);
+ $oldIndexName = $schema . '.' . $oldIndexName;
+ }
+
+ return ['ALTER INDEX ' . $oldIndexName . ' RENAME TO ' . $index->getQuotedName($this)];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCommentOnColumnSQL($tableName, $columnName, $comment)
+ {
+ $tableName = new Identifier($tableName);
+ $columnName = new Identifier($columnName);
+ $comment = $comment === null ? 'NULL' : $this->quoteStringLiteral($comment);
+
+ return sprintf(
+ 'COMMENT ON COLUMN %s.%s IS %s',
+ $tableName->getQuotedName($this),
+ $columnName->getQuotedName($this),
+ $comment
+ );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getCreateSequenceSQL(Sequence $sequence)
+ {
+ return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
+ ' INCREMENT BY ' . $sequence->getAllocationSize() .
+ ' MINVALUE ' . $sequence->getInitialValue() .
+ ' START ' . $sequence->getInitialValue() .
+ $this->getSequenceCacheSQL($sequence);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAlterSequenceSQL(Sequence $sequence)
+ {
+ return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
+ ' INCREMENT BY ' . $sequence->getAllocationSize() .
+ $this->getSequenceCacheSQL($sequence);
+ }
+
+ /**
+ * Cache definition for sequences
+ */
+ private function getSequenceCacheSQL(Sequence $sequence): string
+ {
+ if ($sequence->getCache() > 1) {
+ return ' CACHE ' . $sequence->getCache();
+ }
+
+ return '';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDropSequenceSQL($sequence)
+ {
+ return parent::getDropSequenceSQL($sequence) . ' CASCADE';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDropForeignKeySQL($foreignKey, $table)
+ {
+ return $this->getDropConstraintSQL($foreignKey, $table);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function _getCreateTableSQL($name, array $columns, array $options = [])
+ {
+ $queryFields = $this->getColumnDeclarationListSQL($columns);
+
+ if (isset($options['primary']) && ! empty($options['primary'])) {
+ $keyColumns = array_unique(array_values($options['primary']));
+ $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
+ }
+
+ $query = 'CREATE TABLE ' . $name . ' (' . $queryFields . ')';
+
+ $sql = [$query];
+
+ if (isset($options['indexes']) && ! empty($options['indexes'])) {
+ foreach ($options['indexes'] as $index) {
+ $sql[] = $this->getCreateIndexSQL($index, $name);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Converts a single boolean value.
+ *
+ * First converts the value to its native PHP boolean type
+ * and passes it to the given callback function to be reconverted
+ * into any custom representation.
+ *
+ * @param mixed $value The value to convert.
+ * @param callable $callback The callback function to use for converting the real boolean value.
+ *
+ * @return mixed
+ *
+ * @throws UnexpectedValueException
+ */
+ private function convertSingleBooleanValue($value, $callback)
+ {
+ if ($value === null) {
+ return $callback(null);
+ }
+
+ if (is_bool($value) || is_numeric($value)) {
+ return $callback((bool) $value);
+ }
+
+ if (! is_string($value)) {
+ return $callback(true);
+ }
+
+ /**
+ * Better safe than sorry: http://php.net/in_array#106319
+ */
+ if (in_array(strtolower(trim($value)), $this->booleanLiterals['false'], true)) {
+ return $callback(false);
+ }
+
+ if (in_array(strtolower(trim($value)), $this->booleanLiterals['true'], true)) {
+ return $callback(true);
+ }
+
+ throw new UnexpectedValueException(sprintf("Unrecognized boolean literal '%s'", $value));
+ }
+
+ /**
+ * Converts one or multiple boolean values.
+ *
+ * First converts the value(s) to their native PHP boolean type
+ * and passes them to the given callback function to be reconverted
+ * into any custom representation.
+ *
+ * @param mixed $item The value(s) to convert.
+ * @param callable $callback The callback function to use for converting the real boolean value(s).
+ *
+ * @return mixed
+ */
+ private function doConvertBooleans($item, $callback)
+ {
+ if (is_array($item)) {
+ foreach ($item as $key => $value) {
+ $item[$key] = $this->convertSingleBooleanValue($value, $callback);
+ }
+
+ return $item;
+ }
+
+ return $this->convertSingleBooleanValue($item, $callback);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Postgres wants boolean values converted to the strings 'true'/'false'.
+ */
+ public function convertBooleans($item)
+ {
+ if (! $this->useBooleanTrueFalseStrings) {
+ return parent::convertBooleans($item);
+ }
+
+ return $this->doConvertBooleans(
+ $item,
+ /**
+ * @param mixed $value
+ */
+ static function ($value) {
+ if ($value === null) {
+ return 'NULL';
+ }
+
+ return $value === true ? 'true' : 'false';
+ }
+ );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertBooleansToDatabaseValue($item)
+ {
+ if (! $this->useBooleanTrueFalseStrings) {
+ return parent::convertBooleansToDatabaseValue($item);
+ }
+
+ return $this->doConvertBooleans(
+ $item,
+ /**
+ * @param mixed $value
+ */
+ static function ($value): ?int {
+ return $value === null ? null : (int) $value;
+ }
+ );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertFromBoolean($item)
+ {
+ if ($item !== null && in_array(strtolower($item), $this->booleanLiterals['false'], true)) {
+ return false;
+ }
+
+ return parent::convertFromBoolean($item);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getSequenceNextValSQL($sequence)
+ {
+ return "SELECT NEXTVAL('" . $sequence . "')";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getSetTransactionIsolationSQL($level)
+ {
+ return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL '
+ . $this->_getTransactionIsolationLevelSQL($level);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getBooleanTypeDeclarationSQL(array $column)
+ {
+ return 'BOOLEAN';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getIntegerTypeDeclarationSQL(array $column)
+ {
+ if (! empty($column['autoincrement'])) {
+ return 'SERIAL';
+ }
+
+ return 'INT';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getBigIntTypeDeclarationSQL(array $column)
+ {
+ if (! empty($column['autoincrement'])) {
+ return 'BIGSERIAL';
+ }
+
+ return 'BIGINT';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getSmallIntTypeDeclarationSQL(array $column)
+ {
+ if (! empty($column['autoincrement'])) {
+ return 'SMALLSERIAL';
+ }
+
+ return 'SMALLINT';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getGuidTypeDeclarationSQL(array $column)
+ {
+ return 'UUID';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTimeTypeDeclarationSQL(array $column)
+ {
+ return 'TIMESTAMP(0) WITHOUT TIME ZONE';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTimeTzTypeDeclarationSQL(array $column)
+ {
+ return 'TIMESTAMP(0) WITH TIME ZONE';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTypeDeclarationSQL(array $column)
+ {
+ return 'DATE';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getTimeTypeDeclarationSQL(array $column)
+ {
+ return 'TIME(0) WITHOUT TIME ZONE';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function _getCommonIntegerTypeDeclarationSQL(array $column)
+ {
+ return '';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
+ {
+ return $fixed ? ($length > 0 ? 'CHAR(' . $length . ')' : 'CHAR(255)')
+ : ($length > 0 ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
+ {
+ return 'BYTEA';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getClobTypeDeclarationSQL(array $column)
+ {
+ return 'TEXT';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getName()
+ {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4749',
+ 'PostgreSQLPlatform::getName() is deprecated. Identify platforms by their class.'
+ );
+
+ return 'postgresql';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTimeTzFormatString()
+ {
+ return 'Y-m-d H:i:sO';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
+ {
+ return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getTruncateTableSQL($tableName, $cascade = false)
+ {
+ $tableIdentifier = new Identifier($tableName);
+ $sql = 'TRUNCATE ' . $tableIdentifier->getQuotedName($this);
+
+ if ($cascade) {
+ $sql .= ' CASCADE';
+ }
+
+ return $sql;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getReadLockSQL()
+ {
+ return 'FOR SHARE';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function initializeDoctrineTypeMappings()
+ {
+ $this->doctrineTypeMapping = [
+ 'bigint' => 'bigint',
+ 'bigserial' => 'bigint',
+ 'bool' => 'boolean',
+ 'boolean' => 'boolean',
+ 'bpchar' => 'string',
+ 'bytea' => 'blob',
+ 'char' => 'string',
+ 'date' => 'date',
+ 'datetime' => 'datetime',
+ 'decimal' => 'decimal',
+ 'double' => 'float',
+ 'double precision' => 'float',
+ 'float' => 'float',
+ 'float4' => 'float',
+ 'float8' => 'float',
+ 'inet' => 'string',
+ 'int' => 'integer',
+ 'int2' => 'smallint',
+ 'int4' => 'integer',
+ 'int8' => 'bigint',
+ 'integer' => 'integer',
+ 'interval' => 'string',
+ 'json' => 'json',
+ 'jsonb' => 'json',
+ 'money' => 'decimal',
+ 'numeric' => 'decimal',
+ 'serial' => 'integer',
+ 'serial4' => 'integer',
+ 'serial8' => 'bigint',
+ 'real' => 'float',
+ 'smallint' => 'smallint',
+ 'text' => 'text',
+ 'time' => 'time',
+ 'timestamp' => 'datetime',
+ 'timestamptz' => 'datetimetz',
+ 'timetz' => 'time',
+ 'tsvector' => 'text',
+ 'uuid' => 'guid',
+ 'varchar' => 'string',
+ 'year' => 'date',
+ '_varchar' => 'string',
+ ];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getVarcharMaxLength()
+ {
+ return 65535;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBinaryMaxLength()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBinaryDefaultLength()
+ {
+ return 0;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasNativeJsonType()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated Implement {@see createReservedKeywordsList()} instead.
+ */
+ protected function getReservedKeywordsClass()
+ {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'PostgreSQLPlatform::getReservedKeywordsClass() is deprecated,'
+ . ' use PostgreSQLPlatform::createReservedKeywordsList() instead.'
+ );
+
+ return Keywords\PostgreSQL94Keywords::class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getBlobTypeDeclarationSQL(array $column)
+ {
+ return 'BYTEA';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultValueDeclarationSQL($column)
+ {
+ if ($this->isSerialColumn($column)) {
+ return '';
+ }
+
+ return parent::getDefaultValueDeclarationSQL($column);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsColumnCollation()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getColumnCollationDeclarationSQL($collation)
+ {
+ return 'COLLATE ' . $this->quoteSingleIdentifier($collation);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getJsonTypeDeclarationSQL(array $column)
+ {
+ if (! empty($column['jsonb'])) {
+ return 'JSONB';
+ }
+
+ return 'JSON';
+ }
+
+ /**
+ * @param mixed[] $column
+ */
+ private function isSerialColumn(array $column): bool
+ {
+ return isset($column['type'], $column['autoincrement'])
+ && $column['autoincrement'] === true
+ && $this->isIntegerType($column['type']);
+ }
+
+ /**
+ * Check whether the type of a column is changed in a way that invalidates the default value for the column
+ */
+ private function typeChangeBreaksDefaultValue(ColumnDiff $columnDiff): bool
+ {
+ if ($columnDiff->fromColumn === null) {
+ return $columnDiff->hasChanged('type');
+ }
+
+ $oldTypeIsInteger = $this->isIntegerType($columnDiff->fromColumn->getType());
+ $newTypeIsInteger = $this->isIntegerType($columnDiff->column->getType());
+
+ // default should not be changed when switching between integer types and the default comes from a sequence
+ return $columnDiff->hasChanged('type')
+ && ! ($oldTypeIsInteger && $newTypeIsInteger && $columnDiff->column->getAutoincrement());
+ }
+
+ private function isIntegerType(Type $type): bool
+ {
+ return $type instanceof PhpIntegerMappingType;
+ }
+
+ private function getOldColumnComment(ColumnDiff $columnDiff): ?string
+ {
+ return $columnDiff->fromColumn !== null ? $this->getColumnComment($columnDiff->fromColumn) : null;
+ }
+
+ public function getListTableMetadataSQL(string $table, ?string $schema = null): string
+ {
+ if ($schema !== null) {
+ $table = $schema . '.' . $table;
+ }
+
+ return sprintf(
+ <<<'SQL'
+SELECT obj_description(%s::regclass) AS table_comment;
+SQL
+ ,
+ $this->quoteStringLiteral($table)
+ );
+ }
+}
diff --git a/doctrine/dbal/src/Platforms/SQLServer/Comparator.php b/doctrine/dbal/src/Platforms/SQLServer/Comparator.php
new file mode 100644
index 00000000..0db1a6a5
--- /dev/null
+++ b/doctrine/dbal/src/Platforms/SQLServer/Comparator.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Doctrine\DBAL\Platforms\SQLServer;
+
+use Doctrine\DBAL\Platforms\SQLServerPlatform;
+use Doctrine\DBAL\Schema\Comparator as BaseComparator;
+use Doctrine\DBAL\Schema\Table;
+
+/**
+ * Compares schemas in the context of SQL Server platform.
+ *
+ * @link https://docs.microsoft.com/en-us/sql/t-sql/statements/collations?view=sql-server-ver15
+ */
+class Comparator extends BaseComparator
+{
+ /** @var string */
+ private $databaseCollation;
+
+ /**
+ * @internal The comparator can be only instantiated by a schema manager.
+ */
+ public function __construct(SQLServerPlatform $platform, string $databaseCollation)
+ {
+ parent::__construct($platform);
+
+ $this->databaseCollation = $databaseCollation;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function diffTable(Table $fromTable, Table $toTable)
+ {
+ $fromTable = clone $fromTable;
+ $toTable = clone $toTable;
+
+ $this->normalizeColumns($fromTable);
+ $this->normalizeColumns($toTable);
+
+ return parent::diffTable($fromTable, $toTable);
+ }
+
+ private function normalizeColumns(Table $table): void
+ {
+ foreach ($table->getColumns() as $column) {
+ $options = $column->getPlatformOptions();
+
+ if (! isset($options['collation']) || $options['collation'] !== $this->databaseCollation) {
+ continue;
+ }
+
+ unset($options['collation']);
+ $column->setPlatformOptions($options);
+ }
+ }
+}
diff --git a/doctrine/dbal/src/Platforms/SQLServer2012Platform.php b/doctrine/dbal/src/Platforms/SQLServer2012Platform.php
index 4db8f055..a8ba2fa0 100644
--- a/doctrine/dbal/src/Platforms/SQLServer2012Platform.php
+++ b/doctrine/dbal/src/Platforms/SQLServer2012Platform.php
@@ -2,1729 +2,12 @@
namespace Doctrine\DBAL\Platforms;
-use Doctrine\DBAL\Exception\InvalidLockMode;
-use Doctrine\DBAL\LockMode;
-use Doctrine\DBAL\Schema\Column;
-use Doctrine\DBAL\Schema\ColumnDiff;
-use Doctrine\DBAL\Schema\ForeignKeyConstraint;
-use Doctrine\DBAL\Schema\Identifier;
-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;
-use function array_unique;
-use function array_values;
-use function count;
-use function crc32;
-use function dechex;
-use function explode;
-use function func_get_args;
-use function implode;
-use function is_array;
-use function is_bool;
-use function is_numeric;
-use function is_string;
-use function preg_match;
-use function preg_match_all;
-use function sprintf;
-use function str_replace;
-use function strpos;
-use function strtoupper;
-use function substr_count;
-
-use const PREG_OFFSET_CAPTURE;
-
/**
- * Provides the behavior, features and SQL dialect of the Microsoft SQL Server 2012 database platform.
+ * Provides the behavior, features and SQL dialect of the Microsoft SQL Server database platform
+ * of the oldest supported version.
+ *
+ * @deprecated Use {@see SQLServerPlatform} instead.
*/
-class SQLServer2012Platform extends AbstractPlatform
+class SQLServer2012Platform extends SQLServerPlatform
{
- /**
- * {@inheritdoc}
- */
- public function getCurrentDateSQL()
- {
- return $this->getConvertExpression('date', 'GETDATE()');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getCurrentTimeSQL()
- {
- return $this->getConvertExpression('time', 'GETDATE()');
- }
-
- /**
- * Returns an expression that converts an expression of one data type to another.
- *
- * @param string $dataType The target native data type. Alias data types cannot be used.
- * @param string $expression The SQL expression to convert.
- *
- * @return string
- */
- private function getConvertExpression($dataType, $expression)
- {
- return sprintf('CONVERT(%s, %s)', $dataType, $expression);
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit)
- {
- $factorClause = '';
-
- if ($operator === '-') {
- $factorClause = '-1 * ';
- }
-
- return 'DATEADD(' . $unit . ', ' . $factorClause . $interval . ', ' . $date . ')';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateDiffExpression($date1, $date2)
- {
- return 'DATEDIFF(day, ' . $date2 . ',' . $date1 . ')';
- }
-
- /**
- * {@inheritDoc}
- *
- * Microsoft SQL Server prefers "autoincrement" identity columns
- * since sequences can only be emulated with a table.
- */
- public function prefersIdentityColumns()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- *
- * Microsoft SQL Server supports this through AUTO_INCREMENT columns.
- */
- public function supportsIdentityColumns()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsReleaseSavepoints()
- {
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- public function supportsSchemas()
- {
- return true;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDefaultSchemaName()
- {
- return 'dbo';
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsColumnCollation()
- {
- return true;
- }
-
- public function supportsSequences(): bool
- {
- return true;
- }
-
- public function getAlterSequenceSQL(Sequence $sequence): string
- {
- return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
- ' INCREMENT BY ' . $sequence->getAllocationSize();
- }
-
- public function getCreateSequenceSQL(Sequence $sequence): string
- {
- return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
- ' START WITH ' . $sequence->getInitialValue() .
- ' INCREMENT BY ' . $sequence->getAllocationSize() .
- ' MINVALUE ' . $sequence->getInitialValue();
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDropSequenceSQL($sequence): string
- {
- if ($sequence instanceof Sequence) {
- $sequence = $sequence->getQuotedName($this);
- }
-
- return 'DROP SEQUENCE ' . $sequence;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getListSequencesSQL($database)
- {
- return 'SELECT seq.name,
- CAST(
- seq.increment AS VARCHAR(MAX)
- ) AS increment, -- CAST avoids driver error for sql_variant type
- CAST(
- seq.start_value AS VARCHAR(MAX)
- ) AS start_value -- CAST avoids driver error for sql_variant type
- FROM sys.sequences AS seq';
- }
-
- /**
- * {@inheritdoc}
- */
- public function getSequenceNextValSQL($sequence)
- {
- return 'SELECT NEXT VALUE FOR ' . $sequence;
- }
-
- /**
- * {@inheritDoc}
- */
- public function hasNativeGuidType()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateDatabaseSQL($name)
- {
- return 'CREATE DATABASE ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropDatabaseSQL($name)
- {
- return 'DROP DATABASE ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsCreateDropDatabase()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateSchemaSQL($schemaName)
- {
- return 'CREATE SCHEMA ' . $schemaName;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropForeignKeySQL($foreignKey, $table)
- {
- if (! $foreignKey instanceof ForeignKeyConstraint) {
- $foreignKey = new Identifier($foreignKey);
- }
-
- if (! $table instanceof Table) {
- $table = new Identifier($table);
- }
-
- $foreignKey = $foreignKey->getQuotedName($this);
- $table = $table->getQuotedName($this);
-
- return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropIndexSQL($index, $table = null)
- {
- if ($index instanceof Index) {
- $index = $index->getQuotedName($this);
- } elseif (! is_string($index)) {
- throw new InvalidArgumentException(
- __METHOD__ . '() expects $index parameter to be string or ' . Index::class . '.'
- );
- }
-
- if (! isset($table)) {
- return 'DROP INDEX ' . $index;
- }
-
- if ($table instanceof Table) {
- $table = $table->getQuotedName($this);
- }
-
- return sprintf(
- <<<SQL
- IF EXISTS (SELECT * FROM sysobjects WHERE name = '%s')
- ALTER TABLE %s DROP CONSTRAINT %s
- ELSE
- DROP INDEX %s ON %s
- SQL
- ,
- $index,
- $table,
- $index,
- $index,
- $table
- );
- }
-
- /**
- * {@inheritDoc}
- */
- protected function _getCreateTableSQL($name, array $columns, array $options = [])
- {
- $defaultConstraintsSql = [];
- $commentsSql = [];
-
- $tableComment = $options['comment'] ?? null;
- if ($tableComment !== null) {
- $commentsSql[] = $this->getCommentOnTableSQL($name, $tableComment);
- }
-
- // @todo does other code breaks because of this?
- // force primary keys to be not null
- foreach ($columns as &$column) {
- if (! empty($column['primary'])) {
- $column['notnull'] = true;
- }
-
- // Build default constraints SQL statements.
- if (isset($column['default'])) {
- $defaultConstraintsSql[] = 'ALTER TABLE ' . $name .
- ' ADD' . $this->getDefaultConstraintDeclarationSQL($name, $column);
- }
-
- if (empty($column['comment']) && ! is_numeric($column['comment'])) {
- continue;
- }
-
- $commentsSql[] = $this->getCreateColumnCommentSQL($name, $column['name'], $column['comment']);
- }
-
- $columnListSql = $this->getColumnDeclarationListSQL($columns);
-
- if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
- foreach ($options['uniqueConstraints'] as $constraintName => $definition) {
- $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($constraintName, $definition);
- }
- }
-
- if (isset($options['primary']) && ! empty($options['primary'])) {
- $flags = '';
- if (isset($options['primary_index']) && $options['primary_index']->hasFlag('nonclustered')) {
- $flags = ' NONCLUSTERED';
- }
-
- $columnListSql .= ', PRIMARY KEY' . $flags
- . ' (' . implode(', ', array_unique(array_values($options['primary']))) . ')';
- }
-
- $query = 'CREATE TABLE ' . $name . ' (' . $columnListSql;
-
- $check = $this->getCheckDeclarationSQL($columns);
- if (! empty($check)) {
- $query .= ', ' . $check;
- }
-
- $query .= ')';
-
- $sql = [$query];
-
- if (isset($options['indexes']) && ! empty($options['indexes'])) {
- foreach ($options['indexes'] as $index) {
- $sql[] = $this->getCreateIndexSQL($index, $name);
- }
- }
-
- if (isset($options['foreignKeys'])) {
- foreach ((array) $options['foreignKeys'] as $definition) {
- $sql[] = $this->getCreateForeignKeySQL($definition, $name);
- }
- }
-
- return array_merge($sql, $commentsSql, $defaultConstraintsSql);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreatePrimaryKeySQL(Index $index, $table)
- {
- if ($table instanceof Table) {
- $identifier = $table->getQuotedName($this);
- } else {
- $identifier = $table;
- }
-
- $sql = 'ALTER TABLE ' . $identifier . ' ADD PRIMARY KEY';
-
- if ($index->hasFlag('nonclustered')) {
- $sql .= ' NONCLUSTERED';
- }
-
- return $sql . ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')';
- }
-
- /**
- * Returns the SQL statement for creating a column comment.
- *
- * SQL Server does not support native column comments,
- * therefore the extended properties functionality is used
- * as a workaround to store them.
- * The property name used to store column comments is "MS_Description"
- * which provides compatibility with SQL Server Management Studio,
- * as column comments are stored in the same property there when
- * specifying a column's "Description" attribute.
- *
- * @param string $tableName The quoted table name to which the column belongs.
- * @param string $columnName The quoted column name to create the comment for.
- * @param string|null $comment The column's comment.
- *
- * @return string
- */
- protected function getCreateColumnCommentSQL($tableName, $columnName, $comment)
- {
- if (strpos($tableName, '.') !== false) {
- [$schemaSQL, $tableSQL] = explode('.', $tableName);
- $schemaSQL = $this->quoteStringLiteral($schemaSQL);
- $tableSQL = $this->quoteStringLiteral($tableSQL);
- } else {
- $schemaSQL = "'dbo'";
- $tableSQL = $this->quoteStringLiteral($tableName);
- }
-
- return $this->getAddExtendedPropertySQL(
- 'MS_Description',
- $comment,
- 'SCHEMA',
- $schemaSQL,
- 'TABLE',
- $tableSQL,
- 'COLUMN',
- $columnName
- );
- }
-
- /**
- * Returns the SQL snippet for declaring a default constraint.
- *
- * @param string $table Name of the table to return the default constraint declaration for.
- * @param mixed[] $column Column definition.
- *
- * @return string
- *
- * @throws InvalidArgumentException
- */
- public function getDefaultConstraintDeclarationSQL($table, array $column)
- {
- if (! isset($column['default'])) {
- throw new InvalidArgumentException("Incomplete column definition. 'default' required.");
- }
-
- $columnName = new Identifier($column['name']);
-
- return ' CONSTRAINT ' .
- $this->generateDefaultConstraintName($table, $column['name']) .
- $this->getDefaultValueDeclarationSQL($column) .
- ' FOR ' . $columnName->getQuotedName($this);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateIndexSQL(Index $index, $table)
- {
- $constraint = parent::getCreateIndexSQL($index, $table);
-
- if ($index->isUnique() && ! $index->isPrimary()) {
- $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index);
- }
-
- return $constraint;
- }
-
- /**
- * {@inheritDoc}
- */
- protected function getCreateIndexSQLFlags(Index $index)
- {
- $type = '';
- if ($index->isUnique()) {
- $type .= 'UNIQUE ';
- }
-
- if ($index->hasFlag('clustered')) {
- $type .= 'CLUSTERED ';
- } elseif ($index->hasFlag('nonclustered')) {
- $type .= 'NONCLUSTERED ';
- }
-
- return $type;
- }
-
- /**
- * Extend unique key constraint with required filters
- *
- * @param string $sql
- *
- * @return string
- */
- private function _appendUniqueConstraintDefinition($sql, Index $index)
- {
- $fields = [];
-
- foreach ($index->getQuotedColumns($this) as $field) {
- $fields[] = $field . ' IS NOT NULL';
- }
-
- return $sql . ' WHERE ' . implode(' AND ', $fields);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getAlterTableSQL(TableDiff $diff)
- {
- $queryParts = [];
- $sql = [];
- $columnSql = [];
- $commentsSql = [];
-
- foreach ($diff->addedColumns as $column) {
- if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
- continue;
- }
-
- $columnDef = $column->toArray();
- $addColumnSql = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef);
- if (isset($columnDef['default'])) {
- $addColumnSql .= ' CONSTRAINT ' .
- $this->generateDefaultConstraintName($diff->name, $column->getQuotedName($this)) .
- $this->getDefaultValueDeclarationSQL($columnDef);
- }
-
- $queryParts[] = $addColumnSql;
-
- $comment = $this->getColumnComment($column);
-
- if (empty($comment) && ! is_numeric($comment)) {
- continue;
- }
-
- $commentsSql[] = $this->getCreateColumnCommentSQL(
- $diff->name,
- $column->getQuotedName($this),
- $comment
- );
- }
-
- foreach ($diff->removedColumns as $column) {
- if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
- continue;
- }
-
- $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this);
- }
-
- foreach ($diff->changedColumns as $columnDiff) {
- if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
- continue;
- }
-
- $column = $columnDiff->column;
- $comment = $this->getColumnComment($column);
- $hasComment = ! empty($comment) || is_numeric($comment);
-
- if ($columnDiff->fromColumn instanceof Column) {
- $fromComment = $this->getColumnComment($columnDiff->fromColumn);
- $hasFromComment = ! empty($fromComment) || is_numeric($fromComment);
-
- if ($hasFromComment && $hasComment && $fromComment !== $comment) {
- $commentsSql[] = $this->getAlterColumnCommentSQL(
- $diff->name,
- $column->getQuotedName($this),
- $comment
- );
- } elseif ($hasFromComment && ! $hasComment) {
- $commentsSql[] = $this->getDropColumnCommentSQL($diff->name, $column->getQuotedName($this));
- } elseif (! $hasFromComment && $hasComment) {
- $commentsSql[] = $this->getCreateColumnCommentSQL(
- $diff->name,
- $column->getQuotedName($this),
- $comment
- );
- }
- }
-
- // Do not add query part if only comment has changed.
- if ($columnDiff->hasChanged('comment') && count($columnDiff->changedProperties) === 1) {
- continue;
- }
-
- $requireDropDefaultConstraint = $this->alterColumnRequiresDropDefaultConstraint($columnDiff);
-
- if ($requireDropDefaultConstraint) {
- $queryParts[] = $this->getAlterTableDropDefaultConstraintClause(
- $diff->name,
- $columnDiff->oldColumnName
- );
- }
-
- $columnDef = $column->toArray();
-
- $queryParts[] = 'ALTER COLUMN ' .
- $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef);
-
- if (
- ! isset($columnDef['default'])
- || (! $requireDropDefaultConstraint && ! $columnDiff->hasChanged('default'))
- ) {
- continue;
- }
-
- $queryParts[] = $this->getAlterTableAddDefaultConstraintClause($diff->name, $column);
- }
-
- foreach ($diff->renamedColumns as $oldColumnName => $column) {
- if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
- continue;
- }
-
- $oldColumnName = new Identifier($oldColumnName);
-
- $sql[] = "sp_rename '" .
- $diff->getName($this)->getQuotedName($this) . '.' . $oldColumnName->getQuotedName($this) .
- "', '" . $column->getQuotedName($this) . "', 'COLUMN'";
-
- // Recreate default constraint with new column name if necessary (for future reference).
- if ($column->getDefault() === null) {
- continue;
- }
-
- $queryParts[] = $this->getAlterTableDropDefaultConstraintClause(
- $diff->name,
- $oldColumnName->getQuotedName($this)
- );
- $queryParts[] = $this->getAlterTableAddDefaultConstraintClause($diff->name, $column);
- }
-
- $tableSql = [];
-
- if ($this->onSchemaAlterTable($diff, $tableSql)) {
- return array_merge($tableSql, $columnSql);
- }
-
- foreach ($queryParts as $query) {
- $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
- }
-
- $sql = array_merge($sql, $commentsSql);
-
- $newName = $diff->getNewName();
-
- if ($newName !== false) {
- $sql[] = "sp_rename '" . $diff->getName($this)->getQuotedName($this) . "', '" . $newName->getName() . "'";
-
- /**
- * Rename table's default constraints names
- * to match the new table name.
- * This is necessary to ensure that the default
- * constraints can be referenced in future table
- * alterations as the table name is encoded in
- * default constraints' names.
- */
- $sql[] = "DECLARE @sql NVARCHAR(MAX) = N''; " .
- "SELECT @sql += N'EXEC sp_rename N''' + dc.name + ''', N''' " .
- "+ REPLACE(dc.name, '" . $this->generateIdentifierName($diff->name) . "', " .
- "'" . $this->generateIdentifierName($newName->getName()) . "') + ''', ''OBJECT'';' " .
- 'FROM sys.default_constraints dc ' .
- 'JOIN sys.tables tbl ON dc.parent_object_id = tbl.object_id ' .
- "WHERE tbl.name = '" . $newName->getName() . "';" .
- 'EXEC sp_executesql @sql';
- }
-
- $sql = array_merge(
- $this->getPreAlterTableIndexForeignKeySQL($diff),
- $sql,
- $this->getPostAlterTableIndexForeignKeySQL($diff)
- );
-
- return array_merge($sql, $tableSql, $columnSql);
- }
-
- /**
- * Returns the SQL clause for adding a default constraint in an ALTER TABLE statement.
- *
- * @param string $tableName The name of the table to generate the clause for.
- * @param Column $column The column to generate the clause for.
- *
- * @return string
- */
- private function getAlterTableAddDefaultConstraintClause($tableName, Column $column)
- {
- $columnDef = $column->toArray();
- $columnDef['name'] = $column->getQuotedName($this);
-
- return 'ADD' . $this->getDefaultConstraintDeclarationSQL($tableName, $columnDef);
- }
-
- /**
- * Returns the SQL clause for dropping an existing default constraint in an ALTER TABLE statement.
- *
- * @param string $tableName The name of the table to generate the clause for.
- * @param string $columnName The name of the column to generate the clause for.
- *
- * @return string
- */
- private function getAlterTableDropDefaultConstraintClause($tableName, $columnName)
- {
- return 'DROP CONSTRAINT ' . $this->generateDefaultConstraintName($tableName, $columnName);
- }
-
- /**
- * Checks whether a column alteration requires dropping its default constraint first.
- *
- * Different to other database vendors SQL Server implements column default values
- * as constraints and therefore changes in a column's default value as well as changes
- * in a column's type require dropping the default constraint first before being to
- * alter the particular column to the new definition.
- *
- * @param ColumnDiff $columnDiff The column diff to evaluate.
- *
- * @return bool True if the column alteration requires dropping its default constraint first, false otherwise.
- */
- private function alterColumnRequiresDropDefaultConstraint(ColumnDiff $columnDiff)
- {
- // We can only decide whether to drop an existing default constraint
- // if we know the original default value.
- if (! $columnDiff->fromColumn instanceof Column) {
- return false;
- }
-
- // We only need to drop an existing default constraint if we know the
- // column was defined with a default value before.
- if ($columnDiff->fromColumn->getDefault() === null) {
- return false;
- }
-
- // We need to drop an existing default constraint if the column was
- // defined with a default value before and it has changed.
- if ($columnDiff->hasChanged('default')) {
- return true;
- }
-
- // We need to drop an existing default constraint if the column was
- // defined with a default value before and the native column type has changed.
- return $columnDiff->hasChanged('type') || $columnDiff->hasChanged('fixed');
- }
-
- /**
- * Returns the SQL statement for altering a column comment.
- *
- * SQL Server does not support native column comments,
- * therefore the extended properties functionality is used
- * as a workaround to store them.
- * The property name used to store column comments is "MS_Description"
- * which provides compatibility with SQL Server Management Studio,
- * as column comments are stored in the same property there when
- * specifying a column's "Description" attribute.
- *
- * @param string $tableName The quoted table name to which the column belongs.
- * @param string $columnName The quoted column name to alter the comment for.
- * @param string|null $comment The column's comment.
- *
- * @return string
- */
- protected function getAlterColumnCommentSQL($tableName, $columnName, $comment)
- {
- if (strpos($tableName, '.') !== false) {
- [$schemaSQL, $tableSQL] = explode('.', $tableName);
- $schemaSQL = $this->quoteStringLiteral($schemaSQL);
- $tableSQL = $this->quoteStringLiteral($tableSQL);
- } else {
- $schemaSQL = "'dbo'";
- $tableSQL = $this->quoteStringLiteral($tableName);
- }
-
- return $this->getUpdateExtendedPropertySQL(
- 'MS_Description',
- $comment,
- 'SCHEMA',
- $schemaSQL,
- 'TABLE',
- $tableSQL,
- 'COLUMN',
- $columnName
- );
- }
-
- /**
- * Returns the SQL statement for dropping a column comment.
- *
- * SQL Server does not support native column comments,
- * therefore the extended properties functionality is used
- * as a workaround to store them.
- * The property name used to store column comments is "MS_Description"
- * which provides compatibility with SQL Server Management Studio,
- * as column comments are stored in the same property there when
- * specifying a column's "Description" attribute.
- *
- * @param string $tableName The quoted table name to which the column belongs.
- * @param string $columnName The quoted column name to drop the comment for.
- *
- * @return string
- */
- protected function getDropColumnCommentSQL($tableName, $columnName)
- {
- if (strpos($tableName, '.') !== false) {
- [$schemaSQL, $tableSQL] = explode('.', $tableName);
- $schemaSQL = $this->quoteStringLiteral($schemaSQL);
- $tableSQL = $this->quoteStringLiteral($tableSQL);
- } else {
- $schemaSQL = "'dbo'";
- $tableSQL = $this->quoteStringLiteral($tableName);
- }
-
- return $this->getDropExtendedPropertySQL(
- 'MS_Description',
- 'SCHEMA',
- $schemaSQL,
- 'TABLE',
- $tableSQL,
- 'COLUMN',
- $columnName
- );
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName)
- {
- return [sprintf(
- "EXEC sp_rename N'%s.%s', N'%s', N'INDEX'",
- $tableName,
- $oldIndexName,
- $index->getQuotedName($this)
- ),
- ];
- }
-
- /**
- * Returns the SQL statement for adding an extended property to a database object.
- *
- * @link http://msdn.microsoft.com/en-us/library/ms180047%28v=sql.90%29.aspx
- *
- * @param string $name The name of the property to add.
- * @param string|null $value The value of the property to add.
- * @param string|null $level0Type The type of the object at level 0 the property belongs to.
- * @param string|null $level0Name The name of the object at level 0 the property belongs to.
- * @param string|null $level1Type The type of the object at level 1 the property belongs to.
- * @param string|null $level1Name The name of the object at level 1 the property belongs to.
- * @param string|null $level2Type The type of the object at level 2 the property belongs to.
- * @param string|null $level2Name The name of the object at level 2 the property belongs to.
- *
- * @return string
- */
- public function getAddExtendedPropertySQL(
- $name,
- $value = null,
- $level0Type = null,
- $level0Name = null,
- $level1Type = null,
- $level1Name = null,
- $level2Type = null,
- $level2Name = null
- ) {
- return 'EXEC sp_addextendedproperty ' .
- 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' .
- 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' .
- 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' .
- 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name;
- }
-
- /**
- * Returns the SQL statement for dropping an extended property from a database object.
- *
- * @link http://technet.microsoft.com/en-gb/library/ms178595%28v=sql.90%29.aspx
- *
- * @param string $name The name of the property to drop.
- * @param string|null $level0Type The type of the object at level 0 the property belongs to.
- * @param string|null $level0Name The name of the object at level 0 the property belongs to.
- * @param string|null $level1Type The type of the object at level 1 the property belongs to.
- * @param string|null $level1Name The name of the object at level 1 the property belongs to.
- * @param string|null $level2Type The type of the object at level 2 the property belongs to.
- * @param string|null $level2Name The name of the object at level 2 the property belongs to.
- *
- * @return string
- */
- public function getDropExtendedPropertySQL(
- $name,
- $level0Type = null,
- $level0Name = null,
- $level1Type = null,
- $level1Name = null,
- $level2Type = null,
- $level2Name = null
- ) {
- return 'EXEC sp_dropextendedproperty ' .
- 'N' . $this->quoteStringLiteral($name) . ', ' .
- 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' .
- 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' .
- 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name;
- }
-
- /**
- * Returns the SQL statement for updating an extended property of a database object.
- *
- * @link http://msdn.microsoft.com/en-us/library/ms186885%28v=sql.90%29.aspx
- *
- * @param string $name The name of the property to update.
- * @param string|null $value The value of the property to update.
- * @param string|null $level0Type The type of the object at level 0 the property belongs to.
- * @param string|null $level0Name The name of the object at level 0 the property belongs to.
- * @param string|null $level1Type The type of the object at level 1 the property belongs to.
- * @param string|null $level1Name The name of the object at level 1 the property belongs to.
- * @param string|null $level2Type The type of the object at level 2 the property belongs to.
- * @param string|null $level2Name The name of the object at level 2 the property belongs to.
- *
- * @return string
- */
- public function getUpdateExtendedPropertySQL(
- $name,
- $value = null,
- $level0Type = null,
- $level0Name = null,
- $level1Type = null,
- $level1Name = null,
- $level2Type = null,
- $level2Name = null
- ) {
- return 'EXEC sp_updateextendedproperty ' .
- 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' .
- 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' .
- 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' .
- 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
- {
- return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTablesSQL()
- {
- // "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams
- // Category 2 must be ignored as it is "MS SQL Server 'pseudo-system' object[s]" for replication
- return 'SELECT name, SCHEMA_NAME (uid) AS schema_name FROM sysobjects'
- . " WHERE type = 'U' AND name != 'sysdiagrams' AND category != 2 ORDER BY name";
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTableColumnsSQL($table, $database = null)
- {
- return "SELECT col.name,
- type.name AS type,
- col.max_length AS length,
- ~col.is_nullable AS notnull,
- def.definition AS [default],
- col.scale,
- col.precision,
- col.is_identity AS autoincrement,
- col.collation_name AS collation,
- CAST(prop.value AS NVARCHAR(MAX)) AS comment -- CAST avoids driver error for sql_variant type
- FROM sys.columns AS col
- JOIN sys.types AS type
- ON col.user_type_id = type.user_type_id
- JOIN sys.objects AS obj
- ON col.object_id = obj.object_id
- JOIN sys.schemas AS scm
- ON obj.schema_id = scm.schema_id
- LEFT JOIN sys.default_constraints def
- ON col.default_object_id = def.object_id
- AND col.object_id = def.parent_object_id
- LEFT JOIN sys.extended_properties AS prop
- ON obj.object_id = prop.major_id
- AND col.column_id = prop.minor_id
- AND prop.name = 'MS_Description'
- WHERE obj.type = 'U'
- AND " . $this->getTableWhereClause($table, 'scm.name', 'obj.name');
- }
-
- /**
- * @param string $table
- * @param string|null $database
- *
- * @return string
- */
- public function getListTableForeignKeysSQL($table, $database = null)
- {
- return 'SELECT f.name AS ForeignKey,
- SCHEMA_NAME (f.SCHEMA_ID) AS SchemaName,
- OBJECT_NAME (f.parent_object_id) AS TableName,
- COL_NAME (fc.parent_object_id,fc.parent_column_id) AS ColumnName,
- SCHEMA_NAME (o.SCHEMA_ID) ReferenceSchemaName,
- OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
- COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName,
- f.delete_referential_action_desc,
- f.update_referential_action_desc
- FROM sys.foreign_keys AS f
- INNER JOIN sys.foreign_key_columns AS fc
- INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id
- ON f.OBJECT_ID = fc.constraint_object_id
- WHERE ' .
- $this->getTableWhereClause($table, 'SCHEMA_NAME (f.schema_id)', 'OBJECT_NAME (f.parent_object_id)') .
- ' ORDER BY fc.constraint_column_id';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListTableIndexesSQL($table, $database = null)
- {
- return "SELECT idx.name AS key_name,
- col.name AS column_name,
- ~idx.is_unique AS non_unique,
- idx.is_primary_key AS [primary],
- CASE idx.type
- WHEN '1' THEN 'clustered'
- WHEN '2' THEN 'nonclustered'
- ELSE NULL
- END AS flags
- FROM sys.tables AS tbl
- JOIN sys.schemas AS scm ON tbl.schema_id = scm.schema_id
- JOIN sys.indexes AS idx ON tbl.object_id = idx.object_id
- JOIN sys.index_columns AS idxcol ON idx.object_id = idxcol.object_id AND idx.index_id = idxcol.index_id
- JOIN sys.columns AS col ON idxcol.object_id = col.object_id AND idxcol.column_id = col.column_id
- WHERE " . $this->getTableWhereClause($table, 'scm.name', 'tbl.name') . '
- ORDER BY idx.index_id ASC, idxcol.key_ordinal ASC';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateViewSQL($name, $sql)
- {
- return 'CREATE VIEW ' . $name . ' AS ' . $sql;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListViewsSQL($database)
- {
- return "SELECT name FROM sysobjects WHERE type = 'V' ORDER BY name";
- }
-
- /**
- * Returns the where clause to filter schema and table name in a query.
- *
- * @param string $table The full qualified name of the table.
- * @param string $schemaColumn The name of the column to compare the schema to in the where clause.
- * @param string $tableColumn The name of the column to compare the table to in the where clause.
- *
- * @return string
- */
- private function getTableWhereClause($table, $schemaColumn, $tableColumn)
- {
- if (strpos($table, '.') !== false) {
- [$schema, $table] = explode('.', $table);
- $schema = $this->quoteStringLiteral($schema);
- $table = $this->quoteStringLiteral($table);
- } else {
- $schema = 'SCHEMA_NAME()';
- $table = $this->quoteStringLiteral($table);
- }
-
- return sprintf('(%s = %s AND %s = %s)', $tableColumn, $table, $schemaColumn, $schema);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropViewSQL($name)
- {
- return 'DROP VIEW ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getLocateExpression($str, $substr, $startPos = false)
- {
- if ($startPos === false) {
- return 'CHARINDEX(' . $substr . ', ' . $str . ')';
- }
-
- return 'CHARINDEX(' . $substr . ', ' . $str . ', ' . $startPos . ')';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getModExpression($expression1, $expression2)
- {
- return $expression1 . ' % ' . $expression2;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getTrimExpression($str, $mode = TrimMode::UNSPECIFIED, $char = false)
- {
- if ($char === false) {
- switch ($mode) {
- case TrimMode::LEADING:
- $trimFn = 'LTRIM';
- break;
-
- case TrimMode::TRAILING:
- $trimFn = 'RTRIM';
- break;
-
- default:
- return 'LTRIM(RTRIM(' . $str . '))';
- }
-
- return $trimFn . '(' . $str . ')';
- }
-
- $pattern = "'%[^' + " . $char . " + ']%'";
-
- if ($mode === TrimMode::LEADING) {
- return 'stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)';
- }
-
- if ($mode === TrimMode::TRAILING) {
- return 'reverse(stuff(reverse(' . $str . '), 1, '
- . 'patindex(' . $pattern . ', reverse(' . $str . ')) - 1, null))';
- }
-
- return 'reverse(stuff(reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)), 1, '
- . 'patindex(' . $pattern . ', reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str
- . ') - 1, null))) - 1, null))';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getConcatExpression()
- {
- return sprintf('CONCAT(%s)', implode(', ', func_get_args()));
- }
-
- /**
- * {@inheritDoc}
- */
- public function getListDatabasesSQL()
- {
- return 'SELECT * FROM sys.databases';
- }
-
- /**
- * {@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')";
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSubstringExpression($string, $start, $length = null)
- {
- if ($length !== null) {
- return 'SUBSTRING(' . $string . ', ' . $start . ', ' . $length . ')';
- }
-
- return 'SUBSTRING(' . $string . ', ' . $start . ', LEN(' . $string . ') - ' . $start . ' + 1)';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getLengthExpression($column)
- {
- return 'LEN(' . $column . ')';
- }
-
- public function getCurrentDatabaseExpression(): string
- {
- return 'DB_NAME()';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSetTransactionIsolationSQL($level)
- {
- return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getIntegerTypeDeclarationSQL(array $column)
- {
- return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getBigIntTypeDeclarationSQL(array $column)
- {
- return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSmallIntTypeDeclarationSQL(array $column)
- {
- return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getGuidTypeDeclarationSQL(array $column)
- {
- return 'UNIQUEIDENTIFIER';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTimeTzTypeDeclarationSQL(array $column)
- {
- return 'DATETIMEOFFSET(6)';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getAsciiStringTypeDeclarationSQL(array $column): string
- {
- $length = $column['length'] ?? null;
-
- if (! isset($column['fixed'])) {
- return sprintf('VARCHAR(%d)', $length ?? 255);
- }
-
- return sprintf('CHAR(%d)', $length ?? 255);
- }
-
- /**
- * {@inheritDoc}
- */
- protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
- {
- return $fixed
- ? ($length > 0 ? 'NCHAR(' . $length . ')' : 'CHAR(255)')
- : ($length > 0 ? 'NVARCHAR(' . $length . ')' : 'NVARCHAR(255)');
- }
-
- /**
- * {@inheritdoc}
- */
- protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
- {
- return $fixed
- ? 'BINARY(' . ($length > 0 ? $length : 255) . ')'
- : 'VARBINARY(' . ($length > 0 ? $length : 255) . ')';
- }
-
- /**
- * {@inheritdoc}
- */
- public function getBinaryMaxLength()
- {
- return 8000;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getClobTypeDeclarationSQL(array $column)
- {
- return 'VARCHAR(MAX)';
- }
-
- /**
- * {@inheritDoc}
- */
- protected function _getCommonIntegerTypeDeclarationSQL(array $column)
- {
- return ! empty($column['autoincrement']) ? ' IDENTITY' : '';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTimeTypeDeclarationSQL(array $column)
- {
- // 3 - microseconds precision length
- // http://msdn.microsoft.com/en-us/library/ms187819.aspx
- return 'DATETIME2(6)';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTypeDeclarationSQL(array $column)
- {
- return 'DATE';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getTimeTypeDeclarationSQL(array $column)
- {
- return 'TIME(0)';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getBooleanTypeDeclarationSQL(array $column)
- {
- return 'BIT';
- }
-
- /**
- * {@inheritDoc}
- */
- protected function doModifyLimitQuery($query, $limit, $offset)
- {
- if ($limit === null && $offset <= 0) {
- return $query;
- }
-
- 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
- // result. SQL Server's docs say that a nonordered query's result order is non-
- // deterministic anyway, so this won't do anything that a bunch of update and
- // deletes to the table wouldn't do anyway.
- $query .= ' ORDER BY 1';
- } else {
- // In another DBMS, we could do ORDER BY 0, but SQL Server gets angry if you
- // use constant expressions in the order by list.
- $query .= ' ORDER BY (SELECT 0)';
- }
- }
-
- // This looks somewhat like MYSQL, but limit/offset are in inverse positions
- // Supposedly SQL:2008 core standard.
- // Per TSQL spec, FETCH NEXT n ROWS ONLY is not valid without OFFSET n ROWS.
- $query .= sprintf(' OFFSET %d ROWS', $offset);
-
- if ($limit !== null) {
- $query .= sprintf(' FETCH NEXT %d ROWS ONLY', $limit);
- }
-
- return $query;
- }
-
- /**
- * {@inheritDoc}
- */
- public function supportsLimitOffset()
- {
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- public function convertBooleans($item)
- {
- if (is_array($item)) {
- foreach ($item as $key => $value) {
- if (! is_bool($value) && ! is_numeric($value)) {
- continue;
- }
-
- $item[$key] = (int) (bool) $value;
- }
- } elseif (is_bool($item) || is_numeric($item)) {
- $item = (int) (bool) $item;
- }
-
- return $item;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getCreateTemporaryTableSnippetSQL()
- {
- return 'CREATE TABLE';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getTemporaryTableName($tableName)
- {
- return '#' . $tableName;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTimeFormatString()
- {
- return 'Y-m-d H:i:s.u';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateFormatString()
- {
- return 'Y-m-d';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getTimeFormatString()
- {
- return 'H:i:s';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDateTimeTzFormatString()
- {
- return 'Y-m-d H:i:s.u P';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getName()
- {
- return 'mssql';
- }
-
- /**
- * {@inheritDoc}
- */
- protected function initializeDoctrineTypeMappings()
- {
- $this->doctrineTypeMapping = [
- 'bigint' => 'bigint',
- 'binary' => 'binary',
- 'bit' => 'boolean',
- 'blob' => 'blob',
- 'char' => 'string',
- 'date' => 'date',
- 'datetime' => 'datetime',
- 'datetime2' => 'datetime',
- 'datetimeoffset' => 'datetimetz',
- 'decimal' => 'decimal',
- 'double' => 'float',
- 'double precision' => 'float',
- 'float' => 'float',
- 'image' => 'blob',
- 'int' => 'integer',
- 'money' => 'integer',
- 'nchar' => 'string',
- 'ntext' => 'text',
- 'numeric' => 'decimal',
- 'nvarchar' => 'string',
- 'real' => 'float',
- 'smalldatetime' => 'datetime',
- 'smallint' => 'smallint',
- 'smallmoney' => 'integer',
- 'text' => 'text',
- 'time' => 'time',
- 'tinyint' => 'smallint',
- 'uniqueidentifier' => 'guid',
- 'varbinary' => 'binary',
- 'varchar' => 'string',
- ];
- }
-
- /**
- * {@inheritDoc}
- */
- public function createSavePoint($savepoint)
- {
- return 'SAVE TRANSACTION ' . $savepoint;
- }
-
- /**
- * {@inheritDoc}
- */
- public function releaseSavePoint($savepoint)
- {
- return '';
- }
-
- /**
- * {@inheritDoc}
- */
- public function rollbackSavePoint($savepoint)
- {
- return 'ROLLBACK TRANSACTION ' . $savepoint;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getForeignKeyReferentialActionSQL($action)
- {
- // RESTRICT is not supported, therefore falling back to NO ACTION.
- if (strtoupper($action) === 'RESTRICT') {
- return 'NO ACTION';
- }
-
- return parent::getForeignKeyReferentialActionSQL($action);
- }
-
- public function appendLockHint(string $fromClause, int $lockMode): string
- {
- switch ($lockMode) {
- case LockMode::NONE:
- case LockMode::OPTIMISTIC:
- return $fromClause;
-
- case LockMode::PESSIMISTIC_READ:
- return $fromClause . ' WITH (HOLDLOCK, ROWLOCK)';
-
- case LockMode::PESSIMISTIC_WRITE:
- return $fromClause . ' WITH (UPDLOCK, ROWLOCK)';
-
- default:
- throw InvalidLockMode::fromLockMode($lockMode);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public function getForUpdateSQL()
- {
- return ' ';
- }
-
- /**
- * {@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;
- }
-
- /**
- * {@inheritDoc}
- */
- public function quoteSingleIdentifier($str)
- {
- return '[' . str_replace(']', ']]', $str) . ']';
- }
-
- /**
- * {@inheritDoc}
- */
- public function getTruncateTableSQL($tableName, $cascade = false)
- {
- $tableIdentifier = new Identifier($tableName);
-
- return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this);
- }
-
- /**
- * {@inheritDoc}
- */
- public function getBlobTypeDeclarationSQL(array $column)
- {
- return 'VARBINARY(MAX)';
- }
-
- /**
- * {@inheritdoc}
- *
- * Modifies column declaration order as it differs in Microsoft SQL Server.
- */
- public function getColumnDeclarationSQL($name, array $column)
- {
- if (isset($column['columnDefinition'])) {
- $columnDef = $this->getCustomTypeDeclarationSQL($column);
- } else {
- $collation = ! empty($column['collation']) ?
- ' ' . $this->getColumnCollationDeclarationSQL($column['collation']) : '';
-
- $notnull = ! empty($column['notnull']) ? ' NOT NULL' : '';
-
- $unique = ! empty($column['unique']) ?
- ' ' . $this->getUniqueFieldDeclarationSQL() : '';
-
- $check = ! empty($column['check']) ?
- ' ' . $column['check'] : '';
-
- $typeDecl = $column['type']->getSQLDeclaration($column, $this);
- $columnDef = $typeDecl . $collation . $notnull . $unique . $check;
- }
-
- return $name . ' ' . $columnDef;
- }
-
- protected function getLikeWildcardCharacters(): string
- {
- return parent::getLikeWildcardCharacters() . '[]^';
- }
-
- /**
- * Returns a unique default constraint name for a table and column.
- *
- * @param string $table Name of the table to generate the unique default constraint name for.
- * @param string $column Name of the column in the table to generate the unique default constraint name for.
- *
- * @return string
- */
- private function generateDefaultConstraintName($table, $column)
- {
- return 'DF_' . $this->generateIdentifierName($table) . '_' . $this->generateIdentifierName($column);
- }
-
- /**
- * Returns a hash value for a given identifier.
- *
- * @param string $identifier Identifier to generate a hash value for.
- *
- * @return string
- */
- private function generateIdentifierName($identifier)
- {
- // Always generate name for unquoted identifiers to ensure consistency.
- $identifier = new Identifier($identifier);
-
- return strtoupper(dechex(crc32($identifier->getName())));
- }
-
- protected function getCommentOnTableSQL(string $tableName, ?string $comment): string
- {
- 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
- ,
- $this->quoteStringLiteral((string) $comment),
- $this->quoteStringLiteral($tableName)
- );
- }
-
- public function getListTableMetadataSQL(string $table): string
- {
- 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
- ,
- $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/SQLServerPlatform.php b/doctrine/dbal/src/Platforms/SQLServerPlatform.php
new file mode 100644
index 00000000..732cb636
--- /dev/null
+++ b/doctrine/dbal/src/Platforms/SQLServerPlatform.php
@@ -0,0 +1,1660 @@
+<?php
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\Exception\InvalidLockMode;
+use Doctrine\DBAL\LockMode;
+use Doctrine\DBAL\Schema\Column;
+use Doctrine\DBAL\Schema\ColumnDiff;
+use Doctrine\DBAL\Schema\ForeignKeyConstraint;
+use Doctrine\DBAL\Schema\Identifier;
+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;
+use function array_unique;
+use function array_values;
+use function count;
+use function crc32;
+use function dechex;
+use function explode;
+use function func_get_args;
+use function implode;
+use function is_array;
+use function is_bool;
+use function is_numeric;
+use function is_string;
+use function preg_match;
+use function preg_match_all;
+use function sprintf;
+use function str_replace;
+use function strpos;
+use function strtoupper;
+use function substr_count;
+
+use const PREG_OFFSET_CAPTURE;
+
+/**
+ * Provides the behavior, features and SQL dialect of the Microsoft SQL Server database platform
+ * of the oldest supported version.
+ */
+class SQLServerPlatform extends AbstractPlatform
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getCurrentDateSQL()
+ {
+ return $this->getConvertExpression('date', 'GETDATE()');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCurrentTimeSQL()
+ {
+ return $this->getConvertExpression('time', 'GETDATE()');
+ }
+
+ /**
+ * Returns an expression that converts an expression of one data type to another.
+ *
+ * @param string $dataType The target native data type. Alias data types cannot be used.
+ * @param string $expression The SQL expression to convert.
+ */
+ private function getConvertExpression($dataType, $expression): string
+ {
+ return sprintf('CONVERT(%s, %s)', $dataType, $expression);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit)
+ {
+ $factorClause = '';
+
+ if ($operator === '-') {
+ $factorClause = '-1 * ';
+ }
+
+ return 'DATEADD(' . $unit . ', ' . $factorClause . $interval . ', ' . $date . ')';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateDiffExpression($date1, $date2)
+ {
+ return 'DATEDIFF(day, ' . $date2 . ',' . $date1 . ')';
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Microsoft SQL Server prefers "autoincrement" identity columns
+ * since sequences can only be emulated with a table.
+ *
+ * @deprecated
+ */
+ public function prefersIdentityColumns()
+ {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/1519',
+ 'SQLServerPlatform::prefersIdentityColumns() is deprecated.'
+ );
+
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Microsoft SQL Server supports this through AUTO_INCREMENT columns.
+ */
+ public function supportsIdentityColumns()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supportsReleaseSavepoints()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsSchemas()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDefaultSchemaName()
+ {
+ return 'dbo';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supportsColumnCollation()
+ {
+ return true;
+ }
+
+ public function supportsSequences(): bool
+ {
+ return true;
+ }
+
+ public function getAlterSequenceSQL(Sequence $sequence): string
+ {
+ return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
+ ' INCREMENT BY ' . $sequence->getAllocationSize();
+ }
+
+ public function getCreateSequenceSQL(Sequence $sequence): string
+ {
+ return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
+ ' START WITH ' . $sequence->getInitialValue() .
+ ' INCREMENT BY ' . $sequence->getAllocationSize() .
+ ' MINVALUE ' . $sequence->getInitialValue();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getListSequencesSQL($database)
+ {
+ return 'SELECT seq.name,
+ CAST(
+ seq.increment AS VARCHAR(MAX)
+ ) AS increment, -- CAST avoids driver error for sql_variant type
+ CAST(
+ seq.start_value AS VARCHAR(MAX)
+ ) AS start_value -- CAST avoids driver error for sql_variant type
+ FROM sys.sequences AS seq';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSequenceNextValSQL($sequence)
+ {
+ return 'SELECT NEXT VALUE FOR ' . $sequence;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function hasNativeGuidType()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDropForeignKeySQL($foreignKey, $table)
+ {
+ if (! $foreignKey instanceof ForeignKeyConstraint) {
+ $foreignKey = new Identifier($foreignKey);
+ }
+
+ if (! $table instanceof Table) {
+ $table = new Identifier($table);
+ }
+
+ $foreignKey = $foreignKey->getQuotedName($this);
+ $table = $table->getQuotedName($this);
+
+ return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDropIndexSQL($index, $table = null)
+ {
+ if ($index instanceof Index) {
+ $index = $index->getQuotedName($this);
+ } elseif (! is_string($index)) {
+ throw new InvalidArgumentException(
+ __METHOD__ . '() expects $index parameter to be string or ' . Index::class . '.'
+ );
+ }
+
+ if ($table instanceof Table) {
+ $table = $table->getQuotedName($this);
+ } elseif (! is_string($table)) {
+ throw new InvalidArgumentException(
+ __METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.'
+ );
+ }
+
+ return 'DROP INDEX ' . $index . ' ON ' . $table;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function _getCreateTableSQL($name, array $columns, array $options = [])
+ {
+ $defaultConstraintsSql = [];
+ $commentsSql = [];
+
+ $tableComment = $options['comment'] ?? null;
+ if ($tableComment !== null) {
+ $commentsSql[] = $this->getCommentOnTableSQL($name, $tableComment);
+ }
+
+ // @todo does other code breaks because of this?
+ // force primary keys to be not null
+ foreach ($columns as &$column) {
+ if (! empty($column['primary'])) {
+ $column['notnull'] = true;
+ }
+
+ // Build default constraints SQL statements.
+ if (isset($column['default'])) {
+ $defaultConstraintsSql[] = 'ALTER TABLE ' . $name .
+ ' ADD' . $this->getDefaultConstraintDeclarationSQL($name, $column);
+ }
+
+ if (empty($column['comment']) && ! is_numeric($column['comment'])) {
+ continue;
+ }
+
+ $commentsSql[] = $this->getCreateColumnCommentSQL($name, $column['name'], $column['comment']);
+ }
+
+ $columnListSql = $this->getColumnDeclarationListSQL($columns);
+
+ if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
+ foreach ($options['uniqueConstraints'] as $constraintName => $definition) {
+ $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($constraintName, $definition);
+ }
+ }
+
+ if (isset($options['primary']) && ! empty($options['primary'])) {
+ $flags = '';
+ if (isset($options['primary_index']) && $options['primary_index']->hasFlag('nonclustered')) {
+ $flags = ' NONCLUSTERED';
+ }
+
+ $columnListSql .= ', PRIMARY KEY' . $flags
+ . ' (' . implode(', ', array_unique(array_values($options['primary']))) . ')';
+ }
+
+ $query = 'CREATE TABLE ' . $name . ' (' . $columnListSql;
+
+ $check = $this->getCheckDeclarationSQL($columns);
+ if (! empty($check)) {
+ $query .= ', ' . $check;
+ }
+
+ $query .= ')';
+
+ $sql = [$query];
+
+ if (isset($options['indexes']) && ! empty($options['indexes'])) {
+ foreach ($options['indexes'] as $index) {
+ $sql[] = $this->getCreateIndexSQL($index, $name);
+ }
+ }
+
+ if (isset($options['foreignKeys'])) {
+ foreach ((array) $options['foreignKeys'] as $definition) {
+ $sql[] = $this->getCreateForeignKeySQL($definition, $name);
+ }
+ }
+
+ return array_merge($sql, $commentsSql, $defaultConstraintsSql);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getCreatePrimaryKeySQL(Index $index, $table)
+ {
+ if ($table instanceof Table) {
+ $identifier = $table->getQuotedName($this);
+ } else {
+ $identifier = $table;
+ }
+
+ $sql = 'ALTER TABLE ' . $identifier . ' ADD PRIMARY KEY';
+
+ if ($index->hasFlag('nonclustered')) {
+ $sql .= ' NONCLUSTERED';
+ }
+
+ return $sql . ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')';
+ }
+
+ /**
+ * Returns the SQL statement for creating a column comment.
+ *
+ * SQL Server does not support native column comments,
+ * therefore the extended properties functionality is used
+ * as a workaround to store them.
+ * The property name used to store column comments is "MS_Description"
+ * which provides compatibility with SQL Server Management Studio,
+ * as column comments are stored in the same property there when
+ * specifying a column's "Description" attribute.
+ *
+ * @param string $tableName The quoted table name to which the column belongs.
+ * @param string $columnName The quoted column name to create the comment for.
+ * @param string|null $comment The column's comment.
+ *
+ * @return string
+ */
+ protected function getCreateColumnCommentSQL($tableName, $columnName, $comment)
+ {
+ if (strpos($tableName, '.') !== false) {
+ [$schemaSQL, $tableSQL] = explode('.', $tableName);
+ $schemaSQL = $this->quoteStringLiteral($schemaSQL);
+ $tableSQL = $this->quoteStringLiteral($tableSQL);
+ } else {
+ $schemaSQL = "'dbo'";
+ $tableSQL = $this->quoteStringLiteral($tableName);
+ }
+
+ return $this->getAddExtendedPropertySQL(
+ 'MS_Description',
+ $comment,
+ 'SCHEMA',
+ $schemaSQL,
+ 'TABLE',
+ $tableSQL,
+ 'COLUMN',
+ $columnName
+ );
+ }
+
+ /**
+ * Returns the SQL snippet for declaring a default constraint.
+ *
+ * @internal The method should be only used from within the SQLServerPlatform class hierarchy.
+ *
+ * @param string $table Name of the table to return the default constraint declaration for.
+ * @param mixed[] $column Column definition.
+ *
+ * @return string
+ *
+ * @throws InvalidArgumentException
+ */
+ public function getDefaultConstraintDeclarationSQL($table, array $column)
+ {
+ if (! isset($column['default'])) {
+ throw new InvalidArgumentException("Incomplete column definition. 'default' required.");
+ }
+
+ $columnName = new Identifier($column['name']);
+
+ return ' CONSTRAINT ' .
+ $this->generateDefaultConstraintName($table, $column['name']) .
+ $this->getDefaultValueDeclarationSQL($column) .
+ ' FOR ' . $columnName->getQuotedName($this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getCreateIndexSQL(Index $index, $table)
+ {
+ $constraint = parent::getCreateIndexSQL($index, $table);
+
+ if ($index->isUnique() && ! $index->isPrimary()) {
+ $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index);
+ }
+
+ return $constraint;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function getCreateIndexSQLFlags(Index $index)
+ {
+ $type = '';
+ if ($index->isUnique()) {
+ $type .= 'UNIQUE ';
+ }
+
+ if ($index->hasFlag('clustered')) {
+ $type .= 'CLUSTERED ';
+ } elseif ($index->hasFlag('nonclustered')) {
+ $type .= 'NONCLUSTERED ';
+ }
+
+ return $type;
+ }
+
+ /**
+ * Extend unique key constraint with required filters
+ *
+ * @param string $sql
+ */
+ private function _appendUniqueConstraintDefinition($sql, Index $index): string
+ {
+ $fields = [];
+
+ foreach ($index->getQuotedColumns($this) as $field) {
+ $fields[] = $field . ' IS NOT NULL';
+ }
+
+ return $sql . ' WHERE ' . implode(' AND ', $fields);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAlterTableSQL(TableDiff $diff)
+ {
+ $queryParts = [];
+ $sql = [];
+ $columnSql = [];
+ $commentsSql = [];
+
+ foreach ($diff->addedColumns as $column) {
+ if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
+ continue;
+ }
+
+ $columnDef = $column->toArray();
+ $addColumnSql = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef);
+ if (isset($columnDef['default'])) {
+ $addColumnSql .= ' CONSTRAINT ' .
+ $this->generateDefaultConstraintName($diff->name, $column->getQuotedName($this)) .
+ $this->getDefaultValueDeclarationSQL($columnDef);
+ }
+
+ $queryParts[] = $addColumnSql;
+
+ $comment = $this->getColumnComment($column);
+
+ if (empty($comment) && ! is_numeric($comment)) {
+ continue;
+ }
+
+ $commentsSql[] = $this->getCreateColumnCommentSQL(
+ $diff->name,
+ $column->getQuotedName($this),
+ $comment
+ );
+ }
+
+ foreach ($diff->removedColumns as $column) {
+ if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
+ continue;
+ }
+
+ $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this);
+ }
+
+ foreach ($diff->changedColumns as $columnDiff) {
+ if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
+ continue;
+ }
+
+ $column = $columnDiff->column;
+ $comment = $this->getColumnComment($column);
+ $hasComment = ! empty($comment) || is_numeric($comment);
+
+ if ($columnDiff->fromColumn instanceof Column) {
+ $fromComment = $this->getColumnComment($columnDiff->fromColumn);
+ $hasFromComment = ! empty($fromComment) || is_numeric($fromComment);
+
+ if ($hasFromComment && $hasComment && $fromComment !== $comment) {
+ $commentsSql[] = $this->getAlterColumnCommentSQL(
+ $diff->name,
+ $column->getQuotedName($this),
+ $comment
+ );
+ } elseif ($hasFromComment && ! $hasComment) {
+ $commentsSql[] = $this->getDropColumnCommentSQL($diff->name, $column->getQuotedName($this));
+ } elseif (! $hasFromComment && $hasComment) {
+ $commentsSql[] = $this->getCreateColumnCommentSQL(
+ $diff->name,
+ $column->getQuotedName($this),
+ $comment
+ );
+ }
+ }
+
+ // Do not add query part if only comment has changed.
+ if ($columnDiff->hasChanged('comment') && count($columnDiff->changedProperties) === 1) {
+ continue;
+ }
+
+ $requireDropDefaultConstraint = $this->alterColumnRequiresDropDefaultConstraint($columnDiff);
+
+ if ($requireDropDefaultConstraint) {
+ $queryParts[] = $this->getAlterTableDropDefaultConstraintClause(
+ $diff->name,
+ $columnDiff->oldColumnName
+ );
+ }
+
+ $columnDef = $column->toArray();
+
+ $queryParts[] = 'ALTER COLUMN ' .
+ $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef);
+
+ if (
+ ! isset($columnDef['default'])
+ || (! $requireDropDefaultConstraint && ! $columnDiff->hasChanged('default'))
+ ) {
+ continue;
+ }
+
+ $queryParts[] = $this->getAlterTableAddDefaultConstraintClause($diff->name, $column);
+ }
+
+ foreach ($diff->renamedColumns as $oldColumnName => $column) {
+ if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
+ continue;
+ }
+
+ $oldColumnName = new Identifier($oldColumnName);
+
+ $sql[] = "sp_rename '" .
+ $diff->getName($this)->getQuotedName($this) . '.' . $oldColumnName->getQuotedName($this) .
+ "', '" . $column->getQuotedName($this) . "', 'COLUMN'";
+
+ // Recreate default constraint with new column name if necessary (for future reference).
+ if ($column->getDefault() === null) {
+ continue;
+ }
+
+ $queryParts[] = $this->getAlterTableDropDefaultConstraintClause(
+ $diff->name,
+ $oldColumnName->getQuotedName($this)
+ );
+ $queryParts[] = $this->getAlterTableAddDefaultConstraintClause($diff->name, $column);
+ }
+
+ $tableSql = [];
+
+ if ($this->onSchemaAlterTable($diff, $tableSql)) {
+ return array_merge($tableSql, $columnSql);
+ }
+
+ foreach ($queryParts as $query) {
+ $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
+ }
+
+ $sql = array_merge($sql, $commentsSql);
+
+ $newName = $diff->getNewName();
+
+ if ($newName !== false) {
+ $sql[] = "sp_rename '" . $diff->getName($this)->getQuotedName($this) . "', '" . $newName->getName() . "'";
+
+ /**
+ * Rename table's default constraints names
+ * to match the new table name.
+ * This is necessary to ensure that the default
+ * constraints can be referenced in future table
+ * alterations as the table name is encoded in
+ * default constraints' names.
+ */
+ $sql[] = "DECLARE @sql NVARCHAR(MAX) = N''; " .
+ "SELECT @sql += N'EXEC sp_rename N''' + dc.name + ''', N''' " .
+ "+ REPLACE(dc.name, '" . $this->generateIdentifierName($diff->name) . "', " .
+ "'" . $this->generateIdentifierName($newName->getName()) . "') + ''', ''OBJECT'';' " .
+ 'FROM sys.default_constraints dc ' .
+ 'JOIN sys.tables tbl ON dc.parent_object_id = tbl.object_id ' .
+ "WHERE tbl.name = '" . $newName->getName() . "';" .
+ 'EXEC sp_executesql @sql';
+ }
+
+ $sql = array_merge(
+ $this->getPreAlterTableIndexForeignKeySQL($diff),
+ $sql,
+ $this->getPostAlterTableIndexForeignKeySQL($diff)
+ );
+
+ return array_merge($sql, $tableSql, $columnSql);
+ }
+
+ /**
+ * Returns the SQL clause for adding a default constraint in an ALTER TABLE statement.
+ *
+ * @param string $tableName The name of the table to generate the clause for.
+ * @param Column $column The column to generate the clause for.
+ */
+ private function getAlterTableAddDefaultConstraintClause($tableName, Column $column): string
+ {
+ $columnDef = $column->toArray();
+ $columnDef['name'] = $column->getQuotedName($this);
+
+ return 'ADD' . $this->getDefaultConstraintDeclarationSQL($tableName, $columnDef);
+ }
+
+ /**
+ * Returns the SQL clause for dropping an existing default constraint in an ALTER TABLE statement.
+ *
+ * @param string $tableName The name of the table to generate the clause for.
+ * @param string $columnName The name of the column to generate the clause for.
+ */
+ private function getAlterTableDropDefaultConstraintClause($tableName, $columnName): string
+ {
+ return 'DROP CONSTRAINT ' . $this->generateDefaultConstraintName($tableName, $columnName);
+ }
+
+ /**
+ * Checks whether a column alteration requires dropping its default constraint first.
+ *
+ * Different to other database vendors SQL Server implements column default values
+ * as constraints and therefore changes in a column's default value as well as changes
+ * in a column's type require dropping the default constraint first before being to
+ * alter the particular column to the new definition.
+ */
+ private function alterColumnRequiresDropDefaultConstraint(ColumnDiff $columnDiff): bool
+ {
+ // We can only decide whether to drop an existing default constraint
+ // if we know the original default value.
+ if (! $columnDiff->fromColumn instanceof Column) {
+ return false;
+ }
+
+ // We only need to drop an existing default constraint if we know the
+ // column was defined with a default value before.
+ if ($columnDiff->fromColumn->getDefault() === null) {
+ return false;
+ }
+
+ // We need to drop an existing default constraint if the column was
+ // defined with a default value before and it has changed.
+ if ($columnDiff->hasChanged('default')) {
+ return true;
+ }
+
+ // We need to drop an existing default constraint if the column was
+ // defined with a default value before and the native column type has changed.
+ return $columnDiff->hasChanged('type') || $columnDiff->hasChanged('fixed');
+ }
+
+ /**
+ * Returns the SQL statement for altering a column comment.
+ *
+ * SQL Server does not support native column comments,
+ * therefore the extended properties functionality is used
+ * as a workaround to store them.
+ * The property name used to store column comments is "MS_Description"
+ * which provides compatibility with SQL Server Management Studio,
+ * as column comments are stored in the same property there when
+ * specifying a column's "Description" attribute.
+ *
+ * @param string $tableName The quoted table name to which the column belongs.
+ * @param string $columnName The quoted column name to alter the comment for.
+ * @param string|null $comment The column's comment.
+ *
+ * @return string
+ */
+ protected function getAlterColumnCommentSQL($tableName, $columnName, $comment)
+ {
+ if (strpos($tableName, '.') !== false) {
+ [$schemaSQL, $tableSQL] = explode('.', $tableName);
+ $schemaSQL = $this->quoteStringLiteral($schemaSQL);
+ $tableSQL = $this->quoteStringLiteral($tableSQL);
+ } else {
+ $schemaSQL = "'dbo'";
+ $tableSQL = $this->quoteStringLiteral($tableName);
+ }
+
+ return $this->getUpdateExtendedPropertySQL(
+ 'MS_Description',
+ $comment,
+ 'SCHEMA',
+ $schemaSQL,
+ 'TABLE',
+ $tableSQL,
+ 'COLUMN',
+ $columnName
+ );
+ }
+
+ /**
+ * Returns the SQL statement for dropping a column comment.
+ *
+ * SQL Server does not support native column comments,
+ * therefore the extended properties functionality is used
+ * as a workaround to store them.
+ * The property name used to store column comments is "MS_Description"
+ * which provides compatibility with SQL Server Management Studio,
+ * as column comments are stored in the same property there when
+ * specifying a column's "Description" attribute.
+ *
+ * @param string $tableName The quoted table name to which the column belongs.
+ * @param string $columnName The quoted column name to drop the comment for.
+ *
+ * @return string
+ */
+ protected function getDropColumnCommentSQL($tableName, $columnName)
+ {
+ if (strpos($tableName, '.') !== false) {
+ [$schemaSQL, $tableSQL] = explode('.', $tableName);
+ $schemaSQL = $this->quoteStringLiteral($schemaSQL);
+ $tableSQL = $this->quoteStringLiteral($tableSQL);
+ } else {
+ $schemaSQL = "'dbo'";
+ $tableSQL = $this->quoteStringLiteral($tableName);
+ }
+
+ return $this->getDropExtendedPropertySQL(
+ 'MS_Description',
+ 'SCHEMA',
+ $schemaSQL,
+ 'TABLE',
+ $tableSQL,
+ 'COLUMN',
+ $columnName
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName)
+ {
+ return [sprintf(
+ "EXEC sp_rename N'%s.%s', N'%s', N'INDEX'",
+ $tableName,
+ $oldIndexName,
+ $index->getQuotedName($this)
+ ),
+ ];
+ }
+
+ /**
+ * Returns the SQL statement for adding an extended property to a database object.
+ *
+ * @internal The method should be only used from within the SQLServerPlatform class hierarchy.
+ *
+ * @link http://msdn.microsoft.com/en-us/library/ms180047%28v=sql.90%29.aspx
+ *
+ * @param string $name The name of the property to add.
+ * @param string|null $value The value of the property to add.
+ * @param string|null $level0Type The type of the object at level 0 the property belongs to.
+ * @param string|null $level0Name The name of the object at level 0 the property belongs to.
+ * @param string|null $level1Type The type of the object at level 1 the property belongs to.
+ * @param string|null $level1Name The name of the object at level 1 the property belongs to.
+ * @param string|null $level2Type The type of the object at level 2 the property belongs to.
+ * @param string|null $level2Name The name of the object at level 2 the property belongs to.
+ *
+ * @return string
+ */
+ public function getAddExtendedPropertySQL(
+ $name,
+ $value = null,
+ $level0Type = null,
+ $level0Name = null,
+ $level1Type = null,
+ $level1Name = null,
+ $level2Type = null,
+ $level2Name = null
+ ) {
+ return 'EXEC sp_addextendedproperty ' .
+ 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' .
+ 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' .
+ 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' .
+ 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name;
+ }
+
+ /**
+ * Returns the SQL statement for dropping an extended property from a database object.
+ *
+ * @internal The method should be only used from within the SQLServerPlatform class hierarchy.
+ *
+ * @link http://technet.microsoft.com/en-gb/library/ms178595%28v=sql.90%29.aspx
+ *
+ * @param string $name The name of the property to drop.
+ * @param string|null $level0Type The type of the object at level 0 the property belongs to.
+ * @param string|null $level0Name The name of the object at level 0 the property belongs to.
+ * @param string|null $level1Type The type of the object at level 1 the property belongs to.
+ * @param string|null $level1Name The name of the object at level 1 the property belongs to.
+ * @param string|null $level2Type The type of the object at level 2 the property belongs to.
+ * @param string|null $level2Name The name of the object at level 2 the property belongs to.
+ *
+ * @return string
+ */
+ public function getDropExtendedPropertySQL(
+ $name,
+ $level0Type = null,
+ $level0Name = null,
+ $level1Type = null,
+ $level1Name = null,
+ $level2Type = null,
+ $level2Name = null
+ ) {
+ return 'EXEC sp_dropextendedproperty ' .
+ 'N' . $this->quoteStringLiteral($name) . ', ' .
+ 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' .
+ 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' .
+ 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name;
+ }
+
+ /**
+ * Returns the SQL statement for updating an extended property of a database object.
+ *
+ * @internal The method should be only used from within the SQLServerPlatform class hierarchy.
+ *
+ * @link http://msdn.microsoft.com/en-us/library/ms186885%28v=sql.90%29.aspx
+ *
+ * @param string $name The name of the property to update.
+ * @param string|null $value The value of the property to update.
+ * @param string|null $level0Type The type of the object at level 0 the property belongs to.
+ * @param string|null $level0Name The name of the object at level 0 the property belongs to.
+ * @param string|null $level1Type The type of the object at level 1 the property belongs to.
+ * @param string|null $level1Name The name of the object at level 1 the property belongs to.
+ * @param string|null $level2Type The type of the object at level 2 the property belongs to.
+ * @param string|null $level2Name The name of the object at level 2 the property belongs to.
+ *
+ * @return string
+ */
+ public function getUpdateExtendedPropertySQL(
+ $name,
+ $value = null,
+ $level0Type = null,
+ $level0Name = null,
+ $level1Type = null,
+ $level1Name = null,
+ $level2Type = null,
+ $level2Name = null
+ ) {
+ return 'EXEC sp_updateextendedproperty ' .
+ 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' .
+ 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' .
+ 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' .
+ 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
+ {
+ return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListTablesSQL()
+ {
+ // "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams
+ // Category 2 must be ignored as it is "MS SQL Server 'pseudo-system' object[s]" for replication
+ return 'SELECT name, SCHEMA_NAME (uid) AS schema_name FROM sysobjects'
+ . " WHERE type = 'U' AND name != 'sysdiagrams' AND category != 2 ORDER BY name";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListTableColumnsSQL($table, $database = null)
+ {
+ return "SELECT col.name,
+ type.name AS type,
+ col.max_length AS length,
+ ~col.is_nullable AS notnull,
+ def.definition AS [default],
+ col.scale,
+ col.precision,
+ col.is_identity AS autoincrement,
+ col.collation_name AS collation,
+ CAST(prop.value AS NVARCHAR(MAX)) AS comment -- CAST avoids driver error for sql_variant type
+ FROM sys.columns AS col
+ JOIN sys.types AS type
+ ON col.user_type_id = type.user_type_id
+ JOIN sys.objects AS obj
+ ON col.object_id = obj.object_id
+ JOIN sys.schemas AS scm
+ ON obj.schema_id = scm.schema_id
+ LEFT JOIN sys.default_constraints def
+ ON col.default_object_id = def.object_id
+ AND col.object_id = def.parent_object_id
+ LEFT JOIN sys.extended_properties AS prop
+ ON obj.object_id = prop.major_id
+ AND col.column_id = prop.minor_id
+ AND prop.name = 'MS_Description'
+ WHERE obj.type = 'U'
+ AND " . $this->getTableWhereClause($table, 'scm.name', 'obj.name');
+ }
+
+ /**
+ * @param string $table
+ * @param string|null $database
+ *
+ * @return string
+ */
+ public function getListTableForeignKeysSQL($table, $database = null)
+ {
+ return 'SELECT f.name AS ForeignKey,
+ SCHEMA_NAME (f.SCHEMA_ID) AS SchemaName,
+ OBJECT_NAME (f.parent_object_id) AS TableName,
+ COL_NAME (fc.parent_object_id,fc.parent_column_id) AS ColumnName,
+ SCHEMA_NAME (o.SCHEMA_ID) ReferenceSchemaName,
+ OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
+ COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName,
+ f.delete_referential_action_desc,
+ f.update_referential_action_desc
+ FROM sys.foreign_keys AS f
+ INNER JOIN sys.foreign_key_columns AS fc
+ INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id
+ ON f.OBJECT_ID = fc.constraint_object_id
+ WHERE ' .
+ $this->getTableWhereClause($table, 'SCHEMA_NAME (f.schema_id)', 'OBJECT_NAME (f.parent_object_id)') .
+ ' ORDER BY fc.constraint_column_id';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListTableIndexesSQL($table, $database = null)
+ {
+ return "SELECT idx.name AS key_name,
+ col.name AS column_name,
+ ~idx.is_unique AS non_unique,
+ idx.is_primary_key AS [primary],
+ CASE idx.type
+ WHEN '1' THEN 'clustered'
+ WHEN '2' THEN 'nonclustered'
+ ELSE NULL
+ END AS flags
+ FROM sys.tables AS tbl
+ JOIN sys.schemas AS scm ON tbl.schema_id = scm.schema_id
+ JOIN sys.indexes AS idx ON tbl.object_id = idx.object_id
+ JOIN sys.index_columns AS idxcol ON idx.object_id = idxcol.object_id AND idx.index_id = idxcol.index_id
+ JOIN sys.columns AS col ON idxcol.object_id = col.object_id AND idxcol.column_id = col.column_id
+ WHERE " . $this->getTableWhereClause($table, 'scm.name', 'tbl.name') . '
+ ORDER BY idx.index_id ASC, idxcol.key_ordinal ASC';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListViewsSQL($database)
+ {
+ return "SELECT name, definition FROM sysobjects
+ INNER JOIN sys.sql_modules ON sysobjects.id = sys.sql_modules.object_id
+ WHERE type = 'V' ORDER BY name";
+ }
+
+ /**
+ * Returns the where clause to filter schema and table name in a query.
+ *
+ * @param string $table The full qualified name of the table.
+ * @param string $schemaColumn The name of the column to compare the schema to in the where clause.
+ * @param string $tableColumn The name of the column to compare the table to in the where clause.
+ */
+ private function getTableWhereClause($table, $schemaColumn, $tableColumn): string
+ {
+ if (strpos($table, '.') !== false) {
+ [$schema, $table] = explode('.', $table);
+ $schema = $this->quoteStringLiteral($schema);
+ $table = $this->quoteStringLiteral($table);
+ } else {
+ $schema = 'SCHEMA_NAME()';
+ $table = $this->quoteStringLiteral($table);
+ }
+
+ return sprintf('(%s = %s AND %s = %s)', $tableColumn, $table, $schemaColumn, $schema);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getLocateExpression($str, $substr, $startPos = false)
+ {
+ if ($startPos === false) {
+ return 'CHARINDEX(' . $substr . ', ' . $str . ')';
+ }
+
+ return 'CHARINDEX(' . $substr . ', ' . $str . ', ' . $startPos . ')';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getModExpression($expression1, $expression2)
+ {
+ return $expression1 . ' % ' . $expression2;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getTrimExpression($str, $mode = TrimMode::UNSPECIFIED, $char = false)
+ {
+ if ($char === false) {
+ switch ($mode) {
+ case TrimMode::LEADING:
+ $trimFn = 'LTRIM';
+ break;
+
+ case TrimMode::TRAILING:
+ $trimFn = 'RTRIM';
+ break;
+
+ default:
+ return 'LTRIM(RTRIM(' . $str . '))';
+ }
+
+ return $trimFn . '(' . $str . ')';
+ }
+
+ $pattern = "'%[^' + " . $char . " + ']%'";
+
+ if ($mode === TrimMode::LEADING) {
+ return 'stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)';
+ }
+
+ if ($mode === TrimMode::TRAILING) {
+ return 'reverse(stuff(reverse(' . $str . '), 1, '
+ . 'patindex(' . $pattern . ', reverse(' . $str . ')) - 1, null))';
+ }
+
+ return 'reverse(stuff(reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)), 1, '
+ . 'patindex(' . $pattern . ', reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str
+ . ') - 1, null))) - 1, null))';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getConcatExpression()
+ {
+ return sprintf('CONCAT(%s)', implode(', ', func_get_args()));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListDatabasesSQL()
+ {
+ return 'SELECT * FROM sys.databases';
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated Use {@see SQLServerSchemaManager::listSchemaNames()} instead.
+ */
+ public function getListNamespacesSQL()
+ {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4503',
+ 'SQLServerPlatform::getListNamespacesSQL() is deprecated,'
+ . ' use SQLServerSchemaManager::listSchemaNames() instead.'
+ );
+
+ return "SELECT name FROM sys.schemas WHERE name NOT IN('guest', 'INFORMATION_SCHEMA', 'sys')";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getSubstringExpression($string, $start, $length = null)
+ {
+ if ($length !== null) {
+ return 'SUBSTRING(' . $string . ', ' . $start . ', ' . $length . ')';
+ }
+
+ return 'SUBSTRING(' . $string . ', ' . $start . ', LEN(' . $string . ') - ' . $start . ' + 1)';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getLengthExpression($column)
+ {
+ return 'LEN(' . $column . ')';
+ }
+
+ public function getCurrentDatabaseExpression(): string
+ {
+ return 'DB_NAME()';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getSetTransactionIsolationSQL($level)
+ {
+ return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getIntegerTypeDeclarationSQL(array $column)
+ {
+ return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getBigIntTypeDeclarationSQL(array $column)
+ {
+ return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getSmallIntTypeDeclarationSQL(array $column)
+ {
+ return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($column);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getGuidTypeDeclarationSQL(array $column)
+ {
+ return 'UNIQUEIDENTIFIER';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTimeTzTypeDeclarationSQL(array $column)
+ {
+ return 'DATETIMEOFFSET(6)';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAsciiStringTypeDeclarationSQL(array $column): string
+ {
+ $length = $column['length'] ?? null;
+
+ if (! isset($column['fixed'])) {
+ return sprintf('VARCHAR(%d)', $length ?? 255);
+ }
+
+ return sprintf('CHAR(%d)', $length ?? 255);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
+ {
+ return $fixed
+ ? ($length > 0 ? 'NCHAR(' . $length . ')' : 'CHAR(255)')
+ : ($length > 0 ? 'NVARCHAR(' . $length . ')' : 'NVARCHAR(255)');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed)
+ {
+ return $fixed
+ ? 'BINARY(' . ($length > 0 ? $length : 255) . ')'
+ : 'VARBINARY(' . ($length > 0 ? $length : 255) . ')';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBinaryMaxLength()
+ {
+ return 8000;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getClobTypeDeclarationSQL(array $column)
+ {
+ return 'VARCHAR(MAX)';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function _getCommonIntegerTypeDeclarationSQL(array $column)
+ {
+ return ! empty($column['autoincrement']) ? ' IDENTITY' : '';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTimeTypeDeclarationSQL(array $column)
+ {
+ // 3 - microseconds precision length
+ // http://msdn.microsoft.com/en-us/library/ms187819.aspx
+ return 'DATETIME2(6)';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTypeDeclarationSQL(array $column)
+ {
+ return 'DATE';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getTimeTypeDeclarationSQL(array $column)
+ {
+ return 'TIME(0)';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getBooleanTypeDeclarationSQL(array $column)
+ {
+ return 'BIT';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function doModifyLimitQuery($query, $limit, $offset)
+ {
+ if ($limit === null && $offset <= 0) {
+ return $query;
+ }
+
+ 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
+ // result. SQL Server's docs say that a nonordered query's result order is non-
+ // deterministic anyway, so this won't do anything that a bunch of update and
+ // deletes to the table wouldn't do anyway.
+ $query .= ' ORDER BY 1';
+ } else {
+ // In another DBMS, we could do ORDER BY 0, but SQL Server gets angry if you
+ // use constant expressions in the order by list.
+ $query .= ' ORDER BY (SELECT 0)';
+ }
+ }
+
+ // This looks somewhat like MYSQL, but limit/offset are in inverse positions
+ // Supposedly SQL:2008 core standard.
+ // Per TSQL spec, FETCH NEXT n ROWS ONLY is not valid without OFFSET n ROWS.
+ $query .= sprintf(' OFFSET %d ROWS', $offset);
+
+ if ($limit !== null) {
+ $query .= sprintf(' FETCH NEXT %d ROWS ONLY', $limit);
+ }
+
+ return $query;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertBooleans($item)
+ {
+ if (is_array($item)) {
+ foreach ($item as $key => $value) {
+ if (! is_bool($value) && ! is_numeric($value)) {
+ continue;
+ }
+
+ $item[$key] = (int) (bool) $value;
+ }
+ } elseif (is_bool($item) || is_numeric($item)) {
+ $item = (int) (bool) $item;
+ }
+
+ return $item;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getCreateTemporaryTableSnippetSQL()
+ {
+ return 'CREATE TABLE';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getTemporaryTableName($tableName)
+ {
+ return '#' . $tableName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTimeFormatString()
+ {
+ return 'Y-m-d H:i:s.u';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateFormatString()
+ {
+ return 'Y-m-d';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getTimeFormatString()
+ {
+ return 'H:i:s';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getDateTimeTzFormatString()
+ {
+ return 'Y-m-d H:i:s.u P';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getName()
+ {
+ return 'mssql';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function initializeDoctrineTypeMappings()
+ {
+ $this->doctrineTypeMapping = [
+ 'bigint' => 'bigint',
+ 'binary' => 'binary',
+ 'bit' => 'boolean',
+ 'blob' => 'blob',
+ 'char' => 'string',
+ 'date' => 'date',
+ 'datetime' => 'datetime',
+ 'datetime2' => 'datetime',
+ 'datetimeoffset' => 'datetimetz',
+ 'decimal' => 'decimal',
+ 'double' => 'float',
+ 'double precision' => 'float',
+ 'float' => 'float',
+ 'image' => 'blob',
+ 'int' => 'integer',
+ 'money' => 'integer',
+ 'nchar' => 'string',
+ 'ntext' => 'text',
+ 'numeric' => 'decimal',
+ 'nvarchar' => 'string',
+ 'real' => 'float',
+ 'smalldatetime' => 'datetime',
+ 'smallint' => 'smallint',
+ 'smallmoney' => 'integer',
+ 'text' => 'text',
+ 'time' => 'time',
+ 'tinyint' => 'smallint',
+ 'uniqueidentifier' => 'guid',
+ 'varbinary' => 'binary',
+ 'varchar' => 'string',
+ ];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function createSavePoint($savepoint)
+ {
+ return 'SAVE TRANSACTION ' . $savepoint;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function releaseSavePoint($savepoint)
+ {
+ return '';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function rollbackSavePoint($savepoint)
+ {
+ return 'ROLLBACK TRANSACTION ' . $savepoint;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getForeignKeyReferentialActionSQL($action)
+ {
+ // RESTRICT is not supported, therefore falling back to NO ACTION.
+ if (strtoupper($action) === 'RESTRICT') {
+ return 'NO ACTION';
+ }
+
+ return parent::getForeignKeyReferentialActionSQL($action);
+ }
+
+ public function appendLockHint(string $fromClause, int $lockMode): string
+ {
+ switch ($lockMode) {
+ case LockMode::NONE:
+ case LockMode::OPTIMISTIC:
+ return $fromClause;
+
+ case LockMode::PESSIMISTIC_READ:
+ return $fromClause . ' WITH (HOLDLOCK, ROWLOCK)';
+
+ case LockMode::PESSIMISTIC_WRITE:
+ return $fromClause . ' WITH (UPDLOCK, ROWLOCK)';
+
+ default:
+ throw InvalidLockMode::fromLockMode($lockMode);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getForUpdateSQL()
+ {
+ return ' ';
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated Implement {@see createReservedKeywordsList()} instead.
+ */
+ protected function getReservedKeywordsClass()
+ {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4510',
+ 'SQLServerPlatform::getReservedKeywordsClass() is deprecated,'
+ . ' use SQLServerPlatform::createReservedKeywordsList() instead.'
+ );
+
+ return Keywords\SQLServer2012Keywords::class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function quoteSingleIdentifier($str)
+ {
+ return '[' . str_replace(']', ']]', $str) . ']';
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getTruncateTableSQL($tableName, $cascade = false)
+ {
+ $tableIdentifier = new Identifier($tableName);
+
+ return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getBlobTypeDeclarationSQL(array $column)
+ {
+ return 'VARBINARY(MAX)';
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * Modifies column declaration order as it differs in Microsoft SQL Server.
+ */
+ public function getColumnDeclarationSQL($name, array $column)
+ {
+ if (isset($column['columnDefinition'])) {
+ $columnDef = $this->getCustomTypeDeclarationSQL($column);
+ } else {
+ $collation = ! empty($column['collation']) ?
+ ' ' . $this->getColumnCollationDeclarationSQL($column['collation']) : '';
+
+ $notnull = ! empty($column['notnull']) ? ' NOT NULL' : '';
+
+ $unique = ! empty($column['unique']) ?
+ ' ' . $this->getUniqueFieldDeclarationSQL() : '';
+
+ $check = ! empty($column['check']) ?
+ ' ' . $column['check'] : '';
+
+ $typeDecl = $column['type']->getSQLDeclaration($column, $this);
+ $columnDef = $typeDecl . $collation . $notnull . $unique . $check;
+ }
+
+ return $name . ' ' . $columnDef;
+ }
+
+ public function columnsEqual(Column $column1, Column $column2): bool
+ {
+ if (! parent::columnsEqual($column1, $column2)) {
+ return false;
+ }
+
+ return $this->getDefaultValueDeclarationSQL($column1->toArray())
+ === $this->getDefaultValueDeclarationSQL($column2->toArray());
+ }
+
+ protected function getLikeWildcardCharacters(): string
+ {
+ return parent::getLikeWildcardCharacters() . '[]^';
+ }
+
+ /**
+ * Returns a unique default constraint name for a table and column.
+ *
+ * @param string $table Name of the table to generate the unique default constraint name for.
+ * @param string $column Name of the column in the table to generate the unique default constraint name for.
+ */
+ private function generateDefaultConstraintName($table, $column): string
+ {
+ return 'DF_' . $this->generateIdentifierName($table) . '_' . $this->generateIdentifierName($column);
+ }
+
+ /**
+ * Returns a hash value for a given identifier.
+ *
+ * @param string $identifier Identifier to generate a hash value for.
+ */
+ private function generateIdentifierName($identifier): string
+ {
+ // Always generate name for unquoted identifiers to ensure consistency.
+ $identifier = new Identifier($identifier);
+
+ return strtoupper(dechex(crc32($identifier->getName())));
+ }
+
+ protected function getCommentOnTableSQL(string $tableName, ?string $comment): string
+ {
+ 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
+ ,
+ $this->quoteStringLiteral((string) $comment),
+ $this->quoteStringLiteral($tableName)
+ );
+ }
+
+ public function getListTableMetadataSQL(string $table): string
+ {
+ 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
+ ,
+ $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/SQLite/Comparator.php b/doctrine/dbal/src/Platforms/SQLite/Comparator.php
new file mode 100644
index 00000000..d27ee86d
--- /dev/null
+++ b/doctrine/dbal/src/Platforms/SQLite/Comparator.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Doctrine\DBAL\Platforms\SQLite;
+
+use Doctrine\DBAL\Platforms\SqlitePlatform;
+use Doctrine\DBAL\Schema\Comparator as BaseComparator;
+use Doctrine\DBAL\Schema\Table;
+
+use function strcasecmp;
+
+/**
+ * Compares schemas in the context of SQLite platform.
+ *
+ * BINARY is the default column collation and should be ignored if specified explicitly.
+ */
+class Comparator extends BaseComparator
+{
+ /**
+ * @internal The comparator can be only instantiated by a schema manager.
+ */
+ public function __construct(SqlitePlatform $platform)
+ {
+ parent::__construct($platform);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function diffTable(Table $fromTable, Table $toTable)
+ {
+ $fromTable = clone $fromTable;
+ $toTable = clone $toTable;
+
+ $this->normalizeColumns($fromTable);
+ $this->normalizeColumns($toTable);
+
+ return parent::diffTable($fromTable, $toTable);
+ }
+
+ private function normalizeColumns(Table $table): void
+ {
+ foreach ($table->getColumns() as $column) {
+ $options = $column->getPlatformOptions();
+
+ if (! isset($options['collation']) || strcasecmp($options['collation'], 'binary') !== 0) {
+ continue;
+ }
+
+ unset($options['collation']);
+ $column->setPlatformOptions($options);
+ }
+ }
+}
diff --git a/doctrine/dbal/src/Platforms/SqlitePlatform.php b/doctrine/dbal/src/Platforms/SqlitePlatform.php
index 16818261..6d5adda4 100644
--- a/doctrine/dbal/src/Platforms/SqlitePlatform.php
+++ b/doctrine/dbal/src/Platforms/SqlitePlatform.php
@@ -2,6 +2,7 @@
namespace Doctrine\DBAL\Platforms;
+use Doctrine\DBAL\Driver\API\SQLite\UserDefinedFunctions;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Constraint;
@@ -27,7 +28,6 @@ use function sprintf;
use function sqrt;
use function str_replace;
use function strlen;
-use function strpos;
use function strtolower;
use function trim;
@@ -48,12 +48,20 @@ class SqlitePlatform extends AbstractPlatform
}
/**
+ * @deprecated Generate dates within the application.
+ *
* @param string $type
*
* @return string
*/
public function getNowExpression($type = 'timestamp')
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4753',
+ 'SqlitePlatform::getNowExpression() is deprecated. Generate dates within the application.'
+ );
+
switch ($type) {
case 'time':
return 'time(\'now\')';
@@ -197,9 +205,17 @@ class SqlitePlatform extends AbstractPlatform
/**
* {@inheritDoc}
+ *
+ * @deprecated
*/
public function prefersIdentityColumns()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pulls/1519',
+ 'SqlitePlatform::prefersIdentityColumns() is deprecated.'
+ );
+
return true;
}
@@ -498,22 +514,6 @@ class SqlitePlatform extends AbstractPlatform
/**
* {@inheritDoc}
*/
- public function getCreateViewSQL($name, $sql)
- {
- return 'CREATE VIEW ' . $name . ' AS ' . $sql;
- }
-
- /**
- * {@inheritDoc}
- */
- public function getDropViewSQL($name)
- {
- return 'DROP VIEW ' . $name;
- }
-
- /**
- * {@inheritDoc}
- */
public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey)
{
$query = parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
@@ -537,6 +537,14 @@ class SqlitePlatform extends AbstractPlatform
/**
* {@inheritDoc}
*/
+ public function supportsCreateDropDatabase()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public function supportsIdentityColumns()
{
return true;
@@ -563,6 +571,12 @@ class SqlitePlatform extends AbstractPlatform
*/
public function getName()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4749',
+ 'SqlitePlatform::getName() is deprecated. Identify platforms by their class.'
+ );
+
return 'sqlite';
}
@@ -580,6 +594,8 @@ class SqlitePlatform extends AbstractPlatform
/**
* User-defined function for Sqlite that is used with PDO::sqliteCreateFunction().
*
+ * @deprecated The driver will use {@see sqrt()} in the next major release.
+ *
* @param int|float $value
*
* @return float
@@ -592,6 +608,8 @@ class SqlitePlatform extends AbstractPlatform
/**
* User-defined function for Sqlite that implements MOD(a, b).
*
+ * @deprecated The driver will use {@see UserDefinedFunctions::mod()} in the next major release.
+ *
* @param int $a
* @param int $b
*
@@ -599,10 +617,12 @@ class SqlitePlatform extends AbstractPlatform
*/
public static function udfMod($a, $b)
{
- return $a % $b;
+ return UserDefinedFunctions::mod($a, $b);
}
/**
+ * @deprecated The driver will use {@see UserDefinedFunctions::locate()} in the next major release.
+ *
* @param string $str
* @param string $substr
* @param int $offset
@@ -611,19 +631,7 @@ class SqlitePlatform extends AbstractPlatform
*/
public static function udfLocate($str, $substr, $offset = 0)
{
- // SQL's LOCATE function works on 1-based positions, while PHP's strpos works on 0-based positions.
- // So we have to make them compatible if an offset is given.
- if ($offset > 0) {
- $offset -= 1;
- }
-
- $pos = strpos($str, $substr, $offset);
-
- if ($pos !== false) {
- return $pos + 1;
- }
-
- return 0;
+ return UserDefinedFunctions::locate($str, $substr, $offset);
}
/**
@@ -691,7 +699,7 @@ class SqlitePlatform extends AbstractPlatform
/**
* {@inheritDoc}
*
- * @deprecated Implement {@link createReservedKeywordsList()} instead.
+ * @deprecated Implement {@see createReservedKeywordsList()} instead.
*/
protected function getReservedKeywordsClass()
{
@@ -765,7 +773,7 @@ class SqlitePlatform extends AbstractPlatform
protected function doModifyLimitQuery($query, $limit, $offset)
{
if ($limit === null && $offset > 0) {
- return $query . ' LIMIT -1 OFFSET ' . $offset;
+ return sprintf('%s LIMIT -1 OFFSET %d', $query, $offset);
}
return parent::doModifyLimitQuery($query, $limit, $offset);
@@ -792,6 +800,8 @@ class SqlitePlatform extends AbstractPlatform
/**
* {@inheritDoc}
*
+ * @deprecated
+ *
* Sqlite Platform emulates schema by underscoring each dot and generating tables
* into the default database.
*
@@ -800,6 +810,12 @@ class SqlitePlatform extends AbstractPlatform
*/
public function canEmulateSchemas()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4805',
+ 'SqlitePlatform::canEmulateSchemas() is deprecated.'
+ );
+
return true;
}
@@ -837,6 +853,8 @@ class SqlitePlatform extends AbstractPlatform
/**
* {@inheritDoc}
+ *
+ * @deprecated
*/
public function getCreateConstraintSQL(Constraint $constraint, $table)
{
@@ -1130,7 +1148,7 @@ class SqlitePlatform extends AbstractPlatform
/**
* @return string[]
*/
- private function getColumnNamesInAlteredTable(TableDiff $diff, Table $fromTable)
+ private function getColumnNamesInAlteredTable(TableDiff $diff, Table $fromTable): array
{
$columns = [];
@@ -1170,7 +1188,7 @@ class SqlitePlatform extends AbstractPlatform
/**
* @return Index[]
*/
- private function getIndexesInAlteredTable(TableDiff $diff, Table $fromTable)
+ private function getIndexesInAlteredTable(TableDiff $diff, Table $fromTable): array
{
$indexes = $fromTable->getIndexes();
$columnNames = $this->getColumnNamesInAlteredTable($diff, $fromTable);
@@ -1238,7 +1256,7 @@ class SqlitePlatform extends AbstractPlatform
/**
* @return ForeignKeyConstraint[]
*/
- private function getForeignKeysInAlteredTable(TableDiff $diff, Table $fromTable)
+ private function getForeignKeysInAlteredTable(TableDiff $diff, Table $fromTable): array
{
$foreignKeys = $fromTable->getForeignKeys();
$columnNames = $this->getColumnNamesInAlteredTable($diff, $fromTable);
@@ -1302,7 +1320,7 @@ class SqlitePlatform extends AbstractPlatform
/**
* @return Index[]
*/
- private function getPrimaryIndexInAlteredTable(TableDiff $diff, Table $fromTable)
+ private function getPrimaryIndexInAlteredTable(TableDiff $diff, Table $fromTable): array
{
$primaryIndex = [];
diff --git a/doctrine/dbal/src/Portability/Connection.php b/doctrine/dbal/src/Portability/Connection.php
index a5639792..a22ab92f 100644
--- a/doctrine/dbal/src/Portability/Connection.php
+++ b/doctrine/dbal/src/Portability/Connection.php
@@ -3,14 +3,14 @@
namespace Doctrine\DBAL\Portability;
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
+use Doctrine\DBAL\Driver\Middleware\AbstractConnectionMiddleware;
use Doctrine\DBAL\Driver\Result as DriverResult;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
-use Doctrine\DBAL\ParameterType;
/**
* Portability wrapper for a Connection.
*/
-final class Connection implements ConnectionInterface
+final class Connection extends AbstractConnectionMiddleware
{
public const PORTABILITY_ALL = 255;
public const PORTABILITY_NONE = 0;
@@ -18,22 +18,20 @@ final class Connection implements ConnectionInterface
public const PORTABILITY_EMPTY_TO_NULL = 4;
public const PORTABILITY_FIX_CASE = 8;
- /** @var ConnectionInterface */
- private $connection;
-
/** @var Converter */
private $converter;
public function __construct(ConnectionInterface $connection, Converter $converter)
{
- $this->connection = $connection;
- $this->converter = $converter;
+ parent::__construct($connection);
+
+ $this->converter = $converter;
}
public function prepare(string $sql): DriverStatement
{
return new Statement(
- $this->connection->prepare($sql),
+ parent::prepare($sql),
$this->converter
);
}
@@ -41,53 +39,8 @@ final class Connection implements ConnectionInterface
public function query(string $sql): DriverResult
{
return new Result(
- $this->connection->query($sql),
+ parent::query($sql),
$this->converter
);
}
-
- /**
- * {@inheritDoc}
- */
- public function quote($value, $type = ParameterType::STRING)
- {
- return $this->connection->quote($value, $type);
- }
-
- public function exec(string $sql): int
- {
- return $this->connection->exec($sql);
- }
-
- /**
- * {@inheritDoc}
- */
- public function lastInsertId($name = null)
- {
- return $this->connection->lastInsertId($name);
- }
-
- /**
- * {@inheritDoc}
- */
- public function beginTransaction()
- {
- return $this->connection->beginTransaction();
- }
-
- /**
- * {@inheritDoc}
- */
- public function commit()
- {
- return $this->connection->commit();
- }
-
- /**
- * {@inheritDoc}
- */
- public function rollBack()
- {
- return $this->connection->rollBack();
- }
}
diff --git a/doctrine/dbal/src/Portability/Converter.php b/doctrine/dbal/src/Portability/Converter.php
index 5763c260..eb76eb78 100644
--- a/doctrine/dbal/src/Portability/Converter.php
+++ b/doctrine/dbal/src/Portability/Converter.php
@@ -34,7 +34,7 @@ final class Converter
* @param bool $convertEmptyStringToNull Whether each empty string should be converted to NULL
* @param bool $rightTrimString Whether each string should right-trimmed
* @param int|null $case Convert the case of the column names
- * (one of {@link CASE_LOWER} and {@link CASE_UPPER})
+ * (one of {@see CASE_LOWER} and {@see CASE_UPPER})
*/
public function __construct(bool $convertEmptyStringToNull, bool $rightTrimString, ?int $case)
{
diff --git a/doctrine/dbal/src/Portability/Driver.php b/doctrine/dbal/src/Portability/Driver.php
index 5ae410cd..6d4484f9 100644
--- a/doctrine/dbal/src/Portability/Driver.php
+++ b/doctrine/dbal/src/Portability/Driver.php
@@ -3,20 +3,18 @@
namespace Doctrine\DBAL\Portability;
use Doctrine\DBAL\ColumnCase;
-use Doctrine\DBAL\Connection as DBALConnection;
use Doctrine\DBAL\Driver as DriverInterface;
-use Doctrine\DBAL\Driver\API\ExceptionConverter;
-use Doctrine\DBAL\Driver\PDO;
-use Doctrine\DBAL\Platforms\AbstractPlatform;
+use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
+use LogicException;
+use PDO;
+
+use function method_exists;
use const CASE_LOWER;
use const CASE_UPPER;
-final class Driver implements DriverInterface
+final class Driver extends AbstractDriverMiddleware
{
- /** @var DriverInterface */
- private $driver;
-
/** @var int */
private $mode;
@@ -25,9 +23,10 @@ final class Driver implements DriverInterface
public function __construct(DriverInterface $driver, int $mode, int $case)
{
- $this->driver = $driver;
- $this->mode = $mode;
- $this->case = $case;
+ parent::__construct($driver);
+
+ $this->mode = $mode;
+ $this->case = $case;
}
/**
@@ -35,20 +34,27 @@ final class Driver implements DriverInterface
*/
public function connect(array $params)
{
- $connection = $this->driver->connect($params);
+ $connection = parent::connect($params);
$portability = (new OptimizeFlags())(
$this->getDatabasePlatform(),
$this->mode
);
- $case = 0;
+ $case = null;
if ($this->case !== 0 && ($portability & Connection::PORTABILITY_FIX_CASE) !== 0) {
- if ($connection instanceof PDO\Connection) {
- // make use of c-level support for case handling
+ $nativeConnection = null;
+ if (method_exists($connection, 'getNativeConnection')) {
+ try {
+ $nativeConnection = $connection->getNativeConnection();
+ } catch (LogicException $e) {
+ }
+ }
+
+ if ($nativeConnection instanceof PDO) {
$portability &= ~Connection::PORTABILITY_FIX_CASE;
- $connection->getWrappedConnection()->setAttribute(\PDO::ATTR_CASE, $this->case);
+ $nativeConnection->setAttribute(PDO::ATTR_CASE, $this->case);
} else {
$case = $this->case === ColumnCase::LOWER ? CASE_LOWER : CASE_UPPER;
}
@@ -57,7 +63,7 @@ final class Driver implements DriverInterface
$convertEmptyStringToNull = ($portability & Connection::PORTABILITY_EMPTY_TO_NULL) !== 0;
$rightTrimString = ($portability & Connection::PORTABILITY_RTRIM) !== 0;
- if (! $convertEmptyStringToNull && ! $rightTrimString && $case === 0) {
+ if (! $convertEmptyStringToNull && ! $rightTrimString && $case === null) {
return $connection;
}
@@ -66,25 +72,4 @@ final class Driver implements DriverInterface
new Converter($convertEmptyStringToNull, $rightTrimString, $case)
);
}
-
- /**
- * {@inheritDoc}
- */
- public function getDatabasePlatform()
- {
- return $this->driver->getDatabasePlatform();
- }
-
- /**
- * {@inheritDoc}
- */
- public function getSchemaManager(DBALConnection $conn, AbstractPlatform $platform)
- {
- return $this->driver->getSchemaManager($conn, $platform);
- }
-
- public function getExceptionConverter(): ExceptionConverter
- {
- return $this->driver->getExceptionConverter();
- }
}
diff --git a/doctrine/dbal/src/Portability/OptimizeFlags.php b/doctrine/dbal/src/Portability/OptimizeFlags.php
index 742eb93f..13367c92 100644
--- a/doctrine/dbal/src/Portability/OptimizeFlags.php
+++ b/doctrine/dbal/src/Portability/OptimizeFlags.php
@@ -7,9 +7,9 @@ namespace Doctrine\DBAL\Portability;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\DB2Platform;
use Doctrine\DBAL\Platforms\OraclePlatform;
-use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
+use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\DBAL\Platforms\SqlitePlatform;
-use Doctrine\DBAL\Platforms\SQLServer2012Platform;
+use Doctrine\DBAL\Platforms\SQLServerPlatform;
final class OptimizeFlags
{
@@ -20,11 +20,11 @@ final class OptimizeFlags
* @var array<string,int>
*/
private static $platforms = [
- DB2Platform::class => 0,
- OraclePlatform::class => Connection::PORTABILITY_EMPTY_TO_NULL,
- PostgreSQL94Platform::class => 0,
- SqlitePlatform::class => 0,
- SQLServer2012Platform::class => 0,
+ DB2Platform::class => 0,
+ OraclePlatform::class => Connection::PORTABILITY_EMPTY_TO_NULL,
+ PostgreSQLPlatform::class => 0,
+ SqlitePlatform::class => 0,
+ SQLServerPlatform::class => 0,
];
public function __invoke(AbstractPlatform $platform, int $flags): int
diff --git a/doctrine/dbal/src/Portability/Result.php b/doctrine/dbal/src/Portability/Result.php
index 1fa91ab4..d8440b66 100644
--- a/doctrine/dbal/src/Portability/Result.php
+++ b/doctrine/dbal/src/Portability/Result.php
@@ -4,13 +4,11 @@ declare(strict_types=1);
namespace Doctrine\DBAL\Portability;
+use Doctrine\DBAL\Driver\Middleware\AbstractResultMiddleware;
use Doctrine\DBAL\Driver\Result as ResultInterface;
-final class Result implements ResultInterface
+final class Result extends AbstractResultMiddleware
{
- /** @var ResultInterface */
- private $result;
-
/** @var Converter */
private $converter;
@@ -19,7 +17,8 @@ final class Result implements ResultInterface
*/
public function __construct(ResultInterface $result, Converter $converter)
{
- $this->result = $result;
+ parent::__construct($result);
+
$this->converter = $converter;
}
@@ -29,7 +28,7 @@ final class Result implements ResultInterface
public function fetchNumeric()
{
return $this->converter->convertNumeric(
- $this->result->fetchNumeric()
+ parent::fetchNumeric()
);
}
@@ -39,7 +38,7 @@ final class Result implements ResultInterface
public function fetchAssociative()
{
return $this->converter->convertAssociative(
- $this->result->fetchAssociative()
+ parent::fetchAssociative()
);
}
@@ -49,7 +48,7 @@ final class Result implements ResultInterface
public function fetchOne()
{
return $this->converter->convertOne(
- $this->result->fetchOne()
+ parent::fetchOne()
);
}
@@ -59,7 +58,7 @@ final class Result implements ResultInterface
public function fetchAllNumeric(): array
{
return $this->converter->convertAllNumeric(
- $this->result->fetchAllNumeric()
+ parent::fetchAllNumeric()
);
}
@@ -69,7 +68,7 @@ final class Result implements ResultInterface
public function fetchAllAssociative(): array
{
return $this->converter->convertAllAssociative(
- $this->result->fetchAllAssociative()
+ parent::fetchAllAssociative()
);
}
@@ -79,22 +78,7 @@ final class Result implements ResultInterface
public function fetchFirstColumn(): array
{
return $this->converter->convertFirstColumn(
- $this->result->fetchFirstColumn()
+ parent::fetchFirstColumn()
);
}
-
- public function rowCount(): int
- {
- return $this->result->rowCount();
- }
-
- public function columnCount(): int
- {
- return $this->result->columnCount();
- }
-
- public function free(): void
- {
- $this->result->free();
- }
}
diff --git a/doctrine/dbal/src/Portability/Statement.php b/doctrine/dbal/src/Portability/Statement.php
index f3f94e41..b104cf78 100644
--- a/doctrine/dbal/src/Portability/Statement.php
+++ b/doctrine/dbal/src/Portability/Statement.php
@@ -2,18 +2,15 @@
namespace Doctrine\DBAL\Portability;
+use Doctrine\DBAL\Driver\Middleware\AbstractStatementMiddleware;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\Statement as DriverStatement;
-use Doctrine\DBAL\ParameterType;
/**
* Portability wrapper for a Statement.
*/
-final class Statement implements DriverStatement
+final class Statement extends AbstractStatementMiddleware
{
- /** @var DriverStatement */
- private $stmt;
-
/** @var Converter */
private $converter;
@@ -22,24 +19,9 @@ final class Statement implements DriverStatement
*/
public function __construct(DriverStatement $stmt, Converter $converter)
{
- $this->stmt = $stmt;
- $this->converter = $converter;
- }
-
- /**
- * {@inheritdoc}
- */
- public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
- {
- return $this->stmt->bindParam($param, $variable, $type, $length);
- }
+ parent::__construct($stmt);
- /**
- * {@inheritdoc}
- */
- public function bindValue($param, $value, $type = ParameterType::STRING)
- {
- return $this->stmt->bindValue($param, $value, $type);
+ $this->converter = $converter;
}
/**
@@ -48,7 +30,7 @@ final class Statement implements DriverStatement
public function execute($params = null): ResultInterface
{
return new Result(
- $this->stmt->execute($params),
+ parent::execute($params),
$this->converter
);
}
diff --git a/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php b/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php
index 8cb53150..1ce11b7b 100644
--- a/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php
+++ b/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php
@@ -308,7 +308,10 @@ class ExpressionBuilder
}
/**
- * Quotes a given input parameter.
+ * Builds an SQL literal from a given input parameter.
+ *
+ * The usage of this method is discouraged. Use prepared statements
+ * or {@see AbstractPlatform::quoteStringLiteral()} instead.
*
* @param mixed $input The parameter to be quoted.
* @param int|null $type The type of the parameter.
diff --git a/doctrine/dbal/src/Query/QueryBuilder.php b/doctrine/dbal/src/Query/QueryBuilder.php
index 6d74d010..7f30a128 100644
--- a/doctrine/dbal/src/Query/QueryBuilder.php
+++ b/doctrine/dbal/src/Query/QueryBuilder.php
@@ -327,9 +327,9 @@ class QueryBuilder
/**
* Executes this query using the bound parameters and their types.
*
- * @deprecated Use {@link executeQuery()} or {@link executeStatement()} instead.
+ * @deprecated Use {@see executeQuery()} or {@see executeStatement()} instead.
*
- * @return Result|int
+ * @return Result|int|string
*
* @throws Exception
*/
@@ -1315,11 +1315,9 @@ class QueryBuilder
}
/**
- * @return string
- *
* @throws QueryException
*/
- private function getSQLForSelect()
+ private function getSQLForSelect(): string
{
$query = 'SELECT ' . ($this->sqlParts['distinct'] ? 'DISTINCT ' : '') .
implode(', ', $this->sqlParts['select']);
@@ -1346,7 +1344,7 @@ class QueryBuilder
*
* @throws QueryException
*/
- private function getFromClauses()
+ private function getFromClauses(): array
{
$fromClauses = [];
$knownAliases = [];
@@ -1385,20 +1383,15 @@ class QueryBuilder
}
}
- /**
- * @return bool
- */
- private function isLimitQuery()
+ private function isLimitQuery(): bool
{
return $this->maxResults !== null || $this->firstResult !== 0;
}
/**
* Converts this instance into an INSERT string in SQL.
- *
- * @return string
*/
- private function getSQLForInsert()
+ private function getSQLForInsert(): string
{
return 'INSERT INTO ' . $this->sqlParts['from']['table'] .
' (' . implode(', ', array_keys($this->sqlParts['values'])) . ')' .
@@ -1407,10 +1400,8 @@ class QueryBuilder
/**
* Converts this instance into an UPDATE string in SQL.
- *
- * @return string
*/
- private function getSQLForUpdate()
+ private function getSQLForUpdate(): string
{
$table = $this->sqlParts['from']['table']
. ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
@@ -1422,10 +1413,8 @@ class QueryBuilder
/**
* Converts this instance into a DELETE string in SQL.
- *
- * @return string
*/
- private function getSQLForDelete()
+ private function getSQLForDelete(): string
{
$table = $this->sqlParts['from']['table']
. ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
@@ -1448,7 +1437,7 @@ class QueryBuilder
/**
* Creates a new named parameter and bind the value $value to it.
*
- * This method provides a shortcut for {@link Statement::bindValue()}
+ * This method provides a shortcut for {@see Statement::bindValue()}
* when using prepared statements.
*
* The parameter $value specifies the value that you want to bind. If
@@ -1517,11 +1506,9 @@ class QueryBuilder
* @param string $fromAlias
* @param array<string,true> $knownAliases
*
- * @return string
- *
* @throws QueryException
*/
- private function getSQLForJoins($fromAlias, array &$knownAliases)
+ private function getSQLForJoins($fromAlias, array &$knownAliases): string
{
$sql = '';
diff --git a/doctrine/dbal/src/Result.php b/doctrine/dbal/src/Result.php
index 59c1065a..dce821c6 100644
--- a/doctrine/dbal/src/Result.php
+++ b/doctrine/dbal/src/Result.php
@@ -22,7 +22,7 @@ class Result
private $connection;
/**
- * @internal The result can be only instantiated by {@link Connection} or {@link Statement}.
+ * @internal The result can be only instantiated by {@see Connection} or {@see Statement}.
*/
public function __construct(DriverResult $result, Connection $connection)
{
@@ -170,12 +170,8 @@ class Result
*/
public function iterateNumeric(): Traversable
{
- try {
- while (($row = $this->result->fetchNumeric()) !== false) {
- yield $row;
- }
- } catch (DriverException $e) {
- throw $this->connection->convertException($e);
+ while (($row = $this->fetchNumeric()) !== false) {
+ yield $row;
}
}
@@ -186,12 +182,8 @@ class Result
*/
public function iterateAssociative(): Traversable
{
- try {
- while (($row = $this->result->fetchAssociative()) !== false) {
- yield $row;
- }
- } catch (DriverException $e) {
- throw $this->connection->convertException($e);
+ while (($row = $this->fetchAssociative()) !== false) {
+ yield $row;
}
}
@@ -231,12 +223,8 @@ class Result
*/
public function iterateColumn(): Traversable
{
- try {
- while (($value = $this->result->fetchOne()) !== false) {
- yield $value;
- }
- } catch (DriverException $e) {
- throw $this->connection->convertException($e);
+ while (($value = $this->fetchOne()) !== false) {
+ yield $value;
}
}
@@ -287,11 +275,13 @@ class Result
* @deprecated This API is deprecated and will be removed after 2022
*
* @return mixed
+ *
+ * @throws Exception
*/
public function fetch(int $mode = FetchMode::ASSOCIATIVE)
{
if (func_num_args() > 1) {
- throw new LogicException('Only invocations with one argument are still supported by this legecy API.');
+ throw new LogicException('Only invocations with one argument are still supported by this legacy API.');
}
if ($mode === FetchMode::ASSOCIATIVE) {
@@ -315,11 +305,13 @@ class Result
* @deprecated This API is deprecated and will be removed after 2022
*
* @return list<mixed>
+ *
+ * @throws Exception
*/
public function fetchAll(int $mode = FetchMode::ASSOCIATIVE): array
{
if (func_num_args() > 1) {
- throw new LogicException('Only invocations with one argument are still supported by this legecy API.');
+ throw new LogicException('Only invocations with one argument are still supported by this legacy API.');
}
if ($mode === FetchMode::ASSOCIATIVE) {
diff --git a/doctrine/dbal/src/SQL/Parser.php b/doctrine/dbal/src/SQL/Parser.php
index f1ad6617..b3747e0c 100644
--- a/doctrine/dbal/src/SQL/Parser.php
+++ b/doctrine/dbal/src/SQL/Parser.php
@@ -70,7 +70,7 @@ final class Parser
self::OTHER,
]);
- $this->sqlPattern = sprintf('(%s)+', implode('|', $patterns));
+ $this->sqlPattern = sprintf('(%s)', implode('|', $patterns));
}
/**
diff --git a/doctrine/dbal/src/Schema/AbstractAsset.php b/doctrine/dbal/src/Schema/AbstractAsset.php
index e6b383a6..69e33760 100644
--- a/doctrine/dbal/src/Schema/AbstractAsset.php
+++ b/doctrine/dbal/src/Schema/AbstractAsset.php
@@ -3,6 +3,7 @@
namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Platforms\AbstractPlatform;
+use Doctrine\Deprecations\Deprecation;
use function array_map;
use function crc32;
@@ -110,12 +111,21 @@ abstract class AbstractAsset
* Every non-namespaced element is prefixed with the default namespace
* name which is passed as argument to this method.
*
+ * @deprecated Use {@see getNamespaceName()} and {@see getName()} instead.
+ *
* @param string $defaultNamespaceName
*
* @return string
*/
public function getFullQualifiedName($defaultNamespaceName)
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4814',
+ 'AbstractAsset::getFullQualifiedName() is deprecated.'
+ . ' Use AbstractAsset::getNamespaceName() and ::getName() instead.'
+ );
+
$name = $this->getName();
if ($this->_namespace === null) {
$name = $defaultNamespaceName . '.' . $name;
diff --git a/doctrine/dbal/src/Schema/AbstractSchemaManager.php b/doctrine/dbal/src/Schema/AbstractSchemaManager.php
index 50b9face..e44580b5 100644
--- a/doctrine/dbal/src/Schema/AbstractSchemaManager.php
+++ b/doctrine/dbal/src/Schema/AbstractSchemaManager.php
@@ -28,6 +28,8 @@ use function strtolower;
/**
* Base class for schema managers. Schema managers are used to inspect and/or
* modify the database schema/structure.
+ *
+ * @template T of AbstractPlatform
*/
abstract class AbstractSchemaManager
{
@@ -41,10 +43,13 @@ abstract class AbstractSchemaManager
/**
* Holds instance of the database platform used for this schema manager.
*
- * @var AbstractPlatform
+ * @var T
*/
protected $_platform;
+ /**
+ * @param T $platform
+ */
public function __construct(Connection $connection, AbstractPlatform $platform)
{
$this->_conn = $connection;
@@ -54,7 +59,7 @@ abstract class AbstractSchemaManager
/**
* Returns the associated platform.
*
- * @return AbstractPlatform
+ * @return T
*/
public function getDatabasePlatform()
{
@@ -71,10 +76,18 @@ abstract class AbstractSchemaManager
* $result = $sm->tryMethod('dropView', 'view_name');
* </code>
*
+ * @deprecated
+ *
* @return mixed
*/
public function tryMethod()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4897',
+ 'AbstractSchemaManager::tryMethod() is deprecated.'
+ );
+
$args = func_get_args();
$method = $args[0];
unset($args[0]);
@@ -109,7 +122,7 @@ abstract class AbstractSchemaManager
/**
* Returns a list of all namespaces in the current database.
*
- * @deprecated Use {@link listSchemaNames()} instead.
+ * @deprecated Use {@see listSchemaNames()} instead.
*
* @return string[]
*
@@ -419,6 +432,8 @@ abstract class AbstractSchemaManager
/**
* Drops the constraint from the given table.
*
+ * @deprecated Use {@see dropIndex()}, {@see dropForeignKey()} or {@see dropUniqueConstraint()} instead.
+ *
* @param Table|string $table The name of the table.
*
* @return void
@@ -460,6 +475,16 @@ abstract class AbstractSchemaManager
}
/**
+ * Drops the unique constraint from the given table.
+ *
+ * @throws Exception
+ */
+ public function dropUniqueConstraint(string $name, string $tableName): void
+ {
+ $this->_execSql($this->_platform->getDropUniqueConstraintSQL($name, $tableName));
+ }
+
+ /**
* Drops a view.
*
* @param string $name The name of the view.
@@ -519,6 +544,8 @@ abstract class AbstractSchemaManager
/**
* Creates a constraint on a table.
*
+ * @deprecated Use {@see createIndex()}, {@see createForeignKey()} or {@see createUniqueConstraint()} instead.
+ *
* @param Table|string $table
*
* @return void
@@ -560,6 +587,16 @@ abstract class AbstractSchemaManager
}
/**
+ * Creates a unique constraint on a table.
+ *
+ * @throws Exception
+ */
+ public function createUniqueConstraint(UniqueConstraint $uniqueConstraint, string $tableName): void
+ {
+ $this->_execSql($this->_platform->getCreateUniqueConstraintSQL($uniqueConstraint, $tableName));
+ }
+
+ /**
* Creates a new view.
*
* @return void
@@ -576,6 +613,10 @@ abstract class AbstractSchemaManager
/**
* Drops and creates a constraint.
*
+ * @deprecated Use {@see dropIndex()} and {@see createIndex()},
+ * {@see dropForeignKey()} and {@see createForeignKey()}
+ * or {@see dropUniqueConstraint()} and {@see createUniqueConstraint()} instead.
+ *
* @see dropConstraint()
* @see createConstraint()
*
@@ -587,6 +628,16 @@ abstract class AbstractSchemaManager
*/
public function dropAndCreateConstraint(Constraint $constraint, $table)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4897',
+ 'AbstractSchemaManager::dropAndCreateConstraint() is deprecated.'
+ . ' Use AbstractSchemaManager::dropIndex() and AbstractSchemaManager::createIndex(),'
+ . ' AbstractSchemaManager::dropForeignKey() and AbstractSchemaManager::createForeignKey()'
+ . ' or AbstractSchemaManager::dropUniqueConstraint()'
+ . ' and AbstractSchemaManager::createUniqueConstraint() instead.'
+ );
+
$this->tryMethod('dropConstraint', $constraint, $table);
$this->createConstraint($constraint, $table);
}
@@ -594,6 +645,8 @@ abstract class AbstractSchemaManager
/**
* Drops and creates a new index on a table.
*
+ * @deprecated Use {@see dropIndex()} and {@see createIndex()} instead.
+ *
* @param Table|string $table The name of the table on which the index is to be created.
*
* @return void
@@ -602,6 +655,13 @@ abstract class AbstractSchemaManager
*/
public function dropAndCreateIndex(Index $index, $table)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4897',
+ 'AbstractSchemaManager::dropAndCreateIndex() is deprecated.'
+ . ' Use AbstractSchemaManager::dropIndex() and AbstractSchemaManager::createIndex() instead.'
+ );
+
$this->tryMethod('dropIndex', $index->getQuotedName($this->_platform), $table);
$this->createIndex($index, $table);
}
@@ -609,6 +669,8 @@ abstract class AbstractSchemaManager
/**
* Drops and creates a new foreign key.
*
+ * @deprecated Use {@see dropForeignKey()} and {@see createForeignKey()} instead.
+ *
* @param ForeignKeyConstraint $foreignKey An associative array that defines properties
* of the foreign key to be created.
* @param Table|string $table The name of the table on which the foreign key is to be created.
@@ -619,6 +681,13 @@ abstract class AbstractSchemaManager
*/
public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4897',
+ 'AbstractSchemaManager::dropAndCreateForeignKey() is deprecated.'
+ . ' Use AbstractSchemaManager::dropForeignKey() and AbstractSchemaManager::createForeignKey() instead.'
+ );
+
$this->tryMethod('dropForeignKey', $foreignKey, $table);
$this->createForeignKey($foreignKey, $table);
}
@@ -626,12 +695,21 @@ abstract class AbstractSchemaManager
/**
* Drops and create a new sequence.
*
+ * @deprecated Use {@see dropSequence()} and {@see createSequence()} instead.
+ *
* @return void
*
* @throws Exception
*/
public function dropAndCreateSequence(Sequence $sequence)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4897',
+ 'AbstractSchemaManager::dropAndCreateSequence() is deprecated.'
+ . ' Use AbstractSchemaManager::dropSequence() and AbstractSchemaManager::createSequence() instead.'
+ );
+
$this->tryMethod('dropSequence', $sequence->getQuotedName($this->_platform));
$this->createSequence($sequence);
}
@@ -639,12 +717,21 @@ abstract class AbstractSchemaManager
/**
* Drops and creates a new table.
*
+ * @deprecated Use {@see dropTable()} and {@see createTable()} instead.
+ *
* @return void
*
* @throws Exception
*/
public function dropAndCreateTable(Table $table)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4897',
+ 'AbstractSchemaManager::dropAndCreateTable() is deprecated.'
+ . ' Use AbstractSchemaManager::dropTable() and AbstractSchemaManager::createTable() instead.'
+ );
+
$this->tryMethod('dropTable', $table->getQuotedName($this->_platform));
$this->createTable($table);
}
@@ -652,6 +739,8 @@ abstract class AbstractSchemaManager
/**
* Drops and creates a new database.
*
+ * @deprecated Use {@see dropDatabase()} and {@see createDatabase()} instead.
+ *
* @param string $database The name of the database to create.
*
* @return void
@@ -660,6 +749,13 @@ abstract class AbstractSchemaManager
*/
public function dropAndCreateDatabase($database)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4897',
+ 'AbstractSchemaManager::dropAndCreateDatabase() is deprecated.'
+ . ' Use AbstractSchemaManager::dropDatabase() and AbstractSchemaManager::createDatabase() instead.'
+ );
+
$this->tryMethod('dropDatabase', $database);
$this->createDatabase($database);
}
@@ -667,16 +763,48 @@ abstract class AbstractSchemaManager
/**
* Drops and creates a new view.
*
+ * @deprecated Use {@see dropView()} and {@see createView()} instead.
+ *
* @return void
*
* @throws Exception
*/
public function dropAndCreateView(View $view)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4897',
+ 'AbstractSchemaManager::dropAndCreateView() is deprecated.'
+ . ' Use AbstractSchemaManager::dropView() and AbstractSchemaManager::createView() instead.'
+ );
+
$this->tryMethod('dropView', $view->getQuotedName($this->_platform));
$this->createView($view);
}
+ /**
+ * Alters an existing schema.
+ *
+ * @throws Exception
+ */
+ public function alterSchema(SchemaDiff $schemaDiff): void
+ {
+ $this->_execSql($schemaDiff->toSql($this->_platform));
+ }
+
+ /**
+ * Migrates an existing schema to a new schema.
+ *
+ * @throws Exception
+ */
+ public function migrateSchema(Schema $toSchema): void
+ {
+ $schemaDiff = $this->createComparator()
+ ->compareSchemas($this->createSchema(), $toSchema);
+
+ $this->alterSchema($schemaDiff);
+ }
+
/* alterTable() Methods */
/**
@@ -733,7 +861,7 @@ 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.
+ * @deprecated Use {@see listSchemaNames()} instead.
*
* @param array<int, array<string, mixed>> $namespaces The list of namespace names
* in the native DBMS data definition.
@@ -771,7 +899,7 @@ abstract class AbstractSchemaManager
/**
* Converts a namespace definition from the native DBMS data definition to a portable Doctrine definition.
*
- * @deprecated Use {@link listSchemaNames()} instead.
+ * @deprecated Use {@see listSchemaNames()} instead.
*
* @param array<string, mixed> $namespace The native DBMS namespace definition.
*
@@ -790,37 +918,6 @@ abstract class AbstractSchemaManager
}
/**
- * @param mixed[][] $triggers
- *
- * @return mixed[][]
- */
- protected function _getPortableTriggersList($triggers)
- {
- $list = [];
- foreach ($triggers as $value) {
- $value = $this->_getPortableTriggerDefinition($value);
-
- if (! $value) {
- continue;
- }
-
- $list[] = $value;
- }
-
- return $list;
- }
-
- /**
- * @param mixed[] $trigger
- *
- * @return mixed
- */
- protected function _getPortableTriggerDefinition($trigger)
- {
- return $trigger;
- }
-
- /**
* @param mixed[][] $sequences
*
* @return Sequence[]
@@ -1175,12 +1272,20 @@ abstract class AbstractSchemaManager
* For databases that don't support subschema/namespaces this method
* returns the name of the currently connected database.
*
+ * @deprecated
+ *
* @return string[]
*
* @throws Exception
*/
public function getSchemaSearchPaths()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4821',
+ 'AbstractSchemaManager::getSchemaSearchPaths() is deprecated.'
+ );
+
$database = $this->_conn->getDatabase();
if ($database !== null) {
@@ -1194,6 +1299,8 @@ abstract class AbstractSchemaManager
* Given a table comment this method tries to extract a typehint for Doctrine Type, or returns
* the type given as default.
*
+ * @internal This method should be only used from within the AbstractSchemaManager class hierarchy.
+ *
* @param string|null $comment
* @param string $currentType
*
@@ -1209,6 +1316,8 @@ abstract class AbstractSchemaManager
}
/**
+ * @internal This method should be only used from within the AbstractSchemaManager class hierarchy.
+ *
* @param string|null $comment
* @param string|null $type
*
@@ -1222,4 +1331,9 @@ abstract class AbstractSchemaManager
return str_replace('(DC2Type:' . $type . ')', '', $comment);
}
+
+ public function createComparator(): Comparator
+ {
+ return new Comparator($this->getDatabasePlatform());
+ }
}
diff --git a/doctrine/dbal/src/Schema/ColumnDiff.php b/doctrine/dbal/src/Schema/ColumnDiff.php
index c9c2a52b..83402fd0 100644
--- a/doctrine/dbal/src/Schema/ColumnDiff.php
+++ b/doctrine/dbal/src/Schema/ColumnDiff.php
@@ -2,6 +2,8 @@
namespace Doctrine\DBAL\Schema;
+use Doctrine\Deprecations\Deprecation;
+
use function in_array;
/**
@@ -31,6 +33,15 @@ class ColumnDiff
array $changedProperties = [],
?Column $fromColumn = null
) {
+ if ($fromColumn === null) {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4785',
+ 'Not passing the $fromColumn to %s is deprecated.',
+ __METHOD__
+ );
+ }
+
$this->oldColumnName = $oldColumnName;
$this->column = $column;
$this->changedProperties = $changedProperties;
diff --git a/doctrine/dbal/src/Schema/Comparator.php b/doctrine/dbal/src/Schema/Comparator.php
index 7ddf5238..7791b29b 100644
--- a/doctrine/dbal/src/Schema/Comparator.php
+++ b/doctrine/dbal/src/Schema/Comparator.php
@@ -2,7 +2,11 @@
namespace Doctrine\DBAL\Schema;
+use BadMethodCallException;
+use Doctrine\DBAL\Exception;
+use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types;
+use Doctrine\Deprecations\Deprecation;
use function array_intersect_key;
use function array_key_exists;
@@ -13,38 +17,76 @@ use function array_unique;
use function assert;
use function count;
use function get_class;
+use function sprintf;
use function strtolower;
/**
* Compares two Schemas and return an instance of SchemaDiff.
+ *
+ * @method SchemaDiff compareSchemas(Schema $fromSchema, Schema $toSchema)
*/
class Comparator
{
+ /** @var AbstractPlatform|null */
+ private $platform;
+
/**
- * @return SchemaDiff
- *
- * @throws SchemaException
+ * @internal The comparator can be only instantiated by a schema manager.
+ */
+ public function __construct(?AbstractPlatform $platform = null)
+ {
+ if ($platform === null) {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4659',
+ 'Not passing a $platform to %s is deprecated.'
+ . ' Use AbstractSchemaManager::createComparator() to instantiate the comparator.',
+ __METHOD__
+ );
+ }
+
+ $this->platform = $platform;
+ }
+
+ /**
+ * @param list<mixed> $args
+ */
+ public function __call(string $method, array $args): SchemaDiff
+ {
+ if ($method !== 'compareSchemas') {
+ throw new BadMethodCallException(sprintf('Unknown method "%s"', $method));
+ }
+
+ return $this->doCompareSchemas(...$args);
+ }
+
+ /**
+ * @param list<mixed> $args
*/
- public static function compareSchemas(Schema $fromSchema, Schema $toSchema)
+ public static function __callStatic(string $method, array $args): SchemaDiff
{
- $c = new self();
+ if ($method !== 'compareSchemas') {
+ throw new BadMethodCallException(sprintf('Unknown method "%s"', $method));
+ }
- return $c->compare($fromSchema, $toSchema);
+ $comparator = new self();
+
+ return $comparator->doCompareSchemas(...$args);
}
/**
* Returns a SchemaDiff object containing the differences between the schemas $fromSchema and $toSchema.
*
- * The returned differences are returned in such a way that they contain the
- * operations to change the schema stored in $fromSchema to the schema that is
- * stored in $toSchema.
+ * This method should be called non-statically since it will be declared as non-static in the next major release.
*
* @return SchemaDiff
*
* @throws SchemaException
*/
- public function compare(Schema $fromSchema, Schema $toSchema)
- {
+ private function doCompareSchemas(
+ Schema $fromSchema,
+ Schema $toSchema
+ ) {
$diff = new SchemaDiff();
$diff->fromSchema = $fromSchema;
@@ -162,12 +204,28 @@ class Comparator
}
/**
+ * @deprecated Use non-static call to {@see compareSchemas()} instead.
+ *
+ * @return SchemaDiff
+ *
+ * @throws SchemaException
+ */
+ public function compare(Schema $fromSchema, Schema $toSchema)
+ {
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4707',
+ 'Method compare() is deprecated. Use a non-static call to compareSchemas() instead.'
+ );
+
+ return $this->compareSchemas($fromSchema, $toSchema);
+ }
+
+ /**
* @param Schema $schema
* @param Sequence $sequence
- *
- * @return bool
*/
- private function isAutoIncrementSequenceInSchema($schema, $sequence)
+ private function isAutoIncrementSequenceInSchema($schema, $sequence): bool
{
foreach ($schema->getTables() as $table) {
if ($sequence->isAutoIncrementsFor($table)) {
@@ -197,7 +255,7 @@ class Comparator
*
* @return TableDiff|false
*
- * @throws SchemaException
+ * @throws Exception
*/
public function diffTable(Table $fromTable, Table $toTable)
{
@@ -227,17 +285,26 @@ class Comparator
continue;
}
+ $toColumn = $toTable->getColumn($columnName);
+
// See if column has changed properties in "to" table.
- $changedProperties = $this->diffColumn($column, $toTable->getColumn($columnName));
+ $changedProperties = $this->diffColumn($column, $toColumn);
- if (count($changedProperties) === 0) {
+ if ($this->platform !== null) {
+ if ($this->columnsEqual($column, $toColumn)) {
+ continue;
+ }
+ } elseif (count($changedProperties) === 0) {
continue;
}
- $columnDiff = new ColumnDiff($column->getName(), $toTable->getColumn($columnName), $changedProperties);
+ $tableDifferences->changedColumns[$column->getName()] = new ColumnDiff(
+ $column->getName(),
+ $toColumn,
+ $changedProperties,
+ $column
+ );
- $columnDiff->fromColumn = $column;
- $tableDifferences->changedColumns[$column->getName()] = $columnDiff;
$changes++;
}
@@ -315,15 +382,13 @@ class Comparator
/**
* Try to find columns that only changed their name, rename operations maybe cheaper than add/drop
* however ambiguities between different possibilities should not lead to renaming at all.
- *
- * @return void
*/
- private function detectColumnRenamings(TableDiff $tableDifferences)
+ private function detectColumnRenamings(TableDiff $tableDifferences): void
{
$renameCandidates = [];
foreach ($tableDifferences->addedColumns as $addedColumnName => $addedColumn) {
foreach ($tableDifferences->removedColumns as $removedColumn) {
- if (count($this->diffColumn($addedColumn, $removedColumn)) !== 0) {
+ if (! $this->columnsEqual($addedColumn, $removedColumn)) {
continue;
}
@@ -337,7 +402,7 @@ class Comparator
}
[$removedColumn, $addedColumn] = $candidateColumns[0];
- $removedColumnName = strtolower($removedColumn->getName());
+ $removedColumnName = $removedColumn->getName();
$addedColumnName = strtolower($addedColumn->getName());
if (isset($tableDifferences->renamedColumns[$removedColumnName])) {
@@ -347,7 +412,7 @@ class Comparator
$tableDifferences->renamedColumns[$removedColumnName] = $addedColumn;
unset(
$tableDifferences->addedColumns[$addedColumnName],
- $tableDifferences->removedColumns[$removedColumnName]
+ $tableDifferences->removedColumns[strtolower($removedColumnName)]
);
}
}
@@ -355,10 +420,8 @@ class Comparator
/**
* Try to find indexes that only changed their name, rename operations maybe cheaper than add/drop
* however ambiguities between different possibilities should not lead to renaming at all.
- *
- * @return void
*/
- private function detectIndexRenamings(TableDiff $tableDifferences)
+ private function detectIndexRenamings(TableDiff $tableDifferences): void
{
$renameCandidates = [];
@@ -430,10 +493,24 @@ class Comparator
}
/**
+ * Compares the definitions of the given columns
+ *
+ * @throws Exception
+ */
+ public function columnsEqual(Column $column1, Column $column2): bool
+ {
+ if ($this->platform === null) {
+ return $this->diffColumn($column1, $column2) === [];
+ }
+
+ return $this->platform->columnsEqual($column1, $column2);
+ }
+
+ /**
* Returns the difference between the columns
*
- * If there are differences this method returns $field2, otherwise the
- * boolean false.
+ * If there are differences this method returns the changed properties as a
+ * string array, otherwise an empty array gets returned.
*
* @return string[]
*/
diff --git a/doctrine/dbal/src/Schema/Constraint.php b/doctrine/dbal/src/Schema/Constraint.php
index 65e239ec..85338c78 100644
--- a/doctrine/dbal/src/Schema/Constraint.php
+++ b/doctrine/dbal/src/Schema/Constraint.php
@@ -6,6 +6,8 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* Marker interface for constraints.
+ *
+ * @deprecated Use {@see ForeignKeyConstraint}, {@see Index} or {@see UniqueConstraint} instead.
*/
interface Constraint
{
diff --git a/doctrine/dbal/src/Schema/DB2SchemaManager.php b/doctrine/dbal/src/Schema/DB2SchemaManager.php
index 82c287e0..e06baf36 100644
--- a/doctrine/dbal/src/Schema/DB2SchemaManager.php
+++ b/doctrine/dbal/src/Schema/DB2SchemaManager.php
@@ -8,7 +8,6 @@ use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
use function array_change_key_case;
-use function assert;
use function preg_match;
use function str_replace;
use function strpos;
@@ -19,6 +18,8 @@ use const CASE_LOWER;
/**
* IBM Db2 Schema Manager.
+ *
+ * @extends AbstractSchemaManager<DB2Platform>
*/
class DB2SchemaManager extends AbstractSchemaManager
{
@@ -235,9 +236,7 @@ class DB2SchemaManager extends AbstractSchemaManager
{
$table = parent::listTableDetails($name);
- $platform = $this->_platform;
- assert($platform instanceof DB2Platform);
- $sql = $platform->getListTableCommentsSQL($name);
+ $sql = $this->_platform->getListTableCommentsSQL($name);
$tableOptions = $this->_conn->fetchAssociative($sql);
diff --git a/doctrine/dbal/src/Schema/ForeignKeyConstraint.php b/doctrine/dbal/src/Schema/ForeignKeyConstraint.php
index 97618875..852ad0a3 100644
--- a/doctrine/dbal/src/Schema/ForeignKeyConstraint.php
+++ b/doctrine/dbal/src/Schema/ForeignKeyConstraint.php
@@ -105,6 +105,8 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
* Returns the name of the referencing table
* the foreign key constraint is associated with.
*
+ * @deprecated Use the table that contains the foreign key as part of its {@see Table::$_fkConstraints} instead.
+ *
* @return string
*/
public function getLocalTableName()
@@ -116,6 +118,8 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
* Sets the Table instance of the referencing table
* the foreign key constraint is associated with.
*
+ * @deprecated Use the table that contains the foreign key as part of its {@see Table::$_fkConstraints} instead.
+ *
* @param Table $table Instance of the referencing table.
*
* @return void
@@ -126,6 +130,8 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
}
/**
+ * @deprecated Use the table that contains the foreign key as part of its {@see Table::$_fkConstraints} instead.
+ *
* @return Table
*/
public function getLocalTable()
@@ -190,6 +196,8 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
/**
* {@inheritdoc}
*
+ * @deprecated Use {@see getLocalColumns()} instead.
+ *
* @see getLocalColumns
*/
public function getColumns()
@@ -205,6 +213,8 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
* is a keyword reserved by the platform.
* Otherwise the plain unquoted value as inserted is returned.
*
+ * @deprecated Use {@see getQuotedLocalColumns()} instead.
+ *
* @see getQuotedLocalColumns
*
* @param AbstractPlatform $platform The platform to use for quotation.
@@ -357,10 +367,8 @@ class ForeignKeyConstraint extends AbstractAsset implements Constraint
* on the referenced table the foreign key constraint is associated with.
*
* @param string $event Name of the database operation/event to return the referential action for.
- *
- * @return string|null
*/
- private function onEvent($event)
+ private function onEvent($event): ?string
{
if (isset($this->_options[$event])) {
$onEvent = strtoupper($this->_options[$event]);
diff --git a/doctrine/dbal/src/Schema/Index.php b/doctrine/dbal/src/Schema/Index.php
index 508aa403..fd088a30 100644
--- a/doctrine/dbal/src/Schema/Index.php
+++ b/doctrine/dbal/src/Schema/Index.php
@@ -336,10 +336,8 @@ class Index extends AbstractAsset implements Constraint
/**
* Return whether the two indexes have the same partial index
- *
- * @return bool
*/
- private function samePartialIndex(Index $other)
+ private function samePartialIndex(Index $other): bool
{
if (
$this->hasOption('where')
diff --git a/doctrine/dbal/src/Schema/MySQLSchemaManager.php b/doctrine/dbal/src/Schema/MySQLSchemaManager.php
index 4d54f715..7c175bb6 100644
--- a/doctrine/dbal/src/Schema/MySQLSchemaManager.php
+++ b/doctrine/dbal/src/Schema/MySQLSchemaManager.php
@@ -2,13 +2,13 @@
namespace Doctrine\DBAL\Schema;
+use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Platforms\MariaDb1027Platform;
-use Doctrine\DBAL\Platforms\MySQLPlatform;
+use Doctrine\DBAL\Platforms\MySQL;
use Doctrine\DBAL\Types\Type;
use function array_change_key_case;
use function array_shift;
-use function array_values;
use function assert;
use function explode;
use function is_string;
@@ -22,6 +22,8 @@ use const CASE_LOWER;
/**
* Schema manager for the MySQL RDBMS.
+ *
+ * @extends AbstractSchemaManager<AbstractMySQLPlatform>
*/
class MySQLSchemaManager extends AbstractSchemaManager
{
@@ -166,27 +168,27 @@ class MySQLSchemaManager extends AbstractSchemaManager
break;
case 'tinytext':
- $length = MySQLPlatform::LENGTH_LIMIT_TINYTEXT;
+ $length = AbstractMySQLPlatform::LENGTH_LIMIT_TINYTEXT;
break;
case 'text':
- $length = MySQLPlatform::LENGTH_LIMIT_TEXT;
+ $length = AbstractMySQLPlatform::LENGTH_LIMIT_TEXT;
break;
case 'mediumtext':
- $length = MySQLPlatform::LENGTH_LIMIT_MEDIUMTEXT;
+ $length = AbstractMySQLPlatform::LENGTH_LIMIT_MEDIUMTEXT;
break;
case 'tinyblob':
- $length = MySQLPlatform::LENGTH_LIMIT_TINYBLOB;
+ $length = AbstractMySQLPlatform::LENGTH_LIMIT_TINYBLOB;
break;
case 'blob':
- $length = MySQLPlatform::LENGTH_LIMIT_BLOB;
+ $length = AbstractMySQLPlatform::LENGTH_LIMIT_BLOB;
break;
case 'mediumblob':
- $length = MySQLPlatform::LENGTH_LIMIT_MEDIUMBLOB;
+ $length = AbstractMySQLPlatform::LENGTH_LIMIT_MEDIUMBLOB;
break;
case 'tinyint':
@@ -312,9 +314,9 @@ class MySQLSchemaManager extends AbstractSchemaManager
$result = [];
foreach ($list as $constraint) {
$result[] = new ForeignKeyConstraint(
- array_values($constraint['local']),
+ $constraint['local'],
$constraint['foreignTable'],
- array_values($constraint['foreign']),
+ $constraint['foreign'],
$constraint['name'],
[
'onDelete' => $constraint['onDelete'],
@@ -333,9 +335,7 @@ class MySQLSchemaManager extends AbstractSchemaManager
{
$table = parent::listTableDetails($name);
- $platform = $this->_platform;
- assert($platform instanceof MySQLPlatform);
- $sql = $platform->getListTableMetadataSQL($name);
+ $sql = $this->_platform->getListTableMetadataSQL($name);
$tableOptions = $this->_conn->fetchAssociative($sql);
@@ -349,6 +349,8 @@ class MySQLSchemaManager extends AbstractSchemaManager
$table->addOption('collation', $tableOptions['TABLE_COLLATION']);
}
+ $table->addOption('charset', $tableOptions['CHARACTER_SET_NAME']);
+
if ($tableOptions['AUTO_INCREMENT'] !== null) {
$table->addOption('autoincrement', $tableOptions['AUTO_INCREMENT']);
}
@@ -359,6 +361,11 @@ class MySQLSchemaManager extends AbstractSchemaManager
return $table;
}
+ public function createComparator(): Comparator
+ {
+ return new MySQL\Comparator($this->getDatabasePlatform());
+ }
+
/**
* @return string[]|true[]
*/
diff --git a/doctrine/dbal/src/Schema/OracleSchemaManager.php b/doctrine/dbal/src/Schema/OracleSchemaManager.php
index 13c88524..762492e7 100644
--- a/doctrine/dbal/src/Schema/OracleSchemaManager.php
+++ b/doctrine/dbal/src/Schema/OracleSchemaManager.php
@@ -8,7 +8,6 @@ use Doctrine\DBAL\Types\Type;
use function array_change_key_case;
use function array_values;
-use function assert;
use function is_string;
use function preg_match;
use function str_replace;
@@ -20,6 +19,8 @@ use const CASE_LOWER;
/**
* Oracle Schema Manager.
+ *
+ * @extends AbstractSchemaManager<OraclePlatform>
*/
class OracleSchemaManager extends AbstractSchemaManager
{
@@ -257,7 +258,7 @@ class OracleSchemaManager extends AbstractSchemaManager
*/
public function createDatabase($database)
{
- $statement = 'CREATE USER ' . $database;
+ $statement = $this->_platform->getCreateDatabaseSQL($database);
$params = $this->_conn->getParams();
@@ -282,8 +283,6 @@ class OracleSchemaManager extends AbstractSchemaManager
*/
public function dropAutoincrement($table)
{
- assert($this->_platform instanceof OraclePlatform);
-
$sql = $this->_platform->getDropAutoincrementSql($table);
foreach ($sql as $query) {
$this->_conn->executeStatement($query);
@@ -309,10 +308,8 @@ class OracleSchemaManager extends AbstractSchemaManager
* and thus make references to the particular identifier work.
*
* @param string $identifier The identifier to quote.
- *
- * @return string The quoted identifier.
*/
- private function getQuotedIdentifierName($identifier)
+ private function getQuotedIdentifierName($identifier): string
{
if (preg_match('/[a-z]/', $identifier) === 1) {
return $this->_platform->quoteIdentifier($identifier);
@@ -328,14 +325,13 @@ class OracleSchemaManager extends AbstractSchemaManager
{
$table = parent::listTableDetails($name);
- $platform = $this->_platform;
- assert($platform instanceof OraclePlatform);
- $sql = $platform->getListTableCommentsSQL($name);
+ $sql = $this->_platform->getListTableCommentsSQL($name);
$tableOptions = $this->_conn->fetchAssociative($sql);
if ($tableOptions !== false) {
- $table->addOption('comment', $tableOptions['COMMENTS']);
+ $tableOptions = array_change_key_case($tableOptions, CASE_LOWER);
+ $table->addOption('comment', $tableOptions['comments']);
}
return $table;
diff --git a/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php b/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php
index abc06af4..03239bde 100644
--- a/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php
+++ b/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php
@@ -3,7 +3,7 @@
namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Exception;
-use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
+use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
use Doctrine\Deprecations\Deprecation;
@@ -29,6 +29,8 @@ use const CASE_LOWER;
/**
* PostgreSQL Schema Manager.
+ *
+ * @extends AbstractSchemaManager<PostgreSQLPlatform>
*/
class PostgreSQLSchemaManager extends AbstractSchemaManager
{
@@ -38,7 +40,7 @@ class PostgreSQLSchemaManager extends AbstractSchemaManager
/**
* Gets all the existing schema names.
*
- * @deprecated Use {@link listSchemaNames()} instead.
+ * @deprecated Use {@see listSchemaNames()} instead.
*
* @return string[]
*
@@ -73,9 +75,17 @@ SQL
/**
* {@inheritDoc}
+ *
+ * @deprecated
*/
public function getSchemaSearchPaths()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4821',
+ 'PostgreSQLSchemaManager::getSchemaSearchPaths() is deprecated.'
+ );
+
$params = $this->_conn->getParams();
$searchPaths = $this->_conn->fetchOne('SHOW search_path');
@@ -98,6 +108,8 @@ SQL
* @internal The method should be only used from within the PostgreSQLSchemaManager class hierarchy.
*
* @return string[]
+ *
+ * @throws Exception
*/
public function getExistingSchemaSearchPaths()
{
@@ -111,6 +123,20 @@ SQL
}
/**
+ * Returns the name of the current schema.
+ *
+ * @return string|null
+ *
+ * @throws Exception
+ */
+ protected function getCurrentSchema()
+ {
+ $schemas = $this->getExistingSchemaSearchPaths();
+
+ return array_shift($schemas);
+ }
+
+ /**
* Sets or resets the order of the existing schemas in the current search path of the user.
*
* This is a PostgreSQL only function.
@@ -118,6 +144,8 @@ SQL
* @internal The method should be only used from within the PostgreSQLSchemaManager class hierarchy.
*
* @return void
+ *
+ * @throws Exception
*/
public function determineExistingSchemaSearchPaths()
{
@@ -178,14 +206,6 @@ SQL
/**
* {@inheritdoc}
*/
- protected function _getPortableTriggerDefinition($trigger)
- {
- return $trigger['trigger_name'];
- }
-
- /**
- * {@inheritdoc}
- */
protected function _getPortableViewDefinition($view)
{
return new View($view['schemaname'] . '.' . $view['viewname'], $view['definition']);
@@ -207,10 +227,9 @@ SQL
*/
protected function _getPortableTableDefinition($table)
{
- $schemas = $this->getExistingSchemaSearchPaths();
- $firstSchema = array_shift($schemas);
+ $currentSchema = $this->getCurrentSchema();
- if ($table['schema_name'] === $firstSchema) {
+ if ($table['schema_name'] === $currentSchema) {
return $table['table_name'];
}
@@ -293,7 +312,7 @@ SQL
/**
* {@inheritdoc}
*
- * @deprecated Use {@link listSchemaNames()} instead.
+ * @deprecated Use {@see listSchemaNames()} instead.
*/
protected function getPortableNamespaceDefinition(array $namespace)
{
@@ -458,7 +477,7 @@ SQL
if (
preg_match(
- '([A-Za-z]+\(([0-9]+)\,([0-9]+)\))',
+ '([A-Za-z]+\(([0-9]+),([0-9]+)\))',
$tableColumn['complete_type'],
$match
) === 1
@@ -552,9 +571,7 @@ SQL
{
$table = parent::listTableDetails($name);
- $platform = $this->_platform;
- assert($platform instanceof PostgreSQL94Platform);
- $sql = $platform->getListTableMetadataSQL($name);
+ $sql = $this->_platform->getListTableMetadataSQL($name);
$tableOptions = $this->_conn->fetchAssociative($sql);
diff --git a/doctrine/dbal/src/Schema/SQLServerSchemaManager.php b/doctrine/dbal/src/Schema/SQLServerSchemaManager.php
index f1836fc5..8a8713f0 100644
--- a/doctrine/dbal/src/Schema/SQLServerSchemaManager.php
+++ b/doctrine/dbal/src/Schema/SQLServerSchemaManager.php
@@ -3,7 +3,8 @@
namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Exception;
-use Doctrine\DBAL\Platforms\SQLServer2012Platform;
+use Doctrine\DBAL\Platforms\SQLServer;
+use Doctrine\DBAL\Platforms\SQLServerPlatform;
use Doctrine\DBAL\Types\Type;
use Doctrine\Deprecations\Deprecation;
@@ -18,9 +19,14 @@ use function strtok;
/**
* SQL Server Schema Manager.
+ *
+ * @extends AbstractSchemaManager<SQLServerPlatform>
*/
class SQLServerSchemaManager extends AbstractSchemaManager
{
+ /** @var string|null */
+ private $databaseCollation;
+
/**
* {@inheritDoc}
*/
@@ -221,7 +227,7 @@ SQL
/**
* {@inheritdoc}
*
- * @deprecated Use {@link listSchemaNames()} instead.
+ * @deprecated Use {@see listSchemaNames()} instead.
*/
protected function getPortableNamespaceDefinition(array $namespace)
{
@@ -241,7 +247,7 @@ SQL
protected function _getPortableViewDefinition($view)
{
// @todo
- return new View($view['name'], '');
+ return new View($view['name'], $view['definition']);
}
/**
@@ -271,13 +277,12 @@ SQL
{
if (count($tableDiff->removedColumns) > 0) {
foreach ($tableDiff->removedColumns as $col) {
- $columnConstraintSql = $this->getColumnConstraintSQL($tableDiff->name, $col->getName());
- foreach ($this->_conn->fetchAllAssociative($columnConstraintSql) as $constraint) {
+ foreach ($this->getColumnConstraints($tableDiff->name, $col->getName()) as $constraint) {
$this->_conn->executeStatement(
sprintf(
'ALTER TABLE %s DROP CONSTRAINT %s',
$tableDiff->name,
- $constraint['Name']
+ $constraint
)
);
}
@@ -288,22 +293,32 @@ SQL
}
/**
- * Returns the SQL to retrieve the constraints for a given column.
+ * Returns the names of the constraints for a given column.
*
- * @param string $table
- * @param string $column
+ * @return iterable<string>
*
- * @return string
+ * @throws Exception
*/
- private function getColumnConstraintSQL($table, $column)
+ private function getColumnConstraints(string $table, string $column): iterable
{
- return "SELECT sysobjects.[Name]
- FROM sysobjects INNER JOIN (SELECT [Name],[ID] FROM sysobjects WHERE XType = 'U') AS Tab
- ON Tab.[ID] = sysobjects.[Parent_Obj]
- INNER JOIN sys.default_constraints DefCons ON DefCons.[object_id] = sysobjects.[ID]
- INNER JOIN syscolumns Col ON Col.[ColID] = DefCons.[parent_column_id] AND Col.[ID] = Tab.[ID]
- WHERE Col.[Name] = " . $this->_conn->quote($column) . ' AND Tab.[Name] = ' . $this->_conn->quote($table) . '
- ORDER BY Col.[Name]';
+ return $this->_conn->iterateColumn(
+ <<<'SQL'
+SELECT o.name
+FROM sys.objects o
+ INNER JOIN sys.objects t
+ ON t.object_id = o.parent_object_id
+ AND t.type = 'U'
+ INNER JOIN sys.default_constraints dc
+ ON dc.object_id = o.object_id
+ INNER JOIN sys.columns c
+ ON c.column_id = dc.parent_column_id
+ AND c.object_id = t.object_id
+WHERE t.name = ?
+ AND c.name = ?
+SQL
+ ,
+ [$table, $column]
+ );
}
/**
@@ -315,9 +330,7 @@ SQL
{
$table = parent::listTableDetails($name);
- $platform = $this->_platform;
- assert($platform instanceof SQLServer2012Platform);
- $sql = $platform->getListTableMetadataSQL($name);
+ $sql = $this->_platform->getListTableMetadataSQL($name);
$tableOptions = $this->_conn->fetchAssociative($sql);
@@ -327,4 +340,32 @@ SQL
return $table;
}
+
+ /**
+ * @throws Exception
+ */
+ public function createComparator(): Comparator
+ {
+ return new SQLServer\Comparator($this->getDatabasePlatform(), $this->getDatabaseCollation());
+ }
+
+ /**
+ * @throws Exception
+ */
+ private function getDatabaseCollation(): string
+ {
+ if ($this->databaseCollation === null) {
+ $databaseCollation = $this->_conn->fetchOne(
+ 'SELECT collation_name FROM sys.databases WHERE name = '
+ . $this->_platform->getCurrentDatabaseExpression(),
+ );
+
+ // a database is always selected, even if omitted in the connection parameters
+ assert(is_string($databaseCollation));
+
+ $this->databaseCollation = $databaseCollation;
+ }
+
+ return $this->databaseCollation;
+ }
}
diff --git a/doctrine/dbal/src/Schema/Schema.php b/doctrine/dbal/src/Schema/Schema.php
index 08eb2683..9be9e350 100644
--- a/doctrine/dbal/src/Schema/Schema.php
+++ b/doctrine/dbal/src/Schema/Schema.php
@@ -7,6 +7,7 @@ use Doctrine\DBAL\Schema\Visitor\CreateSchemaSqlCollector;
use Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector;
use Doctrine\DBAL\Schema\Visitor\NamespaceVisitor;
use Doctrine\DBAL\Schema\Visitor\Visitor;
+use Doctrine\Deprecations\Deprecation;
use function array_keys;
use function strpos;
@@ -88,10 +89,18 @@ class Schema extends AbstractAsset
}
/**
+ * @deprecated
+ *
* @return bool
*/
public function hasExplicitForeignKeyIndexes()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4822',
+ 'Schema::hasExplicitForeignKeyIndexes() is deprecated.'
+ );
+
return $this->_schemaConfig->hasExplicitForeignKeyIndexes();
}
@@ -103,7 +112,7 @@ class Schema extends AbstractAsset
protected function _addTable(Table $table)
{
$namespaceName = $table->getNamespaceName();
- $tableName = $table->getFullQualifiedName($this->getName());
+ $tableName = $this->normalizeName($table);
if (isset($this->_tables[$tableName])) {
throw SchemaException::tableAlreadyExists($tableName);
@@ -129,7 +138,7 @@ class Schema extends AbstractAsset
protected function _addSequence(Sequence $sequence)
{
$namespaceName = $sequence->getNamespaceName();
- $seqName = $sequence->getFullQualifiedName($this->getName());
+ $seqName = $this->normalizeName($sequence);
if (isset($this->_sequences[$seqName])) {
throw SchemaException::sequenceAlreadyExists($seqName);
@@ -185,10 +194,8 @@ class Schema extends AbstractAsset
/**
* @param string $name
- *
- * @return string
*/
- private function getFullQualifiedAssetName($name)
+ private function getFullQualifiedAssetName($name): string
{
$name = $this->getUnquotedAssetName($name);
@@ -199,14 +206,17 @@ class Schema extends AbstractAsset
return strtolower($name);
}
+ private function normalizeName(AbstractAsset $asset): string
+ {
+ return $asset->getFullQualifiedName($this->getName());
+ }
+
/**
* Returns the unquoted representation of a given asset name.
*
* @param string $assetName Quoted or unquoted representation of an asset name.
- *
- * @return string
*/
- private function getUnquotedAssetName($assetName)
+ private function getUnquotedAssetName($assetName): string
{
if ($this->isIdentifierQuoted($assetName)) {
return $this->trimQuotes($assetName);
@@ -246,10 +256,20 @@ class Schema extends AbstractAsset
/**
* Gets all table names, prefixed with a schema name, even the default one if present.
*
+ * @deprecated Use {@see getTables()} and {@see Table::getName()} instead.
+ *
* @return string[]
*/
public function getTableNames()
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4800',
+ 'Schema::getTableNames() is deprecated.'
+ . ' Use Schema::getTables() and Table::getName() instead.',
+ __METHOD__
+ );
+
return array_keys($this->_tables);
}
@@ -431,27 +451,29 @@ class Schema extends AbstractAsset
}
/**
+ * @deprecated
+ *
* @return string[]
*
* @throws SchemaException
*/
public function getMigrateToSql(Schema $toSchema, AbstractPlatform $platform)
{
- $comparator = new Comparator();
- $schemaDiff = $comparator->compare($this, $toSchema);
+ $schemaDiff = (new Comparator())->compareSchemas($this, $toSchema);
return $schemaDiff->toSql($platform);
}
/**
+ * @deprecated
+ *
* @return string[]
*
* @throws SchemaException
*/
public function getMigrateFromSql(Schema $fromSchema, AbstractPlatform $platform)
{
- $comparator = new Comparator();
- $schemaDiff = $comparator->compare($fromSchema, $this);
+ $schemaDiff = (new Comparator())->compareSchemas($fromSchema, $this);
return $schemaDiff->toSql($platform);
}
diff --git a/doctrine/dbal/src/Schema/SchemaConfig.php b/doctrine/dbal/src/Schema/SchemaConfig.php
index 56d49c4a..92e0701f 100644
--- a/doctrine/dbal/src/Schema/SchemaConfig.php
+++ b/doctrine/dbal/src/Schema/SchemaConfig.php
@@ -2,12 +2,18 @@
namespace Doctrine\DBAL\Schema;
+use Doctrine\Deprecations\Deprecation;
+
/**
* Configuration for a Schema.
*/
class SchemaConfig
{
- /** @var bool */
+ /**
+ * @deprecated
+ *
+ * @var bool
+ */
protected $hasExplicitForeignKeyIndexes = false;
/** @var int */
@@ -20,20 +26,36 @@ class SchemaConfig
protected $defaultTableOptions = [];
/**
+ * @deprecated
+ *
* @return bool
*/
public function hasExplicitForeignKeyIndexes()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4822',
+ 'SchemaConfig::hasExplicitForeignKeyIndexes() is deprecated.'
+ );
+
return $this->hasExplicitForeignKeyIndexes;
}
/**
+ * @deprecated
+ *
* @param bool $flag
*
* @return void
*/
public function setExplicitForeignKeyIndexes($flag)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4822',
+ 'SchemaConfig::setExplicitForeignKeyIndexes() is deprecated.'
+ );
+
$this->hasExplicitForeignKeyIndexes = (bool) $flag;
}
diff --git a/doctrine/dbal/src/Schema/SchemaDiff.php b/doctrine/dbal/src/Schema/SchemaDiff.php
index 67fb9bb9..50d0d12f 100644
--- a/doctrine/dbal/src/Schema/SchemaDiff.php
+++ b/doctrine/dbal/src/Schema/SchemaDiff.php
@@ -7,7 +7,10 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
use function array_merge;
/**
- * Schema Diff.
+ * Differences between two schemas.
+ *
+ * The object contains the operations to change the schema stored in $fromSchema
+ * to a target schema.
*/
class SchemaDiff
{
diff --git a/doctrine/dbal/src/Schema/SqliteSchemaManager.php b/doctrine/dbal/src/Schema/SqliteSchemaManager.php
index 140ebb3c..3e0e5cfe 100644
--- a/doctrine/dbal/src/Schema/SqliteSchemaManager.php
+++ b/doctrine/dbal/src/Schema/SqliteSchemaManager.php
@@ -4,15 +4,17 @@ namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception;
+use Doctrine\DBAL\Platforms\SQLite;
+use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Types\StringType;
use Doctrine\DBAL\Types\TextType;
use Doctrine\DBAL\Types\Type;
+use Doctrine\Deprecations\Deprecation;
use function array_change_key_case;
use function array_map;
use function array_merge;
use function array_reverse;
-use function array_values;
use function explode;
use function file_exists;
use function preg_match;
@@ -20,7 +22,6 @@ use function preg_match_all;
use function preg_quote;
use function preg_replace;
use function rtrim;
-use function sprintf;
use function str_replace;
use function strpos;
use function strtolower;
@@ -32,14 +33,24 @@ use const CASE_LOWER;
/**
* Sqlite SchemaManager.
+ *
+ * @extends AbstractSchemaManager<SqlitePlatform>
*/
class SqliteSchemaManager extends AbstractSchemaManager
{
/**
* {@inheritdoc}
+ *
+ * @deprecated Delete the database file using the filesystem.
*/
public function dropDatabase($database)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4963',
+ 'SqliteSchemaManager::dropDatabase() is deprecated. Delete the database file using the filesystem.'
+ );
+
if (! file_exists($database)) {
return;
}
@@ -49,9 +60,18 @@ class SqliteSchemaManager extends AbstractSchemaManager
/**
* {@inheritdoc}
+ *
+ * @deprecated The engine will create the database file automatically.
*/
public function createDatabase($database)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/issues/4963',
+ 'SqliteSchemaManager::createDatabase() is deprecated.'
+ . ' The engine will create the database file automatically.'
+ );
+
$params = $this->_conn->getParams();
$params['path'] = $database;
@@ -86,9 +106,18 @@ class SqliteSchemaManager extends AbstractSchemaManager
/**
* {@inheritdoc}
+ *
+ * @deprecated Use {@see dropForeignKey()} and {@see createForeignKey()} instead.
*/
public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table)
{
+ Deprecation::trigger(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4897',
+ 'SqliteSchemaManager::dropAndCreateForeignKey() is deprecated.'
+ . ' Use SqliteSchemaManager::dropForeignKey() and SqliteSchemaManager::createForeignKey() instead.'
+ );
+
$tableDiff = $this->getTableDiffForAlterForeignKey($table);
$tableDiff->changedForeignKeys[] = $foreignKey;
@@ -126,7 +155,7 @@ class SqliteSchemaManager extends AbstractSchemaManager
'#
(?:CONSTRAINT\s+([^\s]+)\s+)?
(?:FOREIGN\s+KEY[^\)]+\)\s*)?
- REFERENCES\s+[^\s]+\s+(?:\([^\)]+\))?
+ REFERENCES\s+[^\s]+\s+(?:\([^)]+\))?
(?:
[^,]*?
(NOT\s+DEFERRABLE|DEFERRABLE)
@@ -175,10 +204,7 @@ class SqliteSchemaManager extends AbstractSchemaManager
$indexBuffer = [];
// fetch primary
- $indexArray = $this->_conn->fetchAllAssociative(sprintf(
- 'PRAGMA TABLE_INFO (%s)',
- $this->_conn->quote($tableName)
- ));
+ $indexArray = $this->_conn->fetchAllAssociative('SELECT * FROM PRAGMA_TABLE_INFO (?)', [$tableName]);
usort(
$indexArray,
@@ -221,10 +247,7 @@ class SqliteSchemaManager extends AbstractSchemaManager
$idx['primary'] = false;
$idx['non_unique'] = ! $tableIndex['unique'];
- $indexArray = $this->_conn->fetchAllAssociative(sprintf(
- 'PRAGMA INDEX_INFO (%s)',
- $this->_conn->quote($keyName)
- ));
+ $indexArray = $this->_conn->fetchAllAssociative('SELECT * FROM PRAGMA_INDEX_INFO (?)', [$keyName]);
foreach ($indexArray as $indexColumnRow) {
$idx['column_name'] = $indexColumnRow['name'];
@@ -431,9 +454,9 @@ class SqliteSchemaManager extends AbstractSchemaManager
$result = [];
foreach ($list as $constraint) {
$result[] = new ForeignKeyConstraint(
- array_values($constraint['local']),
+ $constraint['local'],
$constraint['foreignTable'],
- array_values($constraint['foreign']),
+ $constraint['foreign'],
$constraint['name'],
[
'onDelete' => $constraint['onDelete'],
@@ -450,22 +473,12 @@ class SqliteSchemaManager extends AbstractSchemaManager
/**
* @param Table|string $table
*
- * @return TableDiff
- *
* @throws Exception
*/
- private function getTableDiffForAlterForeignKey($table)
+ private function getTableDiffForAlterForeignKey($table): TableDiff
{
if (! $table instanceof Table) {
- $tableDetails = $this->tryMethod('listTableDetails', $table);
-
- if ($tableDetails === false) {
- throw new Exception(
- sprintf('Sqlite schema manager requires to modify foreign keys table definition "%s".', $table)
- );
- }
-
- $table = $tableDetails;
+ $table = $this->listTableDetails($table);
}
$tableDiff = new TableDiff($table->getName());
@@ -569,11 +582,24 @@ SQL
return $table;
}
+ public function createComparator(): Comparator
+ {
+ return new SQLite\Comparator($this->getDatabasePlatform());
+ }
+
/**
* {@inheritDoc}
+ *
+ * @deprecated
*/
public function getSchemaSearchPaths()
{
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/4821',
+ 'SqliteSchemaManager::getSchemaSearchPaths() is deprecated.'
+ );
+
// 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 d330d03f..4f591eb6 100644
--- a/doctrine/dbal/src/Schema/Table.php
+++ b/doctrine/dbal/src/Schema/Table.php
@@ -314,8 +314,6 @@ class Table extends AbstractAsset
* @param string[] $flags
* @param mixed[] $options
*
- * @return Index
- *
* @throws SchemaException
*/
private function _createIndex(
@@ -325,7 +323,7 @@ class Table extends AbstractAsset
$isPrimary,
array $flags = [],
array $options = []
- ) {
+ ): Index {
if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName)) === 1) {
throw SchemaException::indexNameInvalid($indexName);
}
diff --git a/doctrine/dbal/src/Schema/Visitor/CreateSchemaSqlCollector.php b/doctrine/dbal/src/Schema/Visitor/CreateSchemaSqlCollector.php
index c08fb6fe..730dff77 100644
--- a/doctrine/dbal/src/Schema/Visitor/CreateSchemaSqlCollector.php
+++ b/doctrine/dbal/src/Schema/Visitor/CreateSchemaSqlCollector.php
@@ -91,8 +91,8 @@ class CreateSchemaSqlCollector extends AbstractVisitor
{
return array_merge(
$this->createNamespaceQueries,
- $this->createTableQueries,
$this->createSequenceQueries,
+ $this->createTableQueries,
$this->createFkConstraintQueries
);
}
diff --git a/doctrine/dbal/src/Schema/Visitor/Graphviz.php b/doctrine/dbal/src/Schema/Visitor/Graphviz.php
index 299ff0e7..5af4678f 100644
--- a/doctrine/dbal/src/Schema/Visitor/Graphviz.php
+++ b/doctrine/dbal/src/Schema/Visitor/Graphviz.php
@@ -13,6 +13,8 @@ use function strtolower;
/**
* Create a Graphviz output of a Schema.
+ *
+ * @deprecated
*/
class Graphviz extends AbstractVisitor
{
@@ -62,10 +64,7 @@ class Graphviz extends AbstractVisitor
);
}
- /**
- * @return string
- */
- private function createTableLabel(Table $table)
+ private function createTableLabel(Table $table): string
{
// Start the table
$label = '<<TABLE CELLSPACING="0" BORDER="1" ALIGN="LEFT">';
@@ -107,10 +106,8 @@ class Graphviz extends AbstractVisitor
/**
* @param string $name
* @param string[] $options
- *
- * @return string
*/
- private function createNode($name, $options)
+ private function createNode($name, $options): string
{
$node = $name . ' [';
foreach ($options as $key => $value) {
@@ -126,10 +123,8 @@ class Graphviz extends AbstractVisitor
* @param string $node1
* @param string $node2
* @param string[] $options
- *
- * @return string
*/
- private function createNodeRelation($node1, $node2, $options)
+ private function createNodeRelation($node1, $node2, $options): string
{
$relation = $node1 . ' -> ' . $node2 . ' [';
foreach ($options as $key => $value) {
diff --git a/doctrine/dbal/src/Statement.php b/doctrine/dbal/src/Statement.php
index b7183fa3..782feee2 100644
--- a/doctrine/dbal/src/Statement.php
+++ b/doctrine/dbal/src/Statement.php
@@ -2,8 +2,6 @@
namespace Doctrine\DBAL;
-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;
@@ -40,7 +38,7 @@ class Statement
/**
* The underlying driver statement.
*
- * @var DriverStatement
+ * @var Driver\Statement
*/
protected $stmt;
@@ -61,26 +59,19 @@ class Statement
/**
* Creates a new <tt>Statement</tt> for the given SQL and <tt>Connection</tt>.
*
- * @internal The statement can be only instantiated by {@link Connection}.
+ * @internal The statement can be only instantiated by {@see Connection}.
*
- * @param string $sql The SQL of the statement.
- * @param Connection $conn The connection on which the statement should be executed.
+ * @param Connection $conn The connection for handling statement errors.
+ * @param Driver\Statement $statement The underlying driver-level statement.
+ * @param string $sql The SQL of the statement.
*
* @throws Exception
*/
- public function __construct($sql, Connection $conn)
+ public function __construct(Connection $conn, Driver\Statement $statement, string $sql)
{
- $driverConnection = $conn->getWrappedConnection();
-
- try {
- $stmt = $driverConnection->prepare($sql);
- } catch (Exception $ex) {
- throw $conn->convertExceptionDuringQuery($ex, $sql);
- }
-
- $this->sql = $sql;
- $this->stmt = $stmt;
$this->conn = $conn;
+ $this->stmt = $statement;
+ $this->sql = $sql;
$this->platform = $conn->getDatabasePlatform();
}
@@ -122,7 +113,7 @@ class Statement
try {
return $this->stmt->bindValue($param, $value, $bindingType);
- } catch (Exception $e) {
+ } catch (Driver\Exception $e) {
throw $this->conn->convertException($e);
}
}
@@ -153,7 +144,7 @@ class Statement
}
return $this->stmt->bindParam($param, $variable, $type);
- } catch (Exception $e) {
+ } catch (Driver\Exception $e) {
throw $this->conn->convertException($e);
}
}
@@ -189,7 +180,7 @@ class Statement
$this->stmt->execute($params),
$this->conn
);
- } catch (Exception $ex) {
+ } catch (Driver\Exception $ex) {
throw $this->conn->convertExceptionDuringQuery($ex, $this->sql, $this->params, $this->types);
} finally {
if ($logger !== null) {
@@ -233,7 +224,7 @@ class Statement
/**
* Gets the wrapped driver statement.
*
- * @return DriverStatement
+ * @return Driver\Statement
*/
public function getWrappedStatement()
{
diff --git a/doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php b/doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php
index 875f2a20..a9137206 100644
--- a/doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php
+++ b/doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php
@@ -5,19 +5,19 @@ namespace Doctrine\DBAL\Tools\Console\Command;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Tools\Console\ConnectionProvider;
-use Doctrine\DBAL\Tools\Dumper;
-use LogicException;
use RuntimeException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use function array_keys;
use function assert;
use function is_bool;
-use function is_numeric;
use function is_string;
+use function sprintf;
use function stripos;
/**
@@ -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 (deprecated).'),
new InputOption('force-fetch', null, InputOption::VALUE_NONE, 'Forces fetching the result.'),
])
->setHelp(<<<EOT
@@ -66,6 +66,7 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output)
{
$conn = $this->getConnection($input);
+ $io = new SymfonyStyle($input, $output);
$sql = $input->getArgument('sql');
@@ -75,23 +76,19 @@ EOT
assert(is_string($sql));
- $depth = $input->getOption('depth');
-
- if (! is_numeric($depth)) {
- throw new LogicException("Option 'depth' must contains an integer value");
+ if ($input->getOption('depth') !== null) {
+ $io->warning('Parameter "depth" is deprecated and has no effect anymore.');
}
$forceFetch = $input->getOption('force-fetch');
assert(is_bool($forceFetch));
if (stripos($sql, 'select') === 0 || $forceFetch) {
- $resultSet = $conn->fetchAllAssociative($sql);
+ $this->runQuery($io, $conn, $sql);
} else {
- $resultSet = $conn->executeStatement($sql);
+ $this->runStatement($io, $conn, $sql);
}
- $output->write(Dumper::dump($resultSet, (int) $depth));
-
return 0;
}
@@ -106,4 +103,27 @@ EOT
return $this->connectionProvider->getDefaultConnection();
}
+
+ /**
+ * @throws Exception
+ */
+ private function runQuery(SymfonyStyle $io, Connection $conn, string $sql): void
+ {
+ $resultSet = $conn->fetchAllAssociative($sql);
+ if ($resultSet === []) {
+ $io->success('The query yielded an empty result set.');
+
+ return;
+ }
+
+ $io->table(array_keys($resultSet[0]), $resultSet);
+ }
+
+ /**
+ * @throws Exception
+ */
+ private function runStatement(SymfonyStyle $io, Connection $conn, string $sql): void
+ {
+ $io->success(sprintf('%d rows affected.', $conn->executeStatement($sql)));
+ }
}
diff --git a/doctrine/dbal/src/Tools/Console/ConsoleRunner.php b/doctrine/dbal/src/Tools/Console/ConsoleRunner.php
index 1cc315de..823a1e80 100644
--- a/doctrine/dbal/src/Tools/Console/ConsoleRunner.php
+++ b/doctrine/dbal/src/Tools/Console/ConsoleRunner.php
@@ -2,13 +2,15 @@
namespace Doctrine\DBAL\Tools\Console;
+use Composer\InstalledVersions;
use Doctrine\DBAL\Tools\Console\Command\ReservedWordsCommand;
use Doctrine\DBAL\Tools\Console\Command\RunSqlCommand;
use Exception;
-use PackageVersions\Versions;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
+use function assert;
+
/**
* Handles running the Console Tools inside Symfony Console context.
*/
@@ -25,7 +27,10 @@ class ConsoleRunner
*/
public static function run(ConnectionProvider $connectionProvider, $commands = [])
{
- $cli = new Application('Doctrine Command Line Interface', Versions::getVersion('doctrine/dbal'));
+ $version = InstalledVersions::getVersion('doctrine/dbal');
+ assert($version !== null);
+
+ $cli = new Application('Doctrine Command Line Interface', $version);
$cli->setCatchExceptions(true);
self::addCommands($cli, $connectionProvider);
@@ -47,6 +52,8 @@ class ConsoleRunner
/**
* Prints the instructions to create a configuration file
*
+ * @deprecated This method will be removed without replacement.
+ *
* @return void
*/
public static function printCliConfigTemplate()
diff --git a/doctrine/dbal/src/Tools/Dumper.php b/doctrine/dbal/src/Tools/Dumper.php
deleted file mode 100644
index 23dc7a05..00000000
--- a/doctrine/dbal/src/Tools/Dumper.php
+++ /dev/null
@@ -1,181 +0,0 @@
-<?php
-
-namespace Doctrine\DBAL\Tools;
-
-use ArrayIterator;
-use ArrayObject;
-use DateTimeInterface;
-use Doctrine\Common\Collections\Collection;
-use Doctrine\Common\Persistence\Proxy;
-use stdClass;
-
-use function array_keys;
-use function assert;
-use function class_exists;
-use function count;
-use function end;
-use function explode;
-use function extension_loaded;
-use function get_class;
-use function html_entity_decode;
-use function ini_set;
-use function is_array;
-use function is_object;
-use function is_string;
-use function ob_get_clean;
-use function ob_start;
-use function strip_tags;
-use function strlen;
-use function strrpos;
-use function substr;
-use function var_dump;
-
-/**
- * Static class used to dump the variable to be used on output.
- * Simplified port of Util\Debug from doctrine/common.
- *
- * @internal
- */
-final class Dumper
-{
- /**
- * Private constructor (prevents instantiation).
- *
- * @codeCoverageIgnore
- */
- private function __construct()
- {
- }
-
- /**
- * Returns a dump of the public, protected and private properties of $var.
- *
- * @link https://xdebug.org/
- *
- * @param mixed $var The variable to dump.
- * @param int $maxDepth The maximum nesting level for object properties.
- */
- public static function dump($var, int $maxDepth = 2): string
- {
- $html = ini_set('html_errors', '1');
- assert(is_string($html));
-
- if (extension_loaded('xdebug')) {
- ini_set('xdebug.var_display_max_depth', (string) $maxDepth);
- }
-
- $var = self::export($var, $maxDepth);
-
- ob_start();
- var_dump($var);
-
- try {
- $output = ob_get_clean();
- assert(is_string($output));
-
- return strip_tags(html_entity_decode($output));
- } finally {
- ini_set('html_errors', $html);
- }
- }
-
- /**
- * @param mixed $var
- *
- * @return mixed
- */
- public static function export($var, int $maxDepth)
- {
- $isObj = is_object($var);
-
- if ($var instanceof Collection) {
- $var = $var->toArray();
- }
-
- if ($maxDepth === 0) {
- return is_object($var) ? get_class($var)
- : (is_array($var) ? 'Array(' . count($var) . ')' : $var);
- }
-
- if (is_array($var)) {
- $return = [];
-
- foreach ($var as $k => $v) {
- $return[$k] = self::export($v, $maxDepth - 1);
- }
-
- return $return;
- }
-
- if (! $isObj) {
- return $var;
- }
-
- $return = new stdClass();
- if ($var instanceof DateTimeInterface) {
- $return->__CLASS__ = get_class($var);
- $return->date = $var->format('c');
- $return->timezone = $var->getTimezone()->getName();
-
- return $return;
- }
-
- $return->__CLASS__ = self::getClass($var);
-
- if ($var instanceof Proxy) {
- $return->__IS_PROXY__ = true;
- $return->__PROXY_INITIALIZED__ = $var->__isInitialized();
- }
-
- if ($var instanceof ArrayObject || $var instanceof ArrayIterator) {
- $return->__STORAGE__ = self::export($var->getArrayCopy(), $maxDepth - 1);
- }
-
- return self::fillReturnWithClassAttributes($var, $return, $maxDepth);
- }
-
- /**
- * Fill the $return variable with class attributes
- * Based on obj2array function from {@see https://secure.php.net/manual/en/function.get-object-vars.php#47075}
- *
- * @param object $var
- *
- * @return mixed
- */
- private static function fillReturnWithClassAttributes($var, stdClass $return, int $maxDepth)
- {
- $clone = (array) $var;
-
- foreach (array_keys($clone) as $key) {
- $aux = explode("\0", $key);
- $name = end($aux);
- if ($aux[0] === '') {
- $name .= ':' . ($aux[1] === '*' ? 'protected' : $aux[1] . ':private');
- }
-
- $return->$name = self::export($clone[$key], $maxDepth - 1);
- }
-
- return $return;
- }
-
- /**
- * @param object $object
- */
- private static function getClass($object): string
- {
- $class = get_class($object);
-
- if (! class_exists(Proxy::class)) {
- return $class;
- }
-
- $pos = strrpos($class, '\\' . Proxy::MARKER . '\\');
-
- if ($pos === false) {
- return $class;
- }
-
- return substr($class, $pos + strlen(Proxy::MARKER) + 2);
- }
-}
diff --git a/doctrine/dbal/src/Types/AsciiStringType.php b/doctrine/dbal/src/Types/AsciiStringType.php
index e7975748..ab1e0e06 100644
--- a/doctrine/dbal/src/Types/AsciiStringType.php
+++ b/doctrine/dbal/src/Types/AsciiStringType.php
@@ -12,15 +12,12 @@ final class AsciiStringType extends StringType
/**
* {@inheritdoc}
*/
- public function getSQLDeclaration(array $column, AbstractPlatform $platform)
+ public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
return $platform->getAsciiStringTypeDeclarationSQL($column);
}
- /**
- * {@inheritdoc}
- */
- public function getBindingType()
+ public function getBindingType(): int
{
return ParameterType::ASCII;
}
diff --git a/doctrine/dbal/src/Types/BooleanType.php b/doctrine/dbal/src/Types/BooleanType.php
index f6e4df3b..68a80ef3 100644
--- a/doctrine/dbal/src/Types/BooleanType.php
+++ b/doctrine/dbal/src/Types/BooleanType.php
@@ -4,6 +4,7 @@ namespace Doctrine\DBAL\Types;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
+use Doctrine\DBAL\Platforms\DB2Platform;
/**
* Type that maps an SQL boolean to a PHP boolean.
@@ -49,4 +50,14 @@ class BooleanType extends Type
{
return ParameterType::BOOLEAN;
}
+
+ /**
+ * @return bool
+ */
+ public function requiresSQLCommentHint(AbstractPlatform $platform)
+ {
+ // We require a commented boolean type in order to distinguish between
+ // boolean and smallint as both (have to) map to the same native type.
+ return $platform instanceof DB2Platform;
+ }
}
diff --git a/doctrine/dbal/src/Types/ConversionException.php b/doctrine/dbal/src/Types/ConversionException.php
index f1a18742..278734b9 100644
--- a/doctrine/dbal/src/Types/ConversionException.php
+++ b/doctrine/dbal/src/Types/ConversionException.php
@@ -5,6 +5,8 @@ namespace Doctrine\DBAL\Types;
use Doctrine\DBAL\Exception;
use Throwable;
+use function func_get_arg;
+use function func_num_args;
use function get_class;
use function gettype;
use function implode;
@@ -25,7 +27,7 @@ class ConversionException extends Exception
/**
* Thrown when a Database to Doctrine Type Conversion fails.
*
- * @param string $value
+ * @param mixed $value
* @param string $toType
*
* @return ConversionException
@@ -41,7 +43,7 @@ class ConversionException extends Exception
* Thrown when a Database to Doctrine Type Conversion fails and we can make a statement
* about the expected format.
*
- * @param string $value
+ * @param mixed $value
* @param string $toType
* @param string $expectedFormat
*
@@ -98,7 +100,7 @@ class ConversionException extends Exception
*
* @return ConversionException
*/
- public static function conversionFailedSerialization($value, $format, $error)
+ public static function conversionFailedSerialization($value, $format, $error /*, ?Throwable $previous = null */)
{
$actualType = is_object($value) ? get_class($value) : gettype($value);
@@ -107,7 +109,7 @@ class ConversionException extends Exception
$actualType,
$format,
$error
- ));
+ ), 0, func_num_args() >= 4 ? func_get_arg(3) : null);
}
public static function conversionFailedUnserialization(string $format, string $error): self
diff --git a/doctrine/dbal/src/Types/DecimalType.php b/doctrine/dbal/src/Types/DecimalType.php
index f75d3db2..c70067f2 100644
--- a/doctrine/dbal/src/Types/DecimalType.php
+++ b/doctrine/dbal/src/Types/DecimalType.php
@@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Types;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use function is_float;
+use function is_int;
use const PHP_VERSION_ID;
@@ -34,9 +35,9 @@ class DecimalType extends Type
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
- // Some drivers starting from PHP 8.1 can represent decimals as float
+ // Some drivers starting from PHP 8.1 can represent decimals as float/int
// See also: https://github.com/doctrine/dbal/pull/4818
- if (PHP_VERSION_ID >= 80100 && is_float($value)) {
+ if (PHP_VERSION_ID >= 80100 && (is_float($value) || is_int($value))) {
return (string) $value;
}
diff --git a/doctrine/dbal/src/Types/JsonType.php b/doctrine/dbal/src/Types/JsonType.php
index d17b7f51..d28b8b79 100644
--- a/doctrine/dbal/src/Types/JsonType.php
+++ b/doctrine/dbal/src/Types/JsonType.php
@@ -3,15 +3,15 @@
namespace Doctrine\DBAL\Types;
use Doctrine\DBAL\Platforms\AbstractPlatform;
+use JsonException;
use function is_resource;
use function json_decode;
use function json_encode;
-use function json_last_error;
-use function json_last_error_msg;
use function stream_get_contents;
-use const JSON_ERROR_NONE;
+use const JSON_PRESERVE_ZERO_FRACTION;
+use const JSON_THROW_ON_ERROR;
/**
* Type generating json objects values
@@ -35,13 +35,11 @@ class JsonType extends Type
return null;
}
- $encoded = json_encode($value);
-
- if (json_last_error() !== JSON_ERROR_NONE) {
- throw ConversionException::conversionFailedSerialization($value, 'json', json_last_error_msg());
+ try {
+ return json_encode($value, JSON_THROW_ON_ERROR | JSON_PRESERVE_ZERO_FRACTION);
+ } catch (JsonException $e) {
+ throw ConversionException::conversionFailedSerialization($value, 'json', $e->getMessage(), $e);
}
-
- return $encoded;
}
/**
@@ -57,13 +55,11 @@ class JsonType extends Type
$value = stream_get_contents($value);
}
- $val = json_decode($value, true);
-
- if (json_last_error() !== JSON_ERROR_NONE) {
- throw ConversionException::conversionFailed($value, $this->getName());
+ try {
+ return json_decode($value, true, 512, JSON_THROW_ON_ERROR);
+ } catch (JsonException $e) {
+ throw ConversionException::conversionFailed($value, $this->getName(), $e);
}
-
- return $val;
}
/**
diff --git a/doctrine/dbal/src/Types/Type.php b/doctrine/dbal/src/Types/Type.php
index 03e5b824..c2ae2be5 100644
--- a/doctrine/dbal/src/Types/Type.php
+++ b/doctrine/dbal/src/Types/Type.php
@@ -12,7 +12,7 @@ use function get_class;
/**
* The base class for so-called Doctrine mapping types.
*
- * A Type object is obtained by calling the static {@link getType()} method.
+ * A Type object is obtained by calling the static {@see getType()} method.
*/
abstract class Type
{
@@ -189,7 +189,7 @@ abstract class Type
* Gets the (preferred) binding type for values of this type that
* can be used when binding parameters to prepared statements.
*
- * This method should return one of the {@link ParameterType} constants.
+ * This method should return one of the {@see ParameterType} constants.
*
* @return int
*/
@@ -202,7 +202,7 @@ abstract class Type
* Gets the types array map which holds all registered types and the corresponding
* type class
*
- * @return string[]
+ * @return array<string, string>
*/
public static function getTypesMap()
{
@@ -218,10 +218,13 @@ abstract class Type
* Does working with this column require SQL conversion functions?
*
* This is a metadata function that is required for example in the ORM.
- * Usage of {@link convertToDatabaseValueSQL} and
- * {@link convertToPHPValueSQL} works for any type and mostly
+ * Usage of {@see convertToDatabaseValueSQL} and
+ * {@see convertToPHPValueSQL} works for any type and mostly
* does nothing. This method can additionally be used for optimization purposes.
*
+ * @deprecated Consumers should call {@see convertToDatabaseValueSQL} and {@see convertToPHPValueSQL}
+ * regardless of the type.
+ *
* @return bool
*/
public function canRequireSQLConversion()
diff --git a/doctrine/dbal/src/VersionAwarePlatformDriver.php b/doctrine/dbal/src/VersionAwarePlatformDriver.php
index b3ec8b84..ffcfcd63 100644
--- a/doctrine/dbal/src/VersionAwarePlatformDriver.php
+++ b/doctrine/dbal/src/VersionAwarePlatformDriver.php
@@ -11,6 +11,8 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
* support the correct features and SQL syntax of each version.
* This interface should be implemented by drivers that are capable to do this
* distinction.
+ *
+ * @deprecated All drivers will have to be aware of the server version in the next major release.
*/
interface VersionAwarePlatformDriver extends Driver
{
diff --git a/doctrine/deprecations/.gitignore b/doctrine/deprecations/.gitignore
deleted file mode 100644
index 2ee7dedc..00000000
--- a/doctrine/deprecations/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-vendor
-.phpcs-cache
-composer.lock
diff --git a/composer/package-versions-deprecated/LICENSE b/doctrine/deprecations/LICENSE
index a90b0792..156905cd 100644
--- a/composer/package-versions-deprecated/LICENSE
+++ b/doctrine/deprecations/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2016 Marco Pivetta
+Copyright (c) 2020-2021 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
diff --git a/doctrine/deprecations/README.md b/doctrine/deprecations/README.md
index d6682221..22f0cced 100644
--- a/doctrine/deprecations/README.md
+++ b/doctrine/deprecations/README.md
@@ -137,6 +137,13 @@ class MyTest extends TestCase
triggerTheCodeWithDeprecation();
}
+
+ public function testSomethingDeprecationFixed()
+ {
+ $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issue/1234');
+
+ triggerTheCodeWithoutDeprecation();
+ }
}
```
diff --git a/doctrine/deprecations/composer.json b/doctrine/deprecations/composer.json
index 5cc7ac13..c79e38cd 100644
--- a/doctrine/deprecations/composer.json
+++ b/doctrine/deprecations/composer.json
@@ -8,9 +8,9 @@
"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"
+ "phpunit/phpunit": "^7.5|^8.5|^9.5",
+ "psr/log": "^1|^2|^3",
+ "doctrine/coding-standard": "^9"
},
"suggest": {
"psr/log": "Allows logging deprecations via PSR-3 logger implementation"
@@ -23,5 +23,10 @@
"DeprecationTests\\": "test_fixtures/src",
"Doctrine\\Foo\\": "test_fixtures/vendor/doctrine/foo"
}
+ },
+ "config": {
+ "allow-plugins": {
+ "dealerdirect/phpcodesniffer-composer-installer": true
+ }
}
}
diff --git a/doctrine/deprecations/phpcs.xml b/doctrine/deprecations/phpcs.xml
index 4e0cc21f..f115e43d 100644
--- a/doctrine/deprecations/phpcs.xml
+++ b/doctrine/deprecations/phpcs.xml
@@ -9,6 +9,8 @@
<!-- Ignore warnings, show progress of the run and show sniff names -->
<arg value="nps"/>
+ <config name="php_version" value="70100"/>
+
<!-- Directories to be checked -->
<file>lib</file>
<file>tests</file>
diff --git a/doctrine/deprecations/phpunit.xml.dist b/doctrine/deprecations/phpunit.xml.dist
deleted file mode 100644
index 4740c060..00000000
--- a/doctrine/deprecations/phpunit.xml.dist
+++ /dev/null
@@ -1,8 +0,0 @@
-<?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
deleted file mode 100644
index c4b8ebec..00000000
--- a/doctrine/deprecations/test_fixtures/src/Foo.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?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
deleted file mode 100644
index feccd486..00000000
--- a/doctrine/deprecations/test_fixtures/src/RootDeprecation.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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
- );
-
- }
-}
diff --git a/psr/cache/LICENSE.txt b/psr/cache/LICENSE.txt
new file mode 100644
index 00000000..b1c2c97b
--- /dev/null
+++ b/psr/cache/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2015 PHP Framework Interoperability Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/psr/cache/README.md b/psr/cache/README.md
new file mode 100644
index 00000000..c8706cee
--- /dev/null
+++ b/psr/cache/README.md
@@ -0,0 +1,9 @@
+PSR Cache
+=========
+
+This repository holds all interfaces defined by
+[PSR-6](http://www.php-fig.org/psr/psr-6/).
+
+Note that this is not a Cache implementation of its own. It is merely an
+interface that describes a Cache implementation. See the specification for more
+details.
diff --git a/psr/cache/composer.json b/psr/cache/composer.json
new file mode 100644
index 00000000..e828fec9
--- /dev/null
+++ b/psr/cache/composer.json
@@ -0,0 +1,25 @@
+{
+ "name": "psr/cache",
+ "description": "Common interface for caching libraries",
+ "keywords": ["psr", "psr-6", "cache"],
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Cache\\": "src/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/psr/cache/src/CacheException.php b/psr/cache/src/CacheException.php
new file mode 100644
index 00000000..e27f22f8
--- /dev/null
+++ b/psr/cache/src/CacheException.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace Psr\Cache;
+
+/**
+ * Exception interface for all exceptions thrown by an Implementing Library.
+ */
+interface CacheException
+{
+}
diff --git a/psr/cache/src/CacheItemInterface.php b/psr/cache/src/CacheItemInterface.php
new file mode 100644
index 00000000..63d05dd1
--- /dev/null
+++ b/psr/cache/src/CacheItemInterface.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Psr\Cache;
+
+/**
+ * CacheItemInterface defines an interface for interacting with objects inside a cache.
+ *
+ * Each Item object MUST be associated with a specific key, which can be set
+ * according to the implementing system and is typically passed by the
+ * Cache\CacheItemPoolInterface object.
+ *
+ * The Cache\CacheItemInterface object encapsulates the storage and retrieval of
+ * cache items. Each Cache\CacheItemInterface is generated by a
+ * Cache\CacheItemPoolInterface object, which is responsible for any required
+ * setup as well as associating the object with a unique Key.
+ * Cache\CacheItemInterface objects MUST be able to store and retrieve any type
+ * of PHP value defined in the Data section of the specification.
+ *
+ * Calling Libraries MUST NOT instantiate Item objects themselves. They may only
+ * be requested from a Pool object via the getItem() method. Calling Libraries
+ * SHOULD NOT assume that an Item created by one Implementing Library is
+ * compatible with a Pool from another Implementing Library.
+ */
+interface CacheItemInterface
+{
+ /**
+ * Returns the key for the current cache item.
+ *
+ * The key is loaded by the Implementing Library, but should be available to
+ * the higher level callers when needed.
+ *
+ * @return string
+ * The key string for this cache item.
+ */
+ public function getKey();
+
+ /**
+ * Retrieves the value of the item from the cache associated with this object's key.
+ *
+ * The value returned must be identical to the value originally stored by set().
+ *
+ * If isHit() returns false, this method MUST return null. Note that null
+ * is a legitimate cached value, so the isHit() method SHOULD be used to
+ * differentiate between "null value was found" and "no value was found."
+ *
+ * @return mixed
+ * The value corresponding to this cache item's key, or null if not found.
+ */
+ public function get();
+
+ /**
+ * Confirms if the cache item lookup resulted in a cache hit.
+ *
+ * Note: This method MUST NOT have a race condition between calling isHit()
+ * and calling get().
+ *
+ * @return bool
+ * True if the request resulted in a cache hit. False otherwise.
+ */
+ public function isHit();
+
+ /**
+ * Sets the value represented by this cache item.
+ *
+ * The $value argument may be any item that can be serialized by PHP,
+ * although the method of serialization is left up to the Implementing
+ * Library.
+ *
+ * @param mixed $value
+ * The serializable value to be stored.
+ *
+ * @return static
+ * The invoked object.
+ */
+ public function set($value);
+
+ /**
+ * Sets the expiration time for this cache item.
+ *
+ * @param \DateTimeInterface|null $expiration
+ * The point in time after which the item MUST be considered expired.
+ * If null is passed explicitly, a default value MAY be used. If none is set,
+ * the value should be stored permanently or for as long as the
+ * implementation allows.
+ *
+ * @return static
+ * The called object.
+ */
+ public function expiresAt($expiration);
+
+ /**
+ * Sets the expiration time for this cache item.
+ *
+ * @param int|\DateInterval|null $time
+ * The period of time from the present after which the item MUST be considered
+ * expired. An integer parameter is understood to be the time in seconds until
+ * expiration. If null is passed explicitly, a default value MAY be used.
+ * If none is set, the value should be stored permanently or for as long as the
+ * implementation allows.
+ *
+ * @return static
+ * The called object.
+ */
+ public function expiresAfter($time);
+}
diff --git a/psr/cache/src/CacheItemPoolInterface.php b/psr/cache/src/CacheItemPoolInterface.php
new file mode 100644
index 00000000..03514196
--- /dev/null
+++ b/psr/cache/src/CacheItemPoolInterface.php
@@ -0,0 +1,138 @@
+<?php
+
+namespace Psr\Cache;
+
+/**
+ * CacheItemPoolInterface generates CacheItemInterface objects.
+ *
+ * The primary purpose of Cache\CacheItemPoolInterface is to accept a key from
+ * the Calling Library and return the associated Cache\CacheItemInterface object.
+ * It is also the primary point of interaction with the entire cache collection.
+ * All configuration and initialization of the Pool is left up to an
+ * Implementing Library.
+ */
+interface CacheItemPoolInterface
+{
+ /**
+ * Returns a Cache Item representing the specified key.
+ *
+ * This method must always return a CacheItemInterface object, even in case of
+ * a cache miss. It MUST NOT return null.
+ *
+ * @param string $key
+ * The key for which to return the corresponding Cache Item.
+ *
+ * @throws InvalidArgumentException
+ * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
+ * MUST be thrown.
+ *
+ * @return CacheItemInterface
+ * The corresponding Cache Item.
+ */
+ public function getItem($key);
+
+ /**
+ * Returns a traversable set of cache items.
+ *
+ * @param string[] $keys
+ * An indexed array of keys of items to retrieve.
+ *
+ * @throws InvalidArgumentException
+ * If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
+ * MUST be thrown.
+ *
+ * @return array|\Traversable
+ * A traversable collection of Cache Items keyed by the cache keys of
+ * each item. A Cache item will be returned for each key, even if that
+ * key is not found. However, if no keys are specified then an empty
+ * traversable MUST be returned instead.
+ */
+ public function getItems(array $keys = array());
+
+ /**
+ * Confirms if the cache contains specified cache item.
+ *
+ * Note: This method MAY avoid retrieving the cached value for performance reasons.
+ * This could result in a race condition with CacheItemInterface::get(). To avoid
+ * such situation use CacheItemInterface::isHit() instead.
+ *
+ * @param string $key
+ * The key for which to check existence.
+ *
+ * @throws InvalidArgumentException
+ * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
+ * MUST be thrown.
+ *
+ * @return bool
+ * True if item exists in the cache, false otherwise.
+ */
+ public function hasItem($key);
+
+ /**
+ * Deletes all items in the pool.
+ *
+ * @return bool
+ * True if the pool was successfully cleared. False if there was an error.
+ */
+ public function clear();
+
+ /**
+ * Removes the item from the pool.
+ *
+ * @param string $key
+ * The key to delete.
+ *
+ * @throws InvalidArgumentException
+ * If the $key string is not a legal value a \Psr\Cache\InvalidArgumentException
+ * MUST be thrown.
+ *
+ * @return bool
+ * True if the item was successfully removed. False if there was an error.
+ */
+ public function deleteItem($key);
+
+ /**
+ * Removes multiple items from the pool.
+ *
+ * @param string[] $keys
+ * An array of keys that should be removed from the pool.
+
+ * @throws InvalidArgumentException
+ * If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
+ * MUST be thrown.
+ *
+ * @return bool
+ * True if the items were successfully removed. False if there was an error.
+ */
+ public function deleteItems(array $keys);
+
+ /**
+ * Persists a cache item immediately.
+ *
+ * @param CacheItemInterface $item
+ * The cache item to save.
+ *
+ * @return bool
+ * True if the item was successfully persisted. False if there was an error.
+ */
+ public function save(CacheItemInterface $item);
+
+ /**
+ * Sets a cache item to be persisted later.
+ *
+ * @param CacheItemInterface $item
+ * The cache item to save.
+ *
+ * @return bool
+ * False if the item could not be queued or if a commit was attempted and failed. True otherwise.
+ */
+ public function saveDeferred(CacheItemInterface $item);
+
+ /**
+ * Persists any deferred cache items.
+ *
+ * @return bool
+ * True if all not-yet-saved items were successfully saved or there were none. False otherwise.
+ */
+ public function commit();
+}
diff --git a/psr/cache/src/InvalidArgumentException.php b/psr/cache/src/InvalidArgumentException.php
new file mode 100644
index 00000000..be7c6fa0
--- /dev/null
+++ b/psr/cache/src/InvalidArgumentException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Psr\Cache;
+
+/**
+ * Exception interface for invalid cache arguments.
+ *
+ * Any time an invalid argument is passed into a method it must throw an
+ * exception class which implements Psr\Cache\InvalidArgumentException.
+ */
+interface InvalidArgumentException extends CacheException
+{
+}